[{"data":1,"prerenderedAt":5414},["ShallowReactive",2],{"all-learn-concepts":3},[4,2832],[5,634,1162,1670,2087,2533],{"id":6,"title":7,"body":8,"cardImage":571,"cardImageAlt":572,"date":573,"description":574,"domain":575,"domainKey":576,"extension":577,"featured":578,"fullName":579,"interaction":14,"maturity":580,"mentalModel":581,"meta":582,"navigation":578,"neighbors":583,"ogImage":610,"path":611,"published":578,"robots":610,"seo":612,"shortName":613,"sitemap":614,"socialImage":615,"socialImageAlt":616,"sources":617,"stem":626,"tags":627,"translationKey":14,"updated":573,"__hash__":633},"learnEn/learn/discounted-cash-flow.md","Discounted Cash Flow",{"type":9,"value":10,"toc":545},"minimal",[11,15,23,26,32,35,40,48,51,90,108,118,128,134,138,164,167,171,174,190,193,196,200,203,209,216,223,229,236,240,243,246,252,262,271,274,280,283,289,292,296,303,323,333,339,342,346,351,354,360,364,367,370,374,377,381,384,398,401,421,424,428,432,435,439,442,446,449,453,456,460,463,467,485,489,506,509,513],[12,13,7],"h1",{"id":14},"discounted-cash-flow",[16,17,18,19],"p",{},"Discounted Cash Flow (DCF) valuation asks a simple but demanding question: ",[20,21,22],"strong",{},"what are future distributable cash flows worth today, after accounting for when they arrive and the return required for bearing their risk?",[16,24,25],{},"The answer is not a hidden “correct price.” It is a conditional sentence:",[27,28,29],"blockquote",{},[16,30,31],{},"If these operating, reinvestment, timing, and risk assumptions hold, the estimated value is approximately this amount.",[16,33,34],{},"That distinction is the heart of the method. A spreadsheet can calculate precisely while the assumptions remain deeply uncertain.",[36,37,39],"h2",{"id":38},"an-everyday-example-buying-a-vending-machine","An everyday example: buying a vending machine",[16,41,42,43,47],{},"Suppose a vending machine in an office building is for sale at ",[44,45,46],"code",{},"$120,000",". You would not begin with snack sales. You would ask how much cash remains each year after restocking, electricity, repairs, and the location fee.",[16,49,50],{},"Start with a completely hypothetical set of assumptions:",[52,53,54,62,69,76,83],"ul",{},[55,56,57,58,61],"li",{},"the machine currently leaves ",[44,59,60],{},"$8,000"," of cash per year;",[55,63,64,65,68],{},"that cash grows by ",[44,66,67],{},"3%"," annually for the next five years;",[55,70,71,72,75],{},"because you must wait and the machine could break, lose its location, or sell less than expected, you require a ",[44,73,74],{},"10%"," annual return;",[55,77,78,79,82],{},"after year five, stop guessing year by year and assume cash grows at ",[44,80,81],{},"2%"," in the long run;",[55,84,85,86,89],{},"the machine still has a ",[44,87,88],{},"$5,000"," loan attached to it.",[16,91,92,93,96,97,100,101,96,104,107],{},"Discounting the first five annual cash flows back to today gives about ",[44,94,95],{},"$32,981",". That is the ",[20,98,99],{},"present value of the explicit period",". Summarizing all cash after year five into terminal value and discounting it back gives about ",[44,102,103],{},"$73,421",[20,105,106],{},"present value of terminal value",".",[109,110,116],"pre",{"className":111,"code":113,"language":114,"meta":115},[112],"language-text","Present value of years 1–5   ≈  $32,981\nPresent value after year 5   ≈  $73,421\nOperating asset value        ≈ $106,403\nLess: remaining loan         =   $5,000\nBuyer-equity value           ≈ $101,403\n","text","",[44,117,113],{"__ignoreMap":115},[16,119,120,121,124,125,127],{},"Under these assumptions, ",[44,122,123],{},"$101,403"," is a conditional answer—not the machine’s “correct price.” If the seller still wants ",[44,126,46],{},", DCF helps you ask what must explain the gap: more future cash, less risk, or another source of value.",[16,129,130,131,133],{},"The ",[44,132,74],{}," required return is an everyday stand-in for the intuition of a discount rate. A formal Weighted Average Cost of Capital (WACC) for a company combines the required returns of debt and equity; it is not simply a number chosen by feel.",[36,135,137],{"id":136},"four-terms-in-plain-language","Four terms in plain language",[52,139,140,146,152,158],{},[55,141,142,145],{},[20,143,144],{},"Free Cash Flow to the Firm (FCFF)",": cash the operating business can provide to lenders and shareholders together. Think of it as cash the business has produced before deciding which capital provider receives it.",[55,147,148,151],{},[20,149,150],{},"Weighted Average Cost of Capital (WACC)",": the combined annual return required by lenders and shareholders. In this model it is the discount rate used to translate future cash into today’s units; a higher WACC makes the same future cash worth less today.",[55,153,154,157],{},[20,155,156],{},"Present value of the explicit period",": the sum of the next 5 or 10 years of cash flows after each year has been discounted back to today. “Explicit” only means those years are forecast one by one.",[55,159,160,163],{},[20,161,162],{},"Present value of terminal value",": the model cannot forecast every year forever, so it summarizes all cash flows after the explicit period into one value at the forecast horizon, then discounts that value back to today.",[16,165,166],{},"Add the two present values to estimate Enterprise Value. Subtract Net Debt in this simplified model to estimate Equity Value.",[36,168,170],{"id":169},"first-choose-whose-cash-flow-you-are-valuing","First choose whose cash flow you are valuing",[16,172,173],{},"The first decision is not the growth rate. It is the capital claim.",[52,175,176,184],{},[55,177,178,180,181,183],{},[20,179,144],{}," belongs to debt and equity capital providers together. It is commonly discounted using the ",[20,182,150],{}," to estimate Enterprise Value.",[55,185,186,189],{},[20,187,188],{},"Free Cash Flow to Equity (FCFE)"," belongs only to common equity holders. It is discounted using the cost of equity to estimate Equity Value directly.",[16,191,192],{},"The cash-flow definition and discount rate must match. Discounting FCFF at the cost of equity, or FCFE at WACC, mixes up who receives the cash and who bears the risk.",[16,194,195],{},"The interactive model on this page uses FCFF, WACC, and a simplified net-debt bridge.",[36,197,199],{"id":198},"build-the-explicit-forecast","Build the explicit forecast",[16,201,202],{},"A common FCFF bridge begins with Earnings Before Interest and Taxes (EBIT):",[109,204,207],{"className":205,"code":206,"language":114,"meta":115},[112],"FCFF\n= EBIT × (1 − tax rate)\n+ Depreciation & Amortization\n− Capital Expenditure\n− Change in Net Working Capital\n",[44,208,206],{"__ignoreMap":115},[16,210,211,212,215],{},"The bridge exposes a constraint that optimistic stories often hide: ",[20,213,214],{},"growth is not free",". More revenue may require inventory, receivables, equipment, research, distribution, or other reinvestment before it becomes distributable cash.",[16,217,218,219,222],{},"For each year ",[44,220,221],{},"t",", discount the forecast cash flow:",[109,224,227],{"className":225,"code":226,"language":114,"meta":115},[112],"Present Value of FCFFₜ = FCFFₜ / (1 + r)ᵗ\n",[44,228,226],{"__ignoreMap":115},[16,230,231,232,235],{},"The rate ",[44,233,234],{},"r"," must use the same currency, inflation convention, time scale, and capital claim as the cash flow.",[36,237,239],{"id":238},"account-for-cash-flows-beyond-the-forecast","Account for cash flows beyond the forecast",[16,241,242],{},"A company does not disappear because a model stops after year five. DCF models therefore use a Terminal Value to summarize cash flows after the explicit period.",[16,244,245],{},"One common stable-growth form is:",[109,247,250],{"className":248,"code":249,"language":114,"meta":115},[112],"Terminal Valueₙ = FCFFₙ₊₁ / (r − g)\n",[44,251,249],{"__ignoreMap":115},[16,253,254,255,258,259,107],{},"Here ",[44,256,257],{},"g"," is the stable growth rate. The model requires ",[44,260,261],{},"r > g",[16,263,264,265,267,268,270],{},"When ",[44,266,257],{}," approaches ",[44,269,234],{},", the denominator approaches zero and Terminal Value explodes. That is not a discovery of enormous value. It is a warning that the long-run assumptions have lost economic discipline.",[16,272,273],{},"Discount the Terminal Value back to today and add it to the explicit-period cash flows:",[109,275,278],{"className":276,"code":277,"language":114,"meta":115},[112],"Enterprise Value\n= Σ Present Value of explicit FCFF\n+ Present Value of Terminal Value\n",[44,279,277],{"__ignoreMap":115},[16,281,282],{},"A simplified equity bridge is:",[109,284,287],{"className":285,"code":286,"language":114,"meta":115},[112],"Equity Value = Enterprise Value − Net Debt\n",[44,288,286],{"__ignoreMap":115},[16,290,291],{},"A complete bridge may also add non-operating cash and investments and subtract other non-equity claims. The interactive model uses only net debt so the mechanism stays visible.",[36,293,295],{"id":294},"a-worked-example","A worked example",[16,297,298,299,302],{},"Suppose a fictional business starts with ",[44,300,301],{},"$100m"," of FCFF:",[52,304,305,308,311,314,317],{},[55,306,307],{},"five-year explicit forecast;",[55,309,310],{},"7% annual FCFF growth;",[55,312,313],{},"9% WACC;",[55,315,316],{},"3% stable growth;",[55,318,319,322],{},[44,320,321],{},"$250m"," of net debt.",[16,324,325,326,329,330,107],{},"The present value of the five explicit cash flows is about ",[44,327,328],{},"$473m",". The present value of Terminal Value is about ",[44,331,332],{},"$1,565m",[109,334,337],{"className":335,"code":336,"language":114,"meta":115},[112],"Enterprise Value ≈ $2,038m\nEquity Value     ≈ $1,788m\nTerminal share  ≈ 77%\n",[44,338,336],{"__ignoreMap":115},[16,340,341],{},"That final line is often the most informative. A 77% terminal share does not automatically make the model wrong, but it says most of the answer is controlled by distant assumptions. The next research question should be about sustainable growth, reinvestment, competitive advantage, and the discount rate—not another decimal place.",[36,343,345],{"id":344},"what-dcf-is-actually-good-at","What DCF is actually good at",[347,348,350],"h3",{"id":349},"turning-a-story-into-a-causal-chain","Turning a story into a causal chain",[16,352,353],{},"“This is a great business” cannot enter a model directly. DCF forces the story into observable drivers:",[109,355,358],{"className":356,"code":357,"language":114,"meta":115},[112],"market and competitive advantage\n→ revenue growth and margins\n→ reinvestment\n→ free cash flow\n→ risk and required return\n→ value today\n",[44,359,357],{"__ignoreMap":115},[347,361,363],{"id":362},"locating-disagreement","Locating disagreement",[16,365,366],{},"Two people may produce different values, but the disagreement usually lives in a small number of assumptions: how long growth lasts, what steady-state margins look like, how much reinvestment growth requires, and whether risk is consistently reflected.",[16,368,369],{},"DCF turns “I disagree with the price” into “I disagree with this operating or capital assumption.”",[347,371,373],{"id":372},"comparing-decisions-without-pretending-to-know-the-future","Comparing decisions without pretending to know the future",[16,375,376],{},"DCF can compare projects, acquisitions, capital-allocation choices, or operating scenarios under a common framework. Sensitivity analysis, scenario analysis, stress testing, and Monte Carlo simulation then challenge the conditional answer.",[36,378,380],{"id":379},"where-it-worksand-where-it-degrades","Where it works—and where it degrades",[16,382,383],{},"DCF tends to be most useful when:",[52,385,386,389,392,395],{},[55,387,388],{},"value mainly comes from future distributable cash flows;",[55,390,391],{},"the operating model and reinvestment logic can be explained;",[55,393,394],{},"cash flow and discount rate can be matched consistently; and",[55,396,397],{},"the purpose is to understand value drivers, not merely reproduce a market multiple.",[16,399,400],{},"It becomes fragile when:",[52,402,403,406,409,412,415,418],{},[55,404,405],{},"an early-stage business has no credible path to normalized cash flow;",[55,407,408],{},"a cyclical company is modeled from an abnormal peak or trough;",[55,410,411],{},"debt is closer to operating raw material, as in many financial institutions;",[55,413,414],{},"value comes largely from options to delay, expand, or abandon;",[55,416,417],{},"Terminal Value dominates while steady-state economics remain unconstrained; or",[55,419,420],{},"the model uses precision as decoration but does not test its critical inputs.",[16,422,423],{},"These cases do not always prohibit DCF. They often require a different model structure, cash-flow definition, or uncertainty treatment.",[36,425,427],{"id":426},"common-mistakes","Common mistakes",[347,429,431],{"id":430},"dcf-is-subjective-so-it-is-useless","“DCF is subjective, so it is useless”",[16,433,434],{},"Judgment is unavoidable, but judgment does not have to be hidden. A useful DCF makes assumptions visible, internally consistent, falsifiable, and easy to challenge. A market multiple contains assumptions too; they are simply less explicit.",[347,436,438],{"id":437},"a-higher-discount-rate-is-always-more-conservative","“A higher discount rate is always more conservative”",[16,440,441],{},"Holding everything else constant, a higher discount rate lowers present value. But changing risk, inflation, growth, and cash-flow conventions inconsistently does not create conservatism. It creates a mismatched model.",[347,443,445],{"id":444},"terminal-value-is-the-leftover-bucket","“Terminal Value is the leftover bucket”",[16,447,448],{},"Terminal Value is often most of the valuation. It deserves operating constraints: What reinvestment supports stable growth? Does return on capital fade? Can the growth rate remain below the discount rate and fit the economy?",[347,450,452],{"id":451},"a-precise-calculation-is-an-accurate-valuation","“A precise calculation is an accurate valuation”",[16,454,455],{},"The arithmetic can be exact while the assumptions are wrong. A responsible result is a range with visible drivers, not a fact disguised to two decimal places.",[347,457,459],{"id":458},"enterprise-value-equals-equity-value","“Enterprise Value equals Equity Value”",[16,461,462],{},"FCFF discounted at WACC usually produces Enterprise Value. Only after bridging cash, debt, and other claims do you reach Equity Value.",[36,464,466],{"id":465},"remember-these-five-things","Remember these five things",[468,469,470,473,476,479,482],"ol",{},[55,471,472],{},"Match the claim, cash flow, and discount rate: FCFF ↔ WACC; FCFE ↔ cost of equity.",[55,474,475],{},"Growth consumes reinvestment before it becomes distributable cash.",[55,477,478],{},"Terminal Value is often the main valuation, not an appendix.",[55,480,481],{},"DCF outputs a conditional sentence, not an objective price.",[55,483,484],{},"Use sensitivity, scenarios, stress tests, and simulation to challenge the result.",[36,486,488],{"id":487},"self-test","Self-test",[468,490,491,494,497,500,503],{},[55,492,493],{},"Why should FCFF not be discounted at the cost of equity?",[55,495,496],{},"Why does value usually fall when WACC rises and all else stays constant?",[55,498,499],{},"What happens as stable growth approaches the discount rate?",[55,501,502],{},"Can revenue rise while FCFF falls? What reinvestment could cause that?",[55,504,505],{},"If Terminal Value is 85% of Enterprise Value, which assumptions deserve the most scrutiny?",[16,507,508],{},"This page is an educational, hypothetical illustration. It does not provide investment advice or estimate the value of any real security or company.",[36,510,512],{"id":511},"further-reading","Further reading",[52,514,515,524,531,538],{},[55,516,517],{},[518,519,523],"a",{"href":520,"rel":521},"https://pages.stern.nyu.edu/~adamodar/pdfiles/basics.pdf",[522],"nofollow","Aswath Damodaran, “Basics of Discounted Cash Flow Valuation”",[55,525,526],{},[518,527,530],{"href":528,"rel":529},"https://www.cfainstitute.org/insights/professional-learning/refresher-readings/2026/free-cash-flow-valuation",[522],"CFA Institute, “Free Cash Flow Valuation”",[55,532,533],{},[518,534,537],{"href":535,"rel":536},"https://doi.org/10.2139/ssrn.909070",[522],"Robert S. Harris, “Fundamentals of Discounted Cash Flow”",[55,539,540],{},[518,541,544],{"href":542,"rel":543},"https://doi.org/10.2307/1927792",[522],"Myron J. Gordon, “Dividends, Earnings, and Stock Prices”",{"title":115,"searchDepth":546,"depth":546,"links":547},2,[548,549,550,551,552,553,554,560,561,568,569,570],{"id":38,"depth":546,"text":39},{"id":136,"depth":546,"text":137},{"id":169,"depth":546,"text":170},{"id":198,"depth":546,"text":199},{"id":238,"depth":546,"text":239},{"id":294,"depth":546,"text":295},{"id":344,"depth":546,"text":345,"children":555},[556,558,559],{"id":349,"depth":557,"text":350},3,{"id":362,"depth":557,"text":363},{"id":372,"depth":557,"text":373},{"id":379,"depth":546,"text":380},{"id":426,"depth":546,"text":427,"children":562},[563,564,565,566,567],{"id":430,"depth":557,"text":431},{"id":437,"depth":557,"text":438},{"id":444,"depth":557,"text":445},{"id":451,"depth":557,"text":452},{"id":458,"depth":557,"text":459},{"id":465,"depth":546,"text":466},{"id":487,"depth":546,"text":488},{"id":511,"depth":546,"text":512},"/learn-img/discounted-cash-flow/card-4x5.jpg","An English editorial card titled Discounted Cash Flow, showing future cash-flow bars translated through time and risk into present value.","2026-07-23","Translate future cash flows, time, and risk into a conditional estimate of value today.","Finance & valuation","finance-valuation","md",true,"Discounted Cash Flow Valuation","growing","A DCF is a translator: future cash flow + time + risk → value today.",{},[584,588,592,597,601,605],{"name":585,"fullName":585,"category":586,"summary":587},"Present Value","mathematical mechanism","Converts one future amount into today’s units; DCF applies that mechanism to a complete cash-flow stream.",{"name":589,"fullName":589,"category":590,"summary":591},"Free Cash Flow","core input","Connects operating profit, taxes, reinvestment, and working capital to cash available to capital providers.",{"name":593,"fullName":594,"category":595,"summary":596},"WACC","Weighted Average Cost of Capital","discount-rate input","Supplies a blended required return that matches free cash flow to the firm.",{"name":598,"fullName":598,"category":599,"summary":600},"Terminal Value","long-horizon approximation","Compresses all cash flows after the explicit forecast period into one value at the horizon.",{"name":602,"fullName":602,"category":603,"summary":604},"Sensitivity Analysis","diagnostic method","Shows which assumptions move the conditional valuation most.",{"name":606,"fullName":607,"category":608,"summary":609},"Monte Carlo","Monte Carlo Simulation","uncertainty layer","Runs the DCF value function across many coherent input sets to produce a conditional distribution.",null,"/learn/discounted-cash-flow",{"title":7,"description":574},"DCF",{"loc":611},"/learn-img/discounted-cash-flow/og-1200x627.jpg","An English editorial diagram showing future cash-flow bars being discounted into smaller present-value blocks, beside the title Discounted Cash Flow.",[618,620,622,624],{"title":619,"url":520},"Aswath Damodaran · Basics of Discounted Cash Flow Valuation",{"title":621,"url":528},"CFA Institute · Free Cash Flow Valuation",{"title":623,"url":535},"Robert S. Harris · Fundamentals of Discounted Cash Flow",{"title":625,"url":542},"Myron J. Gordon · Dividends, Earnings, and Stock Prices","learn/discounted-cash-flow",[628,629,630,631,632],"valuation","present-value","free-cash-flow","cost-of-capital","terminal-value","GnjzYNADD_7pc--ePUtArnjz4WwiiImasL6WJfjo4Mo",{"id":635,"title":636,"body":637,"cardImage":1110,"cardImageAlt":1111,"date":1112,"description":1113,"domain":1114,"domainKey":1115,"extension":577,"featured":1116,"fullName":636,"interaction":641,"maturity":580,"mentalModel":1117,"meta":1118,"navigation":578,"neighbors":1119,"ogImage":610,"path":1145,"published":578,"robots":610,"seo":1146,"shortName":636,"sitemap":1147,"socialImage":610,"socialImageAlt":610,"sources":1148,"stem":1155,"tags":1156,"translationKey":641,"updated":1112,"__hash__":1161},"learnEn/learn/idempotency.md","Idempotency",{"type":9,"value":638,"toc":1089},[639,642,648,651,657,661,668,688,691,695,698,704,711,726,730,734,737,743,746,752,755,759,762,768,771,797,801,804,810,813,816,821,825,829,832,836,839,843,850,854,857,861,864,949,952,956,994,998,1019,1021,1038,1040,1057,1059],[12,640,636],{"id":641},"idempotency",[16,643,644,645,107],{},"Idempotency solves the hardest kind of distributed-system failure: not a clear success or failure, but an ",[20,646,647],{},"unknown outcome",[16,649,650],{},"A client sends a payment request. The server charges the card, but the response disappears on the network. The client sees a timeout. If it gives up, a payment that should complete may look failed. If it retries blindly, the customer may be charged twice.",[16,652,653,654],{},"An idempotent contract separates recovery from duplication: ",[20,655,656],{},"the request may be attempted again, but the same business intent does not create the business effect again.",[36,658,660],{"id":659},"a-restaurant-ticket","A restaurant ticket",[16,662,663,664,667],{},"Imagine handing ticket ",[44,665,666],{},"A-842"," to a kitchen and hearing no confirmation. You hand over the same ticket again.",[52,669,670,673,679,682],{},[55,671,672],{},"Without an order number, the kitchen may cook two meals.",[55,674,675,676,678],{},"With a stable order number, it finds ",[44,677,666],{}," and returns the existing order status.",[55,680,681],{},"A genuinely new meal needs a new number.",[55,683,684,685,687],{},"Reusing ",[44,686,666],{}," with a different dish should be rejected, not guessed.",[16,689,690],{},"The ticket is only an identifier. The kitchen still needs a reliable ledger, and recording the number cannot be separated from accepting the order by an unsafe gap.",[36,692,694],{"id":693},"mathematical-and-system-meaning","Mathematical and system meaning",[16,696,697],{},"An idempotent function satisfies:",[109,699,702],{"className":700,"code":701,"language":114,"meta":115},[112],"f(f(x)) = f(x)\n",[44,703,701],{"__ignoreMap":115},[16,705,706,707,710],{},"In software systems, the useful definition is semantic: making the same request multiple times has the same ",[20,708,709],{},"intended effect"," as making it once. It does not require byte-identical responses or forbid extra logs, metrics, and timestamps.",[16,712,713,714,717,718,721,722,725],{},"For example, the first ",[44,715,716],{},"DELETE /documents/42"," might return ",[44,719,720],{},"204"," and the second ",[44,723,724],{},"404",". The responses differ, but the intended state — document 42 is absent — has converged.",[36,727,729],{"id":728},"two-ways-to-get-idempotency","Two ways to get idempotency",[347,731,733],{"id":732},"make-the-operation-naturally-idempotent","Make the operation naturally idempotent",[16,735,736],{},"State assignment tends to converge:",[109,738,741],{"className":739,"code":740,"language":114,"meta":115},[112],"SET order.status = \"PAID\"     repeated → still PAID\nDELETE document 42            repeated → still absent\nPUT /profile { name: \"Li\" }   repeated → same representation\n",[44,742,740],{"__ignoreMap":115},[16,744,745],{},"Relative changes usually do not:",[109,747,750],{"className":748,"code":749,"language":114,"meta":115},[112],"balance = balance + 10\ntoggle subscription\nsend welcome email\ncreate a new charge\n",[44,751,749],{"__ignoreMap":115},[16,753,754],{},"This gives a practical first question: can “change it again” be rewritten as “make it equal to this state”?",[347,756,758],{"id":757},"add-an-idempotency-key","Add an Idempotency Key",[16,760,761],{},"Creating a payment, booking, or cloud resource cannot always be reduced to a simple assignment. The client can instead generate one stable key for one business intent and reuse it for every retry.",[109,763,766],{"className":764,"code":765,"language":114,"meta":115},[112],"Idempotency-Key: order-842-payment\nPOST /payments { amount: 42, currency: \"CAD\" }\n",[44,767,765],{"__ignoreMap":115},[16,769,770],{},"A complete protocol normally needs to:",[468,772,773,776,779,782,785,788,791,794],{},[55,774,775],{},"use one key for one intent, and a new key for a new intent;",[55,777,778],{},"scope the key by caller, account, and operation;",[55,780,781],{},"reserve it atomically with a unique constraint or transaction;",[55,783,784],{},"bind it to a request fingerprint so changed parameters are rejected;",[55,786,787],{},"record whether the operation is processing, complete, or failed;",[55,789,790],{},"replay the stored or semantically equivalent result to a completed duplicate;",[55,792,793],{},"define what a concurrent duplicate sees; and",[55,795,796],{},"declare the TTL (Time to Live) after which the key may be treated as new.",[36,798,800],{"id":799},"the-atomicity-gap-is-the-real-danger","The atomicity gap is the real danger",[16,802,803],{},"This implementation has a race:",[109,805,808],{"className":806,"code":807,"language":114,"meta":115},[112],"if key does not exist:\n  charge_card()\n  save(key, result)\n",[44,809,807],{"__ignoreMap":115},[16,811,812],{},"Two concurrent requests can both observe a missing key and both charge. The service can also crash after charging but before saving the record, leaving a retry indistinguishable from a new request.",[16,814,815],{},"Key reservation, business state transition, and result recording should share one atomic boundary where possible. If the effect crosses a database, queue, email provider, or external payment service, each boundary needs its own idempotency strategy — often a state machine, Transactional Outbox, or consumer Inbox.",[16,817,818],{},[20,819,820],{},"A header without an atomic state machine is decoration, not a guarantee.",[36,822,824],{"id":823},"four-cases-the-contract-must-name","Four cases the contract must name",[347,826,828],{"id":827},"a-completed-duplicate","A completed duplicate",[16,830,831],{},"Return the first recorded result or a semantically equivalent current result. Do not execute the business action again.",[347,833,835],{"id":834},"the-same-key-with-different-parameters","The same key with different parameters",[16,837,838],{},"Reject it. Otherwise the service cannot know whether it received a retry or a mistakenly reused key. Stripe and Amazon Elastic Compute Cloud (Amazon EC2) both treat parameter mismatch as an error.",[347,840,842],{"id":841},"a-concurrent-duplicate","A concurrent duplicate",[16,844,845,846,849],{},"The second request must not also begin the effect. It can wait, receive an ",[44,847,848],{},"in progress"," response, or get a conflict; the API (Application Programming Interface) contract must choose.",[347,851,853],{"id":852},"an-expired-key","An expired key",[16,855,856],{},"Idempotency memory is usually bounded. Once the record is pruned, the same key may execute again. The server's guarantee window must cover the client's maximum retry horizon.",[36,858,860],{"id":859},"http-safe-is-not-the-same-as-idempotent","HTTP: safe is not the same as idempotent",[16,862,863],{},"HTTP (Hypertext Transfer Protocol) distinguishes safe methods from idempotent methods.",[865,866,867,886],"table",{},[868,869,870],"thead",{},[871,872,873,877,880,883],"tr",{},[874,875,876],"th",{},"Method",[874,878,879],{},"Safe?",[874,881,882],{},"Idempotent by semantics?",[874,884,885],{},"Meaning",[887,888,889,905,920,934],"tbody",{},[871,890,891,897,900,902],{},[892,893,894],"td",{},[44,895,896],{},"GET",[892,898,899],{},"yes",[892,901,899],{},[892,903,904],{},"Requests a read and should not ask for a state change.",[871,906,907,912,915,917],{},[892,908,909],{},[44,910,911],{},"PUT",[892,913,914],{},"no",[892,916,899],{},[892,918,919],{},"Replaces the target with a representation; repeats converge.",[871,921,922,927,929,931],{},[892,923,924],{},[44,925,926],{},"DELETE",[892,928,914],{},[892,930,899],{},[892,932,933],{},"Changes state once, but repeated deletion has the same intent.",[871,935,936,941,943,946],{},[892,937,938],{},[44,939,940],{},"POST",[892,942,914],{},[892,944,945],{},"no, by default",[892,947,948],{},"Often means “create another”; needs a business-level contract.",[16,950,951],{},"An operation can therefore be state-changing and idempotent. Idempotent does not mean harmless or read-only.",[36,953,955],{"id":954},"know-the-neighboring-concepts","Know the neighboring concepts",[52,957,958,964,970,976,982,988],{},[55,959,960,963],{},[20,961,962],{},"Retry is a recovery policy."," It controls timeouts, attempt limits, exponential backoff, and jitter. Idempotency makes those attempts safe for the business effect.",[55,965,966,969],{},[20,967,968],{},"Deduplication is a detection mechanism."," It may be used to implement idempotency, but the semantic contract is broader than dropping duplicates.",[55,971,972,975],{},[20,973,974],{},"At-least-once delivery is a delivery guarantee."," It can repeat messages, so consumers need idempotent handling.",[55,977,978,981],{},[20,979,980],{},"Exactly-once is a stronger and often misleading claim."," Idempotency does not prevent repeated delivery or execution; it makes a scoped effect converge as if it happened once.",[55,983,984,987],{},[20,985,986],{},"Optimistic Concurrency Control (OCC) protects against stale writes."," OCC distinguishes competing intentions; idempotency recognizes another delivery of the same intention.",[55,989,990,993],{},[20,991,992],{},"Transactional Outbox closes a cross-system consistency gap."," It still expects duplicate publication and therefore an idempotent consumer.",[36,995,997],{"id":996},"what-it-does-not-solve","What it does not solve",[52,999,1000,1003,1006,1009,1016],{},[55,1001,1002],{},"It does not prevent retry storms; use bounded attempts, backoff, jitter, rate limits, and circuit breaking.",[55,1004,1005],{},"It does not automatically cross databases, queues, emails, and third-party APIs.",[55,1007,1008],{},"It does not prevent two different keys from racing for the same inventory.",[55,1010,1011,1012,1015],{},"It does not decide whether an API should cache and replay a first ",[44,1013,1014],{},"500"," response.",[55,1017,1018],{},"It does not create global exactly-once processing.",[36,1020,466],{"id":465},[468,1022,1023,1026,1029,1032,1035],{},[55,1024,1025],{},"Idempotency is a response to unknown outcomes: retry the attempt without repeating the intent's effect.",[55,1027,1028],{},"Prefer naturally idempotent state assignment when the domain permits it.",[55,1030,1031],{},"One intent gets one key; retries reuse it; a new intent gets a new key.",[55,1033,1034],{},"Reject the same key with changed parameters, and define concurrent and expired-key behavior.",[55,1036,1037],{},"The most dangerous bug lives in the non-atomic gap between the side effect and its idempotency record.",[36,1039,488],{"id":487},[468,1041,1042,1045,1048,1051,1054],{},[55,1043,1044],{},"If the payment committed but its response vanished, what evidence makes a retry safe?",[55,1046,1047],{},"Does your key identify a business intent, or only hash a payload?",[55,1049,1050],{},"What happens when the same key carries a different amount?",[55,1052,1053],{},"Which request wins when two duplicates arrive concurrently?",[55,1055,1056],{},"Does the key's lifetime cover the client's longest retry horizon?",[36,1058,512],{"id":511},[52,1060,1061,1068,1075,1082],{},[55,1062,1063],{},[518,1064,1067],{"href":1065,"rel":1066},"https://www.rfc-editor.org/rfc/rfc9110.html#section-9.2.2",[522],"RFC 9110 · HTTP Semantics §9.2.2 Idempotent Methods",[55,1069,1070],{},[518,1071,1074],{"href":1072,"rel":1073},"https://docs.stripe.com/api/idempotent_requests",[522],"Stripe API · Idempotent requests",[55,1076,1077],{},[518,1078,1081],{"href":1079,"rel":1080},"https://aws.amazon.com/builders-library/making-retries-safe-with-idempotent-APIs/",[522],"AWS Builders' Library · Making retries safe with idempotent APIs",[55,1083,1084],{},[518,1085,1088],{"href":1086,"rel":1087},"https://docs.aws.amazon.com/ec2/latest/devguide/ec2-api-idempotency.html",[522],"Amazon EC2 · Ensuring idempotency in API requests",{"title":115,"searchDepth":546,"depth":546,"links":1090},[1091,1092,1093,1097,1098,1104,1105,1106,1107,1108,1109],{"id":659,"depth":546,"text":660},{"id":693,"depth":546,"text":694},{"id":728,"depth":546,"text":729,"children":1094},[1095,1096],{"id":732,"depth":557,"text":733},{"id":757,"depth":557,"text":758},{"id":799,"depth":546,"text":800},{"id":823,"depth":546,"text":824,"children":1099},[1100,1101,1102,1103],{"id":827,"depth":557,"text":828},{"id":834,"depth":557,"text":835},{"id":841,"depth":557,"text":842},{"id":852,"depth":557,"text":853},{"id":859,"depth":546,"text":860},{"id":954,"depth":546,"text":955},{"id":996,"depth":546,"text":997},{"id":465,"depth":546,"text":466},{"id":487,"depth":546,"text":488},{"id":511,"depth":546,"text":512},"/learn-img/idempotency/card-4x5.jpg","Three paper receipts with the same order ID converge into one completed receipt, illustrating repeated attempts producing one business effect.","2026-07-16","Make an uncertain operation safe to retry: one intent may arrive many times, but its business effect happens once.","Software systems","software-systems",false,"The same intent may be delivered many times; the system creates the business effect once and replays that outcome to retries.",{},[1120,1124,1128,1132,1136,1140],{"name":1121,"fullName":1121,"category":1122,"summary":1123},"Retry","recovery policy","Decides when and how another attempt is made; idempotency decides whether that attempt can repeat the business effect.",{"name":1125,"fullName":1125,"category":1126,"summary":1127},"Idempotency Key","request identity mechanism","Names one business intent so every retry can be recognized as the same operation.",{"name":1129,"fullName":1129,"category":1130,"summary":1131},"Deduplication","duplicate detection mechanism","Detects or suppresses repeats; one possible mechanism for delivering idempotent behavior.",{"name":1133,"fullName":1133,"category":1134,"summary":1135},"At-least-once Delivery","delivery guarantee","May deliver a message repeatedly, requiring an idempotent consumer to absorb duplicates safely.",{"name":1137,"fullName":1137,"category":1138,"summary":1139},"Transactional Outbox","consistency pattern","Bridges a database change and message publication without an unsafe gap, while consumers still handle duplicates.",{"name":1141,"fullName":1142,"category":1143,"summary":1144},"Exactly-once","Exactly-once Processing","stronger guarantee","A frequently overclaimed end-to-end guarantee; idempotency usually converges the effect rather than preventing repeated delivery or execution.","/learn/idempotency",{"title":636,"description":1113},{"loc":1145},[1149,1151,1153,1154],{"title":1150,"url":1065},"RFC 9110 · Idempotent Methods",{"title":1152,"url":1072},"Stripe · Idempotent requests",{"title":1081,"url":1079},{"title":1088,"url":1086},"learn/idempotency",[1157,1158,1159,1160],"reliability","retry","distributed-systems","api-design","obOAANazP6Oy-Xup7MINTmZaH79WsfMHLvRTgREw_Fs",{"id":1163,"title":607,"body":1164,"cardImage":1615,"cardImageAlt":1616,"date":1617,"description":1618,"domain":1619,"domainKey":1620,"extension":577,"featured":578,"fullName":607,"interaction":1168,"maturity":580,"mentalModel":1621,"meta":1622,"navigation":578,"neighbors":1623,"ogImage":610,"path":1648,"published":578,"robots":610,"seo":1649,"shortName":606,"sitemap":1650,"socialImage":1651,"socialImageAlt":1652,"sources":1653,"stem":1662,"tags":1663,"translationKey":1168,"updated":1617,"__hash__":1669},"learnEn/learn/monte-carlo-simulation.md",{"type":9,"value":1165,"toc":1595},[1166,1169,1172,1175,1182,1186,1189,1192,1203,1206,1210,1213,1219,1229,1273,1280,1284,1291,1297,1329,1332,1335,1340,1343,1346,1350,1353,1356,1359,1363,1366,1404,1407,1411,1414,1431,1434,1438,1442,1445,1449,1455,1459,1462,1466,1469,1473,1476,1480,1483,1487,1525,1527,1544,1546,1563,1565],[12,1167,607],{"id":1168},"monte-carlo-simulation",[16,1170,1171],{},"A single forecast makes uncertainty look like a line. Monte Carlo simulation makes it visible as a distribution.",[16,1173,1174],{},"The method repeatedly samples uncertain inputs, sends each sample through the same model, and records the outcome. One run creates one internally consistent possible world. Thousands of runs reveal a range, a median, tails, thresholds, and the paths that fail.",[16,1176,1177,1178,1181],{},"The crucial word is ",[20,1179,1180],{},"conditional",". The result describes what happened inside the worlds the model was allowed to generate. It is not a claim that the model has discovered the objective probability of your real future.",[36,1183,1185],{"id":1184},"an-outdoor-event","An outdoor event",[16,1187,1188],{},"Suppose you are planning an outdoor event. A forecast of “22°C on average” is not enough to decide whether to rent a tent.",[16,1190,1191],{},"A more useful exercise is to replay the day thousands of times using plausible temperature, rain, and wind conditions—while keeping their relationships intact. Some versions are warm and clear; others are wet, cold, and windy. You can then ask:",[52,1193,1194,1197,1200],{},[55,1195,1196],{},"How often does the event cross the failure threshold?",[55,1198,1199],{},"How bad is the lower tail?",[55,1201,1202],{},"Which preparation removes the most fragile outcomes?",[16,1204,1205],{},"Monte Carlo simulation applies this same logic to any model with uncertain inputs. The casino supplied the name; disciplined sampling is the actual idea.",[36,1207,1209],{"id":1208},"the-mechanism","The mechanism",[16,1211,1212],{},"Write the outcome as a model:",[109,1214,1217],{"className":1215,"code":1216,"language":114,"meta":115},[112],"Y = f(X₁, X₂, …, Xₖ)\n",[44,1218,1216],{"__ignoreMap":115},[16,1220,1221,1224,1225,1228],{},[44,1222,1223],{},"Y"," is the result you care about. The ",[44,1226,1227],{},"X"," values are uncertain inputs. A useful simulation then follows seven steps:",[468,1230,1231,1237,1243,1249,1255,1261,1267],{},[55,1232,1233,1236],{},[20,1234,1235],{},"Name the decision and the success condition."," “Assets never run out during 30 years” is testable; “the plan looks good” is not.",[55,1238,1239,1242],{},[20,1240,1241],{},"Represent input uncertainty."," Define ranges or distributions for returns, demand, prices, growth, costs, inflation, duration, or failure rates.",[55,1244,1245,1248],{},[20,1246,1247],{},"Represent dependence."," Correlation and causal constraints keep sampled worlds coherent. Individually plausible inputs can form an impossible combination.",[55,1250,1251,1254],{},[20,1252,1253],{},"Draw one joint sample."," This produces one possible world.",[55,1256,1257,1260],{},[20,1258,1259],{},"Run the complete model."," Preserve compounding, timing, withdrawals, reinvestment, queues, or whatever makes the path matter.",[55,1262,1263,1266],{},[20,1264,1265],{},"Repeat."," The outcomes form an empirical distribution.",[55,1268,1269,1272],{},[20,1270,1271],{},"Read and challenge the distribution."," Report ranges, quantiles, threshold frequency, and failure paths; then change assumptions and add stress tests.",[16,1274,1275,1276,1279],{},"More runs reduce ",[20,1277,1278],{},"sampling noise"," inside the chosen model. They do not repair a bad model, missing risk, stale data, or an unrealistic distribution.",[36,1281,1283],{"id":1282},"a-long-horizon-funding-model","A long-horizon funding model",[16,1285,1286,1287,1290],{},"Consider a model that starts with assets ",[44,1288,1289],{},"B₀",", makes an inflation-adjusted withdrawal at the beginning of each year, and then applies that year's net portfolio return:",[109,1292,1295],{"className":1293,"code":1294,"language":114,"meta":115},[112],"Bₜ = max(0, [Bₜ₋₁ − W₀(1 + π)ᵗ⁻¹] × [1 + Rₜ − f])\n",[44,1296,1294],{"__ignoreMap":115},[52,1298,1299,1305,1311,1317,1323],{},[55,1300,1301,1304],{},[44,1302,1303],{},"Bₜ"," is the year-end balance.",[55,1306,1307,1310],{},[44,1308,1309],{},"W₀"," is the first withdrawal.",[55,1312,1313,1316],{},[44,1314,1315],{},"π"," is inflation.",[55,1318,1319,1322],{},[44,1320,1321],{},"Rₜ"," is the sampled portfolio return.",[55,1324,1325,1328],{},[44,1326,1327],{},"f"," is the annual fee.",[16,1330,1331],{},"Each run samples a different sequence of stock and bond returns while preserving the assumed relationship between them. The model then follows the full path. If assets cannot meet a withdrawal, that path is classified as depleted.",[16,1333,1334],{},"Suppose 1,640 of 2,000 runs last the full period. The careful statement is:",[27,1336,1337],{},[16,1338,1339],{},"Under these return, volatility, correlation, inflation, fee, timing, and withdrawal assumptions, 82% of the synthetic paths did not deplete.",[16,1341,1342],{},"It is not “this person has an objective 82% chance of success.” The number is better used to compare rule changes under the same assumptions: lower spending, a different allocation, lower costs, more time, or a flexible withdrawal policy.",[16,1344,1345],{},"This page is educational and does not provide personalized investment advice. The interactive outputs are hypothetical and depend entirely on visible model assumptions.",[36,1347,1349],{"id":1348},"why-sequence-changes-the-outcome","Why sequence changes the outcome",[16,1351,1352],{},"Without deposits or withdrawals, reordering the same annual returns leaves the final compounded value unchanged. Multiplication does not care about order.",[16,1354,1355],{},"With withdrawals, it does. An early loss reduces the capital base while cash is still leaving the model. A later recovery then compounds on fewer assets. Two paths with the same average return can therefore end very differently.",[16,1357,1358],{},"This is why an average path is often a poor substitute for simulated paths. The average can describe no path that ever occurred, hide temporary depletion, and erase the mechanism that caused failure.",[36,1360,1362],{"id":1361},"what-to-read-in-the-output","What to read in the output",[16,1364,1365],{},"The mean is rarely enough. A decision-quality readout usually includes:",[52,1367,1368,1374,1380,1386,1392,1398],{},[55,1369,1370,1373],{},[20,1371,1372],{},"Median:"," the middle simulated outcome, useful as a center but not as a promise.",[55,1375,1376,1379],{},[20,1377,1378],{},"Quantile range:"," for example, the 10th to 90th percentile band.",[55,1381,1382,1385],{},[20,1383,1384],{},"Threshold frequency:"," the share of sampled worlds crossing a defined failure or target line.",[55,1387,1388,1391],{},[20,1389,1390],{},"Failure timing:"," whether problems cluster early, late, or around a particular condition.",[55,1393,1394,1397],{},[20,1395,1396],{},"Tail severity:"," how bad outcomes become after the threshold is crossed.",[55,1399,1400,1403],{},[20,1401,1402],{},"Sensitivity:"," which assumptions most change the result.",[16,1405,1406],{},"A probability without its condition is an invitation to false precision. Good communication keeps the assumptions beside the output.",[36,1408,1410],{"id":1409},"where-it-helps","Where it helps",[16,1412,1413],{},"Monte Carlo simulation is useful when:",[52,1415,1416,1419,1422,1425,1428],{},[55,1417,1418],{},"several uncertain inputs jointly drive the result;",[55,1420,1421],{},"the order and timing of events matter;",[55,1423,1424],{},"the decision depends on a range, tail, or threshold rather than only an average;",[55,1426,1427],{},"strategies need to be compared under a common set of assumptions; or",[55,1429,1430],{},"a closed-form solution is unavailable or hides the path.",[16,1432,1433],{},"Examples extend beyond financial models: project schedules, inventory, reliability, queues, energy demand, insurance losses, and measurement uncertainty.",[36,1435,1437],{"id":1436},"where-it-fails","Where it fails",[347,1439,1441],{"id":1440},"garbage-in-distribution-out","Garbage in, distribution out",[16,1443,1444],{},"Professional-looking histograms do not make unsupported inputs credible. The hardest work is often defining plausible worlds, not generating random numbers.",[347,1446,1448],{"id":1447},"false-precision","False precision",[16,1450,1451,1454],{},[44,1452,1453],{},"84.7%"," may only be a more stable estimate of the chosen model's answer. Assumption error can be much larger than Monte Carlo sampling error.",[347,1456,1458],{"id":1457},"tail-blindness","Tail blindness",[16,1460,1461],{},"A thin-tailed distribution that never generates liquidity freezes, jumps, regime changes, or correlation spikes cannot reveal those risks. Add explicit stress tests.",[347,1463,1465],{"id":1464},"independence-fantasy","Independence fantasy",[16,1467,1468],{},"Sampling every variable independently can create impossible worlds. Growth, margins, rates, defaults, and asset returns often move together.",[347,1470,1472],{"id":1471},"policy-omission","Policy omission",[16,1474,1475],{},"Real people and organizations adapt. They may change spending, prices, staffing, financing, inventory, or project scope. A fixed-policy model can understate or overstate resilience.",[347,1477,1479],{"id":1478},"objective-error","Objective error",[16,1481,1482],{},"A model can optimize the wrong definition of success. Ending just above zero may still violate liquidity, service, safety, or quality constraints along the path.",[36,1484,1486],{"id":1485},"neighboring-methods","Neighboring methods",[52,1488,1489,1495,1501,1507,1513,1519],{},[55,1490,1491,1494],{},[20,1492,1493],{},"Scenario analysis"," tells a small number of coherent stories. It is easier to explain but covers fewer worlds.",[55,1496,1497,1500],{},[20,1498,1499],{},"Stress testing"," forces named extreme conditions. It complements simulation when modeled tails are incomplete.",[55,1502,1503,1506],{},[20,1504,1505],{},"Sensitivity analysis"," identifies the assumptions worth researching or monitoring. It explains drivers more directly than a distribution alone.",[55,1508,1509,1512],{},[20,1510,1511],{},"Historical simulation"," preserves real combinations from observed periods but cannot show conditions absent from the sample.",[55,1514,1515,1518],{},[20,1516,1517],{},"Bootstrap resampling"," draws from observed data and can preserve some empirical structure, especially with block methods.",[55,1520,1521,1524],{},[20,1522,1523],{},"A forecast"," tries to identify a likely future path. Monte Carlo is usually better at conditional ranges and robustness than at naming the path that will occur.",[36,1526,466],{"id":465},[468,1528,1529,1532,1535,1538,1541],{},[55,1530,1531],{},"Monte Carlo produces many conditional paths, not one privileged forecast.",[55,1533,1534],{},"The model, input distributions, dependence, and policy rules define which worlds can exist.",[55,1536,1537],{},"Read ranges, tails, threshold frequency, and failure paths—not only the average.",[55,1539,1540],{},"More iterations reduce sampling noise, not model risk.",[55,1542,1543],{},"Compare decisions under consistent assumptions and pair simulation with sensitivity analysis and stress testing.",[36,1545,488],{"id":487},[468,1547,1548,1551,1554,1557,1560],{},[55,1549,1550],{},"Why can a fixed 6% annual return behave differently from random paths averaging 6%?",[55,1552,1553],{},"What assumptions must accompany a reported “82%” result?",[55,1555,1556],{},"Which mistake cannot be repaired by increasing the number of simulations?",[55,1558,1559],{},"When should a named stress test be added even if the simulation has a 5th percentile?",[55,1561,1562],{},"Which inputs in your model should not be sampled independently?",[36,1564,512],{"id":511},[52,1566,1567,1574,1581,1588],{},[55,1568,1569],{},[518,1570,1573],{"href":1571,"rel":1572},"https://doi.org/10.1080/01621459.1949.10483310",[522],"Metropolis & Ulam (1949), “The Monte Carlo Method”",[55,1575,1576],{},[518,1577,1580],{"href":1578,"rel":1579},"https://www.nist.gov/news-events/news/2020/01/new-tool-account-uncertainty",[522],"National Institute of Standards and Technology · New Tool to Account for Uncertainty",[55,1582,1583],{},[518,1584,1587],{"href":1585,"rel":1586},"https://www.finra.org/rules-guidance/rulebooks/finra-rules/2214",[522],"Financial Industry Regulatory Authority Rule 2214 · Requirements for Investment Analysis Tools",[55,1589,1590],{},[518,1591,1594],{"href":1592,"rel":1593},"https://www.cfp.net/-/media/files/cfp-board/standards-and-ethics/compliance-resources/cfp-board-tech-guide-questionnaires-checklist.pdf",[522],"Certified Financial Planner Board · Core Financial Planning Technologies questionnaire",{"title":115,"searchDepth":546,"depth":546,"links":1596},[1597,1598,1599,1600,1601,1602,1603,1611,1612,1613,1614],{"id":1184,"depth":546,"text":1185},{"id":1208,"depth":546,"text":1209},{"id":1282,"depth":546,"text":1283},{"id":1348,"depth":546,"text":1349},{"id":1361,"depth":546,"text":1362},{"id":1409,"depth":546,"text":1410},{"id":1436,"depth":546,"text":1437,"children":1604},[1605,1606,1607,1608,1609,1610],{"id":1440,"depth":557,"text":1441},{"id":1447,"depth":557,"text":1448},{"id":1457,"depth":557,"text":1458},{"id":1464,"depth":557,"text":1465},{"id":1471,"depth":557,"text":1472},{"id":1478,"depth":557,"text":1479},{"id":1485,"depth":546,"text":1486},{"id":465,"depth":546,"text":466},{"id":487,"depth":546,"text":488},{"id":511,"depth":546,"text":512},"/learn-img/monte-carlo-simulation/card-4x5.jpg","One orange forecast line opens into many possible paths, with the message one forecast to many conditional futures.","2026-07-22","Generate many conditional futures to see ranges, tails, and failure paths—without mistaking a model for a forecast.","Finance & decision science","finance-decision-science","Do not bet on one future. Sample many coherent futures, run the full model through each one, and read the distribution.",{},[1624,1628,1632,1634,1639,1644],{"name":1625,"fullName":1625,"category":1626,"summary":1627},"Scenario Analysis","narrative method","Compares a small set of coherent, interpretable futures instead of systematically sampling a large distribution.",{"name":1629,"fullName":1629,"category":1630,"summary":1631},"Stress Testing","complementary evidence","Forces a model through named extreme conditions that an assumed distribution may rarely or never generate.",{"name":602,"fullName":602,"category":603,"summary":1633},"Shows which assumptions move the answer most; Monte Carlo propagates their joint uncertainty.",{"name":1635,"fullName":1636,"category":1637,"summary":1638},"Sequence Risk","Sequence-of-Returns Risk","path-dependent risk","Explains why the order of outcomes matters when withdrawals or other path-dependent cash flows are present.",{"name":1640,"fullName":1641,"category":1642,"summary":1643},"Bootstrap","Bootstrap Resampling","sampling mechanism","Resamples observed data and can supply paths to a Monte Carlo model while preserving selected empirical features.",{"name":1645,"fullName":1645,"category":1646,"summary":1647},"Model Risk","parent risk","Covers losses caused by flawed structure, inputs, data, assumptions, or inappropriate use of a model.","/learn/monte-carlo-simulation",{"title":607,"description":1618},{"loc":1648},"/learn-img/monte-carlo-simulation/og-1200x627.jpg","A field of possible paths fans out from one starting point beneath the words Monte Carlo Simulation, illustrating one model producing many conditional futures.",[1654,1656,1658,1660],{"title":1655,"url":1571},"Metropolis & Ulam (1949) · The Monte Carlo Method",{"title":1657,"url":1578},"NIST · New Tool to Account for Uncertainty",{"title":1659,"url":1585},"FINRA Rule 2214 · Investment Analysis Tools",{"title":1661,"url":1592},"CFP Board · Core Financial Planning Technologies Questionnaire","learn/monte-carlo-simulation",[1664,1665,1666,1667,1668],"uncertainty","probability","simulation","decision-making","model-risk","eZmrUkOCINLehZM0qGtD8Nzvnq5_mNHuNeh0hpQjEYw",{"id":1671,"title":1672,"body":1673,"cardImage":2029,"cardImageAlt":2030,"date":1112,"description":2031,"domain":1114,"domainKey":1115,"extension":577,"featured":578,"fullName":1854,"interaction":1677,"maturity":580,"mentalModel":2032,"meta":2033,"navigation":578,"neighbors":2034,"ogImage":610,"path":2063,"published":578,"robots":610,"seo":2064,"shortName":2065,"sitemap":2066,"socialImage":2067,"socialImageAlt":2068,"sources":2069,"stem":2082,"tags":2083,"translationKey":1677,"updated":1112,"__hash__":2086},"learnEn/learn/optimistic-concurrency.md","Optimistic Concurrency",{"type":9,"value":1674,"toc":2019},[1675,1678,1681,1684,1688,1695,1706,1713,1715,1718,1738,1775,1778,1789,1793,1800,1832,1839,1843,1915,1918,1924,1927,1931,1934,1951,1954,1958,1961,1964,1968,1994,1998,2015],[12,1676,1672],{"id":1677},"optimistic-concurrency",[16,1679,1680],{},"Optimistic Concurrency Control (OCC) solves a deceptively simple problem: two people can read the same record, make different changes, and accidentally erase each other's work.",[16,1682,1683],{},"Its defining move is not to lock the record while everyone thinks. It lets work proceed, then validates the writer's original assumption at the moment of commitment.",[36,1685,1687],{"id":1686},"the-failure-it-prevents-lost-update","The failure it prevents: lost update",[16,1689,1690,1691,1694],{},"Suppose Alice and Bob both read document ",[44,1692,1693],{},"#42"," at version 7.",[52,1696,1697,1700,1703],{},[55,1698,1699],{},"Alice changes the title and saves first. The database advances to version 8.",[55,1701,1702],{},"Bob is still editing the old version 7. He changes the owner field and submits the whole object.",[55,1704,1705],{},"Without concurrency control, Bob's stale object can silently restore the old title.",[16,1707,1708,1709,1712],{},"That is a ",[20,1710,1711],{},"lost update",". The dangerous part is not that two people read together. It is that Bob's write was accepted even though the premise behind it was stale.",[36,1714,1209],{"id":1208},[16,1716,1717],{},"OCC normally has three stages:",[468,1719,1720,1726,1732],{},[55,1721,1722,1725],{},[20,1723,1724],{},"Read"," the business data and a concurrency token such as a version number or Entity Tag (ETag).",[55,1727,1728,1731],{},[20,1729,1730],{},"Work"," locally without holding a long-lived exclusive lock.",[55,1733,1734,1737],{},[20,1735,1736],{},"Validate and write"," as one atomic operation. If the token still matches, commit and advance it. If not, report a conflict.",[109,1739,1743],{"className":1740,"code":1741,"language":1742,"meta":115,"style":115},"language-sql shiki shiki-themes dracula","UPDATE documents\nSET title = 'Q3 Growth Plan',\n    version = version + 1\nWHERE id = 42\n  AND version = 7;\n","sql",[44,1744,1745,1753,1758,1763,1769],{"__ignoreMap":115},[1746,1747,1750],"span",{"class":1748,"line":1749},"line",1,[1746,1751,1752],{},"UPDATE documents\n",[1746,1754,1755],{"class":1748,"line":546},[1746,1756,1757],{},"SET title = 'Q3 Growth Plan',\n",[1746,1759,1760],{"class":1748,"line":557},[1746,1761,1762],{},"    version = version + 1\n",[1746,1764,1766],{"class":1748,"line":1765},4,[1746,1767,1768],{},"WHERE id = 42\n",[1746,1770,1772],{"class":1748,"line":1771},5,[1746,1773,1774],{},"  AND version = 7;\n",[16,1776,1777],{},"One affected row means version 7 was still current. Zero affected rows means the record changed after it was read.",[16,1779,1780,1781,1784,1785,1788],{},"The comparison and write must be atomic. A separate ",[44,1782,1783],{},"SELECT"," followed later by an unconditional ",[44,1786,1787],{},"UPDATE"," leaves a Time of Check to Time of Use (TOCTOU) race between the two statements.",[36,1790,1792],{"id":1791},"the-same-idea-in-http","The same idea in HTTP",[16,1794,1795,1796,1799],{},"Hypertext Transfer Protocol (HTTP) exposes this pattern with Entity Tag (ETag) and ",[44,1797,1798],{},"If-Match",":",[109,1801,1805],{"className":1802,"code":1803,"language":1804,"meta":115,"style":115},"language-http shiki shiki-themes dracula","GET /documents/42\nETag: \"v7\"\n\nPUT /documents/42\nIf-Match: \"v7\"\n","http",[44,1806,1807,1812,1817,1822,1827],{"__ignoreMap":115},[1746,1808,1809],{"class":1748,"line":1749},[1746,1810,1811],{},"GET /documents/42\n",[1746,1813,1814],{"class":1748,"line":546},[1746,1815,1816],{},"ETag: \"v7\"\n",[1746,1818,1819],{"class":1748,"line":557},[1746,1820,1821],{"emptyLinePlaceholder":578},"\n",[1746,1823,1824],{"class":1748,"line":1765},[1746,1825,1826],{},"PUT /documents/42\n",[1746,1828,1829],{"class":1748,"line":1771},[1746,1830,1831],{},"If-Match: \"v7\"\n",[16,1833,1834,1835,1838],{},"If the resource is no longer version 7, the server can reject the write with ",[44,1836,1837],{},"412 Precondition Failed",". The condition is evaluated where the write happens, not guessed by the client from an earlier read.",[36,1840,1842],{"id":1841},"optimistic-versus-pessimistic","Optimistic versus pessimistic",[865,1844,1845,1858],{},[868,1846,1847],{},[871,1848,1849,1852,1855],{},[874,1850,1851],{},"Dimension",[874,1853,1854],{},"Optimistic Concurrency Control",[874,1856,1857],{},"Pessimistic Concurrency Control",[887,1859,1860,1871,1882,1893,1904],{},[871,1861,1862,1865,1868],{},[892,1863,1864],{},"Default assumption",[892,1866,1867],{},"Conflicts are uncommon",[892,1869,1870],{},"Conflicts are likely or very costly",[871,1872,1873,1876,1879],{},[892,1874,1875],{},"Control point",[892,1877,1878],{},"Validate at commit",[892,1880,1881],{},"Lock or queue before work",[871,1883,1884,1887,1890],{},[892,1885,1886],{},"No-conflict cost",[892,1888,1889],{},"Little waiting",[892,1891,1892],{},"Lock and waiting overhead remain",[871,1894,1895,1898,1901],{},[892,1896,1897],{},"Conflict cost",[892,1899,1900],{},"Retry, merge, or discard work",[892,1902,1903],{},"Usually wait rather than redo",[871,1905,1906,1909,1912],{},[892,1907,1908],{},"Common risks",[892,1910,1911],{},"Retry storms, livelock, poor conflict UX",[892,1913,1914],{},"Deadlocks, timeouts, lower throughput",[16,1916,1917],{},"A useful approximation is:",[109,1919,1922],{"className":1920,"code":1921,"language":114,"meta":115},[112],"optimistic cost ≈ validation + conflict probability × redo cost\npessimistic cost ≈ locking + waiting + deadlock/timeout handling\n",[44,1923,1921],{"__ignoreMap":115},[16,1925,1926],{},"Real systems often mix them: optimistic editing for ordinary records, short locks or queues for a few hot resources, and idempotency keys around external side effects.",[36,1928,1930],{"id":1929},"conflict-is-part-of-the-protocol","Conflict is part of the protocol",[16,1932,1933],{},"Detecting a conflict is only half the design. The product must decide what happens next:",[52,1935,1936,1939,1942,1945,1948],{},[55,1937,1938],{},"reject and ask the user to refresh;",[55,1940,1941],{},"re-read and retry a deterministic operation;",[55,1943,1944],{},"merge independent fields;",[55,1946,1947],{},"show a three-way merge;",[55,1949,1950],{},"serialize a hot resource through a queue or short transaction.",[16,1952,1953],{},"Automatic retry also needs idempotency, bounded retries, and backoff with jitter. Retrying an operation that sends money, email, or third-party requests can otherwise duplicate the side effect.",[36,1955,1957],{"id":1956},"where-it-fits","Where it fits",[16,1959,1960],{},"OCC is strongest when reads dominate writes, conflicts are rare, users may edit for a long time, and retry or merge is affordable.",[16,1962,1963],{},"It degrades when many requests fight over one hot record, conflicts invalidate expensive work, or a business invariant spans records that a single version token cannot protect.",[36,1965,1967],{"id":1966},"what-it-is-not","What it is not",[52,1969,1970,1976,1982,1988],{},[55,1971,1972,1975],{},[20,1973,1974],{},"Not Last Write Wins."," OCC makes stale writes visible instead of silently accepting the last arrival.",[55,1977,1978,1981],{},[20,1979,1980],{},"Not Multi-Version Concurrency Control (MVCC)."," MVCC mainly answers which version a reader sees; OCC answers whether a writer's premise is still current.",[55,1983,1984,1987],{},[20,1985,1986],{},"Not Compare-and-Swap (CAS)."," CAS is an atomic primitive that can implement the broader OCC strategy.",[55,1989,1990,1993],{},[20,1991,1992],{},"Not Optimistic User Interface."," Optimistic UI changes perceived latency; OCC protects concurrent correctness.",[36,1995,1997],{"id":1996},"five-things-to-keep","Five things to keep",[468,1999,2000,2003,2006,2009,2012],{},[55,2001,2002],{},"OCC means “do not block first; validate the premise at commit.”",[55,2004,2005],{},"The check and write must be atomic.",[55,2007,2008],{},"Version, ETag, and CAS are carriers or mechanisms, not the complete policy.",[55,2010,2011],{},"A conflict needs a designed exit: reject, retry, merge, or serialize.",[55,2013,2014],{},"Choose between waiting and rework based on contention and failure cost, not ideology.",[2016,2017,2018],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":115,"searchDepth":546,"depth":546,"links":2020},[2021,2022,2023,2024,2025,2026,2027,2028],{"id":1686,"depth":546,"text":1687},{"id":1208,"depth":546,"text":1209},{"id":1791,"depth":546,"text":1792},{"id":1841,"depth":546,"text":1842},{"id":1929,"depth":546,"text":1930},{"id":1956,"depth":546,"text":1957},{"id":1966,"depth":546,"text":1967},{"id":1996,"depth":546,"text":1997},"/learn-img/optimistic-concurrency/card-4x5.jpg","A tactile paper version-check machine routes the current document to commit and blocks a stale copy.","Work in parallel; reject stale writes before they overwrite newer changes.","Let people work in parallel; when someone commits, verify that the assumptions they started from are still true.",{},[2035,2039,2044,2049,2054,2058],{"name":2036,"fullName":1857,"category":2037,"summary":2038},"PCC","strategy","Acquire exclusive access before doing the critical work, trading retries for waiting and lock management.",{"name":2040,"fullName":2041,"category":2042,"summary":2043},"MVCC","Multi-Version Concurrency Control","storage model","Keep multiple versions so readers can see a consistent snapshot without blocking writers.",{"name":2045,"fullName":2046,"category":2047,"summary":2048},"CAS","Compare-and-Swap / Compare-and-Set","atomic primitive","Replace a value only when it still equals the expected value; a common building block for OCC.",{"name":2050,"fullName":2051,"category":2052,"summary":2053},"Isolation","Transaction Isolation","semantics","Defines what concurrent transactions may observe and which anomalies the database prevents.",{"name":636,"fullName":2055,"category":2056,"summary":2057},"Idempotent Operation","retry safety","Makes a repeated request produce the intended effect once, which is essential before automatic retries.",{"name":2059,"fullName":2060,"category":2061,"summary":2062},"OT / CRDT","Operational Transformation / Conflict-free Replicated Data Type","merge model","Preserves concurrent intent by transforming or converging operations instead of simply rejecting one writer.","/learn/optimistic-concurrency",{"title":1672,"description":2031},"OCC",{"loc":2063},"/learn-img/optimistic-concurrency/og-1200x627.jpg","Two parallel work paths meet at a validation gate; the current version commits while a stale version loops back to retry.",[2070,2073,2076,2079],{"title":2071,"url":2072},"RFC 9110 · HTTP Semantics: If-Match","https://www.rfc-editor.org/rfc/rfc9110.html#name-if-match",{"title":2074,"url":2075},"PostgreSQL · Concurrency Control","https://www.postgresql.org/docs/current/mvcc.html",{"title":2077,"url":2078},"Microsoft · Handling Concurrency Conflicts in EF Core","https://learn.microsoft.com/en-us/ef/core/saving/concurrency",{"title":2080,"url":2081},"AWS · Optimistic locking with version number","https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/BestPractices_OptimisticLocking.html","learn/optimistic-concurrency",[2084,2085,1159],"concurrency","databases","4GxvGyUtpCprTYwStp6hg4ItFm9EkttScq9GaY52j8M",{"id":2088,"title":2089,"body":2090,"cardImage":2486,"cardImageAlt":2487,"date":2488,"description":2489,"domain":2490,"domainKey":2491,"extension":577,"featured":1116,"fullName":2089,"interaction":2094,"maturity":580,"mentalModel":2396,"meta":2492,"navigation":578,"neighbors":2493,"ogImage":610,"path":2518,"published":578,"robots":610,"seo":2519,"shortName":2089,"sitemap":2520,"socialImage":610,"socialImageAlt":610,"sources":2521,"stem":2527,"tags":2528,"translationKey":2094,"updated":2488,"__hash__":2532},"learnEn/learn/progressive-disclosure.md","Progressive Disclosure",{"type":9,"value":2091,"toc":2473},[2092,2095,2098,2104,2107,2111,2114,2117,2120,2126,2130,2133,2139,2142,2145,2156,2159,2163,2166,2211,2214,2218,2221,2224,2235,2238,2241,2247,2251,2254,2261,2265,2282,2286,2306,2309,2344,2346,2388,2392,2412,2414,2434,2436],[12,2093,2089],{"id":2094},"progressive-disclosure",[16,2096,2097],{},"Feature-rich products tend to put every capability in front of everyone at once. Each setting may be reasonable, yet the collection makes the most common task harder to begin.",[16,2099,2100,2101],{},"Progressive Disclosure offers a different way to arrange complexity: ",[20,2102,2103],{},"show the smallest complete interface required for the current goal, then reveal secondary or advanced options as intent and context deepen.",[16,2105,2106],{},"It does not remove complexity. It decides when complexity earns its place.",[36,2108,2110],{"id":2109},"auto-and-pro-camera-modes","Auto and Pro camera modes",[16,2112,2113],{},"Most people who pick up a camera need to frame a scene and press the shutter. Auto mode handles exposure, focus, and white balance so the first photograph can happen immediately.",[16,2115,2116],{},"Someone who needs to control motion blur can reveal shutter speed. Someone who needs precise control can enter Pro mode and manage aperture, shutter speed, and sensitivity together.",[16,2118,2119],{},"The professional capability remains available. It simply does not charge every person for its complexity before the first photograph.",[16,2121,2122,2123],{},"But “this will permanently delete the photograph” must not be hidden in an advanced layer. ",[20,2124,2125],{},"Low frequency does not mean low importance; risk and consequence belong in the layering decision.",[36,2127,2129],{"id":2128},"the-first-layer-must-be-small-and-complete","The first layer must be small and complete",[16,2131,2132],{},"Suppose someone only wants to export a report. The first layer might contain:",[109,2134,2137],{"className":2135,"code":2136,"language":114,"meta":115},[112],"File name     quarterly-report\nFormat        PDF (Portable Document Format)\nSave to       Downloads\n              [ Advanced options ] [ Export ]\n",[44,2138,2136],{"__ignoreMap":115},[16,2140,2141],{},"The common task can be completed without opening anything, and the outcome is predictable. A second layer can expose page range, image quality, and metadata. A third can expose color profiles, font embedding, and compression algorithms.",[16,2143,2144],{},"The layers answer different questions:",[468,2146,2147,2150,2153],{},[55,2148,2149],{},"What am I trying to complete?",[55,2151,2152],{},"How should the result be adjusted?",[55,2154,2155],{},"How should the underlying implementation be controlled?",[16,2157,2158],{},"If the first layer is only a vague button while consequential defaults remain hidden, the interface is concealing decisions rather than managing complexity.",[36,2160,2162],{"id":2161},"how-to-choose-what-appears-first","How to choose what appears first",[16,2164,2165],{},"Do not begin by asking which controls can collapse. Evaluate every piece of information along four dimensions:",[865,2167,2168,2177],{},[868,2169,2170],{},[871,2171,2172,2174],{},[874,2173,1851],{},[874,2175,2176],{},"Question",[887,2178,2179,2187,2195,2203],{},[871,2180,2181,2184],{},[892,2182,2183],{},"Necessity",[892,2185,2186],{},"Can the current task succeed without it?",[871,2188,2189,2192],{},[892,2190,2191],{},"Frequency",[892,2193,2194],{},"How many people and task instances need it?",[871,2196,2197,2200],{},[892,2198,2199],{},"Risk",[892,2201,2202],{},"Could hiding it change cost, permission, safety, or an irreversible outcome?",[871,2204,2205,2208],{},[892,2206,2207],{},"Dependency",[892,2209,2210],{},"Does it matter only after another choice is made?",[16,2212,2213],{},"Frequent, necessary, or high-consequence information usually belongs in the first layer. Low-frequency, low-risk, conditional information is a better candidate for later disclosure.",[36,2215,2217],{"id":2216},"an-artificial-intelligence-ai-agent-example","An Artificial Intelligence (AI) agent example",[16,2219,2220],{},"AI agent configuration can quickly accumulate model, tool, context, budget, memory, runtime, and approval settings.",[16,2222,2223],{},"A useful starting arrangement might be:",[52,2225,2226,2229,2232],{},[55,2227,2228],{},"Layer one: goal, input, and expected output;",[55,2230,2231],{},"Layer two: audience, tone, length, and allowed sources;",[55,2233,2234],{},"Layer three: model, retry, budget, and tool configuration.",[16,2236,2237],{},"But tool permissions, external writes, cost ceilings, and destructive actions carry high consequences. Even if they are infrequent, they should be visible or explicitly confirmed before execution. “Advanced” is not permission to conceal risk.",[16,2239,2240],{},"The real layering model is therefore not merely novice versus expert:",[109,2242,2245],{"className":2243,"code":2244,"language":114,"meta":115},[112],"disclosure layer = task relevance × frequency × dependency × consequence\n",[44,2246,2244],{"__ignoreMap":115},[36,2248,2250],{"id":2249},"the-trigger-is-part-of-the-design","The trigger is part of the design",[16,2252,2253],{},"“Show formatting settings” creates a better expectation than an isolated plus sign or ellipsis. A disclosure trigger should sit near the content it controls and describe what will appear.",[16,2255,2256,2257,2260],{},"On the web, a Disclosure widget normally combines a button with the content it controls. The Web Accessibility Initiative – Accessible Rich Internet Applications (WAI-ARIA) Authoring Practices Guide recommends a real button, ",[44,2258,2259],{},"aria-expanded"," for state, Enter and Space support, and an experience that does not depend on hover.",[36,2262,2264],{"id":2263},"when-it-works-well","When it works well",[52,2266,2267,2270,2273,2276,2279],{},[55,2268,2269],{},"The product has many capabilities, but common tasks use a stable subset.",[55,2271,2272],{},"Options have natural dependencies, such as revealing compression level only after custom compression is selected.",[55,2274,2275],{},"New users need a quick start while experts still need complete control.",[55,2277,2278],{},"Space is limited in mobile screens, sidebars, and property panels.",[55,2280,2281],{},"Detail is valuable but not necessary for every person on every visit.",[36,2283,2285],{"id":2284},"when-it-degrades","When it degrades",[52,2287,2288,2291,2294,2297,2300,2303],{},[55,2289,2290],{},"People need to compare prices, permissions, or plans simultaneously.",[55,2292,2293],{},"Total cost, renewal, deletion consequences, or visibility are hidden.",[55,2295,2296],{},"Two lines of explanation are collapsed merely to make the page shorter.",[55,2298,2299],{},"Experts must reopen the same layer during every task.",[55,2301,2302],{},"Hidden content becomes difficult to scan, find, print, or understand as a whole.",[55,2304,2305],{},"The trigger is so vague that people never discover the capability.",[16,2307,2308],{},"Common failure shapes include:",[52,2310,2311,2320,2326,2332,2338],{},[55,2312,2313,2316,2317,107],{},[20,2314,2315],{},"Click tunnel:"," a common control lives under ",[44,2318,2319],{},"More → Advanced → Customize → Details",[55,2321,2322,2325],{},[20,2323,2324],{},"Mystery trigger:"," an icon gives no clue that it expands or what it contains.",[55,2327,2328,2331],{},[20,2329,2330],{},"Hidden risk:"," visual simplicity conceals cost, permission, or irreversible consequences.",[55,2333,2334,2337],{},[20,2335,2336],{},"State amnesia:"," the interface forgets an expert's expanded state or clears values on collapse.",[55,2339,2340,2343],{},[20,2341,2342],{},"Hidden dependency:"," a visible decision depends on an undisclosed default with no summary.",[36,2345,955],{"id":954},[52,2347,2348,2358,2364,2370,2376,2382],{},[55,2349,2350,2353,2354,2357],{},[20,2351,2352],{},"A Disclosure Widget is an implementation mechanism."," Buttons, triangles, ",[44,2355,2356],{},"details/summary",", and accordions show and hide; progressive disclosure is the strategy that decides what, when, and why.",[55,2359,2360,2363],{},[20,2361,2362],{},"Contextual Disclosure is a triggered variant."," Selecting “Schedule” reveals a date and time zone because they have become relevant.",[55,2365,2366,2369],{},[20,2367,2368],{},"Staged Disclosure is a flow variant."," It distributes content across a sequence or wizard and emphasizes task order.",[55,2371,2372,2375],{},[20,2373,2374],{},"Information Architecture is the structural foundation."," It handles classification, naming, and connection. A collapsing animation cannot repair a bad taxonomy.",[55,2377,2378,2381],{},[20,2379,2380],{},"Defaults are decision shortcuts."," They make the first layer immediately useful, but invisible defaults can also create surprises.",[55,2383,2384,2387],{},[20,2385,2386],{},"Feature Gating is an access policy."," It decides whether a capability can be used; progressive disclosure normally changes only when it is visible.",[36,2389,2391],{"id":2390},"remember-these-six-things","Remember these six things",[468,2393,2394,2397,2400,2403,2406,2409],{},[55,2395,2396],{},"Do not delete complexity; let users pay for it in installments as their intent deepens.",[55,2398,2399],{},"The first layer must be small but complete: the task works and the outcome is visible.",[55,2401,2402],{},"Layering considers necessity, frequency, dependency, and consequence together.",[55,2404,2405],{},"Low-frequency risks must not be hidden for visual simplicity.",[55,2407,2408],{},"A disclosure control is a mechanism; progressive disclosure is a strategy.",[55,2410,2411],{},"If people are always searching, reopening, or being surprised by hidden defaults, the layers are wrong.",[36,2413,488],{"id":487},[468,2415,2416,2419,2422,2425,2428,2431],{},[55,2417,2418],{},"Can someone complete and predict the common task without expanding anything?",[55,2420,2421],{},"Which low-frequency facts must remain visible because they affect cost, permission, or irreversibility?",[55,2423,2424],{},"Does the trigger explain what it will reveal?",[55,2426,2427],{},"Does each deeper layer add new decision value?",[55,2429,2430],{},"Can keyboard and assistive-technology users perceive and change the state?",[55,2432,2433],{},"Are experts repeatedly reopening the same layer?",[36,2435,512],{"id":511},[52,2437,2438,2445,2452,2459,2466],{},[55,2439,2440],{},[518,2441,2444],{"href":2442,"rel":2443},"https://developer.apple.com/design/human-interface-guidelines/disclosure-controls",[522],"Apple Human Interface Guidelines · Disclosure controls",[55,2446,2447],{},[518,2448,2451],{"href":2449,"rel":2450},"https://www.ibm.com/docs/en/technical-content?topic=practices-progressive-disclosure",[522],"IBM Documentation · Progressive Disclosure",[55,2453,2454],{},[518,2455,2458],{"href":2456,"rel":2457},"https://www.w3.org/WAI/ARIA/apg/patterns/disclosure/",[522],"W3C WAI-ARIA Authoring Practices Guide · Disclosure Pattern",[55,2460,2461],{},[518,2462,2465],{"href":2463,"rel":2464},"https://carbondesignsystem.com/components/accordion/usage/",[522],"Carbon Design System · Accordion usage",[55,2467,2468],{},[518,2469,2472],{"href":2470,"rel":2471},"https://doi.org/10.1177/001872088402600402",[522],"Carroll & Carrithers (1984) · Blocking learner error states in a training-wheels system",{"title":115,"searchDepth":546,"depth":546,"links":2474},[2475,2476,2477,2478,2479,2480,2481,2482,2483,2484,2485],{"id":2109,"depth":546,"text":2110},{"id":2128,"depth":546,"text":2129},{"id":2161,"depth":546,"text":2162},{"id":2216,"depth":546,"text":2217},{"id":2249,"depth":546,"text":2250},{"id":2263,"depth":546,"text":2264},{"id":2284,"depth":546,"text":2285},{"id":954,"depth":546,"text":955},{"id":2390,"depth":546,"text":2391},{"id":487,"depth":546,"text":488},{"id":511,"depth":546,"text":512},"/learn-img/progressive-disclosure/card-4x5.jpg","Three tactile paper interfaces labeled Essential, Context, and Expert sit in layered trays, illustrating options revealed as user intent deepens.","2026-07-17","Show the smallest complete interface for the current goal, then reveal complexity as intent and context deepen.","Interaction design","interaction-design",{},[2494,2498,2502,2506,2510,2514],{"name":2495,"fullName":2495,"category":2496,"summary":2497},"Disclosure Widget","implementation mechanism","Shows and hides content; progressive disclosure decides what should appear, when, and why.",{"name":2499,"fullName":2499,"category":2500,"summary":2501},"Contextual Disclosure","triggered variant","Reveals content in place when a choice or environmental state makes it relevant.",{"name":2503,"fullName":2503,"category":2504,"summary":2505},"Staged Disclosure","flow variant","Distributes information across sequential steps or pages, emphasizing order and transitions.",{"name":2507,"fullName":2507,"category":2508,"summary":2509},"Information Architecture","structural foundation","Classifies and connects information; disclosure decides which layer appears first in an interaction.",{"name":2511,"fullName":2511,"category":2512,"summary":2513},"Defaults","decision shortcut","Preselect common answers so the first layer works, though hidden defaults can also create surprises.",{"name":2515,"fullName":2515,"category":2516,"summary":2517},"Feature Gating","access policy","Decides whether someone may use a feature; disclosure usually changes only when it is visible.","/learn/progressive-disclosure",{"title":2089,"description":2489},{"loc":2518},[2522,2523,2524,2525,2526],{"title":2444,"url":2442},{"title":2451,"url":2449},{"title":2458,"url":2456},{"title":2465,"url":2463},{"title":2472,"url":2470},"learn/progressive-disclosure",[2490,2529,2530,2531],"Complexity","Information architecture","Discoverability","NQxjpbsDvoX9-E3vALpXqRFDd_HlTVxUyyI_2qBobEQ",{"id":2534,"title":2535,"body":2536,"cardImage":2774,"cardImageAlt":2775,"date":1112,"description":2776,"domain":2777,"domainKey":2778,"extension":577,"featured":1116,"fullName":2535,"interaction":2540,"maturity":580,"mentalModel":2779,"meta":2780,"navigation":578,"neighbors":2781,"ogImage":610,"path":2808,"published":578,"robots":610,"seo":2809,"shortName":2810,"sitemap":2811,"socialImage":610,"socialImageAlt":610,"sources":2812,"stem":2825,"tags":2826,"translationKey":2540,"updated":1112,"__hash__":2831},"learnEn/learn/single-source-of-truth.md","Single Source of Truth",{"type":9,"value":2537,"toc":2763},[2538,2541,2547,2550,2554,2557,2563,2570,2573,2587,2591,2594,2608,2611,2618,2622,2628,2631,2637,2644,2648,2651,2654,2660,2664,2667,2670,2674,2677,2697,2700,2702,2734,2738,2741,2744,2746],[12,2539,2535],{"id":2540},"single-source-of-truth",[16,2542,2543,2544],{},"A Single Source of Truth (SSOT) solves the question hidden inside every duplicated fact: ",[20,2545,2546],{},"when copies disagree, which one has the authority to decide what is true now?",[16,2548,2549],{},"Its answer is not “delete every copy.” Caches, search indexes, reports, replicas, translated packages, and deployed pages are all useful. The pattern gives one bounded fact one authoritative owner and makes every other representation a traceable derivative.",[36,2551,2553],{"id":2552},"the-failure-it-prevents-drift","The failure it prevents: drift",[16,2555,2556],{},"Imagine one article exists in four places:",[109,2558,2561],{"className":2559,"code":2560,"language":114,"meta":115},[112],"source.md       version 3\npublic package  version 3\nblog copy       version 4\nproduction      version 3 + a manual hotfix\n",[44,2562,2560],{"__ignoreMap":115},[16,2564,2565,2566,2569],{},"All four look plausible. A future sync might erase the best edit because nobody knows which direction updates should flow. This is ",[20,2567,2568],{},"drift",": representations that were meant to agree quietly diverge.",[16,2571,2572],{},"An SSOT establishes an authority contract:",[468,2574,2575,2578,2581,2584],{},[55,2576,2577],{},"Who may define this fact?",[55,2579,2580],{},"Which direction do updates flow?",[55,2582,2583],{},"How stale may a derived copy become?",[55,2585,2586],{},"How is it rebuilt or reconciled after divergence?",[36,2588,2590],{"id":2589},"one-fact-one-owner-not-one-database-for-everything","One fact, one owner — not one database for everything",[16,2592,2593],{},"Authority should be scoped to a fact or domain:",[52,2595,2596,2599,2602,2605],{},[55,2597,2598],{},"an order service owns the order lifecycle;",[55,2600,2601],{},"an identity system owns a legal customer name;",[55,2603,2604],{},"a source Markdown file owns an article's meaning;",[55,2606,2607],{},"a committed main revision owns the production release.",[16,2609,2610],{},"These facts do not need to live in one physical store. In fact, forcing unrelated domains into one giant database can blur ownership instead of clarifying it.",[16,2612,2613,2614,2617],{},"A useful test is: ",[20,2615,2616],{},"which system is allowed to originate a correction?"," Other systems may read, subscribe, cache, index, translate, or project the fact, but they do not silently become a second independent writer.",[36,2619,2621],{"id":2620},"a-practical-pipeline","A practical pipeline",[109,2623,2626],{"className":2624,"code":2625,"language":114,"meta":115},[112],"authoritative source ──► public package ──► site copy ──► deployment\n        write here           derived          derived        evidence\n",[44,2627,2625],{"__ignoreMap":115},[16,2629,2630],{},"A healthy derivative carries enough lineage to explain itself:",[109,2632,2635],{"className":2633,"code":2634,"language":114,"meta":115},[112],"derived_from   = source identifier\nsource_version = commit, offset, or version\ngenerated_at   = timestamp\nrefresh_policy = on commit / every five minutes / nightly\nrebuild_path   = deterministic command or procedure\n",[44,2636,2634],{"__ignoreMap":115},[16,2638,2639,2640,2643],{},"The safest default is one-way, repeatable generation. Circular synchronization — ",[44,2641,2642],{},"A ⇄ B ⇄ C ⇄ A"," — turns every participant into a potential authority and demands much harder conflict semantics.",[36,2645,2647],{"id":2646},"a-service-example","A service example",[16,2649,2650],{},"Suppose an Order Service owns order status. It publishes updates that feed a search index, an analytics table, and a recommendation system.",[16,2652,2653],{},"Those copies may be optimized for different queries and may be eventually consistent. A refund still goes through the Order Service because it owns the complete transaction history. A fast, nearby copy does not become authoritative merely because it is convenient.",[16,2655,2656,2657],{},"This is why an SSOT can coexist with replication and high read scale: ",[20,2658,2659],{},"physical multiplicity is allowed; ambiguous authority is not.",[36,2661,2663],{"id":2662},"authority-is-not-correctness","Authority is not correctness",[16,2665,2666],{},"The authoritative source can still contain a bug, a bad human entry, or an outdated rule. SSOT does not make its owner infallible. It makes correction directional: fix the owner, then regenerate or reconcile every derivative.",[16,2668,2669],{},"Without that direction, teams patch many copies independently and can never be sure the repair is complete.",[36,2671,2673],{"id":2672},"recovering-from-a-split-truth","Recovering from a split truth",[16,2675,2676],{},"When two copies have both received valid-looking edits:",[468,2678,2679,2682,2685,2688,2691,2694],{},[55,2680,2681],{},"Pause the writes or releases that would widen the split.",[55,2683,2684],{},"Name the exact fact in conflict.",[55,2686,2687],{},"Choose authority using ownership, completeness, timeline, and audit evidence.",[55,2689,2690],{},"Reconcile any valid downstream-only changes back into that source.",[55,2692,2693],{},"Regenerate all derivatives.",[55,2695,2696],{},"Add lineage, diff checks, write permissions, or a one-way publishing path.",[16,2698,2699],{},"The order matters: restore authority before restoring consistency. Synchronizing without first choosing a judge is just an arbitrary overwrite.",[36,2701,1967],{"id":1966},[52,2703,2704,2710,2716,2722,2728],{},[55,2705,2706,2709],{},[20,2707,2708],{},"Not one giant database."," SSOT is about bounded authority, not physical centralization.",[55,2711,2712,2715],{},[20,2713,2714],{},"Not a ban on copies."," Caches, replicas, materialized views, and reports are expected.",[55,2717,2718,2721],{},[20,2719,2720],{},"Not automatically correct."," It identifies where a correction belongs.",[55,2723,2724,2727],{},[20,2725,2726],{},"Not Event Sourcing."," An event log can implement an SSOT, but it is one implementation pattern.",[55,2729,2730,2733],{},[20,2731,2732],{},"Not Single Version of Truth."," SVOT emphasizes consumers agreeing on one definition or result; SSOT emphasizes where authority originates.",[36,2735,2737],{"id":2736},"where-it-becomes-difficult","Where it becomes difficult",[16,2739,2740],{},"The simple one-writer model strains under offline-first collaboration, active-active multi-region writes, network partitions, or facts that genuinely require multiple independent authors.",[16,2742,2743],{},"Those systems still need explicit authority and conflict semantics, but may distribute them through leaders, quorums, merge rules, or Conflict-free Replicated Data Types (CRDTs). “We have multiple writers” is not a reason to leave disagreement undefined.",[36,2745,1997],{"id":1996},[468,2747,2748,2751,2754,2757,2760],{},[55,2749,2750],{},"A fact may have many copies, but it needs one named authority.",[55,2752,2753],{},"Every derivative should expose its source, version, freshness, and rebuild path.",[55,2755,2756],{},"Prefer one-way, idempotent generation when the domain does not require multiple writers.",[55,2758,2759],{},"Correct the source, then regenerate downstream; editing a projection creates drift.",[55,2761,2762],{},"SSOT makes errors repairable and auditable, not impossible.",{"title":115,"searchDepth":546,"depth":546,"links":2764},[2765,2766,2767,2768,2769,2770,2771,2772,2773],{"id":2552,"depth":546,"text":2553},{"id":2589,"depth":546,"text":2590},{"id":2620,"depth":546,"text":2621},{"id":2646,"depth":546,"text":2647},{"id":2662,"depth":546,"text":2663},{"id":2672,"depth":546,"text":2673},{"id":1966,"depth":546,"text":1967},{"id":2736,"depth":546,"text":2737},{"id":1996,"depth":546,"text":1997},"/learn-img/single-source-of-truth/card-4x5.jpg","One paper master record on a dark pedestal branches into a dashboard, report, and cache, showing one authority feeding many derived views.","Give each fact one authoritative owner; treat every other copy as a traceable, rebuildable projection.","Information systems","information-systems","A fact may have many copies, but only one place is authorized to answer what it is now.",{},[2782,2786,2790,2794,2798,2803],{"name":2783,"fullName":2783,"category":2784,"summary":2785},"Canonical Source","authority mechanism","The concrete file, store, or log formally chosen to represent an authoritative fact.",{"name":2787,"fullName":2787,"category":2788,"summary":2789},"Data Lineage","provenance","Records where data came from, which transformations it passed through, and which source version produced it.",{"name":2791,"fullName":2791,"category":2792,"summary":2793},"Materialized View","derived projection","A stored, query-friendly representation that can lag and should be reproducible from its source.",{"name":2795,"fullName":2795,"category":2796,"summary":2797},"Event Sourcing","implementation pattern","Uses an ordered event log as the authoritative record and rebuilds current state by replaying it.",{"name":2799,"fullName":2800,"category":2801,"summary":2802},"CQRS","Command Query Responsibility Segregation","architecture pattern","Separates authoritative commands from read-optimized projections, introducing an explicit synchronization boundary.",{"name":2804,"fullName":2805,"category":2806,"summary":2807},"SVOT","Single Version of Truth","consumption agreement","Aligns consumers on one definition or result; related to, but different from, locating authority.","/learn/single-source-of-truth",{"title":2535,"description":2776},"SSOT",{"loc":2808},[2813,2816,2819,2822],{"title":2814,"url":2815},"Microsoft · Data considerations for microservices","https://learn.microsoft.com/en-us/azure/architecture/microservices/design/data-considerations",{"title":2817,"url":2818},"Microsoft · CQRS pattern","https://learn.microsoft.com/en-us/azure/architecture/patterns/cqrs",{"title":2820,"url":2821},"HashiCorp · Purpose of Terraform State","https://developer.hashicorp.com/terraform/language/state/purpose",{"title":2823,"url":2824},"Kubernetes · Declarative object configuration","https://kubernetes.io/docs/tasks/manage-kubernetes-objects/declarative-config/","learn/single-source-of-truth",[2827,2828,2829,2830],"authority","data-lineage","synchronization","knowledge-systems","S8mKTw8ht-7eqGWjtbKL44GC5KCHXO943zlxtu_PFVU",[2833,3377,3855,4329,4694,5128],{"id":2834,"title":2835,"body":2836,"cardImage":571,"cardImageAlt":3326,"date":573,"description":3327,"domain":3328,"domainKey":576,"extension":577,"featured":578,"fullName":3329,"interaction":14,"maturity":3330,"mentalModel":3331,"meta":3332,"navigation":578,"neighbors":3333,"ogImage":610,"path":3363,"published":578,"robots":610,"seo":3364,"shortName":613,"sitemap":3365,"socialImage":615,"socialImageAlt":3366,"sources":3367,"stem":3372,"tags":3373,"translationKey":14,"updated":573,"__hash__":3376},"learnZh/zh/learn/discounted-cash-flow.md","折现现金流估值",{"type":9,"value":2837,"toc":3302},[2838,2840,2846,2849,2854,2857,2861,2867,2870,2900,2916,2922,2931,2937,2940,2964,2967,2970,2973,2981,2984,2987,2990,2993,2998,3005,3011,3017,3023,3026,3029,3032,3037,3045,3054,3057,3063,3066,3071,3074,3077,3083,3102,3110,3115,3118,3122,3125,3128,3134,3137,3140,3143,3147,3150,3154,3157,3171,3174,3194,3197,3200,3204,3207,3211,3214,3218,3221,3225,3228,3232,3235,3238,3255,3258,3275,3278,3280],[12,2839,2835],{"id":2835},[16,2841,2842,2843],{},"DCF（Discounted Cash Flow，折现现金流估值）问的是一个简单但要求很高的问题：",[20,2844,2845],{},"未来可分配现金流，在考虑收到时间与承担风险所要求的回报后，今天值多少？",[16,2847,2848],{},"答案并不是隐藏在公式里的“正确价格”，而是一句条件句：",[27,2850,2851],{},[16,2852,2853],{},"如果这些经营、再投资、时间与风险假设成立，估计价值大约是这个数。",[16,2855,2856],{},"这是理解 DCF 的核心。表格可以计算得非常精确，但输入假设仍然可能高度不确定。",[36,2858,2860],{"id":2859},"一个生活例子买一台自动售货机","一个生活例子：买一台自动售货机",[16,2862,2863,2864,2866],{},"假设一台放在办公楼里的自动售货机正在出售，卖家开价 ",[44,2865,46],{},"。你不会只问它卖出了多少零食，而会问：扣除补货、电费、维修和场地费以后，它每年真正能留下多少现金？",[16,2868,2869],{},"先放入一组完全假设的数字：",[52,2871,2872,2878,2883,2889,2894],{},[55,2873,2874,2875,2877],{},"它目前每年净留下 ",[44,2876,60],{},"；",[55,2879,2880,2881,2877],{},"未来五年，这笔现金每年增长 ",[44,2882,67],{},[55,2884,2885,2886,2888],{},"因为要等待，而且机器可能故障、失去场地或销量不及预期，你要求 ",[44,2887,74],{}," 的年回报；",[55,2890,2891,2892,2877],{},"第五年以后，不再逐年猜测，只假设现金长期增长 ",[44,2893,81],{},[55,2895,2896,2897,2899],{},"机器还有 ",[44,2898,88],{}," 的贷款需要承担。",[16,2901,2902,2903,2905,2906,2909,2910,2905,2912,2915],{},"把前五年的现金逐年折回今天，合计约 ",[44,2904,95],{},"，这就是",[20,2907,2908],{},"显性期现值","。再把第五年以后的现金概括成终值并折回今天，约为 ",[44,2911,103],{},[20,2913,2914],{},"终值现值","。",[109,2917,2920],{"className":2918,"code":2919,"language":114,"meta":115},[112],"前五年现金的现值       ≈  $32,981\n第五年以后现金的现值   ≈  $73,421\n经营资产价值           ≈ $106,403\n减：剩余贷款           =   $5,000\n买方股权价值           ≈ $101,403\n",[44,2921,2919],{"__ignoreMap":115},[16,2923,2924,2925,2927,2928,2930],{},"在这些假设下，",[44,2926,123],{}," 是一句条件式答案，而不是机器的“正确价格”。如果卖家仍要 ",[44,2929,46],{},"，DCF 帮你追问的是：未来现金是否应该更高、风险是否应该更低，或是否还有别的理由足以解释差距？",[16,2932,2933,2934,2936],{},"这里的 ",[44,2935,74],{}," 是帮助理解折现率的生活类比。正式企业估值中的 WACC（Weighted Average Cost of Capital，加权平均资本成本）还需要结合债务与股权各自要求的回报，并不是凭感觉选择一个数字。",[36,2938,2939],{"id":2939},"先用人话记住四个词",[52,2941,2942,2948,2954,2959],{},[55,2943,2944,2947],{},[20,2945,2946],{},"FCFF（Free Cash Flow to the Firm，企业自由现金流）","：公司经营后，可供债权人与股东共同分配的现金。可以先把它理解成“这门生意真正能产生、还没有决定分给谁的现金”。",[55,2949,2950,2953],{},[20,2951,2952],{},"WACC（Weighted Average Cost of Capital，加权平均资本成本）","：债权人与股东合计要求的年回报率。在这个模型里，它就是把未来现金折回今天所用的折现率；WACC 越高，同一笔未来现金今天越不值钱。",[55,2955,2956,2958],{},[20,2957,2908],{},"：把未来 5 年或 10 年逐年写出的现金流，分别折回今天，再加总。这里的“显性”只表示这些年份是逐年预测的。",[55,2960,2961,2963],{},[20,2962,2914],{},"：模型不会逐年预测到永远，所以把显性期之后的所有现金先概括成预测期末的一笔“终值”，再把这笔终值折回今天。",[16,2965,2966],{},"两项现值相加，得到简化的 Enterprise Value（企业价值）；再扣除 Net Debt（净债务），得到简化的 Equity Value（股权价值）。",[36,2968,2969],{"id":2969},"先决定你在估谁的现金流",[16,2971,2972],{},"第一步不是挑增长率，而是确定资本请求权。",[52,2974,2975,2978],{},[55,2976,2977],{},"**FCFF（Free Cash Flow to the Firm，企业自由现金流）**属于债权人和股东等全部资本提供者。它通常使用 WACC（Weighted Average Cost of Capital，加权平均资本成本）折现，得到 Enterprise Value（企业价值）。",[55,2979,2980],{},"**FCFE（Free Cash Flow to Equity，股权自由现金流）**只属于普通股股东。它使用 Cost of Equity（股权资本成本）折现，直接得到 Equity Value（股权价值）。",[16,2982,2983],{},"现金流定义与折现率必须配对。把 FCFF 用股权资本成本折现，或把 FCFE 用 WACC 折现，会混淆谁收到现金、谁承担风险。",[16,2985,2986],{},"本页互动模型使用 FCFF、WACC 和一条简化的净债务桥梁。",[36,2988,2989],{"id":2989},"建立显性预测期",[16,2991,2992],{},"常见的 FCFF 桥梁以 EBIT（Earnings Before Interest and Taxes，息税前利润）为起点：",[109,2994,2996],{"className":2995,"code":206,"language":114,"meta":115},[112],[44,2997,206],{"__ignoreMap":115},[16,2999,3000,3001,3004],{},"这条桥梁暴露出乐观叙事常常隐藏的约束：",[20,3002,3003],{},"增长不是免费的。"," 更多收入可能先要求更多存货、应收账款、设备、研发、渠道或其他再投资，之后才可能变成可分配现金。",[16,3006,3007,3008,3010],{},"第 ",[44,3009,221],{}," 年现金流的现值是：",[109,3012,3015],{"className":3013,"code":3014,"language":114,"meta":115},[112],"FCFFₜ 的现值 = FCFFₜ / (1 + r)ᵗ\n",[44,3016,3014],{"__ignoreMap":115},[16,3018,3019,3020,3022],{},"折现率 ",[44,3021,234],{}," 必须与现金流使用相同的币种、通胀口径、时间尺度和资本请求权。",[36,3024,3025],{"id":3025},"处理预测期之后的现金流",[16,3027,3028],{},"企业不会因为模型只预测五年，就在第五年末消失。DCF 因此使用 Terminal Value（终值）概括显性预测期后的现金流。",[16,3030,3031],{},"常见的稳定增长公式是：",[109,3033,3035],{"className":3034,"code":249,"language":114,"meta":115},[112],[44,3036,249],{"__ignoreMap":115},[16,3038,3039,3040,3042,3043,2915],{},"其中 ",[44,3041,257],{}," 是稳定增长率，模型要求 ",[44,3044,261],{},[16,3046,3047,3048,3050,3051,3053],{},"当 ",[44,3049,257],{}," 接近 ",[44,3052,234],{}," 时，分母趋近于零，终值会爆炸。这不是发现了巨大的价值，而是长期假设已经失去经济约束的警报。",[16,3055,3056],{},"把终值折回今天，再与显性期现金流相加：",[109,3058,3061],{"className":3059,"code":3060,"language":114,"meta":115},[112],"Enterprise Value\n= Σ 显性期 FCFF 的现值\n+ 终值的现值\n",[44,3062,3060],{"__ignoreMap":115},[16,3064,3065],{},"简化的股权桥梁是：",[109,3067,3069],{"className":3068,"code":286,"language":114,"meta":115},[112],[44,3070,286],{"__ignoreMap":115},[16,3072,3073],{},"完整桥梁还可能加入非经营性现金和投资，并扣除其他非股权请求权。互动模型只使用净债务，让核心机制保持清晰。",[36,3075,3076],{"id":3076},"一个数字例子",[16,3078,3079,3080,3082],{},"假设一家虚构企业从 ",[44,3081,301],{}," 的 FCFF 开始：",[52,3084,3085,3088,3091,3094,3097],{},[55,3086,3087],{},"五年显性预测期；",[55,3089,3090],{},"FCFF 每年增长 7%；",[55,3092,3093],{},"WACC 为 9%；",[55,3095,3096],{},"稳定增长率为 3%；",[55,3098,3099,3100,2915],{},"净债务为 ",[44,3101,321],{},[16,3103,3104,3105,3107,3108,2915],{},"五年显性现金流的现值约为 ",[44,3106,328],{},"，终值折回今天约为 ",[44,3109,332],{},[109,3111,3113],{"className":3112,"code":336,"language":114,"meta":115},[112],[44,3114,336],{"__ignoreMap":115},[16,3116,3117],{},"最后一行通常最值得关注。77% 的终值占比并不自动说明模型错误，但它说明大部分答案都由远期假设控制。接下来更值得研究的是可持续增长、再投资、竞争优势与折现率，而不是多算一个小数位。",[36,3119,3121],{"id":3120},"dcf-真正有用的地方","DCF 真正有用的地方",[347,3123,3124],{"id":3124},"把故事变成因果链",[16,3126,3127],{},"“这是一家优秀企业”无法直接进入模型。DCF 迫使叙事落到可以观察和挑战的驱动因素：",[109,3129,3132],{"className":3130,"code":3131,"language":114,"meta":115},[112],"市场与竞争优势\n→ 收入增长与利润率\n→ 再投资\n→ 自由现金流\n→ 风险与要求回报\n→ 今天的价值\n",[44,3133,3131],{"__ignoreMap":115},[347,3135,3136],{"id":3136},"找到分歧的位置",[16,3138,3139],{},"两个人可能算出不同价值，但分歧通常集中在少数假设：增长能持续多久、稳定利润率是多少、增长需要多少再投资、风险是否被一致地反映。",[16,3141,3142],{},"DCF 把“我不同意这个价格”转化成“我不同意这个经营或资本假设”。",[347,3144,3146],{"id":3145},"比较决策而不是假装知道未来","比较决策，而不是假装知道未来",[16,3148,3149],{},"DCF 可以在统一框架下比较项目、收购、资本配置或经营情景。Sensitivity Analysis（敏感度分析）、Scenario Analysis（情景分析）、Stress Testing（压力测试）与 Monte Carlo Simulation（蒙特卡洛模拟）再负责挑战这个条件式答案。",[36,3151,3153],{"id":3152},"什么时候有效什么时候会退化","什么时候有效，什么时候会退化",[16,3155,3156],{},"DCF 通常更适合以下情况：",[52,3158,3159,3162,3165,3168],{},[55,3160,3161],{},"价值主要来自未来可分配现金流；",[55,3163,3164],{},"经营模式与再投资逻辑能够解释；",[55,3166,3167],{},"现金流与折现率能够一致配对；",[55,3169,3170],{},"目的是理解价值驱动因素，而不只是复刻一个市场倍数。",[16,3172,3173],{},"它在以下情况容易变得脆弱：",[52,3175,3176,3179,3182,3185,3188,3191],{},[55,3177,3178],{},"早期企业还没有可信的正常化现金流路径；",[55,3180,3181],{},"周期性企业正处于异常高点或低点；",[55,3183,3184],{},"债务更像经营原材料，例如许多金融机构；",[55,3186,3187],{},"价值主要来自延迟、扩张或放弃的选择权；",[55,3189,3190],{},"终值占比很高，但稳定状态经济性没有约束；",[55,3192,3193],{},"模型用精确感做装饰，却没有测试关键输入。",[16,3195,3196],{},"这些情况不一定完全禁止 DCF，但往往要求改变模型结构、现金流定义或不确定性处理。",[36,3198,3199],{"id":3199},"常见误区",[347,3201,3203],{"id":3202},"dcf-很主观所以没有用","“DCF 很主观，所以没有用”",[16,3205,3206],{},"判断不可避免，但判断不必隐藏。好的 DCF 会让假设可见、内部一致、可以证伪，也方便别人挑战。市场倍数同样包含假设，只是它们没有被明确写出。",[347,3208,3210],{"id":3209},"提高折现率一定更保守","“提高折现率一定更保守”",[16,3212,3213],{},"在其他条件不变时，提高折现率会降低现值。但如果风险、通胀、增长与现金流口径被不一致地调整，得到的不是保守，而是一个不匹配的模型。",[347,3215,3217],{"id":3216},"终值只是剩余项","“终值只是剩余项”",[16,3219,3220],{},"终值经常构成大部分估值，因此更需要经营约束：稳定增长需要多少再投资？资本回报会不会回落？增长率能否低于折现率，并与经济容量相容？",[347,3222,3224],{"id":3223},"精确计算等于准确估值","“精确计算等于准确估值”",[16,3226,3227],{},"算术可以完全正确，假设却可能错误。负责的输出是带有可见驱动因素的范围，而不是伪装成事实的小数。",[347,3229,3231],{"id":3230},"企业价值就是股权价值","“企业价值就是股权价值”",[16,3233,3234],{},"FCFF 用 WACC 折现通常得到企业价值。只有经过现金、债务与其他请求权的桥梁，才能得到股权价值。",[36,3236,3237],{"id":3237},"记住这五件事",[468,3239,3240,3243,3246,3249,3252],{},[55,3241,3242],{},"匹配请求权、现金流与折现率：FCFF ↔ WACC；FCFE ↔ 股权资本成本。",[55,3244,3245],{},"增长要先消耗再投资，之后才可能变成可分配现金。",[55,3247,3248],{},"终值往往是估值主体，而不是附录。",[55,3250,3251],{},"DCF 输出的是条件句，不是客观价格。",[55,3253,3254],{},"用敏感度、情景、压力测试和模拟挑战结果。",[36,3256,3257],{"id":3257},"自测",[468,3259,3260,3263,3266,3269,3272],{},[55,3261,3262],{},"为什么不能把 FCFF 用股权资本成本折现？",[55,3264,3265],{},"在其他条件不变时，WACC 上升为什么通常会让价值下降？",[55,3267,3268],{},"稳定增长率接近折现率时会发生什么？",[55,3270,3271],{},"收入上升而 FCFF 下降是否可能？哪些再投资会造成这种结果？",[55,3273,3274],{},"如果终值占企业价值的 85%，哪些假设最值得继续研究？",[16,3276,3277],{},"本页只提供通用、假设性的概念学习，不构成投资建议，也不估计任何真实证券或公司的价值。",[36,3279,512],{"id":511},[52,3281,3282,3287,3292,3297],{},[55,3283,3284],{},[518,3285,523],{"href":520,"rel":3286},[522],[55,3288,3289],{},[518,3290,530],{"href":528,"rel":3291},[522],[55,3293,3294],{},[518,3295,537],{"href":535,"rel":3296},[522],[55,3298,3299],{},[518,3300,544],{"href":542,"rel":3301},[522],{"title":115,"searchDepth":546,"depth":546,"links":3303},[3304,3305,3306,3307,3308,3309,3310,3315,3316,3323,3324,3325],{"id":2859,"depth":546,"text":2860},{"id":2939,"depth":546,"text":2939},{"id":2969,"depth":546,"text":2969},{"id":2989,"depth":546,"text":2989},{"id":3025,"depth":546,"text":3025},{"id":3076,"depth":546,"text":3076},{"id":3120,"depth":546,"text":3121,"children":3311},[3312,3313,3314],{"id":3124,"depth":557,"text":3124},{"id":3136,"depth":557,"text":3136},{"id":3145,"depth":557,"text":3146},{"id":3152,"depth":546,"text":3153},{"id":3199,"depth":546,"text":3199,"children":3317},[3318,3319,3320,3321,3322],{"id":3202,"depth":557,"text":3203},{"id":3209,"depth":557,"text":3210},{"id":3216,"depth":557,"text":3217},{"id":3223,"depth":557,"text":3224},{"id":3230,"depth":557,"text":3231},{"id":3237,"depth":546,"text":3237},{"id":3257,"depth":546,"text":3257},{"id":511,"depth":546,"text":512},"纯英文编辑风分享卡：标题为 Discounted Cash Flow，未来现金流柱经过时间与风险被翻译成今天的现值。","把未来现金流、时间与风险翻译成今天的条件式价值。","金融与估值","Discounted Cash Flow Valuation · 折现现金流估值","持续生长","DCF 是一台翻译器：未来现金流 + 时间 + 风险 → 今天的价值。",{},[3334,3339,3344,3348,3353,3358],{"name":3335,"fullName":3336,"category":3337,"summary":3338},"现值","Present Value · 现值","数学机制","把一笔未来金额换算成今天的单位；DCF 把这个机制应用于完整现金流序列。",{"name":3340,"fullName":3341,"category":3342,"summary":3343},"自由现金流","Free Cash Flow · 自由现金流","核心输入","把经营利润、税、再投资与营运资本连接到可供资本提供者分配的现金。",{"name":593,"fullName":3345,"category":3346,"summary":3347},"Weighted Average Cost of Capital · 加权平均资本成本","折现率输入","提供与企业自由现金流相匹配的综合要求回报。",{"name":3349,"fullName":3350,"category":3351,"summary":3352},"终值","Terminal Value · 终值","长期近似","把显性预测期后的全部现金流压缩成预测期末的一项价值。",{"name":3354,"fullName":3355,"category":3356,"summary":3357},"敏感度分析","Sensitivity Analysis · 敏感度分析","诊断方法","显示哪些假设最能推动条件式估值。",{"name":3359,"fullName":3360,"category":3361,"summary":3362},"蒙特卡洛模拟","Monte Carlo Simulation · 蒙特卡洛模拟","不确定性层","让 DCF 价值函数在许多内部一致的输入组合上运行，形成条件式分布。","/zh/learn/discounted-cash-flow",{"title":2835,"description":3327},{"loc":3363},"纯英文横版编辑图：未来现金流柱经过时间与风险折现，变成更小的现值方块，旁边是 Discounted Cash Flow 标题。",[3368,3369,3370,3371],{"title":619,"url":520},{"title":621,"url":528},{"title":623,"url":535},{"title":625,"url":542},"zh/learn/discounted-cash-flow",[3374,3335,3340,3375,3349],"估值","资本成本","irZ1UlFTZ9DTNLZV8lJWnQ_ABsfA8DjucwafG6YeELw",{"id":3378,"title":3379,"body":3380,"cardImage":1110,"cardImageAlt":3810,"date":1112,"description":3811,"domain":3812,"domainKey":1115,"extension":577,"featured":1116,"fullName":636,"interaction":641,"maturity":580,"mentalModel":3813,"meta":3814,"navigation":578,"neighbors":3815,"ogImage":610,"path":3840,"published":578,"robots":610,"seo":3841,"shortName":3379,"sitemap":3842,"socialImage":610,"socialImageAlt":610,"sources":3843,"stem":3848,"tags":3849,"translationKey":641,"updated":1112,"__hash__":3854},"learnZh/zh/learn/idempotency.md","幂等性",{"type":9,"value":3381,"toc":3789},[3382,3384,3390,3393,3399,3402,3408,3428,3431,3434,3437,3442,3449,3461,3464,3467,3470,3475,3478,3483,3486,3490,3493,3498,3501,3527,3530,3533,3538,3541,3544,3549,3552,3555,3558,3562,3565,3568,3574,3578,3581,3585,3588,3659,3662,3665,3703,3707,3726,3729,3746,3748,3765,3767],[12,3383,3379],{"id":3379},[16,3385,3386,3387,2915],{},"Idempotency（幂等性）解决的是分布式系统里最棘手的一类失败：不是明确成功或失败，而是 ",[20,3388,3389],{},"unknown outcome（结果未知）",[16,3391,3392],{},"客户端发起支付；服务端已经扣款，但响应在网络中消失。客户端只看到超时。如果放弃重试，本该完成的支付可能被误认为失败；如果直接重试，用户又可能被扣两次。",[16,3394,3395,3396],{},"幂等契约把恢复与重复分开：",[20,3397,3398],{},"请求可以再次尝试，但同一个业务意图不能再次产生业务效果。",[36,3400,3401],{"id":3401},"餐厅取餐号",[16,3403,3404,3405,3407],{},"想象你把编号 ",[44,3406,666],{}," 的点菜单递给厨房，却没有听见确认，于是又递了一次。",[52,3409,3410,3413,3419,3422],{},[55,3411,3412],{},"没有订单号，厨房可能做两顿饭。",[55,3414,3415,3416,3418],{},"有稳定订单号，厨房查到 ",[44,3417,666],{},"，只返回原订单状态。",[55,3420,3421],{},"真正的新订单必须使用新编号。",[55,3423,3424,3425,3427],{},"仍用 ",[44,3426,666],{}," 却换了菜品，厨房应该拒绝，而不是猜测。",[16,3429,3430],{},"取餐号只是身份。厨房仍然需要可靠账本，而且登记号码与接单之间不能有不安全的缝隙。",[36,3432,3433],{"id":3433},"数学定义与系统定义",[16,3435,3436],{},"数学里的幂等函数满足：",[109,3438,3440],{"className":3439,"code":701,"language":114,"meta":115},[112],[44,3441,701],{"__ignoreMap":115},[16,3443,3444,3445,3448],{},"软件系统更关心语义：同一请求执行多次，其 ",[20,3446,3447],{},"intended effect（预期效果）"," 与执行一次相同。它不要求响应字节完全相同，也不禁止额外的日志、指标和时间戳。",[16,3450,3451,3452,3454,3455,3457,3458,3460],{},"例如，第一次 ",[44,3453,716],{}," 返回 ",[44,3456,720],{},"，第二次返回 ",[44,3459,724],{},"。响应不同，但资源最终都处于“不存在”的状态。",[36,3462,3463],{"id":3463},"两种获得幂等性的方式",[347,3465,3466],{"id":3466},"让操作自然幂等",[16,3468,3469],{},"状态设定通常会收敛：",[109,3471,3473],{"className":3472,"code":740,"language":114,"meta":115},[112],[44,3474,740],{"__ignoreMap":115},[16,3476,3477],{},"相对变化通常不会：",[109,3479,3481],{"className":3480,"code":749,"language":114,"meta":115},[112],[44,3482,749],{"__ignoreMap":115},[16,3484,3485],{},"一个很实用的判断是：能否把“再变化一次”改写成“让它等于这个状态”？",[347,3487,3489],{"id":3488},"增加-idempotency-key幂等键","增加 Idempotency Key（幂等键）",[16,3491,3492],{},"创建支付、预约或云资源不能总被改写成简单赋值。这时客户端为一个业务意图生成稳定 key，并在每次重试中复用。",[109,3494,3496],{"className":3495,"code":765,"language":114,"meta":115},[112],[44,3497,765],{"__ignoreMap":115},[16,3499,3500],{},"完整协议通常要做到：",[468,3502,3503,3506,3509,3512,3515,3518,3521,3524],{},[55,3504,3505],{},"一个意图一个 key；新意图使用新 key；",[55,3507,3508],{},"按调用者、账户和操作限定 key 的作用域；",[55,3510,3511],{},"用唯一约束或事务原子占位；",[55,3513,3514],{},"绑定请求指纹，参数变化时拒绝；",[55,3516,3517],{},"记录处理中、完成或失败状态；",[55,3519,3520],{},"向已完成的重复请求重放原结果或语义等价结果；",[55,3522,3523],{},"定义并发重复请求看到什么；",[55,3525,3526],{},"声明 TTL（Time to Live，存活时间），说明 key 何时可能被当作新请求。",[36,3528,3529],{"id":3529},"原子缝隙才是真正危险的地方",[16,3531,3532],{},"下面的实现存在竞态：",[109,3534,3536],{"className":3535,"code":807,"language":114,"meta":115},[112],[44,3537,807],{"__ignoreMap":115},[16,3539,3540],{},"两个并发请求可能同时看到 key 不存在，于是都扣款；服务也可能在扣款后、保存记录前崩溃，让重试无法与新请求区分。",[16,3542,3543],{},"只要可能，key 占位、业务状态变化与结果记录就应该共享一个原子边界。如果效果跨过数据库、队列、邮件或第三方支付系统，每段边界都要有自己的幂等策略，通常需要状态机、Transactional Outbox（事务发件箱）或消费者 Inbox（收件箱）。",[16,3545,3546],{},[20,3547,3548],{},"只有一个 header，没有原子状态机，只是装饰，不是保证。",[36,3550,3551],{"id":3551},"契约必须说明的四种情况",[347,3553,3554],{"id":3554},"已完成的重复请求",[16,3556,3557],{},"返回第一次记录的结果，或语义等价的当前结果；不要再次执行业务动作。",[347,3559,3561],{"id":3560},"相同-key不同参数","相同 key，不同参数",[16,3563,3564],{},"必须拒绝，否则服务无法判断这是一次重试，还是一次错误的 key 复用。Stripe 与 Amazon Elastic Compute Cloud（Amazon EC2）都把参数不匹配视为错误。",[347,3566,3567],{"id":3567},"同时到达的重复请求",[16,3569,3570,3571,3573],{},"第二个请求不能也开始产生效果。它可以等待、收到 ",[44,3572,848],{},"，或收到冲突响应；API（Application Programming Interface，应用程序编程接口）契约必须做出选择。",[347,3575,3577],{"id":3576},"已过期的-key","已过期的 key",[16,3579,3580],{},"幂等记录通常不会永久保存。记录清理后，同一个 key 可能再次执行。服务端承诺的保证窗口必须覆盖客户端最长的重试周期。",[36,3582,3584],{"id":3583},"http安全不等于幂等","HTTP：安全不等于幂等",[16,3586,3587],{},"HTTP（Hypertext Transfer Protocol，超文本传输协议）把 safe method（安全方法）与 idempotent method（幂等方法）分开。",[865,3589,3590,3604],{},[868,3591,3592],{},[871,3593,3594,3596,3598,3601],{},[874,3595,876],{},[874,3597,879],{},[874,3599,3600],{},"语义上幂等？",[874,3602,3603],{},"含义",[887,3605,3606,3619,3632,3645],{},[871,3607,3608,3612,3614,3616],{},[892,3609,3610],{},[44,3611,896],{},[892,3613,899],{},[892,3615,899],{},[892,3617,3618],{},"请求读取，不应要求状态变化。",[871,3620,3621,3625,3627,3629],{},[892,3622,3623],{},[44,3624,911],{},[892,3626,914],{},[892,3628,899],{},[892,3630,3631],{},"用给定表示替换目标，重复提交仍然收敛。",[871,3633,3634,3638,3640,3642],{},[892,3635,3636],{},[44,3637,926],{},[892,3639,914],{},[892,3641,899],{},[892,3643,3644],{},"会改变一次状态，但重复删除的预期效果相同。",[871,3646,3647,3651,3653,3656],{},[892,3648,3649],{},[44,3650,940],{},[892,3652,914],{},[892,3654,3655],{},"默认 no",[892,3657,3658],{},"常表示“再创建一个”，需要业务层协议赋予幂等性。",[16,3660,3661],{},"所以，一个操作可以改变状态，同时仍然幂等。幂等不等于无害或只读。",[36,3663,3664],{"id":3664},"看清相邻概念",[52,3666,3667,3673,3679,3685,3691,3697],{},[55,3668,3669,3672],{},[20,3670,3671],{},"Retry（重试）是恢复策略。"," 它控制 timeout、尝试上限、exponential backoff（指数退避）与 jitter（抖动）；幂等性让这些尝试不会重复产生业务效果。",[55,3674,3675,3678],{},[20,3676,3677],{},"Deduplication（去重）是检测机制。"," 它可以帮助实现幂等性，但语义契约不只是丢弃重复。",[55,3680,3681,3684],{},[20,3682,3683],{},"At-least-once Delivery（至少一次交付）是交付保证。"," 它可能重复投递，所以消费者需要幂等处理。",[55,3686,3687,3690],{},[20,3688,3689],{},"Exactly-once（恰好一次）是更强、也常被误用的保证。"," 幂等性不阻止重复投递或执行，只让限定范围内的效果收敛得像发生一次。",[55,3692,3693,3696],{},[20,3694,3695],{},"Optimistic Concurrency Control（OCC，乐观并发控制）保护陈旧写入。"," OCC 区分互相竞争的不同意图；幂等性识别同一意图的再次送达。",[55,3698,3699,3702],{},[20,3700,3701],{},"Transactional Outbox（事务发件箱）关闭跨系统一致性缝隙。"," 它仍然允许重复发布，所以消费者仍需幂等。",[36,3704,3706],{"id":3705},"它不能解决什么","它不能解决什么？",[52,3708,3709,3712,3715,3718,3723],{},[55,3710,3711],{},"不能阻止重试风暴；仍需次数上限、backoff、jitter、限流与熔断。",[55,3713,3714],{},"不能自动跨越数据库、队列、邮件和第三方 API。",[55,3716,3717],{},"不能阻止两个不同 key 同时争抢同一份库存。",[55,3719,3720,3721,2915],{},"不能替 API 决定是否缓存并重放第一次 ",[44,3722,1014],{},[55,3724,3725],{},"不能创造全局 exactly-once processing（恰好一次处理）。",[36,3727,3728],{"id":3728},"最后记住五件事",[468,3730,3731,3734,3737,3740,3743],{},[55,3732,3733],{},"幂等性回应的是结果未知：可以重试这次尝试，不能重复这个意图的效果。",[55,3735,3736],{},"领域允许时，优先把动作改成自然幂等的状态设定。",[55,3738,3739],{},"一个意图一个 key；重试复用它；新意图换新 key。",[55,3741,3742],{},"相同 key + 不同参数必须拒绝，并明确并发与过期行为。",[55,3744,3745],{},"最危险的 bug 位于副作用与幂等记录之间的非原子缝隙。",[36,3747,3257],{"id":3257},[468,3749,3750,3753,3756,3759,3762],{},[55,3751,3752],{},"支付已经提交但响应消失时，什么证据能让重试安全？",[55,3754,3755],{},"你的 key 识别业务意图，还是只对 payload 做 hash？",[55,3757,3758],{},"相同 key 携带不同金额时会发生什么？",[55,3760,3761],{},"两个重复请求同时到达时，谁获得执行权？",[55,3763,3764],{},"key 的寿命是否覆盖客户端最长的重试周期？",[36,3766,512],{"id":511},[52,3768,3769,3774,3779,3784],{},[55,3770,3771],{},[518,3772,1067],{"href":1065,"rel":3773},[522],[55,3775,3776],{},[518,3777,1074],{"href":1072,"rel":3778},[522],[55,3780,3781],{},[518,3782,1081],{"href":1079,"rel":3783},[522],[55,3785,3786],{},[518,3787,1088],{"href":1086,"rel":3788},[522],{"title":115,"searchDepth":546,"depth":546,"links":3790},[3791,3792,3793,3797,3798,3804,3805,3806,3807,3808,3809],{"id":3401,"depth":546,"text":3401},{"id":3433,"depth":546,"text":3433},{"id":3463,"depth":546,"text":3463,"children":3794},[3795,3796],{"id":3466,"depth":557,"text":3466},{"id":3488,"depth":557,"text":3489},{"id":3529,"depth":546,"text":3529},{"id":3551,"depth":546,"text":3551,"children":3799},[3800,3801,3802,3803],{"id":3554,"depth":557,"text":3554},{"id":3560,"depth":557,"text":3561},{"id":3567,"depth":557,"text":3567},{"id":3576,"depth":557,"text":3577},{"id":3583,"depth":546,"text":3584},{"id":3664,"depth":546,"text":3664},{"id":3705,"depth":546,"text":3706},{"id":3728,"depth":546,"text":3728},{"id":3257,"depth":546,"text":3257},{"id":511,"depth":546,"text":512},"三张具有相同订单编号的纸质收据汇入一张完成收据，表示多次尝试只产生一次业务效果。","让结果未知的操作可以安全重试：同一个意图可以到达多次，但只产生一次业务效果。","软件系统","同一个意图可以被重复送达；系统只让它产生一次业务效果，后续重试复用第一次的结果。",{},[3816,3820,3824,3828,3832,3836],{"name":1121,"fullName":3817,"category":3818,"summary":3819},"Retry（重试）","恢复策略","决定何时、怎样再次尝试；幂等性决定再次尝试会不会重复产生业务效果。",{"name":1125,"fullName":3821,"category":3822,"summary":3823},"Idempotency Key（幂等键）","请求身份机制","为一个业务意图命名，让系统把每次重试识别为同一次操作。",{"name":1129,"fullName":3825,"category":3826,"summary":3827},"Deduplication（去重）","重复检测机制","检测或压制重复，是实现幂等行为的一种技术机制。",{"name":1133,"fullName":3829,"category":3830,"summary":3831},"At-least-once Delivery（至少一次交付）","交付保证","消息可能被重复投递，因此消费者需要用幂等处理安全吸收重复。",{"name":1137,"fullName":3833,"category":3834,"summary":3835},"Transactional Outbox（事务发件箱）","一致性模式","消除数据库变更与消息发布之间的不安全缝隙，同时仍要求消费者处理重复。",{"name":1141,"fullName":3837,"category":3838,"summary":3839},"Exactly-once Processing（恰好一次处理）","更强保证","常被过度宣称的端到端保证；幂等性通常只让效果收敛，并不阻止重复投递或执行。","/zh/learn/idempotency",{"title":3379,"description":3811},{"loc":3840},[3844,3845,3846,3847],{"title":1150,"url":1065},{"title":1152,"url":1072},{"title":1081,"url":1079},{"title":1088,"url":1086},"zh/learn/idempotency",[3850,3851,3852,3853],"可靠性","重试","分布式系统","API 设计","X_AZ1zHbj0kITA9Q_8EGOW_XgAgV2CEPpEhWU_q5TQM",{"id":3856,"title":3359,"body":3857,"cardImage":1615,"cardImageAlt":4283,"date":1617,"description":4284,"domain":4285,"domainKey":1620,"extension":577,"featured":578,"fullName":3360,"interaction":1168,"maturity":3330,"mentalModel":4286,"meta":4287,"navigation":578,"neighbors":4288,"ogImage":610,"path":4313,"published":578,"robots":610,"seo":4314,"shortName":606,"sitemap":4315,"socialImage":1651,"socialImageAlt":4316,"sources":4317,"stem":4322,"tags":4323,"translationKey":1168,"updated":1617,"__hash__":4328},"learnZh/zh/learn/monte-carlo-simulation.md",{"type":9,"value":3858,"toc":4263},[3859,3861,3864,3867,3874,3877,3880,3883,3894,3897,3900,3903,3908,3916,3960,3967,3970,3976,3981,4011,4014,4017,4022,4025,4028,4032,4035,4038,4041,4045,4048,4086,4089,4093,4096,4113,4116,4120,4124,4127,4130,4135,4138,4141,4144,4147,4150,4153,4156,4159,4162,4199,4202,4219,4221,4238,4241],[12,3860,3359],{"id":3359},[16,3862,3863],{},"一条预测线会把不确定性伪装成确定性。Monte Carlo Simulation（蒙特卡洛模拟）把它重新展开成一个分布。",[16,3865,3866],{},"方法很直接：反复抽取不确定输入，让每组输入通过同一个完整模型，再记录结果。一次运行代表一个内部一致的可能世界；数千次运行则揭示范围、中位数、尾部、阈值与失败路径。",[16,3868,3869,3870,3873],{},"最关键的词是",[20,3871,3872],{},"条件式","。结果只描述模型允许生成的世界，不代表模型发现了真实未来的客观概率。",[36,3875,3876],{"id":3876},"一场户外活动",[16,3878,3879],{},"假设你要举办户外活动。“平均气温 22°C”并不足以决定是否需要租帐篷。",[16,3881,3882],{},"更有用的做法，是根据合理的气温、降雨和风速，把当天重播数千次，同时保留它们之间的关系。有些版本晴朗温暖，有些又冷、又湿、又刮风。然后你可以问：",[52,3884,3885,3888,3891],{},[55,3886,3887],{},"有多少版本越过失败阈值？",[55,3889,3890],{},"下行尾部究竟有多糟？",[55,3892,3893],{},"哪一项准备最能减少脆弱结果？",[16,3895,3896],{},"蒙特卡洛模拟把同一逻辑应用到任何含不确定输入的模型。赌场只是名称来源；真正的核心是有纪律的抽样。",[36,3898,3899],{"id":3899},"工作机制",[16,3901,3902],{},"先把结果写成模型：",[109,3904,3906],{"className":3905,"code":1216,"language":114,"meta":115},[112],[44,3907,1216],{"__ignoreMap":115},[16,3909,3910,3912,3913,3915],{},[44,3911,1223],{}," 是关心的结果，",[44,3914,1227],{}," 是不确定输入。一套有用的模拟通常包含七步：",[468,3917,3918,3924,3930,3936,3942,3948,3954],{},[55,3919,3920,3923],{},[20,3921,3922],{},"明确决策与成功条件。"," “资产在 30 年内没有耗尽”可以检验；“方案看起来不错”不行。",[55,3925,3926,3929],{},[20,3927,3928],{},"表达输入不确定性。"," 为回报、需求、价格、增长、成本、通胀、工期或故障率定义范围或分布。",[55,3931,3932,3935],{},[20,3933,3934],{},"表达依赖关系。"," 相关性与因果约束让抽出的世界保持一致。每个输入单独合理，组合起来仍可能不可能。",[55,3937,3938,3941],{},[20,3939,3940],{},"联合抽样一次。"," 得到一个可能世界。",[55,3943,3944,3947],{},[20,3945,3946],{},"跑完整模型。"," 保留复利、时点、提款、再投资、排队等真正造成路径依赖的机制。",[55,3949,3950,3953],{},[20,3951,3952],{},"反复运行。"," 所有结果组成经验分布。",[55,3955,3956,3959],{},[20,3957,3958],{},"阅读并挑战分布。"," 报告范围、分位数、越线频率和失败路径，再改变假设并增加压力测试。",[16,3961,3962,3963,3966],{},"更多运行次数只会减少所选模型里的",[20,3964,3965],{},"抽样噪音","。它不会修复错误模型、遗漏风险、陈旧数据或不现实的分布。",[36,3968,3969],{"id":3969},"一个长期资金模型",[16,3971,3972,3973,3975],{},"设模型从资产 ",[44,3974,1289],{}," 开始，每年年初提款且提款随通胀增长，随后应用当年的净组合回报：",[109,3977,3979],{"className":3978,"code":1294,"language":114,"meta":115},[112],[44,3980,1294],{"__ignoreMap":115},[52,3982,3983,3991,3996,4001,4006],{},[55,3984,3985,3987,3988,3990],{},[44,3986,1303],{},"：第 ",[44,3989,221],{}," 年末资产。",[55,3992,3993,3995],{},[44,3994,1309],{},"：第一次提款。",[55,3997,3998,4000],{},[44,3999,1315],{},"：通胀率。",[55,4002,4003,4005],{},[44,4004,1321],{},"：抽样得到的组合回报。",[55,4007,4008,4010],{},[44,4009,1327],{},"：年度费用率。",[16,4012,4013],{},"每次运行都会抽取不同的股票与债券回报顺序，同时保留假设中的相互关系，然后走完整条路径。若资产不足以支付某次提款，这条路径就被标为耗尽。",[16,4015,4016],{},"假设 2,000 条路径中有 1,640 条撑完整个期间。准确的表达是：",[27,4018,4019],{},[16,4020,4021],{},"在这组回报、波动、相关性、通胀、费用、时点与提款规则之下，82% 的合成路径没有耗尽。",[16,4023,4024],{},"它不是“某个人客观上有 82% 的成功概率”。这个数字更适合在同一组假设下比较规则变化：降低支出、改变配置、降低成本、增加时间，或采用弹性提款策略。",[16,4026,4027],{},"本页只用于概念学习，不提供个性化投资建议。互动结果均为假设性结果，完全取决于页面上可见的模型假设。",[36,4029,4031],{"id":4030},"为什么顺序会改变结局","为什么顺序会改变结局？",[16,4033,4034],{},"如果没有存入或取出现金，同一组年度回报无论怎样换序，最终复利结果都相同，因为乘法不在乎顺序。",[16,4036,4037],{},"一旦存在提款，顺序就重要了。早期亏损发生时，现金仍持续流出，本金会更快缩小；后来的反弹只能作用在更少的资产上。因此，两条平均回报相同的路径可能走向完全不同的结局。",[16,4039,4040],{},"这也是“平均路径”经常误导的原因。它可能不是任何一条真实路径，会隐藏中途耗尽，还会抹掉真正造成失败的机制。",[36,4042,4044],{"id":4043},"应该读什么输出","应该读什么输出？",[16,4046,4047],{},"平均数通常不够。支持决策的读法一般包括：",[52,4049,4050,4056,4062,4068,4074,4080],{},[55,4051,4052,4055],{},[20,4053,4054],{},"中位数："," 模拟结果的中点，可以描述中心，但不是承诺。",[55,4057,4058,4061],{},[20,4059,4060],{},"分位数范围："," 例如第 10 至第 90 百分位区间。",[55,4063,4064,4067],{},[20,4065,4066],{},"越线频率："," 抽样世界中穿过指定失败线或目标线的比例。",[55,4069,4070,4073],{},[20,4071,4072],{},"失败时点："," 问题集中在早期、后期，还是某个特殊条件附近。",[55,4075,4076,4079],{},[20,4077,4078],{},"尾部严重度："," 越过阈值之后，结果还能坏到什么程度。",[55,4081,4082,4085],{},[20,4083,4084],{},"敏感度："," 哪些假设改变时，结果移动最大。",[16,4087,4088],{},"不说明条件的概率，会制造虚假精确。好的表达会把假设与输出放在一起。",[36,4090,4092],{"id":4091},"什么时候有用","什么时候有用？",[16,4094,4095],{},"蒙特卡洛模拟适合这些问题：",[52,4097,4098,4101,4104,4107,4110],{},[55,4099,4100],{},"多个不确定输入会联合影响结果；",[55,4102,4103],{},"事件顺序与时点重要；",[55,4105,4106],{},"决策关注范围、尾部或阈值，而不只是平均数；",[55,4108,4109],{},"需要在同一套假设下比较不同规则；",[55,4111,4112],{},"没有简洁解析解，或解析解会隐藏完整路径。",[16,4114,4115],{},"应用并不限于金融模型，也包括项目工期、库存、可靠性、排队、能源需求、保险损失与测量不确定性。",[36,4117,4119],{"id":4118},"失败长什么样","失败长什么样？",[347,4121,4123],{"id":4122},"垃圾输入分布输出","垃圾输入，分布输出",[16,4125,4126],{},"专业外观的直方图不会让缺乏依据的输入变可信。最难的工作通常是定义可信世界，而不是生成随机数。",[347,4128,4129],{"id":4129},"虚假精确",[16,4131,4132,4134],{},[44,4133,1453],{}," 可能只是把同一模型的答案算得更稳定。假设误差往往远大于蒙特卡洛抽样误差。",[347,4136,4137],{"id":4137},"尾部失明",[16,4139,4140],{},"如果薄尾分布从不生成流动性冻结、跳跃、制度切换或相关性飙升，模拟当然看不到这些风险。需要额外加入明确的压力测试。",[347,4142,4143],{"id":4143},"独立性幻想",[16,4145,4146],{},"把每个变量独立抽样会生成不可能的世界。增长、利润率、利率、违约与资产回报常常一起变化。",[347,4148,4149],{"id":4149},"策略遗漏",[16,4151,4152],{},"现实中的个人与组织会调整支出、价格、人员、融资、库存或项目范围。固定策略模型可能高估或低估韧性。",[347,4154,4155],{"id":4155},"目标错误",[16,4157,4158],{},"模型可能优化了错误的成功定义。期末余额刚好大于零，仍可能在途中违反流动性、服务、安全或质量约束。",[36,4160,4161],{"id":4161},"容易混淆的邻近方法",[52,4163,4164,4170,4176,4181,4187,4193],{},[55,4165,4166,4169],{},[20,4167,4168],{},"情景分析","讲述少量内部一致的未来，容易解释，但覆盖的世界更少。",[55,4171,4172,4175],{},[20,4173,4174],{},"压力测试","强迫模型进入指定极端环境，适合补足分布没有覆盖的尾部。",[55,4177,4178,4180],{},[20,4179,3354],{},"识别最值得研究或监控的假设，比单独一张分布图更直接地解释驱动因素。",[55,4182,4183,4186],{},[20,4184,4185],{},"历史模拟","保留真实历史组合，却无法展示样本中从未发生的环境。",[55,4188,4189,4192],{},[20,4190,4191],{},"自助抽样","从观测数据重复抽取；区块方法还能保留一部分时间结构。",[55,4194,4195,4198],{},[20,4196,4197],{},"预测","试图识别更可能发生的未来路径；蒙特卡洛通常更擅长条件式范围与稳健性，而不是指出哪条路径会成真。",[36,4200,4201],{"id":4201},"记住五件事",[468,4203,4204,4207,4210,4213,4216],{},[55,4205,4206],{},"蒙特卡洛生成许多条件式路径，不提供一条特权预测。",[55,4208,4209],{},"模型、输入分布、依赖关系与策略规则共同决定哪些世界可以存在。",[55,4211,4212],{},"阅读范围、尾部、越线频率与失败路径，不要只看平均数。",[55,4214,4215],{},"更多迭代减少的是抽样噪音，不是模型风险。",[55,4217,4218],{},"在一致假设下比较决策，并把模拟与敏感度分析、压力测试配合使用。",[36,4220,3257],{"id":3257},[468,4222,4223,4226,4229,4232,4235],{},[55,4224,4225],{},"为什么“每年固定 6%”与“平均回报 6% 的随机路径”可能产生不同结果？",[55,4227,4228],{},"报告“82%”时，必须同时说明哪些假设？",[55,4230,4231],{},"哪一种错误无法靠增加模拟次数修复？",[55,4233,4234],{},"即使模拟已经有第 5 百分位，什么情况仍应加入指定压力测试？",[55,4236,4237],{},"你的模型中，哪些输入不应该独立抽样？",[36,4239,4240],{"id":4240},"延伸阅读",[52,4242,4243,4248,4253,4258],{},[55,4244,4245],{},[518,4246,1573],{"href":1571,"rel":4247},[522],[55,4249,4250],{},[518,4251,1580],{"href":1578,"rel":4252},[522],[55,4254,4255],{},[518,4256,1587],{"href":1585,"rel":4257},[522],[55,4259,4260],{},[518,4261,1594],{"href":1592,"rel":4262},[522],{"title":115,"searchDepth":546,"depth":546,"links":4264},[4265,4266,4267,4268,4269,4270,4271,4279,4280,4281,4282],{"id":3876,"depth":546,"text":3876},{"id":3899,"depth":546,"text":3899},{"id":3969,"depth":546,"text":3969},{"id":4030,"depth":546,"text":4031},{"id":4043,"depth":546,"text":4044},{"id":4091,"depth":546,"text":4092},{"id":4118,"depth":546,"text":4119,"children":4272},[4273,4274,4275,4276,4277,4278],{"id":4122,"depth":557,"text":4123},{"id":4129,"depth":557,"text":4129},{"id":4137,"depth":557,"text":4137},{"id":4143,"depth":557,"text":4143},{"id":4149,"depth":557,"text":4149},{"id":4155,"depth":557,"text":4155},{"id":4161,"depth":546,"text":4161},{"id":4201,"depth":546,"text":4201},{"id":3257,"depth":546,"text":3257},{"id":4240,"depth":546,"text":4240},"纯英文分享卡：一条橙色预测线展开成许多可能路径，标题为 Monte Carlo Simulation，并配有 one forecast to many conditional futures。","生成许多条件式未来，看见范围、尾部与失败路径，而不是把模型误当成预测。","金融与决策科学","不要押注一个未来。抽取许多内部一致的未来，让完整模型逐一运行，再阅读结果分布。",{},[4289,4293,4297,4299,4304,4308],{"name":4168,"fullName":4290,"category":4291,"summary":4292},"Scenario Analysis · 情景分析","叙事方法","比较少量内部一致、容易解释的未来，而不是系统抽取一个大分布。",{"name":4174,"fullName":4294,"category":4295,"summary":4296},"Stress Testing · 压力测试","补充证据","强迫模型进入分布可能极少或从不生成的指定极端环境。",{"name":3354,"fullName":3355,"category":3356,"summary":4298},"识别哪些假设最能推动答案；蒙特卡洛负责传播它们的联合不确定性。",{"name":4300,"fullName":4301,"category":4302,"summary":4303},"收益顺序风险","Sequence-of-Returns Risk · 收益顺序风险","路径依赖风险","解释当提款或其他路径依赖现金流存在时，结果顺序为何会改变结局。",{"name":4191,"fullName":4305,"category":4306,"summary":4307},"Bootstrap Resampling · 自助抽样","抽样机制","对观测数据重复抽样，可为蒙特卡洛模型提供路径并保留选定的经验特征。",{"name":4309,"fullName":4310,"category":4311,"summary":4312},"模型风险","Model Risk · 模型风险","上位风险","涵盖模型结构、输入、数据、假设或使用方式不当造成的损失。","/zh/learn/monte-carlo-simulation",{"title":3359,"description":4284},{"loc":4313},"纯英文横版图：许多可能路径从一个起点向外展开，位于 Monte Carlo Simulation 标题旁，表示一个模型产生许多条件式未来。",[4318,4319,4320,4321],{"title":1655,"url":1571},{"title":1657,"url":1578},{"title":1659,"url":1585},{"title":1661,"url":1592},"zh/learn/monte-carlo-simulation",[4324,4325,4326,4327,4309],"不确定性","概率","模拟","决策","7zTae48k8x0GFFmU6X8WWbjX445Ut22dhMo_989rh-o",{"id":4330,"title":4331,"body":4332,"cardImage":2029,"cardImageAlt":4649,"date":1112,"description":4650,"domain":3812,"domainKey":1115,"extension":577,"featured":578,"fullName":4651,"interaction":1677,"maturity":3330,"mentalModel":4652,"meta":4653,"navigation":578,"neighbors":4654,"ogImage":610,"path":4679,"published":578,"robots":610,"seo":4680,"shortName":2065,"sitemap":4681,"socialImage":2067,"socialImageAlt":4682,"sources":4683,"stem":4689,"tags":4690,"translationKey":1677,"updated":1112,"__hash__":4693},"learnZh/zh/learn/optimistic-concurrency.md","乐观并发控制",{"type":9,"value":4333,"toc":4639},[4334,4336,4339,4342,4346,4352,4363,4370,4373,4376,4393,4417,4420,4429,4433,4439,4463,4469,4472,4542,4545,4551,4554,4557,4560,4577,4580,4583,4586,4589,4592,4618,4620,4637],[12,4335,4331],{"id":4331},[16,4337,4338],{},"Optimistic Concurrency Control（OCC，乐观并发控制）解决的是一个很容易被低估的问题：两个人读到了同一份记录、分别做了修改，然后在不知情的情况下抹掉了对方的工作。",[16,4340,4341],{},"它最关键的动作不是在大家思考和编辑时锁住记录，而是在真正提交的那一刻验证：写入者开始工作时所依赖的前提，现在是否仍然成立？",[36,4343,4345],{"id":4344},"它要阻止的失败lost-update","它要阻止的失败：Lost Update",[16,4347,4348,4349,4351],{},"假设 Alice 和 Bob 都读取了文档 ",[44,4350,1693],{}," 的 version 7：",[52,4353,4354,4357,4360],{},[55,4355,4356],{},"Alice 修改标题并率先保存，数据库前进到 version 8。",[55,4358,4359],{},"Bob 仍在编辑旧的 version 7。他修改 owner，然后把整个旧对象提交回来。",[55,4361,4362],{},"如果系统直接接受 Bob 的写入，Alice 的新标题就可能悄悄消失。",[16,4364,4365,4366,4369],{},"这叫 ",[20,4367,4368],{},"Lost Update（丢失更新）","。危险的不是两个人同时读取，而是 Bob 的写入所依赖的前提已经过期，系统却仍然允许它成功。",[36,4371,4372],{"id":4372},"它怎样工作",[16,4374,4375],{},"OCC 通常分成三个阶段：",[468,4377,4378,4383,4388],{},[55,4379,4380,4382],{},[20,4381,1724],{},"：读取业务数据，同时带走 version、Entity Tag（ETag，实体标签）等并发 token。",[55,4384,4385,4387],{},[20,4386,1730],{},"：在本地编辑或计算，不长期持有排他锁。",[55,4389,4390,4392],{},[20,4391,1736],{},"：把验证与写入做成一次原子操作。token 仍一致就提交并递增；不一致就报告冲突。",[109,4394,4395],{"className":1740,"code":1741,"language":1742,"meta":115,"style":115},[44,4396,4397,4401,4405,4409,4413],{"__ignoreMap":115},[1746,4398,4399],{"class":1748,"line":1749},[1746,4400,1752],{},[1746,4402,4403],{"class":1748,"line":546},[1746,4404,1757],{},[1746,4406,4407],{"class":1748,"line":557},[1746,4408,1762],{},[1746,4410,4411],{"class":1748,"line":1765},[1746,4412,1768],{},[1746,4414,4415],{"class":1748,"line":1771},[1746,4416,1774],{},[16,4418,4419],{},"影响 1 行代表 version 7 仍然有效；影响 0 行代表这份记录在读取之后已经被别人修改。",[16,4421,4422,4423,4425,4426,4428],{},"比较与写入必须是原子的。如果先单独 ",[44,4424,1783],{},"，过一会儿再无条件 ",[44,4427,1787],{},"，两步之间仍然存在 Time of Check to Time of Use（TOCTOU，检查时刻到使用时刻）race。",[36,4430,4432],{"id":4431},"http-里的同一个思想","HTTP 里的同一个思想",[16,4434,4435,4436,4438],{},"Hypertext Transfer Protocol（HTTP，超文本传输协议）通过 Entity Tag（ETag，实体标签）和 ",[44,4437,1798],{}," 表达同样的协议：",[109,4440,4441],{"className":1802,"code":1803,"language":1804,"meta":115,"style":115},[44,4442,4443,4447,4451,4455,4459],{"__ignoreMap":115},[1746,4444,4445],{"class":1748,"line":1749},[1746,4446,1811],{},[1746,4448,4449],{"class":1748,"line":546},[1746,4450,1816],{},[1746,4452,4453],{"class":1748,"line":557},[1746,4454,1821],{"emptyLinePlaceholder":578},[1746,4456,4457],{"class":1748,"line":1765},[1746,4458,1826],{},[1746,4460,4461],{"class":1748,"line":1771},[1746,4462,1831],{},[16,4464,4465,4466,4468],{},"如果资源已经不是 version 7，服务端可以返回 ",[44,4467,1837],{},"。最终条件由真正执行写入的服务端验证，而不是让客户端根据更早的一次读取自行猜测。",[36,4470,4471],{"id":4471},"乐观与悲观",[865,4473,4474,4485],{},[868,4475,4476],{},[871,4477,4478,4481,4483],{},[874,4479,4480],{},"维度",[874,4482,1854],{},[874,4484,1857],{},[887,4486,4487,4498,4509,4520,4531],{},[871,4488,4489,4492,4495],{},[892,4490,4491],{},"默认判断",[892,4493,4494],{},"冲突不常发生",[892,4496,4497],{},"冲突很可能发生，或代价极高",[871,4499,4500,4503,4506],{},[892,4501,4502],{},"控制时机",[892,4504,4505],{},"提交时验证",[892,4507,4508],{},"开始工作前加锁或排队",[871,4510,4511,4514,4517],{},[892,4512,4513],{},"无冲突成本",[892,4515,4516],{},"等待很少",[892,4518,4519],{},"仍然承担锁与等待",[871,4521,4522,4525,4528],{},[892,4523,4524],{},"冲突成本",[892,4526,4527],{},"重试、合并或丢弃工作",[892,4529,4530],{},"通常等待，而不是返工",[871,4532,4533,4536,4539],{},[892,4534,4535],{},"常见风险",[892,4537,4538],{},"Retry storm、livelock、糟糕的冲突体验",[892,4540,4541],{},"Deadlock、timeout、吞吐下降",[16,4543,4544],{},"可以用一个粗略模型理解：",[109,4546,4549],{"className":4547,"code":4548,"language":114,"meta":115},[112],"乐观成本 ≈ 验证成本 + 冲突概率 × 重做成本\n悲观成本 ≈ 加锁成本 + 等待成本 + 死锁 / 超时处理成本\n",[44,4550,4548],{"__ignoreMap":115},[16,4552,4553],{},"真实系统经常混合使用：普通记录用乐观编辑；少数热点资源使用短锁或队列；外部副作用再配合 idempotency key（幂等键）。",[36,4555,4556],{"id":4556},"冲突本身就是协议的一部分",[16,4558,4559],{},"发现冲突只完成了一半。产品还必须决定接下来怎样退出：",[52,4561,4562,4565,4568,4571,4574],{},[55,4563,4564],{},"拒绝并要求用户刷新；",[55,4566,4567],{},"重新读取后重试一个确定性操作；",[55,4569,4570],{},"合并互不冲突的字段；",[55,4572,4573],{},"展示三方合并；",[55,4575,4576],{},"通过队列或短事务把热点资源串行化。",[16,4578,4579],{},"自动重试还需要 Idempotency（幂等性）、有限重试次数，以及带 jitter（抖动）的 backoff（退避）。如果一次操作涉及转账、发邮件或第三方请求，盲目重试可能重复执行副作用。",[36,4581,4582],{"id":4582},"它适合在哪里",[16,4584,4585],{},"OCC 最适合读多写少、冲突罕见、用户编辑时间长，而且重试或合并成本可控的场景。",[16,4587,4588],{},"当大量请求争抢同一个热点记录、冲突会让昂贵工作全部作废，或者业务 invariant（不变量）跨越了单个 version token 无法保护的多条记录时，它会明显退化。",[36,4590,4591],{"id":4591},"它不是什么",[52,4593,4594,4600,4606,4612],{},[55,4595,4596,4599],{},[20,4597,4598],{},"不是 Last Write Wins。"," OCC 会让过期写入显性失败，而不是静默接受最后到达的人。",[55,4601,4602,4605],{},[20,4603,4604],{},"不是 Multi-Version Concurrency Control（MVCC，多版本并发控制）。"," MVCC 主要回答读者应该看见哪个版本；OCC 回答写者的前提是否仍然有效。",[55,4607,4608,4611],{},[20,4609,4610],{},"不是 Compare-and-Swap（CAS，比较并交换）。"," CAS 是可以实现 OCC 策略的一种原子原语。",[55,4613,4614,4617],{},[20,4615,4616],{},"不是 Optimistic User Interface（乐观式界面）。"," Optimistic UI 优化感知速度；OCC 保护并发正确性。",[36,4619,3728],{"id":3728},[468,4621,4622,4625,4628,4631,4634],{},[55,4623,4624],{},"OCC 的核心是“不预先阻塞，在提交时验证前提”。",[55,4626,4627],{},"检查与写入必须原子化。",[55,4629,4630],{},"version、ETag、CAS 是载体或机制，不是完整策略。",[55,4632,4633],{},"冲突必须有被设计过的出口：拒绝、重试、合并或串行化。",[55,4635,4636],{},"应该根据争用程度与失败成本，在“等待”和“返工”之间做选择，而不是把某一种方案当成信仰。",[2016,4638,2018],{},{"title":115,"searchDepth":546,"depth":546,"links":4640},[4641,4642,4643,4644,4645,4646,4647,4648],{"id":4344,"depth":546,"text":4345},{"id":4372,"depth":546,"text":4372},{"id":4431,"depth":546,"text":4432},{"id":4471,"depth":546,"text":4471},{"id":4556,"depth":546,"text":4556},{"id":4582,"depth":546,"text":4582},{"id":4591,"depth":546,"text":4591},{"id":3728,"depth":546,"text":3728},"一台纸艺版本检查装置把当前文档送往提交通道，并拦下过期副本。","允许并行工作，在提交时拒绝会覆盖新修改的旧版本。","Optimistic Concurrency Control · 乐观并发控制","先让大家并行工作；有人提交时，再验证他开始工作时所依赖的前提是否仍然成立。",{},[4655,4659,4663,4667,4671,4675],{"name":2036,"fullName":4656,"category":4657,"summary":4658},"Pessimistic Concurrency Control · 悲观并发控制","策略","在关键工作开始前先取得排他访问权，用等待和锁管理换取更少的返工。",{"name":2040,"fullName":4660,"category":4661,"summary":4662},"Multi-Version Concurrency Control · 多版本并发控制","存储模型","保留多个数据版本，让读者看到一致快照，并减少读取者与写入者互相阻塞。",{"name":2045,"fullName":4664,"category":4665,"summary":4666},"Compare-and-Swap / Compare-and-Set · 比较并交换","原子原语","只有当前值仍等于 expected 时才替换，是实现 OCC 的常见底层积木。",{"name":2050,"fullName":4668,"category":4669,"summary":4670},"Transaction Isolation · 事务隔离","事务语义","决定并发事务能够观察什么，以及数据库会阻止哪些并发异常。",{"name":636,"fullName":4672,"category":4673,"summary":4674},"Idempotent Operation · 幂等操作","重试安全","让重复请求仍只产生预期的一次效果，是自动重试之前必须解决的问题。",{"name":2059,"fullName":4676,"category":4677,"summary":4678},"Operational Transformation / Conflict-free Replicated Data Type · 操作转换 / 无冲突复制数据类型","合并模型","通过转换或收敛并发操作来保留多方意图，而不是简单拒绝其中一个写入者。","/zh/learn/optimistic-concurrency",{"title":4331,"description":4650},{"loc":4679},"两条并行工作路径在验证门汇合：当前版本成功提交，过期版本返回重试。",[4684,4686,4687,4688],{"title":4685,"url":2072},"RFC 9110 · HTTP Semantics：If-Match",{"title":2074,"url":2075},{"title":2077,"url":2078},{"title":2080,"url":2081},"zh/learn/optimistic-concurrency",[4691,4692,3852],"并发控制","数据库","ylbVAlkTgpnLt4H7N1WJPE1lZsdeMwq6McWsfJf2RIA",{"id":4695,"title":4696,"body":4697,"cardImage":2486,"cardImageAlt":5083,"date":2488,"description":5084,"domain":5085,"domainKey":2491,"extension":577,"featured":1116,"fullName":5086,"interaction":2094,"maturity":580,"mentalModel":5003,"meta":5087,"navigation":578,"neighbors":5088,"ogImage":610,"path":5113,"published":578,"robots":610,"seo":5114,"shortName":4696,"sitemap":5115,"socialImage":610,"socialImageAlt":610,"sources":5116,"stem":5122,"tags":5123,"translationKey":2094,"updated":2488,"__hash__":5127},"learnZh/zh/learn/progressive-disclosure.md","渐进披露",{"type":9,"value":4698,"toc":5070},[4699,4701,4704,4710,4713,4717,4720,4723,4726,4732,4736,4739,4745,4748,4751,4762,4765,4769,4772,4817,4820,4824,4827,4830,4841,4844,4847,4853,4856,4863,4869,4873,4890,4894,4914,4917,4952,4955,4996,4999,5019,5021,5041,5043],[12,4700,4696],{"id":4696},[16,4702,4703],{},"一个功能丰富的产品很容易把所有能力同时倒在用户面前。每一项设置都可能合理，但它们一起出现时，最常见的任务反而更难开始。",[16,4705,4706,4707],{},"Progressive Disclosure（渐进披露）提供了另一种安排复杂度的方法：",[20,4708,4709],{},"先给用户完成当前目标所需的最小完整界面，再随着意图和上下文逐层显露次要或高级选项。",[16,4711,4712],{},"它不是删除复杂度，而是决定复杂度什么时候出现。",[36,4714,4716],{"id":4715},"相机的-auto-与-pro","相机的 Auto 与 Pro",[16,4718,4719],{},"拿起相机时，大多数人只需要构图和按快门。Auto 模式先替用户处理曝光、对焦和白平衡，因此第一秒就能完成拍照。",[16,4721,4722],{},"需要控制运动模糊时，可以进入更深一层调整快门速度；需要精确掌控时，再进入 Pro 模式控制光圈、快门与感光度。",[16,4724,4725],{},"专业能力没有消失，只是没有在第一次拍照之前向所有人收费。",[16,4727,4728,4729],{},"但“这张照片会被永久删除”不能被藏进高级层。",[20,4730,4731],{},"低频不等于低重要性；风险和后果必须参与分层。",[36,4733,4735],{"id":4734},"第一层要最小但必须完整","第一层要最小，但必须完整",[16,4737,4738],{},"假设用户只想导出一份报告。第一层可以是：",[109,4740,4743],{"className":4741,"code":4742,"language":114,"meta":115},[112],"文件名       quarterly-report\n格式         PDF（Portable Document Format，便携式文档格式）\n保存到       Downloads\n             [ 高级选项 ] [ 导出 ]\n",[44,4744,4742],{"__ignoreMap":115},[16,4746,4747],{},"用户不展开任何内容，也能完成最常见任务，并且知道结果是什么。第二层再放页面范围、图像质量与元数据；第三层放颜色配置、字体嵌入与压缩算法。",[16,4749,4750],{},"这三层分别回答：",[468,4752,4753,4756,4759],{},[55,4754,4755],{},"我要完成什么？",[55,4757,4758],{},"结果需要怎样调整？",[55,4760,4761],{},"我要怎样控制底层实现？",[16,4763,4764],{},"如果第一层只有一个模糊按钮，而重要默认值全藏在后面，那不是渐进披露，而是隐藏决策。",[36,4766,4768],{"id":4767},"怎样决定什么先出现","怎样决定什么先出现？",[16,4770,4771],{},"不要从“哪些控件可以折叠”开始。先为每项信息判断四个维度：",[865,4773,4774,4783],{},[868,4775,4776],{},[871,4777,4778,4780],{},[874,4779,4480],{},[874,4781,4782],{},"要问的问题",[887,4784,4785,4793,4801,4809],{},[871,4786,4787,4790],{},[892,4788,4789],{},"必要性",[892,4791,4792],{},"没有它，当前任务还能完成吗？",[871,4794,4795,4798],{},[892,4796,4797],{},"频率",[892,4799,4800],{},"有多少用户、多少次任务会用到？",[871,4802,4803,4806],{},[892,4804,4805],{},"风险",[892,4807,4808],{},"隐藏它会不会改变费用、权限、安全或不可逆后果？",[871,4810,4811,4814],{},[892,4812,4813],{},"依赖",[892,4815,4816],{},"它是否只有在另一个选择出现后才有意义？",[16,4818,4819],{},"频繁、必需或高风险的信息通常留在第一层；低频、低风险且依赖特定意图的信息适合后置。",[36,4821,4823],{"id":4822},"一个-artificial-intelligenceai人工智能agent-例子","一个 Artificial Intelligence（AI，人工智能）Agent 例子",[16,4825,4826],{},"AI Agent 的设置很容易堆满模型、工具、上下文、预算、记忆、运行环境和审批策略。",[16,4828,4829],{},"一个合理起点可能是：",[52,4831,4832,4835,4838],{},[55,4833,4834],{},"第一层：目标、输入和输出；",[55,4836,4837],{},"第二层：受众、语气、长度和允许使用的来源；",[55,4839,4840],{},"第三层：模型、重试、预算和工具配置。",[16,4842,4843],{},"但 Tool access（工具权限）、外部写入、费用上限和破坏性操作属于高风险后果。即使低频，也应该在执行前明确显示或确认，不能因为“这是高级设置”就藏起来。",[16,4845,4846],{},"所以真实的分层不只是新手对专家，而是：",[109,4848,4851],{"className":4849,"code":4850,"language":114,"meta":115},[112],"披露层级 = 任务相关性 × 使用频率 × 选项依赖 × 行为后果\n",[44,4852,4850],{"__ignoreMap":115},[36,4854,4855],{"id":4855},"入口本身也是设计",[16,4857,4858,4859,4862],{},"“显示格式设置”比孤立的 ",[44,4860,4861],{},"+"," 或三点图标更容易形成正确预期。披露入口应该靠近它控制的内容，并说明将出现什么。",[16,4864,4865,4866,4868],{},"在网页里，Disclosure（披露控件）通常由一个按钮和一块受控内容组成。WAI-ARIA（Web Accessibility Initiative – Accessible Rich Internet Applications，Web 无障碍倡议—无障碍富互联网应用）Authoring Practices Guide 建议使用真正的按钮，用 ",[44,4867,2259],{}," 暴露状态，让 Enter 与 Space 都能切换，并且不要只靠 hover。",[36,4870,4872],{"id":4871},"什么时候适合","什么时候适合？",[52,4874,4875,4878,4881,4884,4887],{},[55,4876,4877],{},"功能很多，但常见任务只需要一个稳定子集；",[55,4879,4880],{},"选项有自然依赖，例如打开“自定义压缩”后才需要压缩率；",[55,4882,4883],{},"新手需要快速进入，专家仍需要完整控制；",[55,4885,4886],{},"移动端、侧栏或属性面板的空间有限；",[55,4888,4889],{},"详细信息有价值，但不是每个人每次都要读。",[36,4891,4893],{"id":4892},"什么时候会变坏","什么时候会变坏？",[52,4895,4896,4899,4902,4905,4908,4911],{},[55,4897,4898],{},"用户需要同时比较价格、权限或方案，却必须逐个展开；",[55,4900,4901],{},"总价、自动续费、删除后果或公开范围被藏起来；",[55,4903,4904],{},"两行说明也做成折叠区，白白增加一次操作；",[55,4906,4907],{},"专家每次都要打开相同区域；",[55,4909,4910],{},"隐藏内容无法被快速扫描、查找或打印；",[55,4912,4913],{},"入口标签含糊，用户根本不知道功能存在。",[16,4915,4916],{},"常见失败包括：",[52,4918,4919,4928,4934,4940,4946],{},[55,4920,4921,4924,4925,4927],{},[20,4922,4923],{},"点击隧道："," ",[44,4926,2319],{}," 才找到常用设置；",[55,4929,4930,4933],{},[20,4931,4932],{},"神秘入口："," 只有一个不知道会打开什么的图标；",[55,4935,4936,4939],{},[20,4937,4938],{},"隐藏风险："," 用视觉简洁掩盖费用、权限或不可逆后果；",[55,4941,4942,4945],{},[20,4943,4944],{},"状态失忆："," 每次都忘记专家的展开选择，或折叠时清空输入；",[55,4947,4948,4951],{},[20,4949,4950],{},"隐藏依赖："," 第一层结果受隐藏默认值影响，却没有任何摘要。",[36,4953,4954],{"id":4954},"看清概念邻居",[52,4956,4957,4966,4972,4978,4984,4990],{},[55,4958,4959,4962,4963,4965],{},[20,4960,4961],{},"Disclosure Widget（披露控件）是实现机制。"," 按钮、三角形、",[44,4964,2356],{}," 或 Accordion（手风琴）负责显示和隐藏；渐进披露是决定为什么、何时、披露什么的策略。",[55,4967,4968,4971],{},[20,4969,4970],{},"Contextual Disclosure（情境披露）是触发变体。"," 勾选 “Schedule” 后出现日期与时区，内容随着状态变得相关。",[55,4973,4974,4977],{},[20,4975,4976],{},"Staged Disclosure（分阶段披露）是流程变体。"," 把内容放进连续步骤或 Wizard（向导），更强调任务顺序。",[55,4979,4980,4983],{},[20,4981,4982],{},"Information Architecture（信息架构）是结构基础。"," 它负责分类、命名与连接；错误分类不会因为折叠动画而变好。",[55,4985,4986,4989],{},[20,4987,4988],{},"Defaults（默认值）是决策捷径。"," 它让第一层可以直接工作，但隐藏默认值也可能制造意外。",[55,4991,4992,4995],{},[20,4993,4994],{},"Feature Gating（功能门控）是访问策略。"," 它决定能不能用；渐进披露通常只改变什么时候看见。",[36,4997,4998],{"id":4998},"记住这六件事",[468,5000,5001,5004,5007,5010,5013,5016],{},[55,5002,5003],{},"复杂度不要被删除，而要按用户意图分期支付。",[55,5005,5006],{},"第一层必须最小但完整：任务能完成，结果看得见。",[55,5008,5009],{},"分层同时考虑必要性、频率、依赖与后果。",[55,5011,5012],{},"低频风险不能为了简洁被藏起来。",[55,5014,5015],{},"披露控件是机制，渐进披露是策略。",[55,5017,5018],{},"如果用户总在找、总在展开或总被隐藏默认值惊讶，分层就失败了。",[36,5020,3257],{"id":3257},[468,5022,5023,5026,5029,5032,5035,5038],{},[55,5024,5025],{},"用户不展开任何内容，能否完成最常见任务并预测结果？",[55,5027,5028],{},"哪些信息虽然低频，却因为费用、权限或不可逆性必须一直可见？",[55,5030,5031],{},"触发器是否说明将出现什么？",[55,5033,5034],{},"第二层是否增加新的决策价值？",[55,5036,5037],{},"键盘和辅助技术能否感知展开状态？",[55,5039,5040],{},"专家是否总在重复打开同一层？",[36,5042,512],{"id":511},[52,5044,5045,5050,5055,5060,5065],{},[55,5046,5047],{},[518,5048,2444],{"href":2442,"rel":5049},[522],[55,5051,5052],{},[518,5053,2451],{"href":2449,"rel":5054},[522],[55,5056,5057],{},[518,5058,2458],{"href":2456,"rel":5059},[522],[55,5061,5062],{},[518,5063,2465],{"href":2463,"rel":5064},[522],[55,5066,5067],{},[518,5068,2472],{"href":2470,"rel":5069},[522],{"title":115,"searchDepth":546,"depth":546,"links":5071},[5072,5073,5074,5075,5076,5077,5078,5079,5080,5081,5082],{"id":4715,"depth":546,"text":4716},{"id":4734,"depth":546,"text":4735},{"id":4767,"depth":546,"text":4768},{"id":4822,"depth":546,"text":4823},{"id":4855,"depth":546,"text":4855},{"id":4871,"depth":546,"text":4872},{"id":4892,"depth":546,"text":4893},{"id":4954,"depth":546,"text":4954},{"id":4998,"depth":546,"text":4998},{"id":3257,"depth":546,"text":3257},{"id":511,"depth":546,"text":512},"三层纸艺界面分别标注“必要”“情境”和“专家”，表示选项随着用户意图加深而逐层显露。","先给用户完成当前目标所需的最小完整界面，再随着意图与上下文逐层显露复杂度。","交互设计","Progressive Disclosure · 渐进披露",{},[5089,5093,5097,5101,5105,5109],{"name":2495,"fullName":5090,"category":5091,"summary":5092},"Disclosure Widget · 披露控件","实现机制","负责显示或隐藏内容；渐进披露则决定什么内容应该在什么时候出现。",{"name":2499,"fullName":5094,"category":5095,"summary":5096},"Contextual Disclosure · 情境披露","触发变体","当用户选择或环境变化使某项内容相关时，才在原地显露它。",{"name":2503,"fullName":5098,"category":5099,"summary":5100},"Staged Disclosure · 分阶段披露","流程变体","把信息分布在连续步骤或页面中，更强调顺序和阶段转换。",{"name":2507,"fullName":5102,"category":5103,"summary":5104},"Information Architecture · 信息架构","结构基础","决定信息怎样分类与连接；渐进披露决定一次交互中哪一层先出现。",{"name":2511,"fullName":5106,"category":5107,"summary":5108},"Defaults · 默认值","决策捷径","预先选择常见答案，让第一层可以完整工作；隐藏默认值也可能制造意外。",{"name":2515,"fullName":5110,"category":5111,"summary":5112},"Feature Gating · 功能门控","访问策略","决定用户是否有权使用功能；渐进披露通常只改变功能何时可见。","/zh/learn/progressive-disclosure",{"title":4696,"description":5084},{"loc":5113},[5117,5118,5119,5120,5121],{"title":2444,"url":2442},{"title":2451,"url":2449},{"title":2458,"url":2456},{"title":2465,"url":2463},{"title":2472,"url":2470},"zh/learn/progressive-disclosure",[5085,5124,5125,5126],"复杂度","信息架构","可发现性","0Gs0DuwVRbuXEfIETGOdV2BisxGJ1saoq9KSSbc0aGs",{"id":5129,"title":5130,"body":5131,"cardImage":2774,"cardImageAlt":5364,"date":1112,"description":5365,"domain":5366,"domainKey":2778,"extension":577,"featured":1116,"fullName":5367,"interaction":2540,"maturity":3330,"mentalModel":5368,"meta":5369,"navigation":578,"neighbors":5370,"ogImage":610,"path":5395,"published":578,"robots":610,"seo":5396,"shortName":2810,"sitemap":5397,"socialImage":610,"socialImageAlt":610,"sources":5398,"stem":5407,"tags":5408,"translationKey":2540,"updated":1112,"__hash__":5413},"learnZh/zh/learn/single-source-of-truth.md","单一事实来源",{"type":9,"value":5132,"toc":5353},[5133,5135,5141,5144,5148,5151,5157,5164,5167,5181,5185,5188,5202,5205,5212,5215,5221,5224,5230,5236,5239,5242,5245,5251,5254,5257,5260,5264,5267,5287,5290,5292,5324,5328,5331,5334,5336],[12,5134,5130],{"id":5130},[16,5136,5137,5138],{},"Single Source of Truth（SSOT，单一事实来源）解决的是所有重复信息背后的同一个问题：",[20,5139,5140],{},"当多个副本互相矛盾时，谁有权决定“现在是什么”？",[16,5142,5143],{},"它的答案不是“删除所有副本”。缓存、搜索索引、报表、replica（副本）、双语发布包和生产页面都很有用。这个 pattern 要做的是：让一个边界清楚的事实只有一个权威拥有者，其余表示都成为可追踪的派生物。",[36,5145,5147],{"id":5146},"它要阻止的失败drift","它要阻止的失败：drift",[16,5149,5150],{},"假设同一篇文章出现在四个地方：",[109,5152,5155],{"className":5153,"code":5154,"language":114,"meta":115},[112],"source.md       version 3\npublic package  version 3\nblog copy       version 4\nproduction      version 3 + 一次手工 hotfix\n",[44,5156,5154],{"__ignoreMap":115},[16,5158,5159,5160,5163],{},"四个版本看起来都合理。下一次同步却可能删掉最好的修改，因为没有人知道更新应该朝哪个方向流动。这就是 ",[20,5161,5162],{},"drift（漂移）","：本来应该一致的表示悄悄分叉。",[16,5165,5166],{},"一个健康的 SSOT 会明确四件事：",[468,5168,5169,5172,5175,5178],{},[55,5170,5171],{},"谁可以定义这个事实？",[55,5173,5174],{},"更新从哪里流向哪里？",[55,5176,5177],{},"一个派生副本允许落后多久？",[55,5179,5180],{},"分叉以后怎样重建或对账？",[36,5182,5184],{"id":5183},"一个事实一个主人不是所有东西一个数据库","一个事实一个主人，不是所有东西一个数据库",[16,5186,5187],{},"Authority（权威）应该按事实或领域划分：",[52,5189,5190,5193,5196,5199],{},[55,5191,5192],{},"Order Service 拥有订单生命周期；",[55,5194,5195],{},"身份系统拥有客户法定姓名；",[55,5197,5198],{},"source Markdown 拥有一篇文章真正表达的意思；",[55,5200,5201],{},"已提交的 main revision 拥有生产 release。",[16,5203,5204],{},"这些事实不需要住在同一个物理存储里。相反，把无关领域强塞进一个巨大数据库，可能让所有权更模糊。",[16,5206,5207,5208,5211],{},"一个很好用的判断题是：",[20,5209,5210],{},"哪个系统有权发起一次修正？"," 其他系统可以读取、订阅、缓存、索引、翻译或投影这个事实，但不能悄悄成为第二个独立写入者。",[36,5213,5214],{"id":5214},"一个实用发布链",[109,5216,5219],{"className":5217,"code":5218,"language":114,"meta":115},[112],"权威源 ──► 公开内容包 ──► 站点副本 ──► 部署结果\n在这里修改       派生          派生         发布证据\n",[44,5220,5218],{"__ignoreMap":115},[16,5222,5223],{},"一个健康的派生物应该带有足够的 Data Lineage（数据血缘）：",[109,5225,5228],{"className":5226,"code":5227,"language":114,"meta":115},[112],"derived_from   = 源标识\nsource_version = commit / offset / version\ngenerated_at   = 生成时间\nrefresh_policy = 每次提交 / 每五分钟 / 每晚\nrebuild_path   = 可重复的命令或流程\n",[44,5229,5227],{"__ignoreMap":115},[16,5231,5232,5233,5235],{},"最容易推理的默认结构，是单向、可重复地生成。",[44,5234,2642],{}," 这种环形同步会让每一方都可能成为权威，于是必须额外定义复杂的冲突语义。",[36,5237,5238],{"id":5238},"一个服务例子",[16,5240,5241],{},"假设 Order Service 拥有订单状态。它发布更新事件，供搜索索引、分析表和推荐系统消费。",[16,5243,5244],{},"这些副本可以针对不同查询优化，也可以只有 eventual consistency（最终一致性）。但退款仍然必须询问 Order Service，因为它拥有完整交易历史。一个更快、更近的副本，不会因为方便就自动获得权威。",[16,5246,5247,5248],{},"所以 SSOT 完全可以和复制、高读取吞吐同时存在：",[20,5249,5250],{},"物理副本可以很多，权威不能含糊。",[36,5252,5253],{"id":5253},"权威不等于永远正确",[16,5255,5256],{},"权威源仍可能包含 bug、错误录入或过期规则。SSOT 不会让它永不犯错；它让修复有方向：先修正拥有者，再重新生成或对账所有派生物。",[16,5258,5259],{},"如果没有这个方向，团队会在许多副本里分别打补丁，却永远无法确认修复是否完整。",[36,5261,5263],{"id":5262},"分叉以后怎样恢复","分叉以后怎样恢复？",[16,5265,5266],{},"当两个副本都出现了看似有效的修改：",[468,5268,5269,5272,5275,5278,5281,5284],{},[55,5270,5271],{},"暂停会继续扩大分叉的写入或发布。",[55,5273,5274],{},"说清楚发生冲突的是哪一类事实。",[55,5276,5277],{},"根据所有权、完整性、时间线和审计证据确认权威。",[55,5279,5280],{},"把下游独有且正确的修改带回源头。",[55,5282,5283],{},"从修复后的源重新生成所有派生物。",[55,5285,5286],{},"增加 lineage、diff check、写权限或单向发布路径。",[16,5288,5289],{},"顺序很重要：先恢复 authority，再恢复 consistency（数据一致性）。如果不先选择裁判，同步只是随便让一个版本覆盖另一个。",[36,5291,4591],{"id":4591},[52,5293,5294,5300,5306,5312,5318],{},[55,5295,5296,5299],{},[20,5297,5298],{},"不是一个巨大数据库。"," SSOT 关心有边界的权威，而不是物理集中。",[55,5301,5302,5305],{},[20,5303,5304],{},"不是禁止副本。"," 缓存、replica、materialized view（物化视图）和报表本来就应该存在。",[55,5307,5308,5311],{},[20,5309,5310],{},"不是自动保证正确。"," 它告诉我们一次修正应该发生在哪里。",[55,5313,5314,5317],{},[20,5315,5316],{},"不是 Event Sourcing（事件溯源）。"," 事件日志可以实现 SSOT，但只是其中一种实现模式。",[55,5319,5320,5323],{},[20,5321,5322],{},"不是 Single Version of Truth（SVOT，单一版本的真相）。"," SVOT 强调消费者对统一定义或结果达成一致；SSOT 强调权威从哪里产生。",[36,5325,5327],{"id":5326},"什么时候会变难","什么时候会变难？",[16,5329,5330],{},"离线优先协作、active-active（双活）多地域写入、network partition（网络分区），以及真正需要多个独立作者共同定义事实的系统，都会让简单的“单写者”模型变难。",[16,5332,5333],{},"这些系统仍然需要显式权威和冲突语义，只是可能通过 leader（领导者）、quorum（法定人数）、merge rule（合并规则）或 CRDT（Conflict-free Replicated Data Type，无冲突复制数据类型）来分布式地实现。“我们有多个写入者”不等于可以不定义分歧怎样解决。",[36,5335,3728],{"id":3728},[468,5337,5338,5341,5344,5347,5350],{},[55,5339,5340],{},"一个事实可以有很多副本，但需要一个被明确命名的权威。",[55,5342,5343],{},"每个派生物都应该暴露 source、version、freshness 和 rebuild path。",[55,5345,5346],{},"业务不需要多写者时，优先使用单向、幂等的生成流程。",[55,5348,5349],{},"先修改源，再重新生成下游；直接编辑 projection（投影）会制造 drift。",[55,5351,5352],{},"SSOT 让错误可以修复、可以审计，而不是让错误从此不可能发生。",{"title":115,"searchDepth":546,"depth":546,"links":5354},[5355,5356,5357,5358,5359,5360,5361,5362,5363],{"id":5146,"depth":546,"text":5147},{"id":5183,"depth":546,"text":5184},{"id":5214,"depth":546,"text":5214},{"id":5238,"depth":546,"text":5238},{"id":5253,"depth":546,"text":5253},{"id":5262,"depth":546,"text":5263},{"id":4591,"depth":546,"text":4591},{"id":5326,"depth":546,"text":5327},{"id":3728,"depth":546,"text":3728},"一份放在深色基座上的纸艺主记录分流到仪表盘、报告与缓存，表示一个权威来源生成多个派生视图。","让每一类事实只有一个权威拥有者；其余副本都可追踪、可过期、可重建。","信息系统","Single Source of Truth · 单一事实来源","一个事实可以有很多副本，但只能有一个地方被授权回答“现在是什么”。",{},[5371,5375,5379,5383,5387,5391],{"name":2783,"fullName":5372,"category":5373,"summary":5374},"Canonical Source · 规范源","权威机制","被正式选为某类事实权威表示的具体文件、存储或日志。",{"name":2787,"fullName":5376,"category":5377,"summary":5378},"Data Lineage · 数据血缘","来源追踪","记录数据来自哪里、经过哪些转换，以及由哪个源版本产生。",{"name":2791,"fullName":5380,"category":5381,"summary":5382},"Materialized View · 物化视图","派生投影","为查询保存的派生表示；它可以落后，并且应该能从源头重新生成。",{"name":2795,"fullName":5384,"category":5385,"summary":5386},"Event Sourcing · 事件溯源","实现模式","把按顺序排列的事件日志作为权威记录，通过重放构建当前状态。",{"name":2799,"fullName":5388,"category":5389,"summary":5390},"Command Query Responsibility Segregation · 命令查询职责分离","架构模式","把权威命令与读优化投影分开，同时引入明确的同步边界。",{"name":2804,"fullName":5392,"category":5393,"summary":5394},"Single Version of Truth · 单一版本的真相","消费共识","让消费者对一套定义或结果达成一致；它与确定权威位置相关，但并不相同。","/zh/learn/single-source-of-truth",{"title":5130,"description":5365},{"loc":5395},[5399,5401,5403,5405],{"title":5400,"url":2815},"Microsoft · 微服务的数据考量",{"title":5402,"url":2818},"Microsoft · CQRS 模式",{"title":5404,"url":2821},"HashiCorp · Terraform State 的用途",{"title":5406,"url":2824},"Kubernetes · 声明式对象配置","zh/learn/single-source-of-truth",[5409,5410,5411,5412],"权威来源","数据血缘","同步","知识系统","h1AkvbrLGiEFOE7XVMGBVduTF1IUQ2MazQ6rFL9dERs",1785418433463]