AI 资讯
Nmap for Authorized Infrastructure Validation (Not Hacking)
Every deploy makes a promise about the network: "this box only exposes SSH and HTTPS," "the database is never reachable from outside the app tier." Nmap is how you turn that promise into a test that either passes or fails. Nobody has to take the security group's word for it. One rule before anything else: only scan systems you own or are explicitly authorized to assess. Point Nmap at a lab, a VM you control, or your own infrastructure. This is authorized infrastructure validation — a defensive check on exposure you're responsible for, not "hacking." Start with what's actually listening The most basic useful run is a host scan: nmap 192.168.56.10 This does host discovery and a default TCP scan of the common ports. The output lists each port as open , closed , or filtered . open means something accepted the connection. filtered usually means a firewall or security group silently dropped the packet — which is exactly the signal you want when validating that a rule is doing its job. If you expected a wall of filtered and instead see open , that's your finding. When you already know what should be exposed, scan for exactly that and nothing else: nmap -p 22,80,443 host Narrowing to the declared ports keeps the scan fast and the output readable. The question you're answering isn't "what's out there" — it's "does observed reality match what I declared?" Confirm what's really on the port An open port tells you a socket is listening. It does not tell you what . For that, add version detection: nmap -sV -p 22,80,443 host -sV probes each open port and reports the service and, when it can, the version banner. This matters because ports lie. A service you assumed was nginx on 443 might be something a teammate stood up last week. Read the SERVICE and VERSION columns and ask: is this the thing I expected, at the version I expected? A mismatch here is often the first sign of drift or a forgotten container. A methodology, not just commands Running Nmap ad hoc gives you trivia. Runnin
开发者
The Kubernetes Checklist for Teams Without a Platform Team
Most Kubernetes advice assumes you have a platform team: specialists who own upgrades, ingress, security policies, and the 2 a.m. pages. The teams I am writing for usually have three to ten engineers, one of whom “knows Kubernetes,” and no dedicated platform team. They depend on a cluster that nobody fully owns. I work in enterprise environments where platform teams are large and everything is process. This article is the opposite exercise: what is the minimum discipline a small team needs to run Kubernetes in production—and what enterprise baggage should it refuse to copy? The question that matters more than any tool Before any checklist: who owns the platform after the migration is finished? Not “who set it up.” Who owns upgrades next year, certificate renewals, the CNI version, and deprecated APIs? If the answer is one person's name, you do not have a platform. You have key-person risk with YAML on top. If the answer is “nobody, really,” Kubernetes is invisible operational debt accumulating interest. The rest of this checklist exists to make that ownership small enough for a small team to carry. For each item, score 0 if it does not exist, 1 if it exists but is informal or untested, and 2 if it is documented and tested. The purpose is not to produce a flattering number. It is to expose the next few conversations the team needs to have. 1. Deployments: Git is the source of truth Treat Git as the source of truth for workloads and cluster configuration, including temporary fixes. Use one reconciliation path—for example, Argo CD or Flux—so production changes are reviewed and reproducible. Keep emergency access, but reconcile every emergency change back into Git. Define and test a rollback path for every service. A Git revert is useful only if your delivery process can deploy it safely. This converts your cluster from a mystery into a diff. Every other practice gets easier once “what is running?” has an answer. 2. The rollout basics that prevent late-night incidents R
AI 资讯
Shipping an Isometric Game in the Browser With Three.js
A browser game has an unusual constraint: the first level begins before the player reaches the first level. The download, parsing, asset setup, input initialization, rendering pipeline, and first interactive frame are all part of the experience. When building an isometric action game with Three.js, architecture has to account for that startup path as carefully as the gameplay loop. Keep rendering and game state separate Three.js provides scene, camera, materials, geometry, animation, and WebGL abstractions. It does not prescribe a game architecture. Avoid making the scene graph the only source of truth. Gameplay systems should reason about entities, movement, combat, health, and interactions in a form that can be tested without requiring every object to be a rendered mesh. A clean boundary lets the renderer reflect state while simulation code remains understandable. Treat asset loading as a pipeline GLTF is a useful delivery format, but imported assets still need conventions: scale and orientation; origin and pivot placement; animation naming; material expectations; collision representation; texture compression and dimensions; fallback behavior when an asset fails. Write validation tools or loading assertions early. One inconsistent model can create hours of debugging across animation, collision, and camera behavior. Design for mobile constraints from the start A desktop GPU can hide expensive decisions. Mobile hardware and thermal limits expose them. Watch: draw calls and material switches; overdraw from transparent effects; shadow-map cost; texture memory; object churn that triggers garbage collection; high-resolution rendering on dense displays; touch input and viewport changes. Adaptive quality is usually more useful than one rigid “high” setting. Resolution scale, shadow quality, particle counts, and effect density can respond to device capability. Make the camera part of gameplay An isometric camera must balance readability and atmosphere. Occlusion handling,
AI 资讯
To keep the AI from breaking my design, it only writes JSON. I built that out for real, and the JSON turned into code
While mass-producing web tools with an AI, I've changed how I lock the design in three stages. The previous post I wrote about that got this comment: "I'd like to see the JSON approach and the design-system approach side by side." Taken at face value, I should just put the two side by side. But first, let me add a short preface. I don't want to frame this as "the JSON approach versus the design-system approach." When I called the JSON approach a "failure" in that post, I didn't mean the method is inferior; I meant it didn't suit my particular set of tools. A page made with the JSON approach does look thin. But where that thinness comes from is easily misread. Whether the design drifts and whether it looks rich are decided separately. What stops the drift is locking the design; whether it looks rich is how much you build out. What locking with JSON removes is drift in the items you specified in the schema. Whether the screen becomes rich, on the other hand, is determined by how much you've built out the machinery that turns that JSON into a screen. So it isn't that locking with JSON is what made it look like a spreadsheet. In the previous post, too, I wrote that fattening the schema and the renderer does increase the expression itself. But that came with a caveat: past a point, it heads toward rebuilding HTML and CSS by hand. What I really want to check is one step past that. If the template sets the ceiling on expression, then building out the JSON side's template as much as the current one should produce the same screen. So what does that build-out demand? I actually built it and measured. I'll share the result, along with the JSON-approach and design-system-approach screens placed side by side under matched test conditions. I'll admit up front: at the time, I chose the design system without running this comparison. So this is me building the road I didn't take, after the fact, and measuring what that cost consists of. Same order, same one-shot So that the comparis
AI 资讯
I finally found a robot lawnmower I’d trust with my yard
Robot lawnmowers are finally good enough to take a lot of work out of maintaining a yard, but they’re still not set-it-and-forget-it machines. If you don’t want these autonomous cutting machines to tear up your lawn or go roaming in your neighbors’ yard, you’re still going to need to keep an eye on them. But […]
AI 资讯
Common Web Application Technologies
Introduction Modern web applications are rarely built with a single technology. A typical application combines a web server, a programming language, a framework, a database, data formats, and backend services to deliver its functionality. For anyone learning web application security, it’s important to understand these technologies at a basic level—not only to recognize them, but to understand where they sit in the architecture, how data moves through the system, and where weaknesses can be introduced. This article covers: Java Platform ASP.NET PHP Ruby on Rails SQL XML Web Services & SOAP Web Application Architecture: The Big Picture You can think of a web application as a pipeline: User (Browser) ↓ Web Server / App Server ↓ Application Code ↓ Database / Backend Services ↓ Response back to Browser A useful security question to keep in mind: Once user input enters the application, where does it go, how is it processed, and is it handled safely? 1) The Java Platform (Enterprise Web Applications) Java is widely used for large-scale enterprise applications. Java-based web apps can run on operating systems such as Windows, Linux, and Solaris and can use different application servers, frameworks, and third-party components. Simplified Flow Browser ↓ HTTP Request ↓ Java Web Container ↓ Java Application ↓ Database / Other Services ↓ HTTP Response Common Java Terms (Quick Explanations) Enterprise Java Bean (EJB) An Enterprise Java Bean is a relatively heavyweight Java component that encapsulates the logic of a particular business function. It can also handle enterprise requirements such as transaction management. Plain Old Java Object (POJO) POJO stands for Plain Old Java Object —a regular Java object rather than a specialized component like an EJB. POJOs are typically simpler and more lightweight, which is why they are common in modern Java applications. Java Servlet A Java Servlet is a Java component that receives HTTP requests and returns HTTP responses. In many Java web
开发者
Join our DEV Weekend Challenge: Dog Days Edition! $1,000 in Prizes Across FIVE Winners. Submissions Due August 17 at 6:59 AM UTC.
We're back with another DEV Weekend Challenge, a short bite-sized challenge planned to fit into your...
开发者
You can now just point at a mess and this robot vacuum will suck it up
Matic, my current favorite robot vacuum, just got a big upgrade. The company has launched Matic Cues, which brings voice and gesture control to the robot. Now, you can talk directly to your vacuum to tell it what you want it to do, or just point at a mess to have it spot-clean. The feature […]
产品设计
Ford on track to complete $2B factory overhaul for Fathom EV truck
Ford expects to begin prototype builds of the Fathom EV in the first quarter of 2027.
AI 资讯
The Corvette Grand Sport X delivers Porsche 911 performance for a fraction of the price
My drive of the 2027 Corvette Grand Sport X began under oily black clouds, a torrential weather front releasing its grip on Manhattan - an inauspicious start for any mega-powered sports car. Rain pelted the waterlogged pavement, as I set course for the mountain-man roads of the Catskills, then on to Long Island and New […]
AI 资讯
The Painful Truth of Exactly How ICE’s New Shock Gloves Work
ICE is spending millions on shock gloves designed to overpower subjects through intense, localized pain.
AI 资讯
Vercel Launches v0 API for Headless App Building
Vercel has made the v0 API generally available, enabling developers and AI agents to programmatically generate, iterate on, preview, and deploy applications through API calls. By Daniel Dominguez
AI 资讯
33 tests proved the tool was correct. None asked whether it runs.
Acceptance gaps Your monitoring tool has 33 tests. Every one of them passes. It has also never executed, not once, and nothing in your project will ever tell you. Correct, complete, and never started We built a tool that scans four public sources for conversations where our product belongs. It reads only. It never posts. The acceptance was thorough. 33 checks in total. No write access, no credentials, results filtered for relevance, duplicates removed. A hard cap on output, back off on HTTP 429, and a dead source must not swallow the other three. All 33 passed. The tool shipped. The task promised a list of conversations every morning. There was no schedule. So there was never a list. And a tool that does nothing also reports nothing, so nobody noticed. Why your test suite cannot see this Tests answer questions about behaviour. Given this input, does the code do the right thing? Whether anything ever supplies that input is a different kind of question. It lives in a scheduler, a workflow file, a systemd timer, a queue consumer. Your test suite has no opinion about it. This is why the gap survives review. Reviewers read the diff, and the diff is correct. The missing part is not in the diff at all. Note how ordinary the failure is. Nobody was careless. The work was good. It just was not connected to anything. The question to add to every acceptance What starts this, and how would I know if it stopped? Ask it about every tool you ship that is meant to run on its own. A report, a backup, a sync, a scanner, a cleanup job. It has two halves and both matter. Something must start it. And when it stops starting, that must be visible without anyone going to look. Make it answerable by a machine A question you have to remember to ask gets forgotten. So we wrote a guard that asks it for every tool at once. The rule: any script whose own header says it runs daily must appear in a workflow file that has a schedule. Twelve lines of code, and it covers every tool we will ever add. T
AI 资讯
5 Advanced CLI Engineering Patterns in Node.js & Go (Building Production Tools)
5 Advanced CLI Engineering Patterns in Node.js & Go (Building Production Tools) Command line utilities (CLIs) are the backbone of modern developer workflows. From package managers to security scanners, a well-engineered CLI tool can boost developer velocity tenfold. Drawing from production patterns behind open-source CLI tools like node-reaper and port-sniper , here are 5 essential engineering patterns for building high-performance CLI utilities. 1. Graceful Process Signal Handling (SIGINT / SIGTERM) Always handle Ctrl+C cleanly to release ports, clean up temporary files, and restore cursor states. 🔴 Node.js Signal Handler Pattern: import process from ' node:process ' ; function setupGracefulShutdown ( cleanupFn : () => Promise < void > ) { const shutdown = async ( signal : string ) => { console . log ( `\n\n[INFO] Received ${ signal } . Cleaning up resources...` ); try { await cleanupFn (); console . log ( " [SUCCESS] Cleanup complete. Exiting. " ); process . exit ( 0 ); } catch ( err ) { console . error ( " [ERROR] Cleanup failed: " , err ); process . exit ( 1 ); } }; process . on ( ' SIGINT ' , () => shutdown ( ' SIGINT ' )); process . on ( ' SIGTERM ' , () => shutdown ( ' SIGTERM ' )); } 2. Interactive Terminal Prompts & Selection Instead of forcing users to memorize complex flags, provide interactive dropdown menus when flags are omitted. 🔴 Interactive Dropdown Selection: import { select } from ' @inquirer/prompts ' ; export async function promptTargetSelection ( processList : { pid : number ; port : number ; name : string }[]) { const selectedPid = await select ({ message : ' Select zombie process to kill: ' , choices : processList . map ( proc => ({ name : `Port ${ proc . port } ──► PID ${ proc . pid } ( ${ proc . name } )` , value : proc . pid , })), }); return selectedPid ; } 3. High-Speed Concurrent Task Execution in Go When scanning filesystem directories (e.g. cleaning node_modules ), use Go goroutines with worker pools for maximum IOPS efficiency. packa
AI 资讯
Perry Mason in: The Case of the Drifting Timer
Perry Mason in: The Case of the Drifting Timer Opening Statement You need a reactive "current time" in your Vue 3 app. A schedule grid with a red line showing "now." A live clock. A dashboard that updates every minute. Every Vue developer reaches for setInterval first. It works. But "works" and "works well" are different things. This is the story of taking a naive timer from "it ticks" to production-grade — and the four iterations it took to get there. The prosecution calls four exhibits. Let's begin. Exhibit A: The Memory Leak const currentTime = ref ( new Date ()) onMounted (() => { setInterval (() => { currentTime . value = new Date () }, 60000 ) }) It works. Sort of. The defense rests — but the prosecution is just getting started. Exhibits of negligence: The interval is never cleared. When the component unmounts, the timer keeps firing every 60 seconds forever — updating a ref nothing reads anymore, and holding its closure (and everything the ref references) in memory for the lifetime of the page. Silent. Invisible. The kind of leak that shows up in production after a user navigates around your app for 20 minutes. Exhibit B: The Cleanup That Failed const currentTime = ref ( new Date ()) let timeInterval = null onMounted (() => { currentTime . value = new Date () timeInterval = setInterval (() => { currentTime . value = new Date () }, 60000 ) }) onUnmounted (() => { if ( timeInterval ) clearInterval ( timeInterval ) }) Now we clean up. The interval is stored in a variable, cleared on unmount. A step forward — but the prosecution has three more objections: Further evidence: This only works inside components. If someone calls this logic from a Pinia store or outside a component's setup() context, onUnmounted never fires. The timer leaks silently. (Composables called synchronously during setup() are fine — Vue's docs recommend exactly that. The problem is when there's no component instance at all.) The timer fires 60 seconds after load , not at the top of the minute
AI 资讯
Why Rust and WebAssembly Are Replacing JavaScript for Heavy AI Workloads in 2026
Why Rust and WebAssembly Are Replacing JavaScript for Heavy AI Workloads in 2026 While JavaScript remains the reigning language for web UI rendering, high-throughput client-side compute—such as local browser AI inference, video encoding, and cryptographic verification —has completely shifted to Rust compiled to WebAssembly (WASM) . In 2026, running 1B+ parameter models directly inside the browser using WebGPU and WASM SIMD has become standard practice. ⚡ Benchmarks: JS vs WASM SIMD execution Execution Time (Lower is Better) ┌────────────────────────────────────────────────────────┐ │ JavaScript (V8 Engine) : █ █ █ █ █ █ █ █ █ █ 1,420 ms │ │ Rust WASM SIMD : █ █ 210 ms │ └────────────────────────────────────────────────────────┘ Building a Rust WASM Compute Module Add the wasm-bindgen dependency in your Cargo.toml : [package] name = "wasm_ai_engine" version = "0.1.0" edition = "2021" [lib] crate-type = [ "cdylib" ] [dependencies] wasm-bindgen = "0.2" Implement high-speed array processing in src/lib.rs : use wasm_bindgen :: prelude :: * ; #[wasm_bindgen] pub fn process_tensor_data ( inputs : & [ f32 ], multiplier : f32 ) -> Vec < f32 > { inputs .iter () .map (| & x | x * multiplier ) .collect () } #[wasm_bindgen] pub fn compute_cosine_similarity ( vec_a : & [ f32 ], vec_b : & [ f32 ]) -> f32 { let dot_product : f32 = vec_a .iter () .zip ( vec_b .iter ()) .map (|( a , b )| a * b ) .sum (); let norm_a : f32 = vec_a .iter () .map (| a | a * a ) .sum :: < f32 > () .sqrt (); let norm_b : f32 = vec_b .iter () .map (| b | b * b ) .sum :: < f32 > () .sqrt (); if norm_a == 0.0 || norm_b == 0.0 { return 0.0 ; } dot_product / ( norm_a * norm_b ) } Compile directly to WebAssembly: wasm-pack build --target web Integrating into Next.js / Frontend Stack import init , { compute_cosine_similarity } from ' ./pkg/wasm_ai_engine.js ' ; async function runVectorSearch () { await init (); const vec1 = new Float32Array ([ 0.12 , 0.45 , 0.98 ]); const vec2 = new Float32Array ([ 0.15 , 0.42 ,
科技前沿
The largest battery-electric plane ever made has flown for the first time
Heart Aerospace's X1 all-electric demonstrator flew for 27 minutes on just $5 of electricity.
开发者
Morning on a Banana Leaf: A South Indian Breakfast Still Life in CSS
This is a submission for Frontend Challenge - Comfort Food Edition, CSS Art. ...
科技前沿
DJI Mic Mini 2S review: The best tiny mic now offers a pro experience
DJI's Mic Mini 2S offers high-quality audio and ease of use, and it's now better for pros due to the new internal 32-bit float recording.
AI 资讯
My Frontmatter Parser Checks for Too Few Delimiters. It Never Checked for Too Many.
I fixed this script's frontmatter parser a week ago. A draft with an unclosed --- block used to blow up with a bare ValueError: not enough values to unpack , and I patched it to raise a clean, actionable error instead. I wrote that fix up, verified it with a stubbed repro, added a --selftest case for it, called it done. Then I went back to write today's articles and actually looked at the line I "fixed" instead of the error path around it. def parse ( text ): meta = {} body = text if text . lstrip (). startswith ( " --- " ): parts = text . lstrip (). split ( " --- " , 2 ) if len ( parts ) < 3 : raise ValueError ( " frontmatter opened with ' --- ' but never closed with a second ' --- ' delimiter " ) _ , fm , body = parts ... split("---", 2) doesn't split on lines that are --- . It splits on the literal substring "---" , anywhere in the text, and stops after the second one it finds. My fix only handles the case where it finds fewer than two — an unclosed fence. It says nothing about what happens when the second "---" it finds isn't the closing fence at all, because a third one showed up first, buried inside a frontmatter value. That's not a hypothetical. I write these article titles myself, and "before/after" is a phrase I reach for constantly: --- title : My Before---After Refactor tags : ai, python, refactor published : true --- real body starts here split("---", 2) finds the em-dash-style --- inside the title before it finds the real closing fence on its own line. So the split points land in the wrong place entirely: >>> from publish_devto import parse >>> meta , body = parse ( text ) >>> meta { ' title ' : ' My Before ' } >>> body ' After Refactor \n tags: ai, python, refactor \n published: true \n --- \n real body starts here \n ' The title got truncated to "My Before" . tags and published never got parsed as frontmatter fields at all — they're sitting in the body now, as literal text, along with the real closing fence and a stray leftover --- . If I ran this thr