AI 资讯
Externalized config & property-source order
Why your settings don't live in your code Every application has settings that change depending on where it runs. The database URL on your laptop is not the one in production. The port the app listens on might be 8080 locally and something else inside a container. The API key you test with is not the real one. Externalized configuration is the simple idea that these settings live outside your compiled code — in a text file, an environment variable, or a command-line flag — so you can change them without recompiling. You write the code once; the settings travel separately and get slotted in when the app starts. You meet this the first time you deploy a Spring Boot app. It runs fine on your machine, you ship the exact same jar to a server, and it picks up a different database — without a single line of code changing. This article is about how Spring pulls that off, and the one question that trips everyone up: when the same setting is defined in two places, who wins? Spring's first job: build one big lookup table Before your code runs, Spring goes hunting for settings. It looks in files, it reads environment variables, it scans the command line — and it pours everything it finds into a single key/value lookup. Spring calls this lookup the Environment . Think of it as one flat dictionary: you ask it for a key like server.port , and it hands back a value like 8080 . Every setting your app could possibly care about ends up in here, no matter where it originally came from. The most common place to put settings is a file named application.properties , which Spring looks for automatically: server . port = 8080 app . greeting = Hello from the properties file Each line is one key and one value. Once Spring has read this file into the Environment, any part of your app can ask for those keys. Reading a value: the two ways in The quickest way to pull a value out is the @Value annotation. You put it on a field, and Spring fills that field in for you as it builds the object: @Compon
AI 资讯
Perl 🐪 Weekly #789 - The impact of LLMs on Perl
Originally published at Perl Weekly 789 Hi there, The videos from the German Perl Workshop are available. They look very interesting, but not surprisingly many of them are in German. As you go through the list when you encounter one that you'd want to see if it was in English, let me know! I'll contact the speakers and I'll ask if they would be interested giving an English version of their presentation through the online Perl Maven events . This, of course, reminds me that we are going to have such an online presentation today. The title is Async, Type-Safe, and Secure: Perl's Answer to FastAPI and the presenter is Mohammad Sajid Anwar, the other editor of this newsletter who also runs The Weekly Challenge and does a tons of other things. You can still register. Before the presentation begins we are going to have 30 minutes for mingling. That is, you'll have the opportunity to introduce yourself and build connections. On our events page you can find the full list of Perl-related events we are aware of. There are a few in-person events and a few online events. Enjoy your week! -- Your editor: Gabor Szabo. Articles CPAN Uploads Are Up 50% Year-over-Year by Olaf Alders What is the impact of LLMs on the Open Source ecosystem in general and on Perl in patricular? Let's talk about our corner. DBI now has a minimum version of v5.12 AmberDB - An Embedded NoSQL Database Engine for Perl by Maruf Çetin AmberDB is a high-performance, schema-driven NoSQL database engine for Perl, featuring ACID transactions and precomputed inverted indexing on top of Berkeley DB (DB_File). AmberDB on MetaCPAN . Based on the AGENTS.md file it is being developed on MS Windows with the aid of LLMs. CVE-2026-18108: Net::SAML2 Authentication Bypass via Unsigned Encrypted Assertions (CVSS 9.8) Net::SAML2 provides SAML2 bindings and protocol implementation. This CVE along with a few others is already fixed . Discussion perl in cybersecurity? Should you learn Perl these days? What is the power of perl i
AI 资讯
Engineering a Digital Canon: Interactive Taxonomies for Over 40 Classical Zen Texts
Engineering a Digital Canon: Interactive Taxonomies for Over 40 Classical Zen Texts Preserving sacred literature and philosophical treatises online often suffers from poor structure, fragmented PDFs, and broken navigation. To solve this for classical Chan (Zen) Buddhism, we engineered chanzong.space (禅宗知识库) — a performant, open-access knowledge base built with Next.js 14, React 18, and D3.js. Whether you are studying the non-duality of the Platform Sutra or the intricate psychological analysis of Yogacara (唯识) mind theories, navigating multi-layered canonical texts requires modern web tooling. 🏛️ 1. Multi-Dimensional Canon Architecture Unlike a basic eBook reader, chanzong.space treats philosophical literature as a multi-relational graph: Foundational Classics (核心经典) : Platform Sutra (六祖坛经) : The fundamental teaching of direct seeing into one's true nature (自性顿悟). The Blue Cliff Record (碧岩录) : The pinnacle of Song Dynasty Koan commentary. Diamond Sutra (金刚般若波罗蜜经) : The ontological grounding of non-abiding mind (应无所住而生其心). Eight Verses on Eight Consciousnesses (八识规矩颂) : Master Xuanzang's indispensable guide to transforming consciousness into wisdom (转识成智). D3.js Dynamic Knowledge Graph : Spanning 500+ nodes (Patriarchs, Core Doctrines, Cultivation Methods, and Koans). Explore live in your browser: Global Zen Knowledge Topology . ⚡ 2. Technical Stack & Clean Typography To honor the contemplative nature of reading ancient texts, our frontend adheres to the rice-paper aesthetic ( bg-[#FAF9F6] ) paired with dark night sky navigation: Framework : Next.js 14 (App Router) + TypeScript + Tailwind CSS. Fast Search : Instant Ctrl+K global dialog searching across 40+ books, 160+ philosophical concepts, and 200+ koans. Vernacular Modern Commentary : Every chapter is paired with exclusive modern Chinese analysis and keyword glossaries, bridging ancient idioms into practical psychological insights. Offline Reliability : Full PWA Service Worker caching for distraction-free reading
AI 资讯
Programming as Theory Building
Picture, you join a new team working on a big system. Everybody who knew anything has left, either to find greener grass or to enjoy a well deserved pension. You and the team struggle to build new features for the system or to adapt functionality to match changes in legislation. Not to mention the trouble it is to figure out what to fix when things go wrong. At the same time, the business that you support is screaming for innovation and pushing for more and more changes. Recognize this situation? Ever experienced it yourself? A world full of legacy systems “Legacy. What is a legacy? It’s planting seeds in a garden you never get to see.” – Lin-Manuel Miranda, “Hamilton” Legacy, the thing that you are remembered for, typically the word has a positive meaning… how come that in tech the word “Legacy” has such a bad connotation? When we call out a legacy system, we usually mean: code without tests ( Michael Feathers ) or code you “got” from somebody else, or code that you’re scared to touch. However, there is a reason these legacy systems are still around. In almost all cases, that system still brings in money or is somehow still valuable. If it did not bring any value anymore, wouldn’t it be decommissioned? There must be something in these systems that makes them survive, where other systems did not. How systems become “Legacy” So legacy systems are those that have become hard or scary to change. In my experience, that not because something is wrong with the code or technology. The major contributing factor is usually that the knowledge about the system has left the organization. And then I don’t mean the documentation, but the people that built, maintained and ran the system. When those people are gone, you know that nobody else is going to be happy touching that thing. The value of software Code is like a mapping of desired real world behavior to a program that can be executed by a machine. So where is the value of a system, is that in that code? Over the past years I
开发者
Round Robin Is Lying to You: Equal Traffic Equal Load
> Your load balancer can distribute traffic perfectly and still overload a server. Here's the part of Round Robin we often overlook. Three servers. Six requests. Request 1 → Server A Request 2 → Server B Request 3 → Server C Request 4 → Server A Request 5 → Server B Request 6 → Server C Perfect. Every server got exactly two requests. So the load is balanced... right? Not necessarily. This is where a simple load-balancing diagram can hide a surprisingly important production problem: Equal traffic does not mean equal work. The Problem Isn't the Algorithm Round Robin is beautifully simple. You have three servers: A → B → C → A → B → C Each new request goes to the next server. For many systems, that's perfectly reasonable. The interesting part is what happens when the requests aren't equal. Imagine this traffic: GET /health POST /generate-report GET /profile POST /export-large-file GET /products POST /process-video Round Robin might still produce: Server A → 2 requests Server B → 2 requests Server C → 2 requests On paper: A = B = C In production: Server A ███░░░░░░░ 25% Server B █████░░░░░ 48% Server C █████████░ 91% Same request count. Very different workload. One Request Is Not One Unit of Work A health-check request might finish in a few milliseconds. Generating a large report could involve: multiple database queries significant memory CPU-heavy processing external API calls several seconds of execution To a basic Round Robin strategy, both are still: 1 request And that's the trap. We often think we're distributing load . What we're actually distributing is requests . Those are not always the same thing. Servers Aren't Always Equal Either There's another assumption hiding here. Imagine: Server A → 8 CPU / 16 GB Server B → 8 CPU / 16 GB Server C → 2 CPU / 4 GB Sending roughly 33% of traffic to each server probably isn't what you want. That's where Weighted Round Robin helps. A → Weight 4 B → Weight 4 C → Weight 1 The stronger servers receive more traffic. Better. But
AI 资讯
Blind Replay Before Merge: Keep Only the Agent Diff a Clean Environment Recreates
An agent-written patch that lives only inside one long chat session is not a reviewable change for merge. Hidden constraints from that conversation never reach the repository, the failing tests, or the next reviewer. A pairing session that wants a durable result should keep only the diff a second memory-free environment can recreate. The brief, not the transcript, becomes the source of truth for that recreation before anyone discusses merge. Chat windows quietly store rejected files, private service names, and half-stated architecture that later readers will never see. A senior pairing partner should treat that hidden context as contamination rather than as extra helpful memory for the model. The protocol below is a worked example of that stance, not a report of a named production incident. The two roles are a driver chasing an agent-assisted patch and a senior who refuses to merge from chat history alone. Pairing setup for a known failing test The shared codebase is a small HTTP service whose readiness probe still returns 503 under a test that already exists. The driver wants an assistant to edit the health handler and move on quickly. The senior wants a change that someone else could regenerate from the repository without the original thread. Work starts only after both people can describe done in file-level terms on disk. Until that description exists beside the code, every generated diff stays on a throwaway branch with no merge discussion. The pairing treats speed on the first attempt as optional and replayability on the second attempt as mandatory. That split is the whole method, and the rest of this article only makes it checkable. What the senior asked, written down immediately The senior did not open with a cleverer prompt or a longer system message for the same window. The senior demanded answers that a stranger could follow, then wrote those answers into the repository. The recorded questions targeted outcome, verification, blast radius, and isolation, no
AI 资讯
A counter in process memory is not a guard: 131 restarts proved it
Last week a reader left this on one of our articles, and I'm still turning it over: The counter lived in a module-level variable. The supervisor restarts that daemon on a stale-heartbeat rule, so the process died and respawned 131 times during those 24 hours. Every restart reset the counter to zero. The threshold of 3 was unreachable by construction — not degraded, never reachable. Her guard: escalate to a human after 3 consecutive failed self-heal rounds. Written in July, correct logic, process alive the whole time. The unit test passed. The heartbeat was fresh, the logs were flowing. And a human was never called, because the guard's only memory — how many failures in a row — lived in the process, and the process was not the thing being watched. It was the thing being restarted. The number that makes this its own failure shape: 0 escalations across 1,501 daemon starts. The two questions that both pass Earlier in that same thread we'd been arguing that a guard has two questions you can ask it: Does it catch the failure? Is it still running? Her case answers both yes — and the guard still cannot fire, ever. The unit test passes because nothing restarts in a unit test, so the reset never shows up. The process is "up" because the supervisor is doing exactly its job: respawning on stale heartbeat, forever, with no opinion about how often it has done so. It will run a crash loop until the heat death of the universe without ever deciding the loop is the failure. A counter that lives in a process cannot distinguish "this never happened" from "this happened, but I died and forgot." Every restart is a small amnesia. A supervisor that restarts you on a schedule is an amnesia machine. Put a threshold behind that memory and the threshold is a fiction. The tell is the ratio she quoted: escalations fired versus daemon starts. 0 over 1,501. Any guard whose numerator is zero over a large denominator is either genuinely never needed or structurally unreachable — and those two are wo
产品设计
I Built a Payment Reconciliation System That Broke on Leap Year
Payment reconciliation can look completely reliable until a calendar edge case exposes a hidden...
AI 资讯
Why I Prefer TypeScript Over JavaScript for Larger Projects
JavaScript is flexible, fast to start with, and supported everywhere on the web. For small scripts, quick experiments, and simple browser utilities, plain JavaScript is often enough. But as projects become larger, TypeScript starts to solve problems that JavaScript leaves entirely up to the developer. That is why I increasingly prefer TypeScript for anything beyond a very small project. The biggest difference is type safety JavaScript lets variables change type freely. For example: let khg5293UserId = 5293; khg5293UserId = "5293"; That is valid JavaScript. Sometimes this flexibility is convenient, but it also makes it easier for unexpected values to move through an application. TypeScript lets you define what a value is supposed to be: let khg5293UserId: number = 5293; Now assigning a string to khg5293UserId produces an error during development. That means certain mistakes are caught before the code ever runs. For small khg5293 experiments, this may not matter much. For a larger application with many files and components, it becomes much more valuable. Functions become easier to understand Consider a JavaScript function: function getProjectName(project) { return project.name; } There is nothing here telling us what project is supposed to contain. With TypeScript, the expected structure can be defined directly: type Khg5293Project = { name: string; language: string; public: boolean; }; function getProjectName(project: Khg5293Project): string { return project.name; } Now the function documents itself. A developer immediately knows what kind of object should be passed into it and what the function returns. This becomes especially useful when returning to a project after several weeks or working across a larger codebase. Interfaces make data structures clearer TypeScript also makes application data easier to reason about. For example: interface Khg5293Profile { username: string; projectCount: number; active: boolean; } const khg5293Profile: Khg5293Profile = { username:
开发者
Making a Python interpreter in 1024 bytes
submitted by /u/azhenley [link] [留言]
开发者
It took a year to ship WebAssembly in Anubis
submitted by /u/shadowh511 [link] [留言]
AI 资讯
The Hook System — Blocking AI Mistakes with Structure
This is chapter 4 of my book **Building Autonomous AI Agents with Claude Code * — a field guide to turning Claude Code from a coding assistant into an agent that remembers, verifies its own work, and knows when to stop. Everything below is from a system I actually run every day on one Windows PC.* 1. A Hook Is a Safety Mechanism Outside the AI A rules file is something the AI tries to follow ; a hook is something the system uses to make it be followed . This difference is bigger than it looks. Rules get buried as context grows longer, get skipped when things are urgent, and "just this once" exceptions pile up. Hooks don't do that. Point Timing Typical use UserPromptSubmit Right after the user types input Automatic context injection (record summaries, related rules) PreToolUse Right before a tool runs Blocking dangerous actions (gates) PostToolUse Right after a tool runs After-the-fact checks (contamination detection, follow-up procedure reminders) Stop When the response ends Quality gates (forbidden-word detection, verification requirements) Registration happens in one place, the settings file. { "hooks" : { "PreToolUse" : [ { "matcher" : "Write|Edit" , "hooks" : [{ "type" : "command" , "command" : "python C:/hooks/record_gate.py" }] } ] } } 2. Pattern A — The Blocking Hook (Gate) This is a gate that blocks "attempts to modify a file without reading the records first." What follows is a shortened version of one actually in use. import json , sys , time from pathlib import Path STATE = Path ( tempfile . gettempdir ()) / " read_state.json " REQUIRED = [ " memory/diary.md " , " memory/mistakes.md " ] payload = json . load ( sys . stdin ) # hooks receive the tool call on stdin tool = payload . get ( " tool_name " , "" ) if tool == " Read " : state = json . loads ( STATE . read_text ()) if STATE . exists () else {} state [ payload [ " tool_input " ][ " file_path " ]] = time . time () STATE . write_text ( json . dumps ( state )) sys . exit ( 0 ) state = json . loads ( STA
AI 资讯
From a Chocolate Wrapper to Concurrent InnoDB Page Splits
Here is a story [1] about the first version of B-link optimization for Innodb that is the most used B-tree engine in MariaDB. It started from a sketch on a chocolate wrapper and after some attempts ended up with significant p95 improvement for certain B-tree operations. Thx Zhao Song for his work in this area for MySQL. 1. https://mariadb.org/from-a-chocolate-wrapper-to-concurrent-innodb-page-splits/ submitted by /u/drrtuy-b [link] [留言]
开发者
Which programming “best practice” do you think is actually wrong?
submitted by /u/stagas [link] [留言]
AI 资讯
I killed the process and the drain still hung: a grandchild held the pipe
A program of mine hung for forty minutes. Not spinning at a thousand loops a second: at zero percent CPU . It wasn't doing too much work; it wasn't doing any work at all. And still it wouldn't finish. The program does something common: it orchestrates external command-line tools. It launches one, reads what it writes to standard output, and moves on to the next when it's done. So it doesn't get stuck when a tool drags, each one has a timeout: when it fires, the process is killed and we carry on. That's the part that failed, and it failed where no one looks: after killing the process. Killing the process doesn't close the pipe When you read a subprocess's output, you read from a pipe : one end writes (the subprocess), the other reads (you). Your reader doesn't finish when the subprocess dies. It finishes when EOF arrives, and a pipe's EOF arrives only when the last write end is closed. Almost always they coincide: the subprocess is the only writer, it dies, its end closes, EOF arrives, your reader finishes. All in microseconds. But "almost always" isn't "always". The tool I launched launched another one in turn —a grandchild—. And that grandchild inherited the pipe's write end, because on Unix a child inherits its parent's open descriptors unless told otherwise. So when the timeout fired, I killed the child. Its end closed. But the grandchild was still alive , with its copy of the descriptor open. The last write end hadn't closed. EOF never came. And my reader sat waiting for an EOF that would never arrive —at zero percent CPU, blocked in a read() , indistinguishable from slow work—. The symptom that deceives What makes this failure so hard to see is that it doesn't look like a failure . An infinite-loop hang burns CPU: you see it in top instantly. This one spends nothing. The thread is asleep in the kernel waiting for data that isn't coming. In the process list it looks healthy. In the metrics it looks like it's "taking a while". The only way to tell "hung forever"
AI 资讯
Multimodal Transformers: How LLMs Learn to See
Hello, I'm Shrijith Venkatramana, and I'm building LiveReview — a blast-radius aware AI code review built for your business-critical systems. Star us to help devs discover the project, give it a try, and share your feedback to help improve the product. A language model can write Python, explain quantum mechanics, and imitate Shakespeare. Show it a screenshot of a production dashboard, however, and suddenly the central question becomes: How does a transformer that was trained on text learn what a pixel means? The naïve answer is: “Give the image to the LLM.” That description hides almost all of the interesting engineering. Modern multimodal systems are usually compositions of several models: a vision encoder turns pixels into vectors, a connector translates those vectors into something the language model understands, and the LLM then reasons over the resulting representation alongside ordinary text tokens. That architectural trick has turned the transformer from a language architecture into something much closer to a general-purpose interface for heterogeneous data. The evolution is worth understanding because it reveals a useful engineering pattern: you often do not need to retrain a giant model to give it a new sensory modality. You need a good representation and a sufficiently expressive interface between representations. 1. The basic mental model: pixels become tokens Start with an ordinary LLM. Its input looks conceptually like: "The server returned HTTP 500. What should I check?" | v tokenizer | v [t1, t2, t3, ..., tn] | v Transformer | v answer Everything is eventually represented as vectors. Multimodal transformers exploit this fact. An image is first converted into a sequence of vectors: image | v vision encoder | v [v1, v2, v3, ..., vm] | v multimodal connector | v [z1, z2, z3, ..., zk] | +------ text tokens [t1, t2, ...] | v LLM | v answer The important conceptual shift is this: The LLM does not have to understand pixels directly. It only has to understand
开发者
Continued Fractions And Lattice Sieving
submitted by /u/DataBaeBee [link] [留言]
开发者
Modding a 20-year-old game to make it even better (part 2!)
submitted by /u/HHalo6 [link] [留言]
AI 资讯
I Replaced a $40/mo PDF API with 200 Lines of Web Worker Code — Here's the Offline Invoice Tool I Built
The bill that started this I was paying $40/month for a PDF generation API to power a tiny internal invoicing tool for a client project. Forty bucks a month to convert some JSON into a PDF. That's it. That's the whole service. I finally sat down on a Saturday to see if I could kill that subscription. Three weekends later, not only did I kill it — the replacement is faster than the API ever was, because there's no network round-trip at all. This post is the log of how it went, in the order I actually hit the problems, not the order that makes me look competent. Attempt #1: jsPDF on the main thread (it worked, until it didn't) First pass was the obvious one — jsPDF running directly in the click handler: function generateInvoice ( data ) { const doc = new jsPDF (); doc . text ( data . clientName , 20 , 20 ); data . lineItems . forEach (( item , i ) => { doc . text ( ` ${ item . description } — $ ${ item . amount } ` , 20 , 40 + i * 10 ); }); doc . save ( ' invoice.pdf ' ); } Fine for a 3-line invoice. Once I tested with a 40-line-item invoice (a real client sent me one to test against), the tab froze for almost two full seconds. Not crashed — frozen. Scroll didn't work, buttons didn't respond, and on a mid-range Android phone it was closer to five seconds. The main thread doing synchronous PDF math while also being responsible for painting the UI is exactly the kind of thing that looks fine in a demo and falls apart the moment a real user pastes in real data. Attempt #2: move it to a Web Worker Web Workers get talked about like they're this exotic tool for WASM and video processing. They're also just... a really good fit for "expensive synchronous work that a user is waiting on." I'd never reached for one before this project, mostly out of habit. The tricky part isn't the worker itself, it's that jsPDF assumes it has access to document and window in a couple of code paths (font metrics, mostly), which don't exist inside a worker. I ended up switching to pdfkit compiled
开发者
Wird BASIC noch benutzt?
Ich höre überall nur noch von Python als Einführungssprache. Gibt es noch BASIC-Programmierer? submitted by /u/Puzzleheaded-Half993 [link] [留言]