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

标签:#RAM

找到 2544 篇相关文章

AI 资讯

Part 1 — What Actually Happens When Code Runs

When we write: const result = add ( 10 , 20 ); it feels like the computer simply "runs the code." But the CPU doesn't understand JavaScript. There are several layers between the code we write and the hardware actually executing instructions. That's what I wanted to understand first. From JavaScript to the CPU In Node.js, JavaScript is handled by V8 , the JavaScript engine. A simplified view looks like this: JavaScript ↓ V8 ↓ Bytecode ↓ JIT compilation ↓ Machine instructions ↓ CPU V8 doesn't simply "interpret JavaScript" or "compile JavaScript" once and forget about it. It can start with bytecode and progressively compile frequently executed ("hot") code into more optimized machine code. Eventually, the CPU is executing instructions that operate at a much lower level than the JavaScript we originally wrote. What does the CPU actually do? At its core, a CPU repeatedly executes instructions. A simplified mental model is: Fetch → Decode → Execute → Repeat The CPU has several important pieces involved in this process. Registers are tiny, extremely fast storage locations inside the CPU. They're used to hold values the CPU is actively working with. The ALU (Arithmetic Logic Unit) performs many arithmetic and logical operations. The Program Counter (PC) keeps track of where the next instruction comes from. And the CPU runs according to a clock, measured in GHz. A 3 GHz CPU has roughly 3 billion clock cycles per second, but that does not mean it executes 3 billion instructions per second. Different instructions and architectures have different costs. Modern CPUs are far more sophisticated than this simplified model, using pipelining, multiple execution units, branch prediction, out-of-order execution, and more. But the basic model is enough to start reasoning about performance. The CPU doesn't get everything from RAM One of the most important things I learned here is that where data lives matters . A simplified hierarchy looks like: Registers ↓ L1 Cache ↓ L2 Cache ↓ L3 Cache

2026-08-20 原文 →
开发者

Automatiza tareas repetitivas con un bot en Python

Cada tarea manual y repetitiva que haces cada semana es tiempo (y dinero) que un script de Python puede recuperarte. La automatización no es solo para grandes empresas. Primero: ¿qué vale la pena automatizar? Busca tareas repetitivas, basadas en reglas y frecuentes . Algunos ejemplos habituales: Descargar y consolidar informes cada mañana. Copiar datos entre una web y una hoja de cálculo. Enviar recordatorios o alertas. Vigilar precios o cambios en una página. Una regla práctica: si puedes explicar la tarea como una lista de pasos sin excepciones, probablemente se puede automatizar. Las herramientas del ecosistema Python requests / httpx para hablar con APIs y webs. BeautifulSoup / Playwright para web scraping (Playwright cuando la página carga con JavaScript). pandas para transformar datos. APScheduler o cron para ejecutarlo en un horario. Bots de Telegram o Discord para recibir avisos donde ya estás. Un ejemplo mínimo Vigilar el título de una página y avisar si cambia: import requests from bs4 import BeautifulSoup def titulo ( url ): html = requests . get ( url , timeout = 10 ). text return BeautifulSoup ( html , " html.parser " ). title . string . strip () anterior = titulo ( " https://example.com " ) # ...ejecutado por cron cada hora... actual = titulo ( " https://example.com " ) if actual != anterior : print ( " ¡Cambió! " ) # aquí enviarías un mensaje de Telegram De script a bot fiable Un script que corre en tu portátil es un buen comienzo, pero un bot fiable vive en un servidor, registra lo que hace, maneja errores (reintentos, tiempos de espera) y te avisa si algo falla. Ese salto —de experimento a herramienta en la que confías— es donde más aporta un desarrollador. ¿Tienes una tarea que odias hacer a mano? Probablemente se pueda automatizar. Cuéntame cuál es y te digo cómo abordarla: contacto .

2026-08-20 原文 →
AI 资讯

Building Distributed Systems in Elixir: Part 6 — Named Processes

In the previous part of this series, we built a tiny supervisor from scratch. When a worker crashed, the supervisor started a replacement. That replacement had a new PID: old worker -> #PID<0.102.0> new worker -> #PID<0.105.0> This reveals an important limitation of sharing PIDs as a public interface. A PID identifies one running incarnation of a process. It is excellent for sending a reply, setting up a monitor, or creating a link. It is not a stable address for a service that may stop and later be replaced. In this part, we'll use named processes to give a worker a discoverable address: :worker We'll build three small examples using: Process . register / 2 Process . whereis / 1 :global . register_name / 2 :global . whereis_name / 1 send / 2 No GenServer . No OTP Registry . The goal is to understand the lookup problem that registries solve before reaching for those abstractions. The PID-Sharing Problem Suppose one process starts a worker and gives its PID to a client: worker = spawn ( fn -> worker_loop () end ) send ( client , { :worker_started , worker }) The client can now send work directly: send ( worker , { :work , self (), "hello" }) This works while that particular worker process is alive. But process IDs are temporary. If the worker exits, the PID is no longer a route to the service: Client Worker holds #PID<0.102.0> #PID<0.102.0> | | | X exits | | send(#PID<0.102.0>, work) |------------------------------> no worker receives it Sending to a dead local PID does not raise an error and does not restart a process. The message is simply not delivered to a living worker. One answer is to tell every client about every new PID after a restart. That spreads lifecycle knowledge throughout the system. Another answer is to make clients depend on a name and resolve that name when sending. Registering a Local Name Our first worker waits for a stop message: defmodule Worker do def start do spawn ( fn -> receive do :stop -> :ok end end ) end end Starting it gives us a PID:

2026-08-19 原文 →
AI 资讯

A Safer Way to Delegate AI Coding Tasks Without Sharing Accounts

AI coding agents are useful, but team collaboration around them can become messy very quickly. A common shortcut is to share an account, API key, or long-lived access token so another teammate can run a task. It may feel convenient, but it creates avoidable security, ownership, and review problems. A better approach is to separate the task from the account that executes it. The person requesting the work prepares a complete, portable task. The person running it uses their own authorized AI-agent subscription and returns the result with evidence. Here is a practical way to structure that workflow. Why shared AI accounts create problems When several people use the same AI account, it becomes difficult to answer basic operational questions: Who initiated a specific action? Which person approved the resulting changes? What project context was exposed? Who is responsible for reviewing the output? What happens when a teammate changes roles or leaves? Shared credentials also tend to spread. A password may end up in a private message, a token may be copied into a local configuration file, or a browser session may remain active on an unmanaged device. Even when everyone involved is trusted, the process itself is difficult to audit. The goal should not be to share access more efficiently. It should be to share the work without transferring the account. Treat the task as a portable unit A useful AI task should make sense outside the original conversation in which it was created. Someone receiving the task should be able to understand: the desired outcome; the relevant project context; the boundaries of the work; the evidence required for completion; the decisions that still need human review. This turns the request into a portable unit of work rather than a fragment of chat history. For example, instead of writing: Update the import flow. Write something closer to: When a user uploads a CSV containing duplicate email addresses, show a validation summary before importing any re

2026-08-19 原文 →
AI 资讯

The Rate Limiter Strikes Back: Designing a Token Bucket from Scratch

The Quest Begins (The "Why") I still remember the first time our API started choking under a sudden traffic spike. It was a Friday afternoon, the kind where you’re just about to log off, and the monitoring dashboard lit up like a Christmas tree. Requests were piling up, latency shot through the roof, and our users began seeing those dreaded “429 Too Many Requests” errors. We had a naive rate limiter in place—a simple fixed‑window counter that reset every minute. It worked fine when traffic was steady, but as soon as a burst hit, the counter would either let too many through (because we hadn’t hit the limit yet) or block everything for the whole minute (because we’d already exhausted the quota). It felt like trying to hold back a tsunami with a sandbag. Honestly, I was frustrated. I knew there had to be a smarter way to smooth out those bursts without penalizing honest users or over‑protecting the system. That’s when I dove into the world of rate‑limiting algorithms, and the token bucket caught my eye like a shiny loot drop in a dungeon. The Revelation (The Insight) The token bucket is deceptively simple, yet it solves the exact pain points we were experiencing. Imagine a bucket that holds a fixed number of tokens. Tokens drip into the bucket at a steady rate (say, 10 tokens per second). Each incoming request consumes a token. If the bucket is empty, the request is denied or delayed; if there’s a token, the request proceeds and the token is removed. Why does this beat the fixed‑window counter? Burst tolerance – The bucket can store up to its capacity, allowing a short burst of requests up to that limit without waiting for the next window. Smooth throttling – Because tokens are added continuously, the limiter adapts to the actual request rate rather than resetting abruptly at arbitrary intervals. Memory‑light – We only need to track two numbers: the current token count and the last time we refilled the bucket. No arrays of timestamps per key. Here’s a quick ASCII sket

2026-08-19 原文 →
AI 资讯

Custom Software Development: What I Wish I Knew Before Starting

You budgeted six months. It took fourteen. You wanted one thing; you got three things that almost do it. And somewhere between the first sprint and the final invoice, you stopped understanding what you were even paying for. If that sounds familiar, this is the breakdown no one gave you before you started. What custom software development actually means Custom software development is building software from the ground up for your specific business, not configuring Salesforce, not installing a plugin. You're solving a problem your operations have, the way your operations actually work. What trips people up: "custom" doesn't mean "built entirely from scratch." Good dev teams use frameworks, libraries, and third-party services. What's custom is the logic of how your data flows, how business rules are enforced, how users interact. Scope range is huge: Custom dev covers everything from a lightweight internal dashboard to a full-scale multi-tenant SaaS platform. This is why cost estimates vary so wildly. 3 things nobody tells you before you sign 1. Scope creep is almost always the client's fault "Users should be able to manage their accounts" sounds simple. It actually contains dozens of decisions: can they change their email? What verification is required? Can they delete their account? Each one is a feature. Each feature has a cost. The fix: Run a discovery phase (2–4 weeks) before writing a single line of production code. It costs money upfront. It saves far more mid-project. 2. The cheapest bid rarely wins long-term A $40k quote and a $180k quote for the same project both happen. The $40k team isn't lying; they're optimistic, underbidding to win work, or scoping something different. What actually happens: you hit $40k, and you're 40% done. Higher bids from experienced teams often include architecture planning, documentation, testing infrastructure, and post-launch support things the cheap bid omitted. These aren't extras. They're what make the software maintainable in t

2026-08-19 原文 →
AI 资讯

Three Lines to Draw Before You Scrape Instagram

Most write-ups on this subject are about technique. This one is about the three decisions you should make before you write any code, because in my experience every project that went badly went badly for a reason that was decided on day one and not noticed until much later. I have built this kind of collection twice, for competitive analysis and for a partner-vetting workflow. Neither of them needed to touch anything behind a login, and I want to explain why that turned out to be the useful constraint rather than the limiting one. Line one: the login wall is a boundary A login wall is a statement about who the content is for. Treating it as an engineering obstacle to be routed around is the decision that puts a project on the wrong side of everything: terms of service, the platform's own detection, and in several jurisdictions the law. So the first line is simply: if it requires an account to see, it is out of scope. Not "hard," not "for later." Out of scope. I am not going to discuss techniques for getting past one, and I would be sceptical of any article that does. The interesting engineering question here is not how to see more. It is how much you can actually do with what is openly published, and the honest answer is: considerably more than people assume before they check. This constraint also has a practical benefit that is easy to miss. A pipeline built only on openly available data does not break when authentication changes, does not require credential management, and does not put an account at risk. Mine has survived two platform changes that took down colleagues' authenticated collectors. Line two: public does not mean unrestricted The second line is the one developers get wrong most often, and it has nothing to do with access. Data being publicly visible says nothing about whether you may store it, for how long, or what you may do with it. In the EU and UK, information about an identifiable person is personal data whether or not they published it themselves

2026-08-19 原文 →
AI 资讯

Why do we need Map and Set in JavaScript when we already have Arrays and Objects? What do they bring to the table?

I'm currently learning JavaScript and recently came across the Map and Set data structures. I understand that Set stores unique values and Map stores key-value pairs, but I'm wondering what advantages they actually provide over the existing Array and Object structures. What are some practical situations where you would choose Map or Set instead of an Array or Object? I'd especially appreciate real-world examples that make the differences clear. submitted by /u/hamzafullstack [link] [留言]

2026-08-19 原文 →
AI 资讯

Python Polars Cheat Sheet: Fast DataFrames for Busy Engineers

Polars hits the sweet spot between Pandas’ ease and Spark’s scale. If you’ve ever waited on a groupby or cursed a memory error, this cheat sheet is for you. I’ve pulled the patterns that save time in real pipelines, not just toy examples. Bookmark this before your next ETL run. Setup and Basics First, get Polars and a dataset. The lazy API is the default now, so you’ll rarely need to call .lazy() explicitly. Start with a CSV or Parquet file, or create a DataFrame from scratch. pip install polars pyarrow import polars as pl df = pl.read_csv('data.csv') # or pl.read_parquet() df = pl.DataFrame({'a': [1, 2], 'b': ['x', 'y']}) Selecting and Filtering Polars uses expressions, not strings. This feels odd at first but pays off when you chain operations. The syntax is consistent: every column is an expression you can transform, filter, or aggregate. df.select(['a', 'b']) # columns by name df.select(pl.col('a').alias('renamed')) df.filter(pl.col('a') > 10) df.filter(pl.col('b').is_in(['x', 'z'])) df.filter(pl.col('a').is_null()) Transforming Data Polars expressions are composable. You can nest them, reuse them, and even store them in variables. This is where the library shines over Pandas. df.with_columns(pl.col('a').cast(pl.Float64)) df.with_columns(pl.col('a').fill_null(0)) df.with_columns((pl.col('a') * 2).alias('a_doubled')) df.with_columns(pl.col('b').str.to_uppercase()) df.with_columns(pl.col('a').is_between(10, 20)) Grouping and Aggregations Groupbys in Polars are lazy by default. This means you can stack multiple aggregations without materializing intermediate results. The syntax is clean, but watch out for the order of operations. df.group_by('b').agg(pl.col('a').sum()) df.group_by('b').agg([pl.col('a').mean(), pl.col('a').max()]) df.group_by('b').agg(pl.col('a').quantile(0.9)) df.group_by_dynamic('timestamp', every='1d').agg(pl.col('a').sum()) Joins and Concatenation Joins in Polars are explicit. You’ll specify the join type and the columns to join on. Concatenatio

2026-08-19 原文 →