开发者
Python Now Has a Post-Quantum Encryption Library
This is good : Post-quantum cryptography is now one pip-install away for the entire Python ecosystem. With funding from the Sovereign Tech Agency , we implemented support for ML-KEM, the NIST-standard key-establishment primitive, and ML-DSA, the NIST-standard digital-signature primitive, in pyca/cryptography. Remember, the reason to do this now is because there’s no emergency. And because you will make your systems crypto agile, which is always a good idea.
AI 资讯
Ford’s new AI assistant can check your fuel levels and tire pressure
Ford is rolling out a new AI-powered assistant that can answer questions about your Ford or Lincoln vehicle, such as how much fuel you'll need for your next road trip or whether your truck can tow that new motor boat. The app is rolling out first to the Ford and Lincoln mobile apps, where it […]
AI 资讯
Google Releases Angular v22 with Stable Signal Forms, OnPush by Default and Experimental WebMCP
Angular v22, Google's TypeScript-first framework, has introduced API stabilizations, ergonomic templates, and tooling enhancements for AI integration. Key developments include the stabilization of Signal Forms, improved change detection strategies, and a new @Service() decorator for dependency injection. The release supports TypeScript 6 and removes deprecated features. By Daniel Curtis
AI 资讯
The Stale Godot Class Cache Bug That Passed CI but Broke Local Startup
This is a submission for DEV's Summer Bug Smash: Clear the Lineup powered by Sentry . Project overview Nocturne Vania is a small pixel-art Metroidvania built with Godot 4. The game has interconnected rooms, enemy AI, save data, unlockable movement abilities, and a growing automated test suite. I hit this bug after adding a bell tower area. The new rooms, enemies, effects, and map markers used GDScript's class_name keyword so they could be referenced as global types. The new area worked in a freshly imported project and in CI. It did not always work in an existing local checkout. Bug fix or performance improvement Godot stores imported project data under .godot . An editor session that predated the bell tower scripts could still have an old global_script_class_cache.cfg . In that state, starting the game caused a parse error because scripts such as game.gd referred directly to global types that were missing from the stale cache. One room script, for example, inherited from a new global class by name: extends TowerRoom The test code also used the new classes for casts and enum access: var sentinel : = await _test_spawn_enemy ( "res://src/enemies/clockwork_sentinel.tscn" , Vector2 ( 320 , 300 ) ) as ClockworkSentinel if sentinel . _state == ClockworkSentinel . State . CHARGE : charged = true Those references were valid after Godot refreshed its global class registry. Before that refresh, the parser could not resolve them. CI missed the problem because the test workflow imported the project before running the suite. The import regenerated the cache, so CI always tested the healthy state. Local startup followed a different order and exposed the bug. Refreshing or deleting .godot could repair one checkout, but it left the startup dependency in the code. I wanted the game to parse even before the editor rebuilt the cache. Code I merged the complete fix as PR #95 in the project's private repository. Since the repository is not publicly accessible, the relevant before-and-af
AI 资讯
Building SaarDB, Part 6: How SQL Queries Become Key-Value Operations
In Blog 5, we built a SQL parser. It can take this: INSERT INTO payments VALUES ( 500 , payment_1 , pending , 1 ) and turn it into a struct: InsertIntoTable { TableName : "payments" , ColumnValues : [] string { "500" , "payment_1" , "pending" , "1" }, } But this is still not enough for the storage engine. Our storage engine only knows how to store key-value pairs. It does not know what a table is. It does not know what a column is. It does not know that 500 is an integer, pending is a string, and 1 is a boolean. So, in this post we solve the missing bridge of persisting these in our key-value store. CREATE and INSERT are PUT operations This is the first major realisation. A key-value store is extensible to store literally anything. This is what we have been saying from the first post itself. But now we will be taking actual examples to prove that. CREATE TABLE Example Let's start with the create table example and see what should be the key and the value. Serialisation The key should be something that uniquely identifies the table, which is straightforward enough in this case as the table name . The value becomes everything else except the key, which is the schema of the table. So, in order to store the table name, we can append a reserved keyword as prefix like schema as a unique identifier. The structure of the key becomes _schema:<table_name> . The next question to answer is: How do we store a struct like below into our key value store where the value is always string? CreateTable { TableName : "payments" , ColumnDetails : [] Column { { ColumnName : "amount" , DataType : Int }, { ColumnName : "id" , DataType : String }, { ColumnName : "status" , DataType : String }, { ColumnName : "captured" , DataType : Bool }, }, PrimaryKeyColumnPosition : 1 , } One way is to serialise the entire struct into a string and store that directly. But in that case, deserialisation is a complex logic. JSON or struct serialisation and deserialisation is both space-heavy and compute inte
AI 资讯
Cpynet a pastebin you talk to with curl, that forgets everything you send it
A zero-dependency, single-file Go pastebin built for terminals — burn-after-read by default, two independent encryption layers, and a curl one-liner instead of a login form. I keep ending up in situations where I need to move a small piece of text — a log snippet, a password, a container's stdout — from one machine to another, and the clipboard just isn't there. SSH session on a remote box. A locked-down corporate laptop that won't let me touch the OS clipboard at all. A container with no shared volume and no browser. Slack is right there, but pasting a database password into a channel that's archived forever is a special kind of bad idea. So I built CPYNET — a paste-sharing tool with exactly one interface that matters: curl . echo "hello world" | curl --data-binary @- https://cpynet.com/ # https://cpynet.com/482913 curl https://cpynet.com/482913 # hello world That's the whole thing. No account, no API key, no clicking around. Two curl calls and you've moved text between two machines that have nothing in common except a network path. Burn-after-read, actually The paste above is gone the instant that second curl runs. Not "gone in 24 hours" — gone the moment it's read , whether that's one second later or one minute later. Read it twice (even from the same machine) and the second request gets a plain 404 . It also auto-expires on a timer (2 minutes by default) even if nobody ever reads it, so an unread secret doesn't just sit there. None of this lives on disk. It's a Go map behind a mutex, in memory, for the lifetime of one process. Restart the server and every paste that hasn't been read yet is just... gone. That's not a limitation I'm working around — it's the actual point. A "burn after read" tool that persists to disk somewhere you're not thinking about isn't really burning anything. The shell functions, if you don't want to remember the curl flags curl -s https://cpynet.com/install.sh -o install.sh && bash -n install.sh && . install.sh That wires up two functions
AI 资讯
A backup you haven't restored isn't a backup
Migrating from MongoDB Atlas to a self-hosted replica set bought us control and cut our bill. It also quietly removed something we had stopped thinking about: Atlas had been taking continuous backups for us the entire time. After the migration, production data for Prochesta lived in /var/db/mongo on a single VPS. No snapshots. No off-box copy. A rm -rf , a bad migration script, or a dead disk would have been the end of it. We had written "backups" as a follow-up task in the migration spec, which is the engineering equivalent of a sticky note on a bank vault. The requirement we actually cared about was narrower than "back up the database". Most real-world data loss at our scale isn't hardware failure — it's a deploy that writes garbage, or someone running an update without a filter. Recovering to last night doesn't help when the damage happened at 14:20 and you noticed at 14:50. We needed to recover to an arbitrary moment , not to a nightly snapshot. The constraint nobody mentions: Community has no $backupCursor We chose Percona Backup for MongoDB (PBM), and immediately hit the limitation that shapes every decision downstream. PBM offers physical backups — fast file-level copies that restore in minutes and barely touch the running server. They work by opening a backup cursor via the $backupCursor aggregation stage. That stage exists in Percona Server for MongoDB and in MongoDB Enterprise. It does not exist in MongoDB Community, which is what the official mongo:8.0 image ships. So on Community, PBM gives you logical backups only: every document read out through mongod , compressed, and shipped off-box. Two consequences, both accepted deliberately rather than discovered later: Backups cost CPU on the primary — and with a single-member replica set there's no secondary to offload the read to. Restores insert documents and rebuild indexes, so restore time grows with data size much faster than backup time does. At our current size that's minutes, not hours. It's also the t
科技前沿
The downsides of switching from iPhone to Android
If you're considering ditching iOS for an Android device, make sure you know what you might be losing.
开源项目
🔥 pranshuparmar / witr - Why is this running? Trace any process, port, container, or
GitHub热门项目 | Why is this running? Trace any process, port, container, or file back to what started it - CLI + TUI. | Stars: 20,264 | 556 stars today | 语言: Go
开源项目
GitHub doesn't retry webhooks. So I gave my tunnel a database.
Built solo over a weekend for the WeMakeDevs × Zerops challenge. There's a live gateway you can poke...
AI 资讯
These AI Barons Are Ready to Give Away Their Fortunes
A new generation of philanthropists made rich by artificial intelligence are preparing to give away their vast wealth. What should we make of a multi-billion-dollar pinky promise?
AI 资讯
Stripe Uses Graph Search and State Machines to Automate Database Remediation
The engineering team at Stripe recently described how they automated database incident recovery by modeling their global infrastructure as a graph. Using graph search algorithms together with state machines, the team computes and executes remediation plans automatically. By Renato Losio
AI 资讯
Writing terabytes to disk in Go: Stopping the OS Page Cache from eating all your RAM (FADV_DONTNEED)
Hello everyone! This is the second article about the development of RUSEON-core, a Zero-Copy video streaming server for AI platforms and Edge video infrastructure. In the first article , I talked about the fundamental reason why we decided to create our own server in the first place. I also covered the main problem with most similar solutions — the "thundering herd" — and how we managed to squeeze out 8 Gbps on a single CPU core. By the way, I forgot to mention in that article that besides simple streaming, we also record the streams in fMP4 format. It’s stored locally for N amount of time, and it can fly off to an S3 bucket (depending on how long the clients want to keep the recordings). This article is precisely about a non-obvious (well, at least to me, maybe for someone else it's an everyday thing) problem related to data storage and its specifics across all Operating Systems. So, let's dive in. We rolled out our first release to production (100 cameras), made the clients happy, and started working. About an hour passed, and the alerts started flying. I SSH into the server, open htop, and see there's only 100 MB of free RAM. Uh-oh. I should clarify that the production server had 32 gigs of RAM. The expected behavior was that the CPU is chilling, the network card is chewing through the traffic, RAM usage is around 250-300 MB, and the disks are not heavily loaded. So, when you see numbers like that in htop, you start blaming yourself and your crooked hands that wrote this piece of "garbage". But still, we decided to go to Google, ChatGPT, and the like. Fortunately, the answer was found quickly, and we stopped beating ourselves up. The code was absolutely not the culprit; Linux itself ate the memory. If you've ever written tons of data to a disk, I think you already know what’s going on. There is an "invisible enemy" known as the Page Cache. That was exactly the root of this problem. How does the Page Cache work and what to do with it? When your function that is su
开发者
Hey everyone! I recently wrapped up a project migrating 6 separate Go microservice repositories into a unified monorepo setup. I documented the architecture decisions, pipeline setup, and lessons learned here.
Multi-Repo to Monorepo: How I Automated 6 Go Microservice Releases and Then Made It 15x Faster Amandeep Singh Amandeep Singh Amandeep Singh Follow Aug 7 Multi-Repo to Monorepo: How I Automated 6 Go Microservice Releases and Then Made It 15x Faster # go # devops # automation # monorepo 6 reactions 1 comment 10 min read
AI 资讯
I built a friendlier FFmpeg with 36 verbs and a TUI (and it's one line to install)
Mediax: FFmpeg's Cooler Cousin 🚀 FFmpeg is powerful, but the syntax? A nightmare. So I built Mediax. 36 intuitive verbs. Interactive TUI. One-line install. Convert, compress, trim, crop, rotate, add watermarks... all with simple commands. bash mediax convert input.mov output.mp4 mediax compress large.mp4 small.mp4 --quality medium mediax trim video.mp4 clip.mp4 --start 00:01:30 --duration 10 Just run mediax for the interactive terminal interface. One-line install curl -sSL https://raw.githubusercontent.com/robert-sarah/mediax/main/install.sh | sh Built with Go Single binary — no dependencies Cross-platform: Windows, macOS, Linux Open source (MIT) 36 verbs for everything Conversion: convert, compress, gif Audio: extract-audio, mute, volume, replace-audio Video: trim, crop, resize, rotate, flip, concat, split Effects: speed, reverse, blur, sharpen, fade-in, fade-out Advanced: watermark, subtitle, thumbnail, template, batch Examples Resize for Instagram mediax template video.mp4 insta_video.mp4 --platform instagram Extract audio from 1:30 to 1:40 mediax extract-audio video.mp4 clip.mp3 --start 00:01:30 --duration 10 Detect video issues mediax wtf video.mp4 Why I built it I was tired of copying FFmpeg commands from Stack Overflow and breaking files because I forgot a flag. Mediax makes FFmpeg accessible for beginners and faster for pros. Try it today Repo: github.com/robert-sarah/mediax Contributions welcome! 🙏
AI 资讯
Building a Bulletproof Comment Reply System in Node.js & MongoDB 🚀
When building a nested reply system, most developers worry about deep tree complexity or messy data structures. For Vlox , I took a different approach: keeping things flat, fast, and secure by reusing a single Mongoose schema with smart atomic limits. Here is a deep dive into how I engineered a production-ready, race-condition-safe reply mechanism using MongoDB transactions, strict type sanitization, and automated limits. How It Works 🛠️ User Action: A user clicks the reply icon and submits their reply. The Payload: Vlox's system sends 3 fields via the endpoint /api/v1/reply/comment/post/:id : id : The post ID (passed as a URL parameter). rootCommentId : The ID of the root comment being replied to. reply : The raw text entered by the user. Sanitization & Validation: The incoming reply is instantly converted to a trimmed string. It then passes through two critical validation checks: Existence Check: The reply must exist. (If a malicious actor sends a payload without a body, the string literally evaluates to "undefined" and gets blocked). Length Limit: The reply must be under 201 characters, enforcing the standard comment limit. Atomic Transactions: If the validation checks pass, the system initiates a Mongoose transaction to execute the following steps safely: Permission Check: It verifies if the user has permission to reply by checking the post's status via await schemas.Posts.findOne(hotQueries.find_user_post(id, req.session.userId)); . Creation: If permissions are valid, it creates a new reply. (Fun fact: It reuses the exact same schema as standard comments!) The Reply Schema Structure: The reply object functions just like a normal comment, with two distinct exceptions: It does not contain a repliesCount field. It includes an extra rootId field, which explicitly points to the ID of the root comment being replied to. Concurrency & Caps: To guarantee that a single comment never receives more than 10 replies while simultaneously incrementing the counter, the system r
AI 资讯
Google’s top hacker hunter explains why hacking groups get codenames
Google recently changed how it refers and assigns names to hacking groups. TechCrunch spoke with one of the world’s foremost experts on tracking hackers to understand why companies give hackers codenames.
AI 资讯
How We Evolved a Cultural Recommendation Feed From a Weighted SQL Ranker to a Narrative Affinity Model
Building a personalization engine for a multi-format content feed, without machine learning, and the testing process that forced us to rebuild it. TL;DR We run a collaborative cultural curation platform (think: user-submitted recommendations for movies, books, games, music, and long-form posts, all mixed into one feed) on a fairly ordinary PHP + MySQL stack. Over about a year we went through two full generations of the feed ranking algorithm. The first version solved the obvious problem (stop being purely chronological) but quietly failed at real personalization. The second version fixed that by rethinking what "user taste" even means, moving scoring out of SQL and into application code, and adding a layer of post-ranking business rules. This post walks through both generations, why the second one had to happen, and how we actually tested and calibrated a feed ranking system without a data science team or an ML pipeline. No exact weights, table names, or formulas below — just the engineering story. The starting problem: one feed, five content shapes Before personalization is even on the table, a multi-format feed has a normalization problem. Movies, books, games, music, and editorial posts live in different tables, with different columns, different publishing cadences, and engagement numbers on completely different scales. "1,000 likes" on a music post and "1,000 likes" on a book review are not the same signal. So the very first architectural decision — before any ranking logic existed — was building a unification layer that maps every content type into a shared shape (type, author, title, cover, category, engagement counters, timestamp) before any scoring happens. Everything downstream depends on that layer being consistent. Generation 1: a weighted ranker living inside a single SQL query The first real version of the algorithm — internally we called it the hybrid model — had a modest goal: get away from a purely chronological feed without building anything resembl
AI 资讯
Friday Squid Blogging: Arctic Bobtail Squid Video
Nice video of the Arctic bobtail squid. As usual, you can also use this squid post to talk about the security stories in the news that I haven’t covered. Blog moderation policy.
AI 资讯
Dos formas en que un backtest te miente (y cómo evitarlas)
Pruebas una estrategia, o un modelo, sobre datos históricos. El backtest da un número bonito. Y luego, en real, no aparece. Casi siempre es una de estas dos ilusiones — y las dos se descartan con muy poco código. Empaqueté las dos correcciones como librería: honest-eval , Python puro, sin dependencias. Salieron de un bot de trading, pero el rigor no tiene nada de específico al trading. Ilusión 1: el modelo vio el futuro Partir los datos con el clásico train_test_split aleatorio es correcto para datos independientes. En una serie temporal es un desastre silencioso: mete muestras de mañana en el conjunto de entrenamiento, y el modelo "predice" en el test cosas que en producción todavía no habrían pasado. La métrica sale inflada, y confías en un edge que no existe. El test honesto es siempre el futuro : el tramo más reciente en el tiempo. from honest_eval import temporal_split train_idx , test_idx = temporal_split ( timestamps , test_frac = 0.20 , embargo = 24 ) X_tr , X_te = X [ train_idx ], X [ test_idx ] Devuelve índices, así lo aplicas a numpy, pandas o listas por igual. El embargo cierra una fuga más sutil: si tu etiqueta mira h pasos adelante, una muestra de entrenamiento a menos de h del corte ya conoce parte del resultado del test. embargo=h descarta ese borde. La métrica baja — pero por fin es la real out-of-sample . Ilusión 2: la variante ganó por suerte Tienes varias variantes y quieres la mejor. Eliges la de mayor media. Error: con pocas muestras, eso premia la varianza, no la ventaja . La variante más ruidosa suele quedar arriba por azar. Dos correcciones, ambas dentro de select_best_variant : Aparear. Mide variante y baseline sobre el mismo ensayo y trabaja con δ = variante − baseline . La varianza común del ensayo se cancela en la resta, y te quedas con la señal. Exigir cota inferior de confianza > 0. Gradúa una variante solo si media − z·SE > 0 : "incluso siendo pesimista dentro del margen de confianza, sigue por encima del baseline". from honest_eval i