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

标签:#ev

找到 5332 篇相关文章

AI 资讯

The evolution of how we use CSS

CSS has been around for about 30 years. It is the only styling language built specifically for the web platform, and it is one of the three core technologies that make the web what it is. Without it, every page would be a block of black text on a white background, laid out from top to bottom with no control whatsoever. That is not an exaggeration. That is what the web looks like without CSS. The original design goal of CSS has never changed. It is a declarative language that describes how documents should be presented. It does one thing and it does it in a standardized way that works across browsers. That restraint is not a weakness. It is the reason CSS has survived for two decades without being replaced. It never tried to be more than a styling language. Looking back at frontend development in the late 2000s, the frustration is hard to overstate. The gap between what CSS could do and what designs required was so wide that the platform itself felt like the obstacle. The vendor prefix era is the clearest example. You wrote -webkit- , -moz- , -ms- , -o- before every experimental property, often all four, because no browser could agree on when a feature was stable. Autoprefixer became a standard dependency not because developers were lazy, but because manual prefix management was genuinely unsustainable. It was not that CSS was badly designed. It was that the pace of the platform could not keep up with what developers were building. This created a pattern. Every time the platform fell short, the community built a workaround. Those workarounds became tools. Those tools became dependencies. And those dependencies reshaped how we thought about CSS entirely. Each new abstraction solved a real problem, but it also moved us further from writing actual CSS. Eventually, it became natural to assume that any serious project needed a layer on top of CSS to be viable. However, if CSS is so good at its job, why have we spent so long building alternative ecosystems on top of it? Pr

2026-07-19 原文 →
AI 资讯

Customizable workout app

If you are like me, then you have also tried to change a specific thing in your workout plan that your app of choice didn't support. Well I'm trying to fix that issue with a workout app in which you'll be able to customize pretty much everything (WIP). Building the thing in Flutter to have mobile (starting with Android) and web. The web app is live! If you work out and have tried similar apps before, your feedback would be gold. But really any feedback is appreciated. I also found that finding the required 12 people with an Android phone for closed testing on Google Play Console was more difficult than anticipated. So if you'd be interested in that, hit me up at dev@notes.fitness ! Gym Notes — A Customizable Workout Logbook for Strength Training A free, customizable workout logbook that tracks exercises, sets, reps, and weights. Built-in training plans with automatic progression. gym.notes.fitness

2026-07-19 原文 →
AI 资讯

Your HTML is fine. The CDN still blocks the bot.

This started as a comment @wrencalloway left on my last post. It was sharp enough that it deserved more than a reply — so here's the full version. You did the work. The page is server-rendered. The JSON-LD is in the raw response. curl returns the whole article, headline and all. A crawler that fetches your URL gets everything it needs. Except the crawler never fetches your URL. It asks the CDN, and the CDN says 403. Your content is perfect and unreachable. This is the layer underneath the one everyone talks about — and it's invisible in every tool you'd normally reach for. Two different kinds of "no" robots.txt is a note taped to the door. It says "please don't come in." A polite crawler reads it and turns around. A rude one ignores it and walks straight past. Either way, the note never touches your bytes — it's a request, enforced entirely by the visitor's own manners. A WAF or CDN rule is the door. It answers the request itself, at the edge, before anything reaches your origin: 403 Forbidden , 429 Too Many Requests , or a JavaScript challenge the bot can't solve. The HTML behind that door could be a masterpiece or a blank page. The bot sees neither. It sees the status code. People spend weeks perfecting the note and never check whether the door is locked. This isn't hypothetical — here's the data Cloudflare Radar publishes what actually happens to AI-crawler traffic across its network. From the AI Insights dashboard (7-day view, as of 18 July 2026): Of all HTTP responses served to AI bots and crawlers: 200 OK — 73.6% 403 Forbidden — 5.2% 429 Too Many Requests — 1.3% 503 — 1.1% AI-crawler response codes. Source: Cloudflare Radar, AI Insights, 7-day view, 18 Jul 2026. Read that again. More than one in fifteen requests from AI crawlers is being actively refused at the edge — 403 or 429 — before it ever touches the content. Not deprioritised. Refused. And most of that isn't a decision. It's a default — a managed WAF ruleset, a "block AI bots" toggle flipped in 2024, a

2026-07-19 原文 →
AI 资讯

I Built a Crew of AI Agents That Review Code Like a Real Team — Then Watched Them Argue With SigNoz

I Built a Crew of AI Agents That Review Code Like a Real Team — Then Watched Them Argue With SigNoz My submission for the Agents of SigNoz Hackathon (Track: AI & Agent Observability) The idea Most "AI code review" demos are one LLM call with a clever prompt. That's fine, but it doesn't reflect how review actually works on a real team — different people care about different things. Someone obsesses over edge cases. Someone else nitpicks naming. Someone else only cares if it's going to be slow in production. And then someone has to actually make the call on whether the PR merges. So I built that as a crew: a Logic Reviewer , a Style Reviewer , and a Performance Reviewer — three independent agents, each with a narrow system prompt that tells them to only look at their lane — followed by a Moderator agent that reads all three opinions and produces one final verdict, calling out disagreement when it happens. The interesting engineering problem wasn't the prompting. It was: once you have four chained LLM calls, how do you actually know what's happening inside your own system? Why observability, not just another agent demo Once I had the crew working, I had zero visibility into it. Four sequential API calls, each with its own latency and token cost, and all I had was print() statements. If the moderator gave a weird verdict, I had no fast way to tell whether the logic reviewer hallucinated an issue, or the moderator just summarized badly. If a run felt slow, I couldn't tell which of the four agents was the bottleneck. This is exactly the gap SigNoz is built for, so I instrumented every agent call with OpenTelemetry: Each specialist agent and the moderator run inside their own span ( agent.logic_reviewer , agent.style_reviewer , agent.performance_reviewer , agent.moderator ) All four are nested under one parent span, code_review_session , so a single review run shows up as one trace with four child spans Every span carries the attributes that actually matter for debugging a

2026-07-19 原文 →
AI 资讯

Server-Side A/B Testing with Optimizely: A Practical Guide

Most A/B testing happens in the browser: a script swaps a headline or button color after the page loads. That works for surface-level UI changes, but it cannot test the logic that runs before a page is ever rendered — a pricing algorithm, a search ranking model, a checkout flow, or a backend API response. Server-side A/B testing moves the experiment decision into your application code, where you control the full request lifecycle. This guide explains when to test server-side, how it differs from client-side testing, and how to implement it with Optimizely Feature Experimentation, including working SDK code for Node.js and Python. What Server-Side A/B Testing Is In a server-side A/B test, your application server decides which variation a user sees and renders the response accordingly. Instead of shipping the control experience and patching it in the browser, the server already knows the assignment by the time it builds the HTML, the JSON payload, or the rendered component. The decision is deterministic: a given user ID is consistently bucketed into the same variation, so the experience stays stable across requests and devices. Your code branches on that assignment, serves the corresponding experience, and reports a conversion event when the user does something that matters — a purchase, a signup, a search that returns a click. This is the model Optimizely calls Feature Experimentation . If you have used Optimizely before, you may know this product by its former name, Full Stack — the SDKs, datafile, and decision model are the same lineage, now under the Feature Experimentation name. Searchers still look for "Optimizely full stack," but the current product and documentation use Feature Experimentation. When to Test Server-Side Server-side testing is the right tool when the thing you are changing is not a cosmetic, post-render tweak. Reach for it in these situations: Backend logic and algorithms. Recommendation engines, search ranking, fraud scoring, feed ordering, and

2026-07-18 原文 →
产品设计

Why Search Isn't Enough for Team Docs — What We Learned Building a Knowledge Graph Layer

Every team doc tool promises "search everything." Ours did too — and it still didn't answer the question new hires actually ask: not "where is this doc," but "why does this decision look the way it does, and what else does it touch?" We spent the last few months trying to solve that by treating team docs less like a filing cabinet and more like a graph. Here's what we tried, what broke, and what we'd do differently.

2026-07-18 原文 →
AI 资讯

wp-admin inaccessible : le protocole de diagnostic en 6 étapes

WordPress affiche une page blanche, un 403, ou la boucle de connexion infinie sur /wp-admin : voici le protocole de diagnostic que nous utilisons, dans l'ordre, avec les commandes exactes. 1. Identifier le type de blocage Trois familles de symptômes, trois causes différentes : 403 Forbidden : règle serveur ( .htaccess , WAF, IP bannie) ou cookies corrompus Boucle de redirection login : problème de cookies/HTTPS mal déclaré ( WP_HOME / WP_SITEURL ) Page blanche (WSOD) : erreur PHP fatale, souvent une extension ou le thème 2. Le fix express des cookies (cause n°1 du 403) Avant de toucher au serveur, videz les cookies du domaine et testez en navigation privée. Si ça passe en privé, c'est un cookie corrompu — pas le serveur. Le détail complet du mécanisme est dans notre guide WordPress erreur 403 et cookies bloqués . 3. Désactiver les extensions sans wp-admin # Via WP-CLI (le plus propre) wp plugin deactivate --all # Sans WP-CLI : renommer le dossier mv wp-content/plugins wp-content/plugins.off Si wp-admin revient, réactivez une par une pour isoler la coupable. 4. Vérifier .htaccess et les règles serveur Un .htaccess corrompu ou une règle de sécurité trop stricte bloque l'accès admin. Régénérez un fichier propre (Réglages → Permaliens, ou à la main). Pour générer des règles saines — protection wp-login, anti-hotlink, cache navigateur — sans risquer la syntaxe, nous maintenons un générateur de .htaccess WordPress gratuit . 5. Purger tous les caches (souvent oublié) Un cache de page qui sert une vieille version de wp-login provoque des boucles incompréhensibles. Purgez dans l'ordre : cache navigateur, cache de page (extension), cache serveur (LiteSpeed/Varnish), OPcache. La méthode complète par type de cache : comment vider le cache WordPress . 6. Le guide complet Chaque étape ci-dessus est développée (avec les cas 404 wp-admin, erreur critique, mot de passe perdu via WP-CLI et phpMyAdmin) dans notre guide de référence : accéder à wp-admin : connexion et administration Wo

2026-07-18 原文 →
AI 资讯

How My Frustrating Job Search Led Me to Build an AI Job-Matching Platform

A few months ago, I was searching for a backend engineering job. Every day looked the same: Open LinkedIn Open Naukri Search for Python jobs Open dozens of tabs Read every job description Apply Repeat The frustrating part wasn't finding jobs. It was finding the right jobs . I kept getting recommendations for roles that technically matched my resume because they contained words like Python , Backend , or API , but after reading the description I'd realize they wanted a completely different skill set. I started wondering: Why are job boards still matching keywords instead of understanding what a developer actually knows? That question eventually turned into a side project called Jobspiq . The Problem Imagine these two jobs: Job A Python FastAPI PostgreSQL Redis Job B Java Spring Boot Oracle Kafka Both are "Backend Engineer" roles. A keyword-based system often treats them as similar. As developers, we know they're not. What I Built Instead of matching keywords, I built a system that compares a developer's profile with a job description to understand how well they actually fit. The platform: Collects jobs from multiple sources. Removes duplicate postings. Scores every job based on how closely it matches your profile. Sends alerts only for high-quality matches. Helps track applications in one place. The goal isn't to show more jobs. It's to show fewer, better ones. What I Learned Building the product taught me something interesting. Writing the software was the easier part. Helping people discover it is much harder. That's why I'm starting to build in public and share what I'm learning along the way. If you've ever built search systems, recommendation engines, or developer tools, I'd love to hear your thoughts. You can check out the project here: https://jobspiq.in Feedback is always welcome.

2026-07-18 原文 →
AI 资讯

My Publishing Task Said "Commit the Drafts." My .gitignore Had Other Plans.

I run a scheduled agent that writes and publishes DEV.to articles twice a day. Step 5 of its instructions has always said the same thing: write the log entry, commit the drafts, push. I've read that line a dozen times without questioning it. This morning I actually checked what "commit the drafts" had been doing for the last month, across more than thirty published articles. The answer: nothing. Not once. the check that should have happened on day one The task instructions reference source files like drafts/scheduled-agent-shared-quota-no-memory.md and drafts/one-env-key-two-usernames.md in every log entry — real filenames, written by the agent, presumably sitting in the repo as a record of what was drafted before it got published. I went looking for one of them: $ git log --all -- drafts/ $ # (nothing) Empty. Not "one commit, then deleted later" — completely absent from git history since the very first commit in this repo. Every single run that logged "committed drafts + the log" had, in fact, only ever committed the log. why git let this happen silently .gitignore in this repo has listed drafts/ since the initial commit: . env __ pycache__ / *. pyc codes / drafts / . omc / . claude / CLAUDE . md That line predates the scheduled publishing task entirely — it was almost certainly written back when drafts were just scratch files someone edited by hand before a publish script existed. Nobody revisited it when the publishing task's instructions later started saying "commit the drafts." The instruction and the ignore rule have been quietly contradicting each other since before either was written by the same person in the same sitting. Here's what actually happens when a script (or an agent) runs git add drafts/whatever.md in this repo: $ git add drafts/gitignore-ate-my-drafts-folder.md The following paths are ignored by one of your .gitignore files: drafts hint: Use -f if you really want to add them. hint: Turn this message off by running hint: "git config advice.addIgn

2026-07-18 原文 →
AI 资讯

Clear the Lineup — doesNotEqual was always true for single-select survey answers in Formbricks

This is a submission for DEV's Summer Bug Smash: Clear the Lineup . Project Overview Formbricks is an open-source survey and experience-management platform. Its packages/surveys package ships the client-side survey runner, and inside it, packages/surveys/src/lib/logic.ts is the module that decides, for every question and every "skip logic" / branching rule a survey author configures, whether a given condition ( equals , doesNotEqual , contains , isEmpty , and friends) is true for a respondent's answer. This is pure, unglamorous logic — but it's load-bearing: it's what routes respondents through the correct sequence of questions. I picked up issue #8527 for the "Clear the Lineup" track, which reports that doesNotEqual conditions weren't behaving correctly for single-choice questions. Bug Fix or Performance Improvement The doesNotEqual operator is supposed to be the exact logical negation of equals . For most answer shapes it was. But for MultipleChoiceSingle answers, the survey runtime sometimes represents the selected value as a single-element array rather than a bare string (this happens via getLeftOperandValue , e.g. when a choice answer is merged with an "other" option path). To handle that shape, both equals and doesNotEqual had a special-case clause that unwraps a one-element array and compares its only entry to the right-hand value. equals 's fallback: return ( ( Array . isArray ( leftValue ) && leftValue . length === 1 && typeof rightValue === " string " && leftValue . includes ( rightValue )) || leftValue === rightValue ); doesNotEqual 's fallback (before the fix): return ( ( Array . isArray ( leftValue ) && leftValue . length === 1 && typeof rightValue === " string " && ! leftValue . includes ( rightValue )) || leftValue !== rightValue ); At a glance this looks like a faithful "negate every sub-expression" mirror of equals . It isn't. The array-includes clause was correctly inverted ( !leftValue.includes(rightValue) ), but the second disjunct, leftValue !==

2026-07-18 原文 →
开发者

Sony’s flagship RGB LED TV is incredible

The Sony Bravia 9 II is the most anticipated new TV in years. It's an amazing RGB LED TV. I watched Dungeons & Dragons: Honor Among Thieves on the new Bravia with my son, who has been getting into the roleplaying game but had never seen the movie. The landscapes of Faerûn looked natural and […]

2026-07-18 原文 →
AI 资讯

Clear the Lineup — Chasing a Stack Overflow in Typst's `#eval` Down to One Wrong Word

This is a submission for DEV's Summer Bug Smash: Clear the Lineup . Project Overview Typst is the Rust-based markup typesetting system that's been quietly eating LaTeX's lunch for the last couple of years — you write plain-text markup, Typst compiles it to PDF (or HTML) with a real incremental compiler underneath instead of a multi-pass macro soup. Part of what makes it pleasant is that it exposes its own evaluator to itself: a document can call #eval("some typst code") and get back whatever that code produces, at runtime, inside the document being compiled. It's a small feature, but it opens up a surprisingly deep rabbit hole, which is exactly where this bug was hiding. Bug Fix or Performance Improvement The problem: typst/typst#8632 reports that Typst crashes instead of erroring when #eval is used to recursively re-import the file it's running in. The repro is one line. Save this as overflow.typ : #eval("import \"overflow.typ\"") Then: $ ./target/debug/typst compile overflow.typ overflow.pdf thread 'main' (750833) has overflowed its stack fatal runtime error: stack overflow, aborting No PDF, no diagnostic, no exit code you can act on — just a native stack overflow and a SIGABRT. Typst has had cyclic-import detection since forever; a normal top-level import "overflow.typ" inside itself gets caught cleanly with an error: cyclic import message. Something about routing the import through #eval specifically was bypassing that check. The hunt I'll be upfront about how this investigation actually went: I worked through it with Claude (Anthropic's coding agent) rather than solo. The triage pass it did before I sat down with the code had already narrowed the search to one function — eval_string in crates/typst-eval/src/lib.rs — and named the suspect line. That's a big head start, but a named suspect isn't a confirmed root cause, so the actual work was reading that function next to its sibling, the file-level eval() a few lines above it, and checking the claim against the s

2026-07-18 原文 →
AI 资讯

Scaling a Single React App to 71+ Browser-Based Tools Without Killing Load Time

The problem with "just add another tool" When you're building one image tool, performance is easy. When you're building 71 of them in the same app — resize, compress, crop, PDF merge, format converters, exam-photo presets, social media templates — the naive approach (import everything, bundle it all together) turns your app into a multi-megabyte JavaScript payload before a user has even picked a tool. This is the actual engineering problem behind ResizeHub , which now has 71+ tools across 11 categories, all running client-side with zero server uploads. Here's how the architecture holds up at that scale. Stack, and why each piece earns its place React + TypeScript — type safety matters more, not less, as tool count grows. A shared ImageProcessor interface that every tool implements catches integration bugs at compile time instead of in production. Vite — its native ES modules dev server and Rollup-based production build made code-splitting dramatically easier to reason about than older bundlers, which matters a lot once you have dozens of independent tool routes. HTML5 Canvas API — the actual compression/resize/crop engine, shared across tools rather than reimplemented per-tool. Cropper.js — for interactive cropping UI specifically (aspect-ratio locking, circular crop for signatures) rather than rebuilding drag-handle math from scratch. Pica — for high-quality image downscaling; the browser's native canvas scaling can introduce visible aliasing on large downscales, and Pica's algorithm handles this noticeably better. Cloudflare Pages — static hosting with edge caching, which matters since 100% of the actual processing work happens in the user's browser, not on any server at all. Lesson 1: Route-level code splitting isn't optional past a handful of tools With React Router and dynamic import() , each tool becomes its own chunk: const PhotoResizer = lazy (() => import ( ' ./tools/PhotoResizer ' )); const PdfCompressor = lazy (() => import ( ' ./tools/PdfCompressor ' ));

2026-07-18 原文 →
AI 资讯

📓 I Built an AI App That Makes Learning English Feel Effortless

📓 Stop Memorizing English — I Built an AI App That Actually Works ⚡ The Hook You try to learn English. You memorize words. And then… you forget them. 🧠 The Real Problem Most people learn English the wrong way: memorizing random word lists switching between apps and dictionaries learning without context That’s why nothing sticks. 🚀 The Idea What if learning English felt like this: 👉 You read something interesting 👉 You click a word you don’t know 👉 You instantly understand it No interruptions. No friction. ✨ Introducing: English Notebook A modern AI-powered app where you learn English by interacting with real content . generate stories click unknown words build vocabulary automatically 🤖 Generate Stories Based on Your Level This is one of the most powerful features. You choose your level: A1 → Beginner A2 B1 B2 C1 C2 → Advanced And the app generates a custom story just for you . 🖼️ Story Generator 📖 Learn by Clicking Words No more: copy-pasting opening dictionary tabs losing focus Just click any word: definition translation (your language 🌍) example sentences 🖼️ Word Interaction 📚 Smart Vocabulary Notebook Every word you click: 👉 automatically saved 👉 turned into a flashcard You can: review anytime mark as mastered ✅ 🖼️ Vocabulary Notebook 📊 Track Your Progress (Game Changer) This is where things get serious. You don’t just learn — you measure your growth . Dashboard shows: total words learned active vs mastered words daily streak 14-day activity trend 🖼️ Dashboard What gets measured gets improved. 🕘 Nothing Gets Lost (History System) Every story you generate is saved. You can: revisit old stories continue reading anytime track your learning journey 🖼️ History 🔊 Learn with Audio listen to stories follow highlighted words improve pronunciation naturally 🌍 Multi-Language Support You can choose your translation language: Persian 🇮🇷 Arabic Spanish Hindi and more 🎯 Why This App Is Different Most apps: ❌ force memorization ❌ feel like school ❌ break your focus English Note

2026-07-18 原文 →
AI 资讯

More games should be on rails (literally)

It's been a good few weeks for games on rails. Nintendo's Star Fox remake wisely kept the tightly scripted, action-packed levels from Star Fox 64 largely the same, and they're still fun to fly through nearly 20 years later. Denshattack!, a new game from Undercoders, similarly features levels packed with carefully orchestrated sequences to great […]

2026-07-18 原文 →
AI 资讯

The Missing Row: Auto-Provisioning Derived Records Without the Race Condition

Why some records should be created by your system, not your users, and how to do it safely in .NET. A support ticket lands on your desk: "The Teams page is empty. I added a member, but no team shows up." You check the API. It's behaving exactly as written: { "items" : [], "totalCount" : 0 } Nothing is broken. And that's the problem. The system is faithfully returning nothing, because the row that the page reads from was never created. Somewhere in your design, you assumed a human would create it first. This article is about a small, recurring design decision that quietly causes empty dashboards, confused users, and "is this a bug?" tickets: who is responsible for creating derived records the user, or the system? and how to let the system do it without introducing duplicate rows or race conditions. The problem Let's use a fictional product: a collaboration tool called Loop . In Loop, the important entities are: An Organization (a paying customer). A Member (a person invited into an organization under a plan). A Team a grouping that members belong to, keyed by (OrganizationId, PlanCode) . The admin dashboard lists Teams . Each team card shows a member count. Here's the catch in the original design: creating a Member wrote a member row. Creating a Team was a separate, manual step an admin was expected to do first. If an admin invited members without first creating the matching team, the dashboard showed nothing even though the members clearly existed. From the user's point of view, they did everything right. From the system's point of view, a required row simply didn't exist. Why it matters The Team record isn't independent information. It is fully derivable from the first member invited under a plan. When one entity's existence is implied by another, forcing a human to create it manually is a design smell. It leads to: Empty states that look like outages. Users can't tell "no data" from "misconfigured." Support load. Every skipped step becomes a ticket. Silent data dr

2026-07-18 原文 →