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

标签:#tor

找到 1164 篇相关文章

AI 资讯

Content creators drop the ball

During Naomi Osaka's match against Anastasia Zakharova at this year's US Open earlier this week, a gaggle of ring light-wielding influencers who were packed in a luxury suite became enough of a distraction that the umpire paused the match and repeatedly asked them to quiet down. Elsewhere in the USTA Billie Jean King National Tennis […]

2026-09-05 原文 →
AI 资讯

Tableau Dashboard Extensions: What They Add, and What They Can Read

By Michael Nocito , data analyst · Published August 9, 2026 By the end of this page you can add an extension to a dashboard, tell the two hosting kinds apart, and read the permission box well enough to know what you're agreeing to. You'll also know the one behavior that surprises people after publishing, which is what an extension looks like in a PDF. It's about twelve minutes. Here's what to do before you add your first one. Find out where it runs. An extension you drop onto a dashboard is a web application, and some of them are hosted on Tableau-managed servers while others are hosted by whoever built them. That single fact decides how much thought the rest of the decision needs. The short version: an extension is a third-party web application running inside a dashboard object, and one of the two permission levels gives it your full underlying data along with table and field names. Where the code actually runs is the thing the panel doesn't show you, so it gets the picture. The original carries a diagram here. In words: A large rectangle labeled your dashboard contains four panels that all look alike. Three of them are shaded the same and marked as ordinary views. The fourth, in the lower right and outlined in a warning color, is labeled extension. A line runs from that fourth panel, crosses the boundary of the dashboard rectangle, and continues out to a separate box drawn outside and to the right labeled third-party host. The three ordinary views have no lines leaving the rectangle. The drawing shows that the extension panel sits inside the dashboard visually while its code and its data traffic reach outside it, which the other three panels never do. 1. What an extension actually is Before the explanation: you drop an extension onto a dashboard and it draws a chart type Tableau doesn't have. Where did that chart come from? From a web application, written by somebody else, running inside a panel on your dashboard. Tableau's own description is that extensions "let

2026-09-05 原文 →
AI 资讯

Validate Card Brands in Node.js with Luhn and credit-card-brand-detector

When a checkout form receives a card number, the first useful question is often not whether the payment will be approved. It is whether the input is structurally plausible and which network rules should be shown to the user. The open-source credit-card-brand-detector package provides that small client-side or server-side building block. It detects 11 brands, removes spaces and hyphens, and applies a Luhn checksum. It has zero runtime dependencies and exposes CommonJS functions for validation and brand detection. This tutorial builds a minimal Node.js check, verifies the result with known test numbers, and explains what this kind of validation cannot tell you. TL;DR Install version 1.0.1 , call validateCreditCard when you need both a boolean result and a brand, and call detectBrand when you only need the network name. The package does not contact a payment processor, authorize a transaction, tokenize data, or prove that a card exists. Prerequisites You need: Node.js 12 or newer. The package declares >=12.0.0 in its metadata. npm. A terminal and a small JavaScript file. The package is released under the MIT license . The examples below target the published npm package version 1.0.1 , which is also the version I installed for this walkthrough. Install the package Create a directory for the example and install the pinned version: mkdir card-check-example cd card-check-example npm init -y npm install credit-card-brand-detector@1.0.1 Pinning the version makes the example reproducible. If you use a different version later, check its README and package metadata before copying the behavior into a production application. Build the smallest useful check Create check-card.js : const { validateCreditCard , detectBrand , getBrand , } = require ( ' credit-card-brand-detector ' ); const formattedVisa = ' 4532 0151-1283-0366 ' ; const mastercard = ' 5555555555554444 ' ; console . log ( validateCreditCard ( formattedVisa )); console . log ( detectBrand ( mastercard )); console . log

2026-09-05 原文 →
AI 资讯

ADB Says Unauthorized, Offline, or Shows No Device? A Practical USB Debugging Checklist

When adb devices does not show the result you expect, reinstalling random drivers is rarely the best first move. The output already tells you which layer is failing. This checklist separates the most common states: device unauthorized offline An empty device list ADB not recognized by the terminal The goal is to diagnose the connection in a logical order: tool, cable, USB mode, authorization, and finally drivers. Before troubleshooting Make sure the basic setup is correct: Install the latest Android SDK Platform-Tools from Google. Use a USB cable that supports data, not only charging. Unlock the Android phone. Enable Developer options and USB debugging. Connect directly to the computer when possible instead of using an unpowered hub. The location of Developer options differs between Samsung, Xiaomi, Pixel, Huawei, OnePlus, and other interfaces. If you need the device-specific menu paths, this guide to enabling USB debugging on Android phones covers the common manufacturers and the RSA authorization step. Start with one command Open Terminal, PowerShell, or Command Prompt inside the Platform-Tools folder and run: adb devices For extra information, use: adb devices -l A normal result looks similar to this: List of devices attached R58M123ABCD device product:example model:Example device:example The word after the serial number is the important part. What each ADB state means Result Meaning Where to look first device ADB can communicate with the phone The connection is ready unauthorized The phone has not authorized this computer Phone screen and RSA prompt offline ADB sees the device but cannot communicate reliably ADB server, cable, port, or device Empty list The computer is not exposing the phone to ADB Cable, USB mode, driver, or debugging setting adb not recognized The shell cannot find the ADB executable Platform-Tools folder or PATH Case 1: The result is device This is the success state. ADB can send commands to the phone. You can test the connection with a harml

2026-09-05 原文 →
AI 资讯

Robot Policy Evaluation: Why 90% vs 92% Proves Little

Abstract When evaluating robot control policies, many practitioners draw direct conclusions from simple success‑rate percentages. For instance, given Policy A with 90 % success and Policy B with 92 % success, people frequently claim Policy B performs better. Nevertheless, purely comparing percentage figures without sample size, confidence intervals, paired experimental design and statistical power analysis often produces unreliable judgments. Drawing on Clopper‑Pearson exact confidence intervals, Wilson score intervals, McNemar’s paired testing and hierarchical episode‑within‑task structure, this article lays out a complete practical workflow for robot policy evaluation, covering pre‑experiment planning and post‑hoc result checking. For engineering teams running robot‑simulation benchmarks mixed with LLM‑based agent workloads, an API gateway such as 4sapi can help standardize telemetry collection and multi‑backend request orchestration. 1. The Pitfall: Percentages Without Sample Sizes Lack Evidentiary Weight Statements such as “Policy A achieves 90 % success; Policy B achieves 92 % success” are ubiquitous in robotics papers and technical reports. However, these two numbers alone cannot support the conclusion that Policy B is stronger. Valid interpretation must account for roll‑out count, task composition, random seeds, paired‑group configuration and statistical power. The RoboLab v4 benchmark illustrates this concrete risk. Each policy runs only 10 episodes per task. Under this setup, when a policy reaches a 90 % success rate, its 95 % confidence interval spans approximately 19 percentage points . Even expanding to 100 roll‑outs, the interval width still sits near six percentage points. Authors explicitly classify 10‑episode runs as coarse‑grained indicators and warn that fine‑grained policy comparison remains untrustworthy. This warning generalizes across most high‑cost robot benchmarks: reported numbers may print with high numerical precision, yet real statistical

2026-09-05 原文 →
AI 资讯

Unsloth Desktop brings Local AI to the masses

Ever since I got involved with local LLMs I wanted to share the magic with my friends. The process before involved either Ollama or llama.cpp, which are great, but the setup was difficult and a barrier to entry for most people. WHAT ARE THE BENEFITS OF LOCAL AI? Local AI isn't as powerful as cloud-based solutions, but the gap is narrowing. With local AI there are no subscription costs, token limits, or outages, since it all runs on your own hardware. It doesn't require an internet connection, so it can be used fully offline. For businesses that are worried about leaking IP or sensitive data it's especially attractive. It stays on your machine and your data doesn't get captured by some company that may or may not use it to train their next model. WHAT YOU NEED FIRST Before we get started you need to understand what your hardware is capable of. For this to work well I suggest an Apple Silicon Mac with at least 24 GB of unified memory, or a gaming desktop with at least 16 GB of VRAM. The more VRAM you have, the more capable models you will be able to run. For reference, I run it on three machines: a MacBook Pro with 96 GB of unified memory, a Mac Mini with 24 GB, and a gaming desktop with a Radeon 7900 XTX. ONE INSTALLER, NO SETUP Unsloth Desktop is what people have been waiting for. It's just been released as a beta. It's pretty much a single-click install. You download the installer and run it, and from there Unsloth Desktop handles everything else for you. Behind the scenes it scans your machine and determines what needs to be installed. It puts a wrapper around llama.cpp and MLX, which gives you all the power of the top open source models without having to manage the underlying tools. Unsloth Desktop will automatically detect if any of the tools have gotten any updates and will prompt you to install the updates. MODELS COME STRAIGHT FROM HUGGING FACE Not only does Unsloth Desktop make the initial install easy, it integrates directly with Hugging Face. For those who

2026-09-05 原文 →
AI 资讯

Stop changing your sprite sheet to fix animation speed

An eight-frame animation does not have a fixed duration. At 8 fps it lasts one second; at 12 fps it lasts two-thirds of a second; at 16 fps it lasts half a second. Before drawing or generating more frames, check whether the problem is missing poses or the time each pose stays on screen. We maintain FrameSprite, a browser workspace for game assets. This is a timing and export note, not a claim that a particular frame count makes AI animation reliable. The equations work with hand-drawn sprites too. Three numbers that are easy to mix up Source FPS describes how a recording was sampled. Frame count is the number of entries you put in an animation. Playback FPS controls how fast those entries advance in the game. A 24 fps source video can provide eight selected poses that you play at 12 fps. You do not need to preserve every source frame. For equal holds, forward playback and a speed multiplier of 1: duration_seconds = frame_count / playback_fps frame_hold_ms = 1000 / playback_fps fps_for_target = frame_count * 1000 / target_duration_ms Same eight frames Hold per frame Full loop 8 fps 125 ms 1.000 s 12 fps 83.333… ms 0.667 s 16 fps 62.5 ms 0.500 s You changed the cadence without changing one pixel of the sprite sheet. A test you can reproduce Use the public eight-frame sample . Keep the same frames, order, canvas and pivot for all three trials. Change only playback FPS between 8, 12 and 16. Check the animation alone at its intended game size. Run it beside actual movement or attack timing. If cadence improves but a foot or weapon still jumps, inspect the missing phase instead of raising FPS again. If every frame jumps by a small amount, inspect canvas and pivot alignment. If the pause happens only at the seam, look for an accidental duplicate endpoint. The sample makes the arithmetic test repeatable. It is not evidence that eight frames is the right budget for every character or action. Do not accumulate rounded timestamps At 24 fps, one hold is 41.666… milliseconds. St

2026-09-05 原文 →
AI 资讯

Translating 300-Page Books with Claude: Taming Token Limits and Chunking Strategies

How we built a reliable pipeline to split long texts for LLM translation without losing context or breaking the bank At LectuLibre, we translate entire books using Claude. The challenge: a 300-page book is roughly 90,000–120,000 words, which translates to 120,000–160,000 tokens. While Claude 3 models have a 200k context window, sending an entire book in one API call is impractical. It's slow, expensive, and often degrades translation quality due to attention dilution. We needed a robust chunking strategy that preserved context and stayed within token limits. The Problem: One Book, Too Many Tokens When we first started building LectuLibre, we naively assumed we could just pass the whole book to Claude and get a translation back. We quickly hit three walls: Rate limits : A single request with 150k tokens triggered API timeouts and 429 errors. Cost : Even if it worked, processing 150k tokens per request with Opus would cost over $13 per book, and most of the input would be wasted on repeated context. Quality : Long contexts tend to make the model "forget" early chapters, leading to inconsistent character names and terminology. Clearly, chunking was necessary. But how do you split a book without losing narrative flow? First Attempt: Naive Splitting by Paragraphs Our initial approach was simple: split the text into chunks of roughly 10,000 tokens by paragraphs. We used a regex to split on double newlines and then concatenated paragraphs until we hit the token limit. import re def split_into_paragraphs ( text : str ) -> list [ str ]: return re . split ( r ' \n\s*\n ' , text ) def chunk_by_paragraphs ( paragraphs : list [ str ], max_tokens : int = 10000 ) -> list [ str ]: chunks = [] current_chunk = [] current_tokens = 0 for para in paragraphs : # Estimate tokens using character count / 4 (quick and dirty) para_tokens = len ( para ) // 4 if current_tokens + para_tokens > max_tokens and current_chunk : chunks . append ( ' \n\n ' . join ( current_chunk )) current_chunk = []

2026-09-05 原文 →
AI 资讯

I Found a Better Way to Build Websites with Claude AI

If you're using Claude to build websites or applications, one of the biggest improvements you can make is to stop treating Claude like a chatbot where you simply copy and paste code. Instead, you can set up a development workflow where Claude works on the project, GitHub stores the code, and Vercel handles deployment. The basic workflow looks like this: You → Claude → Code → GitHub → Vercel → Live Website Claude works on the project, GitHub keeps the source code and its history, and Vercel can automatically deploy new code pushed to the connected repository. Here's how I approach the setup. Start by discussing the project with Claude Don't immediately tell Claude: "Build me a website." First explain what you're actually trying to build. Tell Claude: What the product is Who the target users are What problem you're solving The main features How the business will operate What you already know What you don't know You can also give Claude examples of existing websites or products that are similar to what you're trying to build. The purpose of this stage isn't to generate code yet. It's to make sure Claude understands the project before development begins. Plan the technical side Once Claude understands the idea, decide how you're going to build it. This is where you determine things such as: Programming language Framework Database Authentication APIs Hosting Folder structure Major features Development priorities For example, you might choose JavaScript/TypeScript with Next.js, PHP with Laravel, or another stack depending on your project. The important thing is to make these decisions deliberately instead of letting the AI randomly choose technologies as the project develops. So my basic AI development process is: Discuss → Plan → Build → Test → Deploy → Improve Create a GitHub repository Next, create a repository for your project on GitHub. Think of GitHub as the central home for your project's source code and its change history. Once the repository exists, your developm

2026-09-05 原文 →
开发者

I Compared 4 Dungeon Generation Algorithms. One of Them Never Works.

Four algorithms. Same grid. Very different dungeons. I implemented BSP trees, cellular automata, random walk, and room placement, ran each one 20 times on an 80x40 grid, and measured everything: connectivity, open space, path length, speed. The Results Algorithm Open Space Connected Rooms Path Length Speed BSP Tree 42.1% 100% 1.0 105 steps 0.88 ms Cellular Automata 55.8% 0% 15.2 78 steps 52.8 ms Random Walk 35.0% 100% 1.0 73 steps 274.7 ms Room Placement 18.9% 100% 1.0 81 steps 0.29 ms The big surprise: cellular automata never produces a connected map. Zero percent connectivity across 20 runs. Every single cave system has unreachable areas. The Maps BSP Tree (structured rooms, always connected) ################################################################################ ################################################################################ #####.........#####.............###################################....#......## #####.........#####.............##..........##############........#....#......## #####...........................##..........##############....................## #####.........#####.............##..........##############.............#......## #####.........#####.............##..........##############........#....#......## ##########.#######################..........##############........#....#......## ##########.#######################..........################..################## ######..........##################..........################..################## ######..........##################..........################..######..........## ######..........##################..........################..######..........## ######..........##################..........################..######..........## ######.............###############..........################..######..........## ######..........##.###############..........################..######..........## ######..........##.###############..........################..######..........##

2026-09-05 原文 →
AI 资讯

CrackMe Level 6: part 2

1. Introduction In the previous article, we began studying a level 6 CrackMe and quickly reached the Serial verification routine based on the Name. Here is this routine below: 0x401510: pusha ; Save all general-purpose registers ; ------------------------------------------------------------------------- ; PHASE 1: BASE64 DECODING AND SIZE CHECK ; ------------------------------------------------------------------------- 0x401511: mov ebx,DWORD PTR [esp+0x2c]; ebx = Pointer to Serial (passed as parameter) 0x401515: mov esi,0x404200 ; esi = Destination buffer for decoded Serial 0x40151a: push ebx ; Argument 2: Serial string 0x40151b: push esi ; Argument 1: Output buffer 0x40151c: call 0x401633 ; CALL: Custom Base64 decoder 0x401521: cmp eax,0x10 ; Is the decoded buffer exactly 16 bytes (128 bits)? 0x401524: jne 0x40162f ; No -> Direct failure (Jump to failure) ; ------------------------------------------------------------------------- ; PHASE 2: CHECK AND PREPARATION OF 64-BIT INTEGERS (S1 AND S2) ; ------------------------------------------------------------------------- 0x40152a: lea edi,[esi+0x10] ; edi = Pointer to second memory block (0x404210) ; Verification of the First 64-bit Number: S1 = [esi] (0x404200) 0x40152d: mov eax,DWORD PTR [esi] ; eax = Low 32 bits of S1 0x40152f: mov edx,DWORD PTR [esi+0x4]; edx = High 32 bits of S1 0x401532: test edx,edx ; Is S1 zero? 0x401534: jne 0x40153e 0x401536: test eax,eax 0x401538: je 0x40162f ; If S1 == 0 -> Failure ; Comparison of S1 with Modulus M (stored at 0x40403c) 0x40153e: sub eax,DWORD PTR ds:0x40403c ; S1 - Modulus (low part) 0x401544: sbb edx,DWORD PTR ds:0x404040 ; S1 - Modulus (high part with borrow) 0x40154a: jae 0x40162f ; If S1 >= Modulus -> Failure (S1 must be < M) ; Copy and Verification of the Second 64-bit Number: S2 = [esi+0x8] (0x404208) 0x401550: mov eax,DWORD PTR [esi+0x8]; eax = Low 32 bits of S2 0x401553: mov edx,DWORD PTR [esi+0xc]; edx = High 32 bits of S2 0x401556: mov DWORD PTR [edi],eax ; Copy

2026-09-04 原文 →
AI 资讯

Tableau Aliases: Rename What Readers See Without Touching the Data

By Michael Nocito , data analyst · Published August 9, 2026 By the end of this page you can turn a chart that says E, W, N and S into one that says East, West, North and South, in about thirty seconds, without editing the data or writing a calculation. You'll also know exactly why the Aliases option is missing on some fields, which is the part that sends people looking for a workaround they don't need. It's about ten minutes. Here's the move. Right-click a dimension in the Data pane, choose Aliases, and type the name you want beside each value. The chart updates, the stored data doesn't change, and every view built on that field picks up the new labels. The short version: an alias renames the members of a discrete dimension. Only discrete dimensions have members, which is why measures, dates and continuous dimensions can't have one. An alias sits in a specific place, between what's stored and what's shown, and that placement explains everything else here. So it gets the picture. The original carries a diagram here. In words: Three stacked panels connected left to right. The left panel is labeled stored and holds four small cells reading E, W, N and S. The middle panel is a narrow vertical band labeled alias, holding four arrows. The right panel is labeled shown and holds four cells reading East, West, North and South. A solid arrow runs from the stored panel through the alias band to the shown panel, indicating the direction labels travel. A second arrow attempting to run backwards from the shown panel to the stored panel is crossed through with a heavy X, showing that renaming the label never changes the stored value. The stored cells still read E, W, N and S after the change. This is on the certification. Aliases sit in Section 2, Exploring and Analyzing Data, which is 37% of the Tableau Desktop Foundations exam and the largest section on it. The questions people get wrong are almost always about which field types accept an alias, which is section 2 below. 1. What

2026-09-04 原文 →
AI 资讯

A Brick, a Post-it, and admin/admin — How I Learned OT Security by Building a Factory in My Bedroom

THE BRICK AND THE POST-IT My chemical plant's first vulnerability wasn't a bug, a piece of malware, or a port left open to the internet. It was a brick. In the computer room — the one with a door held open by a brick — I found a sticky note with credentials on it. They weren't even the right credentials for the system I wanted to break into. But they made me think the way whoever wrote them thinks, so I tried the most obvious pair in the world: admin / admin . And I was in. A brick propping open a door that should be locked. A sticky note guarding a password. A factory-default admin/admin. Three layers of security, three layers defeated — not by a genius hacker, but by a student on day one, carrying no tools at all. If that happens in the IT office, it's a problem. When it happens on a factory floor, where that same computer commands real pumps and valves, it's a different planet. The problem: learning OT without a factory I study computer security. Lately I've been drawn to OT — operational technology, the security of factories, power plants and industrial systems. The problem is simple: you can't learn to defend a factory from a book, and nobody will lend you theirs. Then I realized the answer was already inside the question: if you don't have one, you build one. The build: three commands and a lot of patience The lab is called GRFICSv3: an open source project that simulates an entire chemical plant — the PLC, the operator interface, the network, even the server rooms — inside Docker, on a home computer. Three commands and done: curl -O https://raw.githubusercontent.com/Fortiphyd/GRFICSv3/main/docker-compose.yml docker compose pull docker compose up -d "Three commands and done" is the story version. The real version includes my first error, arriving right on schedule at command number two: permission denied while trying to connect to the docker API at unix:///var/run/docker.sock If you hit this — and you will — here's the diagnosis: the Docker daemon is running fi

2026-09-04 原文 →
AI 资讯

Matplotlib - Session 2

Turning Data Into Decisions Bar charts, histograms, scatter plots, subplots, and plotting straight from pandas Previously learned to draw a line — literally. we now know how to create a figure, style it, and save it. But real analyst work rarely stops at trends over time. You'll need to compare categories , understand distributions , spot relationships between variables , and show several views of the data at once . That's exactly what today covers. Grab a coffee — let's turn raw numbers into charts that actually tell a story. 1. Bar Charts: Comparing Categories When to use one Bar charts are your go-to whenever you're comparing discrete categories against each other — regions, products, departments, months. If someone asks "which one is bigger?", a bar chart answers it instantly. The code import matplotlib.pyplot as plt regions = [ " North " , " South " , " East " , " West " ] revenue = [ 420 , 380 , 510 , 290 ] fig , ax = plt . subplots ( figsize = ( 7 , 5 )) ax . bar ( regions , revenue , color = " teal " ) ax . set_title ( " Revenue by Region " ) ax . set_xlabel ( " Region " ) ax . set_ylabel ( " Revenue ($K) " ) plt . show () A useful variant: horizontal bars When category names are long, flip the chart with barh() — it's far easier to read than squeezing labels sideways: fig , ax = plt . subplots ( figsize = ( 7 , 5 )) ax . barh ( regions , revenue , color = " darkorange " ) ax . set_title ( " Revenue by Region " ) ax . set_xlabel ( " Revenue ($K) " ) plt . show () Rule of thumb: categories on the x-axis → bar() . Long labels or many categories → barh() . 2. Histograms: Understanding Distributions Bar chart vs. histogram — don't mix them up This trips up almost every beginner: a bar chart compares separate categories. A histogram shows how continuous numeric data is distributed by grouping values into ranges called bins . There are no gaps between histogram bars by convention, because the x-axis is continuous, not categorical. The code import matplotlib.pyplot

2026-09-04 原文 →
开发者

How to Find What Is Filling Up Disk Space on a Linux Server

Disk full alerts at 2am? Learn the exact commands to find what's eating your Linux server's disk space and fix it fast. You get the alert: disk usage at 94%. Your app starts throwing errors, logs stop writing, and databases refuse to accept new rows. Finding the culprit fast matters — but on a server with millions of files, knowing where to look is half the battle. Here's a systematic approach to track down disk hogs in minutes, not hours. Start With the Big Picture: df Before you dig into directories, confirm which filesystem is actually full. Run: df -h — shows all mounted filesystems with human-readable sizes df -h / — focus on the root filesystem df -i — check inode usage (a filesystem can be 'full' even with free space if inodes are exhausted) Pay attention to the 'Use%' column. If you see 100% on /var or /home but not /, that tells you exactly which mount point to investigate. Inode exhaustion — df -i showing 100% — is easy to miss and causes the same symptoms as a full disk, so always check both. Drill Down With du Once you know which mount point is full, use du to find the largest directories. Start from the top of that mount point and work down: du -sh /* 2>/dev/null — sizes of every top-level directory, errors suppressed du -sh /var/* 2>/dev/null — drill into /var if that's the culprit du -ah /var | sort -rh | head -20 — list the 20 largest files and folders inside /var The pattern is always the same: run du -sh on the suspicious directory, find the largest subdirectory, repeat one level deeper. You'll usually hit the real culprit within three or four iterations. Common offenders are /var/log (runaway logs), /var/lib/docker (unused images and volumes), and /tmp (applications that don't clean up after themselves). Find Large Files Directly With find Sometimes a single enormous file is the problem — a core dump, a forgotten database export, or a log that rotated incorrectly. Use find to surface files above a size threshold: find / -xdev -size +500M -ls 2>/de

2026-09-04 原文 →
AI 资讯

Protótipos: como a herança realmente funciona no JavaScript

Introdução Muitas linguagens como C#, Java, entre outras são descritas como orientadas a objeto, possibilitando o paradigma Programação Orientada a Objeto (POO). No entanto, quando falamos de JS, sabemos que por mais que existam objetos, ela é dita como uma linguagem orientada a protótipos, mas o que de fato isso significa, qual problema isso resolve e como muda a maneira como programamos? O problema Tanto a orientação a objeto quanto a orientação a protótipo lidam, entre outras coisas, com a questão de como a herança vai funcionar em determinada linguagem e é justamente nesse ponto que as duas abordagens mais se diferem. Em linguagens orientadas a objetos as classes de fato existem, contendo propriedades, métodos e servem como molde para a criação de objetos. Com isso, todo objeto criado a partir de uma classe herda suas propriedades e métodos ficando acessíveis para uso. Como não existem Classes de fato em JavaScript, a herança ocorre de maneira diferente, de objeto para objeto, ligados através da propriedade [[Prototype]] que possui uma referência ao seu protótipo, fazendo com que determinado objeto herde de seu protótipo propriedades e métodos que nunca foram definidos nele. Exemplo com array Quando criamos um array, seja de forma literal com [], ou de forma explícita com new Array(), o resultado final é o mesmo: um array cujo [[Prototype]] aponta para o Array.prototype. Essa propriedade .prototype possui um objeto contendo todas as propriedades e métodos que o [[Prototype]] referencia, possibilitando que todos os arrays possam usar métodos como push, pop, map, filter… Com isso, se irmos além e conferirmos o [[Prototype]] do Array.prototype vamos perceber que ele aponta para o Object.prototype que contém propriedades e métodos também disponível em todo essa cadeia que chamamos de prototype chain . Por fim, se tentarmos visualizar o protótipo do Object.prototype veremos que é null, pois ele representa o último elo dessa cadeia. Teste o código abaixo para ver na p

2026-09-04 原文 →
AI 资讯

What I learned building an enemy state machine in Godot 4

I wrote "just use a match statement, it's fine" three times before I stopped saying it. It is fine, right up until an enemy needs a fourth state and two of the transitions start depending on each other. Here is what actually cost time building enemy AI for a wave-based game, in the order it bit me. Lesson 1: the match statement is fine until state 4 A two-state enemy — chase, attack — is genuinely not worth a framework: func _physics_process ( delta : float ) -> void : match state : State . CHASE : velocity = ( player . global_position - global_position ) . normalized () * speed if global_position . distance_to ( player . global_position ) < attack_range : state = State . ATTACK State . ATTACK : attack_timer -= delta if attack_timer <= 0.0 : do_attack () state = State . CHASE The moment a third and fourth state show up — hurt, dead, stagger, windup — the match block stops being one enemy's logic and becomes a grid of every state times every other state it might transition to. That grid is where the bugs live, not in any single state. Lesson 2: the bug is never inside a state, it's in the transition Every state-machine bug I actually spent time on was the same shape: state A left some flag or timer set that state C didn't know to check. An enemy stuck mid-attack-animation forever, still receiving hits, was not a bug in the attack state — it was the hurt state interrupting attack without cleaning up attack_timer or resetting the animation. The fix that made these bugs findable is giving every state an explicit enter and exit , and never mutating another state's data directly: func change_state ( new_state : State ) -> void : if new_state == state : return _exit_state ( state ) state = new_state _enter_state ( new_state ) func _exit_state ( s : State ) -> void : match s : State . ATTACK : attack_timer = 0.0 sprite . stop () func _enter_state ( s : State ) -> void : match s : State . HURT : velocity = Vector2 . ZERO hurt_timer = HURT_DURATION sprite . play ( "hurt" ) On

2026-09-04 原文 →
AI 资讯

TinyML on ESP32-S3: Person Detection Without Sending Anything to the Cloud

Local inference that actually runs. Your smart camera is not smart. It's a snitch with a monthly bill. It sees a person, panics, compresses a blurry JPEG, uploads your hallway to a data center in Virginia, waits for a GPU to wake up and say "yeah, that's a person," and then charges you $9.99 to tell you what your own eyes could have seen in 100 milliseconds. We can do the same job for $12, with no WiFi, no cloud, and no one else ever seeing the pixels. This is how. The cloud is the bug, not the feature I get why we ended up here. Cloud was easy. You slap an RTSP stream on a Pi, send it to Rekognition, done. But for person detection specifically, cloud fails in three predictable, annoying ways. Privacy isn't a setting, it's a location. If the frame leaves your house, it's not private. It doesn't matter what the privacy policy says. Local inference means the frame lives for about a tenth of a second in PSRAM and then gets overwritten. The chip doesn't care about your pajamas. It doesn't have a retention policy. Latency ruins the whole point. Cloud roundtrip is 300ms when your WiFi is happy, two and a half seconds when your microwave is on. An on-device S3 does it in 80 to 120 milliseconds. Your light turns on when you walk in, not after you've already stubbed your toe in the dark. And cost compounds quietly. One camera is "free tier." Five cameras is a business model. The ESP32-S3 draws less than your keyboard backlight and runs on a power bank during a blackout. No API keys, no rate limits, no "your trial expired" email at 2am. If you need to know who the person is, sure, go cloud. If you just need to know is there a person here right now , local isn't just cheaper. It's the only design that isn't embarrassing. Meet the chip that finally doesn't make you hate yourself Forget the old ESP32-CAM. That thing had 520KB of SRAM and the emotional stability of a dying browser tab. You could run person detection on it if you liked watching the watchdog timer reboot your board

2026-09-04 原文 →