AI 资讯
HTTP Server — Request Lifecycle
Request lifecycle: một HTTP request đi qua đâu, và vì sao "quên gọi next()" làm request treo cho tới khi socket timeout Một request tới một Express hay Fastify server không phải là "gọi handler rồi trả về response". Nó là một chuỗi các bước theo thứ tự cố định: parse HTTP, chạy qua middleware/hook, match route, gọi handler, serialize, gửi response, đóng. Nếu bất kỳ bước nào không chuyển tiếp — Express không gọi next() , Fastify hook không reply.send() hay không return — request treo cho tới khi client hoặc server timeout đóng socket. Đây là loại lỗi không ném exception, không xuất hiện trong error log, chỉ hiện ra qua p99 latency phình lên và số socket ở trạng thái ESTABLISHED tăng dần. Hiểu chính xác lifecycle này là điều kiện tiên quyết để debug những request "biến mất" và để đặt middleware đúng thứ tự. Cơ chế hoạt động Bước dưới cùng giống nhau ở cả hai framework: Node core http.Server nhận TCP connection, parse HTTP request line + headers, phát event request với hai object IncomingMessage (req) và ServerResponse (res). Điểm khác nhau là những gì framework làm giữa lúc nhận request và lúc response ra khỏi socket. Express dựng một chuỗi middleware qua Router . Mỗi lần app.use(fn) hay app.get(path, fn) được gọi, Express bọc fn vào một Layer với path regex (thông qua path-to-regexp ) rồi push vào một stack. Khi request đến, Router.handle duyệt stack tuần tự: với mỗi layer, nếu path match, gọi fn(req, res, next) . next() là closure trỏ vào layer kế tiếp; chỉ khi nó được gọi thì layer sau mới chạy. Error handler được nhận diện bằng arity — hàm 4 tham số (err, req, res, next) — và chỉ được duyệt tới khi next(err) được gọi: import express from ' express ' const app = express () app . use ( express . json ({ limit : ' 1mb ' })) // 1. parse body app . use (( req , _res , next ) => { // 2. request id req . id = crypto . randomUUID () next () }) app . use (( req , _res , next ) => { // 3. auth const token = req . headers . authorization if ( ! token ) return next ( new Erro
AI 资讯
End-to-end Design Walkthrough — Full System Design
Full system design walkthrough: vì sao quy trình 5 bước quan trọng hơn thuật ngữ, và cái bẫy nhảy thẳng vào deep-dive Một buổi phỏng vấn system design 45–60 phút không đánh giá xem thí sinh biết bao nhiêu tên công nghệ, mà đánh giá xem thí sinh có xử lý được một bài toán mơ hồ theo một quy trình có kỷ luật hay không. Cùng đề "thiết kế URL shortener", người thất bại thường bắt đầu bằng "dùng Cassandra vì scale tốt" ngay ở phút thứ hai — chưa hỏi scale bao nhiêu, chưa biết read/write ratio, chưa đồng ý interface. Người pass đi theo một trình tự cứng: requirements → estimation → high-level → deep-dive → tradeoff . Cùng một đề, cùng thời lượng, nhưng người thứ hai dẫn dắt được interviewer thay vì bị dí. Bài này mô tả quy trình đó ở mức thực dụng, các thất bại thường gặp khi bỏ bước, và một hands-on end-to-end trên URL shortener để tự luyện. Cơ chế hoạt động Quy trình chuẩn được nhiều tài liệu tổng hợp (Alex Xu — System Design Interview vol.1; Donne Martin — system-design-primer ; Kleppmann — Designing Data-Intensive Applications ) đều có 4–5 bước gần như trùng nhau. Đây là khung 5 bước dùng thực tế trong phỏng vấn: Requirements clarification (~5 phút). Chốt functional requirement (hệ thống làm gì — API nào, use case nào) và non-functional requirement (availability target, latency target, consistency yêu cầu, security, cost). Không đoán — hỏi lại interviewer. Output: 3–5 gạch đầu dòng functional + 3–5 gạch NFR + danh sách "out of scope" (analytics, billing, ...). Back-of-the-envelope estimation (~5 phút). Tính DAU, QPS peak/avg, read:write ratio, storage growth theo năm, bandwidth. Không cần chính xác — cần đúng order of magnitude để quyết định "cần shard hay không", "cache có ý nghĩa không", "một node đủ hay phải scale ngang". High-level design (~10–15 phút). Vẽ box diagram: client → LB → app tier → cache → primary datastore → async worker → object storage/CDN. Định nghĩa API (endpoint, request/response, status code) và data model (schema chính, index chính). Ở bước này
AI 资讯
Idempotency — Safe Retry
Safe retry: idempotency key để retry một request không biến thành hai lần charge Trong hệ phân tán, retry là mặc định — client, gateway, load balancer, queue consumer đều retry khi timeout hoặc lỗi tạm thời. Vấn đề là nhiều thao tác quan trọng không idempotent tự nhiên: một request POST /charges gửi hai lần thì trừ tiền khách hai lần, một message OrderCreated xử lý hai lần thì ship hai đơn. Idempotency key là cơ chế để server nhận diện "cùng một intent" giữa các lần retry và chỉ thực hiện side effect một lần , trong khi vẫn trả về response giống hệt cho mọi lần gọi lặp — về mặt hiệu ứng thấy được từ bên ngoài, đây là cái người ta hay gọi là "exactly-once effect" (dù ở tầng transport vẫn là at-least-once). Cơ chế hoạt động Client sinh một identifier duy nhất cho mỗi thao tác (thường là UUIDv4) và đính kèm request — quy ước phổ biến là HTTP header Idempotency-Key (Stripe API dùng đúng tên này, và IETF có draft draft-ietf-httpapi-idempotency-key-header chuẩn hoá cùng tên header). Server dùng key làm identity của thao tác trong một cửa sổ TTL: Nhận request với key K . Tra K trong idempotency store. Nếu tồn tại và request cũ ở trạng thái terminal (đã có response), trả lại response đã lưu — không chạy lại business logic. Nếu tồn tại nhưng đang in-flight , trả 409 Conflict (hoặc chờ, tuỳ contract). Nếu chưa tồn tại, INSERT bản ghi với unique constraint trên key, chạy business logic, persist response, commit. Điểm cốt lõi là bước insert + bước business logic + bước lưu response phải nằm trong cùng một transaction boundary — hoặc chí ít, phải có cơ chế đảm bảo không có window mà một retry khác nhìn thấy "chưa có key" trong lúc lần đầu vẫn đang chạy dở. CREATE TABLE idempotency_keys ( key TEXT NOT NULL , user_id BIGINT NOT NULL , request_hash TEXT NOT NULL , -- fingerprint payload status TEXT NOT NULL , -- in_flight | succeeded | failed response_code INT , response_body JSONB , created_at TIMESTAMPTZ NOT NULL DEFAULT now (), locked_until TIMESTAMPTZ , PRIMARY KEY ( user_id ,
AI 资讯
Message Queue — Async Processing
Async processing qua message queue: vì sao đẩy việc nặng ra khỏi request path, và cái giá phải trả bằng eventual consistency Async processing là mô hình tách một request thành hai giai đoạn: request handler nhận việc, xác nhận với client, rồi giao phần xử lý thật cho một worker chạy ngoài request path — thường qua một message queue (RabbitMQ, AWS SQS, Kafka, Redis Streams, hoặc queue trên nền Redis như BullMQ/Sidekiq). Lý do dev gặp nó trong việc thật rất cụ thể: một endpoint gọi payment provider mất 3s, gửi email confirm mất 1s, resize ảnh mất 5s — nếu làm tuần tự trong request, p99 latency của endpoint là tổng các con số đó, và một downstream chậm hoặc chết đủ để làm timeout hết thread pool của app server. Đẩy vào queue thì request trả về trong vài chục ms; nhưng đổi lại, cái "xong" mà client thấy không còn nghĩa là việc đã thực sự hoàn thành. Cơ chế hoạt động Ba thành phần: producer (thường là API server) đóng gói việc thành message rồi publish vào broker; broker (RabbitMQ/SQS/Kafka…) giữ message trong queue có persistence tuỳ cấu hình; consumer/worker poll hoặc được push message, xử lý, rồi ack để broker biết xoá. Nếu worker chết trước khi ack, broker redeliver — đây là gốc của semantic at-least-once : mỗi message được giao ít nhất một lần, có thể nhiều lần. Exactly-once trong hệ phân tán chỉ đạt được ở lớp application bằng cách consumer viết idempotent, không phải bằng cấu hình broker. Ví dụ với RabbitMQ + Node ( amqplib ): // producer — trong HTTP handler const ch = await conn . createConfirmChannel () await ch . assertQueue ( ' image.resize ' , { durable : true }) app . post ( ' /upload ' , async ( req , res ) => { const jobId = crypto . randomUUID () const payload = Buffer . from ( JSON . stringify ({ jobId , s3Key : req . body . key })) await ch . sendToQueue ( ' image.resize ' , payload , { persistent : true , // ghi xuống disk, sống sót broker restart messageId : jobId , // để consumer dedupe contentType : ' application/json ' , }) // đợi broker confirm đ
AI 资讯
CAP Theorem — Consistency vs Availability
CAP: khi network partition xảy ra, chỉ được chọn C hoặc A — không có "cả ba" CAP theorem là kết quả của Gilbert và Lynch (formal proof năm 2002 cho conjecture Brewer đưa ra ở PODC keynote 2000): một hệ phân tán có shared state không thể đồng thời cung cấp cả linearizable Consistency , Availability (mọi request tới non-failing node đều trả lời không lỗi), và Partition tolerance khi có network partition. Trong thực tế, partition là thứ sẽ xảy ra — TCP retransmit, GC pause dài, switch chết, cross-region link flap — nên P là ràng buộc bắt buộc, không phải lựa chọn. Câu hỏi thật là: khi partition xảy ra, hệ thống hy sinh C hay A? Chọn sai gây ra hai loại incident khác nhau: chọn AP mà dữ liệu cần linearizable dẫn tới double-charge, oversell inventory, split-brain; chọn CP mà dữ liệu chỉ cần eventually consistent dẫn tới downtime không cần thiết, user không đọc được profile của chính mình. Cơ chế hoạt động Định nghĩa formal theo Gilbert và Lynch: Consistency ở đây là linearizability : mọi read sau một write hoàn tất phải thấy giá trị mới (hoặc mới hơn); tồn tại một total order các operation phù hợp với real-time. Availability : mọi request tới một non-failing node phải nhận response (không timeout, không error). Partition tolerance : hệ thống tiếp tục hoạt động dù network drop tuỳ ý message giữa các node. Proof intuition: giả sử có 2 node N1, N2 giữ cùng key x=0 . Client ghi x=1 vào N1. Link N1 và N2 đứt. Một client khác đọc x từ N2. Nếu N2 trả về 0 thì không linearizable (mất C). Nếu N2 chờ đến khi thấy được N1 thì mất A. Nếu N2 từ chối phục vụ thì cũng mất A. Không có cách thứ ba. Trong hệ CP, mỗi write phải qua quorum (Raft, Paxos, ZAB); khi node bị isolate khỏi quorum, nó từ chối phục vụ để giữ linearizability: // etcd/Raft-style: khi mất quorum, leader step down và write fail resp , err := kv . Put ( ctx , "order/42" , "paid" ) if err != nil { // err là ErrLeaderChanged hoặc context.DeadlineExceeded khi ở minority side // client thấy unavailable — đúng contract CP re
开发者
Google’s Pixel event is set for August 12
Google's upcoming event in August will introduce new Pixel devices.
产品设计
Figma acquires team behind a vibe-coding app
The Y Combinator-backed company started a vibe-coding platform and later built an agent-creation product.
产品设计
Most Secure Way to Store Auth Tokens
Where should your auth token live so an XSS bug can't steal it? Here's how to build auth that survives the crazy non-secure world we live in. submitted by /u/creasta29 [link] [留言]
AI 资讯
Mysterious Compound Detected on Pluto and Titan
Something on Pluto and one of Saturn’s moons, Titan, absorbs light in a way unexplained by anything in spectroscopic databases.
AI 资讯
The ‘G-Wagen of golf carts’ could be the ideal second car
While the auto industry wrings its hands over the electric vehicle market, sweating details like aerodynamic efficiency and range anxiety, a new EV startup based in Lisbon, Portugal, is zagging in a different direction. Amble's new electric buggy won't impress anyone with its 0-60 time or its self-driving features (it has none). Instead, it takes […]
AI 资讯
ABC tells the government to get out of its newsrooms
ABC is firing back at the Federal Communications Commission after the agency opened an investigation into The View's airtime of political candidates. In a letter to the FCC on Tuesday, ABC argues that the agency's actions pose a risk to editorial independence by targeting programs "perceived as unfriendly to the current administration," as reported earlier […]
创业投融资
Netflix dabbles in shorter video content with its new set of publisher deals with Variety, others
Netflix is bringing 2- to 20-minute videos to its platform through new partnerships with digital publishers, including Rolling Stone and Variety.
AI 资讯
Google announces Pixel 11 launch event in August
Google is hosting its next Made by Google launch event for Pixel hardware on August 12th in New York City, according to an invitation sent by Google to The Verge. Unusually, the event is taking place in the evening: It'll kick off at 6PM ET that day. The email also includes a brief animation teasing […]
AI 资讯
Claude Cowork expands to mobile and web
With this update, users can start a task from their desk, get status updates on their phone, and pick up the finished output later — even if their laptop is closed.
产品设计
AutoShelf 2.0
Auto-organize files on your Mac now with MCP & CLI support Discussion | Link
科技前沿
Facing US export controls, China's DeepSeek plans to make its own chips
It's early, but the plan is to reduce dependency on Nvidia and Huawei.
AI 资讯
Shut Those Laptops! Anthropic Puts Its Claude Cowork Agent on Your Phone
Claude Cowork now keeps working on tasks even after you close your laptop. It’s part of a larger push toward smartphone-controlled agents.
开发者
Q1 2026 Innovation Graph update: Open source collaboration is accelerating worldwide
New Innovation Graph data shows global developer communities growing faster than ever, with collaboration reaching new highs across many economies. The post Q1 2026 Innovation Graph update: Open source collaboration is accelerating worldwide appeared first on The GitHub Blog .
开发者
Nuxt In 2026: The Vue Full-Stack Framework That Deserves More Attention
Everyone knows Next.js is the default full-stack JavaScript framework in 2026. The job ads say so,...
AI 资讯
The Next DEV Weekend Challenge Launches on July 9 - 13. Mark Your Calendar!
We're back with another installment of the DEV Weekend Challenge ! If you missed the earlier editions, these are short-form, high-energy challenges designed to fit right into your weekend. We're giving you the heads-up now so you can clear your schedule! How It Works Our challenge prompt will be revealed at launch. Follow #weekendchallenge for updates. You can also keep an eye on the DEV Weekend Challenge page or look out for the official announcement post from the DEV Team . From there, you'll have the entire weekend to build, document, and submit your project. That's all there is to it! Because our community spans every timezone on the planet, we've set the window so that everyone around the world gets at least a full weekend to participate. Important Dates Launch Time: July 10 at 2:00 AM UTC Submissions Due: July 13 at 6:59 AM UTC Here's what that looks like across a few timezones: Timezone Launch Time (Local) Submissions Due (Local) PDT Thursday, Jul 9 at 7:00 PM Sunday, Jul 12 at 11:59 PM EDT Thursday, Jul 9 at 10:00 PM Monday, Jul 13 at 2:59 AM GMT Friday, Jul 10 at 2:00 AM Monday, Jul 13 at 6:59 AM CEST Friday, Jul 10 at 4:00 AM Monday, Jul 13 at 8:59 AM IST Friday, Jul 10 at 7:30 AM Monday, Jul 13 at 12:29 PM JST Friday, Jul 10 at 11:00 AM Monday, Jul 13 at 3:59 PM AEST Friday, Jul 10 at 12:00 PM Monday, Jul 13 at 4:59 PM While the window technically spans more than 48 hours, our goal is to ensure everyone has a full, uninterrupted weekend to work on their project regardless of where they live. What else is happening? Mark your calendars for the upcoming Summer Bug Smash . Bug Smash - Register Now We can't wait to see what you build!