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

标签:#software

找到 275 篇相关文章

AI 资讯

The Illusion of the Clean Slate

Every engineer has fantasized about it: starting over. Throwing out the old system and building something clean. No legacy constraints. No accumulated compromises. Just pure, intentional design. It never works that way. You can delete all the code. You can architect from scratch. You can make the best technical decisions possible. But you can't delete the organizational memory. You can't unlearn what the last system taught you. You can't escape the patterns that already run through the business, the workflows people have shaped themselves around, the problems you've already paid the cost of understanding. The new system will look clean. But it will be haunted. What rewrites actually inherit A rewrite isn't a fresh start. It's archaeology pretending to be innovation. The constraints don't go away. The old system wasn't overcomplicated because engineers were bad. It was overcomplicated because of customer requirements, regulatory expectations, performance demands, and edge cases that took years to discover. A fresh rewrite finds all those edge cases again. Slower this time, because you don't have documentation—you have broken customers and escalations. The system gets layers of protection again, but now it looks like paranoia instead of learned caution. The organizational memory becomes invisible. Someone fought for that data model three years ago. There was a reason. A business rule that couldn't be violated. A data consistency requirement that cost a quarter to figure out. The new system doesn't have the battle scars that explain why things are the way they are. So they get rebuilt differently, until they hit the same requirement at 2am on a Saturday. The workflow is already baked in. Users have shaped their behavior around the old system. Sales has built their pitch around certain capabilities. Support has written documentation and runbooks. Customers have automation that depends on specific behaviors. The new system is technically cleaner, but it forces change on

2026-06-30 原文 →
AI 资讯

AI เขียนโค้ดแทนเราได้แล้ว — แล้วเราจะเหลืออะไรให้ทำ?

AI เขียนโค้ดแทนเราได้แล้ว — แล้วเราจะเหลืออะไรให้ทำ? มีประโยคที่ได้ยินบ่อยขึ้นทุกวัน: "เดี๋ยวนี้ใครยังไม่ใช้ AI ช่วยเขียนโค้ดบ้าง?" คำตอบคือ — แทบไม่มีแล้วครับ ตั้งแต่ GitHub Copilot, Cursor, Claude, ChatGPT ไปจนถึง agent ที่เขียนโค้ดเองได้ทั้ง project — เราใช้ AI ใน level ที่ต่างกัน: Level หน้าตา ตัวอย่าง 🎵 Vibe Coding พิมพ์สิ่งที่อยากได้ กด accept อย่างเดียว "เขียนหน้า login ให้หน่อย" → กด tab tab tab 🧩 Prompt-Guided คิดก่อน ถามทีละส่วน ตรวจทุกอย่าง "สร้าง UserService ที่ใช้ bcrypt hash password" 🛠️ Skill/Lint-Guided ใช้ AI เป็น editor ชั้นสูง — lint, refactor, test "refactor function นี้ให้เป็น table-driven test" 🏗️ Agent-Based ให้ AI run ทั้ง project — spawn subagent, PR, deploy "พอร์ต microservice นี้จาก Express ไป Fastify" แล้วคำถามคือ — ถ้า AI ทำทั้งหมดนี้ได้ แล้วมนุษย์อย่างเราเหลืออะไร? Unit Test — ตัวอย่างที่เห็นชัดที่สุด ลองดู unit test ที่ AI เขียนให้: // 🤖 AI-generated test func TestCalculateDiscount ( t * testing . T ) { tests := [] struct { name string input float64 expected float64 }{ { "zero" , 0 , 0 }, { "normal" , 100 , 90 }, // 10% discount { "max" , 1000 , 800 }, // 20% discount } for _ , tt := range tests { t . Run ( tt . name , func ( t * testing . T ) { result := CalculateDiscount ( tt . input ) if result != tt . expected { t . Errorf ( "got %v, want %v" , result , tt . expected ) } }) } } ดูเผิน ๆ — สวย, table-driven, ถูกต้องตาม Go convention 1 แต่ถามหน่อย — test นี้บอกอะไรเกี่ยวกับ business? "ส่วนลด 10% สำหรับยอด 100 บาท" — ทำไมต้อง 100? เป็นกฎจากที่ไหน? "ส่วนลด 20% เมื่อยอดถึง 1000" — แล้วถ้าลูกค้าเป็น member ได้เพิ่มอีก 5% ล่ะ? input: 0, expected: 0 — test นี้ cover edge case หรือแค่ cover บรรทัด? AI test ได้ถูกต้องตาม function — แต่มัน ไม่รู้ว่า business จริง ๆ คืออะไร AI ไม่รู้ Business Context — และจะไม่มีวันรู้ นึกภาพระบบ e-commerce: ลูกค้าซื้อสินค้า → ระบบตัดสต็อก → คำนวณส่วนลด → คิดค่าส่ง → ออกใบเสร็จ AI แยก test ทีละ function ได้: ✅ TestDeductStock — "ตัดสต็อก 1 ชิ้น" ✅ TestCalculateDiscount — "ส่วนลด 10%" ✅ TestCalculateShipping —

2026-06-30 原文 →
开发者

🚀 Build Your First Space Shooter Game with Limn Engine

🚀 Build Your First Space Shooter Game with Limn Engine A Complete Step-by-Step Tutorial for JavaScript Beginners Welcome! In this tutorial, you'll build a complete space shooter game using Limn Engine — a zero‑configuration 2D game engine that runs in your browser. What you'll build: A spaceship that moves, shoots bullets, fights waves of enemies, and keeps score. All in about 100 lines of code . By the end, you'll understand: How to create a game loop How to handle keyboard input How to detect collisions How to use particles for visual effects How to manage game state (lives, score, game over) 🎮 Want to play the finished game? Click here to play Space Shooter Live! Before We Start What You Need A text editor (VS Code, Notepad, or any code editor) A web browser (Chrome, Firefox, Edge) Limn Engine — download epic.js from limn-engine-doc.vercel.app What You Should Know Basic JavaScript (variables, functions, arrays, if-statements) How to open an HTML file in a browser No game development experience required! Step 1: The HTML Structure Every Limn Engine game starts with a simple HTML file. <!doctype html> <html> <head> <script src= "asset/epic.js" ></script> </head> <body> <script> // All your game code goes here </script> </body> </html> What's happening: <script src="asset/epic.js"> — loads the Limn Engine library Everything inside the second <script> tag is your game code Save this as game.html and open it in your browser. You should see a blank canvas with a blue gradient background. Step 2: Setting Up the Game The first thing we need is a Display — this is the engine that creates the canvas, runs the game loop, and handles input. const display = new Display (); display . perform (); // Activates performance mode (dual-canvas rendering) display . start ( 800 , 600 ); // Creates an 800×600 canvas What's happening: new Display() — creates the engine display.perform() — turns on high-performance mode display.start(800, 600) — creates a canvas 800 pixels wide and 600 p

2026-06-30 原文 →
AI 资讯

The Bridge Looked Fine Too

This is the fourth post in Craft & Code , a short Friday series about what carpentry can teach us about AI, skill and the future of software. Last week I worried about where the next generation's judgement will come from. This week, why we may not notice it is missing until it is too late. My father built me shelves in an alcove when I was small, and I mentioned in the first post that they may still be there for eternity. The other side of that story is the one every household knows: the shelf that is not quite right. The one that sags under a row of books, or sits a degree off true so that anything round rolls gently to one end. You do not need to be a carpenter to see it. A bad joint, a door that will not close, a shelf that dips — the material tells on the maker, immediately and to everyone. That is the comforting version of the analogy, and the one I expected to write: carpentry is honest about its failures because they are visible, while software can look polished and be rotten underneath. A wonky shelf looks wonky; bad software looks finished. It is a tidy line, and there is real truth in it. But it is only half the truth, and the more interesting half should worry us — because the moment you go up from a shelf to a serious piece of engineering, the comfort falls away completely. Consider two of the most admired structures of the last century. The Tacoma Narrows Bridge was designed by one of the leading suspension-bridge engineers of his day: elegant, slender, celebrated. It opened in the summer of 1940 and tore itself apart in the wind that November, twisting like a ribbon because the design had not reckoned with how the deck would behave aerodynamically. Nobody had seen a wonky bridge; it looked magnificent. The flaw was real, fundamental, and invisible until the wind found it. The Citicorp Center in New York, finished in 1977, was a triumph of structural engineering, raised dramatically on great columns at the midpoints of its sides. Only after it was compl

2026-06-29 原文 →
AI 资讯

The 3-line discipline

When I write code in unfamiliar territory, I write three lines, then I run it. Then I write three more lines, and I run it again. I've been doing this for twenty-four years. It's the most specific habit I have. I almost didn't write this article, because the habit feels too small to be worth describing — but then I noticed that it's the part of my way of working that I can never seem to explain to someone in real time. It needs writing down. Three principles The discipline rests on three things I believe about writing code. They're not deep. They've just stayed with me. 1. Trust nothing but your own code. If you can't trust the code you wrote yourself, what can you trust? Not a library, not a vendor's documentation, not your own assumption from yesterday. The only thing in the system whose behavior you can fully verify is the code you just typed, by running it. 2. Write in code, not in language. If you're describing what the code should do in Japanese or English, you're spending the same time you could have spent writing the code itself. By the time the code runs, the description is already done — by the code, in a more precise form than any language could give it. 3. Make three lines complete. The three lines you just wrote should be complete. Error handling included. Validation included. Logging included. Not "I'll add validation later." Not "I'll wrap it in a try-catch later." Three lines, complete, then run. (There's a small exception to this. Sometimes you do want to ignore every error and move on — for instance, when you're trying to understand whether the happy path works at all before you care about anything else. That's a different mode, used deliberately. It's not the same as "I'll handle errors later.") Why three lines Three lines is roughly the unit of thought I can hold completely. Five lines, and I start guessing what the third line did. Ten lines, and I'm reading the code as if it were someone else's. Three lines is the size that stays mine. When thre

2026-06-29 原文 →
AI 资讯

Three Questions I Ask Every System. Most Design Reviews Skip All Three.

The design doc is fourteen pages. Clean service boundaries, thoughtful API contracts, a deployment story that handles rollback without incident. Six months of work. The team is proud of it, and the work is genuinely good. Three questions will tell more about this system than all fourteen pages. Not questions about implementation details or technology choices. Questions about how the system was designed to age, to fail, and to be understood by someone who didn’t build it. Most architecture conversations never reach these questions, which is part of why the gap between a good system and a great one is often invisible until it is suddenly very visible. What does this make hard? Good architecture conversations focus on what a design enables: faster deployments, independent scaling, and clearer ownership. The question that separates architectural thinking from implementation thinking is the inverse . What does this make hard? Every decision forecloses options. The service boundary that gives teams autonomy makes cross-service transactions expensive. The data model that reads cleanly under expected load makes certain write patterns awkward. The abstraction that simplifies onboarding makes some categories of refactoring nearly invisible as possibilities. These are not arguments against the decisions. They are the other side of every decision, and that other side exists whether or not anyone names it. The design doc that holds up over time is not the one where nothing is difficult. It is the one where the difficult things are named. “This approach makes distributed transactions impossible, and here is why we have decided to accept that constraint.” That sentence, or something close to it, belongs in every significant architecture document. Its absence is not a sign that the constraint wasn’t considered. Often it was. But without the name, the constraint becomes invisible to everyone who wasn’t in the room, which eventually includes the original team. When joining a system s

2026-06-29 原文 →
AI 资讯

PDF::Make - PDF Generation, Extraction and Modification.

I’ve always been fascinated by PDFs. They look simple on the surface. Just a document you can open anywhere but underneath they’re a full layout engine, object graph, drawing model, and archival format all at once. I enjoy that mix of precision and complexity and that is exactly what led me to build PDF::Make (and yes I had some help from Claude LLM). I wanted a fully featured toolkit that could both generate PDFs and let me inspect/edit them programmatically. At the low level, PDF::Make exposes the raw building blocks of the format: PDF objects, pages, the drawing canvas, a parser/reader, and import/merge primitives. This is the layer you reach for when you need fine grained control or want to work with the structure of a document directly. For everyday document creation, PDF::Make::Builder sits on top of that foundation and provides a higher level API. It handles the boilerplate of page setup, fonts, text flow, and layout so you can produce a polished PDF in just a few lines of Perl. The same toolkit is also designed for post-processing. You can open an existing PDF, extract structured text along with its coordinates, and then draw annotations or overlays back onto the page, making it straightforward to build review, QA, or markup workflows on top of documents you didn’t originally generate. This post shows a practical two-step flow: Create a PDF Re-open it, extract text coordinates, and draw border highlights around matched words 1) Create a PDF with PDF::Make::Builder Script: #!/usr/bin/perl use strict ; use warnings ; use PDF::Make:: Builder ; my $pdf = PDF::Make:: Builder -> new ( file_name => ' source_demo.pdf ', configure => { text => { font => { family => ' Helvetica ', size => 12 , colour => ' #222222 ' }, }, }, ); $pdf -> add_page ( page_size => ' Letter ') -> add_h1 ( text => ' PDF::Make blog demo ') -> add_text ( text => ' PDF::Make builds and edits PDF files directly from Perl. ') -> add_text ( text => ' In the next step we extract text coordinates and

2026-06-28 原文 →
AI 资讯

The System Design Framework I Used to Solve 100+ Problems

Hello Devs, for months, I felt confident about system design interviews. I'd watched endless YouTube videos. I'd studied architecture diagrams. I could explain how Netflix builds recommendation systems. I understood Kafka, Redis, load balancers, and microservices. I'd memorized the designs of Twitter, Uber, YouTube, and TinyURL. Then I sat down for my first real system design interview and froze. The interviewer asked: "How would you design a notification system?" I had memorized notification systems. I knew about push notifications, email queues, delivery workers, and retry logic. I could recite architectural patterns. But suddenly, none of that helped. I didn't know which questions to ask first. I started designing before understanding the actual requirements. I built architecture for problems that didn't exist. I missed obvious bottlenecks. I couldn't articulate why I made specific trade-offs. When the interviewer pushed back, I had no framework to adjust. I failed that interview. But that failure taught me something crucial: System design interviews aren't about knowing technologies. They're about knowing how to think. After that, I went back and systematically practiced 20 system design problems. Not passively watching solutions. Actually designing. Making mistakes and refining my approach. And somewhere around problem 12, a pattern emerged. The best candidates didn't know more technologies than anyone else. They had a framework . They asked the same questions in the same order. They structured their thinking consistently. They could handle curveballs because their framework was flexible. They reasoned through trade-offs explicitly. Here's the framework that finally made it click for me. The Problem with Memorization Before I share the framework, let me explain why memorizing designs fails. When you memorize " How to Design Twitter," you learn: Use relational databases for users and tweets Use NoSQL for timelines Cache with Redis Use message queues for fanout S

2026-06-27 原文 →
AI 资讯

SEO Services for Developers: What Actually Matters in 2026

Most developers treat SEO like that one dependency you know you need but keep putting off. You build a fast, clean site with solid architecture, then hand it off to a "marketing person" who asks you to add keyword-stuffed meta descriptions. Here's what changed in 2026: search engines place heavy emphasis on Core Web Vitals, which measure loading performance, interactivity, and visual stability of web pages. The technical foundation you're already building? That's 80% of modern SEO. Let me break down what actually matters when evaluating SEO services as a developer. The Technical Reality Check Technical SEO is the foundation that everything else sits on. On-page optimization and link building amplify a technically sound site. Applied to a technically broken site, they produce unpredictable, often disappointing results. If an SEO service can't speak your language about INP metrics, structured data, or mobile-first indexing, run. What Dev-Focused SEO Services Should Cover Core Web Vitals (Not Just PageSpeed Scores) Core Web Vitals (LCP, CLS, INP) are confirmed ranking factors — INP replaced FID in March 2024. Any SEO service still talking about First Input Delay is using outdated information. What to look for: Field data analysis from real users (not just lab tests) Specific fixes for Interaction to Next Paint Understanding of when to optimize vs. when to rebuild Crawlability and Rendering Google now clarifies that pages returning non-200 status codes (like 4xx or 5xx) may be excluded from the rendering queue entirely. If you're running a JavaScript-heavy framework, this matters. Red flag: SEO services that don't understand Server-Side Rendering (SSR) or Static Site Generation (SSG). Structured Data Implementation Structured data helps search engines understand what your content is about, not just what it says. In 2026, this matters for traditional search and AI search alike. Schema markup isn't just about rich snippets anymore. It's how AI systems like ChatGPT and Per

2026-06-27 原文 →
AI 资讯

Tests Pass, Design Breaks: Why TDD Can't Hold the Line on Design Intent

There is a popular misconception that if you do TDD, your design also stays correct. That if the tests pass, quality is guaranteed. In AI-assisted development, this misconception is the kind that quietly accumulates — the more tests you have, the more invisible damage builds up underneath. All tests passed. The design was still broken. Here is what happened today. A function called safe_post.py had its signature changed. Two arguments — notify_sh and doctor_sh — were removed. The test suite passed in full. But the callers were still using the old signature. They were silently broken. Why did the tests pass? Because the test code itself was using the old signature. The tests had been written (by AI) at a time when the design intent was already misunderstood. The misunderstanding was baked into the tests from the start. Tests passing and the design being correct are two different things. "All tests pass" tells you only one thing: the implementation matches what the tests expect. Whether the tests express the right design intent is a separate question. TDD verifies "implementation against tests" — nothing more Let me restate the TDD definition. Red → Green → Refactor. Write a test. Write the implementation that passes the test. Refactor. In this loop, what the test verifies is whether the implementation meets the test's expectation. That is one verification — and only one. What TDD does not verify is whether the test itself correctly expresses the design intent. The structure looks like this: Design intent → Tests (← this link is not verified) ↓ Implementation (← this link is verified by tests) If the person writing the tests misunderstands the design intent, the tests will pass and the design will still be wrong. Machine learning engineer Hamel Husain calls this the "Gulf of Specification" — the gap between what you intended to measure and what your metric actually measures. Optimize hard against a flawed metric and you optimize hard in the wrong direction. The same d

2026-06-27 原文 →
AI 资讯

Left of the Loop: The Ever-Agreeing Genie

Anthropic's engineers ship eight times more code than they did a few years ago. And they had to start scheduling lunches so people would talk to each other. Fiona Fung, who leads the Claude Code team, said it on Lenny's Podcast last week. Working with agents all day had started to feel isolating. The team was fast, but they'd stopped running into each other. So they added pairwise programming lunches and hackathons — rituals to put back the thing that used to happen on its own. Eight times the output. Scheduled conversation. That ratio is worth sitting with. Whatever goes missing here doesn't show up in the metrics. It doesn't throw an error. It just quietly stops being available. Here's the part that bugs me most. Ask an AI whether your approach is sound and it mostly tells you it is. Not because it's lying — because it's answering the prompt. No stake in the outcome, no history with the system, no memory of the last three times this exact idea was tried and quietly failed. A colleague pushing back is a different thing. They've got context you never typed into the window, because they were there when it was earned. They're going to maintain this too. They might be wrong — but wrong in a direction you hadn't thought of. An agent can't disagree with you like that. It agrees faster. Same with scope. The agent builds what you ask for, all of it, thoroughly. It won't mention that the third feature is the one nobody will use, or that "good enough" happened two iterations ago, or that something next door already solves most of this. Knowing when to stop comes from someone who's watched a codebase rot under a hundred individually-reasonable decisions. And it only knows what you put in front of it. The person who worked on payments remembers the edge case you're about to recreate. The junior who joined three months ago still sees the thing everyone stopped noticing. That gap — between what's in the window and what isn't — is where the expensive mistakes live. Then the part

2026-06-27 原文 →
AI 资讯

Left of the Loop: The End of the Craftsman?

I noticed something a few months ago. I was talking less to my colleagues. Not because anything was wrong. I had a question, I described it to an AI, I got something useful back. Why loop in a human if the loop is already closed? It took a while to name what was actually happening. There's a version of the AI story where the interesting work disappears. The agent implements. The spec session produces the plan. Humans review the output. What's left? Ticket hygiene and rubber stamping. Engineering as a series of approvals. I think that's wrong. But I understand why it feels true. Here's what I think is actually happening instead. The agent produces the increment. But the agent doesn't decide what the increment should move toward. It doesn't know whether this library is the right bet for the next three years. It doesn't know which of two implementation approaches leaves options open and which quietly closes them. It doesn't know whether the architectural call made today creates a problem nobody will notice until the system is under load eighteen months from now. That work — giving the project direction, validating trade-offs, deciding what the system becomes — isn't specable. You can't write a ticket for it. And it's not going away. The craft didn't disappear. It moved. Direction is the word I keep coming back to. The agent executes well. It implements against a spec. It generates options when you ask for them. But it doesn't carry a point of view about where the system should go. It doesn't have a stake in the decision. It will implement the wrong architectural direction just as confidently as the right one, if that's what the spec says. Someone has to hold the direction. Someone has to know enough about the codebase's history, the team's constraints, and the product's trajectory to say: not that library, we've been down that road. Not that pattern, it doesn't survive the load we're heading toward. This approach now, that refactor later, in this order, for these reaso

2026-06-27 原文 →
AI 资讯

Left of the Loop: A Fool with a Tool is Still a Fool

"A fool with a tool is still a fool." — often attributed to Grady Booch I keep coming back to this quote when I watch teams adopt AI. In my last post ( https://schrottner.at/2026/06/18/The-Wrong-End-of-the-Problem.html ) I wrote about shifting the engineering process left — spec sessions, autonomous agents, humans reviewing output rather than writing it. A few people asked the obvious follow-up: if an agent implements and an AI reviews, why do I need a team at all? It's a fair question. And I think the answer is in that quote. The agent validates against your prompt. That's it. If your thinking is muddled, the output will be muddled — just faster and at greater cost. An agent doesn't tell you that you're solving the wrong problem. It solves whatever problem you gave it, thoroughly and without complaint. Most AI usage right now treats AI as a tool. Which means the quality of the output is bounded by the quality of the thinking that went into the prompt. A fool with a tool is still a fool. The tool just makes the foolishness more expensive. The team is the check on intent. Not after the agent has burned three sprints on the wrong thing — before it starts. That's what mob planning actually is, when you think about it. Not a meeting. Not process overhead. It's the place where bad ideas get caught before they get expensive. Where someone asks "wait, why are we building this" before an agent runs with it for a week. But there's something else happening in that room that I think gets underestimated. It's where the learning happens. Not just prompting. System thinking. Architectural patterns. How to decompose a problem. Why a certain approach fits this codebase and another doesn't. How a senior frames a problem before an agent ever touches it — the mental model that makes the output actually good. Right now that knowledge isn't transferring. Everyone is heads-down with their own tools, developing their own habits in isolation. Engineer A gets dramatically better output than

2026-06-27 原文 →
AI 资讯

AI writes code in seconds. Architecture debt takes months to notice.

One thing I've noticed after using AI for development over the past year is this: The code it generates is usually correct. The architecture slowly isn't. That doesn't happen because AI writes bad code. It happens because architecture rarely erodes all at once. Imagine a modular application with clear boundaries. The billing module talks to the orders module through its public interface. Authentication is isolated. Notifications are independent. Everything is predictable. Now imagine hundreds of AI-assisted commits over the next few months. One suggestion imports an internal class because it already exists. Another bypasses a service layer because it's shorter. A helper gets copied into another module. A database query is duplicated instead of reused. None of those changes are catastrophic. In fact, every pull request probably gets approved. The application still builds. The tests still pass. Customers never notice. Until one day, making a simple change requires touching five different modules because everything has quietly become connected. That's architecture debt. And unlike a failing test, it doesn't show up immediately. One thing I've realized is that our current tooling doesn't really watch for this. Unit tests verify behavior. Integration tests verify interactions. Linters enforce style. Static analysis finds bugs. All of those are important. But none of them are asking questions like: Should this module depend on that one? Did someone bypass a defined boundary? Are we introducing new architectural coupling? Is the overall architecture getting healthier or worse over time? Those questions usually get answered during code review. Or worse, during a production incident. The interesting part is that AI isn't really the problem. If anything, it's doing exactly what we ask it to do. It optimizes for solving the problem in front of it. Architecture, on the other hand, is about protecting the system as a whole. Those are different goals. As AI makes us write code fa

2026-06-27 原文 →