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

标签:#dev

找到 2938 篇相关文章

开发者

You Don't Need Node.js to Learn Web Development

I see this every week. Someone decides to learn web development. They Google "how to start web development" and within 20 minutes they're installing Node.js, npm, VS Code, and five extensions they don't understand. They haven't written a single line of code yet. But they've already spent an hour configuring their "environment." Then they get stuck. Node version conflicts. npm permission errors. VS Code extensions that break their syntax highlighting. They think they're not smart enough for programming. They are. They just started with the wrong step. The Problem Learning web development has three core technologies: HTML, CSS, and JavaScript. That's it. Everything else — Node.js, npm, webpack, Vite, React — is extra. It's not the starting point. But most tutorials assume you already have Node.js installed. They say "open your terminal" and "run npm install." Beginners follow along, copy the commands, and have no idea what any of it means. Here's what actually happens: You install Node.js (200MB+) You install VS Code (another 300MB+) You install 5-10 extensions You create a project folder You open terminal and run npm init -y You run npm install live-server You run npx live-server You finally see your HTML page in a browser That's 8 steps before you write Hello World . The Solution You don't need any of that. Not yet. Here's what you actually need to learn HTML, CSS, and JavaScript: A browser (you already have one) A text editor (Notepad works) That's it Open Notepad. Write this: <!DOCTYPE html> <html> <head> <title> My First Page </title> </head> <body> <h1> Hello, World! </h1> <p> This is my first web page. </p> </body> </html> Save it as index.html. Double-click the file. It opens in your browser. You just built your first web page. No terminal. No npm. No Node.js. No configuration. When Should You Actually Learn Node.js? Node.js becomes useful when you need: Server-side code (backend development) Package management (npm packages) Build tools (webpack, Vite) Framew

2026-07-15 原文 →
AI 资讯

Hetzner was cheaper at every size I tested and I still chose managed Postgres

Twelve pricing tabs open. Neon, Hetzner, Supabase, Prisma, Scaleway, OVH. My database is half a gigabyte. I was comparing ten-terabyte price curves. At some point this week I typed the words "I am super lost here" about my own infrastructure. I advise companies on this exact class of decision. That sentence still came out of my hands. If you have ever spent an evening deep in provider pricing pages for a workload that fits on a USB stick from 2009, this one is for you. All numbers below come from the live pricing pages as of July 2026. Rates move, so verify before you commit. Three fears, all pointed at the wrong layers I went in worried about getting attacked, running out of space, and being locked in. All three dissolved under ten minutes of honest reading. DDoS lands on the website edge, not the database. My site already sits behind Cloudflare and Vercel, and a database is never publicly exposed. Only the app talks to it. Whichever provider I picked, that attack surface stayed identical. Here is the shape of the stack, and where each fear lives. MANAGED (what I run today) visitors ──> Cloudflare edge ──> Vercel app ──> managed Postgres [DDoS absorbed] [stateless] [never public, app-only access, provider patches, provider backups, provider on-call] SELF-HOSTED (the alternative I priced) visitors ──> Cloudflare edge ──> Vercel app ──> Hetzner CAX11 [DDoS absorbed] [stateless] [Postgres :5432 firewalled to app, SSH hardened, fail2ban + auto- patching = MINE] │ pg_dump every 6h ▼ encrypted ────> Cloudflare R2 [off-site copies] Same edge, same app, same attack surface. Everything in the right-hand box is what changes owners. Storage was a rounding error. My data is 0.5 GB. Even the cheapest self-hosted box includes 40 GB, eighty times headroom before the first extra cent. Lock-in was a phantom too. Managed Postgres is still stock Postgres. Exiting means a dump, a restore, and one connection string change in the deployment environment. Minutes of cutover, no rewrite an

2026-07-15 原文 →
AI 资讯

LingoBridge-AI: Simplifying Complex Medical Reports for Rural Patients

Body: ​Hi everyone! 👋 ​I am excited to share my latest project, LingoBridge-AI, which I have been building to solve a critical problem in rural healthcare. ​The Problem 🩺 ​In many rural areas, patients receive medical reports that are complex and filled with technical jargon. Due to this, they often struggle to understand their own health conditions, which leads to confusion and delayed medical care. ​The Solution: LingoBridge-AI 💡 ​I developed LingoBridge-AI, an AI-powered tool designed to: ​Simplify complex medical reports into easy-to-understand language. ​Translate information into local languages to ensure better accessibility for patients. ​Bridge the gap between healthcare providers and patients who have limited medical literacy. ​Tech Stack 🛠️ ​Built using Python and AI frameworks. ​Focuses on accuracy, simplicity, and user-friendly output. ​Check it out! 💻 ​You can view the source code and documentation here: 👉 [ https://github.com/cherukuriLakshmi/LingoBridge-AI ] ​I am still working on improving this, and I would love to get some feedback from this amazing community! If you have any suggestions on how to improve the AI or the user experience, please let me know in the comments below. ​Thanks for your support! ​Tags (Add these at the bottom): ai #healthtech #opensource #python #beginners

2026-07-15 原文 →
AI 资讯

What a Vibe Coding Security Scanner Can (and Cannot) Tell You

AI-assisted builders can take an idea from prompt to production in a weekend. That speed is useful, but it also compresses the part of the process where someone normally reviews deployment settings, browser-visible secrets, authorization boundaries, and recovery plans. A public security scanner is a good first pass for that problem. It is also easy to misunderstand. A clean public scan does not mean an application is secure, and a warning does not always mean a vulnerability is exploitable. The useful question is not “Did the scanner pass my app?” It is “What evidence could this scanner actually observe?” Layer 1: the public deployment surface A passive scanner can request the same resources that a normal visitor can reach. Depending on its scope, it may inspect: HTTP security headers such as Content-Security-Policy and Strict-Transport-Security HTTPS behavior and redirect consistency Public JavaScript bundles for credential-shaped strings Public source maps that expose original source structure Common sensitive paths such as environment files or repository metadata Cookie attributes and other response-level deployment signals These checks are valuable because they test the deployed result, not the configuration you intended to ship. For example, a repository may contain a CSP configuration while the CDN response does not. A source map may be disabled in one build configuration but still appear in production. A key may be stored safely on the server in most code paths while one client bundle accidentally contains a privileged token. The deployed surface is where those mistakes become observable. Layer 2: source-code review A public URL cannot reveal every control behind an application. Source review or SAST can inspect code paths, configuration, data flow, and dangerous implementation patterns that never appear in a normal response. This is where you can answer questions such as: Is authorization enforced on the server? Can a user change an object ID and read anothe

2026-07-15 原文 →
AI 资讯

# Building a Lightweight Product Filter with Vanilla JavaScript

Building a Lightweight Product Filter with Vanilla JavaScript While building a small e-commerce project, I wanted users to filter products instantly without refreshing the page. Instead of relying on a frontend framework, I opted for a simple solution using HTML data attributes, vanilla JavaScript, and a little CSS. The goal was straightforward: let visitors filter items by size while keeping the interface fast, responsive, and easy to maintain. HTML Structure Each product card stores its information in data-* attributes. This keeps the markup clean and makes filtering straightforward. <div class= "filters" > <button class= "filter-btn" data-filter= "all" > All </button> <button class= "filter-btn" data-filter= "small" > S </button> <button class= "filter-btn" data-filter= "medium" > M </button> <button class= "filter-btn" data-filter= "large" > L </button> </div> <div class= "product-grid" > <div class= "product-card" data-size= "medium" data-style= "cargo" > Cargo Shorts </div> <div class= "product-card" data-size= "large" data-style= "chino" > Chino Shorts </div> <!-- More product cards --> </div> Using data attributes means you can add new filter categories later without changing your overall structure. JavaScript Filtering Logic The filtering logic listens for button clicks and simply shows or hides product cards based on the selected size. const filterButtons = document . querySelectorAll ( " .filter-btn " ); const productCards = document . querySelectorAll ( " .product-card " ); filterButtons . forEach (( button ) => { button . addEventListener ( " click " , () => { const filterValue = button . dataset . filter ; productCards . forEach (( card ) => { const cardSize = card . dataset . size ; if ( filterValue === " all " || cardSize === filterValue ) { card . classList . remove ( " hidden " ); } else { card . classList . add ( " hidden " ); } }); filterButtons . forEach (( btn ) => btn . classList . remove ( " active " )); button . classList . add ( " active "

2026-07-15 原文 →
AI 资讯

i've been building platforms first for 25 years. i think it's wrong now.

i've been that person. standing in front of leadership with an 18-month architecture diagram, explaining why we need six months of infrastructure before a user touches a single feature. and it made sense. for 25 years it made sense. writing boilerplate was expensive. every feature came with a tax — database migrations, routing config, auth wiring. build a shared platform first, pay that tax once. the roadmap justified the investment. then i saw a stat that wouldn't leave me alone. roughly 60% of features on a six-month roadmap are obsolete by launch. not slightly off. obsolete. the customer's problem shifted. the market moved. you spent six months building a precise answer to a question nobody asks anymore. the longer you invest before showing something real, the more expensive it is to admit you were wrong. so you don't. you ship the wrong thing and call it "on schedule." i've done it. i've watched it happen. AI didn't create this problem. but agents are making it impossible to ignore. the 82-point gap mckinsey's 2025 survey: 88% of organizations use AI. only 6% see real bottom-line impact. that 82-point gap isn't about tools. everyone has the same tools. but something shifted in their may 2026 report. they describe agents working overnight — enriching requirements, generating code, packaging outputs for morning review. they call it the "24-hour sprint." leading organizations see 3-5x productivity with 60% smaller teams. a product owner logs in at 9am and finds a feature went from requirements to tested code overnight. nobody worked late. agents did. that's not autocomplete. that's a different delivery model. and here's what most teams miss: it only works when the work is small, bounded, and complete. agents need to know where a task starts and ends. horizontal platform architectures don't give them that. the codebase is the prompt jeremy d. miller built wolverine for .NET. in june 2026 he wrote: "the structure of your codebase is now, effectively, part of the prom

2026-07-15 原文 →
开发者

Why Your TypeScript 7 Upgrade Broke ESLint, ts-jest, and ts-morph

You installed TypeScript 7, ran your build, and something broke. Maybe ESLint crashed with a cryptic TypeError: Cannot read properties of undefined (reading 'Cjs') . Maybe ts-jest stopped transforming your test files. Maybe your CI pipeline just went red for no reason you can point to. You're not doing anything wrong. TypeScript 7 shipped tsgo, a genuine Go port of the type-checker, not a rewrite from scratch. But the tools that plug into TypeScript don't talk to the type-checker directly, they talk to a programmatic API. That API isn't stable yet, it lands in 7.1. Until then, a chunk of the ecosystem throws errors the moment you point typescript at the new version. The 10-second version Don't replace typescript in your dependencies with the 7.x line if you use typescript-eslint, ts-jest, ts-morph, or any tool doing programmatic type-checking. Keep typescript pinned to 6.x for those tools, and install @typescript/native-preview alongside it purely for fast type-checking in CI or a manual tsgo --noEmit command. Two compilers, living side by side, each doing a different job. Why this is happening The TypeScript team calls this Project Corsa: a line-by-line port of the compiler from the old JavaScript codebase (Strada) into Go (Corsa), preserving identical type-checking behavior while getting roughly 10x faster builds from real OS threads instead of Node's single-threaded event loop. That preservation is impressive, but it's a port, not a reimplementation with a new API surface. Tools like typescript-eslint depend on the programmatic API to walk your AST and pull type information out of the compiler, and that API isn't ready until 7.1. What's actually broken right now typescript-eslint — npm refuses to install alongside typescript@7 at all (ERESOLVE error), because the published peer range only allows versions below 6.1.0. Force it through and ESLint crashes deep inside typescript-estree . Tracked as typescript-eslint issue #12518, closed as not planned since the real

2026-07-15 原文 →
AI 资讯

i tested an ai incident commander against 15 real outages — 88% pass rate

i've been the incident commander who forgot to write down the first 20 minutes of the timeline because i was too busy reading logs. more than once. the war room is chaos — five engineers pasting logs, someone asking if the deploy from 30 minutes ago is related, nobody documenting anything. you start logging events in a doc while reading error logs while drafting a stakeholder update while deciding whether to rollback. you're the bottleneck. not because you're bad at your job — because you're doing four jobs at once. i got tired of watching smart people spend their incident energy on documentation instead of decisions. so i built ai-incident-commander — a CLI tool that handles the mechanical parts. timeline, updates, remediation research, postmortem draft. you make the calls. it does the paperwork. runs on your laptop with a local LLM. no API keys, no cloud, no docker. github.com/deghosal-2026/ai-incident-commander — MIT licensed. what it does one command: pip install git+https://github.com/deghosal-2026/ai-incident-commander.git incident-commander simulate --scenario db-connection-pool --auto-approve 8 pre-built scenarios ship with it. database connection pool, bad deploy, memory leak, cert expiry — the usual suspects. no real data needed to try it. for actual incidents, you point it at a directory with your alert, logs, messages, and github PRs. it outputs 10 markdown files: timeline, stakeholder updates, comms blocks you can paste straight into slack, remediation suggestions, a blameless postmortem, and a cost report. the safety part was the real engineering. three points in the pipeline where the graph pauses and waits for you to say yes — stakeholder update, remediation, postmortem. the AI never ships anything without approval. every remediation comes with a citation. suggestions below 0.7 confidence get suppressed. the postmortem prompt enforces blameless language. all AI content gets labeled [AI-GENERATED — review carefully] . and it never executes anything. i

2026-07-15 原文 →
AI 资讯

From $39/Month to $1: How I Moved 10+ Sites Off Hostinger for Free

Last month I finally did some math I'd been putting off: how much I was actually paying to keep a bunch of sites online. $39/month on Hostinger (about R$200, I'm in Brazil). For hosting 10+ sites: product landing pages, blogs, a couple of small tools. Every month, on autopilot, straight off the card. Then I asked myself the obvious question I'd been avoiding: out of those 10+ sites, how many actually need a server running 24/7? Answer: none. What these sites actually are A product landing page doesn't need PHP processing a request. A blog doesn't need a database query on every page view. A marketing site doesn't change its content every second. That's HTML, CSS, and JS you can generate once and serve from a CDN. In other words: a static site. A few real examples I migrated: eduardovillao.me → my personal blog, built with Astro formroute.dev → a SaaS landing page, plain HTML wpfeatureloop.com → a dev tool landing page, plain HTML Three different kinds of sites (blog, SaaS, dev tool), two different stacks, and none of them needed a server running around the clock just to exist. The reason I hadn't migrated sooner wasn't technical. It was inertia. "It's already paid for, it already works, leave it alone." Classic. The migration I moved everything to Cloudflare Pages . The reasoning is boring because it's so simple: it's free, global CDN, automatic SSL, Git-based deploys, custom domains at no extra cost. For static sites, there's really nothing to debate. The process, in short: Each site became a repo (or a folder inside a monorepo, depending on the case) Connected the repo to Cloudflare Pages Set up the build, mostly plain HTML, Astro for the blog where I wanted content collections and a proper writing workflow Pointed the domain, SSL came up on its own Cancelled hosting for that domain on Hostinger Repeated that site by site. No magic, just repetitive work, but each one took about 20-30 minutes. (If you want the technical deep dive on one specific migration, including

2026-07-15 原文 →
开发者

What MasterMemory Solves—and What It Doesn't: A Practical Guide to Static Game Data in Unity

Introduction When you build games with Unity, you eventually run into the problem of managing static game data—often called master data in Japanese game development. At first, ScriptableObject may be more than enough. If your project has a few dozen items, a few dozen enemies, and only a small number of stage definitions, ScriptableObject is convenient because you can inspect and edit everything directly in the Unity Editor. As the project grows, however, the situation changes. You may end up with tables for items, characters, skills, quests, rewards, shops, gacha pools, stages, enemy placements, progression curves, and localization text. The data is no longer edited only by programmers. Planners and game designers may need to work with it in Excel or Google Sheets. At that point, the problem is no longer just choosing a file format. You need to think about questions such as: How do you load a large amount of data quickly? How do you write ID lookups and composite-key queries safely? Should CSV or JSON be parsed directly at runtime? Is it reasonable to create a large number of Dictionaries? How do you validate references between tables? How do you debug data after converting it to binary? How do you connect the source data edited by planners to the data loaded by Unity? For the runtime loading and lookup part of that problem, one strong option is Cysharp's MasterMemory . The official README describes MasterMemory as a “Source Generator based Embedded Typed Readonly In-Memory Document Database” for .NET and Unity. In practical terms, you define your schema as C# types, a Source Generator creates a typed read-only in-memory database API, and the application loads MessagePack binary data that can be queried through type-safe methods. The official README highlights performance compared with SQLite, low allocation during queries, a small database size, and generated database structures that are type-safe and IDE-friendly. Cygames Engineers' Blog also has useful articles

2026-07-15 原文 →
AI 资讯

From Dubai to Thailand: How I Landed a Remote Role at a South African Company

The Next Chapter When I left the waiter job and returned to engineering, I knew I wanted something different. Not just a different job, but a different way of working. The kind where your location does not limit the problems you can solve. I found that in Thailand, working for a South African company called Exonic. Why Bangkok After Dubai, I wanted somewhere with a lower cost of living where I could build runway while working remotely. Bangkok checks that box. The city is a hub for remote engineers. The internet is fast. The infrastructure works. The street food is better than any restaurant I have ever worked in. I arrived with a laptop and a clear goal: find a remote role where I could work on meaningful projects without being tied to a physical office. Landing the Role at Exonic Exonic is a technology consulting company based in South Africa. They serve clients across multiple industries and geographies. When I found the opening, it matched exactly what I was looking for: full time remote, exposure to diverse projects, and the chance to work across the full stack. The interview process was practical. System design discussions, technical assessments focused on AWS and modern frontend frameworks, and conversations about how I approach end to end delivery. I got the offer and accepted it immediately. As a full time remote employee, I was embedded in Exonic's engineering team. My day to day involved building cloud native solutions for their clients, designing architectures on AWS, and shipping production systems across the entire stack. The team was distributed, and the work required communicating clearly across time zones. Three Continents Through One Company Exonic's client base spans the globe. Over my time there, I built production systems touching three different continents. One project was Scoring AI , a voice enabled match scoring application for sports courts. Players start a match, share a link, and control the scoreboard using voice commands. I worked on th

2026-07-15 原文 →
AI 资讯

Laptop Memory Leak Story

I found a slow, insidious memory leak in a Node.js API gateway caused by lingering event listeners; I fixed it by scoping emitters per request, enforcing cleanup in finally blocks, and adding leak‑aware tests and runtime safeguards—memory usage flattened and OOM restarts stopped. The Incident The gateway handled TLS termination, auth, and request fan‑out for many microservices. Over weeks its resident set size climbed in a staircase pattern until Kubernetes began OOM‑killing pods under load. The failure was gradual —light traffic ran for days, peak traffic crashed in hours—so it escaped casual monitoring. Investigation Heap snapshots and allocation profiles showed growing counts of small objects —closures, request metadata, and event listeners—rather than one giant allocation. Tracing revealed an internal event bus where request‑scoped listeners were attached but not always removed: an early‑exit authentication path returned before the cleanup function ran, leaving listeners that held references to request state. The GC saw those objects as live and never reclaimed them. The Fix (technical details) 1. Scoped emitters per request. Replace global emitters for request‑local concerns with a short‑lived EventEmitter created at request start. When the request ends, the emitter goes out of scope and the whole closure graph becomes collectible. 2. Guaranteed teardown via try/finally . Wrap the entire request pipeline so cleanup runs on success, error, or early return; the finally detaches any remaining listeners, clears timers, and releases caches. 3. Leak‑aware CI tests and runtime metrics. A harness simulated thousands of requests across code paths, captured heap snapshots, and asserted bounded object counts. Production metrics tracked listener counts and emitted alerts when thresholds were exceeded. 4. Operational safeguards. Added backpressure on accept queues, a soft memory threshold that disabled nonessential tracing, and rollout halting on excessive crash loops. Thes

2026-07-15 原文 →
AI 资讯

Why Pipelock Is an Egress Agent Firewall, Not an Inbound WAF

Why Pipelock Is an Egress Agent Firewall, Not an Inbound WAF The question behind the word firewall Security teams hear "firewall" and picture something inbound. A firewall, WAF, or IPS sits in front of a service. Traffic comes from the outside world toward the protected app. The control inspects requests before they reach the app and blocks malicious payloads at the door. That is outside-in protection. It fits web applications, where many attacks have recognizable request shapes: SQL injection, cross-site scripting, known exploit signatures, or malformed protocol behavior. The web server is the thing being attacked, and the attacker sends requests into it. AI agents invert that model. The agent is not only a server receiving input. It reads external content, calls tools, sends HTTP requests, invokes MCP servers, and runs with credentials. The dangerous event is rarely that a hostile packet reached the agent. The dangerous event is that the agent got talked into doing something with outbound effects. That is why Pipelock is built as an egress agent firewall, not a WAF-style inbound firewall. Why inbound filtering is the wrong primary model Prompt injection does not behave like a structured malware packet. It is natural-language instruction sitting in places the agent is supposed to read: a web page, a ticket, a search result, a tool response, an MCP server reply, or a user message. The channel is legitimate. The syntax is often normal. The attack is semantic and context-dependent. Solving that by filtering every input before it reaches the agent turns into an enumeration problem. You write patterns for "ignore previous instructions," then the attacker rephrases. You block one formatting trick, then the instruction is split across paragraphs, hidden in quoted text, encoded, or dressed up as policy text. Known phrases are worth catching, and Pipelock catches known injection markers in content it mediates, but input filtering cannot be the center of the security model.

2026-07-15 原文 →
开发者

The Hidden Cost of Manual IAM Review

The Hidden Cost of Manual IAM Review Most teams don't track how long they spend reviewing IAM policies. When I started measuring it on my own team, the numbers were worse than I expected. A thorough manual review of one IAM policy takes 10 to 15 minutes. Not a quick scan. A real review: read every statement, trace every cross-account trust, verify every condition key, check for privilege escalation paths, confirm the resource ARNs match what you think they should. At 4 engineers touching IAM once a week, that's 4 hours a month. 48 hours a year of senior engineers reading JSON documents. And that's the optimistic case. Add a security incident. Add an audit. Add the emergency Friday-afternoon policy change that needs review before deploy. The real number is higher. What manual review misses The problem isn't just the time. It's that humans are bad at repetitive structured-data review, especially under time pressure. Here are the things I've seen slip through manual IAM reviews on production systems: iam:PassRole with no condition. This is the big one. PassRole lets a principal pass a role to a service — and if there's no iam:PassedToService condition, that role can be passed to any service that accepts roles. Including services the attacker controls. The reviewer saw the action, mentally categorized it as "role stuff," and moved on. It was statement 47 of 52 — the reviewer had already been reading policies for 40 minutes. Wildcard resource with sensitive actions. s3:* on Resource: "*" is obvious. s3:GetObject on "arn:aws:s3:::*-backup/*" with a wildcard in the bucket name — that's subtle. The reviewer reads it as "restricted to backup buckets" and moves on. But the wildcard means any bucket ending in -backup , including ones in other accounts if cross-account access is configured. Missing aws:SourceArn on Lambda invocation permissions. When you grant another service permission to invoke your Lambda function, you need aws:SourceArn to prevent the confused deputy

2026-07-15 原文 →
AI 资讯

I picked a coding agent off a leaderboard. It flopped on our codebase.

Last year my team had to pick a coding agent, and I volunteered to run the evaluation. I felt good about it. I pulled up the public benchmark scores, lined up the contenders, took the one at the top, and told everyone we had a winner. Then we actually pointed it at our repo. It did not blow up dramatically. It just kept being slightly wrong in ways that ate our time. It wrote diffs our reviewers would not approve. It renamed a function and broke three files it had never opened. The tests it ran passed, and the repo was still broken. I had confidently recommended a tool based on a number that turned out to say almost nothing about our situation. That was embarrassing enough that I went and figured out why. It took a few weeks of reading and a couple more bad calls before I landed on something that works. This is that, written plainly, and I hope it saves you the meeting where you have to walk your recommendation back. Why the benchmark score lied to me The score was not fake. It was just measuring somebody else's code. Once I looked properly, four gaps explained the whole thing: The agent might have already seen the answers. The problems in these public benchmarks are old. Models were very likely trained on the actual fixes used to grade them. So the score partly measures memory, not problem-solving. The setup is nothing like real work. A benchmark gives the agent a clean repo, one clear issue, and one command to run the tests. My engineers give it a half-open editor, a messy branch, a Slack thread, and a reviewer comment. Completely different job. Our codebase has its own habits. Our internal libraries, our wrappers, our test style, the imports we ban. No benchmark knows any of that, so an agent can write textbook-perfect code that our reviewers still reject on sight. The bar for passing is way lower. A benchmark passes a patch if the broken test now passes. My team passes a patch if it does that, and does not break unrelated tests, does not reformat the whole file,

2026-07-15 原文 →
AI 资讯

Quantos gamedev são necessários para trocar uma lâmpada?

SPOILER: De 1 à 2000 Durante minha jornada como jogador , existiu uma coisa que me despertou muita curiosidade: os créditos. Quando eu jogava coisas como Final Fantasy, ficava completamente arrepiado quando via aquelas cenas antes do menu inicial, com CGIs bem bonitões e um monte de nomes em japonês — muitos deles que, honestamente, até hoje não sei quem são. Esse arrepio também acontecia quando eu chegava ao final de algum jogo e começavam a aparecer nomes e mais nomes. Quando eu entendi o que eram aqueles nomes, a primeira coisa que me veio à mente foi: peraí, precisa de tudo isso de gente pra fazer um jogo? Too long, didn't read : Sim e não. Skyrim levou aproximadamente 6 anos com uma equipe de 100 pessoas (e ainda é dito que é uma equipe enxuta), enquanto Stardew Valley levou 4,5 anos com uma "equipe" de apenas 1 pessoa. Eles têm quase o mesmo tamanho em horas jogadas na campanha principal. Not too long, I'll read it : É um pensamento lógico que trabalhos maiores no mundo da tecnologia envolvam uma quantidade maior de pessoas trabalhando E tempo. Dessa forma, seria correto assumir que um trabalho menor exige menos tempo e menos pessoas trabalhando. Mas o que os dados dizem? King of Fighters 94: 2 anos, começou com 6 pessoas, aumentou para 60. Clair Obscure - Expedition 33: aproximadamente 6 anos, 30 pessoas. TES V - Skyrim: 6 anos, 100 pessoas. Super Mario Bros: 2 anos, 7 pessoas na equipe principal. Stardew Valley: 4,5 anos, 1 pessoa. Kenshi: 12 anos, 1 pessoa por 6 anos (trabalhando meio período), aproximadamente 8 pessoas por mais 6 anos (tempo integral). Final Fantasy VII (PS1): aproximadamente 2 anos, de 100 a 150 pessoas (uma das maiores equipes da indústria na época). Final Fantasy VII Remake: Cerca de 5 anos, e não se tem números exatos, mas os créditos citam mais de 2000 pessoas, incluindo muitos -istas e -ores (vou tentar confirmar esse número depois). É claro que existem muitos fatores envolvidos aí, como época, demandas de mercado, prazos, tecnologia

2026-07-15 原文 →
AI 资讯

The Modern Browser Testing Stack: AI, CI, Human Review, and the Cost of Maintenance

Browser automation used to be easier to describe. A test opened a page, filled in a form, clicked a button, and checked the result. The hardest parts were usually selectors, waits, and browser compatibility. Those problems still exist, but the surface area has expanded. Today, browser tests may need to handle streaming interfaces, MFA, AI-generated content, multiple operating systems, preview deployments, canary releases, and code changes proposed by AI assistants. The challenge is no longer just writing a script that passes. The challenge is building a testing system that remains understandable and affordable after hundreds of tests and thousands of CI runs. Start by measuring instability instead of normalizing it Flaky tests often become accepted background noise. A test fails, CI retries it, and the second run passes. The pipeline turns green, so the team moves on. Over time, the retry count grows and nobody is sure which failures matter. The problem is that a passing retry does not erase the cost of the first failure. The article on calculating the real cost of flaky test retries in CI provides a useful framework for evaluating compute costs, developer interruptions, delayed feedback, and investigation time. A simple reliability metric can help: first-attempt pass rate = tests passing without retry / total test executions This is often more revealing than the final pipeline pass rate. A suite with a 99% final pass rate may still be deeply unstable if many tests require multiple attempts. Reproduce the environment before changing the test When a browser test fails only in CI, teams often edit the test before reproducing the environment. That can lead to unnecessary waits and conditionals. One of the most common variations is a test that passes in visible Chrome but fails in headless mode. The explanation is not always “headless Chrome is flaky.” Differences in viewport, rendering, animation, fonts, and resource timing can all change application behavior. This det

2026-07-15 原文 →
AI 资讯

Why Browser Test Reliability Is Now a Product Decision, Not Just a Framework Decision

For a long time, teams treated browser test reliability as a framework problem. When tests failed, the usual response was to change selectors, add waits, increase retries, or replace one automation library with another. That approach made sense when the main challenge was simply controlling a browser. Modern applications are different. A single user journey may now include an identity provider, multi-factor authentication, a streaming AI response, a background API request, a feature flag, a canary deployment, and a frontend rendered differently across several operating systems. The test framework is still important, but it is only one part of the reliability problem. The bigger question is whether the entire testing system gives the team enough evidence to make a release decision. Headless failures are usually a symptom, not the real problem A common example is a test that passes locally but fails only in headless Chrome. It is tempting to assume that headless mode is simply unreliable. In practice, the difference is often caused by viewport size, rendering behavior, animation timing, fonts, resource loading, or elements being positioned differently when no visible browser window exists. This breakdown of why browser tests fail only in Chrome headless is useful because it separates several failure categories that are often grouped together as “timing issues.” That distinction matters. A test that fails because an element is outside the viewport needs a different fix from a test that fails because a network request completes later in CI. Adding a longer timeout may hide both problems temporarily, but it does not make the test more trustworthy. Retries can make a weak test suite look healthy Retries are one of the easiest ways to reduce visible failures in CI. They are also one of the easiest ways to hide instability. A flaky test that passes on its third attempt still consumed runner time, delayed feedback, created extra logs, and made it harder to determine whether

2026-07-15 原文 →