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

标签:#dev

找到 2976 篇相关文章

AI 资讯

Applying SAST to Any Application (Without Sonar, Snyk, Semgrep, or Veracode)

Most "how to add SAST to your pipeline" articles gravitate toward the same four names: SonarQube, Snyk, Semgrep, Veracode. They're solid tools, but they're not the only options, and sometimes you can't use them — budget constraints, air-gapped environments, licensing restrictions, or simply wanting something lightweight that lives entirely in your repo. The OWASP Source Code Analysis Tools page lists dozens of alternatives across every language. In this article I'll walk through applying Bandit , a free, open-source SAST tool for Python, to a real sample application — from finding vulnerabilities locally to wiring it into a CI/CD pipeline with GitHub Actions. The same workflow (install → configure → scan → fail the build on high-severity findings → track results over time) applies almost identically if you swap Bandit for other OWASP-listed tools like Brakeman (Ruby), FindSecBugs (Java), Gosec (Go), or Horusec (multi-language). Why Bandit? 100% open source (Apache 2.0), maintained under the PyCQA org. No account, no server, no license key — it runs as a CLI or a library. Understands Python's AST, so it catches real logic patterns, not just regex matches. Easy to tune with a config file and inline # nosec suppressions. ## 1. The sample application Let's use a small Flask app with a few intentionally introduced vulnerabilities — the kind of thing that slips into real codebases under deadline pressure. # app.py import subprocess import sqlite3 import pickle import yaml from flask import Flask , request app = Flask ( __name__ ) DB_PATH = " users.db " @app.route ( " /ping " ) def ping (): host = request . args . get ( " host " ) # Vulnerable: command injection via shell=True result = subprocess . run ( f " ping -c 1 { host } " , shell = True , capture_output = True ) return result . stdout @app.route ( " /user " ) def get_user (): user_id = request . args . get ( " id " ) conn = sqlite3 . connect ( DB_PATH ) cursor = conn . cursor () # Vulnerable: SQL injection via strin

2026-07-09 原文 →
AI 资讯

7 Dockerfile Mistakes That Are Quietly Costing You

Most Dockerfiles work. That's the problem — "it builds and runs" hides a lot of quiet costs in security, speed, and size that don't announce themselves until an audit, an incident, or a cloud bill does it for them. Here are seven mistakes I see constantly, and what to do instead. 1. Running as root By default, the process in your container runs as root — and if someone breaks out, they're root on a surface they shouldn't be. Add a non-root user and switch to it: RUN useradd --system --uid 10001 appuser USER appuser Cheap, and it closes off a whole category of "well, at least it wasn't root" incidents. 2. FROM some-image:latest latest is not a version — it's "whatever was newest when this happened to build." Two builds a week apart can produce different images with no diff to explain it, and a surprise base upgrade is a fun way to spend a Friday. Pin a specific tag, ideally by digest: FROM node:20.11.1-slim 3. Baking secrets into layers COPY .env . or ARG API_KEY followed by using it — and now the secret lives in an image layer forever , recoverable by anyone who pulls the image, even if a later layer deletes the file. Layers are immutable and additive; you can't delete your way out of a leak. Use build secrets ( --mount=type=secret ) or inject at runtime, never at build. 4. No .dockerignore Without one, COPY . . sweeps your .git directory, local env files, node_modules , and test data into the build context — bloating the image and, worse, potentially baking credentials and history into a layer. A five-line .dockerignore is one of the highest-leverage files in the repo. 5. Layer order that destroys your cache COPY . . RUN npm ci # ← reinstalls on EVERY code change Docker invalidates every layer after the first change. Copy the lockfile and install dependencies before copying the rest of your source, so a one-line code change doesn't trigger a full reinstall. This is a build-speed bug hiding as a style choice. 6. Leaving package manager cruft in the image RUN apt-get

2026-07-08 原文 →
AI 资讯

Requests hang forever: why missing timeouts cause recurring outages in .NET

This post was originally published on MatrixTrak.com — the production reliability toolkit for trading bot operators and .NET engineers. When requests hang forever and recycling releases stuck work: why missing timeouts create backlog, how to add budgets safely, and the rollout plan that prevents new incidents.. Most production incidents do not start as "down." They start as waiting. At 09:12 a dependency slows down. Your ASP.NET instances look healthy. CPU is fine. Memory is fine. But requests stop finishing. In-flight count climbs. Connection pools stop turning over. You scale out and it does not help because the new instances just join the waiting. The cost is not subtle. Backlog grows, SLAs fail, and on-call starts recycling processes because it is the only thing that releases the stuck work. Then the incident repeats next week because nothing changed about the waiting. This post gives you a production playbook for .NET: how to set time budgets, wire cancellation, and roll it out without triggering a new outage. Rescuing an ASP.NET service in production? Start at the .NET Production Rescue hub . If you only do three things Write down a total budget per request/job (then enforce it). Set per-attempt timeouts for each dependency and log elapsedMs , timeoutMs , and the decision (retry/stop/fallback). Propagate cancellation end-to-end so work stops (no zombie work after timeouts). Why requests hang forever: infinite waits capture capacity Missing timeouts are not a performance problem. They are a capacity problem. When a call can wait forever, it will eventually wait longer than your system can afford. While it waits, it holds something your service needs to operate: a worker slot, a thread, a connection, a lock, or a request budget. Once enough requests or jobs are holding those resources, the system stops behaving like a service and starts behaving like a queue you did not design. From the outside it looks like "everything is slow." Underneath, you are accumulating

2026-07-08 原文 →
AI 资讯

I Built a Platform Where Developers Can Document Their Products Before They Even Launch

I Built a Platform Where builders Can Document Their Products Before They Even Launch One thing I've learned after building side projects is that writing code isn't the hardest part. Getting people to notice what you've built is. Every time I finished a project, I'd launch it on a few platforms, share it on X, and hope someone would find it. Sometimes I'd get a few users, but after a day or two, the momentum was gone. It made me realize something. Most platforms are designed for the launch, not the journey. But as developers, the journey is where the interesting stuff happens. You fix bugs, redesign the UI three times, celebrate your first user, rewrite your backend, and slowly turn an idea into a real product. Those moments are worth sharing too. So I started building LaunchDock.space . The idea is simple. Instead of only launching finished products, developers can also create a page for projects that are still in development and post daily progress updates. Think of it as a place to build in public, document your progress, and grow an audience before your product is even ready. Along with development logs, LaunchDock lets makers: Launch finished products. Discover tools built by other builders. Follow the progress of other makers. Connect with a community that enjoys discovering new projects. I'm building LaunchDock with React, TypeScript, Node.js, Express, MongoDB, and Cloudflare R2, keeping the stack simple and focused on performance. The project is still evolving, and I'm shipping new features regularly. Building it has taught me a lot about product design, user feedback, and the importance of consistent shipping. I'd love to hear your thoughts. If you were using a platform like this, what feature would make you come back every day?

2026-07-08 原文 →
AI 资讯

How Secure is Your Password? Calculating Shannon Entropy in the Browser

We've all seen password strength meters on sign-up forms. Most of them rely on simplistic, static rules: "Must contain at least 8 characters, one number, and one special character." But from a mathematical standpoint, these rules are a poor proxy for actual password security. A password like Tr0ub4dor&3 conforms to these rules but is far easier to compromise than a randomly generated four-word passphrase like correct-horse-battery-staple . To truly measure password security, we have to look at information theory and compute its Shannon Entropy . Here is how password entropy works, the math behind it, and how you can calculate it directly in the browser with 100% client-side privacy. What is Password Entropy? In cryptography, entropy is a measure of the unpredictability or randomness of a password. It is expressed in bits . An entropy of $N$ bits means there are $2^N$ possible combinations that an attacker would have to guess in a worst-case brute-force search. < 28 bits: Very weak (easily guessed in milliseconds). 28 to 35 bits: Weak (cracked in minutes or hours). 36 to 59 bits: Reasonable protection (days to months). 60 to 127 bits: Very strong (takes years to decades to crack). 128+ bits: Extremely secure (mathematically unfeasible to crack). The Mathematical Formula To calculate the entropy ($E$) of a password, we use the following equation: $$E = L \times \log_2(R)$$ Where: $L$ is the length of the password (number of characters). $R$ is the size of the pool of unique characters from which the password is drawn. $\log_2(R)$ is the binary logarithm of the pool size, representing the amount of information carried by each character. Determining Pool Size ($R$) To find $R$, we analyze which character sets are present in the password string: Lowercase letters ( a-z ): 26 characters Uppercase letters ( A-Z ): 26 characters Numbers ( 0-9 ): 10 characters Common special characters/punctuation: 33 characters (e.g., !@#$%^&*()-_=+[]{}|;:',.<>/? etc.) If a password uses ch

2026-07-08 原文 →
开发者

MarkDown - что это?

MarkDown - что это? [[Markdown]] — это язык разметки, с упрощенным до человекочитаемости синтаксисом. Markdown — создан Джоном Грубером ( John Gruber ) в 2004 году. Markdown — это фактически "микро" язык для трансляции "текста markdown"в подмножество языка XHTML. Markdown - итоговая презентация текста всегда документ HTML , и только потом если нужно следующим шагом PDF, др. стандарты документации. Markdown принципиально не может задействовать весь потенциал XHTML, результатом его работы всегда является ограниченный набор элементов. Markdown — это транслятор который при анализе интегрированного в "текст" markdown HTML/XHTML кода обязан по стандарту просто его транслировать в итоговый образ документа. Markdown — это, если цитировать автора > «Markdown — это инструмент преобразования текста в HTML для веб-писателей. Markdown позволяет писать в легко читаемом и удобном для написания текстовом формате, а затем преобразовывать его в структурно корректный HTML. ║ John Gruber » Примечание Термин транслятор , не обходимо понимать как сущность алгоритм Я не нашел программу реализующая концепт MarkDown по принципам John Gruber. Ни одна программа не умеет делать из Markdown валидный по John Gruber HTML. Все проверенные мною программы Obsidian, MarkText, Typora, на выходе из 10 строк генерируют портянку HTML в несколько тысяч строк!!! Причина Obsidian, Typora и MarkText используют Markdown не для веб-писателей и блогеров, а как формат хранения баз знаний (Knowledge Management)**. John Gruber - Wikipedia

2026-07-08 原文 →
AI 资讯

The API-First SaaS Manifesto: How to Architect a Production-Grade Application in 2026 Without Building Microservices

Every junior developer or solo software engineer falls into the exact same engineering trap: They conflate writing code with building a business. They spend their initial excitement phase setting up intricate user database authentication schemas, writing custom cron jobs for automated subscription reminders, or building heavy background pipelines just to resize a user’s uploaded logo image. By the time their local environment is "infrastructure perfect," weeks have passed. The momentum is gone, burnout sets in, and the repository is abandoned before ever tasting real production traffic. In 2026, computing power has completely shifted to specialized edge layers. Infrastructure has become commoditized. If you are wasting creative bandwidth trying to compete on backend pipelines instead of focusing entirely on your unique value proposition, you are systematically killing your startup. Here is the architectural matrix to decouple your operational infrastructure and shift to a lean, hyper-scalable API-first codebase. Part 1: The Production Infrastructure Decoupling Layer The golden rule of modern systems design is clear: Your application should only maintain two core pillars internally—your proprietary business logic and your core user state database. Everything else—from security to user tracking—is a solved problem that should be offloaded to third-party micro-services. Let’s look at the financial and time trade-offs of building versus outsourcing across critical technical vectors: Microservice Vector The Native Way (High Friction) The 2026 API Standard Launch Velocity Impact Merchant of Record Raw Stripe API + Custom Tax Calculators Lemon Squeezy / Paddle Saves 5 days of legal & accounting setup Feature Rollouts Custom Postgres feature-flag logic loops GrowthBook / LaunchDarkly Zero deployment overhead for major pivots Customer Feedback Manual tables + Admin CRUD boards Featurebase API Instant roadmaps directly inside frontend Media Compression AWS S3 triggers + Edge

2026-07-08 原文 →
AI 资讯

Terraform LifeCycle Rules

Day 9 of the 30 Days of AWS Terraform series focuses on Terraform Lifecycle Rules — powerful controls that decide how Terraform creates, updates, replaces, and destroys resources. What Terraform LifeCycle meta arguments are Lifecycle meta arguments allow us to control how Terraform behaves when it creates, updates, or destroys resources. They help us: Avoid downtime Protect important resources Handle changes made outside Terraform Validate configurations before and after deployment Enforcing compliance Controlling replacement behavior Lifecycle rules allow us to override default behavior safely. Lifecycle rules are Terraform-native controls applied inside a resource block: lifecycle { ... } Lifecycle Rules Covered 1️⃣ create_before_destroy — Zero Downtime Updates Problem: Terraform destroys the old resource before creating the new one → downtime. Solution: lifecycle { create_before_destroy = true } Behavior: New resource is created first Old resource is destroyed only after Ensures zero downtime 2️⃣ prevent_destroy — Protect Critical Resources This setting prevents Terraform from deleting a resource. Example If Terraform tries to destroy this resource, it will fail with an error. This is useful for: Production databases State storage buckets Important data resources 3️⃣ ignore_changes — Allow External Modifications Problem: Terraform overwrites manual or automated external changes. Solution: lifecycle { ignore_changes = [desired_capacity] } Demo: Auto Scaling Group desired capacity modified manually in AWS Console terraform apply did not revert the change Behavior: Terraform ignores changes for specified attributes. ✅ Use for: Auto Scaling Groups Resources modified by external systems Ops-driven configurations 4️⃣ replace_triggered_by — Replace When Dependency Changes Problem: Changing a dependency doesn’t always recreate dependent resources. Solution: lifecycle { replace_triggered_by = [aws_security_group.main] } Behavior: When security group changes EC2 instance i

2026-07-08 原文 →
AI 资讯

Migrating from node_exporter to Grafana Alloy, One Server at a Time

If you've been monitoring Linux servers for any length of time, there's a good chance node_exporter was the first thing you installed. It's lightweight, reliable, and exposes a huge amount of machine metrics for Prometheus to scrape. For years, it has been the default answer. As your infrastructure grows, though, your monitoring stack usually grows with it. First comes log collection. Then traces. Before long you're running node_exporter , a log shipper, and maybe another telemetry agent. Each component has its own configuration, service unit, upgrade cycle, and failure modes. Grafana Alloy changes that by consolidating those responsibilities into a single telemetry agent. This post walks through migrating from node_exporter to Alloy on a real fleet, one server at a time, while maintaining continuous visibility throughout the process. These are the exact steps that survived contact with production on the Irin monitoring stack, not the idealized version that looks clean in a diagram. TL;DR If you're already running node_exporter , don't replace it overnight. Install Grafana Alloy alongside it, configure Alloy's built-in prometheus.exporter.unix component, verify that metrics are reaching your remote Prometheus instance, and only then retire node_exporter. Migrating one server at a time minimizes risk, preserves visibility, and positions your infrastructure for logs, traces, and future telemetry without deploying additional agents. The real difference is the direction of travel Before getting started, it's worth understanding what actually changes. This isn't simply replacing one monitoring agent with another. node_exporter is a server. It listens on a port, typically 9100,and waits for Prometheus to connect and scrape metrics. That means every monitored machine needs an open endpoint, network connectivity from Prometheus, firewall rules, and scrape configurations. Alloy flips that model around. Instead of waiting for Prometheus to connect, Alloy collects metrics loca

2026-07-08 原文 →
AI 资讯

Integrating Git Submodules the Easy Way

Git submodules have a reputation for being fiddly, but most of that pain comes down to a handful of missing commands and one config flag nobody mentions. Used well, they're a clean way to embed a shared library, a design-system repo, or a common docs folder inside another project - pinned to an exact commit so nothing shifts under your feet. This guide walks through the whole lifecycle, from adding a submodule to removing it, and calls out the gotchas that bite teams in real projects. Understanding What a Submodule Actually Is Before the commands, one mental model that clears up most confusion: a submodule embeds another git repo inside yours at a fixed path, pinned to a specific commit. Your repo doesn't track the submodule's files - it tracks which commit of the submodule to check out. That single idea explains almost every quirk that follows. Adding a Submodule Adding one is a single command: git submodule add git@github.com:org/shared-lib.git vendor/shared-lib This clones the repo into vendor/shared-lib , creates a .gitmodules file describing the mapping, and stages the pinned commit (git calls this a "gitlink"). Commit both pieces: git add .gitmodules vendor/shared-lib git commit -m "chore: add shared-lib submodule" The resulting .gitmodules entry is plain text and lives in version control: [submodule "vendor/shared-lib"] path = vendor/shared-lib url = git@github.com:org/shared-lib.git branch = main The branch line is optional: it's only used later when pulling the latest changes automatically. Cloning Without the Empty-Folder Surprise The most common submodule complaint is a teammate cloning the project and finding an empty folder where the submodule should be. The fix is knowing two commands: # Clone everything in one shot git clone --recurse-submodules <your-repo-url> # Already cloned? Initialize after the fact git submodule update --init --recursive Even better, run this once per machine so git pull and git checkout keep submodules in sync automatically - a

2026-07-08 原文 →
开发者

JavaScript Functions: Basic Concepts You Should Know

Introduction When learning JavaScript, one of the first concepts you’ll encounter is functions. Functions are the building blocks of JavaScript. They help you organize code, avoid repetition, and make your programs easier to understand. If variables store data, functions define behavior . You’ll use functions everywhere: handling user input, processing data, calling APIs, and structuring your code. In this article, we’ll cover: What is a function Function declarations Function expressions Parameters vs arguments Return values Arrow Functions Why Functions Matter 1. What is a Function? A function is a reusable block of code designed to perform a specific task. Think of it like a machine: Input → Process → Output function greet () { console . log ( " Hello! " ); } To run the function, you call it: greet (); // Hello! 2. Function Declaration This is the most common way to define a function: function add ( a , b ) { return a + b ; } 💡 Explanation: Defined using the function keyword Can be called before it is declared (because of hoisting) Key parts: function → keyword add → function name a, b → parameters return → output value add (); // ✅ Works! function add ( a , b ) { return a + b ; } 💡 Why does this work? JavaScript reads the code first, and function declarations are stored in memory during the initial phase (hoisting) . That’s why you can call the function even before it’s defined in the code. 3. Function Expressions Functions can also be stored in variables: function add ( a , b ) { return a + b ; } 💡 Explanation: Assigned to a variable Cannot be used before initialization add (); // ❌ Error: Cannot access before initialization const add = function ( a , b ) { return a + b ; }; 💡 Why does this cause an error? Because: const add has not been initialized yet when it is called. The function itself is not in memory at that moment . 4. Parameters vs Arguments This is a common beginner confusion: Parameter: variable in function definition Argument: actual value passed i

2026-07-08 原文 →
AI 资讯

Make your content answer-first so AI models actually cite it

If you want ChatGPT or Google's AI Overviews to quote your pages, structure matters more than volume. Retrieval systems favor passages where the answer is stated plainly and can stand alone. Here's a practical way to test and fix your content. Step 1 — Define the question the page answers Write it as a literal user query. How much does a website cost for a small business in the UK? Step 2 — Extract your current answer passage Copy the first two or three sentences from your page. Paste them somewhere without any extra context. Ask yourself: Does this work as a direct answer? If it only makes sense after reading earlier paragraphs, it doesn’t pass the extraction test. Step 3 — Rewrite answer-first Lead with the conclusion, stated as a fact, then support it. Before: "We get asked about pricing a lot, and honestly it's one of the trickiest questions to answer..." After: "A small-business website in the UK typically costs £1,500–£6,000 for a brochure site and £6,000–£20,000+ for e-commerce. The price depends on three things: page count, payment functionality, and custom vs template design." Step 4 — Test extractability with a model Send the passage to an LLM and check whether it returns a clean, single answer. Use a system prompt that mimics retrieval behavior. System: You are a retrieval system. From the passage below, extract the single most direct answer to the user's question. If no self-contained answer exists, reply "NO_EXTRACTABLE_ANSWER". User question: How much does a website cost for a small business in the UK? Passage: If you get NO_EXTRACTABLE_ANSWER or a vague summary, your structure needs work. Step 5 — Reinforce with structured data Markup question and answer pages with FAQPage schema so the question/answer pairing is machine-readable as well as human-readable. json { " @context ": " https://schema.org ", "@type": "FAQPage", "mainEntity": [{ "@type": "Question", "name": "How much does a website cost for a small business in the UK?", "acceptedAnswer": { "@t

2026-07-08 原文 →
AI 资讯

Install Docker on Ubuntu: APT, Snap, Rootless — Complete Guide 2026

Installing Docker on Ubuntu should be simple, but in practice several Docker-shaped options compete for the same command name, each with different packaging, upgrade behavior, and security implications. This guide compares every major install path so you can pick the one that fits your machine. The options you will encounter include: docker.io from Ubuntu repositories docker-ce from Docker's official APT repository Docker from Snap Docker Desktop manually downloaded .deb packages the Docker convenience script rootless Docker Although they all provide container tooling, they are not interchangeable packages. The best choice depends on whether the machine is a developer workstation, a CI runner, a small server, a self-hosting box, or a production host. My default recommendation is calm but firm: for most technical users on normal Ubuntu machines, install Docker Engine from Docker's official APT repository. Use Ubuntu's docker.io only when distribution integration matters more than upstream Docker packaging. Avoid the Snap package unless you specifically want Snap behavior and understand its limits. Rootless Docker is worth knowing about, but it is not automatically the best default for every machine. This guide explains the tradeoffs, covers post-install security, and gives you clean installation paths for each method. Once Docker Engine is running, the Docker Cheatsheet is your daily command reference, and the Docker Compose Cheatsheet covers multi-container setups. Both sit alongside Git, VS Code, and CI/CD guides in Developer Tools: The Complete Guide to Modern Development Workflows . Quick Recommendation The table below summarizes which install path fits common scenarios. Use case Recommended install Developer workstation Docker official APT repo CI runner Docker official APT repo, version pinned if needed Small self-hosted server Docker official APT repo Production server Docker official APT repo, controlled upgrades Ubuntu-only conservative system Ubuntu docker.

2026-07-08 原文 →
AI 资讯

Is True Database Elasticity Still a Myth?

Is True Database Elasticity Still a Myth? A New Reality Unfolds Introduction For years, the promise of truly elastic, "serverless" databases felt like a mirage in the desert of database management. We were told of systems that could scale to zero during idle periods and burst to handle monumental loads, all while paying only for what we used. The reality, however, often fell short: many solutions were merely cleverly packaged auto-scaling groups, saddling organizations with expensive idle costs and the persistent headache of capacity planning. This bred a healthy skepticism among developers and operations teams alike. Fortunately, that narrative is finally shifting. A new generation of distributed database architectures is emerging, fundamentally redefining what "elasticity" means. These aren't just incremental improvements to connection pooling or replica sets; they represent a paradigm shift towards truly decoupled compute and storage layers, enabling dynamic resource allocation at an unprecedented, granular level – even per query. This tutorial will explore this architectural evolution and demonstrate conceptually how it delivers on the long-awaited promise of genuine pay-as-you-go database services. Understanding the Architecture: A Conceptual Walkthrough The core innovation driving this new wave of elasticity lies in the complete decoupling of compute and storage layers . Traditionally, a database instance (a VM or container) held both its processing power (CPU, RAM) and its local storage. Scaling meant provisioning larger instances or adding more replicas, each with fixed compute and storage capacities, leading to inefficiency. In the modern elastic database, these functions operate independently: Storage Layer: This is a highly distributed, shared storage fabric – often an optimized, resilient object store – that handles data persistence, replication, and durability. It scales automatically based on your data volume, and you typically pay only for the storage

2026-07-08 原文 →
AI 资讯

Why Software Can't Tell You It's Wrong

Software architecture debates have a problem that most other engineering disciplines don't: the alternative was never built. When a bridge fails, the failure is physical, attributable, and measurable against every other bridge that didn't. The engineering decisions that caused it can be isolated, traced, and corrected — not just in theory, but in the next bridge, because the material itself produces feedback that no amount of professional opinion can override. Steel deflects. Concrete cracks. Physics doesn't care what the architect believed. Software produces no equivalent feedback. A system built around the wrong abstractions compiles, runs, ships, and passes its tests just as readily as one built around the right ones. A bug introduced by a misaligned domain model looks identical, from the outside, to a bug introduced by a typo. A feature that took three times longer than it should have, because the structure made it harder than the business logic warranted, produces no artifact that distinguishes it from a feature that was simply difficult. The cost is real. The cause is invisible. This is the unfalsifiability problem, and it runs deeper than "we can't measure everything." It means that when a system becomes expensive to change, the diagnosis almost always lands on the wrong variable. The domain is complex. The requirements changed. The previous team was careless. Almost never: the structure was wrong, and the structure was wrong because nobody ever built the other version of it to compare against. That version doesn't exist, it never will, and every architectural argument in the industry is conducted in its absence. This would be a purely philosophical problem if there were nothing to do about it. There is something to do about it — but it requires accepting that the standard metric for software quality, whether it works, is measuring the wrong thing entirely. The Metric That Hides the Problem The natural substitute for "is this good engineering" is "does it wor

2026-07-08 原文 →
AI 资讯

Probing FFmpeg's av1_vulkan encoder: does your GPU actually support it?

TL;DR FFmpeg 8.x includes av1_vulkan , the first cross-vendor GPU AV1 encoder in mainline FFmpeg. We'll probe whether your GPU + driver actually expose AV1 encode, run a first working encode, benchmark it against SVT-AV1 on your own content, and talk about which jobs deserve it. 📦 Code: github.com/USER/repo (replace before publishing) Until FFmpeg 8.0 ("Huffman", released August 2025), GPU AV1 encoding meant picking a vendor: av1_nvenc for NVIDIA RTX 40+, av1_amf for AMD, av1_qsv for Intel Arc. Three code paths, three sets of flags, three driver stacks. The Vulkan Video encode work gives FFmpeg one encoder that reaches all three vendors through the standard VK_KHR_video_encode_av1 extension. The catch: driver support is a lottery. Plenty of capable hardware sits behind drivers that don't expose the encode extension yet. So before any pipeline decisions, we probe. 1. Check what you're running You want FFmpeg 8.x (8.1.2 is current as of late June 2026) built with Vulkan support, plus the vulkaninfo tool from the Vulkan SDK / vulkan-tools package. $ ffmpeg -version | head -1 ffmpeg version 8.1.2 Copyright ( c ) 2000-2026 the FFmpeg developers $ ffmpeg -hide_banner -encoders | grep vulkan V....D av1_vulkan AV1 ( Vulkan ) ( codec av1 ) If av1_vulkan doesn't appear, your build wasn't compiled with --enable-vulkan (distro packages vary; the BtbN static builds and most 8.x distro packages include it). 2. Probe the driver for AV1 encode 🔍 The encoder existing in FFmpeg means nothing if the driver doesn't expose the extension. This is the step that separates "should work" from "works": $ vulkaninfo | grep -iE "video_encode_(av1|queue)" VK_KHR_video_encode_av1 : extension revision 1 VK_KHR_video_encode_queue : extension revision 12 You see Meaning Both extensions listed You can encode AV1 via Vulkan 🎉 Only video_encode_queue Driver does Vulkan encode, but not AV1 (maybe H.264/H.265 only) Neither Driver too old, or GPU lacks an AV1-capable video engine Rough hardware floor: the

2026-07-08 原文 →
AI 资讯

Ship a 'Go Live' button: OBS in, LL-HLS out, webhooks in between

TL;DR We're adding live streaming to a SaaS dashboard: a backend endpoint that creates a stream, OBS as the broadcaster over RTMPS, LL-HLS playback with hls.js, and a webhook handler that keeps the UI honest. Working "go live" flow in an afternoon. 📦 Code: github.com/USER/repo (replace before publishing) Webinars, coaching sessions, company town halls: sooner or later your product gets the "can users go live?" ticket. The hard parts (ingest servers, transcoding, CDN delivery) are exactly the parts you should not build. We'll use FastPix as the managed layer here; the same flow works nearly line-for-line on Mux, Cloudflare Stream, or api.video. What we're building: A backend endpoint that creates a live stream and returns a stream key An OBS setup broadcasters can follow in two minutes A viewer page playing LL-HLS with hls.js A webhook handler that flips the webinar between scheduled → live → ended 1. Create the stream server-side 🛠️ You need API credentials (Access Token ID + Secret Key). FastPix uses Basic auth on the server API. Node 20.x, plain fetch , no SDK required (though official Node.js/Python/Go/Ruby/PHP/Java/C# SDKs exist if you prefer). // server/routes/streams.js import { Router } from " express " ; const router = Router (); const AUTH = " Basic " + Buffer . from ( ` ${ process . env . FP_TOKEN_ID } : ${ process . env . FP_SECRET } ` ). toString ( " base64 " ); router . post ( " /webinars/:id/stream " , async ( req , res ) => { const r = await fetch ( " https://api.fastpix.io/v1/live/streams " , { method : " POST " , headers : { " Content-Type " : " application/json " , Authorization : AUTH }, body : JSON . stringify ({ playbackSettings : { accessPolicy : " public " }, }), }); if ( ! r . ok ) return res . status ( 502 ). json ({ error : " stream create failed " }); const stream = await r . json (); // persist against your webinar row: // streamId, streamKey (SECRET!), playbackId await db . webinar . update ( req . params . id , { streamId : stream . str

2026-07-08 原文 →
AI 资讯

MCP Servers: The Bridge Connecting Your AI to the Real World

Imagine being able to ask your AI assistant to review your code on GitHub, query a database, or draft a report in your favorite productivity tool, all from a single conversation. That's exactly what the Model Context Protocol (MCP) makes possible. An MCP Server acts as a universal translator. It allows your AI client (like Claude, VSCode, or Cursor) to communicate in a standardized way with external data sources and tools. It transforms your AI from an "isolated chat" into an assistant that can actually execute tasks in your working environment. The Power of Connection: Clients and Servers The beauty of MCP lies in its flexibility. A single MCP server can connect to multiple clients. This means you can set up your server once and use it across different platforms. According to the official documentation, you can install and connect MCP servers to popular clients like: Claude Desktop & Claude Code: For conversational and command-line interactions VS Code & Cursor: For seamless integration with your development environment GitHub Copilot CLI: To extend your coding assistant's capabilities Zed, Gemini CLI, Goose, and many more: The list keeps growing, demonstrating widespread adoption of the protocol ## How to Configure It: A Quick Look Configuration is usually straightforward and relies on JSON files. For many clients, you just need to specify the command to run your server. For example, to add a filesystem server to a VSCode project, you'd create a .vscode/mcp.json file with content like this: { "servers" : { "filesystem" : { "command" : "npx" , "args" : [ "-y" , "@modelcontextprotocol/server-filesystem" , "/path/to/your/project" ] } } } This file tells VSCode how to start the server. Configuration can be at the project level (to share with your team) or global (for personal use across all your projects). Your First Server: A Practical Example Building your own MCP server is more accessible than it might seem. The official TypeScript/JavaScript SDK lets you create a

2026-07-08 原文 →