产品设计
How Canva uses S3 for logged-in session management
I put together a writeup about the interesting technical challenges that led to redesigning Canva's session revocation pipeline that keeps hundreds of millions of user sessions fast and secure. Hopefully some people find the content interesting! submitted by /u/llewvallis [link] [留言]
AI 资讯
We've been spending more time rebuilding things than adding new buttons lately, and honestly, that's been a good thing.
We've been spending more time rebuilding things than adding new buttons lately, and honestly, that's been a good thing. Currently working on: AI-powered brand-aware templates. Website URL → Beautiful testimonial experiences. Better Wall of Love pages and widgets. Theme customization. A much more scalable architecture for generated templates. Building products is funny sometimes. What users will see as a "Generate Template" button has taken weeks of discussions around frontend, backend, rendering, and architecture decisions. Still a lot to do, but we're excited about where Clientalio is heading. Back to building. 🚀 submitted by /u/Intelligent-Video-16 [link] [留言]
开发者
Roll your own file-based router in under 50 lines of code
Nowadays, web frameworks come with ✨ magic ✨. Some more than others, but all of them have some. The...
AI 资讯
Tried building GitHub's search box in Go
Hello, I'm Maneshwar. I'm building git-lrc, a Micro AI code reviewer that runs on every commit. It is...
AI 资讯
Sovereign Lemmings Released
I have released the Sovereign package on Github. It deploys Lemmings into up to 3 cloud regions for your choice in configuration flavor with cost estimations through dry-runs and aggregating the report into one final report as lemmings come and go in the result of the load test. I built it for organizations that plan on using AI to build something, not hire somebody like me who helped write The Library to do it for them. You can hire me in consulting if you need help, but it's available now. But, before you spend $50,000 on a television ad driving people to your new app that you just built after spending $50,000 on tokens, why not run Lemmings and Sovereign first? It's 100% free and does not involve me at all in order for you to read through the extensive README.md files and comments in the code for you to understand what to do to run it and adapt to its results. Enjoy using it! There - that is the post. Now - 🙌🏻 - Ask me anything 🙇🏻 👇🏻
AI 资讯
Python's Object Model in Depth: Why Two Lines That Look the Same Behave Differently
Two lines of code. Same variable. Same operator. Completely different behavior. a = [ 1 , 2 , 3 ] b = a b += [ 4 ] # line A print ( a ) # [1, 2, 3, 4] x = 1 y = x y += 1 # line B print ( x ) # 1 Line A changes a . Line B does not change x . The only difference is whether the variable holds a mutable or immutable object. To understand why this happens, you need to understand how Python actually represents variables internally. Variables Are Not Boxes The box metaphor is how most introductory programming courses explain variables: a variable is a box that holds a value. You put 5 into the box called x . Later you can replace it with 10. In Python this metaphor is accurate for immutable types and dangerously misleading for mutable types. The more accurate model: a Python variable is a name that is bound to an object. The object exists independently of the name. Multiple names can be bound to the same object. Binding a name to a new object does not affect the old object or other names that reference it. You can inspect this directly: a = [ 1 , 2 , 3 ] b = a print ( id ( a ) == id ( b )) # True -- same object, two names x = 5 y = x print ( id ( x ) == id ( y )) # True -- both point to integer object 5 Both cases start the same: two names pointing to the same object. What happens next depends on whether you mutate the object or rebind the name. Two Fundamental Operations Every operation on a Python object falls into one of two categories. Mutation : the object at a given memory address is modified. All names pointing to that address see the change. Rebinding : a name is pointed at a different memory address. Other names pointing to the original address are unaffected. List methods like .append() , .extend() , .sort() , and item assignment lst[i] = x are mutations. Assignment with = is rebinding. The += operator is either mutation or rebinding depending on whether __iadd__ is implemented and the object is mutable. Tracing Through the Object Graph a = [[ 1 , 2 ], [ 3 , 4 ]]
AI 资讯
I liked stackoverflow
Hello. I really liked stackoverflow >5 years ago. There were many people asking about easy-to-medium problems to be solved, and it was a great way for me to learn C/C++/Bash/awk/sed/cmake/Linux/whatever by solving real-life(!) mediocre problems and also helping people in the process and also being criticized and corrected at the same time, from which I learned triple as much. Now stackoverflow is dead. My almost 150k reputation means nothing. Finally they added a "advice" type of questions which is way way too late. Now I lurk over reddit for typic-specific type of questions, but reddit is more a social network then help-me-with-programming-problem site, and the "help me" part is anyway so easy to solve with an AI. It was great back then - the feeling of learning something new and at the same actually helping and actually feeling like an expert in something. I learned the C programming standard by heart by answering really niche questions about C program behaviors. This was really fun for me. I enjoyed the specificity of stackoverflow - the idea of being "exact", answering only the question asked. There are just no questions nowadays on stackoverflow. There is a void now. And AI. There are topic-specific Discord chats, as a modern replacement of IRC, but I always assumed they are used by developers, not for noobs. I know the times without AI will never come again, but the internet, the thing connecting people across the whole globe, just feels more empty, more robotic and like an advertisement nowadays. submitted by /u/kolorcuk [link] [留言]
AI 资讯
SQL query analyzer that generates dialect-specific index DDL across 5 databases without connecting to any of them.
Most SQL performance tooling requires either a $400/month monitoring agent or asking models and hoping the advice applies to your database. The interesting architecture decisions: Heuristic engine runs first (<200ms), LLM is optional and additive — if LLM fails, you still get structured findings All dialect logic lives in one dialect_config.py — DDL templates, optimizer syntax, LLM system prompts, maintenance commands for all 5 DBs Schema-aware mode: paste DDL, get confirmed recommendations with real table names instead of placeholders Every analysis gets a permanent shareable URL Source: https://github.com/AutoShiftOps/querytuner Live: https://querytuner.com submitted by /u/sajjasudhakararao [link] [留言]
AI 资讯
Unity's Path to CoreCLR: What the Mono Cutover Means for Your Studio
Unity is replacing its scripting runtime. Not tweaking it, replacing it. The Mono runtime that has sat under every line of C# you have written in Unity for years is being retired in favour of Microsoft's CoreCLR. It is the most significant change to Unity's foundation in over a decade, and it is no longer a distant roadmap item: the Unity 6.7 public alpha is out now, with CoreCLR arriving as an experimental option. Most of the coverage treats this as good news wrapped in a version number. It is good news. But if you run a real project, the interesting questions are the practical ones: when does this actually reach me, what changes underneath my game, and what is going to break. Here is that read, from the perspective of a studio that plans and runs Unity upgrades for a living. What CoreCLR Is, and Why Unity Is Doing It Unity has been running a heavily customised fork of Mono for years. That custom fork is the reason Unity has always trailed the wider .NET ecosystem: while the rest of the C# world moved to modern runtimes, garbage collectors, and language features, Unity developers looked on from behind a runtime that could not easily keep pace. CoreCLR is Microsoft's modern, open-source .NET runtime, the same one that powers current .NET. Moving to it does three things at once: it gives Unity a far more capable runtime and garbage collector, it unlocks modern C# and the current .NET library ecosystem, and it dramatically improves iteration time, the write-save-wait-for-domain-reload loop that quietly eats hours of every Unity developer's week. Unity 6.8 is expected to target .NET 10 and C# 14. To make room for it, Unity has done something telling: it paused new work on animation and world-building workflows specifically to concentrate engineering on this migration and on architectural stability. That is a company choosing foundations over features, which is the right call, and a sign of how big this change is. The Timeline That Actually Matters The migration lands a
AI 资讯
Unity 6.5 Is Here: Should Your Studio Upgrade?
Unity 6.5 arrived in mid-June 2026, and if you skimmed the announcement you would be forgiven for filing it under "minor update." There is no single headline feature to point at. But 6.5 is more consequential than it looks, because the important changes are subtractions. Several systems that a lot of production projects still lean on have been marked for removal, and the countdown has started. This post is the read we would give a client: what actually changed, which parts matter depending on where you are in your development cycle, and a straight answer on whether to upgrade. First, What Kind of Release This Is Under the Unity 6 model there are two kinds of release, and the difference decides most of the upgrade question on its own. Update releases (6.4, 6.5, 6.6) carry the newest features, platform support, and performance work. Unity describes 6.5 as a Supported release with the same stability and critical-fix quality as an LTS, right up until the next release lands. They are aimed at projects in active or mid-cycle development. LTS releases (6.3 LTS, and 6.7 LTS later this year) are the ones to lock production on. 6.3 LTS is supported with fixes and platform updates through December 2027. They are the safe harbour for a title that is shipping or about to. One date to note if you have not moved recently: Unity 6.0 LTS support ends in October 2026. If you are still on it, that is the real deadline on your calendar, not 6.5. The Real Story: What Is Being Deprecated This is the part worth your attention. None of these break your project today, but each one is a planning item. The Built-In Render Pipeline is deprecated. BIRP still works, and Unity has committed to supporting it through the full 6.7 LTS lifecycle, but it will become obsolete in a future release. If your project is still on BIRP, this is your signal to scope a migration to URP while it is a controlled piece of work rather than something forced on you by an engine upgrade you cannot avoid. Unity has add
AI 资讯
Introducing NumPy4J: Bringing NumPy-Style Computing toJava
Java is everywhere in backend systems, enterprise applications, and production environments. But when it comes to numerical computing, data manipulation, and scientific-style operations, Python's NumPy ecosystem has become the standard. I wanted a similar experience in Java: a lightweight, dependency-free library for working with multidimensional arrays and linear algebra. That idea became NumPy4J. What is NumPy4J? NumPy4J is an open-source numerical computing library for Java inspired by NumPy. It provides: Multidimensional arrays (NDArray) NumPy-style broadcasting Array creation utilities Reshaping and slicing Element-wise operations Linear algebra operations Example: NDArray A = NDArray . of ( new double []{ 1 , 2 , 3 , 4 }, 2 , 2 ); NDArray B = NDArray . ones ( 2 , 2 ); NDArray C = A . add ( B ); Matrix operations: NDArray result = LinearAlgebra . matmul ( A , B ); Solving equations: NDArray x = LinearAlgebra.solve(A, b); Why build another numerical library? There are already excellent Java math libraries available. The goal of NumPy4J is different: Provide a NumPy-like API experience Make multidimensional arrays a first-class concept in Java Keep the API simple and approachable Create a foundation for future scientific computing features Testing approach To make sure behavior stays consistent, NumPy4J uses Python NumPy as a reference implementation. Test cases are generated with NumPy and validated against the Java implementation, covering: Broadcasting Matrix operations Reshaping Transpose Linear solving Element-wise calculations What's next? The roadmap includes: More NumPy-compatible operations Matrix decompositions (QR, LU, Cholesky) Eigenvalue computation More statistics functions Performance improvements Try it out If you work with Java and need NumPy-style numerical operations, I would love for you to try NumPy4J, provide feedback, and contribute ideas. GitHub: https://github.com/darius1973/numpy4j Documentation: https://darius1973.github.io/numpy4j/inde
AI 资讯
Why two O(n²) loops can run 15× apart
Two nested loops can do the same work, have the same O(n²) complexity, and still run around 15× apart. A visual explainer on why: the RAM model, the memory wall, cache lines, locality, L1/L2/L3, prefetching, data layout and false sharing. It also covers how the timing difference between a cache hit and miss became the side channel behind Spectre and Meltdown. submitted by /u/Ok_Marionberry8922 [link] [留言]
AI 资讯
I counted every OP_RETURN on Bitcoin. A machine out-wrote all of human history 45 to 1.
There's a romantic idea about Bitcoin's chain: that it's a wall of human messages. Proposals, memorials, "Vahe was here," pizza jokes, the occasional protest note pinned into the world's most expensive append-only log. I wanted to know if that was actually true. So I counted. Every OP_RETURN output, from the genesis block to block 958,893, no sampling. The answer is no, and it's not close. The one number All human-readable OP_RETURN text ever mined into Bitcoin: 3,827,227 outputs. Runes, one token protocol, in its own era: 171,114,058 OP_RETURN outputs. That's a ratio of 44.7 to 1 . One machine protocol, in a single two-year stretch, wrote about 45 times more to the chain than every human-readable message in Bitcoin's entire history combined. The evidence, per era I split the chain into four eras by block height, not by any label stored in my database. Height boundaries are canonical and anyone can check them against a node, so the result doesn't depend on trusting my extractor's tags. era height range boundary event pre-ordinals 0 – 767,429 before the first inscription ordinals 767,430 – 779,831 inscription #0 to BRC-20 deploy boom-brc20 779,832 – 839,999 BRC-20 ordi deploy to Runes runes 840,000 – 958,893 Runes launch at the halving Then I counted the full population of OP_RETURN outputs in each era. Human-readable text, Runes token messages, and binary blobs (Veriblock and OMNI proof-of-proof timestamping, mostly). era total OP_RETURN human text human % Runes Runes % binary binary % pre-ordinals 51,965,944 861,532 1.66% 7 0.00% 51,103,723 98.34% ordinals 261,767 32,189 12.30% 3 0.00% 229,544 87.69% boom-brc20 2,980,954 402,161 13.49% 40,251 1.35% 2,538,248 85.15% runes 177,474,762 2,531,345 1.43% 171,114,058 96.42% 3,828,604 2.16% Here's the honest twist When I started, I expected to find a fall. A golden human era that machines later ate. That's the clean story, and it's wrong. Look at the human % column again. Human text was never the majority of OP_RETURN. Not
AI 资讯
#02 – Encapsulation & Abstraction in Python
Welcome to Day 2! Today we focus on two core pillars of Object-Oriented Programming: Encapsulation: Hiding internal state and requiring all interaction to go through performing validation or controlled methods. Abstraction: Hiding complex implementation details and exposing only a clean, simplified interface to the user. 1. Access Modifiers: Public, Protected, & Private 🛡️ Python does not have strict enforcement keywords like public or private found in Java or C++. Instead, it uses naming conventions and name mangling to communicate intent and protect internal data. ┌─────────────────────────────────────────────────────────────────────────────┐ │ ACCESS MODIFIERS IN PYTHON │ ├──────────────┬───────────────┬──────────────────────────────────────────────┤ │ Level │ Syntax │ Scope / Intended Access │ ├──────────────┼───────────────┼──────────────────────────────────────────────┤ │ Public │ self.name │ Accessible anywhere (inside & outside class) │ │ Protected │ self._balance │ Internal & subclasses only (Convention) │ │ Private │ self.__pin │ Class internal only (Triggers Name Mangling) │ └──────────────┴───────────────┴──────────────────────────────────────────────┘ Public ( self.name ): Fully accessible from anywhere. Protected ( self._balance ): Single leading underscore. Signals to developers: "This is internal—do not mutate or access outside this class or its subclasses." Private ( self.__pin ): Double leading underscore. Triggers name mangling ( _ClassName__attribute ), making it hard to accidentally access or override outside the class. 💻 Code Example: Access Modifiers & Name Mangling class SecureVault : def __init__ ( self , owner : str , balance : float , pin_code : str ): self . owner = owner # Public self . _balance = balance # Protected (convention) self . __pin = pin_code # Private (name mangled) def verify_pin ( self , pin : str ) -> bool : return self . __pin == pin vault = SecureVault ( " Alice " , 50000.0 , " 9876 " ) # Public access works as expected
开发者
A Fast Path for Fixed-Length Lists in Parquet
submitted by /u/gunnarmorling [link] [留言]
AI 资讯
Physics programming - Rotation and Quaternions
I explain rotations and quaternions. I then implement the latter into my physics engine by replacing the matrix version of angular velocity code with a quaternion version. Lastly, I benchmark the results. submitted by /u/PeterBrobby [link] [留言]
工具
Sandboxing Script Extensions with GraalVM
submitted by /u/grashalm01 [link] [留言]
AI 资讯
I launched to zero signups, then found 5 features nobody could reach
I spent months building an AI agent platform. I launched it on Product Hunt yesterday. Zero signups. The comments were friendly. Three of the four asked for the same thing — not features, not integrations, not a lower price. They wanted to see what the agents did and what they cost . One put it better than my own landing page ever did: they liked that it wasn't "a black box." So I went to make the cost dashboard better. Instead I found out my product had been lying to me for months, and the lies had a pattern. Here's everything, with the code. 1. Every run cost $0.00 The Cost Analytics page reported $0.02 in total across ~100 executions . I'd assumed that meant the platform was cheap to run. It meant the data was being destroyed at write time. cost_cents = int ( ( llm_response . prompt_tokens * 0.5 / 1000 ) + ( llm_response . completion_tokens * 1.5 / 1000 ) ) A typical run on my platform is 56 prompt tokens and 45 completion tokens. That's 0.0843 cents . int() makes it 0 . Not some runs. Essentially every run — because almost every LLM call costs less than one cent. The production numbers: 189 agent runs, 2 with a non-zero cost. 99% of my cost data was zeroes, and the two survivors were just big enough to clear a whole cent. The rates in that formula were correct. I checked them against the providers' pricing pages; the arithmetic is right. The bug is entirely int() on a value that is almost never ≥ 1. A Decimal would have been the textbook fix, but Decimal / float raises TypeError and ~80 call sites do arithmetic on this number, so I widened the column to a float and kept the unit (cents). It's a dashboard estimate, not money — Paddle handles money — so float rounding is irrelevant here. 2. Workflow costs were never recorded at all Truncation at least loses precision. This one lost everything. WorkflowExecution.total_cost_cents and total_tokens_used had no write site anywhere in the codebase . Not a broken write — no write. The columns had been NULL since the feat
AI 资讯
The Bugs I Didn't Write And The Assumptions That Caused Them
This week I accidentally created my first vibe coded application. You might ask how one does this accidentally, but it's actually easier than you think. Assumptions Made: The first mistake I made was to assume that Claude remembered my setup and how I like to pair program. I have only had one previous project coded with the help of Claude and GHCP and it's a much more basic application than what I was building this week. I assumed, incorrectly, that Claude would 'remember' how I liked to work and go through the project with me as we make decisions and coding blocks together. The other assumption I made was giving a somewhat blanket approval for Claude to just run with things. I thought at some point Claude would stop, check its understanding during development and then continue but I got excited at the idea of using subagents and once I'd selected that option there was no stopping Claude on its rampage through my code! So What's the Project? I've recently started looking at doing more work with AI rather than just prompting Claude or GHCP to help with the day to day. I wanted to actually call an LLM and sift through information which could then be saved in a DB and recalled at a later point. I set myself a four week plan (with the help of Claude) to help solidify my learning with week one being a basic console application in C# that takes some text, sends to an LLM and then extracts certain information, in this case names of people, which is saved into a Postgres database. Sounds simple right? Where things went right This project started off very interesting. I had a conversation with Claude, same as I would with another developer, about the right LLM to use for this project. We went through the positives, negatives and the potential cost benefits and pitfalls of each option. In the end it was narrowed down to two choices, OpenAI or Gemini. Given that I was experimenting quite a bit and I didn't want to accidentally run up costs, I decided to go with Gemini's free t
AI 资讯
The Overengineering Trap We All Fall Into
The most dangerous overengineering does not look careless. It looks thoughtful. It has clean interfaces, reusable components, configurable behavior, extension points, and an architecture diagram that makes the system appear ready for anything. Then the next feature arrives. A change that should take one afternoon touches seven layers, breaks three abstractions, and forces the team to understand a framework built for requirements that never appeared. That is what makes overengineering difficult to recognize. It rarely presents itself as unnecessary complexity. It presents itself as responsible engineering. It Usually Begins With a Reasonable Fear Developers do not overengineer because they want to make systems harder. They usually remember an earlier project that became painful. Maybe duplicated business logic spread across several screens. Maybe a component could not support a second use case. Maybe an integration became impossible to replace. Maybe a narrow implementation eventually required an expensive rewrite. The next time a similar problem appears, the team tries to protect itself. What if this feature grows? What if another team needs it? What if product asks for configuration? What if we add more providers? What if the rules change? These are reasonable questions. The problem begins when imagined requirements receive the same architectural weight as real ones. A single approval flow becomes a workflow engine. Two similar components become a universal rendering framework. One pricing exception becomes a configurable rules platform. The team tries to avoid future pain and creates immediate friction instead. The first use case now has to support requirements that do not exist. Developers must understand extension points nobody uses, configuration nobody needs, and interfaces protecting boundaries that have not appeared. Thinking about the future is not the mistake. Building the future before there is evidence is. Reuse Is Expensive Before the Pattern Is Stable