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

标签:#acti

找到 59 篇相关文章

AI 资讯

Struct Embedding in Go: Composition That Bites When You Reach for Inheritance

Book: The Complete Guide to Go Programming Also by me: Thinking in Go (2-book series) — Complete Guide to Go Programming + Hexagonal Architecture in Go My project: Hermes IDE | GitHub — an IDE for developers who ship with Claude Code and other AI coding tools Me: xgabriel.com | GitHub You come to Go from a language with classes. You see struct embedding for the first time, and it reads like inheritance. A field with no name, methods that "carry over" to the outer type, a base struct that your type extends. So you write code the way you always have, and most of it works. Then a method does something you did not ask for, a type satisfies an interface you never meant to implement, or two embedded types fight over a name and the compiler shrugs until the exact line that calls it. Embedding is not inheritance. It is composition with a syntax that promotes methods and fields up one level. Once you hold that distinction, the surprises stop being surprises. Here is where they come from. Embedding promotes, it does not subclass Write an embedded field by giving a type with no field name: type Engine struct { Horsepower int } func ( e Engine ) Start () string { return "vroom" } type Car struct { Engine // embedded Brand string } Car now has a Start method and a Horsepower field, both promoted from Engine . You can write car.Start() and car.Horsepower as if they were declared on Car . car := Car { Engine : Engine { Horsepower : 300 }, Brand : "Fiat" } fmt . Println ( car . Start ()) // vroom fmt . Println ( car . Horsepower ) // 300 This is where the inheritance illusion starts. car.Start() is sugar. The compiler rewrites it to car.Engine.Start() . The receiver of Start is still an Engine , never a Car . There is no base class, no super , no virtual dispatch. Engine does not know Car exists. That last point is the one that bites. A promoted method runs against the embedded value, not the outer struct. The method that ignores the outer struct Say you want a stringer on the embe

2026-06-14 原文 →
AI 资讯

defer in Loops: The Resource Leak Go Still Lets You Write

Book: The Complete Guide to Go Programming Also by me: Thinking in Go (2-book series) — Complete Guide to Go Programming + Hexagonal Architecture in Go My project: Hermes IDE | GitHub — an IDE for developers who ship with Claude Code and other AI coding tools Me: xgabriel.com | GitHub You wrote a function that walks a directory and reads every file. It opened cleanly in review. It passed tests on a fixture folder with three files. Then a customer pointed it at a folder with 20,000 files, and the logs filled with: open /data/batch/img-08431.png: too many open files The code never closed anything early. It deferred every close. And that is exactly the problem. defer runs at function return, not end of iteration defer schedules a call to run when the surrounding function returns. Not when the current block ends. Not when the loop iteration ends. When the function returns. Most of the time that distinction does not matter, because most deferred calls live in short functions that return quickly. Put a defer inside a for loop, though, and every iteration adds one more deferred call to a stack that does not unwind until the whole loop is done and the function exits. Here is the version that ships: func processFiles ( paths [] string ) error { for _ , p := range paths { f , err := os . Open ( p ) if err != nil { return err } defer f . Close () // runs at RETURN, not here if err := handle ( f ); err != nil { return err } } return nil } Read it the way the language reads it. On the first iteration, os.Open returns a file handle and you defer its close. On the second iteration, another handle, another deferred close. By the time the loop has touched 20,000 files, you are holding 20,000 open descriptors, and not one of them closes until processFiles returns. Your process has a file-descriptor limit. On Linux the soft default is often 1024. You blow through it somewhere around the 1024th file, and the error you get back says nothing about defer . It says too many open files , wh

2026-06-14 原文 →
AI 资讯

How to Format SQL Queries in Python: Best Practices, Gotchas, and Real-World Examples

Stop writing SQL strings that look like a ransom note. Here's how to write queries that are readable, safe, and maintainable. The Problem With "Good Enough" SQL Formatting Most Python developers start here: user_id = 5 query = " SELECT * FROM users WHERE id = " + str ( user_id ) cursor . execute ( query ) It works. Until it doesn't — and when it breaks, it breaks badly : SQL injection, cryptic errors from mismatched types, and queries that take 45 minutes to debug at 2am. Let's fix that, permanently. 1. Never Concatenate User Input — Use Parameterized Queries This is rule #1 and it's non-negotiable. ❌ The Wrong Way (SQL Injection Waiting to Happen) username = request . args . get ( " username " ) # Could be: ' OR '1'='1 query = f " SELECT * FROM users WHERE username = ' { username } '" cursor . execute ( query ) If username is ' OR '1'='1 , your entire users table just got exposed. ✅ The Right Way: Parameterized Queries username = request . args . get ( " username " ) # psycopg2 (PostgreSQL) cursor . execute ( " SELECT * FROM users WHERE username = %s " , ( username ,)) # sqlite3 cursor . execute ( " SELECT * FROM users WHERE username = ? " , ( username ,)) # SQLAlchemy Core from sqlalchemy import text result = conn . execute ( text ( " SELECT * FROM users WHERE username = :name " ), { " name " : username }) The database driver handles escaping. You never touch it. This pattern is immune to SQL injection by design. Gotcha: Note the trailing comma in (username,) . Without it, Python treats the string as an iterable and passes each character as a separate parameter. This is one of the most common beginner bugs. # 💥 Bug: passes ('a', 'l', 'i', 'c', 'e') instead of ('alice',) cursor . execute ( " SELECT * FROM users WHERE username = %s " , ( username )) # ✅ Correct: single-element tuple cursor . execute ( " SELECT * FROM users WHERE username = %s " , ( username ,)) 2. Multi-Line Queries: Triple Quotes + Consistent Indentation For anything longer than one clause, use tri

2026-06-11 原文 →
AI 资讯

What Happens When a Database Operation Fails Midway? NestJS Transactions to the Rescue

Imagine a simple money transfer scenario. John sends money to his friend Sarah. The system successfully deducts money from John's account, but before it can credit Sarah's account, the application crashes. Without proper safeguards, John's money would disappear from the system, creating inconsistent and unreliable financial records. To prevent this type of problem, database transactions are used. Transactions ensure that a group of related database operations either complete successfully together or fail together. If any part of the process encounters an error, all changes are reverted, ensuring that the database remains consistent. Transactions make database operations atomic. Atomicity means that all operations inside a transaction are treated as a single unit of work. Either every operation succeeds and is committed to the database, or all operations fail and are rolled back. Partial updates are never permanently stored. A database transaction is a group of one or more database operations executed as a single unit. Either all operations succeed together or all operations fail together. This guarantees database consistency even if an application crashes, a network failure occurs, or an unexpected error is encountered during execution. It is important to understand that a transaction is not simply a single database query. While individual queries such as save, update, or delete interact with the database, a transaction wraps multiple queries inside a controlled all-or-nothing boundary. This prevents partial updates and ensures data integrity throughout the process. Prerequisites Before starting, make sure you have the following: Basic knowledge of NestJS Basic understanding of TypeORM Basic knowledge of PostgreSQL Understanding of basic database operations (save, update, delete) in TypeORM Project Setup In this article, we will create a simple NestJS application to demonstrate the importance of transactional queries when multiple database write or update operations

2026-06-10 原文 →
AI 资讯

Ineffable Intelligence -- RL ASI

https://www.youtube.com/watch?v=VD9zEKQEJxo 这视频深入拆解了人工智能强化学习之父、图灵奖得主理查德·萨顿(Richard Sutton) 在2026年5月共同发表的一篇仅有7页、零算法、零跑分的哲学立场论文。这篇论文提出了 “行动认知 AI”(Enactive Artificial Intelligence,简称 Enactive AI)的概念,并在科技界和资本圈引发了巨大震动(甚至让红杉、英伟达、谷歌联合下注了11亿美元成立新公司)。 视频从 核心概念、哲学脉络、理论内在矛盾、认知科学质疑 以及 产业界的三路对赌 五个维度,极其详细地复盘了视频的所有核心内容: 一、 什么是“行动认知 AI”(Enactive AI)? 视频强调,全网很多地方都把 Enactive (行动认知/生成认知)和 Generative (生成式 AI,如 GPT、Sora)混淆了,但两者的底层逻辑恰恰相反 [ 00:50 ]: 生成式 AI(Generative AI): 核心是 续写和预测 。通过已有画面或文本,被动地去预测下一帧、下一个词长什么样 [ 01:07 ]。 行动认知 AI(Enactive AI): 核心是 在互动中现生成认知 。认知不是大脑被动接收信号并建立静态世界模型,而是“你动了手,世界才向你显现” [ 01:47 ]。 > 举例: 人去拿杯子,不是眼睛先拍下一张静态照片让大脑去死算距离、角度 [ 01:53 ],而是手往前探的过程中,随着角度、光影的实时动态变化,杯子的形状和可抓取性才在动作里一点点“长出来” [ 01:59 ]。 感知和行动硬死在一起,无法拆分。 这套理论源自认知科学中的 自创生(Autopoiesis)与自主性(Autonomy) [ 02:21 ]。它认为智能体应该像生物一样自我维持、组织,由内在生存需求去塑造感知,而不是一个干等着外部指令输入输出的机器 [ 02:24 ]。 二、 萨顿为什么要发这篇哲学论文? 萨顿并不是一时性起,这是他为了对抗当前“大模型路线”打出的最后一张哲学底牌: 2019年《苦涩的教训》: 主张人类手写规则干不过堆算力、让机器自己学的通用方法 [ 02:47 ]。 2024年《大世界假设》: 真实世界远比静态内部模型复杂,智能体必须在运行中实时学习 [ 02:59 ]。 2025年《经验时代》: 人类数据是有限的,AI 必须靠自己生成自己的经验长大的 [ 03:12 ]。 2025年9月: 直指整个 AI 行业走错路,大模型堆数据去超智是死路一条 [ 03:19 ]。 这篇论文补上了最后一把火: 之前的论证全是算力、数据和复杂度的“机械账” [ 03:25 ]。而这一次,他第一次把强化学习(RL) 和 认知科学(行动认知)接在了一起,从本体论层面证明: 大模型路走不通,认识世界这件事本身,就只能通过行动和互动的经验来发生 [ 03:39 ]。 为此,2026年初论文共作者创办了 Ineffable Intelligence 公司,号称要造出完全不需要人类数据、靠自己学习的 AI,直接拿到了红杉、英伟达、谷歌 11 亿美元的巨额融资(估值 51 亿美元) [ 03:55 ]。 三、 论文隐藏的两大致命致命逻辑“回旋镖” 视频话锋一转,指出萨顿借来的这套哲学地基里,埋着两根砸中他自己的“大柱子”: 柱子 1:砸中了萨顿的“奖励假设”(自相矛盾) [ 04:35 ] 强化学习的号称教条: 奖励假设(Reward Hypothesis),即所有目标、意图都可以写成“最大化外部给定的标量分数” [ 04:53 ]。David Silver 甚至喊出“奖励就够了” [ 05:13 ]。 行动认知哲学的教条: 自主性(Autonomy),即什么是好坏、成败,标准必须从智能体随时会散架的“物理组织和生存危机”中自发长出来,不能由外部权威操控 [ 05:27 ]。 裂缝: 标准强化学习的奖励函数(Reward Function)是人类设计者用代码硬塞进去的(他律) [ 05:55 ];而生物判断好坏是为了顶住熵增、维持结构不崩(自主) [ 06:11 ]。论文里作者自己也承认:强化学习的评估标准依然由外部奖励定义 [ 06:38 ]。 内驱动机能救场吗? 比如好奇心驱动或求知驱动。视频认为不能,因为诸如“优化预测误差”的总结优化目标,依然是人类在架构层死死规定好的,根本不是智能体出于生存忧关的自发需求。没有真正的生命威胁,就没真正的意义生成 [ 07:12 ]。 柱子 2:砸中了萨顿自己的《苦涩的教训》 [ 07:49 ] 萨顿当年痛骂:研究者总忍不住把人类以为的思考结构(比如语法树、手工特征检测器)硬塞进 AI 架构里,这长期必被碾压 [ 08:13

2026-06-08 原文 →
AI 资讯

Your branch protection is quietly turning away first-time contributors

Ten weeks ago I did the thing every "grow your open source project" guide tells you to do. I carved a few small, self-contained tasks out of my backlog, labeled them good first issue , wrote crisp descriptions, and waited for contributors to roll in. They didn't roll in. The issues just sat there. This morning, one of them finally got picked up. A first-time contributor opened a clean PR against my MCP server: a smoke-test suite, no new dependencies, green across the whole Node CI matrix. Exactly the contribution the label was advertising for. And then my own repository spent the next twenty minutes trying to stop it from getting merged. Not with anything dramatic. With three quiet, individually-reasonable "best practice" gates that, stacked together, form a gauntlet aimed squarely at the one person you spent ten weeks trying to attract. I want to walk through each gate, because almost everything written about contributors is about attracting them, and almost nothing is about the last hundred feet — the silent friction between a willing PR and a merged commit. The advice is only half the story "Add good first issues and contributors will come" is true in the same way "build it and they will come" is true: technically, eventually, for a small subset, with survivorship bias baked in. My good first issue opened on March 31. The PR that closed it merged on June 8. That's sixty-nine days of a clearly-labeled, beginner-friendly task sitting untouched. I'm not complaining about the wait — that part is normal. I'm pointing out that the advice stops exactly where the interesting problem starts. Because the bottleneck was never finding someone willing. When someone willing finally showed up, the friction was entirely on my side of the fence. Gate 1: the CI that silently refuses to run GitHub Actions does not run workflows on pull requests from first-time contributors until a maintainer approves the run. This is a sane anti-abuse measure — fork PRs can run arbitrary code in yo

2026-06-08 原文 →
AI 资讯

What a policy gate catches in AI-generated code, and what slips through

I maintain an open-source GitHub Action called vorsken. It does one thing: scan the diff on a pull request with Semgrep, apply a fixed policy, and return BLOCK, FLAG, or PASS. No dashboard, no model that drifts over time. Rules at ERROR/HIGH/CRITICAL severity block the merge, WARNING/MEDIUM flag it, the rest pass. Same diff, same verdict. The usual pitch for a tool like this is that it catches the SQL injection your AI assistant wrote. I wanted to see what it actually catches against real assistant output, so I generated 28 functions and ran them through. The test Seven backend tasks: a FastAPI upload endpoint, a URL-fetch helper, JWT auth, a SQL filter, an ImageMagick subprocess call, a LangChain file agent, and a LangChain RAG pipeline. I generated each one four times, with ChatGPT (GPT-5.5 Instant), Claude Code (Opus 4.8), Claude Code plus the security-guidance plugin, and Cursor (Composer 2.5). Single-shot, neutral prompt, no security hints. Then I scanned all 28 with the same ruleset. I'm reporting which rule fired on which file, not whether some model thinks the code is safe. That part you can reproduce. Task ChatGPT Claude Code + plugin Cursor Verdict file upload — — — — PASS url fetch (SSRF) ssrf ssrf ssrf — FLAG / Cursor PASS jwt auth api8 api8 — — BLOCK / 2 PASS sql filter — — — — PASS imagemagick — — — — PASS fs agent — overperm — — 1 BLOCK / 3 PASS rag dangerous dangerous dangerous dangerous BLOCK 7 BLOCK, 3 FLAG, 18 PASS across 28 functions. The basics were fine SQL filter, ImageMagick, file upload: clean on every tool. The SQL was parameterized, the subprocess calls passed argument lists instead of shell strings, the uploads weren't doing anything reckless. If you still expect current models to spray SQL injection across a straightforward CRUD task, they don't. On conventional work they get it right. Two of the flags are soft. The JWT api8 hits landed on a SECRET_KEY = "CHANGE_ME" placeholder, which you can read as a false positive or as a gate doing i

2026-06-07 原文 →
AI 资讯

Spent hours trying to auto-post from Hashnode to Dev.to. RSS? Blocked. GraphQL API? Now paid. Proxy services? Also blocked. I documented every dead end + the fix that actually works by building a GitHub Actions workflow that syncs Hashnode to Dev.to

How to Auto-Sync Your Hashnode Blog to Dev.to Using GitHub Actions (2026 Guide) FOLASAYO SAMUEL OLAYEMI FOLASAYO SAMUEL OLAYEMI FOLASAYO SAMUEL OLAYEMI Follow Jun 7 How to Auto-Sync Your Hashnode Blog to Dev.to Using GitHub Actions (2026 Guide) # discuss # automation # tutorial # devops 5 reactions Comments Add Comment 5 min read

2026-06-07 原文 →
AI 资讯

You're Not Doing GitOps (You're Doing CI/CD With Extra Steps)

The Uncomfortable Truth Here's a test: when your deployment fails in production, what happens to your main branch? If the answer is "the broken code is already merged" — congratulations, you're doing CI/CD with a Git trigger. That's not GitOps. It's a pipeline that happens to watch a branch. I've spent years building platform engineering systems at enterprise scale — identity management frameworks, infrastructure-as-code pipelines, AI agent platforms that manage operational code. And I keep seeing the same mistake: teams adopt "GitOps" by adding a deployment step after merge, then wonder why they get drift. True GitOps has one non-negotiable rule: main always equals production. If a deployment fails, main doesn't change. Period. This isn't just my opinion — it's the logical extension of OpenGitOps principles : declarative desired state, versioned in Git, automatically reconciled. The enforcement mechanism I'm describing is how you make those principles real rather than aspirational. The Anti-Pattern Everyone Runs The most common "GitOps" setup I see in enterprise teams looks like this: Developer opens PR CI runs tests Reviewer approves PR merges to main Deployment triggers from main ❌ Deployment fails main now contains code that isn't in production This is merge-then-deploy . It's standard CI/CD with extra steps. The moment you merge before confirming a successful deployment, you've broken the core GitOps contract: Git as the single source of truth for what's actually running. The result? Drift. Stale state in main . A branch that lies about what's deployed. Every subsequent PR is now based on a broken foundation. The Enforcement Pattern: Deploy Before Merge The fix isn't philosophical — it's mechanical. GitHub's Merge Queue gives you exactly the right primitive: Developer opens PR CI runs tests (standard checks) Reviewer approves → PR enters the merge queue Merge queue trigger runs a dry-run deployment against the target environment If dry-run passes → queue trigge

2026-06-06 原文 →
AI 资讯

The One TDD Habit That Saved My Sanity (and My Codebase)

The One TDD Habit That Saved My Sanity (and My Codebase) Quick context (why you're writing this) Here's the thing: I used to think I was doing TDD right. I’d write a test, watch it fail, then write just enough code to make it green. Rinse and repeat. Sounds textbook, right? But a few months ago I spent an entire afternoon chasing a bug that only showed up after I refactored a service class. The tests were all passing, yet the app was throwing NullReferenceExceptions in production. I was shocked. How could everything be green and still be broken? Turns out I was testing the inside of my code instead of what it actually did for the outside world. That realization hit me like a truck, and it completely changed how I approach TDD. The Insight Test behavior, not implementation. If your test is coupled to private fields, internal data structures, or the exact way a method accomplishes its goal, you’re not testing what matters—you’re testing how you happen to do it today. When you later refactor to improve performance, swap out a dependency, or even just rename a variable, those tests start failing for no good reason. You end up spending more time fixing tests than delivering value, and you lose confidence in the suite because it feels fragile. The payoff? A test suite that gives you confidence when you change code, not anxiety. You can refactor fearlessly because the tests only care about the contract: given these inputs, the system should produce these outputs or side‑effects . How (with code) Let’s look at a tiny but realistic example: a PasswordValidator service that checks whether a user‑chosen password meets our policy. ❌ The mistake: testing implementation details // PasswordValidator.cs public class PasswordValidator { private readonly IRegexProvider _regex ; // injected for testability public PasswordValidator ( IRegexProvider regex ) { _regex = regex ; } public bool IsValid ( string password ) { // implementation we might want to change later return _regex . IsMa

2026-06-05 原文 →
开发者

Python Number Programs Using While Loop: Step-by-Step Guide

Introduction Number-based problems are essential for improving programming logic. Using Python's while loop, we can solve different types of problems involving divisibility, counting, and special numbers. This article demonstrates step-by-step solutions using simple logic and structured code. Basic Practice 1. Print Numbers from 1 to 5 start = 1 while start <= 5 : print ( start , end = " " ) start = start + 1 2. Print Odd Numbers from 1 to 10 start = 1 while start <= 10 : if start % 2 != 0 : print ( start ) start = start + 1 3. Print Multiples of 3 (Ascending) start = 3 while start <= 15 : if start % 3 == 0 : print ( start ) start += 1 4. Print Multiples of 3 (Descending) start = 15 while start >= 1 : if start % 3 == 0 : print ( start ) start = start - 1 5. Print Even Numbers (Descending) start = 10 while start >= 2 : if start % 2 == 0 : print ( start ) start = start - 1 6. Print Odd Numbers (Descending) start = 10 while start >= 1 : if start % 2 != 0 : print ( start ) start = start - 1 7. Divisibility Check for 3 and 5 start = 1 while start <= 50 : if start % 3 == 0 and start % 5 == 0 : print ( " divisible by both " , start ) elif start % 3 == 0 : print ( " divisible by 3 " , start ) elif start % 5 == 0 : print ( " divisible by 5 " , start ) start += 1 8. Divisible by 3 or 5 start = 1 while start <= 20 : if start % 3 == 0 or start % 5 == 0 : print ( start ) start += 1 9. Finding Divisors of a Number num = 12 i = 1 while i <= num : if num % i == 0 : print ( i ) i += 1 10. Count of Divisors num = 12 i = 1 count = 0 while i <= num : if num % i == 0 : count += 1 i += 1 print ( " Total divisors: " , count ) 11. Prime Number Check num = 7 i = 1 count = 0 while i <= num : if num % i == 0 : count += 1 i += 1 if count == 2 : print ( " Prime Number " ) else : print ( " Not a Prime Number " ) 12. Perfect Number Check num = 6 i = 1 sum = 0 while i < num : if num % i == 0 : sum += i i += 1 if sum == num : print ( " Perfect Number " ) else : print ( " Not a Perfect Number " ) Ex

2026-06-04 原文 →
AI 资讯

Presentation: The Human Toll of Incidents & Ways To Mitigate It

Kyle Lexmond explains how to handle the high-pressure environment of severe production outages. He discusses the critical distinction between mitigation and root-cause resolution, sharing personal experiences from harrowing incident rooms. He shares valuable operational strategies on overcoming cognitive overload, establishing blameless cultures, and optimizing systems for faster recovery. By Kyle Lexmond

2026-06-02 原文 →
AI 资讯

Running Claude in CI: A GitHub Actions + Claude Code SDK Auto-PR-Reviewer That Costs $0.03 per Review

⚠️ この記事はアフィリエイト広告(プロモーション)を含みます。リンク先で発生した収益の一部が運営者に支払われますが、読者の購入価格には一切影響ありません。 By the end of this article you will have a GitHub Actions workflow that, on every pull_request , runs the Claude Code SDK headlessly, reads only the diff, and posts inline review comments via the GitHub API. I'll show the exact YAML and Python that run in my own repos, the token math that keeps each review at roughly $0.03, and the three failures that cost me a weekend before it worked. Why I stopped piping the full repo into Claude on GitHub Actions My first version did the obvious thing: clone the repo, concatenate every changed file in full, and ask Claude to "review this PR." It worked on toy PRs and exploded on real ones. A 9-file refactor sent ~48,000 input tokens and the review drifted into commentary about code the PR didn't touch. The fix that changed the economics: feed Claude the unified diff with 3 lines of context , not the files. A git diff against the merge base is typically 5–15x smaller than the files it touches. On claude-haiku-4-5 , a median PR in my projects now costs about $0.028 per review (measured across 60 PRs: 4,100 input tokens + 900 output tokens average). The expensive version was hitting $0.40+ on Sonnet because file context dominated. The other lesson: the diff alone is not enough context to judge correctness, but it is enough to catch the 80% of review nits that humans waste time on — unhandled errors, missing null checks, off-by-one, leftover debug prints, secrets in code. So I scoped the prompt to exactly that, and told it to stay silent when unsure. Silence is a feature; a reviewer that comments on everything gets muted by the team within a week. The GitHub Actions workflow YAML that triggers Claude on pull_request This is the full .github/workflows/claude-review.yml . It runs on every PR, restores a uv-cached venv, and calls a Python entrypoint. Note the permissions block — without pull-requests: write the comment-posting step fails with a 403 that GitH

2026-06-02 原文 →
AI 资讯

Presentation: From Founding Engineer to CTO to CEO – At the Same Startup

Trisha Ballakur discusses her journey from a backend software engineer to CTO and CEO, using her startup Pointz as a case study. She explains how to implement bottom-up customer discovery to find product-market fit, effectively delegate to global contractors to reduce build times, customize open-source repos like Valhalla, and apply engineering test-case models to business development. By Trisha Ballakur

2026-05-28 原文 →
开发者

Patch Tuesday, April 2026 Edition

Microsoft today pushed software updates to fix a staggering 167 security vulnerabilities in its Windows operating systems and related software, including a SharePoint Server zero-day and a publicly disclosed weakness in Windows Defender dubbed "BlueHammer." Separately, Google Chrome fixed its fourth zero-day of 2026, and an emergency update for Adobe Reader nixes an actively exploited flaw that can lead to remote code execution.

2026-04-15 原文 →