今日已更新 113 条资讯 | 累计 37664 条内容
关于我们

标签:#RAM

找到 2551 篇相关文章

AI 资讯

phi – the 12 MB alternative to Pi: no Ts, any model, hashline edit

Hi everyone I’ve been hacking on a terminal coding agent called phi https://github.com/pulseaiclub/phi for the past few months, and I’d love to share what it is and why it exists. If you’ve used tools like Pi, Claude Code, Aider, or Goose, phi tries to hit the same workflow—but deliberately strips away the runtime baggage. It’s a single Go binary, ~12 MB, with no Node, Electron, or Python in sight. Here’s what makes it tick: No model lock-in This is the whole reason phi exists. Model releases are moving faster than any agent maintainer can keep up with. Instead of chasing every new provider, phi tr eats the model as a pluggable config: anything OpenAI-compatible or Anthropic-native works out of the box. You can swap models in seconds without waiting for a n author to add support. Config is a single YAML file, and there’s also a tiny HTML editor so you can point-and-click your way through ~/.phi/config.yaml. As light as it gets Go is the secret sauce here. A stripped release build (CGO_ENABLED=0) comes in at ~12 MB, cold idle RSS around ~21 MB, and a first frame in roughly 40 ms. Ther e are only 6 direct module dependencies. If you want a coding agent you can go build in half a second and read in an afternoon, this is it. A permission gate that actually matters One thing that always makes me nervous with coding agents is the "model deletes your files" moment. Phi defaults to read-only: the agent can scan your codebase , but writes and shell commands require explicit approval. The approval dialog gives you three choices—allow, deny with feedback, or allow everything for the r est of the session. Rules are granular: • bash.allow → go test ./... is fine. • bash.deny → rm -rf * is blocked. • fetch.allowed_hosts → restrict which domains the agent can reach. Sub-agents that don’t bloat your context One big agent is fine for small tasks, but long-running work pollutes the context window with noise. Phi ships a full set of sub-agent tools (agent_spawn, agen t_task, agent_wai

2026-08-11 原文 →
AI 资讯

Union-Find: The Fellowship of the Sets

The Quest Begins (The "Why") I still remember the first time I saw LeetCode 323 “Number of Connected Components in an Undirected Graph”. I stared at the adjacency list, thought “I’ll just run a DFS from every node”, and coded it up in ten minutes. The solution passed the easy tests, but when the hidden test cases hit a graph with 10⁵ nodes and 10⁵ edges, my DFS started to choke—stack overflows, repeated visits, and a sinking feeling that I was brute‑forcing a problem that deserved a smarter tool. That night, after a few too many coffees, I stumbled upon a tiny comment in a discussion thread: “Union‑Find can do this in almost O(1) per operation”. My curiosity sparked like a power‑up in a retro arcade game. I had to know why this seemingly simple data structure could turn a nightmare into a breeze. The Revelation (The Insight) At its heart, Union‑Find (aka Disjoint Set Union, DSU) maintains a collection of elements partitioned into disjoint subsets. It supports two operations: Find(x) – returns the representative (root) of the set containing x . Union(x, y) – merges the sets containing x and y . The magic lies in two simple heuristics: Path Compression – when we walk up the tree to find a root, we make every node on that path point directly to the root. Future finds become flat, almost constant‑time. Union by Rank/Size – we always attach the smaller tree under the root of the larger one, keeping the overall tree shallow. Why does this give us near‑O(1) amortized time? Think of each Find as paying a small “tax” to flatten the path. The tax is paid only a few times per node before it becomes a direct child of the root. Over a sequence of m operations, the total work is bounded by O(m α(n)) , where α is the inverse Ackermann function—so slow‑growing it’s practically a constant for any realistic n . In plain English: every time we climb up, we leave a shortcut behind. The next climber benefits from that shortcut, and the structure keeps getting better. It’s like building

2026-08-11 原文 →
AI 资讯

What AI Coding Tools Are Actually Changing About Technical Interviews

A few years ago, a technical interview mostly tested one thing: can you write correct code, from memory, under pressure. That bar has quietly shifted — and a lot of developers preparing for interviews right now haven't fully clocked it. AI coding assistants are part of daily work at most companies now, from big IT services firms to small product teams. Interview panels have adjusted to that reality faster than most prep guides have. What's actually different now Interviewers care less about whether you can produce a function from scratch, and more about whether you understand what code is doing and why. It's increasingly common to be handed a piece of AI-generated code and asked to find the bug, justify a design decision, or optimize it — instead of writing something from zero on a whiteboard. Some companies go further and let you use AI tools during the technical round, then evaluate how well you direct the tool, verify its output, and catch its mistakes. The skill being tested has moved from "can you write code" to "can you reason clearly with code as your material." Three things I keep seeing candidates get wrong Treating a finished course or degree as the finish line. Completing a syllabus tells an employer you were exposed to concepts. It doesn't tell them you can apply those concepts to a messy, real-world problem — which is exactly what open-ended interview scenarios are designed to expose. Leaning on AI tools without understanding the output. Using an AI assistant while practicing at home is fine. The problem shows up when that habit surfaces in a live interview as an inability to explain your own solution. If you can't walk through why a piece of code works, a couple of follow-up questions will make that obvious fast. Underrating communication and debugging skills. As AI tools take on more initial code-writing, the human value shifts toward reviewing, debugging, and explaining decisions to teammates. Candidates who only practiced writing code — and never pr

2026-08-11 原文 →
AI 资讯

Parallel Coding Agents Need Handoffs, Not More Terminals

The concrete problem Running two or three coding-agent sessions is easy. Knowing when their work is safe to combine is not. One session changes an API while another writes regression tests against the old shape. A third investigates a production failure and quietly edits the same configuration file. Git worktrees prevent immediate filesystem collisions, but they do not explain task dependencies, transfer assumptions, or warn that two agents are solving incompatible versions of the problem. The developer becomes a human message bus: checking terminals, copying commit IDs, repeating context, and deciding which session should wait. The more capable each agent becomes, the less useful a wall of terminal panes is as a coordination interface. The current signal Claude Code now supports messaging between sessions on the same machine. Its documentation describes session discovery, plain-text messages, and a local messaging socket. Agent view separately exposes background-session state, worktrees, pull-request status, and a JSON listing suitable for scripts. Hooks can observe tool input and block a tool call before execution. That does not prove demand for a new product. It does create a concrete implementation moment: the primitives for handoffs and visibility exist, while dependency ownership and conflict negotiation remain a workflow problem. In RayTally's bounded Hacker News snapshot at August 9, 00:33 UTC, the cross-session messaging discussion had 50 points and 26 comments and ranked 18th. Those numbers describe that historical observation only; they are not user counts, market validation, or a prediction of lasting interest. A product direction: a control desk for handoffs The useful product is not another chat window. It is a small local control desk that makes each session declare four things: its goal, worktree, files it expects to touch, and the result another session is waiting for. When the API session finishes, the testing session should receive a compact hando

2026-08-11 原文 →
AI 资讯

NPM vs Yarn vs pnpm vs Bun Which Package Manager Is Best for Modern Web Development?

As developers, we use package managers almost every day. Whether we are working with Node.js, React, Next.js, TypeScript, Express, Prisma, or other technologies in the JavaScript ecosystem, choosing the right package manager can have a meaningful impact on our development workflow. Recently, I spent some time comparing the most popular package managers: npm, Yarn, pnpm, and Bun. After looking at them from the perspective of performance, dependency management, disk efficiency, ecosystem compatibility, and developer productivity, my current preference is pnpm. Why pnpm? For me, pnpm provides one of the best overall balances between speed, disk efficiency, reliability, dependency management, and developer experience. One of the key differences is how pnpm handles dependencies. It uses a content-addressable store and links packages into projects instead of unnecessarily keeping separate copies of the same packages for every project. This can reduce disk usage and make package installation more efficient, especially when working on multiple JavaScript or TypeScript projects. Another advantage is pnpm's stricter dependency management. It encourages projects to explicitly declare the packages they actually depend on, which can help prevent accidental reliance on transitive dependencies. This becomes particularly useful when working on larger applications, monorepos, or team-based projects. What about Bun? Bun is extremely interesting because it is much more than a package manager. It provides a JavaScript/TypeScript runtime, package manager, test runner, and bundler. Its performance is impressive, especially when it comes to package installation and certain development workflows. However, I don't think raw speed should be the only factor when choosing a technology for production. Compatibility, ecosystem maturity, team familiarity, tooling support, and long-term maintainability are equally important. That is why I see Bun as an excellent and promising tool, but I would not

2026-08-11 原文 →
AI 资讯

The AI Coding Team Working Agreement

Every team I've worked with has unwritten rules — who to ask before touching auth, which decisions are settled, what "in progress" actually means. They used to travel by osmosis. Once everyone on the team is coding with an agent, osmosis stops working, because half the conversation now happens in someone's private session. This is the one-page agreement we ended up writing down, and why each clause is in it. When every developer on a team codes with an AI agent, one of the first things to break down can be the unwritten rules. Small, shared assumptions that once traveled through everyday conversation ("ask before you touch auth," "we decided on v2 last week") may not reach a teammate's private session — let alone the agent working in it. The established fix for that is a working agreement : a short, explicit set of norms a team writes for itself. This one is designed for AI-assisted teams — a page you can copy, adapt, and keep somewhere every teammate can access and every agent is configured to read. What a working agreement is — and isn't A working agreement is a team norm, written by the team, kept short, and revised as you learn. It is not a tool, and not a policy handed down from above. It doesn't enforce anything — it aligns behavior. That's precisely why it survives across whatever mix of editors and agents your team actually uses: it lives at the human layer, above any one tool. If you've run agile ceremonies, you've seen these before. What's new is that agents now perform part of the work, so a few assumptions that people may have absorbed implicitly need to be written down. Accountability still stays with people. The template Copy this, cut what doesn't fit, and fill in the blanks. Keep it to a page. # Our AI Coding Working Agreement (v1) ## 1. Shared decisions - Decisions that affect others live in: ______ (a shared memory, a decisions doc). - Before a decision affects someone else's work, we record who decided it, what changed, and why. ## 2. Declaring wo

2026-08-11 原文 →
AI 资讯

The two branches of computing

Why computers have so far been treated as appliances and why now the timeline splits again and can flip back to being instruments like the Dynabook, Smalltalk and Emacs. submitted by /u/Manueljlin [link] [留言]

2026-08-11 原文 →
AI 资讯

Engineering Is the Checkable Fraction of Your Practice

Craft externalizes nothing and transfers by apprenticeship. Engineering writes the governing relation down where someone else can find it wrong. Four times now I have written the same three sentences in different notations, for four problems that looked unrelated: a design method, a coding technology, an architecture-derivation procedure, and a contract-modelling tool. I noticed the repetition only after the fourth. Here it is, stated as precisely as I can manage. Structure is derived from the attribution of forced change. The attribution is kept as an explicit, checkable artifact. The derivation refuses rather than guesses when its inputs underdetermine the answer. Three clauses, each carrying weight. Drop one and look at what remains. Drop derived and you have a documentation exercise: the structure was chosen first and the attribution written to match. This is the normal case, and it makes no prediction, so nothing can disagree with it. Drop explicit artifact and you have taste. Real, valuable, and transferable only by apprenticeship. Drop refusal and you have a generator that answers every question. Its answers carry no information, because it was always going to produce one. The third clause has a lineage worth claiming Type inference has refused for fifty years. Hindley-Milner unification fails rather than picking a plausible substitution: when two types cannot be reconciled, the answer is an error, not a guess. Core HM needs no annotations at all -- it infers principal types, and that is the point. The interesting part is what happened when later extensions broke that guarantee. Type classes admit programs whose type is inferable while the instance to use is not; GADTs and polymorphic recursion break principality outright. In each case the compilers were free to pick a plausible candidate, and they demand an annotation instead. Build systems joined later: Bazel refuses an undeclared dependency rather than resolving it from ambient state ( this rule is missing

2026-08-11 原文 →
AI 资讯

The Bug Wasn't in My Code --- It Was in My Assumptions 🤯

We've all been there. The code looks correct. No obvious syntax errors. The logic seems fine. You read the same function 10 times. And somehow... It still doesn't work. 😭 After wasting way too much time debugging situations like this, I realized something: Sometimes the bug isn't in your code. It's in what you assumed about your code. The classic debugging trap Imagine you're calling an API and expecting this: { "user" : { "name" : "Ash" } } So naturally, you write: const name = response . user . name ; Everything looks perfectly reasonable. But the actual response is: { "data" : { "user" : { "name" : "Ash" } } } Now you're staring at your JavaScript wondering: "Why is user undefined?!" The JavaScript isn't necessarily the problem. Your assumption about the API response was. This happens everywhere It's not just API responses. You can make incorrect assumptions about: What data a function receives Whether a value can be null What an API actually returns Environment variables being available File paths Database records Authentication state Time zones User input Production vs development environments What a third-party library actually does And these assumptions can create some seriously confusing bugs. My new debugging approach Instead of immediately changing the code, I try to verify my assumptions first. 1. What do I think is happening? Write down your assumption. For example: "The API is returning the user object." 2. What is actually happening? Inspect the data. console . log ( response ); Don't guess. Look at it. 3. Where does reality differ from my assumption? Maybe the API response changed. Maybe the value is undefined . Maybe the environment variable isn't loaded. Maybe the backend is returning an error that the frontend isn't handling. 4. Fix the actual problem Only after understanding the mismatch should you change the code. This saves a surprising amount of time. The debugging rule I now follow When something doesn't make sense, I ask: "What am I assuming

2026-08-11 原文 →
产品设计

On comments

Comments in code are often deemed "mostly useless" these days. They are, supposedly, mostly obvious, stale, and repeat what the code already says. And so people pay less attention to them both when reading and writing code. That trend sucks. When used right, comments are genuinely useful and sometimes critically important! So, I wrote about some of the kinds of comments I think earn their place, each with examples from real code bases. Hope you find it useful, and that we can recover some of the love that comments deserve! submitted by /u/Jonhoo [link] [留言]

2026-08-11 原文 →
AI 资讯

8051 What does SDCC do part 1 ?

1. Introduction and Problem Statement A good way to learn what a compiler really does when transforming a C source code into a binary is to disassemble the binary and compare it with the C source code. It is especially true for 8 bits microcontrollers like the 8051. In order to test SDCC we are going to use the following C source code. /* ========================================================================== * * Universal Test Corpus - Heterogeneous Architecture Analysis * * ========================================================================== */ #include <stdint.h> // 1. Global variables (testing absolute/relative addressing modes) volatile uint32_t global_var_32 = 0xDEADBEEF ; volatile uint8_t global_var_8 = 0x42 ; const char string_const [] = "TARGET_STRING" ; // 2. Function with parameter passing and local variables (stack / Frame Pointer test) int32_t callee_function ( int16_t a , int16_t b ) { volatile int32_t local_result = 0 ; // Basic and mixed arithmetic operations (8, 16, 32 bits) local_result += ( int32_t )( a * b ); local_result -= ( int32_t )( a / ( b | 1 )); // Avoid division by zero // Shift tests and logical operations (highly variable depending on ISAs) local_result = ( local_result << 2 ) ^ 0x55AA55AA ; local_result = ( local_result >> 1 ) | ( int32_t ) global_var_8 ; return local_result ; } // 3. Main function grouping complex control flows int main ( void ) { volatile int32_t accumulator = 0 ; int16_t i ; // Loop test (Conditional jumps, decrement, comparison tests) for ( i = 0 ; i < 10 ; i ++ ) { if ( i == 5 ) { accumulator += 100 ; } else { accumulator += i ; } } // Multiple branching test (Switch / Jump Table or cascaded if-else) switch ( global_var_8 ) { case 0x10 : accumulator += 10 ; break ; case 0x20 : accumulator += 20 ; break ; default: accumulator -= 5 ; break ; } // Function call (Stack management, save registers Link Register/PC) accumulator += callee_function (( int16_t ) accumulator , 3 ); // Pointer and indirect memory ac

2026-08-11 原文 →
AI 资讯

The Matrix: Why Merge Sort Beats the Brute Force

The Quest Begins (The "Why") I still remember the first time I got hit with a sorting question in an interview. The interviewer slid a whiteboard marker across the table and said, “Sort this array of a million integers – and tell me why you chose your method.” My brain went straight to the trusty old bubble sort I’d learned in CS101. I started writing nested loops, feeling like Neo dodging bullets in slow motion, only to realize the runtime was creeping toward O(n²). After a few painful minutes, I could see the interviewer’s eyes glaze over – not because I was wrong, but because I was using a sledgehammer to crack a nut. That moment sparked a quest: What makes a sorting algorithm truly efficient, and how do I know when to reach for it? I dove into textbooks, blog posts, and late‑night YouTube deep dives. The answer kept pointing back to one algorithm that felt like discovering a hidden cheat code: Merge Sort . The Revelation (The Insight) So why does Merge Sort work so well? It’s not just about splitting and merging; it’s about guaranteeing that each level of recursion does a linear amount of work, no matter how the input is arranged. Think of an unsorted array as a messy pile of LEGO bricks. Merge Sort first divides the pile into two halves, then halves again, until each sub‑pile contains a single brick – which is, by definition, sorted. The magic happens in the merge step: we take two already‑sorted sub‑arrays and walk through them with two pointers, always picking the smaller front element and appending it to the result. Because each sub‑array is sorted, we never need to look back; we simply advance one pointer at a time. That walk is O(n) for the merge: each element is examined exactly once as it gets placed into the output array. Since we split the array log₂ n times (each level halves the size), we perform an O(n) merge at each of those log₂ n levels. Multiply them together and you get O(n log n) worst‑case time, with O(n) extra space for the temporary buffer

2026-08-11 原文 →
AI 资讯

Ayo GitHub Quietly Killed the Unreviewable Mega-PR

If you've ever opened a PR with 47 changed files and a diff so long GitHub just gives up and shows you "Load Diff" seventeen times, this one's for you. GitHub quietly shipped what might be the biggest pull request update in years, and it's aimed squarely at that problem. Let's talk about stacked pull requests. The problem, in one sentence Big PRs are where good reviews go to die. Nobody reads a 2000 line diff carefully. Some folks reach for AI code review tools like LiveReview to take the edge off, and honestly that helps, but even the best reviewer (human or model) does a better job on a tight, focused diff than on a 2000 line wall. Smaller inputs, better reviews. That's true no matter who's doing the reviewing. Stacked PRs are GitHub's answer: break one massive change into a chain of small, dependent PRs, where each one only reviews the diff it actually introduces, not everything below it. What a stack actually is The rule is simple. You need two or more PRs in the same repo where: The bottom PR targets your trunk branch (usually main ) Every PR after that targets the PR below it, not main That's it. That's the whole trick. Foundational stuff (schemas, shared types) goes at the bottom. Stuff that depends on it (API routes, UI) goes higher up the chain. And here's the part that surprised me: if you just do this manually with plain git, by opening PR #11 against the branch for PR #10 instead of against main , GitHub now recognizes that as a stack automatically. No special tool required. It just notices the base branches form a chain and lights up a banner. Stacking isn't a git concept at all, it's purely a GitHub UI concept layered on top of branches you were already making. Let's actually build one Enough theory. I built a real stack in one of my own repos ( peektea , a terminal file browser I maintain), using a harmless scratch file so nothing real got touched. Here's the actual terminal session, copy pasted, warts and all. First I tried to be fancy and use the CL

2026-08-11 原文 →