AI 资讯
flex: 1 and flex: 1 1 auto are not interchangeable when the parent has no definite height
Short version, so you do not have to click: flex: 1 expands to flex: 1 1 0%. That 0% is a percentage basis and resolves against the parent's height. A panel that is height: auto under a max-height cap has no definite height, so the percentage has nothing to resolve against and the child contributes zero. flex: 1 1 auto fixes it, because the basis becomes the content's own height. The reason it took me an evening: Chromium quietly does what you meant, and the engine that broke it was WKWebView. Every test was green because Playwright ships its own WebKit build rather than the system one. I have not worked out whether the spec requires that collapse or merely permits it, so I cannot say which engine is wrong. If you know which reading applies to a max-height-capped auto-height parent, I would like to hear it. submitted by /u/HolidayChard9706 [link] [留言]
开发者
Succinct and Fast Tiny Pointer Hash Tables
submitted by /u/mttd [link] [留言]
AI 资讯
Stop Copy-Pasting Parts in Docker Compose
Imagine you have a complex microservice. For local development, you need it connected to a message queue, a telemetry collector, and a database. But for your E2E testing, you need a slightly modified version (different env vars, an extra mock dependency, maybe a different port). Most engineers solve this by maintaining two massive, almost-identical YAML files. It is a nightmare to sync changes. Or they simply do this: $ docker compose -f compose.yml -f e2e-compose.yml up --build -d I do NOT like neither of them. Instead use YAML Anchors (&) , Merge Keys (<<:) , and Compose Profiles to create a single, DRY (Don't Repeat Yourself) configuration file. # ------------------------------------------------------------ # 1. REUSABLE BUILDING BLOCKS (Anchors) # ------------------------------------------------------------ x-backend-depends-on : &backend-depends-on message-queue : condition : service_healthy telemetry-collector : condition : service_started x-backend-config : &backend-config build : . user : " 1000:1000" ports : - " 3000:$PORT" env_file : - .env healthcheck : test : [ " CMD" , " curl" , " -f" , " http://localhost:${PORT:-3000}/health" ] interval : 5s timeout : 5s retries : 12 start_period : 10s depends_on : *app-depends-on # ------------------------------------------------------------ # 2. SERVICES # ------------------------------------------------------------ services : # --- Production / Dev Service --- backend : << : *backend-config profiles : [ " dev" ] # --- E2E Test Variant --- backend-e2e : << : *app-config profiles : [ " e2e" ] # Only starts when explicitly called environment : # Override specific ENV vars for testing RETRY_DELAY_MS : " 100" TIMEOUT_MS : " 200" depends_on : << : *app-depends-on # Inherit all base dependencies e2e-fixture : # ADD an extra dependency for testing condition : service_healthy # ... So now how this changes your workflow: Local: docker compose --profile dev up starts only backend + services in default/dev profile. E2E testing:
AI 资讯
Local vs remote MCP servers: which one you actually want
There are two kinds of MCP server, they solve different problems, and almost nothing tells you which one you are building until you are deep enough in to have already made the wrong choice. I worked this out from a submission form. More on that below, because it turns out to be the clearest signal in the whole ecosystem and it is buried in a footnote. The two shapes Local (stdio). The server runs as a process on the user's own machine. The client — Claude Desktop, Cursor, whatever — spawns it and talks to it over stdin/stdout. It is a package the user installs. Remote (Streamable HTTP). The server is a service you host. The client connects out to a URL with a token in an Authorization header. Nothing is installed locally. That is the entire distinction, and it determines everything else. What actually differs Who runs the code. Local: the user, on their hardware. Remote: you, on yours. This is the real decision. Everything below follows from it. Where secrets live. Local servers read credentials from the user's own environment — their shell profile, their config file. You never see them. Remote servers require the user to hold a token you issued, which means you own the entire credential lifecycle: issuing, scoping, rotating, revoking. What the server can reach. A local server can read the user's filesystem, hit localhost, talk to their Docker daemon. A remote server can see none of that, and should not want to. Update path. Remote: you deploy, everyone is on the new version immediately. Local: users run whatever version they installed, possibly forever. Failure surface. A local server fails on one machine. A remote server fails for everyone at once. Pick your poison. Choosing Local if you need the user's filesystem, local processes, a local database, or hardware. Or if the data must not leave their machine. Remote if the server fronts a service you already run. If your MCP server's job is to call your own API, making users install a process that proxies to your HTT
AI 资讯
Introduction
Hi, I’m a Principal Architect with 15+ years of experience designing and delivering scalable, resilient, high-availability Java SaaS platforms. My work sits at the intersection of distributed systems, real-time data platforms, and the emerging enterprise generative AI stack. I enjoy turning complex technical challenges into secure, maintainable systems that create measurable business value. Architectural Foundation I lead technical direction for platforms built with JDK 17–25 and Spring Boot 3.x, with a strong focus on microservices, transactional consistency, and operational resilience. My experience includes: Designing services around ACID transaction requirements Managing distributed workflows with Saga and Outbox patterns Applying strategic Domain-Driven Design (DDD) Defining bounded contexts that align software architecture with business capabilities Using Architecture Decision Records (ADRs) to make technical decisions transparent and durable Real-Time and Distributed Systems I build the “nervous systems” of enterprise platforms using Kafka, Redis, and MongoDB. My focus is on event-driven architectures that support real-time processing, high throughput, low latency, and global availability. I am particularly interested in infrastructure-aware design: making sure application architecture, data flow, deployment topology, and observability work together rather than being treated as separate concerns. Generative AI and Agentic Systems A significant part of my current work involves AI/ML and generative AI initiatives, especially Retrieval-Augmented Generation (RAG) and agentic workflows for enterprise use cases. Areas I am actively exploring include: JVM-native inference: Running inference with ONNX Runtime to reduce network overhead and improve predictability Agent orchestration: Building production-ready workflows with LangChain4j and Spring AI Build vs. buy decisions: Evaluating emerging AI platforms against enterprise requirements AI guardrails: Designing secur
AI 资讯
What's New in Go 1.27: A Developer's Practical Guide
Go 1.27 landed in August 2024, and while it doesn’t introduce earth-shattering changes, it polishes the language in ways that add up. If you’re maintaining production services or building new ones, these updates can save you time and headaches. Let’s cut through the noise and focus on what actually affects your code. Performance: Faster Without Changing a Line The compiler and runtime received several under-the-hood optimizations. Benchmarks show a 3-5% speedup in typical server workloads, with some microbenchmarks hitting 10%. This isn’t magic, it’s the result of better inlining decisions and reduced memory allocation overhead. The best part? You get this for free. Just recompile your existing code with Go 1.27 and measure the difference. One standout improvement is in garbage collection. The GC now handles large heaps more efficiently, which matters if you’re running services with hundreds of gigabytes of live data. Latency spikes during GC cycles should be less pronounced, though you’ll still want to monitor this in production. Language Tweaks: Small but Useful Go 1.27 introduces a few language changes that simplify common patterns. The most notable is the addition of the new built-in function clear. It works on slices, maps, and type parameters, letting you reset collections without reallocating them. This is particularly handy for pooling or reusing buffers. For slices, clear sets all elements to their zero value and truncates the slice to length zero. For maps, it removes all entries, leaving the map empty but with the same capacity. For type parameters, it behaves based on the underlying type, useful for generic code. Another small but welcome change is the ability to use //go:linkname with methods. This was previously restricted to functions, which made certain low-level optimizations awkward. Now you can link methods directly, which is useful for writing highly optimized libraries or interfacing with C code. Tooling: Better Debugging and Dependency Manageme
AI 资讯
Grade Your LLM Pass/Fail and You Will Ship a Disaster
I gave my LLM a 29-question order-reading exam. Last time was how to build the exam. Today: grading. Grading gets its own post for a reason. Build the grading wrong, and the score lies to you. 5 wrong out of 29 — can I ship? No idea. Because "which 5" is missing. If it missed 5 typo-riddled questions, ship it. But if one of those 5 was reading "please cancel my order" as a NEW order? Then even with everything else perfect, you can't ship. That program sends goods to a customer who just cancelled. So don't grade by count. Grade by severity. Severity = "can a human undo this?" My grader has 4 grades. One criterion — is it reversible? In this program, the irreversible moment is when the wrong goods get loaded onto a truck. FATAL Wrong goods on the truck. Cannot be undone RISKY Confirmed something ambiguous without asking. Right this time — fatal next time MISSED Dropped an order. The customer calls. Fixable HARMLESS Over-asked "please confirm." Just slower One principle falls out of this: A wrong confirmation is worse than no confirmation. Sounds obvious. In production you'll be tempted to flip it. Someone complains "it asks for confirmation too often," so you lower the confidence bar. The screen gets cleaner. And the accidents start happening off-screen. The same 28/29 splits two ways FATAL 0 · MISSED 1 → Ship it. Humans catch what it drops FATAL 1 · everything else perfect → Don't ship. You don't know when that 1 comes back Same score. Opposite fates. Two accidents my grader caused The grader is code I wrote. Like all code I write, it had bugs. Accident one — zero points over formatting. A model answer was perfect in content, but the JSON wrapper arrived with the tail cut off. The grader ruled "broken format = fatal." A 100-point answer, zeroed over one missing brace. The fix is simple: count the open brackets and close what's missing (ignoring brackets inside strings). The actual code is in parse_json in the repo . Accident two — penalizing a good answer. For "250 b
AI 资讯
A Good LLM Exam Is 90% Traps
Last time I gave my LLM an order-reading exam and lost 5 times as the exam author. Today: how that exam was built. Conclusion first — nice questions are a waste of paper. You'll want to start with the happy path Ask anyone to write a test and they start with the case that works. "5 boxes of the 250 shipping boxes please" → shipping box 250, 5 boxes. It passes. Feels good. Reassuring. But that's wasted points. Models rarely fail the normal cases. What fails is everything that isn't normal. My 29 questions broke down like this: Normal orders 4 Things that aren't orders 6 ← the biggest group Changes & cancellations 4 Ambiguous ones 5 Typos & extreme shorthand 3 After learning kicks in 7 Normal is the smallest group. On purpose. Why "not an order" gets the most questions The worst accident for this program is shipping something nobody ordered. So the exam should aim at that accident more than anything else. What are the dimensions of the 250 shipping box? Product name: present. Number: present. But it's not an order. It's a question. A program that treats "product name spotted" as "order detected" calls the truck right here. So I planted six of these: price inquiries, stock inquiries, delivery questions, greetings, a tax-invoice request. Changes and cancellations are nastier. I ordered 5 boxes of the 250 — please send only 3 Two numbers. Read only the first half and it's a perfect order. Treat it as a new order and the goods ship twice. Plant traps in the catalog too It's not just about hard questions. Make the data itself messy. Two kinds of clear tape — 48mm and 60mm Five products starting with "250" Different pack sizes per box — 50, 40, 25, 10 sheets A few loose items with no box unit at all One reason: real data already looks like this. A real product catalog always has near-twins. Run the exam on a clean catalog and here's what happens — everything passes. Then you plug in production data and it collapses. If the exam passed but production has accidents, that's no
开发者
Turns are Better than Radians
submitted by /u/Iamsodarncool [link] [留言]
产品设计
The Design and Evolution of io_uring by Jens Axboe
submitted by /u/cdb_11 [link] [留言]
开发者
Go 1.27 is released
submitted by /u/NegotiationInner7307 [link] [留言]
AI 资讯
Part 1 — What Actually Happens When Code Runs
When we write: const result = add ( 10 , 20 ); it feels like the computer simply "runs the code." But the CPU doesn't understand JavaScript. There are several layers between the code we write and the hardware actually executing instructions. That's what I wanted to understand first. From JavaScript to the CPU In Node.js, JavaScript is handled by V8 , the JavaScript engine. A simplified view looks like this: JavaScript ↓ V8 ↓ Bytecode ↓ JIT compilation ↓ Machine instructions ↓ CPU V8 doesn't simply "interpret JavaScript" or "compile JavaScript" once and forget about it. It can start with bytecode and progressively compile frequently executed ("hot") code into more optimized machine code. Eventually, the CPU is executing instructions that operate at a much lower level than the JavaScript we originally wrote. What does the CPU actually do? At its core, a CPU repeatedly executes instructions. A simplified mental model is: Fetch → Decode → Execute → Repeat The CPU has several important pieces involved in this process. Registers are tiny, extremely fast storage locations inside the CPU. They're used to hold values the CPU is actively working with. The ALU (Arithmetic Logic Unit) performs many arithmetic and logical operations. The Program Counter (PC) keeps track of where the next instruction comes from. And the CPU runs according to a clock, measured in GHz. A 3 GHz CPU has roughly 3 billion clock cycles per second, but that does not mean it executes 3 billion instructions per second. Different instructions and architectures have different costs. Modern CPUs are far more sophisticated than this simplified model, using pipelining, multiple execution units, branch prediction, out-of-order execution, and more. But the basic model is enough to start reasoning about performance. The CPU doesn't get everything from RAM One of the most important things I learned here is that where data lives matters . A simplified hierarchy looks like: Registers ↓ L1 Cache ↓ L2 Cache ↓ L3 Cache
AI 资讯
Framework responds to complaints that BIOS update bricks Ryzen 7040 laptops
Framework says it's replacing some out-of-warranty AMD mainboards.
开发者
Double-double: 31 digits of precision without leaving the FPU
submitted by /u/NightElfik [link] [留言]
开发者
The Pit of Success - An Interview with Rico Mariani
submitted by /u/cdb_11 [link] [留言]
开发者
Automatiza tareas repetitivas con un bot en Python
Cada tarea manual y repetitiva que haces cada semana es tiempo (y dinero) que un script de Python puede recuperarte. La automatización no es solo para grandes empresas. Primero: ¿qué vale la pena automatizar? Busca tareas repetitivas, basadas en reglas y frecuentes . Algunos ejemplos habituales: Descargar y consolidar informes cada mañana. Copiar datos entre una web y una hoja de cálculo. Enviar recordatorios o alertas. Vigilar precios o cambios en una página. Una regla práctica: si puedes explicar la tarea como una lista de pasos sin excepciones, probablemente se puede automatizar. Las herramientas del ecosistema Python requests / httpx para hablar con APIs y webs. BeautifulSoup / Playwright para web scraping (Playwright cuando la página carga con JavaScript). pandas para transformar datos. APScheduler o cron para ejecutarlo en un horario. Bots de Telegram o Discord para recibir avisos donde ya estás. Un ejemplo mínimo Vigilar el título de una página y avisar si cambia: import requests from bs4 import BeautifulSoup def titulo ( url ): html = requests . get ( url , timeout = 10 ). text return BeautifulSoup ( html , " html.parser " ). title . string . strip () anterior = titulo ( " https://example.com " ) # ...ejecutado por cron cada hora... actual = titulo ( " https://example.com " ) if actual != anterior : print ( " ¡Cambió! " ) # aquí enviarías un mensaje de Telegram De script a bot fiable Un script que corre en tu portátil es un buen comienzo, pero un bot fiable vive en un servidor, registra lo que hace, maneja errores (reintentos, tiempos de espera) y te avisa si algo falla. Ese salto —de experimento a herramienta en la que confías— es donde más aporta un desarrollador. ¿Tienes una tarea que odias hacer a mano? Probablemente se pueda automatizar. Cuéntame cuál es y te digo cómo abordarla: contacto .
产品设计
Susan Kare: Designing Icons & Graphics For the Original Mac
submitted by /u/Successful_Bowl2564 [link] [留言]
AI 资讯
Building Distributed Systems in Elixir: Part 6 — Named Processes
In the previous part of this series, we built a tiny supervisor from scratch. When a worker crashed, the supervisor started a replacement. That replacement had a new PID: old worker -> #PID<0.102.0> new worker -> #PID<0.105.0> This reveals an important limitation of sharing PIDs as a public interface. A PID identifies one running incarnation of a process. It is excellent for sending a reply, setting up a monitor, or creating a link. It is not a stable address for a service that may stop and later be replaced. In this part, we'll use named processes to give a worker a discoverable address: :worker We'll build three small examples using: Process . register / 2 Process . whereis / 1 :global . register_name / 2 :global . whereis_name / 1 send / 2 No GenServer . No OTP Registry . The goal is to understand the lookup problem that registries solve before reaching for those abstractions. The PID-Sharing Problem Suppose one process starts a worker and gives its PID to a client: worker = spawn ( fn -> worker_loop () end ) send ( client , { :worker_started , worker }) The client can now send work directly: send ( worker , { :work , self (), "hello" }) This works while that particular worker process is alive. But process IDs are temporary. If the worker exits, the PID is no longer a route to the service: Client Worker holds #PID<0.102.0> #PID<0.102.0> | | | X exits | | send(#PID<0.102.0>, work) |------------------------------> no worker receives it Sending to a dead local PID does not raise an error and does not restart a process. The message is simply not delivered to a living worker. One answer is to tell every client about every new PID after a restart. That spreads lifecycle knowledge throughout the system. Another answer is to make clients depend on a name and resolve that name when sending. Registering a Local Name Our first worker waits for a stop message: defmodule Worker do def start do spawn ( fn -> receive do :stop -> :ok end end ) end end Starting it gives us a PID:
开发者
Modern Enterprise Architecture: Architecting for Outcomes • Simon Rohrer
submitted by /u/goto-con [link] [留言]
产品设计
The Ugly Truth About Linux Packaging: I Spent a Month Building a Screen Time Tracker
submitted by /u/ImpressGreen7325 [link] [留言]