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

标签:#t

找到 14091 篇相关文章

开发者

Why My Portfolio Website Still Doesn't Exist

I've noticed something about myself. It's become much harder to get things done. I see less movement compared to my previous self. And sometimes, when I see people get so much done, tasks, projects, anything, I wonder why I can't make progress like that. Now I'm not comparing myself to Elon Musk here, I'm just wondering if I'm doing my best. For the longest time, I've wanted to build a portfolio website. But for some reason or another, I never actually ended up making it, or should I say, starting it. Whenever I had a free block of time, I wouldn't know where to start. I also have this side project I've been wanting to work on. I started it, then never made any more progress beyond the initial feasibility analysis. Why did I never allocate time to either? The Overthinking Starts Early I wanted the portfolio website to be really good. I wanted cool additions, beyond the usual "about me" and "projects" sections, I wanted things like "songs I'm obsessed with right now" and "last night I slept at." I was also looking if my fitbit has an API to show my live heart-rate on my portfolio (why would someone do that?). I was obsessed with the features, and with using the right tech to make it as efficient as possible. What stack should I even use for a portfolio? Same story with this very blog. Before writing a single word, I was wondering what stack to use. I looked into a ton of existing blogs for inspiration, how do I track views, what about comments, how do I stop a DDoS from flooding my DB if I'm storing comments, should I require auth just to leave a comment, should I support font and background color changes, themes, what's the best tool to do all of that? I've noticed this pattern with almost everything I do. I'm so obsessed with doing things right on the first attempt that I never actually make the first attempt, because "doing it right" is just too demanding. Or a related trap, when I want to do something perfectly , I discover prerequisites, and those prerequisites

2026-07-04 原文 →
AI 资讯

How to Test OAuth Recovery Emails Without Exposing Real Inboxes

OAuth recovery emails look harmless until you test them the lazy way. A team sends password reset links or recovery codes into one shared mailbox, confirms that something arrived, and marks the job done. From a security view, that test is too weak. It can hide token reuse, wrong-user delivery, or log retention that exposes sensitive account events. For non-production checks, I like using a disposable email address that belongs to one test run. Some teams build that inbox layer themselves, some use tempmailso, but the core principle is the same: isolate the recovery event, inspect it quickly, and delete the evidence you no longer need. That is helpful when Authentication and OAuth changes ship together. Why OAuth recovery emails deserve their own threat model Recovery email tests are not just "did the mail send?" checks. They sit on the edge of account takeover risk, so the message itself matters almost as much as the login flow. A decent threat model for these emails should ask: did the message reach only the intended inbox for this run? does the link or code expire when the product says it does? is the message revealing too much user data in subject lines or previews? can an older token still be used after a new recovery request? do logs or test fixtures keep the recovery secret longer than they should? This is where shared inboxes become dangerous in a subtle way. Even if nobody has bad intent, mixed test data makes it harder to prove which token belonged to which request. The same operational confusion shows up in email change confirmation checks , and it gets worse when the email can restore account access. OWASP recommends testing authentication recovery features with the same care as sign-in and session controls, because weak recovery paths are a common bypass route for stronger primary login defenses: https://cheatsheetseries.owasp.org/cheatsheets/Forgot_Password_Cheat_Sheet.html A safer test flow for recovery links and codes The cleanest pattern is one inbox

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

Amazon updated 2023’s Fire HD 10 tablet with 4GB of RAM

The Fire HD 8 that launched in 2024 was the last new addition to Amazon's budget-minded tablet lineup, but the company has quietly updated the Fire HD 10 that debuted the year before. In 2023 it was offered with multiple storage configurations that each came with 3GB of RAM, but the 32GB version now ships […]

2026-07-04 原文 →
AI 资讯

Effort Levels in Practice: I Benchmarked low Through max on Real Tasks

The current Claude models give you an effort knob with five settings: low , medium , high , xhigh , max . The docs tell you what each is for. I wanted numbers, so I ran the same three real tasks across all five levels and measured tokens, latency, and quality. The results changed how I set effort, and one of them surprised me. Here is the data and what I do with it now. What effort controls Effort is not just "how much the model thinks." It controls overall token spend: how much it thinks and how it acts. Lower effort means fewer, more consolidated tool calls, less preamble, terser output. Higher effort means more exploration before answering. The default is high if you omit it. const response = await client . messages . create ({ model : " claude-opus-4-8 " , max_tokens : 16000 , thinking : { type : " adaptive " }, output_config : { effort : " medium " }, // the knob messages , }); The three tasks I picked tasks that span the range of what I actually do: Classification : label a contract finding as low/medium/high/critical. Short, scoped. Code generation : write a TypeScript function with edge-case handling. Medium difficulty. Multi-step audit : analyze a 200-line contract for vulnerabilities across functions. Hard, agentic. I ran each at all five effort levels, three times, and averaged. I scored quality against a known-correct answer for tasks 1 and 3, and by manual review for task 2. The results Task 1, classification. Quality was flat across every effort level. The right label is the right label, and the model nailed it at low just as well as at max . But token usage climbed steeply: max used roughly 8x the tokens of low for an identical answer. Latency tracked tokens. The lesson: for genuinely simple, scoped tasks, high effort is pure waste. I set classification to low . Task 2, code generation. Quality improved from low to high , then plateaued. At low the model sometimes skipped an edge case. At high it caught them. xhigh and max produced essentially the sam

2026-07-03 原文 →
AI 资讯

The Go Code Review Comments List: 10 Rules Every Reviewer Cites

Book: The Complete Guide to Go Programming Also by me: Hexagonal Architecture in Go — the companion book in the Thinking in Go series My project: Hermes IDE | GitHub — an IDE for developers who ship with Claude Code and other AI coding tools Me: xgabriel.com | GitHub You open a pull request in a Go repo you just joined. Ten minutes later there are six comments on it. None of them are about your logic. They point at a capitalized error string, a receiver named this , a context stored on a struct. Each comment links the same page: the Go Code Review Comments wiki. That page is the closest thing Go has to an official style council. It grew out of the comments Go's own maintainers left on CLs for years, and most Go teams treat it as the default rulebook. The problem is that the wiki tells you what but rarely why , so the rules read like arbitrary taste. They aren't. Each one exists because the alternative bit somebody. Here are ten that reviewers cite the most, with the reason behind each. Everything below is idiomatic on Go 1.23+. 1. Error strings are lowercase and unpunctuated The rule: an error string should not be capitalized and should not end with punctuation. // wrong return fmt . Errorf ( "Failed to open config." ) // right return fmt . Errorf ( "failed to open config" ) The reason is wrapping. Go errors get concatenated. Your string is almost never the whole sentence a user reads; it's a fragment in a chain built with %w : return fmt . Errorf ( "load settings: %w" , err ) // -> "load settings: open config: permission denied" Capitalize your fragment and you get load settings: Open config: permission denied in the middle of a line. End it with a period and you get a period in the middle of a longer message. Lowercase, no trailing punctuation, and every fragment composes cleanly no matter where it lands in the chain. The exception is a string that begins with an exported name or acronym, which keeps its own case ( HTTP , TLS ). 2. Receiver types are consistent ac

2026-07-03 原文 →
AI 资讯

Go Naming: Why Getters Drop the Get Prefix (and Other Idioms)

Book: The Complete Guide to Go Programming Also by me: Hexagonal Architecture in Go — the companion book in the Thinking in Go series My project: Hermes IDE | GitHub — an IDE for developers who ship with Claude Code and other AI coding tools Me: xgabriel.com | GitHub You write a Go struct with a private field and a method to read it. Muscle memory from Java, C#, or PHP takes over, and you type GetName() . The code compiles. Tests pass. Then a reviewer leaves a comment that just says "drop the Get" with no explanation, and you're left wondering whether that's a real rule or one person's taste. It's a real rule. It's written into the language's own style guide, the standard library follows it everywhere, and several linters will flag the code that breaks it. Go naming isn't a matter of opinion the way it is in some languages. A handful of conventions are baked into the tooling, and once you know them, half the reviewer nitpicks disappear. Getters drop the Get The convention comes straight from the Effective Go document. If you have an unexported field owner , the accessor is named Owner , not GetName or GetOwner . The mutator, if you need one, keeps the Set prefix. type File struct { owner string } func ( f * File ) Owner () string { return f . owner } func ( f * File ) SetOwner ( o string ) { f . owner = o } The reasoning is about how the call reads. person.Name() says the same thing as GetName() with less noise, and the parentheses already tell you it's a method call. Get adds a word that carries no information in a language where field access and method calls look different anyway. The Set prefix stays because there's no other clean way to signal mutation. Name() reads, SetName(x) writes. The asymmetry is deliberate. This shows up all over the standard library. bytes.Buffer has Len() , not GetLen() . sync.Once has no getters to get wrong, but http.Request exposes fields and methods that never carry a Get . time.Time has Hour() , Minute() , Second() . The pattern is

2026-07-03 原文 →
AI 资讯

How to actually track your AI / LLM API spend before the bill surprises you

You wire up the OpenAI SDK, ship the feature, and it works. Three weeks later someone in finance forwards a screenshot of a bill that tripled and asks what happened. You open the provider dashboard, see one big number, and… that's it. No per-feature breakdown, no idea which change caused it, no way to tell whether it's a bug or just growth. I've watched this happen at enough teams that I now treat "we can't explain our AI bill" as a predictable stage every company hits about two months after their first LLM feature ships. Here's how to get ahead of it — starting with plain code, then the tradeoffs, then where a dedicated tool actually earns its keep. Disclosure up front: I work on StackSpend, which does the full version of this. I've kept the first 80% of this post vendor-neutral because most of it you can and should build yourself before you buy anything. The core problem: the bill is a single number, your costs are not Provider dashboards give you total spend over time. What you actually need to make decisions is spend broken down by the dimensions you care about: Per feature — is it the summarizer or the chat assistant that's expensive? Per customer / tenant — which accounts cost more to serve than they pay? Per model — how much are you spending on GPT-4-class vs cheaper models? Per environment — is a runaway staging job quietly burning money? None of those dimensions exist in the raw bill. You have to attach them yourself, at call time, because after the request is gone the context is gone with it. Step 1: capture usage at the call site Every major provider returns token usage in the response. The trick is to log it with your own business context attached — the feature name, the tenant, the environment. Here's the pattern in TypeScript with the OpenAI SDK: import OpenAI from " openai " ; const openai = new OpenAI (); // Prices per 1M tokens — keep these in config, they change often. const PRICING : Record < string , { input : number ; output : number } > = { " g

2026-07-03 原文 →
AI 资讯

Why pandas_market_calendars Fails for Indian Markets (and what to use instead)

Indian algo traders and quant developers hit the same wall: they reach for pandas_market_calendars , set up XNSE , and get back answers that are silently wrong for three segments that matter most in India. Here is what breaks and what to use instead. The three failure cases 1. MCX evening sessions MCX commodity markets (crude oil, natural gas, gold, silver) run until 23:30 IST. pandas_market_calendars has no MCX calendar. Any check after 15:30 returns a wrong answer. # pandas_market_calendars — no MCX at all # mcal.get_calendar("MCX") → KeyError # aion-indian-market-calendar — works correctly from aion_indian_market_calendar import IndiaMarketCalendar from datetime import datetime from zoneinfo import ZoneInfo cal = IndiaMarketCalendar . bundled ( 2026 ) tz = ZoneInfo ( " Asia/Kolkata " ) cal . is_market_open ( " MCX " , datetime ( 2026 , 6 , 18 , 20 , 0 , tzinfo = tz )) # True 2. NSE Currency Derivatives (CDS) — wrong hours, wrong holidays USDINR, EURINR, GBPINR, JPYINR futures and options trade on NSE CDS from 09:00 to 17:00 IST — 90 minutes longer than NSE equity. CDS also has a separate holiday calendar. pandas_market_calendars has no CDS calendar. Using XNSE gives you wrong close times and potentially wrong holiday answers for any currency derivative workflow. from aion_indian_market_calendar import IndiaMarketCalendar cal = IndiaMarketCalendar . bundled ( 2026 ) # These resolve correctly to their respective segments cal . is_market_open ( " USDINR " , at ) # NSE_CURRENCY_DERIVATIVES: closes 17:00 cal . is_market_open ( " NSE " , at ) # NSE_EQUITY: closes 15:30 cal . is_market_open ( " MCX " , at ) # MCX: closes 23:30 3. Muhurat trading (Diwali special session) On Diwali, NSE runs a one-hour equity session in the evening. pandas_market_calendars marks this day as a holiday. Schedulers that rely on it will skip execution entirely. cal = IndiaMarketCalendar . bundled ( 2026 ) events = cal . events_on ( " 2026-11-08 " , exchange = " NSE " ) # Returns the Muhurat t

2026-07-03 原文 →
AI 资讯

unsafe.Pointer in Go: The 4 Patterns the Rules Actually Allow

Book: The Complete Guide to Go Programming Also by me: Hexagonal Architecture in Go — the companion book in the Thinking in Go series My project: Hermes IDE | GitHub — an IDE for developers who ship with Claude Code and other AI coding tools Me: xgabriel.com | GitHub You reach for unsafe.Pointer to skip a copy. Maybe a []byte you want as a string without the allocation, maybe a struct you want to reinterpret as another. The code compiles. go vet stays quiet. Tests pass. Then, weeks later, under GC pressure, a rare crash shows up in a place that has nothing to do with your change. The Go unsafe package documentation is one long doc comment. It lists the conversions that are valid and warns that everything else is not portable and not guaranteed to keep working. The trouble is that "everything else" includes a lot of code that looks obviously correct. The rules are narrow on purpose. There are effectively four patterns you are allowed to write, and the standard library stays inside all four. Here they are, in the shape you will actually use them in Go 1.23+. The one fact under every rule unsafe.Pointer is a pointer the garbage collector understands. It keeps the object it points at alive and it moves with the object if the runtime relocates a stack. uintptr is a plain integer. The GC does not treat it as a reference. Convert a pointer to a uintptr , store that integer in a variable, and as far as the runtime is concerned nothing points at that memory anymore. That single fact is behind three of the four patterns. Every legal conversion either avoids uintptr entirely or keeps it inside one expression where the compiler can prove the pointer stays live. Pattern 1: reinterpret *T1 as *T2 with the same layout The first pattern converts a *T1 to *T2 when the two types have the same memory shape. You take the address, run it through unsafe.Pointer , and cast to the target pointer type. The standard library does exactly this in math.Float64bits : func Float64bits ( f float64

2026-07-03 原文 →
AI 资讯

Five Things to Check When Delivering Fast

By Vilius Vystartas This is the follow-up to What Actually Changed in Two Weeks . That one was about setting up a project for AI-speed delivery. This one is about something I keep re-learning on every fast delivery. You start shipping faster with AI. The code works, the feature lands, it feels good. Then a few weeks later the feedback comes back, and some of it catches you off guard. Not because anything is broken — but because a few things that seemed obvious to you weren't obvious to the other side. No drama. It happens. Here are five things I'm learning to check earlier. 1. What does "done" look like from their side? To me, done means working software. To someone else it might mean pixel-match with a design. Both are valid. What helps: A quick "what does good enough look like to you?" before the work starts. One sentence can save a lot of back and forth. 2. When will they actually look at it? Sending something doesn't mean it gets reviewed immediately. It lands in a queue like everything else. What helps: Naming a review date alongside the delivery date. "I'll share this Tuesday — could you take a look by Friday?" Turns silence from a mystery into a signal. 3. What needs to be perfect vs what can be improved later? Not everything in the feedback is the same weight. A label change and a broken flow are different things. Without saying so upfront, everything looks like an emergency. What helps: Two buckets agreed early. "Here's what I'll get right before it ships. Here's what I'd revisit in a follow-up." Makes the first feedback session more productive. 4. Could they see something before the full delivery? The first time someone sees your work often sets the tone. Showing one page or one flow halfway through can catch mismatches before they multiply. What helps: A mid-point check-in. "First page is ready — want to see if this matches what you had in mind?" Five minutes that can save a round of revisions. 5. Do they have the full picture? You've been living in this

2026-07-03 原文 →
AI 资讯

Method Values vs Method Expressions in Go: A Distinction Worth Knowing

Book: The Complete Guide to Go Programming Also by me: Hexagonal Architecture in Go — the companion book in the Thinking in Go series My project: Hermes IDE | GitHub — an IDE for developers who ship with Claude Code and other AI coding tools Me: xgabriel.com | GitHub You are wiring an HTTP router. You have a Server struct with a handler method, and you want to register it. So you write mux.HandleFunc("/users", srv.ListUsers) and it works. You never stop to ask what srv.ListUsers actually is as an expression. It is a method value. Go took the method, bound it to srv , and handed you back a plain func(http.ResponseWriter, *http.Request) . That binding is the thing doing the quiet work in half the handler wiring you write. There is a second form the Go spec gives you, and most Go developers never type it on purpose: the method expression, Server.ListUsers , which produces a function that takes the receiver as its first argument. Same method, different shape, different use. These two live in the Go spec and they are worth telling apart, because the compiler will happily let you reach for the wrong one. The two forms, side by side Start with a small type and one method. type Greeter struct { prefix string } func ( g Greeter ) Say ( name string ) string { return g . prefix + " " + name } A method value binds the receiver now: g := Greeter { prefix : "hello" } say := g . Say // method value, receiver g is captured fmt . Println ( say ( "ana" )) // "hello ana" say has type func(string) string . The receiver is gone from the signature because Go already stored g inside the closure. Call it later, from anywhere, and it still remembers g . A method expression leaves the receiver open: say := Greeter . Say // method expression, no receiver yet fmt . Println ( say ( g , "ana" )) // "hello ana" say here has type func(Greeter, string) string . The receiver became the first parameter. You supply it at the call site, every time. Same method name. g.Say reads the value g ; Greeter.Sa

2026-07-03 原文 →