<?xml version="1.0" encoding="UTF-8" standalone="no"?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" version="2.0">

<channel>
	<title>Algorithms, Blockchain and Cloud</title>
	<atom:link href="https://helloacm.com/feed/" rel="self" type="application/rss+xml"/>
	<link>https://helloacm.com</link>
	<description>The Ultimate Computer Technology Blog - The Knowledgebase of Computing</description>
	<lastBuildDate>Sat, 17 Oct 2026 17:45:44 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.1.4</generator>
	<itunes:explicit>no</itunes:explicit><itunes:subtitle>The Ultimate Computer Technology Blog - The Knowledgebase of Computing</itunes:subtitle><item>
		<title>Teaching Kids Programming – The Halting Problem: Paradoxes, Self-Reference, and Why Some Problems Are Impossible to Solve</title>
		<link>https://helloacm.com/teaching-kids-programming-the-halting-problem-paradoxes-self-reference-and-why-some-problems-are-impossible-to-solve/</link>
					<comments>https://helloacm.com/teaching-kids-programming-the-halting-problem-paradoxes-self-reference-and-why-some-problems-are-impossible-to-solve/#respond</comments>
		
		<dc:creator><![CDATA[ACMer]]></dc:creator>
		<pubDate>Sat, 17 Oct 2026 17:45:44 +0000</pubDate>
				<category><![CDATA[computational theory]]></category>
		<category><![CDATA[Computer Science]]></category>
		<category><![CDATA[math]]></category>
		<category><![CDATA[teaching kids programming]]></category>
		<category><![CDATA[youtube video]]></category>
		<category><![CDATA[Alan Turing]]></category>
		<category><![CDATA[Barber Paradox]]></category>
		<category><![CDATA[Computability Theory]]></category>
		<category><![CDATA[Diagonalisation]]></category>
		<category><![CDATA[halting problem]]></category>
		<category><![CDATA[Liar Paradox]]></category>
		<category><![CDATA[Paradox]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[Rice's Theorem]]></category>
		<category><![CDATA[Russell's Paradox]]></category>
		<category><![CDATA[Self-reference]]></category>
		<category><![CDATA[Teaching Kids Programming]]></category>
		<category><![CDATA[theoretical computer science]]></category>
		<category><![CDATA[Undecidability]]></category>
		<category><![CDATA[Youtube Video]]></category>
		<guid isPermaLink="false">https://helloacm.com/?p=158165</guid>

					<description><![CDATA[<iframe width="2924" height="1101" src="https://www.youtube.com/embed/le6cyVQzXfg" title="Day 711 - Teaching Kids Programming - The Halting Problem - Paradox" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

<blockquote>
The Halting Problem proves that no algorithm can determine whether every arbitrary program will terminate. Explore the Barber Paradox, Russell's Paradox, self-reference, diagonalisation, and Alan Turing's elegant proof of undecidability.
</blockquote>

<h1>The Halting Problem: Paradoxes, Self-Reference, and Why Some Problems Are Impossible to Solve</h1>

In computer science, we are used to thinking that every problem has a solution. Some problems are easy, some are hard, and some require enormous computational resources. But what if there are problems that no algorithm can ever solve, regardless of how powerful our computers become?

One of the most fascinating examples is <b>the Halting Problem</b>, introduced by Alan Turing in 1936.

The Halting Problem is closely related to a powerful <a href="https://helloacm.com/fundamental-mathematical-formulas-for-machine-learning-optimization-argmax-reasoning-backward-from-the-future/" title="Fundamental mathematical formulas for machine learning (optimization): argmax Reasoning Backward from the Future">mathematical</a> technique called <b>proof by contradiction</b>, and particularly to paradoxes involving <b>self-reference</b>.

Before exploring why the Halting Problem is undecidable, let's first understand what a paradox is, using a few famous examples.

<h2>1. What Is a Paradox?</h2>

A paradox is a statement, situation, or argument that appears to lead to a contradiction, often despite seemingly reasonable assumptions.

Some paradoxes reveal ambiguities in language. Others expose inconsistent assumptions, while some reveal deep limitations in logic and mathematics.

The most interesting paradoxes often involve <b>self-reference</b>: a statement, rule, or procedure that somehow refers to itself.

Let's examine three examples.

<h2>2. The Barber Paradox: Who Shaves the Barber?</h2>

Imagine a small village with exactly one barber.

The barber follows a very strict rule:

<blockquote>
The barber shaves all and only those men in the village who do not shave themselves.
</blockquote>

In other words, if a man doesn't shave himself, the barber shaves him. If a man shaves himself, the barber doesn't shave him.

Everything sounds perfectly reasonable until we ask one simple question:

<b>Who shaves the barber?</b>

<h3>Case A: The Barber Shaves Himself</h3>

Suppose the barber shaves himself.

According to the rule, the barber only shaves men who do not shave themselves. Therefore, he cannot shave himself.

Contradiction!

<h3>Case B: The Barber Does Not Shave Himself</h3>

Now suppose the barber does not shave himself.

According to the rule, the barber must shave every man who does not shave himself. Therefore, he must shave himself.

Another contradiction!

We have only two possibilities:

<blockquote>
If the barber shaves himself, he must not shave himself.

If the barber does not shave himself, he must shave himself.
</blockquote>

Neither possibility works.

<b>The important conclusion is not that the barber faces a difficult decision. It is that such a barber cannot exist under the stated conditions.</b>

The definition itself is inconsistent.

This is known as the <b>Barber Paradox</b>, a popular illustration of the deeper logical issue found in Russell's Paradox.

<h2>3. The Liar Paradox: This Statement Is False</h2>

Consider the following sentence:

<blockquote>
This statement is false.
</blockquote>

Is this sentence true or false?

<h3>Case A: The Statement Is True</h3>

Suppose it is true.

Then what it says must be correct, meaning the statement is false.

Contradiction.

<h3>Case B: The Statement Is False</h3>

Now suppose it is false.

Then its claim that it is false appears to be correct, making it true.

Another contradiction.

<blockquote>
If the statement is true, it is false.

If the statement is false, it is true.
</blockquote>

The problem is that the statement refers to its own truth value.

This is called the <b>Liar Paradox</b>, and it highlights difficulties with unrestricted self-reference in natural language and formal theories of truth.

Different logical systems handle this paradox differently. For example, some restrict self-referential truth statements, while others allow truth values beyond simply true or false.

The key lesson is that apparently simple statements can behave unexpectedly when they refer to themselves.

<h2>4. Russell's Paradox: The Set That Cannot Exist</h2>

The mathematician Bertrand Russell discovered a related contradiction in naive set theory.

Imagine we can freely construct a set using any well-defined property.

Now consider the set R containing exactly those sets that do not contain themselves.

<pre><code>
R = { x | x is a set and x is not an element of x }
</code></pre>

For example, a set of numbers is not itself a number, so it would not contain itself.

Now ask:

<b>Does R contain itself?</b>

<h3>Case A: R Contains Itself</h3>

If R contains itself, then by its own definition it must not contain itself.

Contradiction.

<h3>Case B: R Does Not Contain Itself</h3>

If R does not contain itself, then by its own definition it must contain itself.

Another contradiction.

We have:

<blockquote>
R contains R if and only if R does not contain R.
</blockquote>

Russell's Paradox demonstrated that unrestricted set comprehension leads to inconsistency.

It was one of the reasons mathematicians developed more rigorous axiomatic set theories, such as Zermelo-Fraenkel set theory (ZF and ZFC), where not every property defines a set.

Notice the common pattern across these three examples:

<b>A rule is applied to something that is defined in terms of that very rule.</b>

This recurring structure is extremely important in theoretical computer science.

Now we are ready to explore the Halting Problem.

<h2>5. The Halting Problem: Can We Predict Whether a Program Will Finish?</h2>

Imagine that you are developing a tool that analyses source code.

Given any program and its input, your tool should determine whether the program will eventually terminate or run forever.

For example, consider this Python program:

<pre><code>
def program_a():
    print("Hello, World!")
</code></pre>

Clearly, this <a href="https://helloacm.com/code-is-becoming-cheaper-what-really-matters-for-programmers-in-the-ai-era/" title="Code Is Becoming Cheaper: What Really Matters for Programmers in the AI Era">program</a> terminates.

Now consider another program:

<pre><code>
def program_b():
    while True:
        pass
</code></pre>

This program runs forever.

These two examples are trivial. We can determine their behaviour just by reading the code.

But what about an arbitrary program with complex loops, recursion, dynamic inputs, and complicated conditional logic?

Can we design an algorithm that always predicts whether <b>any program, given any input</b>, will eventually terminate?

This is exactly the Halting Problem.

<h3>Formal Definition</h3>

Suppose there exists a function:

<pre><code>
halts(program, input)
</code></pre>

It returns:

<pre><code>
True   # The program eventually terminates
False  # The program runs forever
</code></pre>

Our hypothetical function must satisfy three requirements:

<ul>
<li><b>Universality:</b> It works for every valid program and every valid input in the computational model.</li>
<li><b>Correctness:</b> It always returns the correct answer.</li>
<li><b>Termination:</b> The halts function must itself terminate in finite time.</li>
</ul>

The third requirement matters enormously.

If a target program terminates, we can discover that by running it. However, if it has not terminated after an hour, a year, or a million years, how can we know whether it will run forever or simply terminate later?

The surprising result is:

<b>No such universal algorithm can exist.</b>

Alan Turing proved this mathematically in 1936.

Let's see why.

<h2>6. Proving the Halting Problem Is Undecidable</h2>

The proof uses <b>proof by contradiction</b>, also known as reductio ad absurdum.

Instead of directly proving that no universal halting checker exists, we temporarily assume one does exist.

Then we construct a program that makes this assumption logically impossible.

<h3>Step 1: Assume a Perfect Halting Checker Exists</h3>

Suppose we have a magical function named halts:

<pre><code>
def halts(program, input):
    # Always returns True if program(input)
    # eventually terminates.
    #
    # Always returns False if program(input)
    # runs forever.
    #
    # This function always terminates.
    ...
</code></pre>

We don't need to know how this function works.

We simply assume that it can correctly solve the Halting Problem for every possible program and input.

<h3>Step 2: Construct a New Program That Does the Opposite</h3>

Using the hypothetical halts function, we construct a new function called paradox.

<pre><code>
def paradox(program):
    if halts(program, program):
        while True:
            pass
    else:
        return
</code></pre>

Think carefully about what this function does.

It first asks whether the given program will terminate when executed with itself as its own input.

If halts predicts that the program terminates, paradox deliberately enters an infinite loop.

If halts predicts that the program runs forever, paradox immediately terminates.

In other words:

<b>The paradox function deliberately does the opposite of what halts predicts.</b>

Notice that self-reference appears in the call:

<pre><code>
halts(program, program)
</code></pre>

The same program is used both as the program being analysed and as its input.

This is perfectly legitimate in theoretical computation: programs can be represented as data and supplied to other programs.

<h3>Step 3: Call the Function With Itself</h3>

Now comes the crucial step.

What happens if we execute:

<pre><code>
paradox(paradox)
</code></pre>

Remember that halts is assumed to be correct for every program and input, including this one.

There are only two possible answers from the halts function.

<h3>Case A: halts(paradox, paradox) Returns True</h3>

This means halts predicts that paradox(paradox) will terminate.

But look at our implementation.

If halts returns True, paradox executes:

<pre><code>
while True:
    pass
</code></pre>

Therefore, paradox(paradox) runs forever.

The halts function predicted termination, but the program does not terminate.

<b>Our supposedly perfect halting checker is wrong.</b>

<h3>Case B: halts(paradox, paradox) Returns False</h3>

This means halts predicts that paradox(paradox) runs forever.

But if halts returns False, paradox executes:

<pre><code>
return
</code></pre>

Therefore, <a href="https://helloacm.com/the-halting-problem-and-its-paradoxical-cousins-when-logic-looks-at-itself/" title="The Halting Problem and Its Paradoxical Cousins: When Logic Looks at Itself">paradox</a>(paradox) terminates immediately.

Again, the halts function predicted nontermination, but the program terminates.

<b>Our supposedly perfect halting checker is wrong again.</b>

<h3>Step 4: The Contradiction</h3>

We can summarise both cases:

<blockquote>
If halts predicts termination, paradox runs forever.

If halts predicts nontermination, paradox terminates.
</blockquote>

The halts function must return either True or False, but both possibilities lead to a contradiction with our assumption that halts is always correct.

Therefore, our original assumption must be false.

<b>A universal, always-correct, always-terminating halting checker cannot exist.</b>

This completes the proof.

<h2>7. Why Is This Called Undecidability?</h2>

In theoretical computer science, a decision problem is a problem whose answer is either Yes or No.

A problem is called <b>decidable</b> if an algorithm exists that always terminates and correctly answers Yes or No for every valid input.

A problem is <b>undecidable</b> if no such algorithm exists.

The Halting Problem is undecidable because there is no general algorithm that can correctly determine whether every arbitrary program will terminate.

This does not mean that we cannot determine termination for any programs.

For example, we can easily prove that a program containing a fixed number of iterations will terminate, assuming its operations terminate.

We can also sometimes prove that certain programs run forever.

Compilers, static analysers, theorem provers, and formal verification tools can successfully establish termination or nontermination for many useful classes of programs.

What is impossible is constructing a single algorithm that is guaranteed to answer correctly for <b>every possible program and input</b>.

This distinction is crucial.

<b>Undecidable does not mean difficult, computationally expensive, or impossible to analyse in every individual case.</b>

It means no total, universally correct decision procedure exists.

<h2>8. Is the Halting Problem Actually a Paradox?</h2>

Strictly speaking, the Halting Problem itself is not a logical paradox.

The Halting Problem is a well-defined mathematical question, and its undecidability is a proven theorem.

The paradoxical behaviour arises when we <b>assume that a perfect universal halting checker exists</b> and then use self-reference to construct a contradiction.

This is different from claiming that computation itself is inconsistent.

The contradiction tells us that our assumption was impossible.

In this respect, the Halting Problem proof resembles the Barber Paradox.

The barber cannot exist with the specified shaving rule.

Likewise, the perfect halting checker cannot exist with the specified correctness and termination requirements.

However, there is an important technical distinction.

The barber's specification directly leads to inconsistency. The Halting Problem uses a carefully constructed algorithm to show that no computable universal checker can satisfy its specification.

This method of constructing an object that disagrees with a supposed universal procedure is called <b>diagonalisation</b>.

It is one of the most powerful techniques in mathematics and theoretical computer science.

<h2>9. Connection to Cantor's Diagonal Argument</h2>

Long before Turing's work, Georg Cantor used diagonalisation to demonstrate that the real numbers are uncountable.

Suppose someone claims to have a complete list of every real number between 0 and 1.

Cantor showed that we can construct a new real number by changing a digit along the diagonal of the list, choosing the new digits carefully to avoid ambiguity.

The resulting number must differ from the first listed number in its first digit, from the second in its second digit, and so on.

Therefore, it cannot appear anywhere on the supposedly complete list.

The list was not complete after all.

Turing's proof follows a related strategy.

We assume a universal procedure exists, then construct a program whose behaviour contradicts what that procedure predicts about it.

Cantor's argument produces a number missing from a supposedly complete list.

Turing's argument produces a program that defeats a supposedly universally correct halting checker.

In both cases, diagonalisation exposes the limits of a proposed universal description or procedure.

<h2>10. Why Can't We Just Simulate the Program?</h2>

A natural objection is:

<blockquote>
Why not simply run the program and observe whether it terminates?
</blockquote>

That works when the program eventually terminates.

But suppose a program has been running for one billion steps without terminating.

Does that mean it will never terminate?

No.

It might terminate after one billion and one steps.

Or after a trillion steps.

Or never.

For example:

<pre><code>
def very_slow_program():
    for i in range(10**100):
        pass
    return
</code></pre>

This program is finite and will eventually terminate under the idealised computational model, despite its enormous running time.

No fixed timeout can correctly distinguish every terminating program from every nonterminating program.

Simulation therefore gives us a <b>one-sided procedure</b>: if the target eventually halts, we can eventually observe that fact.

But if it runs forever, simulation alone never produces a definitive negative answer.

This is why the Halting Problem is described as <b>recognisable but not decidable</b>.

There is a procedure that eventually accepts every halting program-input pair, but no procedure that always terminates and correctly classifies every pair.

<h2>11. Could AI Solve the Halting Problem?</h2>

With advances in artificial intelligence, large language models, program synthesis, and automated reasoning, it is tempting to ask whether sufficiently intelligent AI could solve the Halting Problem.

The answer is still no, provided the AI system is itself an ordinary computable algorithm subject to the same requirements.

AI can make program analysis much more powerful.

It can recognise common infinite-loop patterns, infer program invariants, generate termination proofs, and suggest fixes for nonterminating code.

But no matter how advanced it becomes, a computable AI system cannot guarantee a correct halting decision for every arbitrary program while always terminating itself.

This is not a limitation caused by insufficient training data, model size, GPU power, or reasoning time.

<b>It is a mathematical limitation of computation.</b>

Of course, this does not prevent AI from being extremely useful in practical program <a href="https://helloacm.com/the-alien-dictionary-verification-algorithm/" title="The Alien Dictionary Verification Algorithm">verification</a>.

The impossibility concerns universal guarantees, not practical effectiveness.

<h2>12. Beyond the Halting Problem: Rice's Theorem</h2>

The Halting Problem is not an isolated curiosity.

It leads us toward an even broader result known as <b>Rice's Theorem</b>.

Informally, Rice's Theorem states that every nontrivial semantic property of the partial function computed by a program is undecidable in general.

A semantic property concerns what a program computes, rather than merely how its source code is written.

For example, consider questions such as:

<blockquote>
Does this arbitrary program compute a function that always returns zero?

Does this arbitrary program compute a function that is defined for every possible input?

Does this arbitrary program compute exactly the same function as a given reference program?
</blockquote>

These are examples of nontrivial properties of computed functions, and no universal algorithm can decide them for all programs in a Turing-complete programming language.

However, Rice's Theorem does not say that every question about a program is undecidable.

For instance, checking whether Python source code contains a particular token is a syntactic property and can be decidable.

The distinction between a program's syntax and its computed behaviour matters.

<h2>13. What Does This Mean for Software Engineering?</h2>

As software engineers, we regularly try to reason about program correctness, termination, safety, and performance.

The Halting Problem explains why certain ambitions for fully automated software verification are fundamentally impossible in the unrestricted general case.

We cannot build a universal static analyser that always terminates and perfectly predicts every possible runtime behaviour of every arbitrary program.

Instead, practical tools must make trade-offs.

Some restrict the class of programs they support.

Some return "unknown" when they cannot establish a result.

Others use conservative approximations, potentially reporting issues that cannot actually occur.

Formal verification tools may require programmers to provide invariants, contracts, termination measures, or other supporting proofs.

These approaches are not evidence of poor engineering.

They reflect the mathematical boundaries of what automated analysis can guarantee.

The lesson is that <b>restrictions, assumptions, and incomplete results can be necessary for sound program analysis</b>.

<h2>14. Final Thoughts: The Limits of Computation</h2>

The Barber Paradox, Liar Paradox, Russell's Paradox, and the Halting Problem share a fascinating theme: self-reference can expose contradictions in assumptions that initially seem perfectly reasonable.

The Barber Paradox shows that a certain seemingly simple rule cannot describe an existing barber.

The Liar Paradox challenges straightforward assignments of truth and falsehood to self-referential statements.

Russell's Paradox demonstrates why unrestricted set construction is inconsistent.

The Halting Problem takes self-reference into the world of algorithms and establishes a fundamental limit on what computers can decide.

What makes Turing's result remarkable is its universality.

It applies not just to Python or C++, but to any Turing-complete programming language and every ordinary computational system implementing the same general model of computation.

Even an infinitely fast computer would not make the Halting Problem decidable. The impossibility is not about running out of time; it is about the nonexistence of an algorithm satisfying the specification.

The central insight can be expressed in one sentence:

<blockquote>
If a universal algorithm could always predict whether any program halts, we could construct a program that deliberately contradicts its prediction.
</blockquote>

And that is why the Halting Problem is undecidable.

Sometimes, the most profound discovery in computer science is not finding a better algorithm.

It is proving that the algorithm we are searching for <b>cannot possibly exist</b>.

<h2>References and Further Reading</h2>

<ul>
<li><a href="https://en.wikipedia.org/wiki/Halting_problem">The Halting Problem — Wikipedia</a></li>
<li><a href="https://en.wikipedia.org/wiki/Barber_paradox">The Barber Paradox — Wikipedia</a></li>
<li><a href="https://en.wikipedia.org/wiki/Liar_paradox">The Liar Paradox — Wikipedia</a></li>
<li><a href="https://en.wikipedia.org/wiki/Russell%27s_paradox">Russell's Paradox — Wikipedia</a></li>
<li><a href="https://en.wikipedia.org/wiki/Diagonal_argument">Diagonal Argument — Wikipedia</a></li>
<li><a href="https://en.wikipedia.org/wiki/Rice%27s_theorem">Rice's Theorem — Wikipedia</a></li>
<li><a href="https://doi.org/10.1112/plms/s2-42.1.230">Alan Turing (1936), On Computable Numbers, with an Application to the Entscheidungsproblem</a></li>
</ul>

[show_posts keyword="Paradox"]

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/compute-gcd-in-bash-with-input-validation/" rel="bookmark" title="Compute GCD in Bash with Input Validation">Compute GCD in Bash with Input Validation</a> <small>GCD Computation in Bash What is GCD? GCD stands for Greatest Common Divisor. It is...</small></li>
<li><a href="https://helloacm.com/usb-otg-on-the-go/" rel="bookmark" title="USB OTG (On The Go)">USB OTG (On The Go)</a> <small>USB OTG (On The Go) allows some USB devices to act as both master and...</small></li>
<li><a href="https://helloacm.com/a-google-alert-woke-me-up-postmortem-of-a-wordpress-security-incident/" rel="bookmark" title="A Google Alert Woke Me Up: Postmortem of a WordPress Security Incident">A Google Alert Woke Me Up: Postmortem of a WordPress Security Incident</a> <small>An unpatched WordPress and plugin vulnerability apparently exposed a Cloudflare credential stored in the database....</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-form-smallest-number-from-two-digit-arrays/" rel="bookmark" title="Teaching Kids Programming &#8211; Form Smallest Number From Two Digit Arrays (Set Intersection)">Teaching Kids Programming &#8211; Form Smallest Number From Two Digit Arrays (Set Intersection)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms Given two arrays of unique digits...</small></li>
<li><a href="https://helloacm.com/tutorial-example-how-to-access-microsoft-excel-chart-using-the-windows-scripting-host-jscript/" rel="bookmark" title="Tutorial Example: How to Access Microsoft Excel (Chart) using the Windows Scripting Host (JScript)">Tutorial Example: How to Access Microsoft Excel (Chart) using the Windows Scripting Host (JScript)</a> <small>WSH (Window Scripting Host) is a powerful and handy scripting environment. It is installed by...</small></li>
<li><a href="https://helloacm.com/hot-weather-causes-intel-cpu-throttle-and-nvidia-gpu-crashes-on-windows-11-blue-screen/" rel="bookmark" title="Hot Weather Causes Intel CPU Throttle and NVidia GPU Crashes on Windows 11 (Blue Screen)">Hot Weather Causes Intel CPU Throttle and NVidia GPU Crashes on Windows 11 (Blue Screen)</a> <small>My Microsoft Surface Laptop Studio 2 becomes extremely laggy, slow, and nearly unusable in hot...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-design-a-hash-table/" rel="bookmark" title="Teaching Kids Programming &#8211; Design a Hash Table">Teaching Kids Programming &#8211; Design a Hash Table</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms Design a HashMap without using any...</small></li>
<li><a href="https://helloacm.com/recursive-depth-first-search-algorithm-to-compute-the-sum-of-nodes-with-even-valued-grandparent-in-a-binary-tree/" rel="bookmark" title="Recursive Depth First Search Algorithm to Compute the Sum of Nodes with Even-Valued Grandparent in a Binary Tree">Recursive Depth First Search Algorithm to Compute the Sum of Nodes with Even-Valued Grandparent in a Binary Tree</a> <small>Given a binary tree, return the sum of values of nodes with even-valued grandparent. (A...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<iframe width="2924" height="1101" src="https://www.youtube.com/embed/le6cyVQzXfg" title="Day 711 - Teaching Kids Programming - The Halting Problem - Paradox" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

<blockquote>
The Halting Problem proves that no algorithm can determine whether every arbitrary program will terminate. Explore the Barber Paradox, Russell's Paradox, self-reference, diagonalisation, and Alan Turing's elegant proof of undecidability.
</blockquote>

<h1>The Halting Problem: Paradoxes, Self-Reference, and Why Some Problems Are Impossible to Solve</h1>

In computer science, we are used to thinking that every problem has a solution. Some problems are easy, some are hard, and some require enormous computational resources. But what if there are problems that no algorithm can ever solve, regardless of how powerful our computers become?

One of the most fascinating examples is <b>the Halting Problem</b>, introduced by Alan Turing in 1936.

The Halting Problem is closely related to a powerful <a href="https://helloacm.com/fundamental-mathematical-formulas-for-machine-learning-optimization-argmax-reasoning-backward-from-the-future/" title="Fundamental mathematical formulas for machine learning (optimization): argmax Reasoning Backward from the Future">mathematical</a> technique called <b>proof by contradiction</b>, and particularly to paradoxes involving <b>self-reference</b>.

Before exploring why the Halting Problem is undecidable, let's first understand what a paradox is, using a few famous examples.

<h2>1. What Is a Paradox?</h2>

A paradox is a statement, situation, or argument that appears to lead to a contradiction, often despite seemingly reasonable assumptions.

Some paradoxes reveal ambiguities in language. Others expose inconsistent assumptions, while some reveal deep limitations in logic and mathematics.

The most interesting paradoxes often involve <b>self-reference</b>: a statement, rule, or procedure that somehow refers to itself.

Let's examine three examples.

<h2>2. The Barber Paradox: Who Shaves the Barber?</h2>

Imagine a small village with exactly one barber.

The barber follows a very strict rule:

<blockquote>
The barber shaves all and only those men in the village who do not shave themselves.
</blockquote>

In other words, if a man doesn't shave himself, the barber shaves him. If a man shaves himself, the barber doesn't shave him.

Everything sounds perfectly reasonable until we ask one simple question:

<b>Who shaves the barber?</b>

<h3>Case A: The Barber Shaves Himself</h3>

Suppose the barber shaves himself.

According to the rule, the barber only shaves men who do not shave themselves. Therefore, he cannot shave himself.

Contradiction!

<h3>Case B: The Barber Does Not Shave Himself</h3>

Now suppose the barber does not shave himself.

According to the rule, the barber must shave every man who does not shave himself. Therefore, he must shave himself.

Another contradiction!

We have only two possibilities:

<blockquote>
If the barber shaves himself, he must not shave himself.

If the barber does not shave himself, he must shave himself.
</blockquote>

Neither possibility works.

<b>The important conclusion is not that the barber faces a difficult decision. It is that such a barber cannot exist under the stated conditions.</b>

The definition itself is inconsistent.

This is known as the <b>Barber Paradox</b>, a popular illustration of the deeper logical issue found in Russell's Paradox.

<h2>3. The Liar Paradox: This Statement Is False</h2>

Consider the following sentence:

<blockquote>
This statement is false.
</blockquote>

Is this sentence true or false?

<h3>Case A: The Statement Is True</h3>

Suppose it is true.

Then what it says must be correct, meaning the statement is false.

Contradiction.

<h3>Case B: The Statement Is False</h3>

Now suppose it is false.

Then its claim that it is false appears to be correct, making it true.

Another contradiction.

<blockquote>
If the statement is true, it is false.

If the statement is false, it is true.
</blockquote>

The problem is that the statement refers to its own truth value.

This is called the <b>Liar Paradox</b>, and it highlights difficulties with unrestricted self-reference in natural language and formal theories of truth.

Different logical systems handle this paradox differently. For example, some restrict self-referential truth statements, while others allow truth values beyond simply true or false.

The key lesson is that apparently simple statements can behave unexpectedly when they refer to themselves.

<h2>4. Russell's Paradox: The Set That Cannot Exist</h2>

The mathematician Bertrand Russell discovered a related contradiction in naive set theory.

Imagine we can freely construct a set using any well-defined property.

Now consider the set R containing exactly those sets that do not contain themselves.

<pre><code>
R = { x | x is a set and x is not an element of x }
</code></pre>

For example, a set of numbers is not itself a number, so it would not contain itself.

Now ask:

<b>Does R contain itself?</b>

<h3>Case A: R Contains Itself</h3>

If R contains itself, then by its own definition it must not contain itself.

Contradiction.

<h3>Case B: R Does Not Contain Itself</h3>

If R does not contain itself, then by its own definition it must contain itself.

Another contradiction.

We have:

<blockquote>
R contains R if and only if R does not contain R.
</blockquote>

Russell's Paradox demonstrated that unrestricted set comprehension leads to inconsistency.

It was one of the reasons mathematicians developed more rigorous axiomatic set theories, such as Zermelo-Fraenkel set theory (ZF and ZFC), where not every property defines a set.

Notice the common pattern across these three examples:

<b>A rule is applied to something that is defined in terms of that very rule.</b>

This recurring structure is extremely important in theoretical computer science.

Now we are ready to explore the Halting Problem.

<h2>5. The Halting Problem: Can We Predict Whether a Program Will Finish?</h2>

Imagine that you are developing a tool that analyses source code.

Given any program and its input, your tool should determine whether the program will eventually terminate or run forever.

For example, consider this Python program:

<pre><code>
def program_a():
    print("Hello, World!")
</code></pre>

Clearly, this <a href="https://helloacm.com/code-is-becoming-cheaper-what-really-matters-for-programmers-in-the-ai-era/" title="Code Is Becoming Cheaper: What Really Matters for Programmers in the AI Era">program</a> terminates.

Now consider another program:

<pre><code>
def program_b():
    while True:
        pass
</code></pre>

This program runs forever.

These two examples are trivial. We can determine their behaviour just by reading the code.

But what about an arbitrary program with complex loops, recursion, dynamic inputs, and complicated conditional logic?

Can we design an algorithm that always predicts whether <b>any program, given any input</b>, will eventually terminate?

This is exactly the Halting Problem.

<h3>Formal Definition</h3>

Suppose there exists a function:

<pre><code>
halts(program, input)
</code></pre>

It returns:

<pre><code>
True   # The program eventually terminates
False  # The program runs forever
</code></pre>

Our hypothetical function must satisfy three requirements:

<ul>
<li><b>Universality:</b> It works for every valid program and every valid input in the computational model.</li>
<li><b>Correctness:</b> It always returns the correct answer.</li>
<li><b>Termination:</b> The halts function must itself terminate in finite time.</li>
</ul>

The third requirement matters enormously.

If a target program terminates, we can discover that by running it. However, if it has not terminated after an hour, a year, or a million years, how can we know whether it will run forever or simply terminate later?

The surprising result is:

<b>No such universal algorithm can exist.</b>

Alan Turing proved this mathematically in 1936.

Let's see why.

<h2>6. Proving the Halting Problem Is Undecidable</h2>

The proof uses <b>proof by contradiction</b>, also known as reductio ad absurdum.

Instead of directly proving that no universal halting checker exists, we temporarily assume one does exist.

Then we construct a program that makes this assumption logically impossible.

<h3>Step 1: Assume a Perfect Halting Checker Exists</h3>

Suppose we have a magical function named halts:

<pre><code>
def halts(program, input):
    # Always returns True if program(input)
    # eventually terminates.
    #
    # Always returns False if program(input)
    # runs forever.
    #
    # This function always terminates.
    ...
</code></pre>

We don't need to know how this function works.

We simply assume that it can correctly solve the Halting Problem for every possible program and input.

<h3>Step 2: Construct a New Program That Does the Opposite</h3>

Using the hypothetical halts function, we construct a new function called paradox.

<pre><code>
def paradox(program):
    if halts(program, program):
        while True:
            pass
    else:
        return
</code></pre>

Think carefully about what this function does.

It first asks whether the given program will terminate when executed with itself as its own input.

If halts predicts that the program terminates, paradox deliberately enters an infinite loop.

If halts predicts that the program runs forever, paradox immediately terminates.

In other words:

<b>The paradox function deliberately does the opposite of what halts predicts.</b>

Notice that self-reference appears in the call:

<pre><code>
halts(program, program)
</code></pre>

The same program is used both as the program being analysed and as its input.

This is perfectly legitimate in theoretical computation: programs can be represented as data and supplied to other programs.

<h3>Step 3: Call the Function With Itself</h3>

Now comes the crucial step.

What happens if we execute:

<pre><code>
paradox(paradox)
</code></pre>

Remember that halts is assumed to be correct for every program and input, including this one.

There are only two possible answers from the halts function.

<h3>Case A: halts(paradox, paradox) Returns True</h3>

This means halts predicts that paradox(paradox) will terminate.

But look at our implementation.

If halts returns True, paradox executes:

<pre><code>
while True:
    pass
</code></pre>

Therefore, paradox(paradox) runs forever.

The halts function predicted termination, but the program does not terminate.

<b>Our supposedly perfect halting checker is wrong.</b>

<h3>Case B: halts(paradox, paradox) Returns False</h3>

This means halts predicts that paradox(paradox) runs forever.

But if halts returns False, paradox executes:

<pre><code>
return
</code></pre>

Therefore, <a href="https://helloacm.com/the-halting-problem-and-its-paradoxical-cousins-when-logic-looks-at-itself/" title="The Halting Problem and Its Paradoxical Cousins: When Logic Looks at Itself">paradox</a>(paradox) terminates immediately.

Again, the halts function predicted nontermination, but the program terminates.

<b>Our supposedly perfect halting checker is wrong again.</b>

<h3>Step 4: The Contradiction</h3>

We can summarise both cases:

<blockquote>
If halts predicts termination, paradox runs forever.

If halts predicts nontermination, paradox terminates.
</blockquote>

The halts function must return either True or False, but both possibilities lead to a contradiction with our assumption that halts is always correct.

Therefore, our original assumption must be false.

<b>A universal, always-correct, always-terminating halting checker cannot exist.</b>

This completes the proof.

<h2>7. Why Is This Called Undecidability?</h2>

In theoretical computer science, a decision problem is a problem whose answer is either Yes or No.

A problem is called <b>decidable</b> if an algorithm exists that always terminates and correctly answers Yes or No for every valid input.

A problem is <b>undecidable</b> if no such algorithm exists.

The Halting Problem is undecidable because there is no general algorithm that can correctly determine whether every arbitrary program will terminate.

This does not mean that we cannot determine termination for any programs.

For example, we can easily prove that a program containing a fixed number of iterations will terminate, assuming its operations terminate.

We can also sometimes prove that certain programs run forever.

Compilers, static analysers, theorem provers, and formal verification tools can successfully establish termination or nontermination for many useful classes of programs.

What is impossible is constructing a single algorithm that is guaranteed to answer correctly for <b>every possible program and input</b>.

This distinction is crucial.

<b>Undecidable does not mean difficult, computationally expensive, or impossible to analyse in every individual case.</b>

It means no total, universally correct decision procedure exists.

<h2>8. Is the Halting Problem Actually a Paradox?</h2>

Strictly speaking, the Halting Problem itself is not a logical paradox.

The Halting Problem is a well-defined mathematical question, and its undecidability is a proven theorem.

The paradoxical behaviour arises when we <b>assume that a perfect universal halting checker exists</b> and then use self-reference to construct a contradiction.

This is different from claiming that computation itself is inconsistent.

The contradiction tells us that our assumption was impossible.

In this respect, the Halting Problem proof resembles the Barber Paradox.

The barber cannot exist with the specified shaving rule.

Likewise, the perfect halting checker cannot exist with the specified correctness and termination requirements.

However, there is an important technical distinction.

The barber's specification directly leads to inconsistency. The Halting Problem uses a carefully constructed algorithm to show that no computable universal checker can satisfy its specification.

This method of constructing an object that disagrees with a supposed universal procedure is called <b>diagonalisation</b>.

It is one of the most powerful techniques in mathematics and theoretical computer science.

<h2>9. Connection to Cantor's Diagonal Argument</h2>

Long before Turing's work, Georg Cantor used diagonalisation to demonstrate that the real numbers are uncountable.

Suppose someone claims to have a complete list of every real number between 0 and 1.

Cantor showed that we can construct a new real number by changing a digit along the diagonal of the list, choosing the new digits carefully to avoid ambiguity.

The resulting number must differ from the first listed number in its first digit, from the second in its second digit, and so on.

Therefore, it cannot appear anywhere on the supposedly complete list.

The list was not complete after all.

Turing's proof follows a related strategy.

We assume a universal procedure exists, then construct a program whose behaviour contradicts what that procedure predicts about it.

Cantor's argument produces a number missing from a supposedly complete list.

Turing's argument produces a program that defeats a supposedly universally correct halting checker.

In both cases, diagonalisation exposes the limits of a proposed universal description or procedure.

<h2>10. Why Can't We Just Simulate the Program?</h2>

A natural objection is:

<blockquote>
Why not simply run the program and observe whether it terminates?
</blockquote>

That works when the program eventually terminates.

But suppose a program has been running for one billion steps without terminating.

Does that mean it will never terminate?

No.

It might terminate after one billion and one steps.

Or after a trillion steps.

Or never.

For example:

<pre><code>
def very_slow_program():
    for i in range(10**100):
        pass
    return
</code></pre>

This program is finite and will eventually terminate under the idealised computational model, despite its enormous running time.

No fixed timeout can correctly distinguish every terminating program from every nonterminating program.

Simulation therefore gives us a <b>one-sided procedure</b>: if the target eventually halts, we can eventually observe that fact.

But if it runs forever, simulation alone never produces a definitive negative answer.

This is why the Halting Problem is described as <b>recognisable but not decidable</b>.

There is a procedure that eventually accepts every halting program-input pair, but no procedure that always terminates and correctly classifies every pair.

<h2>11. Could AI Solve the Halting Problem?</h2>

With advances in artificial intelligence, large language models, program synthesis, and automated reasoning, it is tempting to ask whether sufficiently intelligent AI could solve the Halting Problem.

The answer is still no, provided the AI system is itself an ordinary computable algorithm subject to the same requirements.

AI can make program analysis much more powerful.

It can recognise common infinite-loop patterns, infer program invariants, generate termination proofs, and suggest fixes for nonterminating code.

But no matter how advanced it becomes, a computable AI system cannot guarantee a correct halting decision for every arbitrary program while always terminating itself.

This is not a limitation caused by insufficient training data, model size, GPU power, or reasoning time.

<b>It is a mathematical limitation of computation.</b>

Of course, this does not prevent AI from being extremely useful in practical program <a href="https://helloacm.com/the-alien-dictionary-verification-algorithm/" title="The Alien Dictionary Verification Algorithm">verification</a>.

The impossibility concerns universal guarantees, not practical effectiveness.

<h2>12. Beyond the Halting Problem: Rice's Theorem</h2>

The Halting Problem is not an isolated curiosity.

It leads us toward an even broader result known as <b>Rice's Theorem</b>.

Informally, Rice's Theorem states that every nontrivial semantic property of the partial function computed by a program is undecidable in general.

A semantic property concerns what a program computes, rather than merely how its source code is written.

For example, consider questions such as:

<blockquote>
Does this arbitrary program compute a function that always returns zero?

Does this arbitrary program compute a function that is defined for every possible input?

Does this arbitrary program compute exactly the same function as a given reference program?
</blockquote>

These are examples of nontrivial properties of computed functions, and no universal algorithm can decide them for all programs in a Turing-complete programming language.

However, Rice's Theorem does not say that every question about a program is undecidable.

For instance, checking whether Python source code contains a particular token is a syntactic property and can be decidable.

The distinction between a program's syntax and its computed behaviour matters.

<h2>13. What Does This Mean for Software Engineering?</h2>

As software engineers, we regularly try to reason about program correctness, termination, safety, and performance.

The Halting Problem explains why certain ambitions for fully automated software verification are fundamentally impossible in the unrestricted general case.

We cannot build a universal static analyser that always terminates and perfectly predicts every possible runtime behaviour of every arbitrary program.

Instead, practical tools must make trade-offs.

Some restrict the class of programs they support.

Some return "unknown" when they cannot establish a result.

Others use conservative approximations, potentially reporting issues that cannot actually occur.

Formal verification tools may require programmers to provide invariants, contracts, termination measures, or other supporting proofs.

These approaches are not evidence of poor engineering.

They reflect the mathematical boundaries of what automated analysis can guarantee.

The lesson is that <b>restrictions, assumptions, and incomplete results can be necessary for sound program analysis</b>.

<h2>14. Final Thoughts: The Limits of Computation</h2>

The Barber Paradox, Liar Paradox, Russell's Paradox, and the Halting Problem share a fascinating theme: self-reference can expose contradictions in assumptions that initially seem perfectly reasonable.

The Barber Paradox shows that a certain seemingly simple rule cannot describe an existing barber.

The Liar Paradox challenges straightforward assignments of truth and falsehood to self-referential statements.

Russell's Paradox demonstrates why unrestricted set construction is inconsistent.

The Halting Problem takes self-reference into the world of algorithms and establishes a fundamental limit on what computers can decide.

What makes Turing's result remarkable is its universality.

It applies not just to Python or C++, but to any Turing-complete programming language and every ordinary computational system implementing the same general model of computation.

Even an infinitely fast computer would not make the Halting Problem decidable. The impossibility is not about running out of time; it is about the nonexistence of an algorithm satisfying the specification.

The central insight can be expressed in one sentence:

<blockquote>
If a universal algorithm could always predict whether any program halts, we could construct a program that deliberately contradicts its prediction.
</blockquote>

And that is why the Halting Problem is undecidable.

Sometimes, the most profound discovery in computer science is not finding a better algorithm.

It is proving that the algorithm we are searching for <b>cannot possibly exist</b>.

<h2>References and Further Reading</h2>

<ul>
<li><a href="https://en.wikipedia.org/wiki/Halting_problem">The Halting Problem — Wikipedia</a></li>
<li><a href="https://en.wikipedia.org/wiki/Barber_paradox">The Barber Paradox — Wikipedia</a></li>
<li><a href="https://en.wikipedia.org/wiki/Liar_paradox">The Liar Paradox — Wikipedia</a></li>
<li><a href="https://en.wikipedia.org/wiki/Russell%27s_paradox">Russell's Paradox — Wikipedia</a></li>
<li><a href="https://en.wikipedia.org/wiki/Diagonal_argument">Diagonal Argument — Wikipedia</a></li>
<li><a href="https://en.wikipedia.org/wiki/Rice%27s_theorem">Rice's Theorem — Wikipedia</a></li>
<li><a href="https://doi.org/10.1112/plms/s2-42.1.230">Alan Turing (1936), On Computable Numbers, with an Application to the Entscheidungsproblem</a></li>
</ul>

[show_posts keyword="Paradox"]

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/compute-gcd-in-bash-with-input-validation/" rel="bookmark" title="Compute GCD in Bash with Input Validation">Compute GCD in Bash with Input Validation</a> <small>GCD Computation in Bash What is GCD? GCD stands for Greatest Common Divisor. It is...</small></li>
<li><a href="https://helloacm.com/usb-otg-on-the-go/" rel="bookmark" title="USB OTG (On The Go)">USB OTG (On The Go)</a> <small>USB OTG (On The Go) allows some USB devices to act as both master and...</small></li>
<li><a href="https://helloacm.com/a-google-alert-woke-me-up-postmortem-of-a-wordpress-security-incident/" rel="bookmark" title="A Google Alert Woke Me Up: Postmortem of a WordPress Security Incident">A Google Alert Woke Me Up: Postmortem of a WordPress Security Incident</a> <small>An unpatched WordPress and plugin vulnerability apparently exposed a Cloudflare credential stored in the database....</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-form-smallest-number-from-two-digit-arrays/" rel="bookmark" title="Teaching Kids Programming &#8211; Form Smallest Number From Two Digit Arrays (Set Intersection)">Teaching Kids Programming &#8211; Form Smallest Number From Two Digit Arrays (Set Intersection)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms Given two arrays of unique digits...</small></li>
<li><a href="https://helloacm.com/tutorial-example-how-to-access-microsoft-excel-chart-using-the-windows-scripting-host-jscript/" rel="bookmark" title="Tutorial Example: How to Access Microsoft Excel (Chart) using the Windows Scripting Host (JScript)">Tutorial Example: How to Access Microsoft Excel (Chart) using the Windows Scripting Host (JScript)</a> <small>WSH (Window Scripting Host) is a powerful and handy scripting environment. It is installed by...</small></li>
<li><a href="https://helloacm.com/hot-weather-causes-intel-cpu-throttle-and-nvidia-gpu-crashes-on-windows-11-blue-screen/" rel="bookmark" title="Hot Weather Causes Intel CPU Throttle and NVidia GPU Crashes on Windows 11 (Blue Screen)">Hot Weather Causes Intel CPU Throttle and NVidia GPU Crashes on Windows 11 (Blue Screen)</a> <small>My Microsoft Surface Laptop Studio 2 becomes extremely laggy, slow, and nearly unusable in hot...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-design-a-hash-table/" rel="bookmark" title="Teaching Kids Programming &#8211; Design a Hash Table">Teaching Kids Programming &#8211; Design a Hash Table</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms Design a HashMap without using any...</small></li>
<li><a href="https://helloacm.com/recursive-depth-first-search-algorithm-to-compute-the-sum-of-nodes-with-even-valued-grandparent-in-a-binary-tree/" rel="bookmark" title="Recursive Depth First Search Algorithm to Compute the Sum of Nodes with Even-Valued Grandparent in a Binary Tree">Recursive Depth First Search Algorithm to Compute the Sum of Nodes with Even-Valued Grandparent in a Binary Tree</a> <small>Given a binary tree, return the sum of values of nodes with even-valued grandparent. (A...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://helloacm.com/teaching-kids-programming-the-halting-problem-paradoxes-self-reference-and-why-some-problems-are-impossible-to-solve/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Split a Photo into a 3×3 Grid with iPhone Shortcuts: Build, Install, Share and Recreate It in Python</title>
		<link>https://helloacm.com/split-a-photo-into-a-3x3-grid-with-iphone-shortcuts-build-install-share-and-recreate-it-in-python/</link>
					<comments>https://helloacm.com/split-a-photo-into-a-3x3-grid-with-iphone-shortcuts-build-install-share-and-recreate-it-in-python/#respond</comments>
		
		<dc:creator><![CDATA[ACMer]]></dc:creator>
		<pubDate>Mon, 21 Sep 2026 14:04:11 +0000</pubDate>
				<category><![CDATA[iOS]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[shortcut]]></category>
		<category><![CDATA[3x3 photo grid]]></category>
		<category><![CDATA[Apple Shortcuts]]></category>
		<category><![CDATA[Crop Image]]></category>
		<category><![CDATA[Cut Picture into Grid]]></category>
		<category><![CDATA[iCloud Shortcut]]></category>
		<category><![CDATA[image splitter]]></category>
		<category><![CDATA[iOS automation]]></category>
		<category><![CDATA[iOS Shortcuts]]></category>
		<category><![CDATA[iPhone image processing]]></category>
		<category><![CDATA[iPhone Shortcuts]]></category>
		<category><![CDATA[nine grid image]]></category>
		<category><![CDATA[photo grid]]></category>
		<category><![CDATA[Pillow]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[Python image processing]]></category>
		<category><![CDATA[Share Sheet]]></category>
		<category><![CDATA[shortcut file]]></category>
		<guid isPermaLink="false">https://helloacm.com/?p=158151</guid>

					<description><![CDATA[<blockquote>
You do not need a third-party app to split a photo into a nine-image grid on an iPhone. This post shows how to build an Image Nine-Grid shortcut from scratch, accept photos from the Share Sheet or Photos app, split the original image directly into a 3×3 grid without cropping away any content, and save the results. It also explains the .shortcut file format, iCloud sharing, the complete workflow, and an equivalent Python implementation using Pillow.
</blockquote>

Recently I played around with Apple’s built-in Shortcuts app and created a small but useful tool: automatically split one photo into a 3×3 grid of nine smaller images.

In other words, it creates the classic nine-grid layout that is commonly used on social media.

In the past, when I needed this, my first instinct was usually to search the App Store for a nine-grid app, or find an online tool, <a href="https://helloacm.com/hardening-wordpress-disable-php-execution-in-wp-content-uploads/" title="Hardening WordPress: Disable PHP Execution in `wp-content/uploads`">upload the image</a>, split it, and then download the result.

But that is actually unnecessary.

The built-in Shortcuts app on iPhone can do the whole thing.

Once the shortcut has been created, using it is basically:

<strong>Select a photo → Run the shortcut → Automatically get nine images.</strong>

No third-party app is required, and there is no need to upload the photo to any website.

<h2>Download / Install the “Image Nine-Grid” Shortcut</h2>

If you do not want to build the shortcut from scratch, you can directly install the version I created:

<ul>
<li><a href="https://www.icloud.com/shortcuts/ec1b6c3cafd74fef8d48fa88ed24928b" target="_blank" rel="noopener" title="Click here to install: Image Nine-Grid (iCloud)">Click here to install: Image Nine-Grid (iCloud)</a></li>
<li><a href="https://helloacm.com/static/ios-shortcut-picture-cut-into-grid.shortcut" title="Local Download - iOS Shortcut to Cut a Picture into 3x3">Local Download - iOS Shortcut to Cut a Picture into 3x3</a></li>
</ul>

Open the link on an iPhone or iPad.

It will open Apple’s Shortcuts page, where you can add the shortcut to your own Shortcuts library.

After installation, “Image Nine-Grid” will appear in your list of shortcuts.

[caption id="attachment_158154" align="alignnone" width="1905"]<a href="https://helloacm.com/split-a-photo-into-a-3x3-grid-with-iphone-shortcuts-build-install-share-and-recreate-it-in-python/screenshot-2/" rel="attachment wp-att-158154"><img src="https://helloacm.com/wp-content/uploads/2026/09/cut-picture-iphone-shortcut-scaled.jpg" alt="Cut a Picture into 3x3 grid on iphone using shortcut." width="1905" height="2048" class="size-full wp-image-158154" /></a> Cut a Picture into a 3×3 grid on iPhone using Shortcuts.[/caption]

<h3>You Can Also Share a .shortcut File Directly</h3>

iOS Shortcuts can also be exported as files with the extension:

<pre><code>.shortcut</code></pre>

So in addition to the iCloud link above, I can also host the exported file:

<pre><code>Image Nine-Grid.shortcut</code></pre>

on my own server and let people download it directly.

However, for a public blog post, I personally prefer using Apple’s iCloud Shortcut link.

The installation process is more natural, and Apple handles the shortcut signing and verification process.

<h2>What Exactly Is a .shortcut File?</h2>

This is actually quite interesting.

At first, I assumed a .shortcut file might just be XML, JSON, or a normal property list.

Modern exported shortcut files are more complicated than that.

I inspected the shortcut file exported from my iPhone, and the beginning of the file contains:

<pre><code>AEA1</code></pre>

It is essentially an Apple-signed archive.

In simplified form, the structure looks roughly like this:

<pre><code>.shortcut
│
└── AEA1 Signed Archive
    │
    └── Apple Archive
        │
        └── Shortcut.wflow
            │
            └── Binary Property List
                │
                ├── Workflow metadata
                ├── Shortcut icon
                ├── Input / output types
                └── WFWorkflowActions
                    └── Individual shortcut actions
</code></pre>

The shortcut I exported is only around 26 KB, but it already contains the complete workflow together with Apple’s signing <a href="https://helloacm.com/how-to-get-free-https-certificates-via-acme-sh/" title="How to Get Free HTTPS Certificates via acme.sh?">certificate</a> chain.

This is also why it is not a good idea to modify a .shortcut file directly with a text editor or hex editor.

Even if the underlying workflow can be extracted and parsed, modifying the signed exported file would invalidate its signature.

<h2>What Does This Shortcut Actually Do?</h2>

The goal is very simple.

Suppose we have one original photo:

<pre><code>┌─────────────────┐
│                 │
│                 │
│   Original      │
│     Photo       │
│                 │
│                 │
└─────────────────┘</code></pre>

The shortcut directly divides the original image into three columns and three rows:

<pre><code>┌─────┬─────┬─────┐
│  1  │  2  │  3  │
├─────┼─────┼─────┤
│  4  │  5  │  6  │
├─────┼─────┼─────┤
│  7  │  8  │  9  │
└─────┴─────┴─────┘</code></pre>

There is an important distinction here:

<strong>A 3×3 grid does not mean that each tile must be square.</strong>

It simply means dividing the original image into three equal columns and three equal rows.

For example, if the original image is:

<pre><code>4032 × 3024</code></pre>

then each tile is approximately:

<pre><code>1344 × 1008</code></pre>

There is no need to crop the original image into a square first.

That would unnecessarily remove content from the left and right sides, or from the top and bottom, depending on the original orientation.

Finally, all nine images are saved back to the Photos library.

<h2>Creating the “Image Nine-Grid” Shortcut from Scratch</h2>

Here is how to build the whole shortcut from the beginning.

<h3>Step 1: Create a New Shortcut</h3>

Open:

<pre><code>Shortcuts
→ All Shortcuts
→ +
</code></pre>

Create a new shortcut.

I named mine:

<pre><code>Image Nine-Grid</code></pre>

Of course, the name can be anything you like.

<h3>Step 2: Support Two Ways of Providing the Image</h3>

I want the shortcut to support two different ways of receiving an image.

The first way is:

<pre><code>Open Shortcuts
→ Tap “Image Nine-Grid”
→ Select Photo</code></pre>

The second way is more convenient:

<pre><code>Photos
→ Select a photo
→ Share
→ Image Nine-Grid</code></pre>

Therefore, configure the shortcut so that it can receive:

<strong>Images</strong>

from the:

<strong>Share Sheet</strong>

Then check whether an image has already been passed into the shortcut.

The beginning of the shortcut looks roughly like this:

<pre><code>Receive Images from Share Sheet

If Shortcut Input has any value

    Set variable img to Shortcut Input

Otherwise

    Select Photos

    Set variable img to Photos

End If</code></pre>

<!-- Insert screenshot of the input condition here -->

This is really just the same logic we would normally write in code:

<pre><code>if shortcut_input:
    img = shortcut_input
else:
    img = select_photo()</code></pre>

After that, the rest of the workflow does not need to care where the image came from.

Everything simply works with:

<pre><code>img</code></pre>

<h2>Step 3: Get the Image Width and Height</h2>

Next, add:

<strong>Get Details of Images</strong>

Retrieve:

<pre><code>Width
Height</code></pre>

For example, an iPhone photo might be:

<pre><code>4032 × 3024</code></pre>

We do not need to crop the image into a square.

Instead, because the image will be divided into three columns and three rows, calculate the width and height of each tile separately:

<pre><code>tileWidth = Width / 3
tileHeight = Height / 3</code></pre>

For example:

<pre><code>Width = 4032
Height = 3024

tileWidth = 4032 / 3
          = 1344

tileHeight = 3024 / 3
           = 1008</code></pre>

So each tile will be:

<pre><code>1344 × 1008</code></pre>

This preserves the entire original image.

Because both the width and height are scaled by the same factor of three, each tile also has the same aspect ratio as the original image.

<h2>Step 4: Calculate the Position of All Nine Images</h2>

Image coordinates begin from the top-left corner:

<pre><code>(0, 0)</code></pre>

X increases to the right, while Y increases downward.

We now have two dimensions:

<pre><code>tileWidth
tileHeight</code></pre>

So the positions of the nine images are:

<table>
<thead>
<tr>
<th>Image</th>
<th>X</th>
<th>Y</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>0</td>
<td>0</td>
</tr>
<tr>
<td>2</td>
<td>tileWidth</td>
<td>0</td>
</tr>
<tr>
<td>3</td>
<td>2 × tileWidth</td>
<td>0</td>
</tr>
<tr>
<td>4</td>
<td>0</td>
<td>tileHeight</td>
</tr>
<tr>
<td>5</td>
<td>tileWidth</td>
<td>tileHeight</td>
</tr>
<tr>
<td>6</td>
<td>2 × tileWidth</td>
<td>tileHeight</td>
</tr>
<tr>
<td>7</td>
<td>0</td>
<td>2 × tileHeight</td>
</tr>
<tr>
<td>8</td>
<td>tileWidth</td>
<td>2 × tileHeight</td>
</tr>
<tr>
<td>9</td>
<td>2 × tileWidth</td>
<td>2 × tileHeight</td>
</tr>
</tbody>
</table>

Then use:

<strong>Crop Image</strong>

Set:

<pre><code>Position = Custom</code></pre>

Set Width to:

<pre><code>tileWidth</code></pre>

and Height to:

<pre><code>tileHeight</code></pre>

Then use the corresponding X and Y coordinates calculated above.

<h2>A Cleaner Version: Use Two Repeat Loops</h2>

Of course, you could create nine separate Crop Image actions.

But from a programmer’s point of view, that is rather repetitive.

A cleaner implementation uses two loops:

<pre><code>for row in range(3):
    for col in range(3):
        x = col * tileWidth
        y = row * tileHeight

        crop(
            x=x,
            y=y,
            width=tileWidth,
            height=tileHeight
        )</code></pre>

Shortcuts can implement the same idea using:

<strong>Repeat</strong>

The outer loop:

<pre><code>Repeat 3 Times</code></pre>

represents the row.

Calculate:

<pre><code>row = Repeat Index - 1</code></pre>

Then inside it, add another:

<pre><code>Repeat 3 Times</code></pre>

for the column.

Calculate:

<pre><code>column = Repeat Index - 1

X = column × tileWidth
Y = row × tileHeight</code></pre>

Then:

<pre><code>Crop img

Position = Custom
X Coordinate = X
Y Coordinate = Y
Width = tileWidth
Height = tileHeight</code></pre>

Add each cropped image to:

<pre><code>gridImages</code></pre>

After both loops complete:

<pre><code>gridImages</code></pre>

contains exactly nine images.

<h2>Step 5: Save the Nine Images</h2>

Finally add:

<strong>Save to Photo Album</strong>

Use:

<pre><code>gridImages</code></pre>

as the input.

The shortcut is now complete.

<h2>Complete Shortcut Command Flow</h2>

If the whole shortcut is expanded into a sequential command flow, it looks roughly like this:

<pre><code>1. Receive Images from Share Sheet


2. If Shortcut Input has any value

       Set variable img = Shortcut Input

   Otherwise

       Select Photos
       Set variable img = Photos

   End If


3. Get Width of img

       → width


4. Get Height of img

       → height


5. Calculate

       tileWidth = width / 3


6. Calculate

       tileHeight = height / 3


7. Repeat 3 Times

       row = Repeat Index - 1

       Repeat 3 Times

           column = Repeat Index - 1

           X = column × tileWidth
           Y = row × tileHeight

           Crop img

               Position = Custom
               X Coordinate = X
               Y Coordinate = Y
               Width = tileWidth
               Height = tileHeight

           Add cropped result to gridImages

       End Repeat

   End Repeat


8. Save gridImages to Photo Album</code></pre>

From a software engineering point of view, this is already a fairly standard small program.

It contains:

<ul>
<li>Input</li>
<li>Variables</li>
<li>If / Else</li>
<li>Nested Loops</li>
<li>Arithmetic</li>
<li>Coordinate Calculations</li>
<li>Image Processing</li>
<li>Output</li>
</ul>

Apple simply represents these programming concepts as visual actions that can be dragged around.

<h2>What Would the Same Thing Look Like in Python?</h2>

The core algorithm behind the shortcut is actually easier to understand when written in Python.

Install Pillow first:

<pre><code>pip install pillow</code></pre>

Then:

<pre><code>from pathlib import Path
from PIL import Image, ImageOps


def make_nine_grid(input_file: str, output_dir: str = "nine_grid"):
    input_path = Path(input_file)
    output_path = Path(output_dir)

    output_path.mkdir(parents=True, exist_ok=True)

    # Open the image
    image = Image.open(input_path)

    # Correct orientation using EXIF metadata
    image = ImageOps.exif_transpose(image)

    width, height = image.size

    # -------------------------
    # Step 1: Calculate 3 × 3 boundaries
    # -------------------------
    #
    # Divide the width into three columns
    # and the height into three rows.
    #
    # There is no need to crop the source
    # image into a square first.
    #
    # Calculating boundaries this way also
    # handles dimensions that are not exactly
    # divisible by 3 without losing pixels.
    #

    x = [
        0,
        width // 3,
        width * 2 // 3,
        width,
    ]

    y = [
        0,
        height // 3,
        height * 2 // 3,
        height,
    ]

    # -------------------------
    # Step 2: Crop into nine images
    # -------------------------

    index = 1

    for row in range(3):
        for col in range(3):

            box = (
                x[col],
                y[row],
                x[col + 1],
                y[row + 1],
            )

            tile = image.crop(box)

            filename = output_path / f"grid_{index:02}.png"

            tile.save(filename)

            print(
                f"{index}: "
                f"row={row}, "
                f"col={col}, "
                f"box={box}, "
                f"size={tile.size}"
            )

            index += 1


if __name__ == "__main__":
    make_nine_grid(
        "photo.jpg",
        "nine_grid",
    )</code></pre>

Run:

<pre><code>python nine_grid.py</code></pre>

The output directory will contain:

<pre><code>nine_grid/
├── grid_01.png
├── grid_02.png
├── grid_03.png
├── grid_04.png
├── grid_05.png
├── grid_06.png
├── grid_07.png
├── grid_08.png
└── grid_09.png</code></pre>

<h2>One Small but Important Detail in the Python Version</h2>

If the image dimensions are exactly divisible by three, for example:

<pre><code>4032 × 3024</code></pre>

then everything is simple:

<pre><code>4032 / 3 = 1344
3024 / 3 = 1008</code></pre>

Each tile will be exactly:

<pre><code>1344 × 1008</code></pre>

But not every image dimension is divisible by three.

Suppose the source image is:

<pre><code>4033 × 3025</code></pre>

Then:

<pre><code>4033 / 3 = 1344.333...
3025 / 3 = 1008.333...</code></pre>

Obviously, an image cannot contain:

<pre><code>0.333 pixels</code></pre>

If we simply use:

<pre><code>tileWidth = width // 3
tileHeight = height // 3</code></pre>

we get:

<pre><code>tileWidth = 1344
tileHeight = 1008</code></pre>

But then:

<pre><code>1344 × 3 = 4032
1008 × 3 = 3024</code></pre>

One column of pixels on the right and one row of pixels at the bottom would be left unused.

That is why the Python version calculates four X boundaries:

<pre><code>x0 = 0
x1 = width // 3
x2 = width * 2 // 3
x3 = width</code></pre>

and four Y boundaries:

<pre><code>y0 = 0
y1 = height // 3
y2 = height * 2 // 3
y3 = height</code></pre>

For example, with:

<pre><code>width = 4033</code></pre>

the X boundaries are:

<pre><code>0
1344
2688
4033</code></pre>

So the three horizontal sections are:

<pre><code>0    → 1344
1344 → 2688
2688 → 4033</code></pre>

The final tile may be one pixel wider than the others, but no source pixels are lost.

The same logic applies to the height.

The important property is not that every tile must have exactly the same integer dimensions.

It is that:

<strong>The complete source image is divided continuously into a 3×3 grid with no missing or overlapping pixels.</strong>

<h2>Why Is There No Need to Crop the Image into a Square?</h2>

This is an easy misconception to make:

<strong>A nine-grid image does not mean nine square images.</strong>

A 3×3 grid simply means:

<pre><code>3 Columns × 3 Rows</code></pre>

If the original photo is:

<pre><code>4032 × 3024</code></pre>

its aspect ratio is:

<pre><code>4 : 3</code></pre>

After splitting it into a 3×3 grid, each tile is approximately:

<pre><code>1344 × 1008</code></pre>

which is still:

<pre><code>4 : 3</code></pre>

That is exactly what we want.

Both dimensions have been divided by three, so each tile preserves the original image’s aspect ratio.

If we first cropped:

<pre><code>4032 × 3024</code></pre>

into:

<pre><code>3024 × 3024</code></pre>

we would throw away:

<pre><code>4032 - 3024
= 1008 pixels</code></pre>

from the horizontal dimension.

That could easily remove people, scenery, or other important content near the edges of the photo.

The correct approach is therefore:

<strong>Keep the original image and divide its width and height independently into three parts.</strong>

<h2>How Do I Use the Shortcut?</h2>

Once the shortcut has been created, there is normally no need to open the Shortcut editor again.

The simplest method is:

<pre><code>Shortcuts
→ Image Nine-Grid
→ Select Photo</code></pre>

The nine generated images will then be saved to Photos.

I personally prefer running it directly from the Photos app:

<pre><code>Photos
→ Open a photo
→ Share
→ Image Nine-Grid</code></pre>

The selected <a href="https://helloacm.com/chatgpt-image-2-0-casual-selfie-of-me/" title="ChatGPT Image 2.0 – Casual Selfie of Me">image</a> is passed directly into the shortcut as:

<pre><code>Shortcut Input</code></pre>

so there is no need to select the image again.

<h2>Why I Prefer a Shortcut Instead of a Nine-Grid App</h2>

There are obviously many nine-grid apps available in the App Store.

But for such a simple task, installing another dedicated app feels unnecessary.

Creating my own shortcut has several advantages.

First, there are no advertisements, subscriptions, VIP memberships, or limits such as “three free images per day”.

Second, the photo does not need to be uploaded to some unknown website.

Most importantly, once the shortcut is built, it becomes a small tool that I completely control.

And it is very easy to modify.

For example, changing:

<pre><code>3 × 3</code></pre>

to:

<pre><code>2 × 2</code></pre>

creates a four-image grid.

Changing it to:

<pre><code>4 × 4</code></pre>

creates sixteen images.

You could even ask for a number at the beginning:

<pre><code>Ask for Input

Enter N:</code></pre>

Then calculate:

<pre><code>tileWidth = width / N
tileHeight = height / N</code></pre>

and change the loops to:

<pre><code>for row in range(N):
    for col in range(N):</code></pre>

For a more robust Python implementation, calculate the boundaries directly:

<pre><code>x[i] = width * i // N
y[i] = height * i // N</code></pre>

where:

<pre><code>i = 0, 1, 2, ..., N</code></pre>

This ensures that every source pixel is included even when the width or height is not exactly divisible by N.

At that point, it is no longer just a nine-grid shortcut.

It becomes a general-purpose:

<strong>N × N image splitter.</strong>

<h2>Shortcuts Is Really a Form of Programming</h2>

I used to think of Apple Shortcuts mainly as a simple automation tool.

After building a few shortcuts myself, I realized that it is actually very similar to normal programming.

This nine-grid shortcut already involves:

<pre><code>Input
Variables
If / Else
Loops
Nested Loops
Arithmetic
Coordinates
Image Processing
Output</code></pre>

It even contains a typical two-dimensional coordinate problem.

The underlying algorithm is essentially:

<pre><code>for row in range(3):
    for col in range(3):

        left   = width * col // 3
        right  = width * (col + 1) // 3

        top    = height * row // 3
        bottom = height * (row + 1) // 3

        crop(
            left,
            top,
            right,
            bottom,
        )</code></pre>

The same task can probably be implemented in a few dozen lines of Python, but the advantage of Shortcuts is that once the workflow is built, it immediately becomes a reusable tool on the iPhone.

Whenever I need a nine-grid image, I simply use:

<pre><code>Photos
→ Share
→ Image Nine-Grid</code></pre>

A few seconds later, all nine images are already in the Photos library.

For many small tasks like this, there is really no need to install another app.

The iPhone already includes a surprisingly capable automation and visual programming environment.

[show_file file="/var/www/wp-post-common/helloacm.com/ios.php"]

[show_posts keyword="iphone"]

BTW: I've vibe-coded a simple online tool to split an image into a grid: <a title="Split a picture into a precise grid, preview every tile, and download one ZIP. Your image never leaves this device." href="https://doctorlai-msrc.github.io/cut-picture/">Split a picture into a precise grid, preview every tile, and download one ZIP. Your image never leaves this device.</a>

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/planning-to-update-your-website-for-2020-read-this/" rel="bookmark" title="Planning To Update Your Website For 2020? Read This.">Planning To Update Your Website For 2020? Read This.</a> <small>Looking to update your website for 2020? If so, it&#8217;s important to be aware of...</small></li>
<li><a href="https://helloacm.com/the-powerful-remote-cloud-desktop-by-railway-up-visual-studio-code-everywhere/" rel="bookmark" title="The Powerful Remote Cloud Desktop by Railway.Up (Visual Studio Code Everywhere)">The Powerful Remote Cloud Desktop by Railway.Up (Visual Studio Code Everywhere)</a> <small>Although, Railway.Up is ending their free $5 plan monthly soon, you can still benefit it...</small></li>
<li><a href="https://helloacm.com/algorithms-to-shift-a-2d-grid-matrix-in-place/" rel="bookmark" title="Algorithms to Shift a 2D Grid/Matrix In-Place">Algorithms to Shift a 2D Grid/Matrix In-Place</a> <small>Given a 2D grid of size n * m and an integer k. You need...</small></li>
<li><a href="https://helloacm.com/why-does-the-exchange-force-liquidation-when-the-margin-is-low/" rel="bookmark" title="Why does the exchange force liquidation when the margin is low?">Why does the exchange force liquidation when the margin is low?</a> <small>In the cryptocurrency market, as long as you don&#8217;t trade contracts, the risk is not...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-geometry-of-triangle-area-and-side-law/" rel="bookmark" title="Teaching Kids Programming &#8211; Geometry of Triangle Area and Side Law">Teaching Kids Programming &#8211; Geometry of Triangle Area and Side Law</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms We know the area of triangle...</small></li>
<li><a href="https://helloacm.com/on-waiting-list-of-chatgpt-4-api/" rel="bookmark" title="On Waiting List of ChatGPT 4 API">On Waiting List of ChatGPT 4 API</a> <small>As of today, The ChatGPT-4 API Access is not yet available but we can request...</small></li>
<li><a href="https://helloacm.com/how-to-transfer-bts-assets-on-bitshares-blockchain-using-node-js/" rel="bookmark" title="How to Transfer BTS Assets on BitShares Blockchain using Node.Js?">How to Transfer BTS Assets on BitShares Blockchain using Node.Js?</a> <small>Node/Javascript Function to Transfer BTS Assets on BitShares Blockchain To make a transfer on the...</small></li>
<li><a href="https://helloacm.com/greedy-algorithm-to-find-the-lexicographically-smallest-sequences-after-at-most-k-element-swaps/" rel="bookmark" title="Greedy Algorithm to Find the Lexicographically Smallest Sequences After At Most K Element Swaps">Greedy Algorithm to Find the Lexicographically Smallest Sequences After At Most K Element Swaps</a> <small>Given a sequence of n integers arr, determine the lexicographically smallest sequence which may be...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<blockquote>
You do not need a third-party app to split a photo into a nine-image grid on an iPhone. This post shows how to build an Image Nine-Grid shortcut from scratch, accept photos from the Share Sheet or Photos app, split the original image directly into a 3×3 grid without cropping away any content, and save the results. It also explains the .shortcut file format, iCloud sharing, the complete workflow, and an equivalent Python implementation using Pillow.
</blockquote>

Recently I played around with Apple’s built-in Shortcuts app and created a small but useful tool: automatically split one photo into a 3×3 grid of nine smaller images.

In other words, it creates the classic nine-grid layout that is commonly used on social media.

In the past, when I needed this, my first instinct was usually to search the App Store for a nine-grid app, or find an online tool, <a href="https://helloacm.com/hardening-wordpress-disable-php-execution-in-wp-content-uploads/" title="Hardening WordPress: Disable PHP Execution in `wp-content/uploads`">upload the image</a>, split it, and then download the result.

But that is actually unnecessary.

The built-in Shortcuts app on iPhone can do the whole thing.

Once the shortcut has been created, using it is basically:

<strong>Select a photo → Run the shortcut → Automatically get nine images.</strong>

No third-party app is required, and there is no need to upload the photo to any website.

<h2>Download / Install the “Image Nine-Grid” Shortcut</h2>

If you do not want to build the shortcut from scratch, you can directly install the version I created:

<ul>
<li><a href="https://www.icloud.com/shortcuts/ec1b6c3cafd74fef8d48fa88ed24928b" target="_blank" rel="noopener" title="Click here to install: Image Nine-Grid (iCloud)">Click here to install: Image Nine-Grid (iCloud)</a></li>
<li><a href="https://helloacm.com/static/ios-shortcut-picture-cut-into-grid.shortcut" title="Local Download - iOS Shortcut to Cut a Picture into 3x3">Local Download - iOS Shortcut to Cut a Picture into 3x3</a></li>
</ul>

Open the link on an iPhone or iPad.

It will open Apple’s Shortcuts page, where you can add the shortcut to your own Shortcuts library.

After installation, “Image Nine-Grid” will appear in your list of shortcuts.

[caption id="attachment_158154" align="alignnone" width="1905"]<a href="https://helloacm.com/split-a-photo-into-a-3x3-grid-with-iphone-shortcuts-build-install-share-and-recreate-it-in-python/screenshot-2/" rel="attachment wp-att-158154"><img src="https://helloacm.com/wp-content/uploads/2026/09/cut-picture-iphone-shortcut-scaled.jpg" alt="Cut a Picture into 3x3 grid on iphone using shortcut." width="1905" height="2048" class="size-full wp-image-158154" /></a> Cut a Picture into a 3×3 grid on iPhone using Shortcuts.[/caption]

<h3>You Can Also Share a .shortcut File Directly</h3>

iOS Shortcuts can also be exported as files with the extension:

<pre><code>.shortcut</code></pre>

So in addition to the iCloud link above, I can also host the exported file:

<pre><code>Image Nine-Grid.shortcut</code></pre>

on my own server and let people download it directly.

However, for a public blog post, I personally prefer using Apple’s iCloud Shortcut link.

The installation process is more natural, and Apple handles the shortcut signing and verification process.

<h2>What Exactly Is a .shortcut File?</h2>

This is actually quite interesting.

At first, I assumed a .shortcut file might just be XML, JSON, or a normal property list.

Modern exported shortcut files are more complicated than that.

I inspected the shortcut file exported from my iPhone, and the beginning of the file contains:

<pre><code>AEA1</code></pre>

It is essentially an Apple-signed archive.

In simplified form, the structure looks roughly like this:

<pre><code>.shortcut
│
└── AEA1 Signed Archive
    │
    └── Apple Archive
        │
        └── Shortcut.wflow
            │
            └── Binary Property List
                │
                ├── Workflow metadata
                ├── Shortcut icon
                ├── Input / output types
                └── WFWorkflowActions
                    └── Individual shortcut actions
</code></pre>

The shortcut I exported is only around 26 KB, but it already contains the complete workflow together with Apple’s signing <a href="https://helloacm.com/how-to-get-free-https-certificates-via-acme-sh/" title="How to Get Free HTTPS Certificates via acme.sh?">certificate</a> chain.

This is also why it is not a good idea to modify a .shortcut file directly with a text editor or hex editor.

Even if the underlying workflow can be extracted and parsed, modifying the signed exported file would invalidate its signature.

<h2>What Does This Shortcut Actually Do?</h2>

The goal is very simple.

Suppose we have one original photo:

<pre><code>┌─────────────────┐
│                 │
│                 │
│   Original      │
│     Photo       │
│                 │
│                 │
└─────────────────┘</code></pre>

The shortcut directly divides the original image into three columns and three rows:

<pre><code>┌─────┬─────┬─────┐
│  1  │  2  │  3  │
├─────┼─────┼─────┤
│  4  │  5  │  6  │
├─────┼─────┼─────┤
│  7  │  8  │  9  │
└─────┴─────┴─────┘</code></pre>

There is an important distinction here:

<strong>A 3×3 grid does not mean that each tile must be square.</strong>

It simply means dividing the original image into three equal columns and three equal rows.

For example, if the original image is:

<pre><code>4032 × 3024</code></pre>

then each tile is approximately:

<pre><code>1344 × 1008</code></pre>

There is no need to crop the original image into a square first.

That would unnecessarily remove content from the left and right sides, or from the top and bottom, depending on the original orientation.

Finally, all nine images are saved back to the Photos library.

<h2>Creating the “Image Nine-Grid” Shortcut from Scratch</h2>

Here is how to build the whole shortcut from the beginning.

<h3>Step 1: Create a New Shortcut</h3>

Open:

<pre><code>Shortcuts
→ All Shortcuts
→ +
</code></pre>

Create a new shortcut.

I named mine:

<pre><code>Image Nine-Grid</code></pre>

Of course, the name can be anything you like.

<h3>Step 2: Support Two Ways of Providing the Image</h3>

I want the shortcut to support two different ways of receiving an image.

The first way is:

<pre><code>Open Shortcuts
→ Tap “Image Nine-Grid”
→ Select Photo</code></pre>

The second way is more convenient:

<pre><code>Photos
→ Select a photo
→ Share
→ Image Nine-Grid</code></pre>

Therefore, configure the shortcut so that it can receive:

<strong>Images</strong>

from the:

<strong>Share Sheet</strong>

Then check whether an image has already been passed into the shortcut.

The beginning of the shortcut looks roughly like this:

<pre><code>Receive Images from Share Sheet

If Shortcut Input has any value

    Set variable img to Shortcut Input

Otherwise

    Select Photos

    Set variable img to Photos

End If</code></pre>

<!-- Insert screenshot of the input condition here -->

This is really just the same logic we would normally write in code:

<pre><code>if shortcut_input:
    img = shortcut_input
else:
    img = select_photo()</code></pre>

After that, the rest of the workflow does not need to care where the image came from.

Everything simply works with:

<pre><code>img</code></pre>

<h2>Step 3: Get the Image Width and Height</h2>

Next, add:

<strong>Get Details of Images</strong>

Retrieve:

<pre><code>Width
Height</code></pre>

For example, an iPhone photo might be:

<pre><code>4032 × 3024</code></pre>

We do not need to crop the image into a square.

Instead, because the image will be divided into three columns and three rows, calculate the width and height of each tile separately:

<pre><code>tileWidth = Width / 3
tileHeight = Height / 3</code></pre>

For example:

<pre><code>Width = 4032
Height = 3024

tileWidth = 4032 / 3
          = 1344

tileHeight = 3024 / 3
           = 1008</code></pre>

So each tile will be:

<pre><code>1344 × 1008</code></pre>

This preserves the entire original image.

Because both the width and height are scaled by the same factor of three, each tile also has the same aspect ratio as the original image.

<h2>Step 4: Calculate the Position of All Nine Images</h2>

Image coordinates begin from the top-left corner:

<pre><code>(0, 0)</code></pre>

X increases to the right, while Y increases downward.

We now have two dimensions:

<pre><code>tileWidth
tileHeight</code></pre>

So the positions of the nine images are:

<table>
<thead>
<tr>
<th>Image</th>
<th>X</th>
<th>Y</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>0</td>
<td>0</td>
</tr>
<tr>
<td>2</td>
<td>tileWidth</td>
<td>0</td>
</tr>
<tr>
<td>3</td>
<td>2 × tileWidth</td>
<td>0</td>
</tr>
<tr>
<td>4</td>
<td>0</td>
<td>tileHeight</td>
</tr>
<tr>
<td>5</td>
<td>tileWidth</td>
<td>tileHeight</td>
</tr>
<tr>
<td>6</td>
<td>2 × tileWidth</td>
<td>tileHeight</td>
</tr>
<tr>
<td>7</td>
<td>0</td>
<td>2 × tileHeight</td>
</tr>
<tr>
<td>8</td>
<td>tileWidth</td>
<td>2 × tileHeight</td>
</tr>
<tr>
<td>9</td>
<td>2 × tileWidth</td>
<td>2 × tileHeight</td>
</tr>
</tbody>
</table>

Then use:

<strong>Crop Image</strong>

Set:

<pre><code>Position = Custom</code></pre>

Set Width to:

<pre><code>tileWidth</code></pre>

and Height to:

<pre><code>tileHeight</code></pre>

Then use the corresponding X and Y coordinates calculated above.

<h2>A Cleaner Version: Use Two Repeat Loops</h2>

Of course, you could create nine separate Crop Image actions.

But from a programmer’s point of view, that is rather repetitive.

A cleaner implementation uses two loops:

<pre><code>for row in range(3):
    for col in range(3):
        x = col * tileWidth
        y = row * tileHeight

        crop(
            x=x,
            y=y,
            width=tileWidth,
            height=tileHeight
        )</code></pre>

Shortcuts can implement the same idea using:

<strong>Repeat</strong>

The outer loop:

<pre><code>Repeat 3 Times</code></pre>

represents the row.

Calculate:

<pre><code>row = Repeat Index - 1</code></pre>

Then inside it, add another:

<pre><code>Repeat 3 Times</code></pre>

for the column.

Calculate:

<pre><code>column = Repeat Index - 1

X = column × tileWidth
Y = row × tileHeight</code></pre>

Then:

<pre><code>Crop img

Position = Custom
X Coordinate = X
Y Coordinate = Y
Width = tileWidth
Height = tileHeight</code></pre>

Add each cropped image to:

<pre><code>gridImages</code></pre>

After both loops complete:

<pre><code>gridImages</code></pre>

contains exactly nine images.

<h2>Step 5: Save the Nine Images</h2>

Finally add:

<strong>Save to Photo Album</strong>

Use:

<pre><code>gridImages</code></pre>

as the input.

The shortcut is now complete.

<h2>Complete Shortcut Command Flow</h2>

If the whole shortcut is expanded into a sequential command flow, it looks roughly like this:

<pre><code>1. Receive Images from Share Sheet


2. If Shortcut Input has any value

       Set variable img = Shortcut Input

   Otherwise

       Select Photos
       Set variable img = Photos

   End If


3. Get Width of img

       → width


4. Get Height of img

       → height


5. Calculate

       tileWidth = width / 3


6. Calculate

       tileHeight = height / 3


7. Repeat 3 Times

       row = Repeat Index - 1

       Repeat 3 Times

           column = Repeat Index - 1

           X = column × tileWidth
           Y = row × tileHeight

           Crop img

               Position = Custom
               X Coordinate = X
               Y Coordinate = Y
               Width = tileWidth
               Height = tileHeight

           Add cropped result to gridImages

       End Repeat

   End Repeat


8. Save gridImages to Photo Album</code></pre>

From a software engineering point of view, this is already a fairly standard small program.

It contains:

<ul>
<li>Input</li>
<li>Variables</li>
<li>If / Else</li>
<li>Nested Loops</li>
<li>Arithmetic</li>
<li>Coordinate Calculations</li>
<li>Image Processing</li>
<li>Output</li>
</ul>

Apple simply represents these programming concepts as visual actions that can be dragged around.

<h2>What Would the Same Thing Look Like in Python?</h2>

The core algorithm behind the shortcut is actually easier to understand when written in Python.

Install Pillow first:

<pre><code>pip install pillow</code></pre>

Then:

<pre><code>from pathlib import Path
from PIL import Image, ImageOps


def make_nine_grid(input_file: str, output_dir: str = "nine_grid"):
    input_path = Path(input_file)
    output_path = Path(output_dir)

    output_path.mkdir(parents=True, exist_ok=True)

    # Open the image
    image = Image.open(input_path)

    # Correct orientation using EXIF metadata
    image = ImageOps.exif_transpose(image)

    width, height = image.size

    # -------------------------
    # Step 1: Calculate 3 × 3 boundaries
    # -------------------------
    #
    # Divide the width into three columns
    # and the height into three rows.
    #
    # There is no need to crop the source
    # image into a square first.
    #
    # Calculating boundaries this way also
    # handles dimensions that are not exactly
    # divisible by 3 without losing pixels.
    #

    x = [
        0,
        width // 3,
        width * 2 // 3,
        width,
    ]

    y = [
        0,
        height // 3,
        height * 2 // 3,
        height,
    ]

    # -------------------------
    # Step 2: Crop into nine images
    # -------------------------

    index = 1

    for row in range(3):
        for col in range(3):

            box = (
                x[col],
                y[row],
                x[col + 1],
                y[row + 1],
            )

            tile = image.crop(box)

            filename = output_path / f"grid_{index:02}.png"

            tile.save(filename)

            print(
                f"{index}: "
                f"row={row}, "
                f"col={col}, "
                f"box={box}, "
                f"size={tile.size}"
            )

            index += 1


if __name__ == "__main__":
    make_nine_grid(
        "photo.jpg",
        "nine_grid",
    )</code></pre>

Run:

<pre><code>python nine_grid.py</code></pre>

The output directory will contain:

<pre><code>nine_grid/
├── grid_01.png
├── grid_02.png
├── grid_03.png
├── grid_04.png
├── grid_05.png
├── grid_06.png
├── grid_07.png
├── grid_08.png
└── grid_09.png</code></pre>

<h2>One Small but Important Detail in the Python Version</h2>

If the image dimensions are exactly divisible by three, for example:

<pre><code>4032 × 3024</code></pre>

then everything is simple:

<pre><code>4032 / 3 = 1344
3024 / 3 = 1008</code></pre>

Each tile will be exactly:

<pre><code>1344 × 1008</code></pre>

But not every image dimension is divisible by three.

Suppose the source image is:

<pre><code>4033 × 3025</code></pre>

Then:

<pre><code>4033 / 3 = 1344.333...
3025 / 3 = 1008.333...</code></pre>

Obviously, an image cannot contain:

<pre><code>0.333 pixels</code></pre>

If we simply use:

<pre><code>tileWidth = width // 3
tileHeight = height // 3</code></pre>

we get:

<pre><code>tileWidth = 1344
tileHeight = 1008</code></pre>

But then:

<pre><code>1344 × 3 = 4032
1008 × 3 = 3024</code></pre>

One column of pixels on the right and one row of pixels at the bottom would be left unused.

That is why the Python version calculates four X boundaries:

<pre><code>x0 = 0
x1 = width // 3
x2 = width * 2 // 3
x3 = width</code></pre>

and four Y boundaries:

<pre><code>y0 = 0
y1 = height // 3
y2 = height * 2 // 3
y3 = height</code></pre>

For example, with:

<pre><code>width = 4033</code></pre>

the X boundaries are:

<pre><code>0
1344
2688
4033</code></pre>

So the three horizontal sections are:

<pre><code>0    → 1344
1344 → 2688
2688 → 4033</code></pre>

The final tile may be one pixel wider than the others, but no source pixels are lost.

The same logic applies to the height.

The important property is not that every tile must have exactly the same integer dimensions.

It is that:

<strong>The complete source image is divided continuously into a 3×3 grid with no missing or overlapping pixels.</strong>

<h2>Why Is There No Need to Crop the Image into a Square?</h2>

This is an easy misconception to make:

<strong>A nine-grid image does not mean nine square images.</strong>

A 3×3 grid simply means:

<pre><code>3 Columns × 3 Rows</code></pre>

If the original photo is:

<pre><code>4032 × 3024</code></pre>

its aspect ratio is:

<pre><code>4 : 3</code></pre>

After splitting it into a 3×3 grid, each tile is approximately:

<pre><code>1344 × 1008</code></pre>

which is still:

<pre><code>4 : 3</code></pre>

That is exactly what we want.

Both dimensions have been divided by three, so each tile preserves the original image’s aspect ratio.

If we first cropped:

<pre><code>4032 × 3024</code></pre>

into:

<pre><code>3024 × 3024</code></pre>

we would throw away:

<pre><code>4032 - 3024
= 1008 pixels</code></pre>

from the horizontal dimension.

That could easily remove people, scenery, or other important content near the edges of the photo.

The correct approach is therefore:

<strong>Keep the original image and divide its width and height independently into three parts.</strong>

<h2>How Do I Use the Shortcut?</h2>

Once the shortcut has been created, there is normally no need to open the Shortcut editor again.

The simplest method is:

<pre><code>Shortcuts
→ Image Nine-Grid
→ Select Photo</code></pre>

The nine generated images will then be saved to Photos.

I personally prefer running it directly from the Photos app:

<pre><code>Photos
→ Open a photo
→ Share
→ Image Nine-Grid</code></pre>

The selected <a href="https://helloacm.com/chatgpt-image-2-0-casual-selfie-of-me/" title="ChatGPT Image 2.0 – Casual Selfie of Me">image</a> is passed directly into the shortcut as:

<pre><code>Shortcut Input</code></pre>

so there is no need to select the image again.

<h2>Why I Prefer a Shortcut Instead of a Nine-Grid App</h2>

There are obviously many nine-grid apps available in the App Store.

But for such a simple task, installing another dedicated app feels unnecessary.

Creating my own shortcut has several advantages.

First, there are no advertisements, subscriptions, VIP memberships, or limits such as “three free images per day”.

Second, the photo does not need to be uploaded to some unknown website.

Most importantly, once the shortcut is built, it becomes a small tool that I completely control.

And it is very easy to modify.

For example, changing:

<pre><code>3 × 3</code></pre>

to:

<pre><code>2 × 2</code></pre>

creates a four-image grid.

Changing it to:

<pre><code>4 × 4</code></pre>

creates sixteen images.

You could even ask for a number at the beginning:

<pre><code>Ask for Input

Enter N:</code></pre>

Then calculate:

<pre><code>tileWidth = width / N
tileHeight = height / N</code></pre>

and change the loops to:

<pre><code>for row in range(N):
    for col in range(N):</code></pre>

For a more robust Python implementation, calculate the boundaries directly:

<pre><code>x[i] = width * i // N
y[i] = height * i // N</code></pre>

where:

<pre><code>i = 0, 1, 2, ..., N</code></pre>

This ensures that every source pixel is included even when the width or height is not exactly divisible by N.

At that point, it is no longer just a nine-grid shortcut.

It becomes a general-purpose:

<strong>N × N image splitter.</strong>

<h2>Shortcuts Is Really a Form of Programming</h2>

I used to think of Apple Shortcuts mainly as a simple automation tool.

After building a few shortcuts myself, I realized that it is actually very similar to normal programming.

This nine-grid shortcut already involves:

<pre><code>Input
Variables
If / Else
Loops
Nested Loops
Arithmetic
Coordinates
Image Processing
Output</code></pre>

It even contains a typical two-dimensional coordinate problem.

The underlying algorithm is essentially:

<pre><code>for row in range(3):
    for col in range(3):

        left   = width * col // 3
        right  = width * (col + 1) // 3

        top    = height * row // 3
        bottom = height * (row + 1) // 3

        crop(
            left,
            top,
            right,
            bottom,
        )</code></pre>

The same task can probably be implemented in a few dozen lines of Python, but the advantage of Shortcuts is that once the workflow is built, it immediately becomes a reusable tool on the iPhone.

Whenever I need a nine-grid image, I simply use:

<pre><code>Photos
→ Share
→ Image Nine-Grid</code></pre>

A few seconds later, all nine images are already in the Photos library.

For many small tasks like this, there is really no need to install another app.

The iPhone already includes a surprisingly capable automation and visual programming environment.

[show_file file="/var/www/wp-post-common/helloacm.com/ios.php"]

[show_posts keyword="iphone"]

BTW: I've vibe-coded a simple online tool to split an image into a grid: <a title="Split a picture into a precise grid, preview every tile, and download one ZIP. Your image never leaves this device." href="https://doctorlai-msrc.github.io/cut-picture/">Split a picture into a precise grid, preview every tile, and download one ZIP. Your image never leaves this device.</a>

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/planning-to-update-your-website-for-2020-read-this/" rel="bookmark" title="Planning To Update Your Website For 2020? Read This.">Planning To Update Your Website For 2020? Read This.</a> <small>Looking to update your website for 2020? If so, it&#8217;s important to be aware of...</small></li>
<li><a href="https://helloacm.com/the-powerful-remote-cloud-desktop-by-railway-up-visual-studio-code-everywhere/" rel="bookmark" title="The Powerful Remote Cloud Desktop by Railway.Up (Visual Studio Code Everywhere)">The Powerful Remote Cloud Desktop by Railway.Up (Visual Studio Code Everywhere)</a> <small>Although, Railway.Up is ending their free $5 plan monthly soon, you can still benefit it...</small></li>
<li><a href="https://helloacm.com/algorithms-to-shift-a-2d-grid-matrix-in-place/" rel="bookmark" title="Algorithms to Shift a 2D Grid/Matrix In-Place">Algorithms to Shift a 2D Grid/Matrix In-Place</a> <small>Given a 2D grid of size n * m and an integer k. You need...</small></li>
<li><a href="https://helloacm.com/why-does-the-exchange-force-liquidation-when-the-margin-is-low/" rel="bookmark" title="Why does the exchange force liquidation when the margin is low?">Why does the exchange force liquidation when the margin is low?</a> <small>In the cryptocurrency market, as long as you don&#8217;t trade contracts, the risk is not...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-geometry-of-triangle-area-and-side-law/" rel="bookmark" title="Teaching Kids Programming &#8211; Geometry of Triangle Area and Side Law">Teaching Kids Programming &#8211; Geometry of Triangle Area and Side Law</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms We know the area of triangle...</small></li>
<li><a href="https://helloacm.com/on-waiting-list-of-chatgpt-4-api/" rel="bookmark" title="On Waiting List of ChatGPT 4 API">On Waiting List of ChatGPT 4 API</a> <small>As of today, The ChatGPT-4 API Access is not yet available but we can request...</small></li>
<li><a href="https://helloacm.com/how-to-transfer-bts-assets-on-bitshares-blockchain-using-node-js/" rel="bookmark" title="How to Transfer BTS Assets on BitShares Blockchain using Node.Js?">How to Transfer BTS Assets on BitShares Blockchain using Node.Js?</a> <small>Node/Javascript Function to Transfer BTS Assets on BitShares Blockchain To make a transfer on the...</small></li>
<li><a href="https://helloacm.com/greedy-algorithm-to-find-the-lexicographically-smallest-sequences-after-at-most-k-element-swaps/" rel="bookmark" title="Greedy Algorithm to Find the Lexicographically Smallest Sequences After At Most K Element Swaps">Greedy Algorithm to Find the Lexicographically Smallest Sequences After At Most K Element Swaps</a> <small>Given a sequence of n integers arr, determine the lexicographically smallest sequence which may be...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://helloacm.com/split-a-photo-into-a-3x3-grid-with-iphone-shortcuts-build-install-share-and-recreate-it-in-python/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Microsoft Global Hackathon 2026: One Week to Turn an Idea into Something Real</title>
		<link>https://helloacm.com/microsoft-global-hackathon-2026-one-week-to-turn-an-idea-into-something-real/</link>
					<comments>https://helloacm.com/microsoft-global-hackathon-2026-one-week-to-turn-an-idea-into-something-real/#respond</comments>
		
		<dc:creator><![CDATA[ACMer]]></dc:creator>
		<pubDate>Sun, 20 Sep 2026 13:05:27 +0000</pubDate>
				<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[developer tools]]></category>
		<category><![CDATA[Engineering Culture]]></category>
		<category><![CDATA[Experimentation]]></category>
		<category><![CDATA[Fake It Until You Make It]]></category>
		<category><![CDATA[Global Hackathon]]></category>
		<category><![CDATA[Hackathon]]></category>
		<category><![CDATA[Innovation]]></category>
		<category><![CDATA[Microsoft Global Hackathon]]></category>
		<category><![CDATA[Microsoft Life]]></category>
		<category><![CDATA[POC]]></category>
		<category><![CDATA[Product Development]]></category>
		<category><![CDATA[Proof of Concept]]></category>
		<category><![CDATA[Prototype]]></category>
		<category><![CDATA[Software Developer]]></category>
		<category><![CDATA[software engineer]]></category>
		<category><![CDATA[software engineering]]></category>
		<category><![CDATA[Technology]]></category>
		<guid isPermaLink="false">https://helloacm.com/?p=158136</guid>

					<description><![CDATA[<blockquote>
Over the past couple of years, I have started taking part in Microsoft’s annual Global Hackathon. With only one week to experiment, the goal is rarely to build a production-ready product. Instead, it is about validating an idea, creating a proof of concept, learning something new, and collaborating with people outside your usual team.
</blockquote>

[caption id="attachment_158146" align="alignnone" width="1241"]<a href="https://helloacm.com/microsoft-global-hackathon-2026-one-week-to-turn-an-idea-into-something-real/microsoft-global-hackathon-badges/" rel="attachment wp-att-158146"><img src="https://helloacm.com/wp-content/uploads/2026/09/microsoft-global-hackathon-badges.jpg" alt="Registration entitles a Digital Hackathon Badge (as a Hackathon Participant)" width="1241" height="921" class="size-full wp-image-158146" /></a> Registration entitles a Digital Hackathon Badge (as a Hackathon Participant)[/caption]
It was only in the past couple of years that I started taking part more seriously in Microsoft’s annual Global Hackathon.

Microsoft Hackathon is an internal innovation event held every September. It started back in 2014 and has now been running for more than a decade. The scale is huge, with participants coming from different teams and product groups around the world. People who would normally never work together often form temporary teams around a shared idea.

I had known about the event for years, but I only really started participating in it recently.

<h2>Hackathon Usually Lasts Just One Week</h2>

The main <a href="https://helloacm.com/unleashing-innovation-inside-hackathon-events-at-big-internet-companies-hackathon-t-shirt-from-microsoft/" title="Unleashing Innovation: Inside Hackathon Events at Big Internet Companies (Hackathon T-shirt from Microsoft)">Hackathon</a> activity basically lasts for one week.

Usually, by the Monday of the following week, teams need to upload a video of around two minutes explaining what the project does, what problem it tries to solve, and showing the final demo.

One interesting thing is that Hackathon does not require you to deliver a fully completed product in the same way as a normal software project.

You can certainly write code, but usually nobody is going to review your code line by line.

In many cases, the real final output or delivery is simply that two-minute video.

After taking part a few times, I have increasingly felt that Hackathon is very different from normal software engineering work.

The Microsoft Logo is at the back of the neck. On the first day, some engineers wear it already.
[caption id="attachment_158141" align="alignnone" width="2048"]<a href="https://helloacm.com/microsoft-global-hackathon-2026-one-week-to-turn-an-idea-into-something-real/microsoft-hackathon-swags-2026-09-14-09-32-53/" rel="attachment wp-att-158141"><img src="https://helloacm.com/wp-content/uploads/2026/09/microsoft-hackathon-swags-2026-09-14-09.32.53-scaled.jpg" alt="Free Stuffs/Swags (Microsoft Hackathon Week)" width="2048" height="1152" class="size-full wp-image-158141" /></a> Free Stuffs/Swags (Microsoft Hackathon Week)[/caption]

In day-to-day development, we worry about a lot of things:

<strong>Architecture, Code Quality, Testing, Security, Performance, Deployment, Maintainability.</strong>

But Hackathon lasts only a few days.

From Monday to Friday, there really is not that much time available for <a href="https://helloacm.com/ai-coding-agents-are-reshaping-the-barrier-to-programming/" title="AI Coding Agents Are Reshaping the Barrier to Programming">coding</a> and experimentation.

Trying to build a mature, stable, production-ready product within just a few days is simply unrealistic.

That is why most Hackathon projects are essentially:

<strong>Proofs of Concept.</strong>

The main goal is to prove one thing:

<strong>This idea can work.</strong>

<h2>Fake It Until You Make It</h2>

Because time is so limited, Hackathon is a perfect environment for the mindset:

<strong>Fake it until you make it.</strong>

Of course, “fake” here does not mean fabricating results.

It means that, in order to validate an idea quickly, you can mock some data, simplify complicated workflows, or build a prototype that looks reasonably complete while only implementing the core functionality.

For example, a real production system might require:

Backend, Database, Authentication, Security Review, Monitoring, Deployment, Scalability...

But during Hackathon, many of these things can be skipped initially.

As long as the final demo can help people understand:

<strong>If we really built this properly, what might the finished product look like?</strong>

Then the project has already achieved a large part of its purpose.

<h2>Sometimes the Idea Matters More Than the Delivery</h2>

That is why I think one of the most interesting things about Hackathon is this:

<strong>The project idea is often more important than the final delivery.</strong>

In normal work, getting a new idea onto a <a href="https://helloacm.com/difference-between-product-design-interview-and-system-design-interview/" title="Difference Between Product Design Interview and System Design Interview">product</a> roadmap involves many practical considerations:

Priority, Resource, Budget, Customer Requirement, Security, Compliance, Cost...

Sometimes an idea can be discussed for months before anyone writes the first line of code.

Hackathon works differently.

Got an idea?

<strong>Build something first and see what happens.</strong>

Spend a few days validating it.

If the idea turns out to be bad, that is perfectly fine.

At least it has been tested.

But sometimes an idea that initially sounds a little unrealistic can become surprisingly interesting once someone turns it into a working <a href="https://helloacm.com/simple-but-powerful-simulated-annealing-npm-library-with-demo/" title="Simple but Powerful Simulated Annealing NPM Library (with Demo)">demo</a>.

That, in my opinion, is one of the biggest values of Hackathon.

<h2>This Year I Joined Two Projects</h2>

This year I registered for Hackathon again and joined two projects.

Strictly speaking, though, I was not working on Hackathon projects 100% of the time.

I was more like an occasional contributor, helping out where needed.

Hackathon is actually quite flexible.

<strong>Registering does not mean you must participate fully.</strong>

<strong>Participating does not mean you must upload a video.</strong>

<strong>Uploading a video does not mean you will win anything.</strong>

Signing up does not mean you have to stop all your normal work and spend the entire week hacking full-time.

How much you participate really depends on your own time and interest.

This year I mainly joined in, contributed here and there, and helped when something needed doing.

<h2>There Are Also T-Shirts, SWAG and a Lunch Voucher</h2>

Hackathon also comes with a few fun extras.

Once you register, you can usually collect Hackathon clothing on Monday morning, along with some small pieces of SWAG.

This year, there was also a free lunch voucher.

None of these things are particularly valuable on their own, but they give the whole event a bit more of a sense of occasion.

Normally everyone in the company is busy with their own projects.

During Hackathon Week, however, the atmosphere in the office feels noticeably different.

You see teams you have never encountered before working on all kinds of unusual ideas.

Some people build AI projects.

Some build hardware.

Some build developer tools.

Others work on highly experimental projects.

<h2>You Do Not Have to Win</h2>

I think one of the easiest mistakes to make is to treat Hackathon purely as a competition.

Of course, there are judging processes and winning projects.

But for most participants, winning is probably not the most important part.

I think:

<strong>Taking part already has value.</strong>

Registering is good.

Joining a project is good.

Actually writing code for a few days is even better.

If you also manage to produce a two-minute demo video at the end, then the experience feels more complete.

Whether you win an award or not is actually much less important.

<h2>One Week of “Legitimate Tinkering”</h2>

For me, Hackathon increasingly feels like one week of:

<strong>Legitimate tinkering time.</strong>

Normally, everyone has their own projects, deadlines, bugs, meetings, and day-to-day responsibilities.

It is difficult to justify spending several days experimenting with something that has little or nothing to do with your normal work.

Hackathon creates exactly that opportunity.

The pace of normal work is usually a little lighter during the week.

You can look at what ideas other teams around the company are exploring.

You can join a project in an area you know almost nothing about.

Or you can simply use the week to learn a new framework, explore a new AI technology, or meet colleagues you would normally never have the chance to work with.

Sometimes the most important thing is not even what you eventually build.

It is simply this:

<strong>You finally have a legitimate reason to spend a few days exploring something you would otherwise never touch.</strong>

<h2>The Idea Matters More Than the Result</h2>

So these days, when I think about Hackathon, I care much less about what the final project actually looks like.

One week is never enough to build a truly mature product anyway.

What matters more is:

<strong>Is the idea worth trying?</strong>

<strong>Did you validate it with a prototype?</strong>

<strong>Did you learn something new along the way?</strong>

Normal software engineering is usually about answering the question:

<strong>How can we build this reliably?</strong>

Hackathon is more like asking:

<strong>Why not just try building it first?</strong>

And I think that is what makes Hackathon interesting.

[caption id="attachment_158138" align="alignnone" width="1152"]<a href="https://helloacm.com/microsoft-global-hackathon-2026-one-week-to-turn-an-idea-into-something-real/microsoft-hackathon-2026-09-14-10-56-06/" rel="attachment wp-att-158138"><img src="https://helloacm.com/wp-content/uploads/2026/09/microsoft-hackathon-2026-09-14-10.56.06-scaled.jpg" alt="The Hackathon Notebook - I don&#039;t want to use it." width="1152" height="2048" class="size-full wp-image-158138" /></a> The Hackathon Notebook - I don't want to use it.[/caption]

[caption id="attachment_158139" align="alignnone" width="2048"]<a href="https://helloacm.com/microsoft-global-hackathon-2026-one-week-to-turn-an-idea-into-something-real/microsoft-hackathon-free-lunch-2026-09-15-12-11-27/" rel="attachment wp-att-158139"><img src="https://helloacm.com/wp-content/uploads/2026/09/microsoft-hackathon-free-lunch-2026-09-15-12.11.27-scaled.jpg" alt="Free Lunch and a Free Dessert." width="2048" height="1152" class="size-full wp-image-158139" /></a> Free Lunch and a Free Dessert.[/caption]

[caption id="attachment_158140" align="alignnone" width="2048"]<a href="https://helloacm.com/microsoft-global-hackathon-2026-one-week-to-turn-an-idea-into-something-real/microsoft-hackathon-free-lunch-voucher-2026-09-15-11-52-38/" rel="attachment wp-att-158140"><img src="https://helloacm.com/wp-content/uploads/2026/09/microsoft-hackathon-free-lunch-voucher-2026-09-15-11.52.38-scaled.jpg" alt="Free Lunch Voucher - Microsoft Hackathon 2026" width="2048" height="1152" class="size-full wp-image-158140" /></a> Free Lunch Voucher - Microsoft Hackathon 2026[/caption]

[show_file file="/var/www/wp-post-common/helloacm.com/microsoft.php"]

[show_posts keyword="Hackathon"]

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/microsofts-excel-just-got-smarter-the-new-copilot-function/" rel="bookmark" title="Microsoft&#8217;s Excel Just Got Smarter: The New Copilot Function">Microsoft&#8217;s Excel Just Got Smarter: The New Copilot Function</a> <small>All in AI. Microsoft has integrated AI (Copilot) to its Office products. I’m thrilled to...</small></li>
<li><a href="https://helloacm.com/calculating-pi-with-numerical-integration-in-python-and-c/" rel="bookmark" title="Calculating Pi with Numerical Integration in Python and C++">Calculating Pi with Numerical Integration in Python and C++</a> <small>This article explains how to approximate Pi using the definite integral . It introduces the...</small></li>
<li><a href="https://helloacm.com/chatgpt-refactors-rewrites-the-code-using-promise-all-sending-requests-in-parallel/" rel="bookmark" title="ChatGPT Refactors/Rewrites the Code using Promise.All &#8211; Sending Requests in Parallel">ChatGPT Refactors/Rewrites the Code using Promise.All &#8211; Sending Requests in Parallel</a> <small>In one of my project, I have the following code (Node/Javascript) that invokes a few...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-maximum-odd-binary-number/" rel="bookmark" title="Teaching Kids Programming &#8211; Maximum Odd Binary Number">Teaching Kids Programming &#8211; Maximum Odd Binary Number</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given a binary string...</small></li>
<li><a href="https://helloacm.com/interview-question-the-number-of-bits-required-to-convert-one-integer-to-another-cc-function/" rel="bookmark" title="Interview Question: The Number of Bits Required to Convert One Integer to Another (C/C++ function)">Interview Question: The Number of Bits Required to Convert One Integer to Another (C/C++ function)</a> <small>The question is: how many bits are required to change if we want to convert...</small></li>
<li><a href="https://helloacm.com/understanding-the-sigma-function-divisors-multiplicativity-and-the-formula/" rel="bookmark" title="Understanding the Sigma Function: Divisors, Multiplicativity, and the Formula">Understanding the Sigma Function: Divisors, Multiplicativity, and the Formula</a> <small>Understanding the Sigma Function: Divisors, Multiplicativity, and the Formula Understanding the Sigma Function: From Divisors...</small></li>
<li><a href="https://helloacm.com/a-google-alert-woke-me-up-postmortem-of-a-wordpress-security-incident/" rel="bookmark" title="A Google Alert Woke Me Up: Postmortem of a WordPress Security Incident">A Google Alert Woke Me Up: Postmortem of a WordPress Security Incident</a> <small>An unpatched WordPress and plugin vulnerability apparently exposed a Cloudflare credential stored in the database....</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-introduction-to-units-of-information-byte-kb-mb-gb-tb-pb/" rel="bookmark" title="Teaching Kids Programming &#8211; Introduction to Units of Information (Byte, KB, MB, GB, TB, PB)">Teaching Kids Programming &#8211; Introduction to Units of Information (Byte, KB, MB, GB, TB, PB)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms Information is the lifeblood of the...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<blockquote>
Over the past couple of years, I have started taking part in Microsoft’s annual Global Hackathon. With only one week to experiment, the goal is rarely to build a production-ready product. Instead, it is about validating an idea, creating a proof of concept, learning something new, and collaborating with people outside your usual team.
</blockquote>

[caption id="attachment_158146" align="alignnone" width="1241"]<a href="https://helloacm.com/microsoft-global-hackathon-2026-one-week-to-turn-an-idea-into-something-real/microsoft-global-hackathon-badges/" rel="attachment wp-att-158146"><img src="https://helloacm.com/wp-content/uploads/2026/09/microsoft-global-hackathon-badges.jpg" alt="Registration entitles a Digital Hackathon Badge (as a Hackathon Participant)" width="1241" height="921" class="size-full wp-image-158146" /></a> Registration entitles a Digital Hackathon Badge (as a Hackathon Participant)[/caption]
It was only in the past couple of years that I started taking part more seriously in Microsoft’s annual Global Hackathon.

Microsoft Hackathon is an internal innovation event held every September. It started back in 2014 and has now been running for more than a decade. The scale is huge, with participants coming from different teams and product groups around the world. People who would normally never work together often form temporary teams around a shared idea.

I had known about the event for years, but I only really started participating in it recently.

<h2>Hackathon Usually Lasts Just One Week</h2>

The main <a href="https://helloacm.com/unleashing-innovation-inside-hackathon-events-at-big-internet-companies-hackathon-t-shirt-from-microsoft/" title="Unleashing Innovation: Inside Hackathon Events at Big Internet Companies (Hackathon T-shirt from Microsoft)">Hackathon</a> activity basically lasts for one week.

Usually, by the Monday of the following week, teams need to upload a video of around two minutes explaining what the project does, what problem it tries to solve, and showing the final demo.

One interesting thing is that Hackathon does not require you to deliver a fully completed product in the same way as a normal software project.

You can certainly write code, but usually nobody is going to review your code line by line.

In many cases, the real final output or delivery is simply that two-minute video.

After taking part a few times, I have increasingly felt that Hackathon is very different from normal software engineering work.

The Microsoft Logo is at the back of the neck. On the first day, some engineers wear it already.
[caption id="attachment_158141" align="alignnone" width="2048"]<a href="https://helloacm.com/microsoft-global-hackathon-2026-one-week-to-turn-an-idea-into-something-real/microsoft-hackathon-swags-2026-09-14-09-32-53/" rel="attachment wp-att-158141"><img src="https://helloacm.com/wp-content/uploads/2026/09/microsoft-hackathon-swags-2026-09-14-09.32.53-scaled.jpg" alt="Free Stuffs/Swags (Microsoft Hackathon Week)" width="2048" height="1152" class="size-full wp-image-158141" /></a> Free Stuffs/Swags (Microsoft Hackathon Week)[/caption]

In day-to-day development, we worry about a lot of things:

<strong>Architecture, Code Quality, Testing, Security, Performance, Deployment, Maintainability.</strong>

But Hackathon lasts only a few days.

From Monday to Friday, there really is not that much time available for <a href="https://helloacm.com/ai-coding-agents-are-reshaping-the-barrier-to-programming/" title="AI Coding Agents Are Reshaping the Barrier to Programming">coding</a> and experimentation.

Trying to build a mature, stable, production-ready product within just a few days is simply unrealistic.

That is why most Hackathon projects are essentially:

<strong>Proofs of Concept.</strong>

The main goal is to prove one thing:

<strong>This idea can work.</strong>

<h2>Fake It Until You Make It</h2>

Because time is so limited, Hackathon is a perfect environment for the mindset:

<strong>Fake it until you make it.</strong>

Of course, “fake” here does not mean fabricating results.

It means that, in order to validate an idea quickly, you can mock some data, simplify complicated workflows, or build a prototype that looks reasonably complete while only implementing the core functionality.

For example, a real production system might require:

Backend, Database, Authentication, Security Review, Monitoring, Deployment, Scalability...

But during Hackathon, many of these things can be skipped initially.

As long as the final demo can help people understand:

<strong>If we really built this properly, what might the finished product look like?</strong>

Then the project has already achieved a large part of its purpose.

<h2>Sometimes the Idea Matters More Than the Delivery</h2>

That is why I think one of the most interesting things about Hackathon is this:

<strong>The project idea is often more important than the final delivery.</strong>

In normal work, getting a new idea onto a <a href="https://helloacm.com/difference-between-product-design-interview-and-system-design-interview/" title="Difference Between Product Design Interview and System Design Interview">product</a> roadmap involves many practical considerations:

Priority, Resource, Budget, Customer Requirement, Security, Compliance, Cost...

Sometimes an idea can be discussed for months before anyone writes the first line of code.

Hackathon works differently.

Got an idea?

<strong>Build something first and see what happens.</strong>

Spend a few days validating it.

If the idea turns out to be bad, that is perfectly fine.

At least it has been tested.

But sometimes an idea that initially sounds a little unrealistic can become surprisingly interesting once someone turns it into a working <a href="https://helloacm.com/simple-but-powerful-simulated-annealing-npm-library-with-demo/" title="Simple but Powerful Simulated Annealing NPM Library (with Demo)">demo</a>.

That, in my opinion, is one of the biggest values of Hackathon.

<h2>This Year I Joined Two Projects</h2>

This year I registered for Hackathon again and joined two projects.

Strictly speaking, though, I was not working on Hackathon projects 100% of the time.

I was more like an occasional contributor, helping out where needed.

Hackathon is actually quite flexible.

<strong>Registering does not mean you must participate fully.</strong>

<strong>Participating does not mean you must upload a video.</strong>

<strong>Uploading a video does not mean you will win anything.</strong>

Signing up does not mean you have to stop all your normal work and spend the entire week hacking full-time.

How much you participate really depends on your own time and interest.

This year I mainly joined in, contributed here and there, and helped when something needed doing.

<h2>There Are Also T-Shirts, SWAG and a Lunch Voucher</h2>

Hackathon also comes with a few fun extras.

Once you register, you can usually collect Hackathon clothing on Monday morning, along with some small pieces of SWAG.

This year, there was also a free lunch voucher.

None of these things are particularly valuable on their own, but they give the whole event a bit more of a sense of occasion.

Normally everyone in the company is busy with their own projects.

During Hackathon Week, however, the atmosphere in the office feels noticeably different.

You see teams you have never encountered before working on all kinds of unusual ideas.

Some people build AI projects.

Some build hardware.

Some build developer tools.

Others work on highly experimental projects.

<h2>You Do Not Have to Win</h2>

I think one of the easiest mistakes to make is to treat Hackathon purely as a competition.

Of course, there are judging processes and winning projects.

But for most participants, winning is probably not the most important part.

I think:

<strong>Taking part already has value.</strong>

Registering is good.

Joining a project is good.

Actually writing code for a few days is even better.

If you also manage to produce a two-minute demo video at the end, then the experience feels more complete.

Whether you win an award or not is actually much less important.

<h2>One Week of “Legitimate Tinkering”</h2>

For me, Hackathon increasingly feels like one week of:

<strong>Legitimate tinkering time.</strong>

Normally, everyone has their own projects, deadlines, bugs, meetings, and day-to-day responsibilities.

It is difficult to justify spending several days experimenting with something that has little or nothing to do with your normal work.

Hackathon creates exactly that opportunity.

The pace of normal work is usually a little lighter during the week.

You can look at what ideas other teams around the company are exploring.

You can join a project in an area you know almost nothing about.

Or you can simply use the week to learn a new framework, explore a new AI technology, or meet colleagues you would normally never have the chance to work with.

Sometimes the most important thing is not even what you eventually build.

It is simply this:

<strong>You finally have a legitimate reason to spend a few days exploring something you would otherwise never touch.</strong>

<h2>The Idea Matters More Than the Result</h2>

So these days, when I think about Hackathon, I care much less about what the final project actually looks like.

One week is never enough to build a truly mature product anyway.

What matters more is:

<strong>Is the idea worth trying?</strong>

<strong>Did you validate it with a prototype?</strong>

<strong>Did you learn something new along the way?</strong>

Normal software engineering is usually about answering the question:

<strong>How can we build this reliably?</strong>

Hackathon is more like asking:

<strong>Why not just try building it first?</strong>

And I think that is what makes Hackathon interesting.

[caption id="attachment_158138" align="alignnone" width="1152"]<a href="https://helloacm.com/microsoft-global-hackathon-2026-one-week-to-turn-an-idea-into-something-real/microsoft-hackathon-2026-09-14-10-56-06/" rel="attachment wp-att-158138"><img src="https://helloacm.com/wp-content/uploads/2026/09/microsoft-hackathon-2026-09-14-10.56.06-scaled.jpg" alt="The Hackathon Notebook - I don&#039;t want to use it." width="1152" height="2048" class="size-full wp-image-158138" /></a> The Hackathon Notebook - I don't want to use it.[/caption]

[caption id="attachment_158139" align="alignnone" width="2048"]<a href="https://helloacm.com/microsoft-global-hackathon-2026-one-week-to-turn-an-idea-into-something-real/microsoft-hackathon-free-lunch-2026-09-15-12-11-27/" rel="attachment wp-att-158139"><img src="https://helloacm.com/wp-content/uploads/2026/09/microsoft-hackathon-free-lunch-2026-09-15-12.11.27-scaled.jpg" alt="Free Lunch and a Free Dessert." width="2048" height="1152" class="size-full wp-image-158139" /></a> Free Lunch and a Free Dessert.[/caption]

[caption id="attachment_158140" align="alignnone" width="2048"]<a href="https://helloacm.com/microsoft-global-hackathon-2026-one-week-to-turn-an-idea-into-something-real/microsoft-hackathon-free-lunch-voucher-2026-09-15-11-52-38/" rel="attachment wp-att-158140"><img src="https://helloacm.com/wp-content/uploads/2026/09/microsoft-hackathon-free-lunch-voucher-2026-09-15-11.52.38-scaled.jpg" alt="Free Lunch Voucher - Microsoft Hackathon 2026" width="2048" height="1152" class="size-full wp-image-158140" /></a> Free Lunch Voucher - Microsoft Hackathon 2026[/caption]

[show_file file="/var/www/wp-post-common/helloacm.com/microsoft.php"]

[show_posts keyword="Hackathon"]

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/microsofts-excel-just-got-smarter-the-new-copilot-function/" rel="bookmark" title="Microsoft&#8217;s Excel Just Got Smarter: The New Copilot Function">Microsoft&#8217;s Excel Just Got Smarter: The New Copilot Function</a> <small>All in AI. Microsoft has integrated AI (Copilot) to its Office products. I’m thrilled to...</small></li>
<li><a href="https://helloacm.com/calculating-pi-with-numerical-integration-in-python-and-c/" rel="bookmark" title="Calculating Pi with Numerical Integration in Python and C++">Calculating Pi with Numerical Integration in Python and C++</a> <small>This article explains how to approximate Pi using the definite integral . It introduces the...</small></li>
<li><a href="https://helloacm.com/chatgpt-refactors-rewrites-the-code-using-promise-all-sending-requests-in-parallel/" rel="bookmark" title="ChatGPT Refactors/Rewrites the Code using Promise.All &#8211; Sending Requests in Parallel">ChatGPT Refactors/Rewrites the Code using Promise.All &#8211; Sending Requests in Parallel</a> <small>In one of my project, I have the following code (Node/Javascript) that invokes a few...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-maximum-odd-binary-number/" rel="bookmark" title="Teaching Kids Programming &#8211; Maximum Odd Binary Number">Teaching Kids Programming &#8211; Maximum Odd Binary Number</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given a binary string...</small></li>
<li><a href="https://helloacm.com/interview-question-the-number-of-bits-required-to-convert-one-integer-to-another-cc-function/" rel="bookmark" title="Interview Question: The Number of Bits Required to Convert One Integer to Another (C/C++ function)">Interview Question: The Number of Bits Required to Convert One Integer to Another (C/C++ function)</a> <small>The question is: how many bits are required to change if we want to convert...</small></li>
<li><a href="https://helloacm.com/understanding-the-sigma-function-divisors-multiplicativity-and-the-formula/" rel="bookmark" title="Understanding the Sigma Function: Divisors, Multiplicativity, and the Formula">Understanding the Sigma Function: Divisors, Multiplicativity, and the Formula</a> <small>Understanding the Sigma Function: Divisors, Multiplicativity, and the Formula Understanding the Sigma Function: From Divisors...</small></li>
<li><a href="https://helloacm.com/a-google-alert-woke-me-up-postmortem-of-a-wordpress-security-incident/" rel="bookmark" title="A Google Alert Woke Me Up: Postmortem of a WordPress Security Incident">A Google Alert Woke Me Up: Postmortem of a WordPress Security Incident</a> <small>An unpatched WordPress and plugin vulnerability apparently exposed a Cloudflare credential stored in the database....</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-introduction-to-units-of-information-byte-kb-mb-gb-tb-pb/" rel="bookmark" title="Teaching Kids Programming &#8211; Introduction to Units of Information (Byte, KB, MB, GB, TB, PB)">Teaching Kids Programming &#8211; Introduction to Units of Information (Byte, KB, MB, GB, TB, PB)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms Information is the lifeblood of the...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://helloacm.com/microsoft-global-hackathon-2026-one-week-to-turn-an-idea-into-something-real/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>CP/M: The Operating System That Came Before MS-DOS</title>
		<link>https://helloacm.com/cp-m-the-operating-system-that-came-before-ms-dos/</link>
					<comments>https://helloacm.com/cp-m-the-operating-system-that-came-before-ms-dos/#respond</comments>
		
		<dc:creator><![CDATA[ACMer]]></dc:creator>
		<pubDate>Sat, 19 Sep 2026 10:58:03 +0000</pubDate>
				<category><![CDATA[hardware]]></category>
		<category><![CDATA[nostalgic]]></category>
		<category><![CDATA[OS - Operating System]]></category>
		<category><![CDATA[vintage computing]]></category>
		<category><![CDATA[command line]]></category>
		<category><![CDATA[computer history]]></category>
		<category><![CDATA[computing]]></category>
		<category><![CDATA[Control Program for Microcomputers]]></category>
		<category><![CDATA[Control Program Monitor]]></category>
		<category><![CDATA[CP/M]]></category>
		<category><![CDATA[Digital Research]]></category>
		<category><![CDATA[Gary Kildall]]></category>
		<category><![CDATA[IBM PC]]></category>
		<category><![CDATA[Microsoft DOS]]></category>
		<category><![CDATA[MS-DOS]]></category>
		<category><![CDATA[operating system]]></category>
		<category><![CDATA[past technology]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[retro computing]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[vintage computers]]></category>
		<guid isPermaLink="false">https://helloacm.com/?p=158114</guid>

					<description><![CDATA[<blockquote>
A look back at CP/M, one of the most influential operating systems before the rise of Microsoft DOS. Its command-line interface and familiar commands such as DIR, TYPE, and FORMAT show just how much early personal computing shaped the systems that followed.

CP/M: The Operating System Pioneer Before Microsoft DOS
Before DOS: A Look Back at the CP/M Operating System
CP/M: The Operating System That Came Before MS-DOS
From CP/M to DOS: The Early History of Personal Computer Operating Systems
Looking at CP/M Feels Like Seeing an Ancestor of DOS
</blockquote>

This is CP/M, an operating system that predates <a href="https://helloacm.com/lost-era-microsoft-dos-16-bit-assembly-echo-program-revisited/" title="Lost Era, Microsoft DOS, 16-bit Assembly, Echo program revisited">Microsoft DOS</a> by several years. Looking at its command-line interface, it already feels surprisingly familiar: commands such as DIR, COPY, TYPE, and FORMAT later became standard parts of the DOS world. CP/M was developed by Digital Research in the 1970s and became one of the dominant operating systems for early microcomputers before the IBM PC era.

When IBM launched its PC in 1981, Microsoft supplied <a href="https://helloacm.com/the-8-bit-dos-by-famicom-clone-bbgdos-in-the-1990s/" title="The 8 bit DOS by Famicom Clone – BBGDOS in the 1990s">MS-DOS</a>, whose early design and command conventions were heavily influenced by the CP/M ecosystem. In many ways, looking at a CP/M screen today feels like looking at an ancestor of DOS —and, indirectly, a small piece of the family tree that eventually led to modern Windows.

CP/M originally stood for Control Program/Monitor. Later, Digital Research also used the expansion Control Program for Microcomputers.

It was created by Gary Kildall in the 1970s and became one of the most important operating systems for 8-bit microcomputers before DOS.

[caption id="attachment_158115" align="alignnone" width="816"]<a href="https://helloacm.com/cp-m-the-operating-system-that-came-before-ms-dos/cp-m-os-microsoft/" rel="attachment wp-att-158115"><img src="https://helloacm.com/wp-content/uploads/2026/09/cp-m-os-microsoft.jpg" alt="CP/M OS - Microsoft" width="816" height="540" class="size-full wp-image-158115" /></a> CP/M OS - Microsoft[/caption]

[show_file file="/var/www/wp-post-common/helloacm.com/nostalgic.php"]

[show_posts keyword="Operating System"]

Reposted to <a href="https://steemit.com/@justyy/are-you-this-old-apple-cp-m-1980-microsoft" title="Are you this old? Apple CP/M - 1980 Microsoft">Are you this old? Apple CP/M - 1980 Microsoft</a> | <a href="https://blurt.blog/blog/@justyy/are-you-this-old-apple-cp-m-1980-microsoft" title="Are you this old? Apple CP/M - 1980 Microsoft">Are you this old? Apple CP/M - 1980 Microsoft</a>

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/how-to-analyze-website-by-using-the-wappalyzer-chrome-extension/" rel="bookmark" title="How to Analyze Website by using the Wappalyzer (Chrome Extension)?">How to Analyze Website by using the Wappalyzer (Chrome Extension)?</a> <small>. And here is a list of technology used in this blog. And basically it...</small></li>
<li><a href="https://helloacm.com/chatgpt-refactors-rewrites-the-code-using-promise-all-sending-requests-in-parallel/" rel="bookmark" title="ChatGPT Refactors/Rewrites the Code using Promise.All &#8211; Sending Requests in Parallel">ChatGPT Refactors/Rewrites the Code using Promise.All &#8211; Sending Requests in Parallel</a> <small>In one of my project, I have the following code (Node/Javascript) that invokes a few...</small></li>
<li><a href="https://helloacm.com/frequently-asked-core-java-interview-questions-and-answers-guest-article/" rel="bookmark" title="Frequently Asked Core Java Interview Questions and Answers">Frequently Asked Core Java Interview Questions and Answers</a> <small>Here is a few questions that I find it useful for preparing the interviews (Java)....</small></li>
<li><a href="https://helloacm.com/how-to-use-the-dynamic-link-library-in-c-linux-gcc-compiler/" rel="bookmark" title="How to Use the Dynamic Link Library in C++ Linux (gcc compiler)?">How to Use the Dynamic Link Library in C++ Linux (gcc compiler)?</a> <small>The Dynamic Link Library (DLL) is stored separately from the target application and shared among...</small></li>
<li><a href="https://helloacm.com/a-tiny-logic-puzzle-about-truth-and-lies/" rel="bookmark" title="A Tiny Logic Puzzle About Truth and Lies">A Tiny Logic Puzzle About Truth and Lies</a> <small>A small village logic puzzle shows why careful reasoning matters. With 100 villagers each giving...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-minimum-number-of-perfect-squares-via-theorem-guided-iterative-deepening-dfs/" rel="bookmark" title="Teaching Kids Programming &#8211; Minimum Number of Perfect Squares via Theorem-guided iterative deepening DFS">Teaching Kids Programming &#8211; Minimum Number of Perfect Squares via Theorem-guided iterative deepening DFS</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms This article explores an iterative-deepening recursive...</small></li>
<li><a href="https://helloacm.com/calculating-pi-with-numerical-integration-in-python-and-c/" rel="bookmark" title="Calculating Pi with Numerical Integration in Python and C++">Calculating Pi with Numerical Integration in Python and C++</a> <small>This article explains how to approximate Pi using the definite integral . It introduces the...</small></li>
<li><a href="https://helloacm.com/coding-exercise-simple-nl-implementation-on-windows-platform-using-c-gcc/" rel="bookmark" title="Coding Exercise &#8211; Simple [nl] Implementation on Windows Platform using C++ (GCC)">Coding Exercise &#8211; Simple [nl] Implementation on Windows Platform using C++ (GCC)</a> <small>On Linux BASH shell, the &#8216;nl&#8217; utility is used to print out text file (or...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<blockquote>
A look back at CP/M, one of the most influential operating systems before the rise of Microsoft DOS. Its command-line interface and familiar commands such as DIR, TYPE, and FORMAT show just how much early personal computing shaped the systems that followed.

CP/M: The Operating System Pioneer Before Microsoft DOS
Before DOS: A Look Back at the CP/M Operating System
CP/M: The Operating System That Came Before MS-DOS
From CP/M to DOS: The Early History of Personal Computer Operating Systems
Looking at CP/M Feels Like Seeing an Ancestor of DOS
</blockquote>

This is CP/M, an operating system that predates <a href="https://helloacm.com/lost-era-microsoft-dos-16-bit-assembly-echo-program-revisited/" title="Lost Era, Microsoft DOS, 16-bit Assembly, Echo program revisited">Microsoft DOS</a> by several years. Looking at its command-line interface, it already feels surprisingly familiar: commands such as DIR, COPY, TYPE, and FORMAT later became standard parts of the DOS world. CP/M was developed by Digital Research in the 1970s and became one of the dominant operating systems for early microcomputers before the IBM PC era.

When IBM launched its PC in 1981, Microsoft supplied <a href="https://helloacm.com/the-8-bit-dos-by-famicom-clone-bbgdos-in-the-1990s/" title="The 8 bit DOS by Famicom Clone – BBGDOS in the 1990s">MS-DOS</a>, whose early design and command conventions were heavily influenced by the CP/M ecosystem. In many ways, looking at a CP/M screen today feels like looking at an ancestor of DOS —and, indirectly, a small piece of the family tree that eventually led to modern Windows.

CP/M originally stood for Control Program/Monitor. Later, Digital Research also used the expansion Control Program for Microcomputers.

It was created by Gary Kildall in the 1970s and became one of the most important operating systems for 8-bit microcomputers before DOS.

[caption id="attachment_158115" align="alignnone" width="816"]<a href="https://helloacm.com/cp-m-the-operating-system-that-came-before-ms-dos/cp-m-os-microsoft/" rel="attachment wp-att-158115"><img src="https://helloacm.com/wp-content/uploads/2026/09/cp-m-os-microsoft.jpg" alt="CP/M OS - Microsoft" width="816" height="540" class="size-full wp-image-158115" /></a> CP/M OS - Microsoft[/caption]

[show_file file="/var/www/wp-post-common/helloacm.com/nostalgic.php"]

[show_posts keyword="Operating System"]

Reposted to <a href="https://steemit.com/@justyy/are-you-this-old-apple-cp-m-1980-microsoft" title="Are you this old? Apple CP/M - 1980 Microsoft">Are you this old? Apple CP/M - 1980 Microsoft</a> | <a href="https://blurt.blog/blog/@justyy/are-you-this-old-apple-cp-m-1980-microsoft" title="Are you this old? Apple CP/M - 1980 Microsoft">Are you this old? Apple CP/M - 1980 Microsoft</a>

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/how-to-analyze-website-by-using-the-wappalyzer-chrome-extension/" rel="bookmark" title="How to Analyze Website by using the Wappalyzer (Chrome Extension)?">How to Analyze Website by using the Wappalyzer (Chrome Extension)?</a> <small>. And here is a list of technology used in this blog. And basically it...</small></li>
<li><a href="https://helloacm.com/chatgpt-refactors-rewrites-the-code-using-promise-all-sending-requests-in-parallel/" rel="bookmark" title="ChatGPT Refactors/Rewrites the Code using Promise.All &#8211; Sending Requests in Parallel">ChatGPT Refactors/Rewrites the Code using Promise.All &#8211; Sending Requests in Parallel</a> <small>In one of my project, I have the following code (Node/Javascript) that invokes a few...</small></li>
<li><a href="https://helloacm.com/frequently-asked-core-java-interview-questions-and-answers-guest-article/" rel="bookmark" title="Frequently Asked Core Java Interview Questions and Answers">Frequently Asked Core Java Interview Questions and Answers</a> <small>Here is a few questions that I find it useful for preparing the interviews (Java)....</small></li>
<li><a href="https://helloacm.com/how-to-use-the-dynamic-link-library-in-c-linux-gcc-compiler/" rel="bookmark" title="How to Use the Dynamic Link Library in C++ Linux (gcc compiler)?">How to Use the Dynamic Link Library in C++ Linux (gcc compiler)?</a> <small>The Dynamic Link Library (DLL) is stored separately from the target application and shared among...</small></li>
<li><a href="https://helloacm.com/a-tiny-logic-puzzle-about-truth-and-lies/" rel="bookmark" title="A Tiny Logic Puzzle About Truth and Lies">A Tiny Logic Puzzle About Truth and Lies</a> <small>A small village logic puzzle shows why careful reasoning matters. With 100 villagers each giving...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-minimum-number-of-perfect-squares-via-theorem-guided-iterative-deepening-dfs/" rel="bookmark" title="Teaching Kids Programming &#8211; Minimum Number of Perfect Squares via Theorem-guided iterative deepening DFS">Teaching Kids Programming &#8211; Minimum Number of Perfect Squares via Theorem-guided iterative deepening DFS</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms This article explores an iterative-deepening recursive...</small></li>
<li><a href="https://helloacm.com/calculating-pi-with-numerical-integration-in-python-and-c/" rel="bookmark" title="Calculating Pi with Numerical Integration in Python and C++">Calculating Pi with Numerical Integration in Python and C++</a> <small>This article explains how to approximate Pi using the definite integral . It introduces the...</small></li>
<li><a href="https://helloacm.com/coding-exercise-simple-nl-implementation-on-windows-platform-using-c-gcc/" rel="bookmark" title="Coding Exercise &#8211; Simple [nl] Implementation on Windows Platform using C++ (GCC)">Coding Exercise &#8211; Simple [nl] Implementation on Windows Platform using C++ (GCC)</a> <small>On Linux BASH shell, the &#8216;nl&#8217; utility is used to print out text file (or...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://helloacm.com/cp-m-the-operating-system-that-came-before-ms-dos/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>From Drag-and-Drop to Directing AI: Faster Coding, but Are We Growing as Developers?</title>
		<link>https://helloacm.com/from-drag-and-drop-to-directing-ai-faster-coding-but-are-we-growing-as-developers/</link>
					<comments>https://helloacm.com/from-drag-and-drop-to-directing-ai-faster-coding-but-are-we-growing-as-developers/#respond</comments>
		
		<dc:creator><![CDATA[ACMer]]></dc:creator>
		<pubDate>Wed, 16 Sep 2026 15:49:48 +0000</pubDate>
				<category><![CDATA[AGI: Artificial General Intelligence]]></category>
		<category><![CDATA[Artificial Intelligence]]></category>
		<category><![CDATA[Engineering]]></category>
		<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[AI Agents]]></category>
		<category><![CDATA[AI coding]]></category>
		<category><![CDATA[artificial intelligence]]></category>
		<category><![CDATA[code review]]></category>
		<category><![CDATA[delphi]]></category>
		<category><![CDATA[Developer Learning]]></category>
		<category><![CDATA[Developer Productivity]]></category>
		<category><![CDATA[GPT-6 Astra]]></category>
		<category><![CDATA[Human in the Loop]]></category>
		<category><![CDATA[Prompt Engineering]]></category>
		<category><![CDATA[RAD]]></category>
		<category><![CDATA[rapid application development]]></category>
		<category><![CDATA[software engineering]]></category>
		<category><![CDATA[VB6]]></category>
		<guid isPermaLink="false">https://helloacm.com/?p=158105</guid>

					<description><![CDATA[<blockquote>
From building interfaces in VB and Delphi to directing multiple AI <a href="https://helloacm.com/ai-coding-agents-are-reshaping-the-barrier-to-programming/" title="AI Coding Agents Are Reshaping the Barrier to Programming">agents</a>, software development has changed dramatically. This reflection explores the enduring value of RAD, the productivity gains of AI coding, and the challenges of code review and continuous learning. We can produce more software, but are we becoming better developers at the same rate?
</blockquote>

Putting these two pictures side by side makes me feel a little nostalgic. One shows the familiar Visual Basic form designer. The other shows someone telling an AI agent, “Fix this shit.” From dragging buttons onto a form and double-clicking to write event handlers, to describing requirements and waiting for AI to change the code, the way we develop software has changed considerably.

[caption id="attachment_158106" align="alignnone" width="640"]<a href="https://helloacm.com/from-drag-and-drop-to-directing-ai-faster-coding-but-are-we-growing-as-developers/old-rad-development-application/" rel="attachment wp-att-158106"><img src="https://helloacm.com/wp-content/uploads/2026/09/old-rad-development-application.jpg" alt="Visual Basic form designer" width="640" height="506" class="size-full wp-image-158106" /></a> Visual Basic form designer[/caption]

<em>Back then, you could drag a button onto a window, double-click it, write a few lines of code, and watch a small application take shape.</em>

<h2>Remembering the Days of VB and Delphi</h2>

When we used to develop desktop applications, RAD was an exciting concept: <a href="https://helloacm.com/delphi-is-30-years-old/" title="Delphi is 30 Years Old!">Rapid Application Development</a>. The names that immediately come to mind are VB and Delphi. Drag in a button, add a text box, adjust a few properties, and write the event handlers. The interface and its behaviour came together inside a single IDE.

What you saw was what you got, and the feedback was immediate. Watching an empty window gradually become a useful application gave you a very tangible sense of achievement. At the time, I thought this technology was brilliant. Learn it properly, and surely you could use it for the rest of your career.

You may have heard this programming joke: “Smart programmers use Delphi; real programmers use C++.” It is part praise for productive tools and part rivalry over technical skill. Joking aside, a programmer’s ability ultimately shows in how clearly they understand a problem and how reliably their software solves it. In the AI era, perhaps we can add another line: “Smart programmers get AI to help write code; seasoned programmers know which decisions they must make themselves.” Our tools can do more and more of the work, but we still need to understand the results and take responsibility for them.

<h3>VB6’s Convenience and the Cost of Moving On</h3>

VB6, in particular, struck a comfortable balance between an approachable <a href="https://helloacm.com/modern-c-language-features/" title="Modern C++ Language Features">language</a>, GUI design, and an integrated development environment. If you wanted to build a small utility, you could get straight to solving the problem without first setting up an elaborate project structure.

Microsoft later shifted its development focus towards .NET, and support for the VB6 IDE ended in 2008. However, ending support for the development tools is different from making existing applications stop working. The core VB6 runtime still receives limited support on supported versions of Windows. <a href="https://learn.microsoft.com/en-us/previous-versions/visualstudio/visual-basic-6/visual-basic-6-support-policy">Microsoft’s VB6 support statement</a>

I understand why that transition disappointed long-time developers. .NET had its own technical merits, but for people already getting their work done perfectly well with VB6, migration meant learning again, adapting existing code, and getting used to another ecosystem. The platform moved forward, but the time developers had already invested did not necessarily carry over intact. What I miss is that feeling of having a comfortable tool with manageable complexity: open it and get to work.

<h3>Can One Technology Really Last an Entire Career?</h3>

Looking back, the idea of learning one technology and relying on it for a lifetime seems rather optimistic. The tooling around JavaScript and Node.js is a particularly striking example: frameworks, build tools, dependency management, and layers of abstraction piled on top of one another. Every so often, another unfamiliar name appears. It is easy to feel that the next generation has arrived before you have understood the previous one. Of course, a new framework appearing does not immediately make your existing one obsolete. Whether to adopt it should depend on what the project actually needs.

<h2>Will AI Make RAD Obsolete?</h2>

With the rise of AI over the past couple of years, I have started to feel that the drag-and-drop experience, once so important, matters a little less.

That makes sense. Visual designers are primarily tools for people: they turn the work of building an interface into something we can manipulate directly. AI can generate interface code, layouts, and event logic without first picking up a mouse and dragging a button from a toolbox onto a form. Steps that engineers once performed manually can now be delegated to a model.

Still, saying that “AI has replaced RAD” would go too far. Strictly speaking, RAD is a development methodology that emphasises rapid prototyping, iteration, and user feedback. Dragging controls around is just one familiar way its tools can support that process. <a href="https://www.ibm.com/think/topics/rapid-application-development">IBM’s introduction to RAD</a>

RAD Studio, which includes Delphi, is also still evolving, and its visual development tools are incorporating AI capabilities. <a href="https://www.embarcadero.com/products/rad-studio">RAD Studio’s official overview</a> Viewed this way, AI can accelerate the process of building a prototype, gathering feedback, and making the next round of changes.

AI does not need to drag controls around to generate an interface. People still need to see the result, try the product, and decide whether the interactions make sense. Automatically generating a form’s code does not automatically answer which fields users should fill in or where they might make mistakes.

<h2>From Dragging Controls to Directing Multiple Agents</h2>

[caption id="attachment_158107" align="alignnone" width="2048"]<a href="https://helloacm.com/from-drag-and-drop-to-directing-ai-faster-coding-but-are-we-growing-as-developers/vscode-gpt-6-astra/" rel="attachment wp-att-158107"><img src="https://helloacm.com/wp-content/uploads/2026/09/vscode-gpt-6-astra-scaled.jpg" alt="GPT-6 Astra and the AI agent development interface" width="2048" height="1151" class="size-full wp-image-158107" /></a> GPT-6 Astra and the AI agent development interface[/caption]

<em>From dragging a button ourselves to assigning a task to an agent, our relationship with development tools has changed.</em>

These days, my routine involves firing up GPT-6 Astra and doing some prompt engineering: explaining the requirements, supplying context, setting constraints, and then waiting ten or twenty minutes to see what the agent produces.

While waiting, I can open several threads and direct multiple agents at once. One implements a feature, another investigates a problem, and a third reviews changes. I move between tasks, answer questions, correct their direction, and check the results. Previously, most of my attention went to the function I was writing. Now I also have to watch how several tasks fit together and whether different agents have interpreted the same requirement differently.

The “Fix this shit.” in the screenshot is funny and captures a programmer’s mood rather well. But getting the job done properly usually requires considerably more context: what is broken, what should happen, which behaviours must remain intact, and what counts as a successful fix. The more capable the model becomes, the more important it is to make those conditions clear. Otherwise, it may solve the wrong problem very efficiently.

<h2>Once AI Writes the Code, Who Understands and Reviews It?</h2>

The code certainly arrives faster. But as more of it comes back, another <a href="https://helloacm.com/what-is-tcp-ip-4-layer-vs-osi-7-layer/" title="Software Engineer Interview Question: What is TCP/IP (4 Layer vs OSI 7 Layer)?">question</a> appears: can we still keep up with reading it?

<h3>Easier Than Assembly Is a Very Low Bar</h3>

Sometimes I think that however difficult AI-generated code becomes to understand, surely it is still easier to read than assembly. On reflection, though, that is a rather low standard. Understanding the syntax of a line of high-level code and understanding why an entire system was designed a certain way are very different challenges. You may recognise every function name and follow the logic, yet still miss the edge cases affected by a change.

Of course, AI-generated code is not destined to be unreadable. If we can ask a model to implement a feature, we should also ask it to keep the design simple, avoid unnecessary abstractions, and explain the important trade-offs. Cheap code generation does not give the people maintaining it unlimited time.

<h3>A Human in the Loop Must Do More Than Click Approve</h3>

I expect more code reviews to begin with an AI pass: checking common mistakes, tracing the paths affected by a change, and identifying missing tests. Engineers can then examine the changes more deeply according to risk. Permissions, security, data integrity, and critical business rules especially need someone who understands the implications and takes responsibility.

But “AI writes it, then AI reviews it” does not automatically guarantee correctness. Two agents may accept the same mistaken assumption. If they misunderstand the requirement from the start, the code and its tests can be consistently wrong together.

That is why I think a human in the loop remains essential, and that involvement must be meaningful. Engineers need enough context and time to question an implementation, ask for evidence, and reject a change. If the amount of code they face each day multiplies while their review time stays the same, the process can easily shrink to little more than clicking “Approve”.

<h2>Our Output Is Growing Faster Than Our Experience</h2>

This brings me to something that has been on my mind lately: <strong>my output has increased, but the experience and sense of achievement I get from the work have not increased at the same rate.</strong>

Previously, solving a problem myself meant reading documentation, trying approaches, making mistakes, debugging, and eventually discovering the cause. The process could be frustrating, but those mistakes and detours became part of my experience. Now AI can quickly deliver a working result, and I can understand its explanation. Yet there is still a gap between “I understand what it says” and “I can make that judgement independently next time”.

Directing five agents at once can move five tasks forward. It does not make me absorb the knowledge involved five times faster. The more frequently I switch between tasks, the easier it becomes to remember the conclusions without having time to digest the reasoning.

<h3>Making Time to Understand</h3>

That does not mean I have to rewrite every line by hand to learn anything. AI can help with learning too: comparing two approaches, explaining an edge case, or walking me through reproducing a failure. The key is to leave time for understanding, make my own judgements, and test those judgements against actual results. Otherwise, it becomes easy to mistake “the project is finished” for “I have mastered the skills involved”.

Looking back at those VB and <a href="https://helloacm.com/simple-and-fast-hash-functions-in-delphi/" title="Simple and Fast Hash Functions in Delphi">Delphi</a> windows, I also miss a very clear connection: I knew what I had done, how the program had changed because of it, and what I had learnt along the way. That connection is less direct now, and the sense of achievement needs to come from other parts of the work as well. Defining a problem clearly, spotting a flawed approach, and combining several agents’ contributions into a reliable system all require engineering ability.

However quickly the tools change, I still hope to finish each project with a working program and a few more things I truly understand.

[show_file file="/var/www/wp-post-common/helloacm.com/ai.php"]

[show_posts keyword="Software Engineering"]

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/a-google-alert-woke-me-up-postmortem-of-a-wordpress-security-incident/" rel="bookmark" title="A Google Alert Woke Me Up: Postmortem of a WordPress Security Incident">A Google Alert Woke Me Up: Postmortem of a WordPress Security Incident</a> <small>An unpatched WordPress and plugin vulnerability apparently exposed a Cloudflare credential stored in the database....</small></li>
<li><a href="https://helloacm.com/software-engineering-companies-which-company-pays-most-and-which-company-is-hardest-to-get-in/" rel="bookmark" title="Software Engineering Companies: Which Company Pays Most? and Which Company Is Hardest to Get In?">Software Engineering Companies: Which Company Pays Most? and Which Company Is Hardest to Get In?</a> <small>Software Engineering Companies Acronyms These are acronyms used to refer to groups of major tech...</small></li>
<li><a href="https://helloacm.com/the-memory-manager-in-c-c-heap-vs-stack/" rel="bookmark" title="The Memory Manager in C/C++ (Heap vs Stack)">The Memory Manager in C/C++ (Heap vs Stack)</a> <small>This is one of the most frequently asked interview questions for Software Engineer roles. In...</small></li>
<li><a href="https://helloacm.com/hardening-wordpress-disable-php-execution-in-wp-content-uploads/" rel="bookmark" title="Hardening WordPress: Disable PHP Execution in `wp-content/uploads`">Hardening WordPress: Disable PHP Execution in `wp-content/uploads`</a> <small>WordPress must be able to write media files to `wp-content/uploads`, but files stored there should...</small></li>
<li><a href="https://helloacm.com/how-to-make-ping-tests-to-global-servers-using-php/" rel="bookmark" title="How to Make Ping Tests to Global Servers using PHP?">How to Make Ping Tests to Global Servers using PHP?</a> <small>I recently consider purchasing my third VPS Server and the ping speed is one of...</small></li>
<li><a href="https://helloacm.com/why-and-when-should-you-do-a-profiling-on-your-application/" rel="bookmark" title="Why and When should you do a Profiling on Your Application?">Why and When should you do a Profiling on Your Application?</a> <small>There was a time that a bug was assigned to me saying that my module...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-verify-preorder-sequence-in-binary-search-tree-monotonous-stack/" rel="bookmark" title="Teaching Kids Programming &#8211; Verify Preorder Sequence in Binary Search Tree (Monotonous Stack)">Teaching Kids Programming &#8211; Verify Preorder Sequence in Binary Search Tree (Monotonous Stack)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms A stack-based solution for LeetCode 255,...</small></li>
<li><a href="https://helloacm.com/trick-count-the-number-of-api-in-com/" rel="bookmark" title="Trick: Count the Number of API in COM">Trick: Count the Number of API in COM</a> <small>Delphi is a handy tool to develop the COM (Component Object Model) DLL. A *_TLB.pas...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<blockquote>
From building interfaces in VB and Delphi to directing multiple AI <a href="https://helloacm.com/ai-coding-agents-are-reshaping-the-barrier-to-programming/" title="AI Coding Agents Are Reshaping the Barrier to Programming">agents</a>, software development has changed dramatically. This reflection explores the enduring value of RAD, the productivity gains of AI coding, and the challenges of code review and continuous learning. We can produce more software, but are we becoming better developers at the same rate?
</blockquote>

Putting these two pictures side by side makes me feel a little nostalgic. One shows the familiar Visual Basic form designer. The other shows someone telling an AI agent, “Fix this shit.” From dragging buttons onto a form and double-clicking to write event handlers, to describing requirements and waiting for AI to change the code, the way we develop software has changed considerably.

[caption id="attachment_158106" align="alignnone" width="640"]<a href="https://helloacm.com/from-drag-and-drop-to-directing-ai-faster-coding-but-are-we-growing-as-developers/old-rad-development-application/" rel="attachment wp-att-158106"><img src="https://helloacm.com/wp-content/uploads/2026/09/old-rad-development-application.jpg" alt="Visual Basic form designer" width="640" height="506" class="size-full wp-image-158106" /></a> Visual Basic form designer[/caption]

<em>Back then, you could drag a button onto a window, double-click it, write a few lines of code, and watch a small application take shape.</em>

<h2>Remembering the Days of VB and Delphi</h2>

When we used to develop desktop applications, RAD was an exciting concept: <a href="https://helloacm.com/delphi-is-30-years-old/" title="Delphi is 30 Years Old!">Rapid Application Development</a>. The names that immediately come to mind are VB and Delphi. Drag in a button, add a text box, adjust a few properties, and write the event handlers. The interface and its behaviour came together inside a single IDE.

What you saw was what you got, and the feedback was immediate. Watching an empty window gradually become a useful application gave you a very tangible sense of achievement. At the time, I thought this technology was brilliant. Learn it properly, and surely you could use it for the rest of your career.

You may have heard this programming joke: “Smart programmers use Delphi; real programmers use C++.” It is part praise for productive tools and part rivalry over technical skill. Joking aside, a programmer’s ability ultimately shows in how clearly they understand a problem and how reliably their software solves it. In the AI era, perhaps we can add another line: “Smart programmers get AI to help write code; seasoned programmers know which decisions they must make themselves.” Our tools can do more and more of the work, but we still need to understand the results and take responsibility for them.

<h3>VB6’s Convenience and the Cost of Moving On</h3>

VB6, in particular, struck a comfortable balance between an approachable <a href="https://helloacm.com/modern-c-language-features/" title="Modern C++ Language Features">language</a>, GUI design, and an integrated development environment. If you wanted to build a small utility, you could get straight to solving the problem without first setting up an elaborate project structure.

Microsoft later shifted its development focus towards .NET, and support for the VB6 IDE ended in 2008. However, ending support for the development tools is different from making existing applications stop working. The core VB6 runtime still receives limited support on supported versions of Windows. <a href="https://learn.microsoft.com/en-us/previous-versions/visualstudio/visual-basic-6/visual-basic-6-support-policy">Microsoft’s VB6 support statement</a>

I understand why that transition disappointed long-time developers. .NET had its own technical merits, but for people already getting their work done perfectly well with VB6, migration meant learning again, adapting existing code, and getting used to another ecosystem. The platform moved forward, but the time developers had already invested did not necessarily carry over intact. What I miss is that feeling of having a comfortable tool with manageable complexity: open it and get to work.

<h3>Can One Technology Really Last an Entire Career?</h3>

Looking back, the idea of learning one technology and relying on it for a lifetime seems rather optimistic. The tooling around JavaScript and Node.js is a particularly striking example: frameworks, build tools, dependency management, and layers of abstraction piled on top of one another. Every so often, another unfamiliar name appears. It is easy to feel that the next generation has arrived before you have understood the previous one. Of course, a new framework appearing does not immediately make your existing one obsolete. Whether to adopt it should depend on what the project actually needs.

<h2>Will AI Make RAD Obsolete?</h2>

With the rise of AI over the past couple of years, I have started to feel that the drag-and-drop experience, once so important, matters a little less.

That makes sense. Visual designers are primarily tools for people: they turn the work of building an interface into something we can manipulate directly. AI can generate interface code, layouts, and event logic without first picking up a mouse and dragging a button from a toolbox onto a form. Steps that engineers once performed manually can now be delegated to a model.

Still, saying that “AI has replaced RAD” would go too far. Strictly speaking, RAD is a development methodology that emphasises rapid prototyping, iteration, and user feedback. Dragging controls around is just one familiar way its tools can support that process. <a href="https://www.ibm.com/think/topics/rapid-application-development">IBM’s introduction to RAD</a>

RAD Studio, which includes Delphi, is also still evolving, and its visual development tools are incorporating AI capabilities. <a href="https://www.embarcadero.com/products/rad-studio">RAD Studio’s official overview</a> Viewed this way, AI can accelerate the process of building a prototype, gathering feedback, and making the next round of changes.

AI does not need to drag controls around to generate an interface. People still need to see the result, try the product, and decide whether the interactions make sense. Automatically generating a form’s code does not automatically answer which fields users should fill in or where they might make mistakes.

<h2>From Dragging Controls to Directing Multiple Agents</h2>

[caption id="attachment_158107" align="alignnone" width="2048"]<a href="https://helloacm.com/from-drag-and-drop-to-directing-ai-faster-coding-but-are-we-growing-as-developers/vscode-gpt-6-astra/" rel="attachment wp-att-158107"><img src="https://helloacm.com/wp-content/uploads/2026/09/vscode-gpt-6-astra-scaled.jpg" alt="GPT-6 Astra and the AI agent development interface" width="2048" height="1151" class="size-full wp-image-158107" /></a> GPT-6 Astra and the AI agent development interface[/caption]

<em>From dragging a button ourselves to assigning a task to an agent, our relationship with development tools has changed.</em>

These days, my routine involves firing up GPT-6 Astra and doing some prompt engineering: explaining the requirements, supplying context, setting constraints, and then waiting ten or twenty minutes to see what the agent produces.

While waiting, I can open several threads and direct multiple agents at once. One implements a feature, another investigates a problem, and a third reviews changes. I move between tasks, answer questions, correct their direction, and check the results. Previously, most of my attention went to the function I was writing. Now I also have to watch how several tasks fit together and whether different agents have interpreted the same requirement differently.

The “Fix this shit.” in the screenshot is funny and captures a programmer’s mood rather well. But getting the job done properly usually requires considerably more context: what is broken, what should happen, which behaviours must remain intact, and what counts as a successful fix. The more capable the model becomes, the more important it is to make those conditions clear. Otherwise, it may solve the wrong problem very efficiently.

<h2>Once AI Writes the Code, Who Understands and Reviews It?</h2>

The code certainly arrives faster. But as more of it comes back, another <a href="https://helloacm.com/what-is-tcp-ip-4-layer-vs-osi-7-layer/" title="Software Engineer Interview Question: What is TCP/IP (4 Layer vs OSI 7 Layer)?">question</a> appears: can we still keep up with reading it?

<h3>Easier Than Assembly Is a Very Low Bar</h3>

Sometimes I think that however difficult AI-generated code becomes to understand, surely it is still easier to read than assembly. On reflection, though, that is a rather low standard. Understanding the syntax of a line of high-level code and understanding why an entire system was designed a certain way are very different challenges. You may recognise every function name and follow the logic, yet still miss the edge cases affected by a change.

Of course, AI-generated code is not destined to be unreadable. If we can ask a model to implement a feature, we should also ask it to keep the design simple, avoid unnecessary abstractions, and explain the important trade-offs. Cheap code generation does not give the people maintaining it unlimited time.

<h3>A Human in the Loop Must Do More Than Click Approve</h3>

I expect more code reviews to begin with an AI pass: checking common mistakes, tracing the paths affected by a change, and identifying missing tests. Engineers can then examine the changes more deeply according to risk. Permissions, security, data integrity, and critical business rules especially need someone who understands the implications and takes responsibility.

But “AI writes it, then AI reviews it” does not automatically guarantee correctness. Two agents may accept the same mistaken assumption. If they misunderstand the requirement from the start, the code and its tests can be consistently wrong together.

That is why I think a human in the loop remains essential, and that involvement must be meaningful. Engineers need enough context and time to question an implementation, ask for evidence, and reject a change. If the amount of code they face each day multiplies while their review time stays the same, the process can easily shrink to little more than clicking “Approve”.

<h2>Our Output Is Growing Faster Than Our Experience</h2>

This brings me to something that has been on my mind lately: <strong>my output has increased, but the experience and sense of achievement I get from the work have not increased at the same rate.</strong>

Previously, solving a problem myself meant reading documentation, trying approaches, making mistakes, debugging, and eventually discovering the cause. The process could be frustrating, but those mistakes and detours became part of my experience. Now AI can quickly deliver a working result, and I can understand its explanation. Yet there is still a gap between “I understand what it says” and “I can make that judgement independently next time”.

Directing five agents at once can move five tasks forward. It does not make me absorb the knowledge involved five times faster. The more frequently I switch between tasks, the easier it becomes to remember the conclusions without having time to digest the reasoning.

<h3>Making Time to Understand</h3>

That does not mean I have to rewrite every line by hand to learn anything. AI can help with learning too: comparing two approaches, explaining an edge case, or walking me through reproducing a failure. The key is to leave time for understanding, make my own judgements, and test those judgements against actual results. Otherwise, it becomes easy to mistake “the project is finished” for “I have mastered the skills involved”.

Looking back at those VB and <a href="https://helloacm.com/simple-and-fast-hash-functions-in-delphi/" title="Simple and Fast Hash Functions in Delphi">Delphi</a> windows, I also miss a very clear connection: I knew what I had done, how the program had changed because of it, and what I had learnt along the way. That connection is less direct now, and the sense of achievement needs to come from other parts of the work as well. Defining a problem clearly, spotting a flawed approach, and combining several agents’ contributions into a reliable system all require engineering ability.

However quickly the tools change, I still hope to finish each project with a working program and a few more things I truly understand.

[show_file file="/var/www/wp-post-common/helloacm.com/ai.php"]

[show_posts keyword="Software Engineering"]

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/a-google-alert-woke-me-up-postmortem-of-a-wordpress-security-incident/" rel="bookmark" title="A Google Alert Woke Me Up: Postmortem of a WordPress Security Incident">A Google Alert Woke Me Up: Postmortem of a WordPress Security Incident</a> <small>An unpatched WordPress and plugin vulnerability apparently exposed a Cloudflare credential stored in the database....</small></li>
<li><a href="https://helloacm.com/software-engineering-companies-which-company-pays-most-and-which-company-is-hardest-to-get-in/" rel="bookmark" title="Software Engineering Companies: Which Company Pays Most? and Which Company Is Hardest to Get In?">Software Engineering Companies: Which Company Pays Most? and Which Company Is Hardest to Get In?</a> <small>Software Engineering Companies Acronyms These are acronyms used to refer to groups of major tech...</small></li>
<li><a href="https://helloacm.com/the-memory-manager-in-c-c-heap-vs-stack/" rel="bookmark" title="The Memory Manager in C/C++ (Heap vs Stack)">The Memory Manager in C/C++ (Heap vs Stack)</a> <small>This is one of the most frequently asked interview questions for Software Engineer roles. In...</small></li>
<li><a href="https://helloacm.com/hardening-wordpress-disable-php-execution-in-wp-content-uploads/" rel="bookmark" title="Hardening WordPress: Disable PHP Execution in `wp-content/uploads`">Hardening WordPress: Disable PHP Execution in `wp-content/uploads`</a> <small>WordPress must be able to write media files to `wp-content/uploads`, but files stored there should...</small></li>
<li><a href="https://helloacm.com/how-to-make-ping-tests-to-global-servers-using-php/" rel="bookmark" title="How to Make Ping Tests to Global Servers using PHP?">How to Make Ping Tests to Global Servers using PHP?</a> <small>I recently consider purchasing my third VPS Server and the ping speed is one of...</small></li>
<li><a href="https://helloacm.com/why-and-when-should-you-do-a-profiling-on-your-application/" rel="bookmark" title="Why and When should you do a Profiling on Your Application?">Why and When should you do a Profiling on Your Application?</a> <small>There was a time that a bug was assigned to me saying that my module...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-verify-preorder-sequence-in-binary-search-tree-monotonous-stack/" rel="bookmark" title="Teaching Kids Programming &#8211; Verify Preorder Sequence in Binary Search Tree (Monotonous Stack)">Teaching Kids Programming &#8211; Verify Preorder Sequence in Binary Search Tree (Monotonous Stack)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms A stack-based solution for LeetCode 255,...</small></li>
<li><a href="https://helloacm.com/trick-count-the-number-of-api-in-com/" rel="bookmark" title="Trick: Count the Number of API in COM">Trick: Count the Number of API in COM</a> <small>Delphi is a handy tool to develop the COM (Component Object Model) DLL. A *_TLB.pas...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://helloacm.com/from-drag-and-drop-to-directing-ai-faster-coding-but-are-we-growing-as-developers/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>When AI Writes the Code, What Skills Do Developers Still Need?</title>
		<link>https://helloacm.com/when-ai-writes-the-code-what-skills-do-developers-still-need/</link>
					<comments>https://helloacm.com/when-ai-writes-the-code-what-skills-do-developers-still-need/#respond</comments>
		
		<dc:creator><![CDATA[ACMer]]></dc:creator>
		<pubDate>Wed, 09 Sep 2026 15:26:01 +0000</pubDate>
				<category><![CDATA[Artificial Intelligence]]></category>
		<category><![CDATA[ChatGPT (OpenAI)]]></category>
		<category><![CDATA[Harness Engineering]]></category>
		<category><![CDATA[software development]]></category>
		<category><![CDATA[Vibe Coding]]></category>
		<category><![CDATA[AI Agents]]></category>
		<category><![CDATA[AI coding]]></category>
		<category><![CDATA[AI Evolution]]></category>
		<category><![CDATA[artificial intelligence]]></category>
		<category><![CDATA[ChatGPT]]></category>
		<category><![CDATA[Future of Programming]]></category>
		<category><![CDATA[Large Language Models]]></category>
		<category><![CDATA[MCP]]></category>
		<category><![CDATA[Multimodal AI]]></category>
		<category><![CDATA[Natural Language Programming]]></category>
		<category><![CDATA[Software Developers]]></category>
		<category><![CDATA[software engineering]]></category>
		<category><![CDATA[Tool Calling]]></category>
		<guid isPermaLink="false">https://helloacm.com/?p=158098</guid>

					<description><![CDATA[<h2>From Chatting to Taking Action: AI Is Turning Yesterday’s Wonders into Today’s Routine</h2>

Recently, I came across a video from more than three years ago. In it, we were still amazed that ChatGPT could hold a conversation like that.

Ask it a question, and it could give a coherent answer. Ask it to explain some code, and it could walk through it line by line. Ask it to write a function, and it could produce an implementation. Even then, I felt this technology would change the world.

Looking back now, that experience seems surprisingly basic. Our excitement was understandable; what followed simply happened faster than we had imagined.

<h2>From Stack Overflow to Asking AI Directly</h2>

Previously, when programmers encountered a problem, we would usually search online, browse <a href="https://helloacm.com/the-404-not-found-code-of-stackoverflow/" title="The 404-not-found Code of StackOverFlow">Stack Overflow</a>, read documentation, and work through discussions, piecing together a solution from several pages. “Copy &amp; Paste” was always a slightly tongue-in-cheek description. The time-consuming part was often deciding which answer applied and adapting it to our needs.

Watching the video from three years ago, even the pace at which AI’s replies appeared on screen was noticeably slower than it is today. Back then, we would stare at the screen and patiently wait for it to finish, fascinated by the words taking shape in real time. Today, responses arrive faster and AI can handle much more complex tasks, yet we already complain that it takes too long to think or act. We adapt remarkably quickly: as technology advances, our expectations rise with it, and experiences that once amazed us soon become the standard we take for granted.

<iframe width="1840" height="1035" src="https://www.youtube.com/embed/garlKUEw1oA" title="ChatGPT Amazed Us 3 Years Ago—Now AI Can Take Action 三年前，ChatGPT 会聊天就让我们惊叹了！如今 AI 已经能动手干活" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

ChatGPT compressed many of those steps into a conversation. It could explain concepts, organise information, and provide examples, and we could keep asking follow-up questions. Avoiding all that switching between browser tabs was already exciting enough.

But at that stage, it mostly did the talking while we did the work. It suggested a command, and we copied it into a terminal. It generated code, and we pasted it into an editor. When something failed, we copied the error message back into the chat.

<h2>AI Began to Gain “Eyes”, “Ears”, and “Hands”</h2>

Before long, AI’s capabilities expanded beyond text conversations into seeing, listening, and acting. It could “look at” images, screenshots, and videos and interpret their contents; “listen to” speech, recognise what we say, and respond by voice; and use tools to read files, modify code, execute commands, and adjust its approach based on the results.

These “eyes”, “ears”, and “hands” are metaphors, of course. Behind them are multimodal understanding, voice interaction, and tools and execution environments that connect AI to external systems. The capabilities available also vary between models and products.

MCP, or Model Context Protocol, provides a standard way to connect data sources and tools, making it easier for AI to work with external systems. It is one of the standard interfaces for connecting those “hands”, rather than the source of all these capabilities.

The practical difference is straightforward: previously, I had to describe what I saw in text and transfer AI-generated code and commands to my computer myself. Now, I can provide a screenshot, a voice message, or a clearly defined task and let it analyse, modify, run, and check things within its authorised scope.

The chat box still looks familiar, but behind it are growing capabilities to perceive information and take action.

Reference: <a href="https://www.anthropic.com/news/model-context-protocol">Anthropic: Introducing the Model Context Protocol</a>

<h2>From Explaining Coding Problems to Contributing to Mathematical Research</h2>

Meanwhile, the models themselves continue to become more capable, even reaching into frontier mathematics.

On 8 September 2026, OpenAI announced that its internal AI system had produced a proof addressing the Navier–Stokes existence and smoothness problem. This concerns whether three-dimensional fluid motion can develop a singularity within a finite time. The relevant research dates back to 1934, and the problem later became one of the Millennium Prize Problems.

According to the announcement, the group that found the solution involved approximately 10,000 collaborating <a href="https://helloacm.com/ai-coding-agents-are-reshaping-the-barrier-to-programming/" title="AI Coding Agents Are Reshaping the Barrier to Programming">agents</a> and arrived at its result after about 88 hours. GPT-6 Astra then participated in a further 17 hours of Lean formalisation and verification.

Reference: <a href="https://openai.com/index/navier-stokes-solution/">OpenAI: On the Navier–Stokes Millennium Prize Problem</a>

<h3>Remarkable Progress Still Requires Precise Reporting</h3>

One distinction matters here: the proof came from an internal system more capable than Astra. It would be misleading to describe this as someone asking ChatGPT a question and Astra immediately solving a century-old problem.

Also, at the time of writing, the Clay Mathematics Institute’s website still lists the problem as unsolved. A company publishing a proof, formal verification, and thorough scrutiny and acceptance by the mathematical community are distinct stages.

Reference: <a href="https://www.claymath.org/millennium-problems/">Clay Mathematics Institute: The Millennium Prize Problems</a>

Even with those qualifications, the development is remarkable. Just over three years ago, we were impressed that AI could explain a programming exercise. Today, we need to seriously consider its role in major mathematical research.

<h2>From Vibe Coding to Harness Engineering</h2>

The changes are just as visible in programmers’ everyday work.

<h3>Turning Ideas into Software Through Natural Language</h3>

The experience associated with vibe coding is to describe an idea in natural language, let AI build an initial version, and refine it through feedback. This is particularly compelling for prototypes and small tools: things that previously required line-by-line implementation can now begin with a description.

However, there is still a substantial gap between producing a working demo and maintaining reliable software over time.

<h3>Helping AI Work Reliably and Consistently</h3>

This is why harness engineering deserves attention. It is an engineering approach focused on providing AI with the working environment, context, tools, constraints, and feedback mechanisms it needs to complete tasks reliably.

In an engineering article, OpenAI described an experiment in which a team built a product using Codex, with agents generating all the code while engineers defined goals, designed the environment, and established feedback loops.

Reference: <a href="https://openai.com/index/harness-engineering/">OpenAI: Harness Engineering</a>

Increasingly, I feel that programmers can delegate a substantial amount of manual coding to AI across many development tasks. But saying that programmers “basically no longer need to write code” is still too broad. Projects differ enormously in complexity, legacy constraints, and reliability requirements.

<strong>We may spend less time typing code, but that does not necessarily mean we spend less effort defining problems, reviewing results, and evaluating trade-offs.</strong>

<h2>Will English Be the Programming Language of the Future?</h2>

I sometimes joke that the <a href="https://helloacm.com/teaching-kids-programming-vlog-harness-engineering-commanding-ai-to-get-work-done/" title="Teaching Kids Programming vLog: Harness Engineering — Commanding AI to Get Work Done">programming</a> language of the future is English.

More precisely, it is natural language. English works, and so does Chinese. Previously, we had to translate requirements into a programming language ourselves. Increasingly, we can delegate that translation and implementation to AI.

But the phrase “you only need to describe your requirements” makes it easy to underestimate how difficult that can be.

<h3>Expressing Requirements Clearly Is a Skill</h3>

“Optimise this service for me” sounds clear, but it leaves almost everything unspecified.

<ul>
<li>Are we reducing average latency or improving P99 latency?</li>
<li>Are we increasing throughput or reducing costs?</li>
<li>Can the interface change?</li>
<li>How much accuracy, if any, can we sacrifice?</li>
<li>How will we establish whether the change actually helped?</li>
</ul>

Without answers to these questions, even an excellent AI coding system can move very efficiently in the wrong direction.

<h2>You Can Delegate Code Generation, but You Still Need to Develop Your Judgement</h2>

<h3>The Ability to Read Code</h3>

You do not have to write every line yourself, but you need to be able to inspect critical logic, trace data flows, and identify questionable assumptions.

Tests matter too, but passing tests only demonstrates that the code passed those particular tests. It does not automatically establish that the requirements were understood correctly.

<h3>Domain Expertise</h3>

Domain expertise remains essential. Understanding business rules, the meaning of the data, and real usage scenarios helps you judge whether an impressive-looking implementation actually solves the problem.

Some mistakes never raise an exception. The software may even perform extremely well while producing something the user never needed.

<h3>Software Engineering Skills</h3>

<a href="https://helloacm.com/interview-question-what-happens-when-you-type-google-com-in-the-browser-address-bar/" title="Software Engineering Interview Question: What Happens When You Type Google.com in the Browser Address Bar?">Software engineering</a> skills do not lose their value simply because generating code becomes easier. Architecture, interfaces, maintainability, observability, deployment, and rollback still require careful thought. The faster code is produced, the more important it becomes to keep those disciplines in step.

Using AI well is therefore becoming a skill in its own right. It involves much more than remembering a few effective prompts. It includes breaking down tasks, providing context, defining acceptance criteria, and knowing what to trust, what to verify, and what to question further.

<h2>Yesterday’s Wonders Are Becoming Today’s Default Expectations</h2>

What strikes me most about AI is how quickly it changes our idea of “normal”.

The first time it generates working code, it feels extraordinary. After using it for a while, we start wondering why it did not write the tests as well. Once it can modify, test, and fix the code itself, we begin expecting it to deliver the entire feature.

Yesterday’s surprise quickly becomes today’s minimum expectation. Once something we thought impossible becomes possible, we adapt faster than we might have imagined.

More than three years ago, I looked at ChatGPT’s responses and felt that it would change the world. Watching that old video now, I still agree with that judgement. I simply have a much more concrete understanding of what that change looks like.

AI has already entered our workflows and shortened the distance between an idea and a working result.

I need to keep adapting too: placing less emphasis on how much code I personally write, and asking whether I can identify worthwhile problems, explain them clearly, and judge whether the final result stands up to scrutiny.

[show_file file="/var/www/wp-post-common/helloacm.com/software-engineer.php"]

[show_posts keyword="chatgpt"]

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/a-google-alert-woke-me-up-postmortem-of-a-wordpress-security-incident/" rel="bookmark" title="A Google Alert Woke Me Up: Postmortem of a WordPress Security Incident">A Google Alert Woke Me Up: Postmortem of a WordPress Security Incident</a> <small>An unpatched WordPress and plugin vulnerability apparently exposed a Cloudflare credential stored in the database....</small></li>
<li><a href="https://helloacm.com/the-memory-manager-in-c-c-heap-vs-stack/" rel="bookmark" title="The Memory Manager in C/C++ (Heap vs Stack)">The Memory Manager in C/C++ (Heap vs Stack)</a> <small>This is one of the most frequently asked interview questions for Software Engineer roles. In...</small></li>
<li><a href="https://helloacm.com/hardening-wordpress-disable-php-execution-in-wp-content-uploads/" rel="bookmark" title="Hardening WordPress: Disable PHP Execution in `wp-content/uploads`">Hardening WordPress: Disable PHP Execution in `wp-content/uploads`</a> <small>WordPress must be able to write media files to `wp-content/uploads`, but files stored there should...</small></li>
<li><a href="https://helloacm.com/delphi-is-30-years-old/" rel="bookmark" title="Delphi is 30 Years Old!">Delphi is 30 Years Old!</a> <small>People who know the Delphi programming language are probably revealing their age. Many people think...</small></li>
<li><a href="https://helloacm.com/what-is-tcp-ip-4-layer-vs-osi-7-layer/" rel="bookmark" title="Software Engineer Interview Question: What is TCP/IP (4 Layer vs OSI 7 Layer)?">Software Engineer Interview Question: What is TCP/IP (4 Layer vs OSI 7 Layer)?</a> <small>Note: recently this has been asked in the first round of the technical interviews by...</small></li>
<li><a href="https://helloacm.com/tetration-operator-in-math-simply-explained-with-python-algorithms/" rel="bookmark" title="Tetration Operator in Math Simply Explained with Python Algorithms">Tetration Operator in Math Simply Explained with Python Algorithms</a> <small>What is Tetration Operator in Math? Tetration is an operation in mathematics that involves iterated...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-verify-preorder-sequence-in-binary-search-tree-monotonous-stack/" rel="bookmark" title="Teaching Kids Programming &#8211; Verify Preorder Sequence in Binary Search Tree (Monotonous Stack)">Teaching Kids Programming &#8211; Verify Preorder Sequence in Binary Search Tree (Monotonous Stack)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms A stack-based solution for LeetCode 255,...</small></li>
<li><a href="https://helloacm.com/toss-a-coin-256-times-the-math-behind-an-unbreakable-bitcoin-private-key/" rel="bookmark" title="Toss a Coin 256 Times: The Math Behind an Unbreakable Bitcoin Private Key">Toss a Coin 256 Times: The Math Behind an Unbreakable Bitcoin Private Key</a> <small>Why Cracking a Bitcoin Key Is Harder Than You Can Possibly Imagine I often see...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<h2>From Chatting to Taking Action: AI Is Turning Yesterday’s Wonders into Today’s Routine</h2>

Recently, I came across a video from more than three years ago. In it, we were still amazed that ChatGPT could hold a conversation like that.

Ask it a question, and it could give a coherent answer. Ask it to explain some code, and it could walk through it line by line. Ask it to write a function, and it could produce an implementation. Even then, I felt this technology would change the world.

Looking back now, that experience seems surprisingly basic. Our excitement was understandable; what followed simply happened faster than we had imagined.

<h2>From Stack Overflow to Asking AI Directly</h2>

Previously, when programmers encountered a problem, we would usually search online, browse <a href="https://helloacm.com/the-404-not-found-code-of-stackoverflow/" title="The 404-not-found Code of StackOverFlow">Stack Overflow</a>, read documentation, and work through discussions, piecing together a solution from several pages. “Copy &amp; Paste” was always a slightly tongue-in-cheek description. The time-consuming part was often deciding which answer applied and adapting it to our needs.

Watching the video from three years ago, even the pace at which AI’s replies appeared on screen was noticeably slower than it is today. Back then, we would stare at the screen and patiently wait for it to finish, fascinated by the words taking shape in real time. Today, responses arrive faster and AI can handle much more complex tasks, yet we already complain that it takes too long to think or act. We adapt remarkably quickly: as technology advances, our expectations rise with it, and experiences that once amazed us soon become the standard we take for granted.

<iframe width="1840" height="1035" src="https://www.youtube.com/embed/garlKUEw1oA" title="ChatGPT Amazed Us 3 Years Ago—Now AI Can Take Action 三年前，ChatGPT 会聊天就让我们惊叹了！如今 AI 已经能动手干活" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

ChatGPT compressed many of those steps into a conversation. It could explain concepts, organise information, and provide examples, and we could keep asking follow-up questions. Avoiding all that switching between browser tabs was already exciting enough.

But at that stage, it mostly did the talking while we did the work. It suggested a command, and we copied it into a terminal. It generated code, and we pasted it into an editor. When something failed, we copied the error message back into the chat.

<h2>AI Began to Gain “Eyes”, “Ears”, and “Hands”</h2>

Before long, AI’s capabilities expanded beyond text conversations into seeing, listening, and acting. It could “look at” images, screenshots, and videos and interpret their contents; “listen to” speech, recognise what we say, and respond by voice; and use tools to read files, modify code, execute commands, and adjust its approach based on the results.

These “eyes”, “ears”, and “hands” are metaphors, of course. Behind them are multimodal understanding, voice interaction, and tools and execution environments that connect AI to external systems. The capabilities available also vary between models and products.

MCP, or Model Context Protocol, provides a standard way to connect data sources and tools, making it easier for AI to work with external systems. It is one of the standard interfaces for connecting those “hands”, rather than the source of all these capabilities.

The practical difference is straightforward: previously, I had to describe what I saw in text and transfer AI-generated code and commands to my computer myself. Now, I can provide a screenshot, a voice message, or a clearly defined task and let it analyse, modify, run, and check things within its authorised scope.

The chat box still looks familiar, but behind it are growing capabilities to perceive information and take action.

Reference: <a href="https://www.anthropic.com/news/model-context-protocol">Anthropic: Introducing the Model Context Protocol</a>

<h2>From Explaining Coding Problems to Contributing to Mathematical Research</h2>

Meanwhile, the models themselves continue to become more capable, even reaching into frontier mathematics.

On 8 September 2026, OpenAI announced that its internal AI system had produced a proof addressing the Navier–Stokes existence and smoothness problem. This concerns whether three-dimensional fluid motion can develop a singularity within a finite time. The relevant research dates back to 1934, and the problem later became one of the Millennium Prize Problems.

According to the announcement, the group that found the solution involved approximately 10,000 collaborating <a href="https://helloacm.com/ai-coding-agents-are-reshaping-the-barrier-to-programming/" title="AI Coding Agents Are Reshaping the Barrier to Programming">agents</a> and arrived at its result after about 88 hours. GPT-6 Astra then participated in a further 17 hours of Lean formalisation and verification.

Reference: <a href="https://openai.com/index/navier-stokes-solution/">OpenAI: On the Navier–Stokes Millennium Prize Problem</a>

<h3>Remarkable Progress Still Requires Precise Reporting</h3>

One distinction matters here: the proof came from an internal system more capable than Astra. It would be misleading to describe this as someone asking ChatGPT a question and Astra immediately solving a century-old problem.

Also, at the time of writing, the Clay Mathematics Institute’s website still lists the problem as unsolved. A company publishing a proof, formal verification, and thorough scrutiny and acceptance by the mathematical community are distinct stages.

Reference: <a href="https://www.claymath.org/millennium-problems/">Clay Mathematics Institute: The Millennium Prize Problems</a>

Even with those qualifications, the development is remarkable. Just over three years ago, we were impressed that AI could explain a programming exercise. Today, we need to seriously consider its role in major mathematical research.

<h2>From Vibe Coding to Harness Engineering</h2>

The changes are just as visible in programmers’ everyday work.

<h3>Turning Ideas into Software Through Natural Language</h3>

The experience associated with vibe coding is to describe an idea in natural language, let AI build an initial version, and refine it through feedback. This is particularly compelling for prototypes and small tools: things that previously required line-by-line implementation can now begin with a description.

However, there is still a substantial gap between producing a working demo and maintaining reliable software over time.

<h3>Helping AI Work Reliably and Consistently</h3>

This is why harness engineering deserves attention. It is an engineering approach focused on providing AI with the working environment, context, tools, constraints, and feedback mechanisms it needs to complete tasks reliably.

In an engineering article, OpenAI described an experiment in which a team built a product using Codex, with agents generating all the code while engineers defined goals, designed the environment, and established feedback loops.

Reference: <a href="https://openai.com/index/harness-engineering/">OpenAI: Harness Engineering</a>

Increasingly, I feel that programmers can delegate a substantial amount of manual coding to AI across many development tasks. But saying that programmers “basically no longer need to write code” is still too broad. Projects differ enormously in complexity, legacy constraints, and reliability requirements.

<strong>We may spend less time typing code, but that does not necessarily mean we spend less effort defining problems, reviewing results, and evaluating trade-offs.</strong>

<h2>Will English Be the Programming Language of the Future?</h2>

I sometimes joke that the <a href="https://helloacm.com/teaching-kids-programming-vlog-harness-engineering-commanding-ai-to-get-work-done/" title="Teaching Kids Programming vLog: Harness Engineering — Commanding AI to Get Work Done">programming</a> language of the future is English.

More precisely, it is natural language. English works, and so does Chinese. Previously, we had to translate requirements into a programming language ourselves. Increasingly, we can delegate that translation and implementation to AI.

But the phrase “you only need to describe your requirements” makes it easy to underestimate how difficult that can be.

<h3>Expressing Requirements Clearly Is a Skill</h3>

“Optimise this service for me” sounds clear, but it leaves almost everything unspecified.

<ul>
<li>Are we reducing average latency or improving P99 latency?</li>
<li>Are we increasing throughput or reducing costs?</li>
<li>Can the interface change?</li>
<li>How much accuracy, if any, can we sacrifice?</li>
<li>How will we establish whether the change actually helped?</li>
</ul>

Without answers to these questions, even an excellent AI coding system can move very efficiently in the wrong direction.

<h2>You Can Delegate Code Generation, but You Still Need to Develop Your Judgement</h2>

<h3>The Ability to Read Code</h3>

You do not have to write every line yourself, but you need to be able to inspect critical logic, trace data flows, and identify questionable assumptions.

Tests matter too, but passing tests only demonstrates that the code passed those particular tests. It does not automatically establish that the requirements were understood correctly.

<h3>Domain Expertise</h3>

Domain expertise remains essential. Understanding business rules, the meaning of the data, and real usage scenarios helps you judge whether an impressive-looking implementation actually solves the problem.

Some mistakes never raise an exception. The software may even perform extremely well while producing something the user never needed.

<h3>Software Engineering Skills</h3>

<a href="https://helloacm.com/interview-question-what-happens-when-you-type-google-com-in-the-browser-address-bar/" title="Software Engineering Interview Question: What Happens When You Type Google.com in the Browser Address Bar?">Software engineering</a> skills do not lose their value simply because generating code becomes easier. Architecture, interfaces, maintainability, observability, deployment, and rollback still require careful thought. The faster code is produced, the more important it becomes to keep those disciplines in step.

Using AI well is therefore becoming a skill in its own right. It involves much more than remembering a few effective prompts. It includes breaking down tasks, providing context, defining acceptance criteria, and knowing what to trust, what to verify, and what to question further.

<h2>Yesterday’s Wonders Are Becoming Today’s Default Expectations</h2>

What strikes me most about AI is how quickly it changes our idea of “normal”.

The first time it generates working code, it feels extraordinary. After using it for a while, we start wondering why it did not write the tests as well. Once it can modify, test, and fix the code itself, we begin expecting it to deliver the entire feature.

Yesterday’s surprise quickly becomes today’s minimum expectation. Once something we thought impossible becomes possible, we adapt faster than we might have imagined.

More than three years ago, I looked at ChatGPT’s responses and felt that it would change the world. Watching that old video now, I still agree with that judgement. I simply have a much more concrete understanding of what that change looks like.

AI has already entered our workflows and shortened the distance between an idea and a working result.

I need to keep adapting too: placing less emphasis on how much code I personally write, and asking whether I can identify worthwhile problems, explain them clearly, and judge whether the final result stands up to scrutiny.

[show_file file="/var/www/wp-post-common/helloacm.com/software-engineer.php"]

[show_posts keyword="chatgpt"]

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/a-google-alert-woke-me-up-postmortem-of-a-wordpress-security-incident/" rel="bookmark" title="A Google Alert Woke Me Up: Postmortem of a WordPress Security Incident">A Google Alert Woke Me Up: Postmortem of a WordPress Security Incident</a> <small>An unpatched WordPress and plugin vulnerability apparently exposed a Cloudflare credential stored in the database....</small></li>
<li><a href="https://helloacm.com/the-memory-manager-in-c-c-heap-vs-stack/" rel="bookmark" title="The Memory Manager in C/C++ (Heap vs Stack)">The Memory Manager in C/C++ (Heap vs Stack)</a> <small>This is one of the most frequently asked interview questions for Software Engineer roles. In...</small></li>
<li><a href="https://helloacm.com/hardening-wordpress-disable-php-execution-in-wp-content-uploads/" rel="bookmark" title="Hardening WordPress: Disable PHP Execution in `wp-content/uploads`">Hardening WordPress: Disable PHP Execution in `wp-content/uploads`</a> <small>WordPress must be able to write media files to `wp-content/uploads`, but files stored there should...</small></li>
<li><a href="https://helloacm.com/delphi-is-30-years-old/" rel="bookmark" title="Delphi is 30 Years Old!">Delphi is 30 Years Old!</a> <small>People who know the Delphi programming language are probably revealing their age. Many people think...</small></li>
<li><a href="https://helloacm.com/what-is-tcp-ip-4-layer-vs-osi-7-layer/" rel="bookmark" title="Software Engineer Interview Question: What is TCP/IP (4 Layer vs OSI 7 Layer)?">Software Engineer Interview Question: What is TCP/IP (4 Layer vs OSI 7 Layer)?</a> <small>Note: recently this has been asked in the first round of the technical interviews by...</small></li>
<li><a href="https://helloacm.com/tetration-operator-in-math-simply-explained-with-python-algorithms/" rel="bookmark" title="Tetration Operator in Math Simply Explained with Python Algorithms">Tetration Operator in Math Simply Explained with Python Algorithms</a> <small>What is Tetration Operator in Math? Tetration is an operation in mathematics that involves iterated...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-verify-preorder-sequence-in-binary-search-tree-monotonous-stack/" rel="bookmark" title="Teaching Kids Programming &#8211; Verify Preorder Sequence in Binary Search Tree (Monotonous Stack)">Teaching Kids Programming &#8211; Verify Preorder Sequence in Binary Search Tree (Monotonous Stack)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms A stack-based solution for LeetCode 255,...</small></li>
<li><a href="https://helloacm.com/toss-a-coin-256-times-the-math-behind-an-unbreakable-bitcoin-private-key/" rel="bookmark" title="Toss a Coin 256 Times: The Math Behind an Unbreakable Bitcoin Private Key">Toss a Coin 256 Times: The Math Behind an Unbreakable Bitcoin Private Key</a> <small>Why Cracking a Bitcoin Key Is Harder Than You Can Possibly Imagine I often see...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://helloacm.com/when-ai-writes-the-code-what-skills-do-developers-still-need/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>A Google Alert Woke Me Up: Postmortem of a WordPress Security Incident</title>
		<link>https://helloacm.com/a-google-alert-woke-me-up-postmortem-of-a-wordpress-security-incident/</link>
					<comments>https://helloacm.com/a-google-alert-woke-me-up-postmortem-of-a-wordpress-security-incident/#respond</comments>
		
		<dc:creator><![CDATA[ACMer]]></dc:creator>
		<pubDate>Mon, 07 Sep 2026 10:45:57 +0000</pubDate>
				<category><![CDATA[cloud]]></category>
		<category><![CDATA[cloudflare]]></category>
		<category><![CDATA[CloudFlare]]></category>
		<category><![CDATA[CVE (Common Vulnerabilities and Exposures)]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[wordpress]]></category>
		<category><![CDATA[API token exposure]]></category>
		<category><![CDATA[Cloudflare security]]></category>
		<category><![CDATA[CloudFlare Worker]]></category>
		<category><![CDATA[Database Security]]></category>
		<category><![CDATA[domain verification]]></category>
		<category><![CDATA[filesystem permissions]]></category>
		<category><![CDATA[Google Search Console]]></category>
		<category><![CDATA[google webmaster]]></category>
		<category><![CDATA[hacker]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[js]]></category>
		<category><![CDATA[Least Privilege]]></category>
		<category><![CDATA[MySQL Security]]></category>
		<category><![CDATA[PHP security]]></category>
		<category><![CDATA[security incident postmortem]]></category>
		<category><![CDATA[SEO poisoning]]></category>
		<category><![CDATA[static blog]]></category>
		<category><![CDATA[traffic hijacking]]></category>
		<category><![CDATA[vulnerability]]></category>
		<category><![CDATA[WebShell]]></category>
		<category><![CDATA[website backups]]></category>
		<category><![CDATA[website compromise]]></category>
		<category><![CDATA[website ownership hijacking]]></category>
		<category><![CDATA[wordpress security]]></category>
		<category><![CDATA[WordPress vulnerability]]></category>
		<category><![CDATA[wp_options]]></category>
		<guid isPermaLink="false">https://helloacm.com/?p=158051</guid>

					<description><![CDATA[<blockquote>
An unpatched WordPress and plugin vulnerability apparently exposed a Cloudflare credential stored in the database. The attacker then deployed a malicious Worker, hijacked selected blog pages, redirected traffic to gambling websites, and added an unauthorised verified owner to Google Search Console. This post reconstructs the incident, examines what the evidence does and does not prove, and documents the hardening measures taken. It is a clear reminder that effective security depends on prompt patching, least-privilege access, monitoring, and recoverable backups—not on any single defensive product.
</blockquote>

<h3>A Google Alert Woke Me Up: Postmortem of a WordPress Security Incident</h3>

On 11 August 2026, I received an email from Google Search Console informing me that a new verified owner had been added to one of my websites.

[caption id="attachment_158060" align="alignnone" width="1312"]<a href="https://helloacm.com/a-google-alert-woke-me-up-postmortem-of-a-wordpress-security-incident/new-owner-google-webmaster/" rel="attachment wp-att-158060"><img src="https://helloacm.com/wp-content/uploads/2026/09/new-owner-google-webmaster.jpg" alt="New Owner is added/verified - which indicates a security breach." width="1312" height="1140" class="size-full wp-image-158060" /></a> New Owner is added/verified - which indicates a security breach.[/caption]

[bctt tweet="I did not recognise the account."]

The moment I saw the email, I knew something was wrong.

If an unknown person can verify themselves as a site owner, the problem is probably more serious than comment spam, credential stuffing, or routine vulnerability scanning. It suggests that the attacker may be able to control what the website returns to visitors.

I immediately started checking WordPress, Cloudflare, the MySQL database, the web server, and the system logs.

[caption id="attachment_158057" align="alignnone" width="1456"]<a href="https://helloacm.com/a-google-alert-woke-me-up-postmortem-of-a-wordpress-security-incident/cloudflare-audit-logs/" rel="attachment wp-att-158057"><img src="https://helloacm.com/wp-content/uploads/2026/09/cloudflare-audit-logs.jpg" alt="Cloudflare Account&#039;s Audit logs for access" width="1456" height="913" class="size-full wp-image-158057" /></a> Cloudflare Account's Audit logs for access[/caption]

The investigation confirmed that the website had been compromised. The attacker had intercepted requests for several blog pages before they reached my origin server and replaced the legitimate content with Indonesian-language gambling promotions.

I discovered and contained the <a href="https://helloacm.com/a-steemit-development-incident/" title="A SteemIt Development Incident">incident</a> reasonably quickly, but it was still a serious wake-up call.

WordPress has always been a frequent target. More accurately, however, the risk does not come only from WordPress core. It comes from the complete chain of trust involving WordPress, plugins, themes, databases, API tokens, CDN configuration, filesystem permissions, and operational practices.

[caption id="attachment_158056" align="alignnone" width="705"]<a href="https://helloacm.com/a-google-alert-woke-me-up-postmortem-of-a-wordpress-security-incident/cloudflare-api-access/" rel="attachment wp-att-158056"><img src="https://helloacm.com/wp-content/uploads/2026/09/cloudflare-api-access.jpg" alt="Cloudflare&#039;s API access logs" width="705" height="919" class="size-full wp-image-158056" /></a> Cloudflare's API access logs[/caption]

<h4>How the incident happened?</h4>

Over the years, I have accumulated approximately eight WordPress installations. Each site has its own collection of themes and plugins.

One plugin needed to communicate with the Cloudflare API, so it stored a Cloudflare credential in the WordPress database.

The WordPress options table contains a large amount of site and plugin configuration. Some plugins also store API tokens and other secrets there in a form that the application can use directly.

The affected site was still running an older WordPress 6.8.x release and included a plugin affected by a recently disclosed security issue. The <a href="https://helloacm.com/full-disclosure-helloacm-com-xss-vulnerability-notification/" title="Full Disclosure: helloacm.com XSS vulnerability notification">vulnerability </a>had been made public during the previous month, but I had not upgraded the site promptly after the patched version became available.

Based on the server logs, database contents, and Cloudflare configuration, the most likely attack path was:

<ol>
<li>The attacker exploited a publicly known WordPress or plugin vulnerability to access data that should not have been readable.</li>
<li>This exposed a Cloudflare credential stored by a plugin in the WordPress database.</li>
<li>The attacker used the credential to modify Cloudflare configuration and deploy an unauthorised Worker.</li>
<li>The malicious Worker intercepted selected blog requests before they reached my origin server.</li>
<li>Some legitimate pages were replaced with Indonesian-language gambling content.</li>
<li>By controlling the content returned for the domain, the attacker completed Google Search Console ownership verification.</li>
<li>Google’s “new owner added” email finally alerted me to the compromise.</li>
</ol>

This is the most plausible explanation supported by the available evidence. It is not a complete reconstruction of every action performed by the attacker.

Incident analysis must distinguish between what has been confirmed, what is highly likely, and what cannot yet be excluded. A technically plausible attack path should not automatically be presented as fully proven.

<h4>Timeline of the incident</h4>

<ul>
<li>July 2026: A security issue affecting the older WordPress or plugin combination was publicly disclosed, followed by a patched release. I did not upgrade immediately, creating a window of exposure.</li>
<li>Mid-to-late July 2026: The server logs showed increasing automated probes against WordPress and common plugin endpoints. Public servers receive this kind of scanning every day, so scanning alone does not prove a successful compromise.</li>
<li>Late July to early August 2026: Requests appeared for known vulnerable paths, upload locations, and suspicious script names. Most returned “not found,” but they showed that automated attack systems were continuously testing the site.</li>
<li>Early August 2026: The attacker likely used the unpatched vulnerability to access sensitive plugin configuration. The evidence supports database-secret disclosure more strongly than a successful WordPress dashboard login.</li>
<li>Shortly afterwards: The exposed Cloudflare credential was used to add or modify edge-side logic. Selected blog pages began being replaced before the requests reached the origin server.</li>
<li>During the same period: Hijacked pages displayed Indonesian-language gambling promotions, apparently for <a href="https://helloacm.com/3-ways-to-protect-your-website-from-negative-seo/" title="3 Ways to Protect Your Website from Negative SEO">SEO</a> poisoning and traffic redirection.</li>
<li>11 August 2026: By controlling the website response, the attacker completed Google Search Console verification and added an unknown identity as a verified site owner.</li>
<li>11 August 2026: I received Google’s ownership notification and immediately began incident response.</li>
<li>11–12 August 2026: I removed the unauthorised Google owner, inspected and removed suspicious Cloudflare Workers and configuration, and revoked and rotated potentially exposed credentials.</li>
<li>12 August 2026: I upgraded the affected WordPress installations and inspected administrator accounts, database privileges, web logs, file timestamps, scheduled tasks, and common WebShell indicators.</li>
<li>12 August 2026: I removed sensitive plugin configuration left in the database and began restricting MySQL filesystem capabilities.</li>
<li>12 August 2026: I added a rule <a href="https://helloacm.com/hardening-wordpress-disable-php-execution-in-wp-content-uploads/" title="Hardening WordPress: Disable PHP Execution in `wp-content/uploads`">preventing PHP execution inside WordPress upload directories</a> while reviewing the Apache configuration and service state.</li>
<li>Ongoing: I am continuing to review filesystem permissions, backup recoverability, Cloudflare token permissions, and the core, theme, and plugin versions used by the remaining WordPress installations.</li>
</ul>

<h4>What the attacker did</h4>

The following actions are either confirmed or strongly supported by the available evidence:

<ul>
<li>Obtained a credential capable of calling the Cloudflare API.</li>
<li>Added or modified Cloudflare edge-side execution logic.</li>
<li>Intercepted selected WordPress page requests before they reached the origin server.</li>
<li>Returned gambling promotional content to visitors or search engines.</li>
<li>Added an unauthorised owner to Google Search Console.</li>
<li>Attempted to exploit the domain’s existing reputation and rankings for SEO poisoning and traffic redirection.</li>
</ul>

Google Search Console owner access should not be underestimated.

It does not provide root access to the server and does not directly expose server files. However, an unauthorised owner may be able to submit sitemaps, request indexing, view search-related data, and help malicious pages appear in Google’s index more quickly.

Fortunately, Google’s ownership notification was the key signal that exposed the incident.

Without that email, an attack targeting only selected URLs, geographical regions, user agents, or search-engine crawlers could have been difficult to notice. Visiting the homepage normally might have shown nothing unusual.

<h4>Did the attacker log in to the WordPress dashboard?</h4>

At present, there is no evidence that the attacker successfully logged in to the WordPress dashboard.

The WordPress database still contained only my legitimate administrator account. I found no unauthorised administrator, and the available logs did not provide sufficient evidence of a successful dashboard login.

However, absence of evidence is not evidence of absence.

Logs may have been rotated, proxy layers may have hidden parts of the traffic, and some application activity may not have produced complete audit records.

The accurate conclusion is:

There is currently no evidence that the attacker logged in to the WordPress dashboard, but the related credentials should still be treated as potentially exposed.

I changed the WordPress administrator password and rotated the WordPress authentication keys and salts, invalidating existing login cookies and sessions.

The <a href="https://helloacm.com/how-to-ssh-to-remote-host-using-the-priviate-public-keys-authentication/" title="How to SSH to Remote Host using the Priviate/Public Keys Authentication?">authentication</a> keys and salts in <code>wp-config.php</code> are primarily used to protect cookies, sessions, and nonces. Changing them logs everyone out, but it does not change user passwords.

WordPress stores user passwords as salted password hashes. Even if a password hash is leaked, the attacker does not normally receive the plaintext password directly, but can still attempt to guess it offline.

Salting prevents precomputed rainbow-table attacks and ensures that identical passwords produce different hashes. It does not protect a weak password from dictionary or brute-force attacks.

Therefore, if the database may have been exposed, changing the password is still the correct response, especially if the password was short, predictable, or reused elsewhere.

<h4>Did the attacker gain access to the server filesystem?</h4>

This was my biggest concern.

A Cloudflare Worker executes on Cloudflare’s edge network. It can intercept, rewrite, or proxy website requests, but it does not automatically receive access to the origin server’s filesystem.

Likewise, a database vulnerability does not automatically provide operating-system command execution. The files MySQL can read or write depend on the database account’s privileges, MySQL configuration, and operating-system permissions.

My checks showed that the <a href="https://helloacm.com/shrink-wordpress-database-usage/" title="Shrink WordPress Database Usage">WordPress database</a> account did not have global file privileges. Only local maintenance and database-administrator accounts had the relevant privilege.

Local MySQL file import was disabled, and server-side file access was either constrained or subsequently disabled more strictly.

The logs contained many probes for uploaded scripts and WebShells, but the relevant requests generally returned “not found.”

I found no direct evidence that the attacker successfully uploaded and executed a WebShell. I also found no confirmed evidence that the attacker obtained a server shell or root access.

However, it would be irresponsible to conclude that the filesystem was definitely untouched.

Some website directories had historically been owned by the web-server account, with broader write access than necessary. If an attacker had obtained PHP code execution, they could theoretically have modified files writable by that account.

The most defensible conclusion is:

The exposed Cloudflare credential and edge-page hijacking are supported by evidence. No direct evidence of PHP execution, a successful WebShell, or server-file modification has been found. However, because some historical filesystem permissions were too broad, filesystem compromise cannot be ruled out solely from the available logs.

<h4>Were the WebShell probes related to this vulnerability?</h4>

The logs included requests for suspicious PHP filenames under WordPress upload directories. These looked more like generic WebShell discovery attempts.

The requests returned HTTP <code>404</code>, meaning those particular files were not present when requested.

A request for a filename resembling a WebShell does not prove that the scanner uploaded it. Automated attack tools routinely probe the Internet for known WebShell filenames left behind by previous compromises.

The <a href="https://helloacm.com/php7-x-is-deprecated-by-wordpress-why-you-should-upgrade-to-php8-x/" title="PHP7.x is deprecated by WordPress: Why You Should Upgrade to PHP8.x?">WordPress</a> vulnerability may have allowed access to database information, but that does not automatically provide PHP execution or filesystem write access.

Installing a working WebShell would normally require an additional capability, such as:

<ul>
<li>Arbitrary file upload.</li>
<li>Arbitrary file write.</li>
<li>Remote code execution.</li>
<li>Compromised WordPress dashboard access.</li>
<li>Permission to install a malicious plugin.</li>
<li>Another vulnerable component providing code execution.</li>
</ul>

No causal connection has therefore been established between the observed WebShell probes and the Cloudflare credential exposure involved in this incident.

The upload-directory protection is preventive hardening, not proof that this attack involved a WebShell.

<h4>Were MySQL usernames or passwords exposed?</h4>

If the vulnerability only permitted access to the WordPress options table, it could expose tokens and secrets stored there by plugins, but it would not necessarily expose the WordPress MySQL password.

The WordPress database username and password are normally stored in <code>wp-config.php</code>, not in the WordPress options table.

The WordPress MySQL credentials would be more likely to leak only if the attacker obtained arbitrary file-read access, PHP code execution, or another capability that allowed <code>wp-config.php</code> to be read.

MySQL also does not normally store recoverable plaintext database-user passwords in its system tables. It stores authentication information instead. However, weak passwords may still be vulnerable to offline attacks if those authentication records are exposed.

Based on the investigation so far, I found no direct evidence that the WordPress database credentials or all MySQL user passwords were leaked.

Rotating the dedicated WordPress database account password is nevertheless a relatively low-cost precaution. After changing the password in MySQL, the matching value in <code>wp-config.php</code> must be updated immediately, or WordPress will no longer be able to connect to the database.

<h4>Why did Cloudflare not stop the attack?</h4>

Cloudflare is not a box that automatically solves every security problem.

It can provide DDoS protection, a web application firewall, bot management, rate limiting, and origin shielding. These protections depend on appropriate configuration and on the malicious activity matching something Cloudflare can identify.

More importantly, the attacker apparently obtained a valid Cloudflare API token.

From Cloudflare’s perspective, an administrative operation made with a valid credential may look authorised. A WAF primarily examines web traffic; it does not automatically classify every API operation performed with a valid token as malicious.

Cloudflare was therefore not merely a defensive layer in this incident. Because the exposed token had too much authority, Cloudflare also became an amplifier in the attack chain.

This reinforced an important principle:

API tokens must follow the principle of least privilege. A normal WordPress plugin should not possess a credential capable of controlling an entire website’s request path unless that capability is absolutely necessary.

<h4>Why does WordPress store secrets in the database?</h4>

Many WordPress plugins store external API credentials in the options table in a form that the application can use directly.

This does not necessarily mean that the plugin developer knows nothing about security. The application must be able to obtain the credential at runtime to call an external API without human intervention.

Even if the database value is encrypted, the application must still have access to the corresponding decryption key. If an attacker gains sufficient application-level privileges and the key exists in the same server or execution environment, the attacker may still be able to decrypt it.

Encryption has value, but it is not a substitute for access control.

More effective controls include:

<ul>
<li>Avoid giving WordPress plugins high-privilege infrastructure credentials.</li>
<li>Create separate tokens for each site and purpose.</li>
<li>Restrict every token to only the required resources and operations.</li>
<li>Use expiry dates and rotate credentials regularly.</li>
<li>Delete unused plugins instead of merely deactivating them.</li>
<li>Treat database backups as sensitive data.</li>
<li>Monitor token usage, Worker changes, and ownership changes.</li>
<li>Revoke credentials when the plugin that used them is removed or disabled.</li>
</ul>

Secret-management systems such as Key Vault can improve storage, rotation, access control, and auditing. However, they cannot automatically protect an application that has already been completely compromised.

The most important safeguards are limiting what a credential can do and limiting how long it remains valid.

<h4>What I did after discovering the incident</h4>

Once I discovered the compromise, my first priority was to contain the active risk rather than construct a perfectly neat attack narrative.

The completed or ongoing actions include:

<ol>
<li>Removed the unauthorised Google Search Console owner.</li>
<li>Removed unauthorised Cloudflare Workers and related configuration.</li>
<li>Revoked and regenerated potentially exposed API tokens.</li>
<li>Upgraded the affected WordPress installations.</li>
<li>Updated plugins and themes and removed unused components.</li>
<li>Inspected WordPress administrator accounts, application passwords, and suspicious sessions.</li>
<li>Removed sensitive plugin settings left in the database.</li>
<li>Restricted the WordPress database account’s privileges.</li>
<li>Disabled unnecessary MySQL local-file import functionality. <a href="https://helloacm.com/hardening-mysql-file-access-with-local_infile0-and-secure_file_privnull/" title="Hardening MySQL File Access with local_infile=0 and secure_file_priv=NULL">Linux Disk Space Troubleshooting: Find Large Files and Directories with ncdu</a></li>
<li>Disabled or tightly constrained MySQL server-side file access.</li>
<li>Reviewed web logs, system logs, scheduled tasks, and suspicious files.</li>
<li>Disabled PHP execution inside WordPress upload directories.</li>
<li>Began reviewing owners, groups, and permissions across all website files.</li>
<li>Checked whether existing backups were complete and recoverable, not merely whether backup files existed.</li>
<li>Rotated administrator <a href="https://helloacm.com/monitoring-28-vps-machines-including-a-raspberry-pi-with-nezha-dashboard/" title="Monitoring 28 VPS Machines (Including a Raspberry Pi) with Nezha Dashboard">passwords</a>, database passwords, and WordPress authentication keys and salts.</li>
</ol>

<h4>Why disable PHP execution in the uploads directory?</h4>
See: <a href="https://helloacm.com/hardening-wordpress-disable-php-execution-in-wp-content-uploads/" title="Hardening WordPress: Disable PHP Execution in `wp-content/uploads`">Hardening WordPress: Disable PHP Execution in `wp-content/uploads`</a>

The WordPress uploads directory should primarily contain static content such as images, videos, and PDF documents. Under normal circumstances, there is no reason to execute PHP there.

Suppose a vulnerability allows an attacker to bypass file-type validation and upload a disguised PHP script. If the web server permits PHP execution in the uploads directory, that file could become a WebShell.

The attacker might then execute commands through a browser, read configuration files, modify website code, or attempt to move further into the server.

Disabling PHP execution in the uploads directory breaks that common escalation path.

Even if a malicious PHP file is uploaded, the web server will not execute it as a program.

This protection usually presents little compatibility risk and significantly reduces the impact of many WordPress upload vulnerabilities. It is therefore a sensible default.

However, it is not a complete defence. If theme, plugin, or other executable directories remain writable by the web-server account, an attacker may find another location.

<h4>Revisiting filesystem permissions</h4>

The investigation revealed that, over the years, I had left some WordPress permissions broader than necessary.

This was partly done for convenience. Installing plugins, enabling updates, and resolving write errors becomes easier when the web-server account owns large parts of the website.

Convenience, however, often increases the attack surface.

Also, for MySQL, it is better to disable local file access: <a href="https://helloacm.com/hardening-mysql-file-access-with-local_infile0-and-secure_file_privnull/" title="Hardening MySQL File Access with local_infile=0 and secure_file_priv=NULL">Hardening MySQL File Access with local_infile=0 and secure_file_priv=NULL</a>

I am now restructuring permissions according to least privilege:

<ul>
<li>Application code should normally be owned by a deployment or administrative account.</li>
<li>The web-server account should be able to read code but should not own the entire site.</li>
<li>Write access should be granted only to upload, cache, or temporary directories that genuinely require it.</li>
<li>Configuration files should use stricter permissions.</li>
<li>The entire site should not be writable by the web-server account merely for convenience.</li>
<li>Temporary troubleshooting permissions must not become permanent.</li>
<li>Writable directories should not also execute server-side scripts wherever possible.</li>
</ul>

The goal is not to find one universally correct permission number.

The real question is:

If the PHP process is compromised, exactly which files can the attacker modify?

The answer should be “only a small number of operationally necessary directories,” not “the entire website.”

How I will handle WordPress updates

After this incident, WordPress upgrades can no longer remain an “I will do it when I have time” maintenance task.

My plan is to:

<ul>
<li>Review and apply WordPress security updates promptly.</li>
<li>Update plugins and themes at the same time.</li>
<li>Remove disabled, abandoned, or unnecessary plugins.</li>
<li>Avoid blindly enabling automatic major-version upgrades everywhere.</li>
<li>Verify backups before upgrading.</li>
<li>Test critical website functions after each upgrade.</li>
<li>Maintain a central version inventory for all WordPress installations.</li>
<li>Check regularly for known vulnerabilities instead of relying only on dashboard notifications.</li>
</ul>

I still prefer to perform important upgrades manually because the servers contain several historical websites with different plugin combinations. Fully unattended major upgrades could introduce compatibility problems.

However, “manual upgrades” must never become an excuse for “no upgrades.”

A backup is not enough unless it can be restored

It is easy to develop a false sense of security when scheduled backup jobs are running and files appear in a backup directory.

A reliable backup should satisfy several conditions:

<ul>
<li>The backup files are complete and not corrupted.</li>
<li>Both the database and uploaded content are included.</li>
<li>At least one copy exists outside the production server.</li>
<li>The same credentials cannot delete both production data and every backup.</li>
<li>A defined retention policy exists.</li>
<li>Restore tests are performed periodically.</li>
<li>The expected recovery time is understood.</li>
</ul>

A backup that has never been restored is only a potentially useful copy of some data.

<h4>Should I migrate to a static blog?</h4>

While discussing the incident with friends, one suggestion was to migrate to a static-blog system such as Hexo. Articles could be written in Markdown, stored in GitHub, and converted into static pages through an automated deployment pipeline.

The suggestion makes sense.

My blogs are primarily personal records. They do not depend heavily on membership systems, complex plugins, or dynamic backend functionality. For this use case, a static site would significantly reduce the attack surface associated with PHP, databases, plugins, and administrative logins.

However, I currently have approximately eight WordPress sites, accumulated through many years of experiments and technical history.

Migrating all articles, URLs, images, comments, and SEO metadata at once would not be a small project.

A more realistic approach may be:

<ul>
<li>Write new content in Markdown.</li>
<li>Migrate the simplest blogs first.</li>
<li>Reduce functionality on WordPress sites that must remain.</li>
<li>Delete unnecessary plugins and themes.</li>
<li>Preserve old URLs where possible to avoid breaking inbound links.</li>
<li>Use dynamic functionality only where it is genuinely required.</li>
</ul>

With modern AI agents, bulk-converting articles, generating metadata, repairing image paths, creating static-site configuration, and debugging deployment pipelines is considerably easier than it used to be.

That makes migrating years of historical content much more practical.

<h4>What this incident taught me</h4>

The attack did not appear to begin with the most obvious target: my WordPress administrator password.

Instead, it followed a less visible chain of trust:

Unpatched application or plugin → sensitive database configuration → overprivileged external token → edge-level request hijacking → unauthorised search-engine ownership

Each individual weakness might not appear catastrophic:

<ul>
<li>A WordPress update was delayed.</li>
<li>A plugin stored an API token in the database.</li>
<li>The token had broader permissions than necessary.</li>
<li>A Cloudflare Worker could modify page responses.</li>
<li>Google allowed ownership to be verified through website content.</li>
</ul>

When these conditions were combined, however, the attacker gained capabilities far beyond the original vulnerability.

Security is not simply “I use Cloudflare,” “I enabled HTTPS,” or “my password is strong.”

It is a system of boundaries, permissions, patching, monitoring, detection, alerting, backups, and recovery capabilities.

The fortunate part of this incident is that the attacker’s apparent objective was gambling-site traffic and search-ranking manipulation. Google’s ownership-change email also alerted me quickly.

So far, I have found no direct evidence that the attacker logged in to the <a href="https://helloacm.com/wordpress-how-to-output-full-text-in-the-feed/" title="WordPress: How to Output Full Text in the Feed?">WordPress</a> dashboard, executed a PHP WebShell, or gained a server shell.

But “not found” does not mean “definitively did not happen.”

The remaining hardening work will therefore assume a more serious level of exposure: rotating credentials, reducing permissions, patching software, checking files, validating backups, and monitoring the systems for further anomalies.

<h4>Final thoughts</h4>

I have maintained websites and servers for many years. I already knew that WordPress and its plugins required prompt updates.

There is always, however, a gap between knowing something and acting on it—a quiet assumption that nothing will happen during the next few days.

The Internet does not wait until I have time.

Once a vulnerability becomes public, automated scanning and mass exploitation can begin very quickly. An attacker does not need to target me personally. They only need to scan enough websites and find one that has not yet been upgraded.

Google Search Console’s notification woke me up. It also reminded me that the most frightening part of a security incident is not simply discovering that a page was modified. It is not knowing exactly how far the attacker progressed.

This incident was a clear warning.

My next steps include enforcing the no-PHP rule in WordPress upload directories, disabling unnecessary MySQL file capabilities, rebuilding filesystem permissions, testing backup restoration, reducing Cloudflare token privileges, and upgrading every WordPress installation more consistently.

Where practical, I will also begin migrating suitable blogs to Markdown-based static sites.

WordPress is convenient—but convenience is never free.

[caption id="attachment_158058" align="alignnone" width="674"]<a href="https://helloacm.com/a-google-alert-woke-me-up-postmortem-of-a-wordpress-security-incident/cloudflare-kv-flow/" rel="attachment wp-att-158058"><img src="https://helloacm.com/wp-content/uploads/2026/09/cloudflare-kv-flow.jpg" alt="Cloudflare Serves the requests with KV values." width="674" height="526" class="size-full wp-image-158058" /></a> Cloudflare Serves the requests with KV values.[/caption]

[caption id="attachment_158059" align="alignnone" width="1269"]<a href="https://helloacm.com/a-google-alert-woke-me-up-postmortem-of-a-wordpress-security-incident/cloudflare-kv-html-values/" rel="attachment wp-att-158059"><img src="https://helloacm.com/wp-content/uploads/2026/09/cloudflare-kv-html-values.jpg" alt="CloudFlare&#039;s KV values which hijacks the requests" width="1269" height="696" class="size-full wp-image-158059" /></a> CloudFlare's KV values which hijacks the requests[/caption]

<h3>Appendix: Malicious CloudFlare Worker Code to Hijack HTML</h3>
<pre lang=js>
// Worker penyaji halaman HTML kustom dari KV (milik tools manual-page/).
// Terpisah dari lp-worker: script name, KV namespace, dan deploy-nya sendiri.
//
// Key KV di-prefix hostname (satu namespace dipakai banyak domain):
// {host}:pages.txt -&gt; daftar path yang aktif untuk host tsb
// page:{host}:{path} -&gt; isi HTML halaman
// Path yang terdaftar disajikan apa adanya ke semua pengunjung.
// Path lain → diteruskan transparan ke origin.

const CACHE_TTL_MS = 300_000; // cache pages.txt per host di isolate, 5 menit

const pagesCache = new Map(); // host -&gt; { time, pages }

async function getPages(env, host) {
    const now = Date.now();
    const cached = pagesCache.get(host);
    if (cached && now - cached.time &lt; CACHE_TTL_MS) {
        return cached.pages;
    }
    const text = await env.PAGES.get($ {
        host
    }: pages.txt);
    const pages = new Set(
        text ? text.split('\n').map((p) => p.trim()).filter((p) =&gt; p !== '') : []
    );
    pagesCache.set(host, {
        time: now,
        pages
    });
    return pages;
}

export default {
    async fetch(request, env) {
        if (request.method !== 'GET' && request.method !== 'HEAD') {
            return passThrough();
        }

        const url = new URL(request.url);
        const host = url.host.toLowerCase().replace(/^www\./, '');
        // Normalisasi sama dengan main.py: lowercase, tanpa trailing slash
        const key = '/' + url.pathname.toLowerCase().replace(/^\/+|\/+$/g, '');

        // Pass-through ke origin — inject X-Forwarded-Proto agar WordPress/nginx
        // tahu request aslinya HTTPS (diperlukan kalau SSL mode CF = Flexible)
        function passThrough() {
            const modified = new Request(request);
            modified.headers.set('X-Forwarded-Proto', 'https');
            modified.headers.set('X-Forwarded-Host', url.host);
            modified.headers.set('X-Forwarded-SSL', 'on');
            modified.headers.set('X-Forwarded-Port', '443');
            return fetch(modified);
        }

        // Root → teruskan ke origin (situs asli tetap jalan normal)
        if (key === '/') {
            return passThrough();
        }

        // File verifikasi GSC (googlexxx.html) dari KV — cek dua key:
        //   - key polos: google{token}.html (utils.py via lp-worker-content)
        //   - key prefixed: page:{host}:{path} (manual-page/main.py)
        const verifyMatch = key.match(/^\/(google[a-z0-9]+\.html)$/);
        if (verifyMatch) {
            const [plain, gsc] = await Promise.all([
                env.PAGES.get(verifyMatch[1]),
                env.PAGES.get(`page:${host}:${key}`),
            ]);
            const html = plain || gsc;
            if (html !== null) {
                return new Response(html, {
                    headers: {
                        'content-type': 'text/html; charset=utf-8'
                    },
                });
            }
            return passThrough();
        }

        // Binding KV hilang (deploy parsial) -&gt; gagal-aman ke origin,
        // jangan 500-kan seluruh domain
        if (!env.PAGES) {
            return passThrough();
        }

        try {
            const pages = await getPages(env, host);
            if (!pages.has(key)) {
                return passThrough();
            }

            const html = await env.PAGES.get(`page:${host}:${key}`);
            if (html === null) {
                return passThrough();
            }
            return new Response(html, {
                headers: {
                    'content-type': 'text/html; charset=utf-8'
                },
            });
        } catch {
            return passThrough(); // KV error -&gt; gagal-aman ke origin
        }
    },
};
</pre>

[show_file file="/var/www/wp-post-common/helloacm.com/incidents.php"]

[show_posts keyword="security incident"]

[show_posts keyword="wordpress"]

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/accidentally-deleting-over-18000-files-with-shiftdelete-recovering-data-from-a-surface-ssd-using-winfr/" rel="bookmark" title="Accidentally Deleting Over 18,000 Files with Shift+Delete: Recovering Data from a Surface SSD Using WinFR">Accidentally Deleting Over 18,000 Files with Shift+Delete: Recovering Data from a Surface SSD Using WinFR</a> <small>While freeing space on my Surface Laptop Studio 2, I accidentally used Shift+Delete to permanently...</small></li>
<li><a href="https://helloacm.com/using-absolute-keyword-in-delphi-to-remove-unnecessary-assignment-function/" rel="bookmark" title="Using Absolute Keyword in Delphi to Remove Unnecessary Assignment Function">Using Absolute Keyword in Delphi to Remove Unnecessary Assignment Function</a> <small>The Delphi/Object Pascal provides a keyword absolute, which you can also find examples at this...</small></li>
<li><a href="https://helloacm.com/how-to-compute-the-chain-age-uptime-and-downtime-for-steem-blockchain/" rel="bookmark" title="How to Compute the Chain Age, Uptime and Downtime for Steem Blockchain?">How to Compute the Chain Age, Uptime and Downtime for Steem Blockchain?</a> <small>Steem Blockchain has been running for a while, and how to compute the Chain Age,...</small></li>
<li><a href="https://helloacm.com/how-to-parallel-for-in-linux-bash-shell/" rel="bookmark" title="How to Parallel For in Linux Bash Shell?">How to Parallel For in Linux Bash Shell?</a> <small>The Linux Bash Shell supports inherent task parallelism. For example, you can put a &#038;...</small></li>
<li><a href="https://helloacm.com/algorithms-to-find-the-three-numbers-in-array-that-sum-up-to-zero-3sum/" rel="bookmark" title="Algorithms to Find the Three Numbers in Array that Sum up to Zero (3Sum)">Algorithms to Find the Three Numbers in Array that Sum up to Zero (3Sum)</a> <small>Given an array nums of n integers, are there elements a, b, c in nums...</small></li>
<li><a href="https://helloacm.com/displaying-a-file-with-line-number-on-linux-shells/" rel="bookmark" title="Displaying a File with Line Number on Linux Shells">Displaying a File with Line Number on Linux Shells</a> <small>There are many ways to show line numbers when displaying text files. For example, in...</small></li>
<li><a href="https://helloacm.com/turning-a-dusty-mini-pc-into-a-home-server-my-nuc-8s-second-life/" rel="bookmark" title="Turning a Dusty Mini PC into a Home Server: My NUC-8’s Second Life">Turning a Dusty Mini PC into a Home Server: My NUC-8’s Second Life</a> <small>I gave an unused Beelink SEi8 mini PC a second life by installing Ubuntu and...</small></li>
<li><a href="https://helloacm.com/algorithm-to-check-if-a-string-matches-a-pattern/" rel="bookmark" title="Algorithm to Check if A String Matches a Pattern">Algorithm to Check if A String Matches a Pattern</a> <small>Given a pattern and a string str, find if str follows the same pattern. Here...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<blockquote>
An unpatched WordPress and plugin vulnerability apparently exposed a Cloudflare credential stored in the database. The attacker then deployed a malicious Worker, hijacked selected blog pages, redirected traffic to gambling websites, and added an unauthorised verified owner to Google Search Console. This post reconstructs the incident, examines what the evidence does and does not prove, and documents the hardening measures taken. It is a clear reminder that effective security depends on prompt patching, least-privilege access, monitoring, and recoverable backups—not on any single defensive product.
</blockquote>

<h3>A Google Alert Woke Me Up: Postmortem of a WordPress Security Incident</h3>

On 11 August 2026, I received an email from Google Search Console informing me that a new verified owner had been added to one of my websites.

[caption id="attachment_158060" align="alignnone" width="1312"]<a href="https://helloacm.com/a-google-alert-woke-me-up-postmortem-of-a-wordpress-security-incident/new-owner-google-webmaster/" rel="attachment wp-att-158060"><img src="https://helloacm.com/wp-content/uploads/2026/09/new-owner-google-webmaster.jpg" alt="New Owner is added/verified - which indicates a security breach." width="1312" height="1140" class="size-full wp-image-158060" /></a> New Owner is added/verified - which indicates a security breach.[/caption]

[bctt tweet="I did not recognise the account."]

The moment I saw the email, I knew something was wrong.

If an unknown person can verify themselves as a site owner, the problem is probably more serious than comment spam, credential stuffing, or routine vulnerability scanning. It suggests that the attacker may be able to control what the website returns to visitors.

I immediately started checking WordPress, Cloudflare, the MySQL database, the web server, and the system logs.

[caption id="attachment_158057" align="alignnone" width="1456"]<a href="https://helloacm.com/a-google-alert-woke-me-up-postmortem-of-a-wordpress-security-incident/cloudflare-audit-logs/" rel="attachment wp-att-158057"><img src="https://helloacm.com/wp-content/uploads/2026/09/cloudflare-audit-logs.jpg" alt="Cloudflare Account&#039;s Audit logs for access" width="1456" height="913" class="size-full wp-image-158057" /></a> Cloudflare Account's Audit logs for access[/caption]

The investigation confirmed that the website had been compromised. The attacker had intercepted requests for several blog pages before they reached my origin server and replaced the legitimate content with Indonesian-language gambling promotions.

I discovered and contained the <a href="https://helloacm.com/a-steemit-development-incident/" title="A SteemIt Development Incident">incident</a> reasonably quickly, but it was still a serious wake-up call.

WordPress has always been a frequent target. More accurately, however, the risk does not come only from WordPress core. It comes from the complete chain of trust involving WordPress, plugins, themes, databases, API tokens, CDN configuration, filesystem permissions, and operational practices.

[caption id="attachment_158056" align="alignnone" width="705"]<a href="https://helloacm.com/a-google-alert-woke-me-up-postmortem-of-a-wordpress-security-incident/cloudflare-api-access/" rel="attachment wp-att-158056"><img src="https://helloacm.com/wp-content/uploads/2026/09/cloudflare-api-access.jpg" alt="Cloudflare&#039;s API access logs" width="705" height="919" class="size-full wp-image-158056" /></a> Cloudflare's API access logs[/caption]

<h4>How the incident happened?</h4>

Over the years, I have accumulated approximately eight WordPress installations. Each site has its own collection of themes and plugins.

One plugin needed to communicate with the Cloudflare API, so it stored a Cloudflare credential in the WordPress database.

The WordPress options table contains a large amount of site and plugin configuration. Some plugins also store API tokens and other secrets there in a form that the application can use directly.

The affected site was still running an older WordPress 6.8.x release and included a plugin affected by a recently disclosed security issue. The <a href="https://helloacm.com/full-disclosure-helloacm-com-xss-vulnerability-notification/" title="Full Disclosure: helloacm.com XSS vulnerability notification">vulnerability </a>had been made public during the previous month, but I had not upgraded the site promptly after the patched version became available.

Based on the server logs, database contents, and Cloudflare configuration, the most likely attack path was:

<ol>
<li>The attacker exploited a publicly known WordPress or plugin vulnerability to access data that should not have been readable.</li>
<li>This exposed a Cloudflare credential stored by a plugin in the WordPress database.</li>
<li>The attacker used the credential to modify Cloudflare configuration and deploy an unauthorised Worker.</li>
<li>The malicious Worker intercepted selected blog requests before they reached my origin server.</li>
<li>Some legitimate pages were replaced with Indonesian-language gambling content.</li>
<li>By controlling the content returned for the domain, the attacker completed Google Search Console ownership verification.</li>
<li>Google’s “new owner added” email finally alerted me to the compromise.</li>
</ol>

This is the most plausible explanation supported by the available evidence. It is not a complete reconstruction of every action performed by the attacker.

Incident analysis must distinguish between what has been confirmed, what is highly likely, and what cannot yet be excluded. A technically plausible attack path should not automatically be presented as fully proven.

<h4>Timeline of the incident</h4>

<ul>
<li>July 2026: A security issue affecting the older WordPress or plugin combination was publicly disclosed, followed by a patched release. I did not upgrade immediately, creating a window of exposure.</li>
<li>Mid-to-late July 2026: The server logs showed increasing automated probes against WordPress and common plugin endpoints. Public servers receive this kind of scanning every day, so scanning alone does not prove a successful compromise.</li>
<li>Late July to early August 2026: Requests appeared for known vulnerable paths, upload locations, and suspicious script names. Most returned “not found,” but they showed that automated attack systems were continuously testing the site.</li>
<li>Early August 2026: The attacker likely used the unpatched vulnerability to access sensitive plugin configuration. The evidence supports database-secret disclosure more strongly than a successful WordPress dashboard login.</li>
<li>Shortly afterwards: The exposed Cloudflare credential was used to add or modify edge-side logic. Selected blog pages began being replaced before the requests reached the origin server.</li>
<li>During the same period: Hijacked pages displayed Indonesian-language gambling promotions, apparently for <a href="https://helloacm.com/3-ways-to-protect-your-website-from-negative-seo/" title="3 Ways to Protect Your Website from Negative SEO">SEO</a> poisoning and traffic redirection.</li>
<li>11 August 2026: By controlling the website response, the attacker completed Google Search Console verification and added an unknown identity as a verified site owner.</li>
<li>11 August 2026: I received Google’s ownership notification and immediately began incident response.</li>
<li>11–12 August 2026: I removed the unauthorised Google owner, inspected and removed suspicious Cloudflare Workers and configuration, and revoked and rotated potentially exposed credentials.</li>
<li>12 August 2026: I upgraded the affected WordPress installations and inspected administrator accounts, database privileges, web logs, file timestamps, scheduled tasks, and common WebShell indicators.</li>
<li>12 August 2026: I removed sensitive plugin configuration left in the database and began restricting MySQL filesystem capabilities.</li>
<li>12 August 2026: I added a rule <a href="https://helloacm.com/hardening-wordpress-disable-php-execution-in-wp-content-uploads/" title="Hardening WordPress: Disable PHP Execution in `wp-content/uploads`">preventing PHP execution inside WordPress upload directories</a> while reviewing the Apache configuration and service state.</li>
<li>Ongoing: I am continuing to review filesystem permissions, backup recoverability, Cloudflare token permissions, and the core, theme, and plugin versions used by the remaining WordPress installations.</li>
</ul>

<h4>What the attacker did</h4>

The following actions are either confirmed or strongly supported by the available evidence:

<ul>
<li>Obtained a credential capable of calling the Cloudflare API.</li>
<li>Added or modified Cloudflare edge-side execution logic.</li>
<li>Intercepted selected WordPress page requests before they reached the origin server.</li>
<li>Returned gambling promotional content to visitors or search engines.</li>
<li>Added an unauthorised owner to Google Search Console.</li>
<li>Attempted to exploit the domain’s existing reputation and rankings for SEO poisoning and traffic redirection.</li>
</ul>

Google Search Console owner access should not be underestimated.

It does not provide root access to the server and does not directly expose server files. However, an unauthorised owner may be able to submit sitemaps, request indexing, view search-related data, and help malicious pages appear in Google’s index more quickly.

Fortunately, Google’s ownership notification was the key signal that exposed the incident.

Without that email, an attack targeting only selected URLs, geographical regions, user agents, or search-engine crawlers could have been difficult to notice. Visiting the homepage normally might have shown nothing unusual.

<h4>Did the attacker log in to the WordPress dashboard?</h4>

At present, there is no evidence that the attacker successfully logged in to the WordPress dashboard.

The WordPress database still contained only my legitimate administrator account. I found no unauthorised administrator, and the available logs did not provide sufficient evidence of a successful dashboard login.

However, absence of evidence is not evidence of absence.

Logs may have been rotated, proxy layers may have hidden parts of the traffic, and some application activity may not have produced complete audit records.

The accurate conclusion is:

There is currently no evidence that the attacker logged in to the WordPress dashboard, but the related credentials should still be treated as potentially exposed.

I changed the WordPress administrator password and rotated the WordPress authentication keys and salts, invalidating existing login cookies and sessions.

The <a href="https://helloacm.com/how-to-ssh-to-remote-host-using-the-priviate-public-keys-authentication/" title="How to SSH to Remote Host using the Priviate/Public Keys Authentication?">authentication</a> keys and salts in <code>wp-config.php</code> are primarily used to protect cookies, sessions, and nonces. Changing them logs everyone out, but it does not change user passwords.

WordPress stores user passwords as salted password hashes. Even if a password hash is leaked, the attacker does not normally receive the plaintext password directly, but can still attempt to guess it offline.

Salting prevents precomputed rainbow-table attacks and ensures that identical passwords produce different hashes. It does not protect a weak password from dictionary or brute-force attacks.

Therefore, if the database may have been exposed, changing the password is still the correct response, especially if the password was short, predictable, or reused elsewhere.

<h4>Did the attacker gain access to the server filesystem?</h4>

This was my biggest concern.

A Cloudflare Worker executes on Cloudflare’s edge network. It can intercept, rewrite, or proxy website requests, but it does not automatically receive access to the origin server’s filesystem.

Likewise, a database vulnerability does not automatically provide operating-system command execution. The files MySQL can read or write depend on the database account’s privileges, MySQL configuration, and operating-system permissions.

My checks showed that the <a href="https://helloacm.com/shrink-wordpress-database-usage/" title="Shrink WordPress Database Usage">WordPress database</a> account did not have global file privileges. Only local maintenance and database-administrator accounts had the relevant privilege.

Local MySQL file import was disabled, and server-side file access was either constrained or subsequently disabled more strictly.

The logs contained many probes for uploaded scripts and WebShells, but the relevant requests generally returned “not found.”

I found no direct evidence that the attacker successfully uploaded and executed a WebShell. I also found no confirmed evidence that the attacker obtained a server shell or root access.

However, it would be irresponsible to conclude that the filesystem was definitely untouched.

Some website directories had historically been owned by the web-server account, with broader write access than necessary. If an attacker had obtained PHP code execution, they could theoretically have modified files writable by that account.

The most defensible conclusion is:

The exposed Cloudflare credential and edge-page hijacking are supported by evidence. No direct evidence of PHP execution, a successful WebShell, or server-file modification has been found. However, because some historical filesystem permissions were too broad, filesystem compromise cannot be ruled out solely from the available logs.

<h4>Were the WebShell probes related to this vulnerability?</h4>

The logs included requests for suspicious PHP filenames under WordPress upload directories. These looked more like generic WebShell discovery attempts.

The requests returned HTTP <code>404</code>, meaning those particular files were not present when requested.

A request for a filename resembling a WebShell does not prove that the scanner uploaded it. Automated attack tools routinely probe the Internet for known WebShell filenames left behind by previous compromises.

The <a href="https://helloacm.com/php7-x-is-deprecated-by-wordpress-why-you-should-upgrade-to-php8-x/" title="PHP7.x is deprecated by WordPress: Why You Should Upgrade to PHP8.x?">WordPress</a> vulnerability may have allowed access to database information, but that does not automatically provide PHP execution or filesystem write access.

Installing a working WebShell would normally require an additional capability, such as:

<ul>
<li>Arbitrary file upload.</li>
<li>Arbitrary file write.</li>
<li>Remote code execution.</li>
<li>Compromised WordPress dashboard access.</li>
<li>Permission to install a malicious plugin.</li>
<li>Another vulnerable component providing code execution.</li>
</ul>

No causal connection has therefore been established between the observed WebShell probes and the Cloudflare credential exposure involved in this incident.

The upload-directory protection is preventive hardening, not proof that this attack involved a WebShell.

<h4>Were MySQL usernames or passwords exposed?</h4>

If the vulnerability only permitted access to the WordPress options table, it could expose tokens and secrets stored there by plugins, but it would not necessarily expose the WordPress MySQL password.

The WordPress database username and password are normally stored in <code>wp-config.php</code>, not in the WordPress options table.

The WordPress MySQL credentials would be more likely to leak only if the attacker obtained arbitrary file-read access, PHP code execution, or another capability that allowed <code>wp-config.php</code> to be read.

MySQL also does not normally store recoverable plaintext database-user passwords in its system tables. It stores authentication information instead. However, weak passwords may still be vulnerable to offline attacks if those authentication records are exposed.

Based on the investigation so far, I found no direct evidence that the WordPress database credentials or all MySQL user passwords were leaked.

Rotating the dedicated WordPress database account password is nevertheless a relatively low-cost precaution. After changing the password in MySQL, the matching value in <code>wp-config.php</code> must be updated immediately, or WordPress will no longer be able to connect to the database.

<h4>Why did Cloudflare not stop the attack?</h4>

Cloudflare is not a box that automatically solves every security problem.

It can provide DDoS protection, a web application firewall, bot management, rate limiting, and origin shielding. These protections depend on appropriate configuration and on the malicious activity matching something Cloudflare can identify.

More importantly, the attacker apparently obtained a valid Cloudflare API token.

From Cloudflare’s perspective, an administrative operation made with a valid credential may look authorised. A WAF primarily examines web traffic; it does not automatically classify every API operation performed with a valid token as malicious.

Cloudflare was therefore not merely a defensive layer in this incident. Because the exposed token had too much authority, Cloudflare also became an amplifier in the attack chain.

This reinforced an important principle:

API tokens must follow the principle of least privilege. A normal WordPress plugin should not possess a credential capable of controlling an entire website’s request path unless that capability is absolutely necessary.

<h4>Why does WordPress store secrets in the database?</h4>

Many WordPress plugins store external API credentials in the options table in a form that the application can use directly.

This does not necessarily mean that the plugin developer knows nothing about security. The application must be able to obtain the credential at runtime to call an external API without human intervention.

Even if the database value is encrypted, the application must still have access to the corresponding decryption key. If an attacker gains sufficient application-level privileges and the key exists in the same server or execution environment, the attacker may still be able to decrypt it.

Encryption has value, but it is not a substitute for access control.

More effective controls include:

<ul>
<li>Avoid giving WordPress plugins high-privilege infrastructure credentials.</li>
<li>Create separate tokens for each site and purpose.</li>
<li>Restrict every token to only the required resources and operations.</li>
<li>Use expiry dates and rotate credentials regularly.</li>
<li>Delete unused plugins instead of merely deactivating them.</li>
<li>Treat database backups as sensitive data.</li>
<li>Monitor token usage, Worker changes, and ownership changes.</li>
<li>Revoke credentials when the plugin that used them is removed or disabled.</li>
</ul>

Secret-management systems such as Key Vault can improve storage, rotation, access control, and auditing. However, they cannot automatically protect an application that has already been completely compromised.

The most important safeguards are limiting what a credential can do and limiting how long it remains valid.

<h4>What I did after discovering the incident</h4>

Once I discovered the compromise, my first priority was to contain the active risk rather than construct a perfectly neat attack narrative.

The completed or ongoing actions include:

<ol>
<li>Removed the unauthorised Google Search Console owner.</li>
<li>Removed unauthorised Cloudflare Workers and related configuration.</li>
<li>Revoked and regenerated potentially exposed API tokens.</li>
<li>Upgraded the affected WordPress installations.</li>
<li>Updated plugins and themes and removed unused components.</li>
<li>Inspected WordPress administrator accounts, application passwords, and suspicious sessions.</li>
<li>Removed sensitive plugin settings left in the database.</li>
<li>Restricted the WordPress database account’s privileges.</li>
<li>Disabled unnecessary MySQL local-file import functionality. <a href="https://helloacm.com/hardening-mysql-file-access-with-local_infile0-and-secure_file_privnull/" title="Hardening MySQL File Access with local_infile=0 and secure_file_priv=NULL">Linux Disk Space Troubleshooting: Find Large Files and Directories with ncdu</a></li>
<li>Disabled or tightly constrained MySQL server-side file access.</li>
<li>Reviewed web logs, system logs, scheduled tasks, and suspicious files.</li>
<li>Disabled PHP execution inside WordPress upload directories.</li>
<li>Began reviewing owners, groups, and permissions across all website files.</li>
<li>Checked whether existing backups were complete and recoverable, not merely whether backup files existed.</li>
<li>Rotated administrator <a href="https://helloacm.com/monitoring-28-vps-machines-including-a-raspberry-pi-with-nezha-dashboard/" title="Monitoring 28 VPS Machines (Including a Raspberry Pi) with Nezha Dashboard">passwords</a>, database passwords, and WordPress authentication keys and salts.</li>
</ol>

<h4>Why disable PHP execution in the uploads directory?</h4>
See: <a href="https://helloacm.com/hardening-wordpress-disable-php-execution-in-wp-content-uploads/" title="Hardening WordPress: Disable PHP Execution in `wp-content/uploads`">Hardening WordPress: Disable PHP Execution in `wp-content/uploads`</a>

The WordPress uploads directory should primarily contain static content such as images, videos, and PDF documents. Under normal circumstances, there is no reason to execute PHP there.

Suppose a vulnerability allows an attacker to bypass file-type validation and upload a disguised PHP script. If the web server permits PHP execution in the uploads directory, that file could become a WebShell.

The attacker might then execute commands through a browser, read configuration files, modify website code, or attempt to move further into the server.

Disabling PHP execution in the uploads directory breaks that common escalation path.

Even if a malicious PHP file is uploaded, the web server will not execute it as a program.

This protection usually presents little compatibility risk and significantly reduces the impact of many WordPress upload vulnerabilities. It is therefore a sensible default.

However, it is not a complete defence. If theme, plugin, or other executable directories remain writable by the web-server account, an attacker may find another location.

<h4>Revisiting filesystem permissions</h4>

The investigation revealed that, over the years, I had left some WordPress permissions broader than necessary.

This was partly done for convenience. Installing plugins, enabling updates, and resolving write errors becomes easier when the web-server account owns large parts of the website.

Convenience, however, often increases the attack surface.

Also, for MySQL, it is better to disable local file access: <a href="https://helloacm.com/hardening-mysql-file-access-with-local_infile0-and-secure_file_privnull/" title="Hardening MySQL File Access with local_infile=0 and secure_file_priv=NULL">Hardening MySQL File Access with local_infile=0 and secure_file_priv=NULL</a>

I am now restructuring permissions according to least privilege:

<ul>
<li>Application code should normally be owned by a deployment or administrative account.</li>
<li>The web-server account should be able to read code but should not own the entire site.</li>
<li>Write access should be granted only to upload, cache, or temporary directories that genuinely require it.</li>
<li>Configuration files should use stricter permissions.</li>
<li>The entire site should not be writable by the web-server account merely for convenience.</li>
<li>Temporary troubleshooting permissions must not become permanent.</li>
<li>Writable directories should not also execute server-side scripts wherever possible.</li>
</ul>

The goal is not to find one universally correct permission number.

The real question is:

If the PHP process is compromised, exactly which files can the attacker modify?

The answer should be “only a small number of operationally necessary directories,” not “the entire website.”

How I will handle WordPress updates

After this incident, WordPress upgrades can no longer remain an “I will do it when I have time” maintenance task.

My plan is to:

<ul>
<li>Review and apply WordPress security updates promptly.</li>
<li>Update plugins and themes at the same time.</li>
<li>Remove disabled, abandoned, or unnecessary plugins.</li>
<li>Avoid blindly enabling automatic major-version upgrades everywhere.</li>
<li>Verify backups before upgrading.</li>
<li>Test critical website functions after each upgrade.</li>
<li>Maintain a central version inventory for all WordPress installations.</li>
<li>Check regularly for known vulnerabilities instead of relying only on dashboard notifications.</li>
</ul>

I still prefer to perform important upgrades manually because the servers contain several historical websites with different plugin combinations. Fully unattended major upgrades could introduce compatibility problems.

However, “manual upgrades” must never become an excuse for “no upgrades.”

A backup is not enough unless it can be restored

It is easy to develop a false sense of security when scheduled backup jobs are running and files appear in a backup directory.

A reliable backup should satisfy several conditions:

<ul>
<li>The backup files are complete and not corrupted.</li>
<li>Both the database and uploaded content are included.</li>
<li>At least one copy exists outside the production server.</li>
<li>The same credentials cannot delete both production data and every backup.</li>
<li>A defined retention policy exists.</li>
<li>Restore tests are performed periodically.</li>
<li>The expected recovery time is understood.</li>
</ul>

A backup that has never been restored is only a potentially useful copy of some data.

<h4>Should I migrate to a static blog?</h4>

While discussing the incident with friends, one suggestion was to migrate to a static-blog system such as Hexo. Articles could be written in Markdown, stored in GitHub, and converted into static pages through an automated deployment pipeline.

The suggestion makes sense.

My blogs are primarily personal records. They do not depend heavily on membership systems, complex plugins, or dynamic backend functionality. For this use case, a static site would significantly reduce the attack surface associated with PHP, databases, plugins, and administrative logins.

However, I currently have approximately eight WordPress sites, accumulated through many years of experiments and technical history.

Migrating all articles, URLs, images, comments, and SEO metadata at once would not be a small project.

A more realistic approach may be:

<ul>
<li>Write new content in Markdown.</li>
<li>Migrate the simplest blogs first.</li>
<li>Reduce functionality on WordPress sites that must remain.</li>
<li>Delete unnecessary plugins and themes.</li>
<li>Preserve old URLs where possible to avoid breaking inbound links.</li>
<li>Use dynamic functionality only where it is genuinely required.</li>
</ul>

With modern AI agents, bulk-converting articles, generating metadata, repairing image paths, creating static-site configuration, and debugging deployment pipelines is considerably easier than it used to be.

That makes migrating years of historical content much more practical.

<h4>What this incident taught me</h4>

The attack did not appear to begin with the most obvious target: my WordPress administrator password.

Instead, it followed a less visible chain of trust:

Unpatched application or plugin → sensitive database configuration → overprivileged external token → edge-level request hijacking → unauthorised search-engine ownership

Each individual weakness might not appear catastrophic:

<ul>
<li>A WordPress update was delayed.</li>
<li>A plugin stored an API token in the database.</li>
<li>The token had broader permissions than necessary.</li>
<li>A Cloudflare Worker could modify page responses.</li>
<li>Google allowed ownership to be verified through website content.</li>
</ul>

When these conditions were combined, however, the attacker gained capabilities far beyond the original vulnerability.

Security is not simply “I use Cloudflare,” “I enabled HTTPS,” or “my password is strong.”

It is a system of boundaries, permissions, patching, monitoring, detection, alerting, backups, and recovery capabilities.

The fortunate part of this incident is that the attacker’s apparent objective was gambling-site traffic and search-ranking manipulation. Google’s ownership-change email also alerted me quickly.

So far, I have found no direct evidence that the attacker logged in to the <a href="https://helloacm.com/wordpress-how-to-output-full-text-in-the-feed/" title="WordPress: How to Output Full Text in the Feed?">WordPress</a> dashboard, executed a PHP WebShell, or gained a server shell.

But “not found” does not mean “definitively did not happen.”

The remaining hardening work will therefore assume a more serious level of exposure: rotating credentials, reducing permissions, patching software, checking files, validating backups, and monitoring the systems for further anomalies.

<h4>Final thoughts</h4>

I have maintained websites and servers for many years. I already knew that WordPress and its plugins required prompt updates.

There is always, however, a gap between knowing something and acting on it—a quiet assumption that nothing will happen during the next few days.

The Internet does not wait until I have time.

Once a vulnerability becomes public, automated scanning and mass exploitation can begin very quickly. An attacker does not need to target me personally. They only need to scan enough websites and find one that has not yet been upgraded.

Google Search Console’s notification woke me up. It also reminded me that the most frightening part of a security incident is not simply discovering that a page was modified. It is not knowing exactly how far the attacker progressed.

This incident was a clear warning.

My next steps include enforcing the no-PHP rule in WordPress upload directories, disabling unnecessary MySQL file capabilities, rebuilding filesystem permissions, testing backup restoration, reducing Cloudflare token privileges, and upgrading every WordPress installation more consistently.

Where practical, I will also begin migrating suitable blogs to Markdown-based static sites.

WordPress is convenient—but convenience is never free.

[caption id="attachment_158058" align="alignnone" width="674"]<a href="https://helloacm.com/a-google-alert-woke-me-up-postmortem-of-a-wordpress-security-incident/cloudflare-kv-flow/" rel="attachment wp-att-158058"><img src="https://helloacm.com/wp-content/uploads/2026/09/cloudflare-kv-flow.jpg" alt="Cloudflare Serves the requests with KV values." width="674" height="526" class="size-full wp-image-158058" /></a> Cloudflare Serves the requests with KV values.[/caption]

[caption id="attachment_158059" align="alignnone" width="1269"]<a href="https://helloacm.com/a-google-alert-woke-me-up-postmortem-of-a-wordpress-security-incident/cloudflare-kv-html-values/" rel="attachment wp-att-158059"><img src="https://helloacm.com/wp-content/uploads/2026/09/cloudflare-kv-html-values.jpg" alt="CloudFlare&#039;s KV values which hijacks the requests" width="1269" height="696" class="size-full wp-image-158059" /></a> CloudFlare's KV values which hijacks the requests[/caption]

<h3>Appendix: Malicious CloudFlare Worker Code to Hijack HTML</h3>
<pre lang=js>
// Worker penyaji halaman HTML kustom dari KV (milik tools manual-page/).
// Terpisah dari lp-worker: script name, KV namespace, dan deploy-nya sendiri.
//
// Key KV di-prefix hostname (satu namespace dipakai banyak domain):
// {host}:pages.txt -&gt; daftar path yang aktif untuk host tsb
// page:{host}:{path} -&gt; isi HTML halaman
// Path yang terdaftar disajikan apa adanya ke semua pengunjung.
// Path lain → diteruskan transparan ke origin.

const CACHE_TTL_MS = 300_000; // cache pages.txt per host di isolate, 5 menit

const pagesCache = new Map(); // host -&gt; { time, pages }

async function getPages(env, host) {
    const now = Date.now();
    const cached = pagesCache.get(host);
    if (cached && now - cached.time &lt; CACHE_TTL_MS) {
        return cached.pages;
    }
    const text = await env.PAGES.get($ {
        host
    }: pages.txt);
    const pages = new Set(
        text ? text.split('\n').map((p) => p.trim()).filter((p) =&gt; p !== '') : []
    );
    pagesCache.set(host, {
        time: now,
        pages
    });
    return pages;
}

export default {
    async fetch(request, env) {
        if (request.method !== 'GET' && request.method !== 'HEAD') {
            return passThrough();
        }

        const url = new URL(request.url);
        const host = url.host.toLowerCase().replace(/^www\./, '');
        // Normalisasi sama dengan main.py: lowercase, tanpa trailing slash
        const key = '/' + url.pathname.toLowerCase().replace(/^\/+|\/+$/g, '');

        // Pass-through ke origin — inject X-Forwarded-Proto agar WordPress/nginx
        // tahu request aslinya HTTPS (diperlukan kalau SSL mode CF = Flexible)
        function passThrough() {
            const modified = new Request(request);
            modified.headers.set('X-Forwarded-Proto', 'https');
            modified.headers.set('X-Forwarded-Host', url.host);
            modified.headers.set('X-Forwarded-SSL', 'on');
            modified.headers.set('X-Forwarded-Port', '443');
            return fetch(modified);
        }

        // Root → teruskan ke origin (situs asli tetap jalan normal)
        if (key === '/') {
            return passThrough();
        }

        // File verifikasi GSC (googlexxx.html) dari KV — cek dua key:
        //   - key polos: google{token}.html (utils.py via lp-worker-content)
        //   - key prefixed: page:{host}:{path} (manual-page/main.py)
        const verifyMatch = key.match(/^\/(google[a-z0-9]+\.html)$/);
        if (verifyMatch) {
            const [plain, gsc] = await Promise.all([
                env.PAGES.get(verifyMatch[1]),
                env.PAGES.get(`page:${host}:${key}`),
            ]);
            const html = plain || gsc;
            if (html !== null) {
                return new Response(html, {
                    headers: {
                        'content-type': 'text/html; charset=utf-8'
                    },
                });
            }
            return passThrough();
        }

        // Binding KV hilang (deploy parsial) -&gt; gagal-aman ke origin,
        // jangan 500-kan seluruh domain
        if (!env.PAGES) {
            return passThrough();
        }

        try {
            const pages = await getPages(env, host);
            if (!pages.has(key)) {
                return passThrough();
            }

            const html = await env.PAGES.get(`page:${host}:${key}`);
            if (html === null) {
                return passThrough();
            }
            return new Response(html, {
                headers: {
                    'content-type': 'text/html; charset=utf-8'
                },
            });
        } catch {
            return passThrough(); // KV error -&gt; gagal-aman ke origin
        }
    },
};
</pre>

[show_file file="/var/www/wp-post-common/helloacm.com/incidents.php"]

[show_posts keyword="security incident"]

[show_posts keyword="wordpress"]

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/accidentally-deleting-over-18000-files-with-shiftdelete-recovering-data-from-a-surface-ssd-using-winfr/" rel="bookmark" title="Accidentally Deleting Over 18,000 Files with Shift+Delete: Recovering Data from a Surface SSD Using WinFR">Accidentally Deleting Over 18,000 Files with Shift+Delete: Recovering Data from a Surface SSD Using WinFR</a> <small>While freeing space on my Surface Laptop Studio 2, I accidentally used Shift+Delete to permanently...</small></li>
<li><a href="https://helloacm.com/using-absolute-keyword-in-delphi-to-remove-unnecessary-assignment-function/" rel="bookmark" title="Using Absolute Keyword in Delphi to Remove Unnecessary Assignment Function">Using Absolute Keyword in Delphi to Remove Unnecessary Assignment Function</a> <small>The Delphi/Object Pascal provides a keyword absolute, which you can also find examples at this...</small></li>
<li><a href="https://helloacm.com/how-to-compute-the-chain-age-uptime-and-downtime-for-steem-blockchain/" rel="bookmark" title="How to Compute the Chain Age, Uptime and Downtime for Steem Blockchain?">How to Compute the Chain Age, Uptime and Downtime for Steem Blockchain?</a> <small>Steem Blockchain has been running for a while, and how to compute the Chain Age,...</small></li>
<li><a href="https://helloacm.com/how-to-parallel-for-in-linux-bash-shell/" rel="bookmark" title="How to Parallel For in Linux Bash Shell?">How to Parallel For in Linux Bash Shell?</a> <small>The Linux Bash Shell supports inherent task parallelism. For example, you can put a &#038;...</small></li>
<li><a href="https://helloacm.com/algorithms-to-find-the-three-numbers-in-array-that-sum-up-to-zero-3sum/" rel="bookmark" title="Algorithms to Find the Three Numbers in Array that Sum up to Zero (3Sum)">Algorithms to Find the Three Numbers in Array that Sum up to Zero (3Sum)</a> <small>Given an array nums of n integers, are there elements a, b, c in nums...</small></li>
<li><a href="https://helloacm.com/displaying-a-file-with-line-number-on-linux-shells/" rel="bookmark" title="Displaying a File with Line Number on Linux Shells">Displaying a File with Line Number on Linux Shells</a> <small>There are many ways to show line numbers when displaying text files. For example, in...</small></li>
<li><a href="https://helloacm.com/turning-a-dusty-mini-pc-into-a-home-server-my-nuc-8s-second-life/" rel="bookmark" title="Turning a Dusty Mini PC into a Home Server: My NUC-8’s Second Life">Turning a Dusty Mini PC into a Home Server: My NUC-8’s Second Life</a> <small>I gave an unused Beelink SEi8 mini PC a second life by installing Ubuntu and...</small></li>
<li><a href="https://helloacm.com/algorithm-to-check-if-a-string-matches-a-pattern/" rel="bookmark" title="Algorithm to Check if A String Matches a Pattern">Algorithm to Check if A String Matches a Pattern</a> <small>Given a pattern and a string str, find if str follows the same pattern. Here...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://helloacm.com/a-google-alert-woke-me-up-postmortem-of-a-wordpress-security-incident/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>The Controlled Variable Method: Why Good Experiments Change One Thing at a Time?</title>
		<link>https://helloacm.com/the-controlled-variable-method-why-good-experiments-change-one-thing-at-a-time/</link>
					<comments>https://helloacm.com/the-controlled-variable-method-why-good-experiments-change-one-thing-at-a-time/#respond</comments>
		
		<dc:creator><![CDATA[ACMer]]></dc:creator>
		<pubDate>Mon, 07 Sep 2026 10:08:52 +0000</pubDate>
				<category><![CDATA[Engineering]]></category>
		<category><![CDATA[knowledgebase]]></category>
		<category><![CDATA[Simply Explained]]></category>
		<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[A/B testing]]></category>
		<category><![CDATA[benchmarking]]></category>
		<category><![CDATA[causation]]></category>
		<category><![CDATA[controlled variable method]]></category>
		<category><![CDATA[controlled variables]]></category>
		<category><![CDATA[correlation vs causation]]></category>
		<category><![CDATA[dependent variable]]></category>
		<category><![CDATA[experimental design]]></category>
		<category><![CDATA[independent variable]]></category>
		<category><![CDATA[Knowledge Sharing]]></category>
		<category><![CDATA[Performance Testing]]></category>
		<category><![CDATA[scientific experiment]]></category>
		<category><![CDATA[scientific method]]></category>
		<category><![CDATA[software engineering]]></category>
		<category><![CDATA[Troubleshooting]]></category>
		<guid isPermaLink="false">https://helloacm.com/?p=158080</guid>

					<description><![CDATA[<blockquote>
The controlled variable method is one of the most important principles in scientific experiments and engineering practice. When investigating how one factor affects an outcome, we change that factor while keeping other relevant conditions as consistent as possible. Using examples from sugar dissolution, plant growth, and software performance testing, this article explains independent, dependent, and controlled variables, and shows why controlled experiments are essential for understanding causation, benchmarking, and systematic problem solving.
</blockquote>

The controlled variable method is one of the most fundamental ideas in scientific experimentation.

In simple terms:

<strong>When studying how one factor affects an outcome, change that factor while keeping other relevant conditions as constant as possible.</strong>

Its purpose is to answer a very important question:

<strong>What actually caused the result to change?</strong>

<h3>A Simple Example</h3>

Suppose we want to investigate:

<strong>Does water temperature affect how quickly sugar dissolves?</strong>

We could perform two experiments:

<ul>
<li>Experiment A: 200 mL of water at 20°C with 20 g of sugar.</li>
<li>Experiment B: 200 mL of water at 60°C with 20 g of sugar.</li>
</ul>

Both experiments use the same type of container, the same amount of water, the same amount of sugar, and the same stirring method.

The only major difference is:

<strong>water temperature.</strong>

We then measure how long it takes for the sugar to dissolve completely.

If the sugar consistently dissolves much faster in the 60°C water, we have stronger evidence that:

<strong>temperature affects the rate at which sugar dissolves.</strong>

<h3>The Three Types of Variables</h3>

Controlled experiments normally involve three important types of variables.

<h4>1. Independent Variable</h4>

The independent variable is the factor deliberately changed by the experimenter.

In our example, it is:

<strong>water temperature.</strong>

For example:

<code>20°C → 40°C → 60°C</code>

<h4>2. Dependent Variable</h4>

The dependent variable is the outcome that we measure or observe.

In this example, it is:

<strong>the time required for the sugar to dissolve.</strong>

We change the temperature and observe whether the dissolving time changes as a result.

<h4>3. Controlled Variables</h4>

Controlled variables are other factors that might influence the result and therefore should be kept as consistent as possible.

For example:

<ul>
<li>volume of water</li>
<li>amount of sugar</li>
<li>type of sugar</li>
<li>size and material of the container</li>
<li>stirring speed</li>
<li>stirring method</li>
</ul>

A useful way to remember the controlled variable method is:

<strong>Change one thing, measure one thing, and keep the rest as constant as possible.</strong>

<h3>Why Do We Need Controlled Variables?</h3>

Most real-world outcomes are affected by many factors simultaneously.

If several conditions change at the same time, it becomes difficult to determine which factor actually caused the observed result.

Imagine a programmer saying:

<strong>“I replaced the algorithm and the program became 30% faster.”</strong>

That sounds like evidence that the new algorithm is better.

But what if several other things changed at the same time?

<ul>
<li>The benchmark ran on a faster CPU.</li>
<li>The compiler was upgraded.</li>
<li>Compiler optimisation was enabled.</li>
<li>The test dataset became smaller.</li>
<li>The database cache was already warm.</li>
<li>Network conditions improved.</li>
</ul>

Now it becomes impossible to confidently attribute the 30% improvement to the <a href="https://helloacm.com/deep-dive-into-reinforcement-learning-understanding-the-q-learning-algorithm/" title="Deep Dive into Reinforcement Learning: Understanding the Q-Learning Algorithm">algorithm</a> itself.

A better experiment would look like this:

<code>Algorithm A + same machine + same compiler + same dataset + same configuration</code>

<code>Algorithm B + same machine + same compiler + same dataset + same configuration</code>

The only important change is:

<strong>the algorithm.</strong>

Then we compare execution times.

This is essentially the same principle behind benchmarks, A/B tests, and controlled experiments in software engineering.

<h3>Another Example: Fertiliser and Plant Growth</h3>

Suppose we want to investigate:

<strong>Does fertiliser cause plants to grow faster?</strong>

A badly designed experiment might look like this:

<code>Plant A: fertiliser + lots of sunlight</code>

<code>Plant B: no fertiliser + little sunlight</code>

After several weeks, Plant A is much taller.

Can we conclude that fertiliser caused the difference?

No.

Two major factors changed:

<ul>
<li>fertiliser</li>
<li>sunlight</li>
</ul>

We cannot tell which one caused the plant to grow faster.

A better <a href="https://helloacm.com/multi-processes-experiments-when-can-windows-utilize-all-the-cores/" title="Multi-Processes Experiments – When Can Windows Utilize All the Cores?">experiment</a> would keep the following conditions similar:

<ul>
<li>plant species</li>
<li>soil</li>
<li>pot size</li>
<li>amount of water</li>
<li>sunlight</li>
<li>temperature</li>
</ul>

The only difference would be:

<code>Plant A: fertiliser</code>

<code>Plant B: no fertiliser</code>

Now the experiment provides much stronger evidence about whether fertiliser affects plant growth.

<h3>Controlled Does Not Mean Absolutely Identical</h3>

There is an important subtlety here.

Controlling variables does not mean that every condition in the real world must be perfectly identical.

That is often impossible.

Two plants will never have exactly identical biological states, and two executions of a computer program will never have exactly identical CPU scheduling, cache states, interrupts, or background activity.

The real goal is:

<strong>to control the important factors that could significantly influence the result.</strong>

Researchers can also reduce random variation by:

<ul>
<li>repeating experiments</li>
<li>increasing sample sizes</li>
<li>randomising experimental subjects</li>
<li>calculating averages</li>
<li>performing statistical analysis</li>
</ul>

<h3>Controlled Experiments and Causation</h3>

The deeper importance of the controlled variable method is not merely about how experiments are performed.

It reflects one of the most important principles of scientific reasoning:

<strong>Correlation does not imply causation.</strong>

Suppose we observe:

<code>When A increases, B also increases.</code>

That does not automatically prove:

<code>A causes B.</code>

There could be another variable C:

<code>C → A</code>

<code>C → B</code>

It is also possible that:

<code>B → A</code>

Or the relationship could simply be coincidence.

Controlled experiments try to eliminate these alternative explanations.

If:

<ul>
<li>other important conditions remain similar</li>
<li>only A is deliberately changed</li>
<li>B changes consistently afterwards</li>
<li>the result can be reproduced repeatedly</li>
</ul>

then we gain much stronger evidence that A actually influences B.

<h3>Software Engineers Use Controlled Experiments All the Time</h3>

The controlled variable method is not limited to physics, chemistry, or biology.

Software engineers use the same idea constantly.

Suppose an API originally has:

<code>API latency = 500 ms</code>

After adding a database index:

<code>API latency = 200 ms</code>

If everything else remains approximately the same, there is good evidence that the index caused the improvement.

But imagine changing all of these things simultaneously:

<ul>
<li>adding more servers</li>
<li>rewriting the SQL query</li>
<li>adding Redis caching</li>
<li>creating database indexes</li>
<li>upgrading the CPU</li>
</ul>

The system might become ten times faster.

But now there is another problem:

<strong>Which optimisation actually mattered?</strong>

This is why a powerful technique in performance tuning, <a href="https://helloacm.com/python-debugging-get-current-executed-function-name-and-print-traceback/" title="Python Debugging: Get Current Executed Function Name and Print Traceback">debugging</a>, and system experimentation is:

<strong>Change one important thing at a time.</strong>

Change it.

Measure it.

Record the result.

Then make the next change.

<h3>Conclusion</h3>

The controlled variable method can be summarised very simply:

<strong>Study one major factor at a time.</strong>

In other words:

<ul>
<li>change the independent variable</li>
<li>measure the dependent variable</li>
<li>control the other relevant variables</li>
</ul>

A useful mental model is:

<code>Change one thing → Observe the result → Keep other conditions consistent</code>

This is more than just an experimental technique.

It is also a powerful way of thinking.

Whenever two things appear to happen together, instead of immediately assuming causation, ask:

<strong>What else changed?</strong>

<strong>If I changed only this one variable, would the same result still occur?</strong>

That question is at the heart of the controlled variable method.

[show_posts keyword="knowledge"]

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/listen-to-what-an-seo-expert-has-to-say-about-its-benefits/" rel="bookmark" title="Listen to what an SEO expert has to say about its benefits">Listen to what an SEO expert has to say about its benefits</a> <small>To get the most from your business, you must follow your customers and take your...</small></li>
<li><a href="https://helloacm.com/excel-tip-faster-auto-complete/" rel="bookmark" title="Excel Tip: Faster Auto-complete">Excel Tip: Faster Auto-complete</a> <small>The Microsoft Excel is heavily used and widely used. There are so many tricks/tips that...</small></li>
<li><a href="https://helloacm.com/code-is-becoming-cheaper-what-really-matters-for-programmers-in-the-ai-era/" rel="bookmark" title="Code Is Becoming Cheaper: What Really Matters for Programmers in the AI Era">Code Is Becoming Cheaper: What Really Matters for Programmers in the AI Era</a> <small>AI is rapidly reducing the cost of writing code. Work that once took programmers hours...</small></li>
<li><a href="https://helloacm.com/linux-disk-space-troubleshooting-find-large-files-and-directories-with-ncdu/" rel="bookmark" title="Linux Disk Space Troubleshooting: Find Large Files and Directories with ncdu">Linux Disk Space Troubleshooting: Find Large Files and Directories with ncdu</a> <small>Linux servers can run out of disk space because of growing logs, backups, caches, or...</small></li>
<li><a href="https://helloacm.com/how-to-design-a-high-performance-hit-counter-class/" rel="bookmark" title="How to Design a High Performance/Scalable Hit Counter Class?">How to Design a High Performance/Scalable Hit Counter Class?</a> <small>Design a hit counter which counts the number of hits received in the past 5...</small></li>
<li><a href="https://helloacm.com/include-the-binary-files-in-your-source-code/" rel="bookmark" title="Include the Binary Files in Your Source Code">Include the Binary Files in Your Source Code</a> <small>Sometimes, you might want to wrap a binary file (image, executable) in your source code,...</small></li>
<li><a href="https://helloacm.com/using-cloudflare-worker-serverless-technology-to-deploy-a-load-balancer-rpc-node-for-steem-blockchain/" rel="bookmark" title="Using CloudFlare Worker Serverless Technology to Deploy a Load Balancer (RPC Node) for Steem Blockchain">Using CloudFlare Worker Serverless Technology to Deploy a Load Balancer (RPC Node) for Steem Blockchain</a> <small>A few days ago, I launched the &#8220;Load Balancing&#8221; Node: https://steem.senior.workers.dev/ It is a Javascript...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-backtracking-algorithm-to-find-factor-combinations-math-recursive-depth-first-search/" rel="bookmark" title="Teaching Kids Programming &#8211; Backtracking Algorithm to Find Factor Combinations (Math, Recursive Depth First Search)">Teaching Kids Programming &#8211; Backtracking Algorithm to Find Factor Combinations (Math, Recursive Depth First Search)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms Numbers can be regarded as the...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<blockquote>
The controlled variable method is one of the most important principles in scientific experiments and engineering practice. When investigating how one factor affects an outcome, we change that factor while keeping other relevant conditions as consistent as possible. Using examples from sugar dissolution, plant growth, and software performance testing, this article explains independent, dependent, and controlled variables, and shows why controlled experiments are essential for understanding causation, benchmarking, and systematic problem solving.
</blockquote>

The controlled variable method is one of the most fundamental ideas in scientific experimentation.

In simple terms:

<strong>When studying how one factor affects an outcome, change that factor while keeping other relevant conditions as constant as possible.</strong>

Its purpose is to answer a very important question:

<strong>What actually caused the result to change?</strong>

<h3>A Simple Example</h3>

Suppose we want to investigate:

<strong>Does water temperature affect how quickly sugar dissolves?</strong>

We could perform two experiments:

<ul>
<li>Experiment A: 200 mL of water at 20°C with 20 g of sugar.</li>
<li>Experiment B: 200 mL of water at 60°C with 20 g of sugar.</li>
</ul>

Both experiments use the same type of container, the same amount of water, the same amount of sugar, and the same stirring method.

The only major difference is:

<strong>water temperature.</strong>

We then measure how long it takes for the sugar to dissolve completely.

If the sugar consistently dissolves much faster in the 60°C water, we have stronger evidence that:

<strong>temperature affects the rate at which sugar dissolves.</strong>

<h3>The Three Types of Variables</h3>

Controlled experiments normally involve three important types of variables.

<h4>1. Independent Variable</h4>

The independent variable is the factor deliberately changed by the experimenter.

In our example, it is:

<strong>water temperature.</strong>

For example:

<code>20°C → 40°C → 60°C</code>

<h4>2. Dependent Variable</h4>

The dependent variable is the outcome that we measure or observe.

In this example, it is:

<strong>the time required for the sugar to dissolve.</strong>

We change the temperature and observe whether the dissolving time changes as a result.

<h4>3. Controlled Variables</h4>

Controlled variables are other factors that might influence the result and therefore should be kept as consistent as possible.

For example:

<ul>
<li>volume of water</li>
<li>amount of sugar</li>
<li>type of sugar</li>
<li>size and material of the container</li>
<li>stirring speed</li>
<li>stirring method</li>
</ul>

A useful way to remember the controlled variable method is:

<strong>Change one thing, measure one thing, and keep the rest as constant as possible.</strong>

<h3>Why Do We Need Controlled Variables?</h3>

Most real-world outcomes are affected by many factors simultaneously.

If several conditions change at the same time, it becomes difficult to determine which factor actually caused the observed result.

Imagine a programmer saying:

<strong>“I replaced the algorithm and the program became 30% faster.”</strong>

That sounds like evidence that the new algorithm is better.

But what if several other things changed at the same time?

<ul>
<li>The benchmark ran on a faster CPU.</li>
<li>The compiler was upgraded.</li>
<li>Compiler optimisation was enabled.</li>
<li>The test dataset became smaller.</li>
<li>The database cache was already warm.</li>
<li>Network conditions improved.</li>
</ul>

Now it becomes impossible to confidently attribute the 30% improvement to the <a href="https://helloacm.com/deep-dive-into-reinforcement-learning-understanding-the-q-learning-algorithm/" title="Deep Dive into Reinforcement Learning: Understanding the Q-Learning Algorithm">algorithm</a> itself.

A better experiment would look like this:

<code>Algorithm A + same machine + same compiler + same dataset + same configuration</code>

<code>Algorithm B + same machine + same compiler + same dataset + same configuration</code>

The only important change is:

<strong>the algorithm.</strong>

Then we compare execution times.

This is essentially the same principle behind benchmarks, A/B tests, and controlled experiments in software engineering.

<h3>Another Example: Fertiliser and Plant Growth</h3>

Suppose we want to investigate:

<strong>Does fertiliser cause plants to grow faster?</strong>

A badly designed experiment might look like this:

<code>Plant A: fertiliser + lots of sunlight</code>

<code>Plant B: no fertiliser + little sunlight</code>

After several weeks, Plant A is much taller.

Can we conclude that fertiliser caused the difference?

No.

Two major factors changed:

<ul>
<li>fertiliser</li>
<li>sunlight</li>
</ul>

We cannot tell which one caused the plant to grow faster.

A better <a href="https://helloacm.com/multi-processes-experiments-when-can-windows-utilize-all-the-cores/" title="Multi-Processes Experiments – When Can Windows Utilize All the Cores?">experiment</a> would keep the following conditions similar:

<ul>
<li>plant species</li>
<li>soil</li>
<li>pot size</li>
<li>amount of water</li>
<li>sunlight</li>
<li>temperature</li>
</ul>

The only difference would be:

<code>Plant A: fertiliser</code>

<code>Plant B: no fertiliser</code>

Now the experiment provides much stronger evidence about whether fertiliser affects plant growth.

<h3>Controlled Does Not Mean Absolutely Identical</h3>

There is an important subtlety here.

Controlling variables does not mean that every condition in the real world must be perfectly identical.

That is often impossible.

Two plants will never have exactly identical biological states, and two executions of a computer program will never have exactly identical CPU scheduling, cache states, interrupts, or background activity.

The real goal is:

<strong>to control the important factors that could significantly influence the result.</strong>

Researchers can also reduce random variation by:

<ul>
<li>repeating experiments</li>
<li>increasing sample sizes</li>
<li>randomising experimental subjects</li>
<li>calculating averages</li>
<li>performing statistical analysis</li>
</ul>

<h3>Controlled Experiments and Causation</h3>

The deeper importance of the controlled variable method is not merely about how experiments are performed.

It reflects one of the most important principles of scientific reasoning:

<strong>Correlation does not imply causation.</strong>

Suppose we observe:

<code>When A increases, B also increases.</code>

That does not automatically prove:

<code>A causes B.</code>

There could be another variable C:

<code>C → A</code>

<code>C → B</code>

It is also possible that:

<code>B → A</code>

Or the relationship could simply be coincidence.

Controlled experiments try to eliminate these alternative explanations.

If:

<ul>
<li>other important conditions remain similar</li>
<li>only A is deliberately changed</li>
<li>B changes consistently afterwards</li>
<li>the result can be reproduced repeatedly</li>
</ul>

then we gain much stronger evidence that A actually influences B.

<h3>Software Engineers Use Controlled Experiments All the Time</h3>

The controlled variable method is not limited to physics, chemistry, or biology.

Software engineers use the same idea constantly.

Suppose an API originally has:

<code>API latency = 500 ms</code>

After adding a database index:

<code>API latency = 200 ms</code>

If everything else remains approximately the same, there is good evidence that the index caused the improvement.

But imagine changing all of these things simultaneously:

<ul>
<li>adding more servers</li>
<li>rewriting the SQL query</li>
<li>adding Redis caching</li>
<li>creating database indexes</li>
<li>upgrading the CPU</li>
</ul>

The system might become ten times faster.

But now there is another problem:

<strong>Which optimisation actually mattered?</strong>

This is why a powerful technique in performance tuning, <a href="https://helloacm.com/python-debugging-get-current-executed-function-name-and-print-traceback/" title="Python Debugging: Get Current Executed Function Name and Print Traceback">debugging</a>, and system experimentation is:

<strong>Change one important thing at a time.</strong>

Change it.

Measure it.

Record the result.

Then make the next change.

<h3>Conclusion</h3>

The controlled variable method can be summarised very simply:

<strong>Study one major factor at a time.</strong>

In other words:

<ul>
<li>change the independent variable</li>
<li>measure the dependent variable</li>
<li>control the other relevant variables</li>
</ul>

A useful mental model is:

<code>Change one thing → Observe the result → Keep other conditions consistent</code>

This is more than just an experimental technique.

It is also a powerful way of thinking.

Whenever two things appear to happen together, instead of immediately assuming causation, ask:

<strong>What else changed?</strong>

<strong>If I changed only this one variable, would the same result still occur?</strong>

That question is at the heart of the controlled variable method.

[show_posts keyword="knowledge"]

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/listen-to-what-an-seo-expert-has-to-say-about-its-benefits/" rel="bookmark" title="Listen to what an SEO expert has to say about its benefits">Listen to what an SEO expert has to say about its benefits</a> <small>To get the most from your business, you must follow your customers and take your...</small></li>
<li><a href="https://helloacm.com/excel-tip-faster-auto-complete/" rel="bookmark" title="Excel Tip: Faster Auto-complete">Excel Tip: Faster Auto-complete</a> <small>The Microsoft Excel is heavily used and widely used. There are so many tricks/tips that...</small></li>
<li><a href="https://helloacm.com/code-is-becoming-cheaper-what-really-matters-for-programmers-in-the-ai-era/" rel="bookmark" title="Code Is Becoming Cheaper: What Really Matters for Programmers in the AI Era">Code Is Becoming Cheaper: What Really Matters for Programmers in the AI Era</a> <small>AI is rapidly reducing the cost of writing code. Work that once took programmers hours...</small></li>
<li><a href="https://helloacm.com/linux-disk-space-troubleshooting-find-large-files-and-directories-with-ncdu/" rel="bookmark" title="Linux Disk Space Troubleshooting: Find Large Files and Directories with ncdu">Linux Disk Space Troubleshooting: Find Large Files and Directories with ncdu</a> <small>Linux servers can run out of disk space because of growing logs, backups, caches, or...</small></li>
<li><a href="https://helloacm.com/how-to-design-a-high-performance-hit-counter-class/" rel="bookmark" title="How to Design a High Performance/Scalable Hit Counter Class?">How to Design a High Performance/Scalable Hit Counter Class?</a> <small>Design a hit counter which counts the number of hits received in the past 5...</small></li>
<li><a href="https://helloacm.com/include-the-binary-files-in-your-source-code/" rel="bookmark" title="Include the Binary Files in Your Source Code">Include the Binary Files in Your Source Code</a> <small>Sometimes, you might want to wrap a binary file (image, executable) in your source code,...</small></li>
<li><a href="https://helloacm.com/using-cloudflare-worker-serverless-technology-to-deploy-a-load-balancer-rpc-node-for-steem-blockchain/" rel="bookmark" title="Using CloudFlare Worker Serverless Technology to Deploy a Load Balancer (RPC Node) for Steem Blockchain">Using CloudFlare Worker Serverless Technology to Deploy a Load Balancer (RPC Node) for Steem Blockchain</a> <small>A few days ago, I launched the &#8220;Load Balancing&#8221; Node: https://steem.senior.workers.dev/ It is a Javascript...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-backtracking-algorithm-to-find-factor-combinations-math-recursive-depth-first-search/" rel="bookmark" title="Teaching Kids Programming &#8211; Backtracking Algorithm to Find Factor Combinations (Math, Recursive Depth First Search)">Teaching Kids Programming &#8211; Backtracking Algorithm to Find Factor Combinations (Math, Recursive Depth First Search)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms Numbers can be regarded as the...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://helloacm.com/the-controlled-variable-method-why-good-experiments-change-one-thing-at-a-time/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Code Is Becoming Cheaper: What Really Matters for Programmers in the AI Era</title>
		<link>https://helloacm.com/code-is-becoming-cheaper-what-really-matters-for-programmers-in-the-ai-era/</link>
					<comments>https://helloacm.com/code-is-becoming-cheaper-what-really-matters-for-programmers-in-the-ai-era/#respond</comments>
		
		<dc:creator><![CDATA[ACMer]]></dc:creator>
		<pubDate>Fri, 04 Sep 2026 15:02:18 +0000</pubDate>
				<category><![CDATA[AGI: Artificial General Intelligence]]></category>
		<category><![CDATA[Artificial Intelligence]]></category>
		<category><![CDATA[Engineering]]></category>
		<category><![CDATA[Harness Engineering]]></category>
		<category><![CDATA[Prompt]]></category>
		<category><![CDATA[software development]]></category>
		<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[Vibe Coding]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[AI coding]]></category>
		<category><![CDATA[AI Generated Code]]></category>
		<category><![CDATA[artificial intelligence]]></category>
		<category><![CDATA[Automated Testing]]></category>
		<category><![CDATA[CI/CD]]></category>
		<category><![CDATA[code review]]></category>
		<category><![CDATA[Engineering Judgment]]></category>
		<category><![CDATA[Future of Programming]]></category>
		<category><![CDATA[Human in the Loop]]></category>
		<category><![CDATA[Large Language Models]]></category>
		<category><![CDATA[LLM]]></category>
		<category><![CDATA[Programmers]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[Prompt Engineering]]></category>
		<category><![CDATA[RAG]]></category>
		<category><![CDATA[Software Architecture]]></category>
		<category><![CDATA[software engineering]]></category>
		<category><![CDATA[system design]]></category>
		<guid isPermaLink="false">https://helloacm.com/?p=158062</guid>

					<description><![CDATA[[caption id="attachment_158064" align="alignnone" width="2048"]<a href="https://helloacm.com/code-is-becoming-cheaper-what-really-matters-for-programmers-in-the-ai-era/problem-solving-dating-2026-08-29-11-37-22/" rel="attachment wp-att-158064"><img src="https://helloacm.com/wp-content/uploads/2026/09/problem-solving-dating-2026-08-29-11.37.22-scaled.jpg" alt="Leetcoding/Problem Solving on a Date" width="2048" height="1152" class="size-full wp-image-158064" /></a> Leetcoding/Problem Solving on a Date[/caption]

<blockquote>
AI is rapidly reducing the cost of writing code. Work that once took programmers hours or days can now be generated, tested, reviewed, and turned into pull requests within minutes. As a result, the role of software engineers is shifting from writing every line of code to reviewing, designing, validating, and making higher-level decisions. Code itself is becoming cheaper, while architecture, security, verification, code review, and engineering judgment are becoming more valuable. AI may become a tireless 24/7 programmer, but humans still need to decide where the ship should go.
</blockquote>

<h2>Code Is Becoming Cheaper</h2>

Linus Torvalds once famously said:

<blockquote>Talk is cheap. Show me the code.</blockquote>

I used to strongly agree with that.

After all, programmers are ultimately judged by the code they produce. No matter how impressive the design sounds or how polished the PowerPoint looks, if you cannot actually build it, or if the code does not work, then none of it really matters.

But in the age of AI, I increasingly feel that this sentence needs to be reinterpreted.

Because now, <strong>code itself is becoming cheaper.</strong>

I honestly cannot remember the last time I manually typed out a large piece of code from start to finish.

These days, my daily work feels much more like directing different <a href="https://helloacm.com/ai-coding-agents-are-reshaping-the-barrier-to-programming/" title="AI Coding Agents Are Reshaping the Barrier to Programming">AI agents</a>. I explain the requirements clearly, tell them where the codebase is, what the goal is, what constraints need to be respected, and then the AI starts analysing the code, designing the solution, implementing it, adding tests, and eventually producing a PR.

Most of the time, the code generated by AI is already quite good.

Of course, I do not completely ignore it.

I usually ask another AI to perform a round of code review first, check whether there are any obvious problems, then I quickly inspect the key logic myself. Sometimes I also do some manual testing.

The whole workflow is already very different from how software development used to work.

<h2>Ten or More PRs a Day Is No Longer Unusual</h2>

In the past, if a pull request suddenly changed hundreds or even thousands of lines of code, people would usually suggest:

<blockquote>Split it up. Keep the PR small.</blockquote>

That made reviews easier and made problems easier to spot.

That principle is still valid.

The problem is that AI has increased the speed of code generation by an order of magnitude, while human review speed has not increased at the same rate.

These days, ten or more PRs in a single day is not particularly unusual, and even a relatively ordinary feature can easily involve hundreds of lines of changes.

If we still reviewed everything the old-fashioned way, line by line:

<pre><code>Line 1...
Line 2...
Line 3...
...</code></pre>

then we would spend the entire day doing nothing but <a href="https://helloacm.com/the-review-of-cozmo-robot-from-anki/" title="The Review of cozmo robot from Anki">review</a>.

So more and more, I find myself using a kind of sampling-based review.

First, I check whether the overall design direction is correct.

Then I inspect a few critical functions.

I look at how data flows, how errors are handled, whether interfaces have been broken, and what the tests are actually covering.

If the overall direction looks right, I no longer spend as much time obsessing over every implementation detail.

This is a very obvious shift:

<strong>Engineers are moving from being code writers to becoming code supervisors.</strong>

<h2>One Thing AI Is Extremely Good At: Making CI Green</h2>

There is also something quite interesting about AI.

AI is very good at “solving problems.”

Especially this one:

<blockquote>Make the CI pass.</blockquote>

Give it a failing test, and it will work very hard to turn that test green.

Sometimes it genuinely fixes the underlying bug.

But sometimes the solution is rather amusing.

For example, AI really likes writing code like this:

<pre><code>try {
    ...
} catch {
    ...
}</code></pre>

Something failed?

Catch it.

Still failing?

Catch it again.

Or perhaps a test fails, so it adds a special case.

Another test fails, so it patches that too.

Eventually the CI says:

<pre><code>PASS</code></pre>

And the AI concludes:

<blockquote>Task completed.</blockquote>

Locally, every individual change may look “reasonable.”

But after six months or a year of these patches accumulating, what will the codebase look like?

That is a much harder <a href="https://helloacm.com/what-is-tcp-ip-4-layer-vs-osi-7-layer/" title="Software Engineer Interview Question: What is TCP/IP (4 Layer vs OSI 7 Layer)?">question</a>.

This is why:

<strong>CI Passing ≠ Code Quality.</strong>

And even:

<strong>CI Passing ≠ Correctness.</strong>

Tests can only tell you that the things you tested did not expose a problem. They do not prove that the system itself is correct.

AI is particularly good at optimising for a clearly defined objective function.

If you tell it:

<blockquote>Make CI green.</blockquote>

it will do everything it can to make CI green.

But “make sure this codebase is still maintainable five years from now” is a much fuzzier objective, with an extremely long feedback cycle.

AI is not naturally good at that kind of goal yet.

<h2>But Maybe Future Code Is Meant to Be Read by AI Anyway?</h2>

Then I started thinking about the problem from another angle.

Are we still using old software engineering assumptions to judge future software development?

In the past, we always emphasised:

<blockquote>Code should be readable.</blockquote>

Why?

Because another engineer might need to read it later.

But what if, in the future, 80% of code maintenance is done by AI?

In that world, perhaps a lot of code will no longer be primarily written for humans.

It may increasingly be written for AI.

As long as:

<ul>
<li>the behaviour is correct</li>
<li>the interfaces are clear</li>
<li>the tests are comprehensive</li>
<li>the contracts are explicit</li>
<li>the observability is sufficient</li>
<li>AI can understand and modify the code</li>
</ul>

then some of the coding-style concerns we used to obsess over may simply become less important.

The ability to identify problems, ask the right questions, and solve them is becoming increasingly important for engineers.

AI can help us <a href="https://helloacm.com/chatgpt-refactors-rewrites-the-code-using-promise-all-sending-requests-in-parallel/" title="ChatGPT Refactors/Rewrites the Code using Promise.All – Sending Requests in Parallel">write code</a>, search for information, generate solutions, and automate much of the implementation work. But the most valuable part of engineering is often not simply “getting the task done.” It starts with recognising that there is a problem in the first place. In complex systems, problems rarely announce themselves clearly. They may be hidden behind declining performance, worsening user experience, architectural complexity, accumulating technical debt, or even a requirement that looks reasonable but is fundamentally pointing in the wrong direction. Once a problem is identified, an engineer still needs to turn a vague observation into a clear, precise, and testable question. If the problem is defined incorrectly, even the most capable AI will simply execute the wrong direction faster and more thoroughly. Only then comes solving the problem: comparing alternatives, understanding trade-offs, evaluating risks, and choosing the most appropriate approach. AI can be an extremely powerful executor, but identifying the real problem, asking the right question, and judging what the right solution should be remain some of the most important skills an engineer can have.

That does not mean code quality stops mattering.

Quite the opposite.

It means the definition of “quality” may start to change.

In the past, we focused on:

<blockquote>Human Readability</blockquote>

In the future, we may increasingly care about:

<blockquote>Machine Maintainability</blockquote>

The two are closely related, but they are not necessarily identical.

<h2>What Is Becoming More Valuable Is Judgment</h2>

So I increasingly believe this:

<strong>Code is becoming cheaper, but engineering ability is not.</strong>

If anything, some engineering skills are becoming much more valuable.

For example:

<ul>
<li>architecture</li>
<li>design</li>
<li>code review</li>
<li>debugging</li>
<li>security</li>
<li>performance analysis</li>
<li>requirement decomposition</li>
<li>judging whether a solution is over-engineered</li>
<li>judging whether AI truly solved the problem or merely hid it</li>
<li>judging whether a PR with completely green CI will become technical debt six months later</li>
</ul>

These skills are becoming more important, not less.

AI can generate hundreds of lines of code in a minute, but it does not necessarily know whether those hundreds of lines should exist in the first place.

Those are two very different problems.

In the past, the biggest difference between a senior engineer and a junior engineer might have been:

A senior engineer writes better code.

In the future, the bigger difference may become:

<strong>A senior engineer knows which code should never be written in the first place.</strong>

<h2>Will Programmers Disappear?</h2>

Elon Musk has expressed a fairly extreme view before:

Once AI becomes powerful enough, traditional programmers may no longer be needed, and AI may even bypass high-level programming languages entirely and directly generate machine-executable code.

I am sceptical of that conclusion.

Not because AI cannot do it.

Technically, AI can certainly generate machine code.

The question is:

<strong>Would you run it?</strong>

Imagine that AI generates a 500 MB binary for you.

Then it says:

<pre><code>Trust me.</code></pre>

Would you deploy it to a bank?

Azure?

An operating system?

A medical device?

A self-driving car?

How do you know there is no hidden malicious behaviour inside it?

How do you perform security auditing?

How do you verify that it actually matches the specification?

Someone may say:

Easy.

Use another AI to review it.

But then another question immediately appears:

How do you know the second AI is correct?

Use a third AI?

Then who audits the third one?

If multiple AIs are based on similar training data, similar architectures, or even similar reasoning patterns, they may all make the same mistake.

Eventually, we return to the same fundamental question:

<strong>Who is accountable?</strong>

That is one reason I believe <strong>Human in the Loop</strong> will remain difficult to eliminate in many important software systems.

<h2>From Machine Code, to Assembly, to C, to AI</h2>

If we look back at the history of <a href="https://helloacm.com/teaching-kids-programming-vlog-harness-engineering-commanding-ai-to-get-work-done/" title="Teaching Kids Programming vLog: Harness Engineering — Commanding AI to Get Work Done">programming</a> languages, there is actually a very interesting pattern.

At first, humans worked directly with machine instructions.

Then came assembly language.

Then came higher-level programming languages.

Early C compilers had to be implemented using lower-level languages. Once C compilers became mature enough, they could gradually be rewritten in C itself, becoming self-hosting compilers.

After that, most programmers no longer needed to care about instructions such as:

<pre><code>MOV
PUSH
JMP</code></pre>

And certainly not the underlying zeros and ones.

We simply kept moving up the abstraction stack.

First:

<pre><code>Machine Code</code></pre>

Then:

<pre><code>Assembly</code></pre>

Then:

<pre><code>C</code></pre>

Then:

<pre><code>C++ / Java / Python / C#</code></pre>

And now, perhaps we are entering another layer:

<pre><code>Natural Language</code></pre>

The programmer says:

<blockquote>Add a rate limiter to this API. It needs to support distributed deployment, it must not rely on local memory, and it should include unit tests and integration tests.</blockquote>

And the AI handles:

<pre><code>C#
Python
SQL
YAML
Terraform
Dockerfile
...</code></pre>

From this perspective, AI is not eliminating programming.

It is simply raising the abstraction level once again.

<h2>But This Time, There Is One Fundamental Difference</h2>

There is, however, one major difference between this abstraction shift and all the previous ones.

Traditional tools were largely deterministic.

Given the same C program:

<pre><code>gcc hello.c</code></pre>

under the same environment, using the same compiler and the same options, you expect a deterministic result.

A compiler does not decide to produce implementation A today and implementation B tomorrow because it “feels like it.”

LLMs are completely different.

Today you ask:

<blockquote>Implement this function.</blockquote>

It may give you solution A.

Ask again one minute later:

It may give you solution B.

Switch to another model:

Solution C.

That is because modern large language models are fundamentally probabilistic systems.

They use the existing context to continuously predict the next most likely token.

Of course, we can use many techniques to improve consistency and reliability:

<ul>
<li>Prompt Engineering</li>
<li>RAG</li>
<li>better context</li>
<li>lower temperature</li>
<li>Structured Output</li>
<li>Schema Validation</li>
<li>Unit Tests</li>
<li>Static Analysis</li>
<li>Formal Verification</li>
<li>CI/CD</li>
<li>using one AI to review another AI</li>
</ul>

All of these techniques can reduce the error space.

But they do not change one fundamental fact:

<strong>AI itself is not a deterministic <a href="https://helloacm.com/teaching-kids-programming-vlog-harness-engineering-commanding-ai-to-get-work-done/" title="Teaching Kids Programming vLog: Harness Engineering — Commanding AI to Get Work Done">compiler</a> in the traditional sense.</strong>

So the real challenge of AI-assisted programming is no longer:

<blockquote>Can AI write code?</blockquote>

That problem is already largely solved.

The much harder question is:

<blockquote>How do we know the code AI wrote is actually correct?</blockquote>

That may turn out to be one of the most important software engineering questions of the next decade.

<h2>Talk Is Cheap, and Code Is Becoming Cheap Too</h2>

So if I were to rewrite Linus's quote today, I might say:

<blockquote>Talk is cheap.</blockquote>

<blockquote>Code is becoming cheap too.</blockquote>

<blockquote>Judgment is expensive.</blockquote>

In the past, the scarce skill was:

<strong>The ability to turn ideas into code.</strong>

AI is rapidly driving the cost of that skill downward.

In the future, the truly scarce skills may become:

<ul>
<li>knowing what should be built</li>
<li>knowing why it should be built that way</li>
<li>knowing when AI is wrong</li>
<li>knowing when an AI-generated solution should be thrown away and redesigned from scratch</li>
</ul>

And when ten or more AI agents are working for you 24/7, tirelessly generating code, you still need to know one thing very clearly:

<strong>Where should the ship actually be going?</strong>

AI can become an extremely capable sailor.

But what engineers increasingly need to learn may no longer be how to row.

<strong>It is how to steer.</strong>

<h3>Do We Still Need LeetCode? Old-School Programming</h3>

I will probably keep doing LeetCode.

Even though I rarely need to manually write large amounts of code at work anymore, and many LeetCode-style algorithm problems are not directly useful in day-to-day software engineering, solving them still helps me keep my programming skills sharp.

After all, even if AI writes most of the code in the future, the ability to read code, understand the logic, and judge whether an implementation is correct will still matter.

And writing code manually is still a very effective way to learn.

It does not just train coding skills. It also trains problem solving: how to break a problem down, identify patterns, choose the right data structures and algorithms, and gradually turn an idea into working code.

There is also something satisfying about solving a problem and finally seeing that green AC. It is a small but reliable dose of dopamine.

That is why my iPad is almost always with me, either in my hand or in my bag. Even when I am out on a date with my wife, if I suddenly get five spare minutes, I can pull it out, solve a problem, and have a little fun.

Maybe one day, manually typing code line by line will become a kind of “old-school programming.”

But for me, it is still one of the best forms of mental exercise.

[caption id="attachment_158071" align="alignnone" width="1152"]<a href="https://helloacm.com/code-is-becoming-cheaper-what-really-matters-for-programmers-in-the-ai-era/2026-08-09-21-19-15/" rel="attachment wp-att-158071"><img src="https://helloacm.com/wp-content/uploads/2026/09/2026-08-09-21.19.15-scaled.jpg" alt="Leetcoding on a Date." width="1152" height="2048" class="size-full wp-image-158071" /></a> Leetcoding on a Date.[/caption]

[caption id="attachment_158070" align="alignnone" width="1672"]<a href="https://helloacm.com/code-is-becoming-cheaper-what-really-matters-for-programmers-in-the-ai-era/leetcoding-costa-2026-08-30-13-40-30/" rel="attachment wp-att-158070"><img src="https://helloacm.com/wp-content/uploads/2026/09/leetcoding-costa-2026-08-30-13.40.30.png" alt="Leetcoding at Costa" width="1672" height="941" class="size-full wp-image-158070" /></a> Leetcoding at Costa[/caption]

[caption id="attachment_158069" align="alignnone" width="2048"]<a href="https://helloacm.com/code-is-becoming-cheaper-what-really-matters-for-programmers-in-the-ai-era/leetcoding-camping-2026-08-23-20-27-32/" rel="attachment wp-att-158069"><img src="https://helloacm.com/wp-content/uploads/2026/09/leetcoding-camping-2026-08-23-20.27.32-scaled.jpg" alt="Leetcoding while Camping" width="2048" height="1152" class="size-full wp-image-158069" /></a> Leetcoding while Camping[/caption]

[caption id="attachment_158068" align="alignnone" width="2048"]<a href="https://helloacm.com/code-is-becoming-cheaper-what-really-matters-for-programmers-in-the-ai-era/leetcodeing-in-the-middle-of-wales-lake-2026-08-25-10-43-19/" rel="attachment wp-att-158068"><img src="https://helloacm.com/wp-content/uploads/2026/09/leetcodeing-in-the-middle-of-wales-lake-2026-08-25-10.43.19-scaled.jpg" alt="Leetcoding at the Wales Lake" width="2048" height="1152" class="size-full wp-image-158068" /></a> Leetcoding at the Wales Lake[/caption]

[show_file file="/var/www/wp-post-common/helloacm.com/leetcode.php"]

[show_file file="/var/www/wp-post-common/helloacm.com/ai.php"]

[show_posts keyword="leetcode"]

<h3>Code Is Becoming an Intermediate Artifact: Reflections on The End of Software Engineering</h3>
This paper: https://arxiv.org/pdf/2606.05608v1

<h2>What Is “The End of Software Engineering” Really Arguing?</h2>

The core argument of this paper can actually be compressed into one sentence:

<blockquote>
<strong>What AI agents are really changing is not merely the speed of writing code. They are turning code from the central product of software systems into a temporary tool that agents may generate, use, and even discard in order to complete a task. In the future, the core work of engineers will increasingly shift from writing code to defining problems, expressing intent, designing constraints, orchestrating agents, and verifying results.</strong>
</blockquote>

The paper is titled <strong>The End of Software Engineering</strong>.

However, if I were to describe its actual thesis more precisely, I would probably call it:

<blockquote>
<strong>The End of Code-Centric Software Engineering</strong>
</blockquote>

In other words:

<blockquote>
<strong>Software engineering is not disappearing. What may be disappearing is software engineering centred around humans manually writing code.</strong>
</blockquote>

<h3>Traditional Software Engineering: Humans Reason, Code Encodes the Decisions</h3>

The traditional development process looks roughly like this:

<pre><code>Problem
↓
Human Reasoning
↓
Design
↓
Code
↓
Execution
↓
Result</code></pre>

Engineers first understand a problem, design a solution, and then encode those decisions into software.

When requirements change, we once again have to understand the problem, modify the design, change the code, test it, and redeploy it.

The paper argues that this model contains a fundamental scalability problem:

<blockquote>
System complexity keeps increasing, while human cognitive capacity remains relatively fixed.
</blockquote>

Over the past several decades, we have invented many techniques for dealing with complexity:

<ul>
<li>abstraction</li>
<li>object-oriented programming</li>
<li>modules</li>
<li>frameworks</li>
<li>microservices</li>
<li>CI/CD</li>
<li>cloud platforms</li>
</ul>

All of these are extremely valuable.

But from the paper's perspective, they mainly help humans manage complexity more effectively.

They do not fundamentally change one fact:

<strong>Humans still have to understand the system and encode the logic into software.</strong>

<h3>Agents Change Who Performs the Reasoning</h3>

The agentic model increasingly looks like this:

<pre><code>Intent
↓
Agent Reasoning
↓
Tools / APIs / Generated Code
↓
Result</code></pre>

The important change is not simply that AI helps programmers produce more code.

Instead:

<strong>The LLM or agent itself becomes part of the reasoning engine.</strong>

An agent may:

<ul>
<li>understand the goal</li>
<li>decompose the task</li>
<li>query data</li>
<li>call APIs</li>
<li>generate Python, SQL, or shell scripts</li>
<li>execute the code</li>
<li>inspect the result</li>
<li>re-plan after failure</li>
<li>finally deliver the outcome</li>
</ul>

This leads to a very important shift:

<blockquote>
<strong>Code no longer has to be the product.</strong>
</blockquote>

Code may simply become an intermediate artifact generated by an agent during one step of its reasoning process.

For example, an agent might generate 300 lines of Python to solve a task.

Once the code has run and the result has been produced, those 300 lines may not even need to be preserved.

They may never need to:

<ul>
<li>enter Git</li>
<li>go through code review</li>
<li>be maintained for years</li>
<li>become part of the final product</li>
</ul>

The valuable thing is the outcome, not necessarily the 300 lines of code.

I think this is one of the most important ideas in the paper.

<h3>From “AI Helps Me Build Software” to “AI Produces the Outcome”</h3>

Most people today still think about AI coding in roughly this way:

<pre><code>AI
↓
Software
↓
Result</code></pre>

For example:

<pre><code>Copilot
↓
helps me write code
↓
I build software
↓
the user gets a result</code></pre>

That is still fundamentally traditional software engineering.

The code-generation step has simply become faster.

The paper argues that the true agentic paradigm increasingly looks like:

<pre><code>Agent
↓
Result</code></pre>

Imagine that I tell an agent:

<blockquote>
Analyse one year of my server logs, identify abnormal traffic, and produce a security risk report.
</blockquote>

In the future, I may not care whether the agent:

<ul>
<li>wrote Python</li>
<li>ran SQL</li>
<li>used shell commands</li>
<li>generated temporary scripts</li>
<li>used a particular library</li>
</ul>

I care about one thing:

<blockquote>
<strong>Is the result correct?</strong>
</blockquote>

The paper describes this transition roughly as:

<pre><code>Local Software
↓
SaaS
↓
AaaS — Agent as a Service</code></pre>

SaaS reduced the need for users to care about infrastructure and deployment.

AaaS may go one step further:

<strong>Users may no longer need to care how the software solution itself is implemented.</strong>

<h3>So Where Does the Value of Programmers Go?</h3>

This is, in my view, one of the most interesting parts of the paper.

In the past:

<pre><code>Human = Code Author</code></pre>

In the future, the role may increasingly become:

<pre><code>Human =
Intent Architect
+ Coordinator
+ Auditor</code></pre>

The value of human engineers therefore moves upward.

<h4>Intent Articulation</h4>

Can you accurately explain:

<strong>What problem actually needs to be solved?</strong>

<h4>Architectural Oversight</h4>

How should the agents be organised?

Where are the system boundaries?

Which decisions can be delegated to AI?

Which decisions should never be delegated entirely?

<h4>Quality Calibration</h4>

How do you define “good”?

If you cannot define what correct or excellent looks like, then even an extremely capable agent will struggle to optimise toward the right outcome.

<h4>Evaluation and Verification</h4>

The agent gives you an answer.

But:

<strong>How do you know it is actually correct?</strong>

<h4>Governance</h4>

Which operations require a human in the loop?

Which actions require approval?

Which agents may access production systems?

Which ones should never have that access?

These questions become increasingly valuable.

This leads to an important conclusion:

<blockquote>
<strong>In the future, an engineer's greatest competitive advantage may not even be solving problems. It may move one step earlier: identifying which problems are worth solving and defining them precisely.</strong>
</blockquote>

Code generation will become increasingly commoditised.

But:

<blockquote>
<strong>Problem formulation will not.</strong>
</blockquote>

<h3>The Future 10x Engineer May Not Be Someone Who Writes 10x More Code</h3>

The paper also predicts an interesting organisational shift.

A traditional engineering team might look like:

<pre><code>PM
+ Architect
\+ 20 Developers
+ QA
+ DevOps</code></pre>

A future organisation may look more like:

<pre><code>A few senior engineers / architects
+
PM Agents
+
Coding Agents
+
Testing Agents
+
Debugging Agents
+
Security Agents</code></pre>

Humans provide:

<pre><code>Goals
+
Constraints
+
Judgement</code></pre>

Agents provide:

<pre><code>Execution</code></pre>

Under this model, the future <strong>10x engineer</strong> may no longer be someone capable of writing ten times more code.

Instead, it may be:

<blockquote>
<strong>Someone capable of effectively orchestrating ten, dozens, or even more specialised agents.</strong>
</blockquote>

The scarce skill moves from execution toward orchestration.

<h3>However, the Paper Contains an Important Contradiction</h3>

The title is deliberately aggressive:

<blockquote>
<strong>The End of Software Engineering</strong>
</blockquote>

But some of the evidence cited by the paper itself suggests that we are still far away from that point.

Agents may perform extremely well on isolated tasks:

<blockquote>
<strong>More than 80% success</strong>
</blockquote>

But when the task becomes long-term software maintenance, performance may fall to:

<blockquote>
<strong>38% or below</strong>
</blockquote>

The problems include:

<ul>
<li>context drift</li>
<li>error propagation</li>
<li>technical debt</li>
<li>verification failures</li>
<li>difficulty maintaining long-term system state</li>
</ul>

This exposes an important distinction.

AI is becoming increasingly good at:

<blockquote>
“Fix this issue for me.”
</blockquote>

But that is very different from:

<blockquote>
“Own this repository for the next three years and make sure its architecture does not decay.”
</blockquote>

The second task involves long-term architecture, technical debt, implicit requirements, historical context, team knowledge, and continuously changing state.

The paper itself ultimately acknowledges that:

<blockquote>
Fully autonomous software engineering remains a multi-year research challenge.
</blockquote>

<h3>My Biggest Reservation: The Mathematical Argument Makes a Large Leap</h3>

The paper also tries to argue for the inevitability of agentic software engineering from a complexity perspective.

If a system contains <code>n</code> components, the number of possible dependency graphs may grow roughly like:

<pre><code>2^(n choose 2)</code></pre>

In other words, the theoretical number of possible dependency combinations grows combinatorially.

The argument then roughly becomes:

<pre><code>Software complexity keeps increasing

+

Human cognitive capacity remains relatively fixed

+

LLM capacity can increase with compute

↓

The agentic paradigm must eventually scale better</code></pre>

The direction is interesting.

However, I think there is a substantial logical jump here.

The number of possible dependency graphs may indeed grow exponentially.

But that does not directly prove that:

<blockquote>
The practical cognitive complexity of software engineering itself grows exponentially.
</blockquote>

And it certainly does not prove that:

<blockquote>
LLMs can efficiently handle that exponential complexity.
</blockquote>

LLMs have their own limitations:

<ul>
<li>context windows</li>
<li>reasoning errors</li>
<li>hallucinations</li>
<li>compute cost</li>
<li>state management</li>
<li>verification difficulty</li>
</ul>

So when the paper describes the transition toward agentic software engineering as something close to a “first-principles necessity” or as inevitable, I would treat that as:

<strong>An interesting thesis rather than a rigorously proven theorem.</strong>

<h3>How I Would Summarise the Paper</h3>

I would not summarise it as:

<blockquote>
<strong>AI will eliminate software engineers.</strong>
</blockquote>

I would summarise it as:

<blockquote>
<strong>AI is pushing software engineering one abstraction layer higher.</strong>
</blockquote>

Over the past several decades, the progression has roughly looked like:

<pre><code>Machine Code
↓
Assembly
↓
C
↓
C++ / Java
↓
Frameworks
↓
Cloud / APIs
↓
AI Coding</code></pre>

The next layer may be:

<pre><code>Intent
↓
Agent
↓
Reasoning
↓
Tools / APIs / Generated Code
↓
Outcome</code></pre>

Software engineering has always moved toward higher levels of abstraction.

Programmers stopped writing machine code manually.

Later, most developers no longer needed to manually manage many low-level details involving memory, sockets, threads, and machine deployment.

AI may simply be continuing the same historical trend:

<strong>Engineers increasingly manipulate intent instead of directly manipulating code.</strong>

<h3>The One Idea Worth Remembering</h3>

The most valuable idea in the paper, in my view, is not:

<blockquote>
The End of Software Engineering.
</blockquote>

It is the idea behind this statement:

<blockquote>
<strong>What persists is the agent's capability, not its intermediate artifacts.</strong>
</blockquote>

Put differently:

<blockquote>
<strong>In the AI era, code is gradually losing its status as the final product and becoming an intermediate artifact in the process of solving problems. What becomes scarce instead moves upward: discovering problems, defining them precisely, asking the right questions, designing system boundaries, and determining whether the answer is actually correct.</strong>
</blockquote>

That argument is much deeper than the somewhat clickbait headline:

<blockquote>
<strong>“Software Engineering is ending.”</strong>
</blockquote>

[caption id="attachment_158075" align="alignnone" width="1126"]<a href="https://helloacm.com/code-is-becoming-cheaper-what-really-matters-for-programmers-in-the-ai-era/paper-the-end-of-software-engineering/" rel="attachment wp-att-158075"><img src="https://helloacm.com/wp-content/uploads/2026/09/paper-the-end-of-software-engineering.jpg" alt="The End of Software Engineering:
How AI Agents Are Fundamentally Restructuring the Software Paradigm" width="1126" height="1602" class="size-full wp-image-158075" /></a> The End of Software Engineering:<br />How AI Agents Are Fundamentally Restructuring the Software Paradigm[/caption]

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/teaching-kids-programming-verify-preorder-sequence-in-binary-search-tree-monotonous-stack/" rel="bookmark" title="Teaching Kids Programming &#8211; Verify Preorder Sequence in Binary Search Tree (Monotonous Stack)">Teaching Kids Programming &#8211; Verify Preorder Sequence in Binary Search Tree (Monotonous Stack)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms A stack-based solution for LeetCode 255,...</small></li>
<li><a href="https://helloacm.com/the-memory-manager-in-c-c-heap-vs-stack/" rel="bookmark" title="The Memory Manager in C/C++ (Heap vs Stack)">The Memory Manager in C/C++ (Heap vs Stack)</a> <small>This is one of the most frequently asked interview questions for Software Engineer roles. In...</small></li>
<li><a href="https://helloacm.com/hardening-wordpress-disable-php-execution-in-wp-content-uploads/" rel="bookmark" title="Hardening WordPress: Disable PHP Execution in `wp-content/uploads`">Hardening WordPress: Disable PHP Execution in `wp-content/uploads`</a> <small>WordPress must be able to write media files to `wp-content/uploads`, but files stored there should...</small></li>
<li><a href="https://helloacm.com/ai-coding-agents-are-reshaping-the-barrier-to-programming/" rel="bookmark" title="AI Coding Agents Are Reshaping the Barrier to Programming">AI Coding Agents Are Reshaping the Barrier to Programming</a> <small>AI Coding Agents Are Reshaping the Barrier to Programming Coding Is Becoming as Easy as...</small></li>
<li><a href="https://helloacm.com/tetration-operator-in-math-simply-explained-with-python-algorithms/" rel="bookmark" title="Tetration Operator in Math Simply Explained with Python Algorithms">Tetration Operator in Math Simply Explained with Python Algorithms</a> <small>What is Tetration Operator in Math? Tetration is an operation in mathematics that involves iterated...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-minimum-number-of-perfect-squares-via-theorem-guided-iterative-deepening-dfs/" rel="bookmark" title="Teaching Kids Programming &#8211; Minimum Number of Perfect Squares via Theorem-guided iterative deepening DFS">Teaching Kids Programming &#8211; Minimum Number of Perfect Squares via Theorem-guided iterative deepening DFS</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms This article explores an iterative-deepening recursive...</small></li>
<li><a href="https://helloacm.com/turning-a-dusty-mini-pc-into-a-home-server-my-nuc-8s-second-life/" rel="bookmark" title="Turning a Dusty Mini PC into a Home Server: My NUC-8’s Second Life">Turning a Dusty Mini PC into a Home Server: My NUC-8’s Second Life</a> <small>I gave an unused Beelink SEi8 mini PC a second life by installing Ubuntu and...</small></li>
<li><a href="https://helloacm.com/delphi-is-30-years-old/" rel="bookmark" title="Delphi is 30 Years Old!">Delphi is 30 Years Old!</a> <small>People who know the Delphi programming language are probably revealing their age. Many people think...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[[caption id="attachment_158064" align="alignnone" width="2048"]<a href="https://helloacm.com/code-is-becoming-cheaper-what-really-matters-for-programmers-in-the-ai-era/problem-solving-dating-2026-08-29-11-37-22/" rel="attachment wp-att-158064"><img src="https://helloacm.com/wp-content/uploads/2026/09/problem-solving-dating-2026-08-29-11.37.22-scaled.jpg" alt="Leetcoding/Problem Solving on a Date" width="2048" height="1152" class="size-full wp-image-158064" /></a> Leetcoding/Problem Solving on a Date[/caption]

<blockquote>
AI is rapidly reducing the cost of writing code. Work that once took programmers hours or days can now be generated, tested, reviewed, and turned into pull requests within minutes. As a result, the role of software engineers is shifting from writing every line of code to reviewing, designing, validating, and making higher-level decisions. Code itself is becoming cheaper, while architecture, security, verification, code review, and engineering judgment are becoming more valuable. AI may become a tireless 24/7 programmer, but humans still need to decide where the ship should go.
</blockquote>

<h2>Code Is Becoming Cheaper</h2>

Linus Torvalds once famously said:

<blockquote>Talk is cheap. Show me the code.</blockquote>

I used to strongly agree with that.

After all, programmers are ultimately judged by the code they produce. No matter how impressive the design sounds or how polished the PowerPoint looks, if you cannot actually build it, or if the code does not work, then none of it really matters.

But in the age of AI, I increasingly feel that this sentence needs to be reinterpreted.

Because now, <strong>code itself is becoming cheaper.</strong>

I honestly cannot remember the last time I manually typed out a large piece of code from start to finish.

These days, my daily work feels much more like directing different <a href="https://helloacm.com/ai-coding-agents-are-reshaping-the-barrier-to-programming/" title="AI Coding Agents Are Reshaping the Barrier to Programming">AI agents</a>. I explain the requirements clearly, tell them where the codebase is, what the goal is, what constraints need to be respected, and then the AI starts analysing the code, designing the solution, implementing it, adding tests, and eventually producing a PR.

Most of the time, the code generated by AI is already quite good.

Of course, I do not completely ignore it.

I usually ask another AI to perform a round of code review first, check whether there are any obvious problems, then I quickly inspect the key logic myself. Sometimes I also do some manual testing.

The whole workflow is already very different from how software development used to work.

<h2>Ten or More PRs a Day Is No Longer Unusual</h2>

In the past, if a pull request suddenly changed hundreds or even thousands of lines of code, people would usually suggest:

<blockquote>Split it up. Keep the PR small.</blockquote>

That made reviews easier and made problems easier to spot.

That principle is still valid.

The problem is that AI has increased the speed of code generation by an order of magnitude, while human review speed has not increased at the same rate.

These days, ten or more PRs in a single day is not particularly unusual, and even a relatively ordinary feature can easily involve hundreds of lines of changes.

If we still reviewed everything the old-fashioned way, line by line:

<pre><code>Line 1...
Line 2...
Line 3...
...</code></pre>

then we would spend the entire day doing nothing but <a href="https://helloacm.com/the-review-of-cozmo-robot-from-anki/" title="The Review of cozmo robot from Anki">review</a>.

So more and more, I find myself using a kind of sampling-based review.

First, I check whether the overall design direction is correct.

Then I inspect a few critical functions.

I look at how data flows, how errors are handled, whether interfaces have been broken, and what the tests are actually covering.

If the overall direction looks right, I no longer spend as much time obsessing over every implementation detail.

This is a very obvious shift:

<strong>Engineers are moving from being code writers to becoming code supervisors.</strong>

<h2>One Thing AI Is Extremely Good At: Making CI Green</h2>

There is also something quite interesting about AI.

AI is very good at “solving problems.”

Especially this one:

<blockquote>Make the CI pass.</blockquote>

Give it a failing test, and it will work very hard to turn that test green.

Sometimes it genuinely fixes the underlying bug.

But sometimes the solution is rather amusing.

For example, AI really likes writing code like this:

<pre><code>try {
    ...
} catch {
    ...
}</code></pre>

Something failed?

Catch it.

Still failing?

Catch it again.

Or perhaps a test fails, so it adds a special case.

Another test fails, so it patches that too.

Eventually the CI says:

<pre><code>PASS</code></pre>

And the AI concludes:

<blockquote>Task completed.</blockquote>

Locally, every individual change may look “reasonable.”

But after six months or a year of these patches accumulating, what will the codebase look like?

That is a much harder <a href="https://helloacm.com/what-is-tcp-ip-4-layer-vs-osi-7-layer/" title="Software Engineer Interview Question: What is TCP/IP (4 Layer vs OSI 7 Layer)?">question</a>.

This is why:

<strong>CI Passing ≠ Code Quality.</strong>

And even:

<strong>CI Passing ≠ Correctness.</strong>

Tests can only tell you that the things you tested did not expose a problem. They do not prove that the system itself is correct.

AI is particularly good at optimising for a clearly defined objective function.

If you tell it:

<blockquote>Make CI green.</blockquote>

it will do everything it can to make CI green.

But “make sure this codebase is still maintainable five years from now” is a much fuzzier objective, with an extremely long feedback cycle.

AI is not naturally good at that kind of goal yet.

<h2>But Maybe Future Code Is Meant to Be Read by AI Anyway?</h2>

Then I started thinking about the problem from another angle.

Are we still using old software engineering assumptions to judge future software development?

In the past, we always emphasised:

<blockquote>Code should be readable.</blockquote>

Why?

Because another engineer might need to read it later.

But what if, in the future, 80% of code maintenance is done by AI?

In that world, perhaps a lot of code will no longer be primarily written for humans.

It may increasingly be written for AI.

As long as:

<ul>
<li>the behaviour is correct</li>
<li>the interfaces are clear</li>
<li>the tests are comprehensive</li>
<li>the contracts are explicit</li>
<li>the observability is sufficient</li>
<li>AI can understand and modify the code</li>
</ul>

then some of the coding-style concerns we used to obsess over may simply become less important.

The ability to identify problems, ask the right questions, and solve them is becoming increasingly important for engineers.

AI can help us <a href="https://helloacm.com/chatgpt-refactors-rewrites-the-code-using-promise-all-sending-requests-in-parallel/" title="ChatGPT Refactors/Rewrites the Code using Promise.All – Sending Requests in Parallel">write code</a>, search for information, generate solutions, and automate much of the implementation work. But the most valuable part of engineering is often not simply “getting the task done.” It starts with recognising that there is a problem in the first place. In complex systems, problems rarely announce themselves clearly. They may be hidden behind declining performance, worsening user experience, architectural complexity, accumulating technical debt, or even a requirement that looks reasonable but is fundamentally pointing in the wrong direction. Once a problem is identified, an engineer still needs to turn a vague observation into a clear, precise, and testable question. If the problem is defined incorrectly, even the most capable AI will simply execute the wrong direction faster and more thoroughly. Only then comes solving the problem: comparing alternatives, understanding trade-offs, evaluating risks, and choosing the most appropriate approach. AI can be an extremely powerful executor, but identifying the real problem, asking the right question, and judging what the right solution should be remain some of the most important skills an engineer can have.

That does not mean code quality stops mattering.

Quite the opposite.

It means the definition of “quality” may start to change.

In the past, we focused on:

<blockquote>Human Readability</blockquote>

In the future, we may increasingly care about:

<blockquote>Machine Maintainability</blockquote>

The two are closely related, but they are not necessarily identical.

<h2>What Is Becoming More Valuable Is Judgment</h2>

So I increasingly believe this:

<strong>Code is becoming cheaper, but engineering ability is not.</strong>

If anything, some engineering skills are becoming much more valuable.

For example:

<ul>
<li>architecture</li>
<li>design</li>
<li>code review</li>
<li>debugging</li>
<li>security</li>
<li>performance analysis</li>
<li>requirement decomposition</li>
<li>judging whether a solution is over-engineered</li>
<li>judging whether AI truly solved the problem or merely hid it</li>
<li>judging whether a PR with completely green CI will become technical debt six months later</li>
</ul>

These skills are becoming more important, not less.

AI can generate hundreds of lines of code in a minute, but it does not necessarily know whether those hundreds of lines should exist in the first place.

Those are two very different problems.

In the past, the biggest difference between a senior engineer and a junior engineer might have been:

A senior engineer writes better code.

In the future, the bigger difference may become:

<strong>A senior engineer knows which code should never be written in the first place.</strong>

<h2>Will Programmers Disappear?</h2>

Elon Musk has expressed a fairly extreme view before:

Once AI becomes powerful enough, traditional programmers may no longer be needed, and AI may even bypass high-level programming languages entirely and directly generate machine-executable code.

I am sceptical of that conclusion.

Not because AI cannot do it.

Technically, AI can certainly generate machine code.

The question is:

<strong>Would you run it?</strong>

Imagine that AI generates a 500 MB binary for you.

Then it says:

<pre><code>Trust me.</code></pre>

Would you deploy it to a bank?

Azure?

An operating system?

A medical device?

A self-driving car?

How do you know there is no hidden malicious behaviour inside it?

How do you perform security auditing?

How do you verify that it actually matches the specification?

Someone may say:

Easy.

Use another AI to review it.

But then another question immediately appears:

How do you know the second AI is correct?

Use a third AI?

Then who audits the third one?

If multiple AIs are based on similar training data, similar architectures, or even similar reasoning patterns, they may all make the same mistake.

Eventually, we return to the same fundamental question:

<strong>Who is accountable?</strong>

That is one reason I believe <strong>Human in the Loop</strong> will remain difficult to eliminate in many important software systems.

<h2>From Machine Code, to Assembly, to C, to AI</h2>

If we look back at the history of <a href="https://helloacm.com/teaching-kids-programming-vlog-harness-engineering-commanding-ai-to-get-work-done/" title="Teaching Kids Programming vLog: Harness Engineering — Commanding AI to Get Work Done">programming</a> languages, there is actually a very interesting pattern.

At first, humans worked directly with machine instructions.

Then came assembly language.

Then came higher-level programming languages.

Early C compilers had to be implemented using lower-level languages. Once C compilers became mature enough, they could gradually be rewritten in C itself, becoming self-hosting compilers.

After that, most programmers no longer needed to care about instructions such as:

<pre><code>MOV
PUSH
JMP</code></pre>

And certainly not the underlying zeros and ones.

We simply kept moving up the abstraction stack.

First:

<pre><code>Machine Code</code></pre>

Then:

<pre><code>Assembly</code></pre>

Then:

<pre><code>C</code></pre>

Then:

<pre><code>C++ / Java / Python / C#</code></pre>

And now, perhaps we are entering another layer:

<pre><code>Natural Language</code></pre>

The programmer says:

<blockquote>Add a rate limiter to this API. It needs to support distributed deployment, it must not rely on local memory, and it should include unit tests and integration tests.</blockquote>

And the AI handles:

<pre><code>C#
Python
SQL
YAML
Terraform
Dockerfile
...</code></pre>

From this perspective, AI is not eliminating programming.

It is simply raising the abstraction level once again.

<h2>But This Time, There Is One Fundamental Difference</h2>

There is, however, one major difference between this abstraction shift and all the previous ones.

Traditional tools were largely deterministic.

Given the same C program:

<pre><code>gcc hello.c</code></pre>

under the same environment, using the same compiler and the same options, you expect a deterministic result.

A compiler does not decide to produce implementation A today and implementation B tomorrow because it “feels like it.”

LLMs are completely different.

Today you ask:

<blockquote>Implement this function.</blockquote>

It may give you solution A.

Ask again one minute later:

It may give you solution B.

Switch to another model:

Solution C.

That is because modern large language models are fundamentally probabilistic systems.

They use the existing context to continuously predict the next most likely token.

Of course, we can use many techniques to improve consistency and reliability:

<ul>
<li>Prompt Engineering</li>
<li>RAG</li>
<li>better context</li>
<li>lower temperature</li>
<li>Structured Output</li>
<li>Schema Validation</li>
<li>Unit Tests</li>
<li>Static Analysis</li>
<li>Formal Verification</li>
<li>CI/CD</li>
<li>using one AI to review another AI</li>
</ul>

All of these techniques can reduce the error space.

But they do not change one fundamental fact:

<strong>AI itself is not a deterministic <a href="https://helloacm.com/teaching-kids-programming-vlog-harness-engineering-commanding-ai-to-get-work-done/" title="Teaching Kids Programming vLog: Harness Engineering — Commanding AI to Get Work Done">compiler</a> in the traditional sense.</strong>

So the real challenge of AI-assisted programming is no longer:

<blockquote>Can AI write code?</blockquote>

That problem is already largely solved.

The much harder question is:

<blockquote>How do we know the code AI wrote is actually correct?</blockquote>

That may turn out to be one of the most important software engineering questions of the next decade.

<h2>Talk Is Cheap, and Code Is Becoming Cheap Too</h2>

So if I were to rewrite Linus's quote today, I might say:

<blockquote>Talk is cheap.</blockquote>

<blockquote>Code is becoming cheap too.</blockquote>

<blockquote>Judgment is expensive.</blockquote>

In the past, the scarce skill was:

<strong>The ability to turn ideas into code.</strong>

AI is rapidly driving the cost of that skill downward.

In the future, the truly scarce skills may become:

<ul>
<li>knowing what should be built</li>
<li>knowing why it should be built that way</li>
<li>knowing when AI is wrong</li>
<li>knowing when an AI-generated solution should be thrown away and redesigned from scratch</li>
</ul>

And when ten or more AI agents are working for you 24/7, tirelessly generating code, you still need to know one thing very clearly:

<strong>Where should the ship actually be going?</strong>

AI can become an extremely capable sailor.

But what engineers increasingly need to learn may no longer be how to row.

<strong>It is how to steer.</strong>

<h3>Do We Still Need LeetCode? Old-School Programming</h3>

I will probably keep doing LeetCode.

Even though I rarely need to manually write large amounts of code at work anymore, and many LeetCode-style algorithm problems are not directly useful in day-to-day software engineering, solving them still helps me keep my programming skills sharp.

After all, even if AI writes most of the code in the future, the ability to read code, understand the logic, and judge whether an implementation is correct will still matter.

And writing code manually is still a very effective way to learn.

It does not just train coding skills. It also trains problem solving: how to break a problem down, identify patterns, choose the right data structures and algorithms, and gradually turn an idea into working code.

There is also something satisfying about solving a problem and finally seeing that green AC. It is a small but reliable dose of dopamine.

That is why my iPad is almost always with me, either in my hand or in my bag. Even when I am out on a date with my wife, if I suddenly get five spare minutes, I can pull it out, solve a problem, and have a little fun.

Maybe one day, manually typing code line by line will become a kind of “old-school programming.”

But for me, it is still one of the best forms of mental exercise.

[caption id="attachment_158071" align="alignnone" width="1152"]<a href="https://helloacm.com/code-is-becoming-cheaper-what-really-matters-for-programmers-in-the-ai-era/2026-08-09-21-19-15/" rel="attachment wp-att-158071"><img src="https://helloacm.com/wp-content/uploads/2026/09/2026-08-09-21.19.15-scaled.jpg" alt="Leetcoding on a Date." width="1152" height="2048" class="size-full wp-image-158071" /></a> Leetcoding on a Date.[/caption]

[caption id="attachment_158070" align="alignnone" width="1672"]<a href="https://helloacm.com/code-is-becoming-cheaper-what-really-matters-for-programmers-in-the-ai-era/leetcoding-costa-2026-08-30-13-40-30/" rel="attachment wp-att-158070"><img src="https://helloacm.com/wp-content/uploads/2026/09/leetcoding-costa-2026-08-30-13.40.30.png" alt="Leetcoding at Costa" width="1672" height="941" class="size-full wp-image-158070" /></a> Leetcoding at Costa[/caption]

[caption id="attachment_158069" align="alignnone" width="2048"]<a href="https://helloacm.com/code-is-becoming-cheaper-what-really-matters-for-programmers-in-the-ai-era/leetcoding-camping-2026-08-23-20-27-32/" rel="attachment wp-att-158069"><img src="https://helloacm.com/wp-content/uploads/2026/09/leetcoding-camping-2026-08-23-20.27.32-scaled.jpg" alt="Leetcoding while Camping" width="2048" height="1152" class="size-full wp-image-158069" /></a> Leetcoding while Camping[/caption]

[caption id="attachment_158068" align="alignnone" width="2048"]<a href="https://helloacm.com/code-is-becoming-cheaper-what-really-matters-for-programmers-in-the-ai-era/leetcodeing-in-the-middle-of-wales-lake-2026-08-25-10-43-19/" rel="attachment wp-att-158068"><img src="https://helloacm.com/wp-content/uploads/2026/09/leetcodeing-in-the-middle-of-wales-lake-2026-08-25-10.43.19-scaled.jpg" alt="Leetcoding at the Wales Lake" width="2048" height="1152" class="size-full wp-image-158068" /></a> Leetcoding at the Wales Lake[/caption]

[show_file file="/var/www/wp-post-common/helloacm.com/leetcode.php"]

[show_file file="/var/www/wp-post-common/helloacm.com/ai.php"]

[show_posts keyword="leetcode"]

<h3>Code Is Becoming an Intermediate Artifact: Reflections on The End of Software Engineering</h3>
This paper: https://arxiv.org/pdf/2606.05608v1

<h2>What Is “The End of Software Engineering” Really Arguing?</h2>

The core argument of this paper can actually be compressed into one sentence:

<blockquote>
<strong>What AI agents are really changing is not merely the speed of writing code. They are turning code from the central product of software systems into a temporary tool that agents may generate, use, and even discard in order to complete a task. In the future, the core work of engineers will increasingly shift from writing code to defining problems, expressing intent, designing constraints, orchestrating agents, and verifying results.</strong>
</blockquote>

The paper is titled <strong>The End of Software Engineering</strong>.

However, if I were to describe its actual thesis more precisely, I would probably call it:

<blockquote>
<strong>The End of Code-Centric Software Engineering</strong>
</blockquote>

In other words:

<blockquote>
<strong>Software engineering is not disappearing. What may be disappearing is software engineering centred around humans manually writing code.</strong>
</blockquote>

<h3>Traditional Software Engineering: Humans Reason, Code Encodes the Decisions</h3>

The traditional development process looks roughly like this:

<pre><code>Problem
↓
Human Reasoning
↓
Design
↓
Code
↓
Execution
↓
Result</code></pre>

Engineers first understand a problem, design a solution, and then encode those decisions into software.

When requirements change, we once again have to understand the problem, modify the design, change the code, test it, and redeploy it.

The paper argues that this model contains a fundamental scalability problem:

<blockquote>
System complexity keeps increasing, while human cognitive capacity remains relatively fixed.
</blockquote>

Over the past several decades, we have invented many techniques for dealing with complexity:

<ul>
<li>abstraction</li>
<li>object-oriented programming</li>
<li>modules</li>
<li>frameworks</li>
<li>microservices</li>
<li>CI/CD</li>
<li>cloud platforms</li>
</ul>

All of these are extremely valuable.

But from the paper's perspective, they mainly help humans manage complexity more effectively.

They do not fundamentally change one fact:

<strong>Humans still have to understand the system and encode the logic into software.</strong>

<h3>Agents Change Who Performs the Reasoning</h3>

The agentic model increasingly looks like this:

<pre><code>Intent
↓
Agent Reasoning
↓
Tools / APIs / Generated Code
↓
Result</code></pre>

The important change is not simply that AI helps programmers produce more code.

Instead:

<strong>The LLM or agent itself becomes part of the reasoning engine.</strong>

An agent may:

<ul>
<li>understand the goal</li>
<li>decompose the task</li>
<li>query data</li>
<li>call APIs</li>
<li>generate Python, SQL, or shell scripts</li>
<li>execute the code</li>
<li>inspect the result</li>
<li>re-plan after failure</li>
<li>finally deliver the outcome</li>
</ul>

This leads to a very important shift:

<blockquote>
<strong>Code no longer has to be the product.</strong>
</blockquote>

Code may simply become an intermediate artifact generated by an agent during one step of its reasoning process.

For example, an agent might generate 300 lines of Python to solve a task.

Once the code has run and the result has been produced, those 300 lines may not even need to be preserved.

They may never need to:

<ul>
<li>enter Git</li>
<li>go through code review</li>
<li>be maintained for years</li>
<li>become part of the final product</li>
</ul>

The valuable thing is the outcome, not necessarily the 300 lines of code.

I think this is one of the most important ideas in the paper.

<h3>From “AI Helps Me Build Software” to “AI Produces the Outcome”</h3>

Most people today still think about AI coding in roughly this way:

<pre><code>AI
↓
Software
↓
Result</code></pre>

For example:

<pre><code>Copilot
↓
helps me write code
↓
I build software
↓
the user gets a result</code></pre>

That is still fundamentally traditional software engineering.

The code-generation step has simply become faster.

The paper argues that the true agentic paradigm increasingly looks like:

<pre><code>Agent
↓
Result</code></pre>

Imagine that I tell an agent:

<blockquote>
Analyse one year of my server logs, identify abnormal traffic, and produce a security risk report.
</blockquote>

In the future, I may not care whether the agent:

<ul>
<li>wrote Python</li>
<li>ran SQL</li>
<li>used shell commands</li>
<li>generated temporary scripts</li>
<li>used a particular library</li>
</ul>

I care about one thing:

<blockquote>
<strong>Is the result correct?</strong>
</blockquote>

The paper describes this transition roughly as:

<pre><code>Local Software
↓
SaaS
↓
AaaS — Agent as a Service</code></pre>

SaaS reduced the need for users to care about infrastructure and deployment.

AaaS may go one step further:

<strong>Users may no longer need to care how the software solution itself is implemented.</strong>

<h3>So Where Does the Value of Programmers Go?</h3>

This is, in my view, one of the most interesting parts of the paper.

In the past:

<pre><code>Human = Code Author</code></pre>

In the future, the role may increasingly become:

<pre><code>Human =
Intent Architect
+ Coordinator
+ Auditor</code></pre>

The value of human engineers therefore moves upward.

<h4>Intent Articulation</h4>

Can you accurately explain:

<strong>What problem actually needs to be solved?</strong>

<h4>Architectural Oversight</h4>

How should the agents be organised?

Where are the system boundaries?

Which decisions can be delegated to AI?

Which decisions should never be delegated entirely?

<h4>Quality Calibration</h4>

How do you define “good”?

If you cannot define what correct or excellent looks like, then even an extremely capable agent will struggle to optimise toward the right outcome.

<h4>Evaluation and Verification</h4>

The agent gives you an answer.

But:

<strong>How do you know it is actually correct?</strong>

<h4>Governance</h4>

Which operations require a human in the loop?

Which actions require approval?

Which agents may access production systems?

Which ones should never have that access?

These questions become increasingly valuable.

This leads to an important conclusion:

<blockquote>
<strong>In the future, an engineer's greatest competitive advantage may not even be solving problems. It may move one step earlier: identifying which problems are worth solving and defining them precisely.</strong>
</blockquote>

Code generation will become increasingly commoditised.

But:

<blockquote>
<strong>Problem formulation will not.</strong>
</blockquote>

<h3>The Future 10x Engineer May Not Be Someone Who Writes 10x More Code</h3>

The paper also predicts an interesting organisational shift.

A traditional engineering team might look like:

<pre><code>PM
+ Architect
\+ 20 Developers
+ QA
+ DevOps</code></pre>

A future organisation may look more like:

<pre><code>A few senior engineers / architects
+
PM Agents
+
Coding Agents
+
Testing Agents
+
Debugging Agents
+
Security Agents</code></pre>

Humans provide:

<pre><code>Goals
+
Constraints
+
Judgement</code></pre>

Agents provide:

<pre><code>Execution</code></pre>

Under this model, the future <strong>10x engineer</strong> may no longer be someone capable of writing ten times more code.

Instead, it may be:

<blockquote>
<strong>Someone capable of effectively orchestrating ten, dozens, or even more specialised agents.</strong>
</blockquote>

The scarce skill moves from execution toward orchestration.

<h3>However, the Paper Contains an Important Contradiction</h3>

The title is deliberately aggressive:

<blockquote>
<strong>The End of Software Engineering</strong>
</blockquote>

But some of the evidence cited by the paper itself suggests that we are still far away from that point.

Agents may perform extremely well on isolated tasks:

<blockquote>
<strong>More than 80% success</strong>
</blockquote>

But when the task becomes long-term software maintenance, performance may fall to:

<blockquote>
<strong>38% or below</strong>
</blockquote>

The problems include:

<ul>
<li>context drift</li>
<li>error propagation</li>
<li>technical debt</li>
<li>verification failures</li>
<li>difficulty maintaining long-term system state</li>
</ul>

This exposes an important distinction.

AI is becoming increasingly good at:

<blockquote>
“Fix this issue for me.”
</blockquote>

But that is very different from:

<blockquote>
“Own this repository for the next three years and make sure its architecture does not decay.”
</blockquote>

The second task involves long-term architecture, technical debt, implicit requirements, historical context, team knowledge, and continuously changing state.

The paper itself ultimately acknowledges that:

<blockquote>
Fully autonomous software engineering remains a multi-year research challenge.
</blockquote>

<h3>My Biggest Reservation: The Mathematical Argument Makes a Large Leap</h3>

The paper also tries to argue for the inevitability of agentic software engineering from a complexity perspective.

If a system contains <code>n</code> components, the number of possible dependency graphs may grow roughly like:

<pre><code>2^(n choose 2)</code></pre>

In other words, the theoretical number of possible dependency combinations grows combinatorially.

The argument then roughly becomes:

<pre><code>Software complexity keeps increasing

+

Human cognitive capacity remains relatively fixed

+

LLM capacity can increase with compute

↓

The agentic paradigm must eventually scale better</code></pre>

The direction is interesting.

However, I think there is a substantial logical jump here.

The number of possible dependency graphs may indeed grow exponentially.

But that does not directly prove that:

<blockquote>
The practical cognitive complexity of software engineering itself grows exponentially.
</blockquote>

And it certainly does not prove that:

<blockquote>
LLMs can efficiently handle that exponential complexity.
</blockquote>

LLMs have their own limitations:

<ul>
<li>context windows</li>
<li>reasoning errors</li>
<li>hallucinations</li>
<li>compute cost</li>
<li>state management</li>
<li>verification difficulty</li>
</ul>

So when the paper describes the transition toward agentic software engineering as something close to a “first-principles necessity” or as inevitable, I would treat that as:

<strong>An interesting thesis rather than a rigorously proven theorem.</strong>

<h3>How I Would Summarise the Paper</h3>

I would not summarise it as:

<blockquote>
<strong>AI will eliminate software engineers.</strong>
</blockquote>

I would summarise it as:

<blockquote>
<strong>AI is pushing software engineering one abstraction layer higher.</strong>
</blockquote>

Over the past several decades, the progression has roughly looked like:

<pre><code>Machine Code
↓
Assembly
↓
C
↓
C++ / Java
↓
Frameworks
↓
Cloud / APIs
↓
AI Coding</code></pre>

The next layer may be:

<pre><code>Intent
↓
Agent
↓
Reasoning
↓
Tools / APIs / Generated Code
↓
Outcome</code></pre>

Software engineering has always moved toward higher levels of abstraction.

Programmers stopped writing machine code manually.

Later, most developers no longer needed to manually manage many low-level details involving memory, sockets, threads, and machine deployment.

AI may simply be continuing the same historical trend:

<strong>Engineers increasingly manipulate intent instead of directly manipulating code.</strong>

<h3>The One Idea Worth Remembering</h3>

The most valuable idea in the paper, in my view, is not:

<blockquote>
The End of Software Engineering.
</blockquote>

It is the idea behind this statement:

<blockquote>
<strong>What persists is the agent's capability, not its intermediate artifacts.</strong>
</blockquote>

Put differently:

<blockquote>
<strong>In the AI era, code is gradually losing its status as the final product and becoming an intermediate artifact in the process of solving problems. What becomes scarce instead moves upward: discovering problems, defining them precisely, asking the right questions, designing system boundaries, and determining whether the answer is actually correct.</strong>
</blockquote>

That argument is much deeper than the somewhat clickbait headline:

<blockquote>
<strong>“Software Engineering is ending.”</strong>
</blockquote>

[caption id="attachment_158075" align="alignnone" width="1126"]<a href="https://helloacm.com/code-is-becoming-cheaper-what-really-matters-for-programmers-in-the-ai-era/paper-the-end-of-software-engineering/" rel="attachment wp-att-158075"><img src="https://helloacm.com/wp-content/uploads/2026/09/paper-the-end-of-software-engineering.jpg" alt="The End of Software Engineering:
How AI Agents Are Fundamentally Restructuring the Software Paradigm" width="1126" height="1602" class="size-full wp-image-158075" /></a> The End of Software Engineering:<br />How AI Agents Are Fundamentally Restructuring the Software Paradigm[/caption]

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/teaching-kids-programming-verify-preorder-sequence-in-binary-search-tree-monotonous-stack/" rel="bookmark" title="Teaching Kids Programming &#8211; Verify Preorder Sequence in Binary Search Tree (Monotonous Stack)">Teaching Kids Programming &#8211; Verify Preorder Sequence in Binary Search Tree (Monotonous Stack)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms A stack-based solution for LeetCode 255,...</small></li>
<li><a href="https://helloacm.com/the-memory-manager-in-c-c-heap-vs-stack/" rel="bookmark" title="The Memory Manager in C/C++ (Heap vs Stack)">The Memory Manager in C/C++ (Heap vs Stack)</a> <small>This is one of the most frequently asked interview questions for Software Engineer roles. In...</small></li>
<li><a href="https://helloacm.com/hardening-wordpress-disable-php-execution-in-wp-content-uploads/" rel="bookmark" title="Hardening WordPress: Disable PHP Execution in `wp-content/uploads`">Hardening WordPress: Disable PHP Execution in `wp-content/uploads`</a> <small>WordPress must be able to write media files to `wp-content/uploads`, but files stored there should...</small></li>
<li><a href="https://helloacm.com/ai-coding-agents-are-reshaping-the-barrier-to-programming/" rel="bookmark" title="AI Coding Agents Are Reshaping the Barrier to Programming">AI Coding Agents Are Reshaping the Barrier to Programming</a> <small>AI Coding Agents Are Reshaping the Barrier to Programming Coding Is Becoming as Easy as...</small></li>
<li><a href="https://helloacm.com/tetration-operator-in-math-simply-explained-with-python-algorithms/" rel="bookmark" title="Tetration Operator in Math Simply Explained with Python Algorithms">Tetration Operator in Math Simply Explained with Python Algorithms</a> <small>What is Tetration Operator in Math? Tetration is an operation in mathematics that involves iterated...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-minimum-number-of-perfect-squares-via-theorem-guided-iterative-deepening-dfs/" rel="bookmark" title="Teaching Kids Programming &#8211; Minimum Number of Perfect Squares via Theorem-guided iterative deepening DFS">Teaching Kids Programming &#8211; Minimum Number of Perfect Squares via Theorem-guided iterative deepening DFS</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms This article explores an iterative-deepening recursive...</small></li>
<li><a href="https://helloacm.com/turning-a-dusty-mini-pc-into-a-home-server-my-nuc-8s-second-life/" rel="bookmark" title="Turning a Dusty Mini PC into a Home Server: My NUC-8’s Second Life">Turning a Dusty Mini PC into a Home Server: My NUC-8’s Second Life</a> <small>I gave an unused Beelink SEi8 mini PC a second life by installing Ubuntu and...</small></li>
<li><a href="https://helloacm.com/delphi-is-30-years-old/" rel="bookmark" title="Delphi is 30 Years Old!">Delphi is 30 Years Old!</a> <small>People who know the Delphi programming language are probably revealing their age. Many people think...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://helloacm.com/code-is-becoming-cheaper-what-really-matters-for-programmers-in-the-ai-era/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Linux Disk Space Troubleshooting: Find Large Files and Directories with ncdu</title>
		<link>https://helloacm.com/linux-disk-space-troubleshooting-find-large-files-and-directories-with-ncdu/</link>
					<comments>https://helloacm.com/linux-disk-space-troubleshooting-find-large-files-and-directories-with-ncdu/#respond</comments>
		
		<dc:creator><![CDATA[ACMer]]></dc:creator>
		<pubDate>Tue, 01 Sep 2026 18:22:02 +0000</pubDate>
				<category><![CDATA[DevOps]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[df Command]]></category>
		<category><![CDATA[Disk Monitoring]]></category>
		<category><![CDATA[Disk Space]]></category>
		<category><![CDATA[du Command]]></category>
		<category><![CDATA[inode]]></category>
		<category><![CDATA[linux commands]]></category>
		<category><![CDATA[linux devops]]></category>
		<category><![CDATA[linux server]]></category>
		<category><![CDATA[Log Cleanup]]></category>
		<category><![CDATA[ncdu]]></category>
		<category><![CDATA[Server Maintenance]]></category>
		<category><![CDATA[system administration]]></category>
		<guid isPermaLink="false">https://helloacm.com/?p=158044</guid>

					<description><![CDATA[<blockquote>
Linux servers can run out of disk space because of growing logs, backups, caches, or Docker data, potentially causing databases, websites, and other services to fail. This article explains how to diagnose disk-space and inode issues using traditional commands such as df, du, find, and lsof, while introducing ncdu as a faster and more intuitive way to identify the largest files and directories.
</blockquote>

[caption id="attachment_158045" align="alignnone" width="848"]<a href="https://helloacm.com/linux-disk-space-troubleshooting-find-large-files-and-directories-with-ncdu/linux-ncdu-command-disk-free-space/" rel="attachment wp-att-158045"><img src="https://helloacm.com/wp-content/uploads/2026/09/linux-ncdu-command-disk-free-space.jpg" alt="Using ncdu to find out which folders/files take most diskspace" width="848" height="1221" class="size-full wp-image-158045" /></a> Using ncdu to find out which folders/files take most diskspace[/caption]

One common reason a Linux server goes down is that one of its filesystems has run out of space. Typical causes include rapidly growing log files, old database backups, accumulated Docker images, temporary files, and application caches.

When a filesystem becomes full, databases may be unable to write new data, web services may fail to create temporary files, and logging services may stop working. This can eventually cause websites and other services to fail.

To detect the problem early, I normally add a disk-space <a href="https://helloacm.com/turning-a-dusty-raspberry-pi-into-a-home-server-for-blockchain-monitoring/" title="Turning a Dusty Raspberry Pi into a Home Server for Blockchain Monitoring">monitoring</a> script to <code>crontab</code>. It sends an alert when disk usage reaches a predefined threshold, allowing me to take action before the filesystem becomes completely full.

<h2>Checking Disk Usage with Traditional Linux Commands</h2>

When a disk-space problem occurs, the first command I normally run is:

<pre lang=bash><code>df -hT</code></pre>

This displays the size, filesystem type, used space, available space, and usage percentage of each mounted filesystem.

Sometimes there appears to be free disk space, but the system still reports that it cannot create new files. This may mean that all available inodes have been used. The inode usage can be checked with:

<pre lang=bash><code>df -ih</code></pre>

The next step is to identify which files and directories are consuming the most space. The traditional approach is to combine commands such as <code>du</code>, <code>find</code>, <code>sort</code>, and <code>head</code>.

For example, the following command lists the ten largest top-level directories under the root directory:

<pre lang=bash><code>sudo du -xhd1 / 2&gt;/dev/null | sort -hr | head -n 10</code></pre>

The options have the following meanings:

<ul>
<li><code>-x</code>: Stay on the current filesystem and do not enter other mounted filesystems.</li>
<li><code>-h</code>: Display sizes in a human-readable format such as MB and GB.</li>
<li><code>-d1</code>: Only display entries one level below the root directory.</li>
<li><code>2&gt;/dev/null</code>: Hide permission-denied and other error messages.</li>
<li><code>sort -hr</code>: Sort the results by size in descending order.</li>
<li><code>head -n 10</code>: Display only the first ten results.</li>
</ul>

To recursively find the ten largest files or directories anywhere in the root filesystem, use:

<pre lang=bash><code>sudo du -xah / 2&gt;/dev/null | sort -hr | head -n 10</code></pre>

To search only for the ten largest files, use:

<pre lang=bash><code>sudo find / -xdev -type f -printf '%s\t%p\n' 2&gt;/dev/null \
    | sort -nr \
    | head -n 10 \
    | numfmt --field=1 --to=iec</code></pre>

These commands are useful, but they contain many options and are difficult to remember. I used to ask ChatGPT or another AI tool whenever I needed them. I could get the correct command each time, but I would usually forget it again afterwards.

Frequently used commands can be saved in a <a href="https://helloacm.com/monitoring-28-vps-machines-including-a-raspberry-pi-with-nezha-dashboard/" title="Monitoring 28 VPS Machines (Including a Raspberry Pi) with Nezha Dashboard">shell</a> script or configured as aliases. However, neither approach is as convenient as using an interactive disk-usage tool.

<h2>Analysing Disk Usage with ncdu</h2>

I recently discovered a very useful disk-space analysis tool called <code>ncdu</code>.

The name stands for <strong>NCurses Disk Usage</strong>. It provides an interactive terminal interface for browsing the disk usage of files and directories, making the results much easier to understand than the raw output from <code>du</code>.

On Ubuntu or Debian, install it with:

<pre lang=bash><code>sudo apt update
sudo apt install ncdu</code></pre>

After installation, scan the root filesystem with:

<pre lang=bash><code>sudo ncdu -x /</code></pre>

The <code>-x</code> option keeps the scan within the current filesystem. This prevents <code>ncdu</code> from scanning external drives, network storage, or other mounted filesystems.

If all mounted directories should be included, omit this option:

<pre lang=bash><code>sudo ncdu /</code></pre>

Once the scan has finished, <code>ncdu</code> displays the files and <a href="https://helloacm.com/make-lots-of-directories-with-smd-bat-using-windows-batch/" title="Make Lots of Directories with SMD.bat using Windows Batch">directories</a> according to how much space they consume. The interface can be controlled with the following keys:

<ul>
<li>Use the up and down arrow keys to select an item.</li>
<li>Press <code>Enter</code> to open a directory.</li>
<li>Press the left arrow key to return to the parent directory.</li>
<li>Press <code>s</code> to sort by size.</li>
<li>Press <code>n</code> to sort by name.</li>
<li>Press <code>q</code> to quit.</li>
<li>Press <code>?</code> to display help.</li>
</ul>

This makes it easy to navigate through the <a href="https://helloacm.com/enter-the-command-shell-prompt-with-specified-directory-on-windows-registry/" title="Enter the Command Shell Prompt with Specified Directory on Windows (Registry)">directory</a> tree and quickly identify the files or directories consuming the most disk space.

Be careful: <code>ncdu</code> also provides a deletion function. Pressing <code>d</code> deletes the selected file or directory. This is particularly dangerous when running <code>sudo ncdu /</code>, because accidentally deleting a system directory could make the server unusable. Always verify the selected path before deleting anything.

<h2>Disk Space Is Not Released After Deleting a File</h2>

Another common problem occurs when a large file has been deleted, but <code>df -h</code> still shows that the space has not been released.

This normally happens because a running process still has the deleted file open. The directory entry has been removed, but the filesystem cannot reclaim the space until the process closes its file handle.

Use the following command to find deleted files that are still open:

<pre><code>sudo lsof +L1</code></pre>

After identifying the responsible process, restart the corresponding service or, after confirming that it is safe, terminate the process. The filesystem should then release the occupied space.

<h2>Summary</h2>

Traditional commands such as <code>du</code>, <code>find</code>, <code>sort</code>, and <code>head</code> remain powerful. They are particularly useful for scripts, automated maintenance, and remote troubleshooting across multiple servers.

For quickly investigating a disk-space problem, however, the interactive interface provided by <code>ncdu</code> is much more intuitive and efficient.

When a Linux server is running out of disk space, I now normally investigate it in the following order:

<pre lang=bash><code>df -hT
df -ih
sudo ncdu -x /</code></pre>

First, identify which filesystem is running out of space. Next, check whether the inode limit has been reached. Finally, use <code>ncdu</code> to navigate through the directory tree and locate the largest files and directories.

Compared with repeatedly constructing complicated shell pipelines, this approach is faster, easier to remember, and less prone to mistakes.

[show_file file="/var/www/wp-post-common/helloacm.com/bash.php"]

[show_posts keyword="linux"]

Reposted to <a href="https://steemit.com/blog/@justyy/using-ncdu-to-find-out-the-most-occupied-files-directories" title="Using ncdu to find out the most occupied files/directories">Using ncdu to find out the most occupied files/directories</a> | <a href="https://blurt.blog/blog/@justyy/using-ncdu-to-find-out-the-most-occupied-files-directories" title="Using ncdu to find out the most occupied files/directories">Using ncdu to find out the most occupied files/directories</a>

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/how-to-use-the-dynamic-link-library-in-c-linux-gcc-compiler/" rel="bookmark" title="How to Use the Dynamic Link Library in C++ Linux (gcc compiler)?">How to Use the Dynamic Link Library in C++ Linux (gcc compiler)?</a> <small>The Dynamic Link Library (DLL) is stored separately from the target application and shared among...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-minimum-number-of-perfect-squares-via-theorem-guided-iterative-deepening-dfs/" rel="bookmark" title="Teaching Kids Programming &#8211; Minimum Number of Perfect Squares via Theorem-guided iterative deepening DFS">Teaching Kids Programming &#8211; Minimum Number of Perfect Squares via Theorem-guided iterative deepening DFS</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms This article explores an iterative-deepening recursive...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-implement-the-accumulate-function-in-python/" rel="bookmark" title="Teaching Kids Programming &#8211; Implement the Accumulate Function in Python">Teaching Kids Programming &#8211; Implement the Accumulate Function in Python</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms The accumulate function is provided in...</small></li>
<li><a href="https://helloacm.com/review-of-wiseup-smart-eyewear-sunglass-camera-usb-chargeable-1080p-video-spy-camera/" rel="bookmark" title="Review of WiseUp &#8220;Smart&#8221; Eyewear Sunglass Camera (USB Chargeable 1080p Video Spy Camera)">Review of WiseUp &#8220;Smart&#8221; Eyewear Sunglass Camera (USB Chargeable 1080p Video Spy Camera)</a> <small>Summer has come and the temperature rises to more than 30 degrees as shown on...</small></li>
<li><a href="https://helloacm.com/algorithm-to-check-if-a-binary-tree-can-be-constructed-via-hash-tables/" rel="bookmark" title="Algorithm to Check if a Binary Tree can be Constructed via Hash Tables">Algorithm to Check if a Binary Tree can be Constructed via Hash Tables</a> <small>Have the function TreeConstructor(strArr) take the array of strings stored in strArr, which will contain...</small></li>
<li><a href="https://helloacm.com/hardening-mysql-file-access-with-local_infile0-and-secure_file_privnull/" rel="bookmark" title="Hardening MySQL File Access with local_infile=0 and secure_file_priv=NULL">Hardening MySQL File Access with local_infile=0 and secure_file_priv=NULL</a> <small>MySQL needs permission to read and write ordinary database files, but most application databases do...</small></li>
<li><a href="https://helloacm.com/accidentally-deleting-over-18000-files-with-shiftdelete-recovering-data-from-a-surface-ssd-using-winfr/" rel="bookmark" title="Accidentally Deleting Over 18,000 Files with Shift+Delete: Recovering Data from a Surface SSD Using WinFR">Accidentally Deleting Over 18,000 Files with Shift+Delete: Recovering Data from a Surface SSD Using WinFR</a> <small>While freeing space on my Surface Laptop Studio 2, I accidentally used Shift+Delete to permanently...</small></li>
<li><a href="https://helloacm.com/how-to-make-ping-tests-to-global-servers-using-php/" rel="bookmark" title="How to Make Ping Tests to Global Servers using PHP?">How to Make Ping Tests to Global Servers using PHP?</a> <small>I recently consider purchasing my third VPS Server and the ping speed is one of...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<blockquote>
Linux servers can run out of disk space because of growing logs, backups, caches, or Docker data, potentially causing databases, websites, and other services to fail. This article explains how to diagnose disk-space and inode issues using traditional commands such as df, du, find, and lsof, while introducing ncdu as a faster and more intuitive way to identify the largest files and directories.
</blockquote>

[caption id="attachment_158045" align="alignnone" width="848"]<a href="https://helloacm.com/linux-disk-space-troubleshooting-find-large-files-and-directories-with-ncdu/linux-ncdu-command-disk-free-space/" rel="attachment wp-att-158045"><img src="https://helloacm.com/wp-content/uploads/2026/09/linux-ncdu-command-disk-free-space.jpg" alt="Using ncdu to find out which folders/files take most diskspace" width="848" height="1221" class="size-full wp-image-158045" /></a> Using ncdu to find out which folders/files take most diskspace[/caption]

One common reason a Linux server goes down is that one of its filesystems has run out of space. Typical causes include rapidly growing log files, old database backups, accumulated Docker images, temporary files, and application caches.

When a filesystem becomes full, databases may be unable to write new data, web services may fail to create temporary files, and logging services may stop working. This can eventually cause websites and other services to fail.

To detect the problem early, I normally add a disk-space <a href="https://helloacm.com/turning-a-dusty-raspberry-pi-into-a-home-server-for-blockchain-monitoring/" title="Turning a Dusty Raspberry Pi into a Home Server for Blockchain Monitoring">monitoring</a> script to <code>crontab</code>. It sends an alert when disk usage reaches a predefined threshold, allowing me to take action before the filesystem becomes completely full.

<h2>Checking Disk Usage with Traditional Linux Commands</h2>

When a disk-space problem occurs, the first command I normally run is:

<pre lang=bash><code>df -hT</code></pre>

This displays the size, filesystem type, used space, available space, and usage percentage of each mounted filesystem.

Sometimes there appears to be free disk space, but the system still reports that it cannot create new files. This may mean that all available inodes have been used. The inode usage can be checked with:

<pre lang=bash><code>df -ih</code></pre>

The next step is to identify which files and directories are consuming the most space. The traditional approach is to combine commands such as <code>du</code>, <code>find</code>, <code>sort</code>, and <code>head</code>.

For example, the following command lists the ten largest top-level directories under the root directory:

<pre lang=bash><code>sudo du -xhd1 / 2&gt;/dev/null | sort -hr | head -n 10</code></pre>

The options have the following meanings:

<ul>
<li><code>-x</code>: Stay on the current filesystem and do not enter other mounted filesystems.</li>
<li><code>-h</code>: Display sizes in a human-readable format such as MB and GB.</li>
<li><code>-d1</code>: Only display entries one level below the root directory.</li>
<li><code>2&gt;/dev/null</code>: Hide permission-denied and other error messages.</li>
<li><code>sort -hr</code>: Sort the results by size in descending order.</li>
<li><code>head -n 10</code>: Display only the first ten results.</li>
</ul>

To recursively find the ten largest files or directories anywhere in the root filesystem, use:

<pre lang=bash><code>sudo du -xah / 2&gt;/dev/null | sort -hr | head -n 10</code></pre>

To search only for the ten largest files, use:

<pre lang=bash><code>sudo find / -xdev -type f -printf '%s\t%p\n' 2&gt;/dev/null \
    | sort -nr \
    | head -n 10 \
    | numfmt --field=1 --to=iec</code></pre>

These commands are useful, but they contain many options and are difficult to remember. I used to ask ChatGPT or another AI tool whenever I needed them. I could get the correct command each time, but I would usually forget it again afterwards.

Frequently used commands can be saved in a <a href="https://helloacm.com/monitoring-28-vps-machines-including-a-raspberry-pi-with-nezha-dashboard/" title="Monitoring 28 VPS Machines (Including a Raspberry Pi) with Nezha Dashboard">shell</a> script or configured as aliases. However, neither approach is as convenient as using an interactive disk-usage tool.

<h2>Analysing Disk Usage with ncdu</h2>

I recently discovered a very useful disk-space analysis tool called <code>ncdu</code>.

The name stands for <strong>NCurses Disk Usage</strong>. It provides an interactive terminal interface for browsing the disk usage of files and directories, making the results much easier to understand than the raw output from <code>du</code>.

On Ubuntu or Debian, install it with:

<pre lang=bash><code>sudo apt update
sudo apt install ncdu</code></pre>

After installation, scan the root filesystem with:

<pre lang=bash><code>sudo ncdu -x /</code></pre>

The <code>-x</code> option keeps the scan within the current filesystem. This prevents <code>ncdu</code> from scanning external drives, network storage, or other mounted filesystems.

If all mounted directories should be included, omit this option:

<pre lang=bash><code>sudo ncdu /</code></pre>

Once the scan has finished, <code>ncdu</code> displays the files and <a href="https://helloacm.com/make-lots-of-directories-with-smd-bat-using-windows-batch/" title="Make Lots of Directories with SMD.bat using Windows Batch">directories</a> according to how much space they consume. The interface can be controlled with the following keys:

<ul>
<li>Use the up and down arrow keys to select an item.</li>
<li>Press <code>Enter</code> to open a directory.</li>
<li>Press the left arrow key to return to the parent directory.</li>
<li>Press <code>s</code> to sort by size.</li>
<li>Press <code>n</code> to sort by name.</li>
<li>Press <code>q</code> to quit.</li>
<li>Press <code>?</code> to display help.</li>
</ul>

This makes it easy to navigate through the <a href="https://helloacm.com/enter-the-command-shell-prompt-with-specified-directory-on-windows-registry/" title="Enter the Command Shell Prompt with Specified Directory on Windows (Registry)">directory</a> tree and quickly identify the files or directories consuming the most disk space.

Be careful: <code>ncdu</code> also provides a deletion function. Pressing <code>d</code> deletes the selected file or directory. This is particularly dangerous when running <code>sudo ncdu /</code>, because accidentally deleting a system directory could make the server unusable. Always verify the selected path before deleting anything.

<h2>Disk Space Is Not Released After Deleting a File</h2>

Another common problem occurs when a large file has been deleted, but <code>df -h</code> still shows that the space has not been released.

This normally happens because a running process still has the deleted file open. The directory entry has been removed, but the filesystem cannot reclaim the space until the process closes its file handle.

Use the following command to find deleted files that are still open:

<pre><code>sudo lsof +L1</code></pre>

After identifying the responsible process, restart the corresponding service or, after confirming that it is safe, terminate the process. The filesystem should then release the occupied space.

<h2>Summary</h2>

Traditional commands such as <code>du</code>, <code>find</code>, <code>sort</code>, and <code>head</code> remain powerful. They are particularly useful for scripts, automated maintenance, and remote troubleshooting across multiple servers.

For quickly investigating a disk-space problem, however, the interactive interface provided by <code>ncdu</code> is much more intuitive and efficient.

When a Linux server is running out of disk space, I now normally investigate it in the following order:

<pre lang=bash><code>df -hT
df -ih
sudo ncdu -x /</code></pre>

First, identify which filesystem is running out of space. Next, check whether the inode limit has been reached. Finally, use <code>ncdu</code> to navigate through the directory tree and locate the largest files and directories.

Compared with repeatedly constructing complicated shell pipelines, this approach is faster, easier to remember, and less prone to mistakes.

[show_file file="/var/www/wp-post-common/helloacm.com/bash.php"]

[show_posts keyword="linux"]

Reposted to <a href="https://steemit.com/blog/@justyy/using-ncdu-to-find-out-the-most-occupied-files-directories" title="Using ncdu to find out the most occupied files/directories">Using ncdu to find out the most occupied files/directories</a> | <a href="https://blurt.blog/blog/@justyy/using-ncdu-to-find-out-the-most-occupied-files-directories" title="Using ncdu to find out the most occupied files/directories">Using ncdu to find out the most occupied files/directories</a>

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/how-to-use-the-dynamic-link-library-in-c-linux-gcc-compiler/" rel="bookmark" title="How to Use the Dynamic Link Library in C++ Linux (gcc compiler)?">How to Use the Dynamic Link Library in C++ Linux (gcc compiler)?</a> <small>The Dynamic Link Library (DLL) is stored separately from the target application and shared among...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-minimum-number-of-perfect-squares-via-theorem-guided-iterative-deepening-dfs/" rel="bookmark" title="Teaching Kids Programming &#8211; Minimum Number of Perfect Squares via Theorem-guided iterative deepening DFS">Teaching Kids Programming &#8211; Minimum Number of Perfect Squares via Theorem-guided iterative deepening DFS</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms This article explores an iterative-deepening recursive...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-implement-the-accumulate-function-in-python/" rel="bookmark" title="Teaching Kids Programming &#8211; Implement the Accumulate Function in Python">Teaching Kids Programming &#8211; Implement the Accumulate Function in Python</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms The accumulate function is provided in...</small></li>
<li><a href="https://helloacm.com/review-of-wiseup-smart-eyewear-sunglass-camera-usb-chargeable-1080p-video-spy-camera/" rel="bookmark" title="Review of WiseUp &#8220;Smart&#8221; Eyewear Sunglass Camera (USB Chargeable 1080p Video Spy Camera)">Review of WiseUp &#8220;Smart&#8221; Eyewear Sunglass Camera (USB Chargeable 1080p Video Spy Camera)</a> <small>Summer has come and the temperature rises to more than 30 degrees as shown on...</small></li>
<li><a href="https://helloacm.com/algorithm-to-check-if-a-binary-tree-can-be-constructed-via-hash-tables/" rel="bookmark" title="Algorithm to Check if a Binary Tree can be Constructed via Hash Tables">Algorithm to Check if a Binary Tree can be Constructed via Hash Tables</a> <small>Have the function TreeConstructor(strArr) take the array of strings stored in strArr, which will contain...</small></li>
<li><a href="https://helloacm.com/hardening-mysql-file-access-with-local_infile0-and-secure_file_privnull/" rel="bookmark" title="Hardening MySQL File Access with local_infile=0 and secure_file_priv=NULL">Hardening MySQL File Access with local_infile=0 and secure_file_priv=NULL</a> <small>MySQL needs permission to read and write ordinary database files, but most application databases do...</small></li>
<li><a href="https://helloacm.com/accidentally-deleting-over-18000-files-with-shiftdelete-recovering-data-from-a-surface-ssd-using-winfr/" rel="bookmark" title="Accidentally Deleting Over 18,000 Files with Shift+Delete: Recovering Data from a Surface SSD Using WinFR">Accidentally Deleting Over 18,000 Files with Shift+Delete: Recovering Data from a Surface SSD Using WinFR</a> <small>While freeing space on my Surface Laptop Studio 2, I accidentally used Shift+Delete to permanently...</small></li>
<li><a href="https://helloacm.com/how-to-make-ping-tests-to-global-servers-using-php/" rel="bookmark" title="How to Make Ping Tests to Global Servers using PHP?">How to Make Ping Tests to Global Servers using PHP?</a> <small>I recently consider purchasing my third VPS Server and the ping speed is one of...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://helloacm.com/linux-disk-space-troubleshooting-find-large-files-and-directories-with-ncdu/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Hardening MySQL File Access with local_infile=0 and secure_file_priv=NULL</title>
		<link>https://helloacm.com/hardening-mysql-file-access-with-local_infile0-and-secure_file_privnull/</link>
					<comments>https://helloacm.com/hardening-mysql-file-access-with-local_infile0-and-secure_file_privnull/#respond</comments>
		
		<dc:creator><![CDATA[ACMer]]></dc:creator>
		<pubDate>Sat, 22 Aug 2026 21:58:40 +0000</pubDate>
				<category><![CDATA[database]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[Database Security]]></category>
		<category><![CDATA[Defense in Depth]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[File Access Control]]></category>
		<category><![CDATA[Least Privilege]]></category>
		<category><![CDATA[local_infile]]></category>
		<category><![CDATA[MySQL Security]]></category>
		<category><![CDATA[secure_file_priv]]></category>
		<category><![CDATA[Security Hardening]]></category>
		<category><![CDATA[Server Security]]></category>
		<category><![CDATA[wordpress security]]></category>
		<guid isPermaLink="false">https://helloacm.com/?p=158035</guid>

					<description><![CDATA[MySQL needs permission to read and write ordinary <a href="https://helloacm.com/how-to-describe-a-table-in-sqlite-database/" title="How to Describe a Table in Sqlite Database?">database</a> files, but most application databases do not need SQL statements to exchange arbitrary files with the operating system. If a server exists primarily for WordPress or another web application, leaving unused file-transfer features enabled creates unnecessary attack surface.

Two MySQL settings provide a useful layer of defence:

<pre><code>[mysqld]
local_infile=0
secure_file_priv=NULL</code></pre>

They protect two different file-access paths. <code>local_infile=0</code> disables files being loaded from a database client's machine, while <code>secure_file_priv=NULL</code> disables supported SQL operations that read from or write to the MySQL server's filesystem. They overlap in purpose, but one does not replace the other.

<h2>The Two Meanings of “Local”</h2>

The terminology is initially confusing because <code>LOCAL</code> means local to the MySQL <strong>client</strong>, not local to the database server.

Consider these two statements:

<pre><code>LOAD DATA INFILE '/path/data.csv' INTO TABLE records;

LOAD DATA LOCAL INFILE '/path/data.csv' INTO TABLE records;</code></pre>

Without <code>LOCAL</code>, the MySQL server process opens a file on the <strong>server host</strong>. With <code>LOCAL</code>, the client program opens a file on the <strong>client host</strong> and sends its contents to the server.

This difference explains why both settings are useful:

<table>
<thead>
<tr>
<th>Setting</th>
<th>File location it protects</th>
<th>Main operations affected</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>local_infile=0</code></td>
<td>The client host, which may be an application or web server</td>
<td><code>LOAD DATA LOCAL INFILE</code></td>
</tr>
<tr>
<td><code>secure_file_priv=NULL</code></td>
<td>The MySQL server host</td>
<td><code>LOAD DATA INFILE</code>, <code>SELECT ... INTO OUTFILE</code>, <code>SELECT ... INTO DUMPFILE</code>, and <code>LOAD_FILE()</code></td>
</tr>
</tbody>
</table>

<h2>Why Disable <code>LOAD DATA LOCAL INFILE</code>?</h2>

<code>LOAD DATA LOCAL INFILE</code> is convenient when an administrator needs to import a large CSV file. However, it also crosses an important security boundary: the MySQL server asks the connected client to read a local file and transmit it.

MySQL documents two principal risks. A malicious or modified server could request a different file from the one the client intended to send. In a web environment, the “client” may actually be the web server process, so the readable files at risk are those available to that process—not merely files on an administrator's laptop.

There is another reason to treat <code>LOCAL</code> carefully: a <code>LOAD DATA LOCAL</code> operation does not require MySQL's global <code>FILE</code> privilege. It instead depends on both the server and client allowing the <code>LOCAL</code> capability. Disabling it at the server therefore creates a clear, central policy boundary:

<pre><code>local_infile=0</code></pre>

With this setting, the server rejects <code>LOAD DATA LOCAL INFILE</code> even if a client library or command-line client has enabled local loading. For a WordPress database, this feature is normally unnecessary, so disabling it is a low-cost application of least privilege.

<h2>Why Set <code>secure_file_priv=NULL</code>?</h2>

The <code>secure_file_priv</code> variable controls SQL operations that interact directly with files on the database server. In MySQL, its three possible forms have very different security meanings:

<table>
<thead>
<tr>
<th>Value</th>
<th>Behaviour</th>
</tr>
</thead>
<tbody>
<tr>
<td>Empty string</td>
<td>File import and export are unrestricted, subject to privileges and operating-system permissions; MySQL explicitly describes this as insecure</td>
</tr>
<tr>
<td>Directory path</td>
<td>File operations are restricted to that directory</td>
</tr>
<tr>
<td><code>NULL</code></td>
<td>File import and export operations are disabled</td>
</tr>
</tbody>
</table>

For an <a href="https://helloacm.com/three-ways-of-running-a-continuous-nodejs-application-on-your-server/" title="Three ways of Running a continuous NodeJS Application on Your Server">application</a> database that never needs server-side file import or export, the strongest setting is:

<pre><code>secure_file_priv=NULL</code></pre>

This blocks SQL features that could otherwise be used to make the MySQL server process read an accessible file or write query results to the filesystem. That matters because filesystem access can turn a database compromise into a wider server compromise. For example, an unnecessary ability to write files may allow data to be placed somewhere it should never appear, while an unnecessary ability to read files may expose configuration or application data accessible to the MySQL operating-system account.

The setting is especially valuable as defence in depth. A normal application account should not have the global <code>FILE</code> privilege in the first place, but configuration mistakes happen, credentials can be misused, and vulnerabilities sometimes let attackers execute unintended SQL. <code>secure_file_priv=NULL</code> provides a server-wide backstop even if a privilege is accidentally granted.

<h2>Why Both Settings Are Needed</h2>

It is tempting to assume that <code>secure_file_priv=NULL</code> disables every form of file loading. It does not protect the client-side <code>LOCAL</code> path. When <code>LOCAL</code> is used, the client—not the MySQL server—reads the source file, and the normal server-side <code>FILE</code> privilege and <code>secure_file_priv</code> restriction do not govern that read.

Conversely, <code>local_infile=0</code> disables only the <code>LOCAL</code> form. It does not by itself prevent a sufficiently privileged account from using server-side operations such as <code>SELECT ... INTO OUTFILE</code>.

The settings therefore close complementary paths:

<pre><code>Client filesystem  --X--&gt;  MySQL       local_infile=0
MySQL              --X--&gt;  Server FS   secure_file_priv=NULL</code></pre>

Together, they establish a simple policy: data enters and leaves the application database through expected database queries and approved backup tools, not through general-purpose SQL file operations.

<h2>Configuration and Verification</h2>

On a typical Debian or Ubuntu installation, add the settings to the <code>[mysqld]</code> section of the MySQL server configuration, commonly in <code>/etc/mysql/mysql.conf.d/mysqld.cnf</code>:

<pre><code>[mysqld]
local_infile=0
secure_file_priv=NULL</code></pre>

Restart MySQL because <code>secure_file_priv</code> is a startup-only variable:

<pre><code>sudo systemctl restart mysql</code></pre>

Then verify the effective values rather than assuming that the intended configuration file was loaded:

<pre><code>SHOW GLOBAL VARIABLES LIKE 'local_infile';
SHOW GLOBAL VARIABLES LIKE 'secure_file_priv';</code></pre>

The expected results are <code>OFF</code> for <code>local_infile</code> and <code>NULL</code> for <code>secure_file_priv</code>.

It is worth checking the MySQL error log after restarting. A misplaced directive, duplicate setting, invalid value, or configuration file loaded in an unexpected order can leave the server with a different effective policy.

<h2>What Could Break?</h2>

These settings are appropriate only when their affected features are not part of a legitimate workflow.

<code>local_infile=0</code> breaks tools or scripts that depend on <code>LOAD DATA LOCAL INFILE</code>, including some bulk CSV-import and MySQL Shell import workflows. <code>secure_file_priv=NULL</code> blocks server-side file import/export and also prevents workflows such as <code>mysqldump --tab</code> that rely on server file creation.

An ordinary <a href="https://helloacm.com/store-and-backup-unlimited-photos-using-amazon-photos-prime/" title="Store and Backup Unlimited Photos using Amazon Photos (Prime)">backup</a> such as the following remains unaffected because the client receives database rows through the normal protocol and the shell writes the output file:

<pre><code>mysqldump --single-transaction database_name &gt; backup.sql</code></pre>

If server-side import or export is genuinely required, a dedicated directory is safer than an empty <code>secure_file_priv</code> value:

<pre><code>secure_file_priv=/var/lib/mysql-files/</code></pre>

That directory should exist, have tightly controlled ownership and permissions, and contain no application code or sensitive configuration. Enable only the capability actually required, for the shortest practical period, and disable it again afterward.

<h2>What These Settings Do Not Solve</h2>

These options are safeguards, not a complete database-security strategy. They do not prevent SQL injection, stop an attacker from reading database rows through ordinary <code>SELECT</code> queries, protect stolen credentials, or restrict a process that has already gained operating-system access. They also do not compensate for an application account with excessive privileges.

A sound baseline still includes:

<ul>
<li>giving each application its own database account;</li>
<li>granting only the required schema-level privileges;</li>
<li>ensuring application accounts do not have the global <code>FILE</code> privilege;</li>
<li>using parameterised queries and keeping applications, plugins, and MySQL patched;</li>
<li>restricting network access to the database;</li>
<li>running MySQL as an unprivileged operating-system user;</li>
<li>protecting configuration, backup, and database files with appropriate filesystem permissions; and</li>
<li>testing and monitoring backups.</li>
</ul>

<h2>Conclusion</h2>

Security hardening is often less about adding complex controls and more about removing capabilities that a workload never uses. A typical WordPress or web-application database has no reason to accept client-side local-file loads or let SQL statements access the server filesystem.

Setting <code>local_infile=0</code> and <code>secure_file_priv=NULL</code> closes both paths with minimal impact on normal application queries and conventional logical backups. The result is not an invulnerable database, but it is a smaller attack surface and a stronger final barrier when another layer fails—exactly what good defence in depth should provide.

<h2>References</h2>

<ul>
<li><a href="https://dev.mysql.com/doc/refman/8.4/en/server-system-variables.html">MySQL 8.4: Server System Variables</a></li>
<li><a href="https://dev.mysql.com/doc/refman/8.4/en/load-data-local-security.html">MySQL 8.4: Security Considerations for LOAD DATA LOCAL</a></li>
<li><a href="https://dev.mysql.com/doc/refman/8.4/en/load-data.html">MySQL 8.4: LOAD DATA Statement</a></li>
</ul>

<blockquote><strong>Compatibility note:</strong> The exact accepted values and defaults are product- and version-specific. The <code>secure_file_priv=NULL</code> behaviour described here is for MySQL. Check the documentation and effective variables before applying the same configuration to MariaDB or another MySQL-compatible server.</blockquote>

[show_posts keyword="mysql"]

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/how-to-find-the-mode-in-a-binary-search-tree/" rel="bookmark" title="How to Find the Mode in a Binary Search Tree?">How to Find the Mode in a Binary Search Tree?</a> <small>Given a BST (Binary Search Tree) with duplicates, find its mode(s) &#8211; the most frequently...</small></li>
<li><a href="https://helloacm.com/sql-inner-join-tutorial-with-example-managers-with-at-least-5-direct-reports/" rel="bookmark" title="SQL Inner Join Tutorial with Example:  Managers with at Least 5 Direct Reports">SQL Inner Join Tutorial with Example:  Managers with at Least 5 Direct Reports</a> <small>Given the following SQL Schema: Create table If Not Exists Employee (Id int, Name varchar(255),...</small></li>
<li><a href="https://helloacm.com/compute-the-maximum-score-after-splitting-a-string/" rel="bookmark" title="Compute the Maximum Score After Splitting a String">Compute the Maximum Score After Splitting a String</a> <small>Given a string s of zeros and ones, return the maximum score after splitting the...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-largest-sum-of-non-adjacent-numbers-2d-version-disappearing-coins-in-a-matrix/" rel="bookmark" title="Teaching Kids Programming &#8211; Largest Sum of Non-Adjacent Numbers (2D Version &#8211; Disappearing Coins in a Matrix)">Teaching Kids Programming &#8211; Largest Sum of Non-Adjacent Numbers (2D Version &#8211; Disappearing Coins in a Matrix)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given a two-dimensional list...</small></li>
<li><a href="https://helloacm.com/how-to-compute-the-chain-age-uptime-and-downtime-for-steem-blockchain/" rel="bookmark" title="How to Compute the Chain Age, Uptime and Downtime for Steem Blockchain?">How to Compute the Chain Age, Uptime and Downtime for Steem Blockchain?</a> <small>Steem Blockchain has been running for a while, and how to compute the Chain Age,...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-minimum-number-of-perfect-squares-via-theorem-guided-iterative-deepening-dfs/" rel="bookmark" title="Teaching Kids Programming &#8211; Minimum Number of Perfect Squares via Theorem-guided iterative deepening DFS">Teaching Kids Programming &#8211; Minimum Number of Perfect Squares via Theorem-guided iterative deepening DFS</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms This article explores an iterative-deepening recursive...</small></li>
<li><a href="https://helloacm.com/accidentally-deleting-over-18000-files-with-shiftdelete-recovering-data-from-a-surface-ssd-using-winfr/" rel="bookmark" title="Accidentally Deleting Over 18,000 Files with Shift+Delete: Recovering Data from a Surface SSD Using WinFR">Accidentally Deleting Over 18,000 Files with Shift+Delete: Recovering Data from a Surface SSD Using WinFR</a> <small>While freeing space on my Surface Laptop Studio 2, I accidentally used Shift+Delete to permanently...</small></li>
<li><a href="https://helloacm.com/best-security-practices-for-holding-cryptocurrencies-on-exchanges/" rel="bookmark" title="Best Security Practices for Holding Cryptocurrencies on Exchanges">Best Security Practices for Holding Cryptocurrencies on Exchanges</a> <small>Previously, I was scammed about 1355 USDT because I clicked a phishing link that I...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[MySQL needs permission to read and write ordinary <a href="https://helloacm.com/how-to-describe-a-table-in-sqlite-database/" title="How to Describe a Table in Sqlite Database?">database</a> files, but most application databases do not need SQL statements to exchange arbitrary files with the operating system. If a server exists primarily for WordPress or another web application, leaving unused file-transfer features enabled creates unnecessary attack surface.

Two MySQL settings provide a useful layer of defence:

<pre><code>[mysqld]
local_infile=0
secure_file_priv=NULL</code></pre>

They protect two different file-access paths. <code>local_infile=0</code> disables files being loaded from a database client's machine, while <code>secure_file_priv=NULL</code> disables supported SQL operations that read from or write to the MySQL server's filesystem. They overlap in purpose, but one does not replace the other.

<h2>The Two Meanings of “Local”</h2>

The terminology is initially confusing because <code>LOCAL</code> means local to the MySQL <strong>client</strong>, not local to the database server.

Consider these two statements:

<pre><code>LOAD DATA INFILE '/path/data.csv' INTO TABLE records;

LOAD DATA LOCAL INFILE '/path/data.csv' INTO TABLE records;</code></pre>

Without <code>LOCAL</code>, the MySQL server process opens a file on the <strong>server host</strong>. With <code>LOCAL</code>, the client program opens a file on the <strong>client host</strong> and sends its contents to the server.

This difference explains why both settings are useful:

<table>
<thead>
<tr>
<th>Setting</th>
<th>File location it protects</th>
<th>Main operations affected</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>local_infile=0</code></td>
<td>The client host, which may be an application or web server</td>
<td><code>LOAD DATA LOCAL INFILE</code></td>
</tr>
<tr>
<td><code>secure_file_priv=NULL</code></td>
<td>The MySQL server host</td>
<td><code>LOAD DATA INFILE</code>, <code>SELECT ... INTO OUTFILE</code>, <code>SELECT ... INTO DUMPFILE</code>, and <code>LOAD_FILE()</code></td>
</tr>
</tbody>
</table>

<h2>Why Disable <code>LOAD DATA LOCAL INFILE</code>?</h2>

<code>LOAD DATA LOCAL INFILE</code> is convenient when an administrator needs to import a large CSV file. However, it also crosses an important security boundary: the MySQL server asks the connected client to read a local file and transmit it.

MySQL documents two principal risks. A malicious or modified server could request a different file from the one the client intended to send. In a web environment, the “client” may actually be the web server process, so the readable files at risk are those available to that process—not merely files on an administrator's laptop.

There is another reason to treat <code>LOCAL</code> carefully: a <code>LOAD DATA LOCAL</code> operation does not require MySQL's global <code>FILE</code> privilege. It instead depends on both the server and client allowing the <code>LOCAL</code> capability. Disabling it at the server therefore creates a clear, central policy boundary:

<pre><code>local_infile=0</code></pre>

With this setting, the server rejects <code>LOAD DATA LOCAL INFILE</code> even if a client library or command-line client has enabled local loading. For a WordPress database, this feature is normally unnecessary, so disabling it is a low-cost application of least privilege.

<h2>Why Set <code>secure_file_priv=NULL</code>?</h2>

The <code>secure_file_priv</code> variable controls SQL operations that interact directly with files on the database server. In MySQL, its three possible forms have very different security meanings:

<table>
<thead>
<tr>
<th>Value</th>
<th>Behaviour</th>
</tr>
</thead>
<tbody>
<tr>
<td>Empty string</td>
<td>File import and export are unrestricted, subject to privileges and operating-system permissions; MySQL explicitly describes this as insecure</td>
</tr>
<tr>
<td>Directory path</td>
<td>File operations are restricted to that directory</td>
</tr>
<tr>
<td><code>NULL</code></td>
<td>File import and export operations are disabled</td>
</tr>
</tbody>
</table>

For an <a href="https://helloacm.com/three-ways-of-running-a-continuous-nodejs-application-on-your-server/" title="Three ways of Running a continuous NodeJS Application on Your Server">application</a> database that never needs server-side file import or export, the strongest setting is:

<pre><code>secure_file_priv=NULL</code></pre>

This blocks SQL features that could otherwise be used to make the MySQL server process read an accessible file or write query results to the filesystem. That matters because filesystem access can turn a database compromise into a wider server compromise. For example, an unnecessary ability to write files may allow data to be placed somewhere it should never appear, while an unnecessary ability to read files may expose configuration or application data accessible to the MySQL operating-system account.

The setting is especially valuable as defence in depth. A normal application account should not have the global <code>FILE</code> privilege in the first place, but configuration mistakes happen, credentials can be misused, and vulnerabilities sometimes let attackers execute unintended SQL. <code>secure_file_priv=NULL</code> provides a server-wide backstop even if a privilege is accidentally granted.

<h2>Why Both Settings Are Needed</h2>

It is tempting to assume that <code>secure_file_priv=NULL</code> disables every form of file loading. It does not protect the client-side <code>LOCAL</code> path. When <code>LOCAL</code> is used, the client—not the MySQL server—reads the source file, and the normal server-side <code>FILE</code> privilege and <code>secure_file_priv</code> restriction do not govern that read.

Conversely, <code>local_infile=0</code> disables only the <code>LOCAL</code> form. It does not by itself prevent a sufficiently privileged account from using server-side operations such as <code>SELECT ... INTO OUTFILE</code>.

The settings therefore close complementary paths:

<pre><code>Client filesystem  --X--&gt;  MySQL       local_infile=0
MySQL              --X--&gt;  Server FS   secure_file_priv=NULL</code></pre>

Together, they establish a simple policy: data enters and leaves the application database through expected database queries and approved backup tools, not through general-purpose SQL file operations.

<h2>Configuration and Verification</h2>

On a typical Debian or Ubuntu installation, add the settings to the <code>[mysqld]</code> section of the MySQL server configuration, commonly in <code>/etc/mysql/mysql.conf.d/mysqld.cnf</code>:

<pre><code>[mysqld]
local_infile=0
secure_file_priv=NULL</code></pre>

Restart MySQL because <code>secure_file_priv</code> is a startup-only variable:

<pre><code>sudo systemctl restart mysql</code></pre>

Then verify the effective values rather than assuming that the intended configuration file was loaded:

<pre><code>SHOW GLOBAL VARIABLES LIKE 'local_infile';
SHOW GLOBAL VARIABLES LIKE 'secure_file_priv';</code></pre>

The expected results are <code>OFF</code> for <code>local_infile</code> and <code>NULL</code> for <code>secure_file_priv</code>.

It is worth checking the MySQL error log after restarting. A misplaced directive, duplicate setting, invalid value, or configuration file loaded in an unexpected order can leave the server with a different effective policy.

<h2>What Could Break?</h2>

These settings are appropriate only when their affected features are not part of a legitimate workflow.

<code>local_infile=0</code> breaks tools or scripts that depend on <code>LOAD DATA LOCAL INFILE</code>, including some bulk CSV-import and MySQL Shell import workflows. <code>secure_file_priv=NULL</code> blocks server-side file import/export and also prevents workflows such as <code>mysqldump --tab</code> that rely on server file creation.

An ordinary <a href="https://helloacm.com/store-and-backup-unlimited-photos-using-amazon-photos-prime/" title="Store and Backup Unlimited Photos using Amazon Photos (Prime)">backup</a> such as the following remains unaffected because the client receives database rows through the normal protocol and the shell writes the output file:

<pre><code>mysqldump --single-transaction database_name &gt; backup.sql</code></pre>

If server-side import or export is genuinely required, a dedicated directory is safer than an empty <code>secure_file_priv</code> value:

<pre><code>secure_file_priv=/var/lib/mysql-files/</code></pre>

That directory should exist, have tightly controlled ownership and permissions, and contain no application code or sensitive configuration. Enable only the capability actually required, for the shortest practical period, and disable it again afterward.

<h2>What These Settings Do Not Solve</h2>

These options are safeguards, not a complete database-security strategy. They do not prevent SQL injection, stop an attacker from reading database rows through ordinary <code>SELECT</code> queries, protect stolen credentials, or restrict a process that has already gained operating-system access. They also do not compensate for an application account with excessive privileges.

A sound baseline still includes:

<ul>
<li>giving each application its own database account;</li>
<li>granting only the required schema-level privileges;</li>
<li>ensuring application accounts do not have the global <code>FILE</code> privilege;</li>
<li>using parameterised queries and keeping applications, plugins, and MySQL patched;</li>
<li>restricting network access to the database;</li>
<li>running MySQL as an unprivileged operating-system user;</li>
<li>protecting configuration, backup, and database files with appropriate filesystem permissions; and</li>
<li>testing and monitoring backups.</li>
</ul>

<h2>Conclusion</h2>

Security hardening is often less about adding complex controls and more about removing capabilities that a workload never uses. A typical WordPress or web-application database has no reason to accept client-side local-file loads or let SQL statements access the server filesystem.

Setting <code>local_infile=0</code> and <code>secure_file_priv=NULL</code> closes both paths with minimal impact on normal application queries and conventional logical backups. The result is not an invulnerable database, but it is a smaller attack surface and a stronger final barrier when another layer fails—exactly what good defence in depth should provide.

<h2>References</h2>

<ul>
<li><a href="https://dev.mysql.com/doc/refman/8.4/en/server-system-variables.html">MySQL 8.4: Server System Variables</a></li>
<li><a href="https://dev.mysql.com/doc/refman/8.4/en/load-data-local-security.html">MySQL 8.4: Security Considerations for LOAD DATA LOCAL</a></li>
<li><a href="https://dev.mysql.com/doc/refman/8.4/en/load-data.html">MySQL 8.4: LOAD DATA Statement</a></li>
</ul>

<blockquote><strong>Compatibility note:</strong> The exact accepted values and defaults are product- and version-specific. The <code>secure_file_priv=NULL</code> behaviour described here is for MySQL. Check the documentation and effective variables before applying the same configuration to MariaDB or another MySQL-compatible server.</blockquote>

[show_posts keyword="mysql"]

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/how-to-find-the-mode-in-a-binary-search-tree/" rel="bookmark" title="How to Find the Mode in a Binary Search Tree?">How to Find the Mode in a Binary Search Tree?</a> <small>Given a BST (Binary Search Tree) with duplicates, find its mode(s) &#8211; the most frequently...</small></li>
<li><a href="https://helloacm.com/sql-inner-join-tutorial-with-example-managers-with-at-least-5-direct-reports/" rel="bookmark" title="SQL Inner Join Tutorial with Example:  Managers with at Least 5 Direct Reports">SQL Inner Join Tutorial with Example:  Managers with at Least 5 Direct Reports</a> <small>Given the following SQL Schema: Create table If Not Exists Employee (Id int, Name varchar(255),...</small></li>
<li><a href="https://helloacm.com/compute-the-maximum-score-after-splitting-a-string/" rel="bookmark" title="Compute the Maximum Score After Splitting a String">Compute the Maximum Score After Splitting a String</a> <small>Given a string s of zeros and ones, return the maximum score after splitting the...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-largest-sum-of-non-adjacent-numbers-2d-version-disappearing-coins-in-a-matrix/" rel="bookmark" title="Teaching Kids Programming &#8211; Largest Sum of Non-Adjacent Numbers (2D Version &#8211; Disappearing Coins in a Matrix)">Teaching Kids Programming &#8211; Largest Sum of Non-Adjacent Numbers (2D Version &#8211; Disappearing Coins in a Matrix)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given a two-dimensional list...</small></li>
<li><a href="https://helloacm.com/how-to-compute-the-chain-age-uptime-and-downtime-for-steem-blockchain/" rel="bookmark" title="How to Compute the Chain Age, Uptime and Downtime for Steem Blockchain?">How to Compute the Chain Age, Uptime and Downtime for Steem Blockchain?</a> <small>Steem Blockchain has been running for a while, and how to compute the Chain Age,...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-minimum-number-of-perfect-squares-via-theorem-guided-iterative-deepening-dfs/" rel="bookmark" title="Teaching Kids Programming &#8211; Minimum Number of Perfect Squares via Theorem-guided iterative deepening DFS">Teaching Kids Programming &#8211; Minimum Number of Perfect Squares via Theorem-guided iterative deepening DFS</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms This article explores an iterative-deepening recursive...</small></li>
<li><a href="https://helloacm.com/accidentally-deleting-over-18000-files-with-shiftdelete-recovering-data-from-a-surface-ssd-using-winfr/" rel="bookmark" title="Accidentally Deleting Over 18,000 Files with Shift+Delete: Recovering Data from a Surface SSD Using WinFR">Accidentally Deleting Over 18,000 Files with Shift+Delete: Recovering Data from a Surface SSD Using WinFR</a> <small>While freeing space on my Surface Laptop Studio 2, I accidentally used Shift+Delete to permanently...</small></li>
<li><a href="https://helloacm.com/best-security-practices-for-holding-cryptocurrencies-on-exchanges/" rel="bookmark" title="Best Security Practices for Holding Cryptocurrencies on Exchanges">Best Security Practices for Holding Cryptocurrencies on Exchanges</a> <small>Previously, I was scammed about 1355 USDT because I clicked a phishing link that I...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://helloacm.com/hardening-mysql-file-access-with-local_infile0-and-secure_file_privnull/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Accidentally Deleting Over 18,000 Files with Shift+Delete: Recovering Data from a Surface SSD Using WinFR</title>
		<link>https://helloacm.com/accidentally-deleting-over-18000-files-with-shiftdelete-recovering-data-from-a-surface-ssd-using-winfr/</link>
					<comments>https://helloacm.com/accidentally-deleting-over-18000-files-with-shiftdelete-recovering-data-from-a-surface-ssd-using-winfr/#respond</comments>
		
		<dc:creator><![CDATA[ACMer]]></dc:creator>
		<pubDate>Fri, 21 Aug 2026 18:22:36 +0000</pubDate>
				<category><![CDATA[harddisk]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[technical]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[3-2-1 Backup]]></category>
		<category><![CDATA[data backup]]></category>
		<category><![CDATA[data loss]]></category>
		<category><![CDATA[Data Recovery]]></category>
		<category><![CDATA[Deleted File Recovery]]></category>
		<category><![CDATA[hard drive]]></category>
		<category><![CDATA[Hard Drive Recovery]]></category>
		<category><![CDATA[Protect Data]]></category>
		<category><![CDATA[RAID-1]]></category>
		<category><![CDATA[Recycle Bin]]></category>
		<category><![CDATA[Shift Delete]]></category>
		<category><![CDATA[SSD Recovery]]></category>
		<category><![CDATA[SSD TRIM]]></category>
		<category><![CDATA[Surface Laptop Studio 2]]></category>
		<category><![CDATA[Techology]]></category>
		<category><![CDATA[Windows File Recovery]]></category>
		<category><![CDATA[Windows Tips]]></category>
		<category><![CDATA[WinFR]]></category>
		<category><![CDATA[WinFr Tool]]></category>
		<guid isPermaLink="false">https://helloacm.com/?p=158017</guid>

					<description><![CDATA[<blockquote>
While freeing space on my Surface Laptop Studio 2, I accidentally used Shift+Delete to permanently remove the C:\tests directory, which unexpectedly contained photographs from a trip to Switzerland. This article documents my attempts to recover the data using Microsoft’s Windows File Recovery tool in Regular and Extensive modes, while explaining SSD TRIM, recovery destinations, HDD recovery, Recycle Bin settings, and the important difference between RAID redundancy and a genuine backup.
</blockquote>

I bought my <a href="https://codingforspeed.com/my-work-station-of-microsoft-surface-studio-laptop/" title="Microsoft Surface Laptop Studio" rel="noopener" target="_blank">Microsoft Surface Laptop Studio</a> 2 a few years ago. It has a 2TB SSD, almost all of which is allocated to the C drive.

Recently, I noticed that the C drive had less than 200GB of free space remaining, so I decided to remove some large files that I no longer needed. There was a folder named <code>tests</code> in the root directory of the C drive. I vaguely remembered creating it last year while compiling the STEEM blockchain software and downloading blockchain data for testing.

Assuming that everything inside could simply be downloaded again, I deleted the folder without properly checking its contents.

Even worse, I happened to hold down the <code>Shift</code> key while deleting it.

In Windows, <code>Shift+Delete</code> bypasses the Recycle Bin and permanently deletes the selected files. Once the deletion had started, I suddenly noticed some DSLR photographs from last year's trip to Switzerland appearing in the list.

By the time I realised what was happening and clicked Cancel, it was already too late. Only a few empty directories remained under <code>C:\tests</code>, while almost all the files had disappeared.

<h2>Fortunately, the Photos Had Been Backed Up</h2>

Fortunately, I remembered copying these photographs to a RAID 1 storage system built from two 18TB mechanical hard drives. After checking the storage, I confirmed that a complete copy of the deleted Switzerland photographs was still available.

However, I still could not be certain whether <code>C:\tests</code> had contained other files that had not been backed up.

I therefore decided to use this opportunity to test Microsoft's own file recovery utility: Windows File Recovery, commonly known as WinFR.

Before continuing, it is important to clarify a frequently misunderstood point:

<strong>RAID 1 is not a backup.</strong>

RAID 1 primarily provides disk redundancy. If one drive fails, the other drive can continue operating. However, if a file is accidentally deleted, encrypted by ransomware or logically corrupted, that change is normally mirrored to both drives.

What saved me in this incident was not RAID 1 itself. It was the fact that I had previously copied the photographs from the Surface SSD to a separate storage system. The real protection came from having another independent copy.

<h2>Installing Windows File Recovery</h2>

Windows File Recovery, commonly known as WinFR, is an official Microsoft command-line recovery utility for Windows 10 and Windows 11, available as a free download from the Microsoft Store. It can attempt to recover files that have been deleted from local SSDs, mechanical hard drives, external drives and USB storage devices and can no longer be restored from the Recycle Bin. WinFR provides recovery modes such as Regular and Extensive and supports filters based on filenames, file types and original paths. The recovery destination must be different from the source drive to avoid overwriting data that may still be recoverable.

[caption id="attachment_158027" align="alignnone" width="651"]<a href="https://helloacm.com/accidentally-deleting-over-18000-files-with-shiftdelete-recovering-data-from-a-surface-ssd-using-winfr/winfr-recovery-tool/" rel="attachment wp-att-158027"><img src="https://helloacm.com/wp-content/uploads/2026/08/winfr-recovery-tool.png" alt="WinFr is a Windows Recovery Tool" width="651" height="409" class="size-full wp-image-158027" /></a> WinFr is a Windows Recovery Tool[/caption]

WinFR is not installed in Windows by default. It must be downloaded and installed from the Microsoft Store by searching for <strong>Windows File Recovery</strong>.

After installation, open Windows File Recovery as an administrator. Its general command syntax is relatively straightforward:

<blockquote><code>winfr source-drive: destination-drive: /mode /n path-filter</code></blockquote>

The folder that I had accidentally deleted was:

<blockquote><code>C:\tests</code></blockquote>

I used an independent D drive as the recovery destination and first ran:

<blockquote><code>winfr C: D: /regular /n \tests\</code></blockquote>

In this command:

<ul>
<li><code>C:</code> is the source drive from which the files were deleted;</li>
<li><code>D:</code> is the destination drive on which recovered files will be stored;</li>
<li><code>/regular</code> selects Regular recovery mode;</li>
<li><code>/n \tests\</code> asks WinFR to concentrate on content that was originally located under <code>C:\tests</code>.</li>
</ul>

Under a normal Windows NTFS configuration, path matching is case-insensitive. Therefore, <code>\tests\</code> and <code>\TESTS\</code> normally produce the same result. It is also normal for WinFR to display the filter as <code>TESTS\*</code>.

After recovery, WinFR automatically creates a timestamped directory on the destination drive, such as:

<blockquote><code>D:\Recovery_20260813_230934</code></blockquote>

<h2>Why Must the Recovery Destination Be Different from the C Drive?</h2>

One of the most important principles of file recovery is:

<strong>Never save recovered files back to the drive from which they are being recovered.</strong>

After a file is deleted, the file system marks its storage space as available. The original data may still exist temporarily, but any new write operation could overwrite that space.

If WinFR scans the C drive while simultaneously writing recovered files back to the same drive, it could overwrite files that have not yet been recovered.

<a href="https://helloacm.com/a-five-year-milestone-at-microsoft-anniversary-crystal/" title="A Five-Year Milestone at Microsoft (Anniversary Crystal)">Microsoft</a> requires the source and destination drives to be different. If the computer has only one physical drive, it is safer to connect an external USB drive and use it as the destination. You should also avoid creating a new partition on the source drive after losing data.

<a href="https://support.microsoft.com/en-us/windows/experience/backup-recovery/windows-file-recovery" target="_blank" rel="noopener">Microsoft: Windows File Recovery documentation</a>

In my case, the D drive belonged to a separate storage system and could therefore be used as the recovery destination.

There was still one unavoidable complication: WinFR had not been installed before the accident, so installing it from the Microsoft Store caused a small amount of new data to be written to the C drive.

For an ordinary recovery attempt, that risk may be acceptable. However, if the deleted data is unique and extremely valuable, the safest response is not to continue installing software on the affected computer. It may be better to stop using the machine, shut it down and either create a forensic disk image or consult a professional data recovery service.

<h2>What Is the Difference Between <code>/regular</code> and <code>/extensive</code>?</h2>

WinFR currently provides two main recovery modes.

<h3><code>/regular</code> Mode</h3>

The <code>/regular</code> mode is suitable when:

<ul>
<li>The source drive uses NTFS;</li>
<li>The files were deleted recently;</li>
<li>The file system itself is not corrupted;</li>
<li>You want to use the remaining file-system metadata to recover the files.</li>
</ul>

For example:

<blockquote><code>winfr C: D: /regular /n \tests\</code></blockquote>

This is Microsoft's recommended first option for files that were recently deleted from a healthy NTFS partition.

In my test, <code>/regular</code> quickly found the original directory structure and a large number of file records. The scan reported more than 18,000 candidate files.

<h3><code>/extensive</code> Mode</h3>

If <code>/regular</code> does not find the required files, the next option is:

<blockquote><code>winfr C: D: /extensive /n \tests\</code></blockquote>

The <code>/extensive</code> mode performs a more thorough scan and is suitable when:

<ul>
<li>The files were deleted some time ago;</li>
<li>The disk has been formatted;</li>
<li>The file system is corrupted;</li>
<li>The drive uses a non-NTFS file system such as FAT or exFAT;</li>
<li><code>/regular</code> failed to find the required files.</li>
</ul>

This mode is considerably slower. At the beginning of the scan, the progress indicator may remain at <code>00%</code> for a long time. This does not necessarily mean that WinFR has stopped responding. Disk read activity can be checked in Task Manager to confirm whether the scan is still running.

Microsoft recommends trying <code>/regular</code> first for recently deleted files on NTFS and then using <code>/extensive</code> if the first attempt is unsuccessful.

<h2>Why Were the Filenames Recovered but the Photographs Remained Unreadable?</h2>

I ran both <code>/regular</code> and <code>/extensive</code>. Both modes recovered a large number of files, and many of the original filenames and directory structures appeared to be intact.

However, many of the recovered photographs could not be opened. Windows reported that the files were damaged or corrupted.

This result is not actually contradictory.

On NTFS, file metadata and the actual file contents are stored separately. Information such as the filename, path, size and timestamps is normally stored in the Master File Table, or MFT, while the photograph's actual contents are stored in separate data clusters.

After deletion, the following situation can occur:

<ol>
<li>The filename and directory relationships still remain in the MFT;</li>
<li>WinFR can therefore reconstruct the original filename and directory structure;</li>
<li>The clusters containing the photograph data have already been overwritten or cleared internally by the SSD;</li>
<li>The result is a file whose name and size appear normal but whose contents are damaged.</li>
</ol>

Therefore, <strong>recovering a file entry does not necessarily mean that the file itself has been successfully recovered</strong>.

The recovered files must be opened and verified. For important data, it may also be necessary to check file hashes, verify that images can be decoded correctly and confirm that videos play from beginning to end.

<h2>Why Is SSD Recovery More Difficult Than Mechanical Hard Drive Recovery?</h2>

When a file is deleted from a traditional mechanical hard drive, the file record and its associated sectors are generally marked as available. As long as those sectors have not been overwritten by new data, the original contents may still remain on the magnetic surface and may be recoverable.

SSDs are more complicated.

Windows can use the TRIM command to tell the SSD controller that certain logical data blocks are no longer required. The SSD may subsequently erase those flash cells during its background garbage-collection process.

This does not necessarily mean that all data is physically erased the moment the Delete key is pressed. However, TRIM can significantly shorten the recovery window.

This explains my recovery result. Enough file-system metadata remained for WinFR to reconstruct filenames and directories, but the data blocks containing the photographs may already have been processed by TRIM and SSD garbage collection. The recovered photographs therefore could not be opened.

After accidentally deleting data from an <a href="https://helloacm.com/how-to-check-hard-disk-type-nvme-ssd-on-servers-vms/" title="How to Check Hard Disk Type (NVMe SSD) on Servers/VMs?">SSD</a>, it is advisable to:

<ul>
<li>Immediately minimise writes to the source drive;</li>
<li>Avoid downloading files, installing large applications or running updates;</li>
<li>Never save recovered data back to the source drive;</li>
<li>Check the Recycle Bin, OneDrive, File History and other backups first;</li>
<li>Consider shutting down the computer and seeking professional assistance if the data is extremely valuable.</li>
</ul>

Microsoft also warns that continued use of the computer may overwrite storage space that has been marked as available. Deleted data on an SSD may be particularly difficult or impossible to recover.

<h2>Why Did WinFR Recover Files That Were Apparently Not Inside <code>tests</code>?</h2>

After the recovery completed, I found several directories in the output, not just <code>tests</code>:

<ul>
<li><code>Documents</code></li>
<li><code>Misc</code></li>
<li><code>Pictures</code></li>
<li><code>tests</code></li>
</ul>

Some of these folders even contained files whose origin I did not recognise.

This does not necessarily mean that the path filter was completely ignored. WinFR attempts to reconstruct files from the remaining NTFS metadata, but the original parent directory may no longer be reliably available for every file.

The Windows system drive also continuously creates and deletes temporary files in the background. Some unrelated file records may therefore be included in the recovery results.

Microsoft's documentation acknowledges that additional files from the operating-system drive can sometimes be recovered even when filters are used.

WinFR should therefore be treated as a best-effort data rescue tool rather than a precise backup restoration utility. Recovery results must be reviewed manually and should not simply be copied back to the C drive in their entirety.

<h2>Can WinFR Recover Files from Mechanical Hard Drives?</h2>

Yes.

WinFR supports several types of local <a href="https://helloacm.com/remove-the-temporary-files-including-windows-old-on-windows-10-to-save-space-via-storage-sense/" title="Remove the Temporary Files (including Windows.old) on Windows 10 to Save Space via Storage Sense">storage</a>, including:

<ul>
<li>Internal SSDs;</li>
<li>Internal mechanical hard drives;</li>
<li>External mechanical hard drives;</li>
<li>USB storage devices;</li>
<li>Storage devices using supported file systems such as NTFS, FAT and exFAT.</li>
</ul>

For files that were recently deleted from a healthy NTFS mechanical hard drive, <code>/regular</code> is the appropriate first option. If the files were deleted some time ago, the disk was formatted or the file system is not NTFS, <code>/extensive</code> may be more suitable.

Because mechanical hard drives do not normally use SSD-style TRIM behaviour, accidentally deleted data may have a better chance of recovery, provided that the original sectors have not been overwritten.

However, recovery is never guaranteed. Once the original sectors have been overwritten by new data, recovery software cannot reconstruct their previous contents.

<h2>Does the Recycle Bin Keep Files for Seven Days?</h2>

The local Windows Recycle Bin does not have a universal seven-day retention period.

How long a file remains recoverable from the Recycle Bin depends on several factors:

<ul>
<li>Whether the user manually empties the Recycle Bin;</li>
<li>The configured Recycle Bin capacity;</li>
<li>Whether the file is too large to be placed in the Recycle Bin;</li>
<li>Whether Storage Sense is enabled;</li>
<li>The configured Storage Sense period for removing Recycle Bin content.</li>
</ul>

Microsoft states that Storage Sense is normally disabled by default, although Windows may enable selected cleanup behaviour and notify the user when the system is critically short of storage.

The <a href="https://helloacm.com/how-to-empty-recycle-bin-when-it-hangs-due-to-lots-of-files/" title="How to Empty Recycle Bin when it hangs due to lots of files?">Recycle Bin</a> cleanup setting can be checked and changed under:

<blockquote><code>Settings → System → Storage → Storage Sense</code></blockquote>

Then review the option:

<blockquote><code>Delete files in my Recycle Bin if they have been there for over</code></blockquote>

The Recycle Bin is therefore a useful safety buffer, but it is not a reliable backup.

<a href="https://support.microsoft.com/en-us/windows/experience/storage-filemanagement/manage-drive-space-with-storage-sense" target="_blank" rel="noopener">Microsoft: Managing drive space with Storage Sense</a>

<h2>Lessons from This Accident</h2>

This accidental deletion did not result in the permanent loss of the photographs because another copy existed on a separate storage system.

However, most of the photographs recovered by WinFR were corrupted. This demonstrated how difficult it can be to reverse a permanent deletion from an SSD.

In future, I will follow these rules when cleaning storage:

<ol>
<li>Open and inspect a directory before deleting the entire folder;</li>
<li>Avoid casually using <code>Shift+Delete</code>;</li>
<li>Move large folders into a temporary quarantine directory and wait several days before permanently deleting them;</li>
<li>Enable deletion confirmation in the Recycle Bin properties and ensure that “Don't move files to the Recycle Bin” is not selected;</li>
<li>Check the automatic cleanup period configured in Storage Sense;</li>
<li>Keep important files in multiple independent locations;</li>
<li>Regularly verify backups instead of merely checking that the backup disks still exist;</li>
<li>Use the 3-2-1 backup strategy for genuinely important data: at least three copies, stored on two types of media, with one copy kept off-site or in the cloud.</li>
</ol>

This incident gave me a practical opportunity to use WinFR and helped me understand the difference between recovering filenames, recovering actual file contents, SSD TRIM and maintaining proper backups.

The final lesson is simple:

[bctt tweet="File recovery should only be treated as a last resort. A tested and independent <a href="https://helloacm.com/avoid-single-point-of-failures-by-introducing-multiple-master-backup-reader-node-on-steem-bot-applications/" title="Avoid Single Point of Failures by Introducing Multiple Master Backup Reader Node on Steem Bot Applications">backup</a> remains the only reliable protection."]

[caption id="attachment_158026" align="alignnone" width="993"]<a href="https://helloacm.com/accidentally-deleting-over-18000-files-with-shiftdelete-recovering-data-from-a-surface-ssd-using-winfr/data-recovery-via-winfr-in-process/" rel="attachment wp-att-158026"><img src="https://helloacm.com/wp-content/uploads/2026/08/data-recovery-via-winfr-in-process.png" alt="Recovery Logs in Process via WinFr" width="993" height="815" class="size-full wp-image-158026" /></a> Recovery Logs in Process via WinFr[/caption]

[caption id="attachment_158025" align="alignnone" width="993"]<a href="https://helloacm.com/accidentally-deleting-over-18000-files-with-shiftdelete-recovering-data-from-a-surface-ssd-using-winfr/disk-recovery-logs-via-winfr-power-shell/" rel="attachment wp-att-158025"><img src="https://helloacm.com/wp-content/uploads/2026/08/disk-recovery-logs-via-winfr-power-shell.png" alt="Recovery Logs in Process via WinFr" width="993" height="815" class="size-full wp-image-158025" /></a> Recovery Logs in Process via WinFr[/caption]

[caption id="attachment_158024" align="alignnone" width="331"]<a href="https://helloacm.com/accidentally-deleting-over-18000-files-with-shiftdelete-recovering-data-from-a-surface-ssd-using-winfr/disk-recovery-logs-via-winfr-new-folder/" rel="attachment wp-att-158024"><img src="https://helloacm.com/wp-content/uploads/2026/08/disk-recovery-logs-via-winfr-new-folder.png" alt="A New Folder is Created for Storing the Recovered Files/Data so it won&#039;t be overwritten" width="331" height="154" class="size-full wp-image-158024" /></a> A New Folder is Created for Storing the Recovered Files/Data so it won't be overwritten[/caption]

[caption id="attachment_158023" align="alignnone" width="762"]<a href="https://helloacm.com/accidentally-deleting-over-18000-files-with-shiftdelete-recovering-data-from-a-surface-ssd-using-winfr/disk-recovery-logs-via-winfr-folder-structures/" rel="attachment wp-att-158023"><img src="https://helloacm.com/wp-content/uploads/2026/08/disk-recovery-logs-via-winfr-folder-structures.png" alt="Recovered Files/Folders via WinFr SSD Disk Recovery Software" width="762" height="492" class="size-full wp-image-158023" /></a> Recovered Files/Folders via WinFr SSD Disk Recovery Software[/caption]

[caption id="attachment_158022" align="alignnone" width="641"]<a href="https://helloacm.com/accidentally-deleting-over-18000-files-with-shiftdelete-recovering-data-from-a-surface-ssd-using-winfr/disk-recovery-logs-via-winfr-2/" rel="attachment wp-att-158022"><img src="https://helloacm.com/wp-content/uploads/2026/08/disk-recovery-logs-via-winfr-2.png" alt="WinFr Disk Recovery Logs" width="641" height="953" class="size-full wp-image-158022" /></a> WinFr Disk Recovery Logs[/caption]

[caption id="attachment_158021" align="alignnone" width="937"]<a href="https://helloacm.com/accidentally-deleting-over-18000-files-with-shiftdelete-recovering-data-from-a-surface-ssd-using-winfr/disk-recovery-logs-via-winfr/" rel="attachment wp-att-158021"><img src="https://helloacm.com/wp-content/uploads/2026/08/disk-recovery-logs-via-winfr.png" alt="WinFr Disk Recovery Logs" width="937" height="977" class="size-full wp-image-158021" /></a> WinFr Disk Recovery Logs[/caption]

<h3>Data is only yours if you have backups</h3>
Over the years, I have lost a hard drive while travelling (to Czech Republic, checked out from the hotel and travelling back to UK), experienced a NAS drive failure, and even had a drive somehow damaged by a faulty connection to a computer’s power supply. On that occasion, I paid several hundred pounds to a professional data recovery company, but they were unable to recover the data—and I still had to pay the fee. Since then, I have firmly believed that data is only truly yours when it is properly backed up. I now keep multiple local copies of important files and also back them up across different cloud or online platforms to minimise the risk of an unrecoverable single point of failure.

<a href="https://helloacm.com/crystaldiskinfo-software-shows-percentage-of-usage-lifespan-of-ssd/" title="CrystalDiskInfo Software Shows Percentage of Usage (Lifespan) of SSD">CrystalDiskInfo</a> shows the lifespan of the SSD remaining is 68%.
[caption id="attachment_158020" align="alignnone" width="674"]<a href="https://helloacm.com/accidentally-deleting-over-18000-files-with-shiftdelete-recovering-data-from-a-surface-ssd-using-winfr/ssd-life-span-surface-studio-microsoft-2026-08-21/" rel="attachment wp-att-158020"><img src="https://helloacm.com/wp-content/uploads/2026/08/ssd-life-span-surface-studio-microsoft-2026-08-21.jpg" alt="68% lifespan of the SSD. Usage about 16848 hours roughly 2 years " width="674" height="635" class="size-full wp-image-158020" /></a> 68% lifespan of the SSD. Usage about 16848 hours roughly 2 years [/caption]

[show_posts keyword="Hard Drive"]

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/sql-inner-join-tutorial-with-example-managers-with-at-least-5-direct-reports/" rel="bookmark" title="SQL Inner Join Tutorial with Example:  Managers with at Least 5 Direct Reports">SQL Inner Join Tutorial with Example:  Managers with at Least 5 Direct Reports</a> <small>Given the following SQL Schema: Create table If Not Exists Employee (Id int, Name varchar(255),...</small></li>
<li><a href="https://helloacm.com/best-black-friday-2015-deals-for-programmers/" rel="bookmark" title="Best Black Friday Deals for Programmers!">Best Black Friday Deals for Programmers!</a> <small>I have almost drained my bank account for the big shopping event this year &#8211;...</small></li>
<li><a href="https://helloacm.com/chatgpt-refactors-rewrites-the-code-using-promise-all-sending-requests-in-parallel/" rel="bookmark" title="ChatGPT Refactors/Rewrites the Code using Promise.All &#8211; Sending Requests in Parallel">ChatGPT Refactors/Rewrites the Code using Promise.All &#8211; Sending Requests in Parallel</a> <small>In one of my project, I have the following code (Node/Javascript) that invokes a few...</small></li>
<li><a href="https://helloacm.com/how-to-analyze-website-by-using-the-wappalyzer-chrome-extension/" rel="bookmark" title="How to Analyze Website by using the Wappalyzer (Chrome Extension)?">How to Analyze Website by using the Wappalyzer (Chrome Extension)?</a> <small>. And here is a list of technology used in this blog. And basically it...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-algorithms-to-count-houses-in-a-circular-street/" rel="bookmark" title="Teaching Kids Programming &#8211; Algorithms to Count Houses in a Circular Street">Teaching Kids Programming &#8211; Algorithms to Count Houses in a Circular Street</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given an object street...</small></li>
<li><a href="https://helloacm.com/a-tiny-logic-puzzle-about-truth-and-lies/" rel="bookmark" title="A Tiny Logic Puzzle About Truth and Lies">A Tiny Logic Puzzle About Truth and Lies</a> <small>A small village logic puzzle shows why careful reasoning matters. With 100 villagers each giving...</small></li>
<li><a href="https://helloacm.com/difference-between-product-design-interview-and-system-design-interview/" rel="bookmark" title="Difference Between Product Design Interview and System Design Interview">Difference Between Product Design Interview and System Design Interview</a> <small>In a Facebook/Meta interview (Software Engineering Roles including Site Reliability Engineers and Enterprise Engineers), the...</small></li>
<li><a href="https://helloacm.com/how-to-use-the-dynamic-link-library-in-c-linux-gcc-compiler/" rel="bookmark" title="How to Use the Dynamic Link Library in C++ Linux (gcc compiler)?">How to Use the Dynamic Link Library in C++ Linux (gcc compiler)?</a> <small>The Dynamic Link Library (DLL) is stored separately from the target application and shared among...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<blockquote>
While freeing space on my Surface Laptop Studio 2, I accidentally used Shift+Delete to permanently remove the C:\tests directory, which unexpectedly contained photographs from a trip to Switzerland. This article documents my attempts to recover the data using Microsoft’s Windows File Recovery tool in Regular and Extensive modes, while explaining SSD TRIM, recovery destinations, HDD recovery, Recycle Bin settings, and the important difference between RAID redundancy and a genuine backup.
</blockquote>

I bought my <a href="https://codingforspeed.com/my-work-station-of-microsoft-surface-studio-laptop/" title="Microsoft Surface Laptop Studio" rel="noopener" target="_blank">Microsoft Surface Laptop Studio</a> 2 a few years ago. It has a 2TB SSD, almost all of which is allocated to the C drive.

Recently, I noticed that the C drive had less than 200GB of free space remaining, so I decided to remove some large files that I no longer needed. There was a folder named <code>tests</code> in the root directory of the C drive. I vaguely remembered creating it last year while compiling the STEEM blockchain software and downloading blockchain data for testing.

Assuming that everything inside could simply be downloaded again, I deleted the folder without properly checking its contents.

Even worse, I happened to hold down the <code>Shift</code> key while deleting it.

In Windows, <code>Shift+Delete</code> bypasses the Recycle Bin and permanently deletes the selected files. Once the deletion had started, I suddenly noticed some DSLR photographs from last year's trip to Switzerland appearing in the list.

By the time I realised what was happening and clicked Cancel, it was already too late. Only a few empty directories remained under <code>C:\tests</code>, while almost all the files had disappeared.

<h2>Fortunately, the Photos Had Been Backed Up</h2>

Fortunately, I remembered copying these photographs to a RAID 1 storage system built from two 18TB mechanical hard drives. After checking the storage, I confirmed that a complete copy of the deleted Switzerland photographs was still available.

However, I still could not be certain whether <code>C:\tests</code> had contained other files that had not been backed up.

I therefore decided to use this opportunity to test Microsoft's own file recovery utility: Windows File Recovery, commonly known as WinFR.

Before continuing, it is important to clarify a frequently misunderstood point:

<strong>RAID 1 is not a backup.</strong>

RAID 1 primarily provides disk redundancy. If one drive fails, the other drive can continue operating. However, if a file is accidentally deleted, encrypted by ransomware or logically corrupted, that change is normally mirrored to both drives.

What saved me in this incident was not RAID 1 itself. It was the fact that I had previously copied the photographs from the Surface SSD to a separate storage system. The real protection came from having another independent copy.

<h2>Installing Windows File Recovery</h2>

Windows File Recovery, commonly known as WinFR, is an official Microsoft command-line recovery utility for Windows 10 and Windows 11, available as a free download from the Microsoft Store. It can attempt to recover files that have been deleted from local SSDs, mechanical hard drives, external drives and USB storage devices and can no longer be restored from the Recycle Bin. WinFR provides recovery modes such as Regular and Extensive and supports filters based on filenames, file types and original paths. The recovery destination must be different from the source drive to avoid overwriting data that may still be recoverable.

[caption id="attachment_158027" align="alignnone" width="651"]<a href="https://helloacm.com/accidentally-deleting-over-18000-files-with-shiftdelete-recovering-data-from-a-surface-ssd-using-winfr/winfr-recovery-tool/" rel="attachment wp-att-158027"><img src="https://helloacm.com/wp-content/uploads/2026/08/winfr-recovery-tool.png" alt="WinFr is a Windows Recovery Tool" width="651" height="409" class="size-full wp-image-158027" /></a> WinFr is a Windows Recovery Tool[/caption]

WinFR is not installed in Windows by default. It must be downloaded and installed from the Microsoft Store by searching for <strong>Windows File Recovery</strong>.

After installation, open Windows File Recovery as an administrator. Its general command syntax is relatively straightforward:

<blockquote><code>winfr source-drive: destination-drive: /mode /n path-filter</code></blockquote>

The folder that I had accidentally deleted was:

<blockquote><code>C:\tests</code></blockquote>

I used an independent D drive as the recovery destination and first ran:

<blockquote><code>winfr C: D: /regular /n \tests\</code></blockquote>

In this command:

<ul>
<li><code>C:</code> is the source drive from which the files were deleted;</li>
<li><code>D:</code> is the destination drive on which recovered files will be stored;</li>
<li><code>/regular</code> selects Regular recovery mode;</li>
<li><code>/n \tests\</code> asks WinFR to concentrate on content that was originally located under <code>C:\tests</code>.</li>
</ul>

Under a normal Windows NTFS configuration, path matching is case-insensitive. Therefore, <code>\tests\</code> and <code>\TESTS\</code> normally produce the same result. It is also normal for WinFR to display the filter as <code>TESTS\*</code>.

After recovery, WinFR automatically creates a timestamped directory on the destination drive, such as:

<blockquote><code>D:\Recovery_20260813_230934</code></blockquote>

<h2>Why Must the Recovery Destination Be Different from the C Drive?</h2>

One of the most important principles of file recovery is:

<strong>Never save recovered files back to the drive from which they are being recovered.</strong>

After a file is deleted, the file system marks its storage space as available. The original data may still exist temporarily, but any new write operation could overwrite that space.

If WinFR scans the C drive while simultaneously writing recovered files back to the same drive, it could overwrite files that have not yet been recovered.

<a href="https://helloacm.com/a-five-year-milestone-at-microsoft-anniversary-crystal/" title="A Five-Year Milestone at Microsoft (Anniversary Crystal)">Microsoft</a> requires the source and destination drives to be different. If the computer has only one physical drive, it is safer to connect an external USB drive and use it as the destination. You should also avoid creating a new partition on the source drive after losing data.

<a href="https://support.microsoft.com/en-us/windows/experience/backup-recovery/windows-file-recovery" target="_blank" rel="noopener">Microsoft: Windows File Recovery documentation</a>

In my case, the D drive belonged to a separate storage system and could therefore be used as the recovery destination.

There was still one unavoidable complication: WinFR had not been installed before the accident, so installing it from the Microsoft Store caused a small amount of new data to be written to the C drive.

For an ordinary recovery attempt, that risk may be acceptable. However, if the deleted data is unique and extremely valuable, the safest response is not to continue installing software on the affected computer. It may be better to stop using the machine, shut it down and either create a forensic disk image or consult a professional data recovery service.

<h2>What Is the Difference Between <code>/regular</code> and <code>/extensive</code>?</h2>

WinFR currently provides two main recovery modes.

<h3><code>/regular</code> Mode</h3>

The <code>/regular</code> mode is suitable when:

<ul>
<li>The source drive uses NTFS;</li>
<li>The files were deleted recently;</li>
<li>The file system itself is not corrupted;</li>
<li>You want to use the remaining file-system metadata to recover the files.</li>
</ul>

For example:

<blockquote><code>winfr C: D: /regular /n \tests\</code></blockquote>

This is Microsoft's recommended first option for files that were recently deleted from a healthy NTFS partition.

In my test, <code>/regular</code> quickly found the original directory structure and a large number of file records. The scan reported more than 18,000 candidate files.

<h3><code>/extensive</code> Mode</h3>

If <code>/regular</code> does not find the required files, the next option is:

<blockquote><code>winfr C: D: /extensive /n \tests\</code></blockquote>

The <code>/extensive</code> mode performs a more thorough scan and is suitable when:

<ul>
<li>The files were deleted some time ago;</li>
<li>The disk has been formatted;</li>
<li>The file system is corrupted;</li>
<li>The drive uses a non-NTFS file system such as FAT or exFAT;</li>
<li><code>/regular</code> failed to find the required files.</li>
</ul>

This mode is considerably slower. At the beginning of the scan, the progress indicator may remain at <code>00%</code> for a long time. This does not necessarily mean that WinFR has stopped responding. Disk read activity can be checked in Task Manager to confirm whether the scan is still running.

Microsoft recommends trying <code>/regular</code> first for recently deleted files on NTFS and then using <code>/extensive</code> if the first attempt is unsuccessful.

<h2>Why Were the Filenames Recovered but the Photographs Remained Unreadable?</h2>

I ran both <code>/regular</code> and <code>/extensive</code>. Both modes recovered a large number of files, and many of the original filenames and directory structures appeared to be intact.

However, many of the recovered photographs could not be opened. Windows reported that the files were damaged or corrupted.

This result is not actually contradictory.

On NTFS, file metadata and the actual file contents are stored separately. Information such as the filename, path, size and timestamps is normally stored in the Master File Table, or MFT, while the photograph's actual contents are stored in separate data clusters.

After deletion, the following situation can occur:

<ol>
<li>The filename and directory relationships still remain in the MFT;</li>
<li>WinFR can therefore reconstruct the original filename and directory structure;</li>
<li>The clusters containing the photograph data have already been overwritten or cleared internally by the SSD;</li>
<li>The result is a file whose name and size appear normal but whose contents are damaged.</li>
</ol>

Therefore, <strong>recovering a file entry does not necessarily mean that the file itself has been successfully recovered</strong>.

The recovered files must be opened and verified. For important data, it may also be necessary to check file hashes, verify that images can be decoded correctly and confirm that videos play from beginning to end.

<h2>Why Is SSD Recovery More Difficult Than Mechanical Hard Drive Recovery?</h2>

When a file is deleted from a traditional mechanical hard drive, the file record and its associated sectors are generally marked as available. As long as those sectors have not been overwritten by new data, the original contents may still remain on the magnetic surface and may be recoverable.

SSDs are more complicated.

Windows can use the TRIM command to tell the SSD controller that certain logical data blocks are no longer required. The SSD may subsequently erase those flash cells during its background garbage-collection process.

This does not necessarily mean that all data is physically erased the moment the Delete key is pressed. However, TRIM can significantly shorten the recovery window.

This explains my recovery result. Enough file-system metadata remained for WinFR to reconstruct filenames and directories, but the data blocks containing the photographs may already have been processed by TRIM and SSD garbage collection. The recovered photographs therefore could not be opened.

After accidentally deleting data from an <a href="https://helloacm.com/how-to-check-hard-disk-type-nvme-ssd-on-servers-vms/" title="How to Check Hard Disk Type (NVMe SSD) on Servers/VMs?">SSD</a>, it is advisable to:

<ul>
<li>Immediately minimise writes to the source drive;</li>
<li>Avoid downloading files, installing large applications or running updates;</li>
<li>Never save recovered data back to the source drive;</li>
<li>Check the Recycle Bin, OneDrive, File History and other backups first;</li>
<li>Consider shutting down the computer and seeking professional assistance if the data is extremely valuable.</li>
</ul>

Microsoft also warns that continued use of the computer may overwrite storage space that has been marked as available. Deleted data on an SSD may be particularly difficult or impossible to recover.

<h2>Why Did WinFR Recover Files That Were Apparently Not Inside <code>tests</code>?</h2>

After the recovery completed, I found several directories in the output, not just <code>tests</code>:

<ul>
<li><code>Documents</code></li>
<li><code>Misc</code></li>
<li><code>Pictures</code></li>
<li><code>tests</code></li>
</ul>

Some of these folders even contained files whose origin I did not recognise.

This does not necessarily mean that the path filter was completely ignored. WinFR attempts to reconstruct files from the remaining NTFS metadata, but the original parent directory may no longer be reliably available for every file.

The Windows system drive also continuously creates and deletes temporary files in the background. Some unrelated file records may therefore be included in the recovery results.

Microsoft's documentation acknowledges that additional files from the operating-system drive can sometimes be recovered even when filters are used.

WinFR should therefore be treated as a best-effort data rescue tool rather than a precise backup restoration utility. Recovery results must be reviewed manually and should not simply be copied back to the C drive in their entirety.

<h2>Can WinFR Recover Files from Mechanical Hard Drives?</h2>

Yes.

WinFR supports several types of local <a href="https://helloacm.com/remove-the-temporary-files-including-windows-old-on-windows-10-to-save-space-via-storage-sense/" title="Remove the Temporary Files (including Windows.old) on Windows 10 to Save Space via Storage Sense">storage</a>, including:

<ul>
<li>Internal SSDs;</li>
<li>Internal mechanical hard drives;</li>
<li>External mechanical hard drives;</li>
<li>USB storage devices;</li>
<li>Storage devices using supported file systems such as NTFS, FAT and exFAT.</li>
</ul>

For files that were recently deleted from a healthy NTFS mechanical hard drive, <code>/regular</code> is the appropriate first option. If the files were deleted some time ago, the disk was formatted or the file system is not NTFS, <code>/extensive</code> may be more suitable.

Because mechanical hard drives do not normally use SSD-style TRIM behaviour, accidentally deleted data may have a better chance of recovery, provided that the original sectors have not been overwritten.

However, recovery is never guaranteed. Once the original sectors have been overwritten by new data, recovery software cannot reconstruct their previous contents.

<h2>Does the Recycle Bin Keep Files for Seven Days?</h2>

The local Windows Recycle Bin does not have a universal seven-day retention period.

How long a file remains recoverable from the Recycle Bin depends on several factors:

<ul>
<li>Whether the user manually empties the Recycle Bin;</li>
<li>The configured Recycle Bin capacity;</li>
<li>Whether the file is too large to be placed in the Recycle Bin;</li>
<li>Whether Storage Sense is enabled;</li>
<li>The configured Storage Sense period for removing Recycle Bin content.</li>
</ul>

Microsoft states that Storage Sense is normally disabled by default, although Windows may enable selected cleanup behaviour and notify the user when the system is critically short of storage.

The <a href="https://helloacm.com/how-to-empty-recycle-bin-when-it-hangs-due-to-lots-of-files/" title="How to Empty Recycle Bin when it hangs due to lots of files?">Recycle Bin</a> cleanup setting can be checked and changed under:

<blockquote><code>Settings → System → Storage → Storage Sense</code></blockquote>

Then review the option:

<blockquote><code>Delete files in my Recycle Bin if they have been there for over</code></blockquote>

The Recycle Bin is therefore a useful safety buffer, but it is not a reliable backup.

<a href="https://support.microsoft.com/en-us/windows/experience/storage-filemanagement/manage-drive-space-with-storage-sense" target="_blank" rel="noopener">Microsoft: Managing drive space with Storage Sense</a>

<h2>Lessons from This Accident</h2>

This accidental deletion did not result in the permanent loss of the photographs because another copy existed on a separate storage system.

However, most of the photographs recovered by WinFR were corrupted. This demonstrated how difficult it can be to reverse a permanent deletion from an SSD.

In future, I will follow these rules when cleaning storage:

<ol>
<li>Open and inspect a directory before deleting the entire folder;</li>
<li>Avoid casually using <code>Shift+Delete</code>;</li>
<li>Move large folders into a temporary quarantine directory and wait several days before permanently deleting them;</li>
<li>Enable deletion confirmation in the Recycle Bin properties and ensure that “Don't move files to the Recycle Bin” is not selected;</li>
<li>Check the automatic cleanup period configured in Storage Sense;</li>
<li>Keep important files in multiple independent locations;</li>
<li>Regularly verify backups instead of merely checking that the backup disks still exist;</li>
<li>Use the 3-2-1 backup strategy for genuinely important data: at least three copies, stored on two types of media, with one copy kept off-site or in the cloud.</li>
</ol>

This incident gave me a practical opportunity to use WinFR and helped me understand the difference between recovering filenames, recovering actual file contents, SSD TRIM and maintaining proper backups.

The final lesson is simple:

[bctt tweet="File recovery should only be treated as a last resort. A tested and independent <a href="https://helloacm.com/avoid-single-point-of-failures-by-introducing-multiple-master-backup-reader-node-on-steem-bot-applications/" title="Avoid Single Point of Failures by Introducing Multiple Master Backup Reader Node on Steem Bot Applications">backup</a> remains the only reliable protection."]

[caption id="attachment_158026" align="alignnone" width="993"]<a href="https://helloacm.com/accidentally-deleting-over-18000-files-with-shiftdelete-recovering-data-from-a-surface-ssd-using-winfr/data-recovery-via-winfr-in-process/" rel="attachment wp-att-158026"><img src="https://helloacm.com/wp-content/uploads/2026/08/data-recovery-via-winfr-in-process.png" alt="Recovery Logs in Process via WinFr" width="993" height="815" class="size-full wp-image-158026" /></a> Recovery Logs in Process via WinFr[/caption]

[caption id="attachment_158025" align="alignnone" width="993"]<a href="https://helloacm.com/accidentally-deleting-over-18000-files-with-shiftdelete-recovering-data-from-a-surface-ssd-using-winfr/disk-recovery-logs-via-winfr-power-shell/" rel="attachment wp-att-158025"><img src="https://helloacm.com/wp-content/uploads/2026/08/disk-recovery-logs-via-winfr-power-shell.png" alt="Recovery Logs in Process via WinFr" width="993" height="815" class="size-full wp-image-158025" /></a> Recovery Logs in Process via WinFr[/caption]

[caption id="attachment_158024" align="alignnone" width="331"]<a href="https://helloacm.com/accidentally-deleting-over-18000-files-with-shiftdelete-recovering-data-from-a-surface-ssd-using-winfr/disk-recovery-logs-via-winfr-new-folder/" rel="attachment wp-att-158024"><img src="https://helloacm.com/wp-content/uploads/2026/08/disk-recovery-logs-via-winfr-new-folder.png" alt="A New Folder is Created for Storing the Recovered Files/Data so it won&#039;t be overwritten" width="331" height="154" class="size-full wp-image-158024" /></a> A New Folder is Created for Storing the Recovered Files/Data so it won't be overwritten[/caption]

[caption id="attachment_158023" align="alignnone" width="762"]<a href="https://helloacm.com/accidentally-deleting-over-18000-files-with-shiftdelete-recovering-data-from-a-surface-ssd-using-winfr/disk-recovery-logs-via-winfr-folder-structures/" rel="attachment wp-att-158023"><img src="https://helloacm.com/wp-content/uploads/2026/08/disk-recovery-logs-via-winfr-folder-structures.png" alt="Recovered Files/Folders via WinFr SSD Disk Recovery Software" width="762" height="492" class="size-full wp-image-158023" /></a> Recovered Files/Folders via WinFr SSD Disk Recovery Software[/caption]

[caption id="attachment_158022" align="alignnone" width="641"]<a href="https://helloacm.com/accidentally-deleting-over-18000-files-with-shiftdelete-recovering-data-from-a-surface-ssd-using-winfr/disk-recovery-logs-via-winfr-2/" rel="attachment wp-att-158022"><img src="https://helloacm.com/wp-content/uploads/2026/08/disk-recovery-logs-via-winfr-2.png" alt="WinFr Disk Recovery Logs" width="641" height="953" class="size-full wp-image-158022" /></a> WinFr Disk Recovery Logs[/caption]

[caption id="attachment_158021" align="alignnone" width="937"]<a href="https://helloacm.com/accidentally-deleting-over-18000-files-with-shiftdelete-recovering-data-from-a-surface-ssd-using-winfr/disk-recovery-logs-via-winfr/" rel="attachment wp-att-158021"><img src="https://helloacm.com/wp-content/uploads/2026/08/disk-recovery-logs-via-winfr.png" alt="WinFr Disk Recovery Logs" width="937" height="977" class="size-full wp-image-158021" /></a> WinFr Disk Recovery Logs[/caption]

<h3>Data is only yours if you have backups</h3>
Over the years, I have lost a hard drive while travelling (to Czech Republic, checked out from the hotel and travelling back to UK), experienced a NAS drive failure, and even had a drive somehow damaged by a faulty connection to a computer’s power supply. On that occasion, I paid several hundred pounds to a professional data recovery company, but they were unable to recover the data—and I still had to pay the fee. Since then, I have firmly believed that data is only truly yours when it is properly backed up. I now keep multiple local copies of important files and also back them up across different cloud or online platforms to minimise the risk of an unrecoverable single point of failure.

<a href="https://helloacm.com/crystaldiskinfo-software-shows-percentage-of-usage-lifespan-of-ssd/" title="CrystalDiskInfo Software Shows Percentage of Usage (Lifespan) of SSD">CrystalDiskInfo</a> shows the lifespan of the SSD remaining is 68%.
[caption id="attachment_158020" align="alignnone" width="674"]<a href="https://helloacm.com/accidentally-deleting-over-18000-files-with-shiftdelete-recovering-data-from-a-surface-ssd-using-winfr/ssd-life-span-surface-studio-microsoft-2026-08-21/" rel="attachment wp-att-158020"><img src="https://helloacm.com/wp-content/uploads/2026/08/ssd-life-span-surface-studio-microsoft-2026-08-21.jpg" alt="68% lifespan of the SSD. Usage about 16848 hours roughly 2 years " width="674" height="635" class="size-full wp-image-158020" /></a> 68% lifespan of the SSD. Usage about 16848 hours roughly 2 years [/caption]

[show_posts keyword="Hard Drive"]

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/sql-inner-join-tutorial-with-example-managers-with-at-least-5-direct-reports/" rel="bookmark" title="SQL Inner Join Tutorial with Example:  Managers with at Least 5 Direct Reports">SQL Inner Join Tutorial with Example:  Managers with at Least 5 Direct Reports</a> <small>Given the following SQL Schema: Create table If Not Exists Employee (Id int, Name varchar(255),...</small></li>
<li><a href="https://helloacm.com/best-black-friday-2015-deals-for-programmers/" rel="bookmark" title="Best Black Friday Deals for Programmers!">Best Black Friday Deals for Programmers!</a> <small>I have almost drained my bank account for the big shopping event this year &#8211;...</small></li>
<li><a href="https://helloacm.com/chatgpt-refactors-rewrites-the-code-using-promise-all-sending-requests-in-parallel/" rel="bookmark" title="ChatGPT Refactors/Rewrites the Code using Promise.All &#8211; Sending Requests in Parallel">ChatGPT Refactors/Rewrites the Code using Promise.All &#8211; Sending Requests in Parallel</a> <small>In one of my project, I have the following code (Node/Javascript) that invokes a few...</small></li>
<li><a href="https://helloacm.com/how-to-analyze-website-by-using-the-wappalyzer-chrome-extension/" rel="bookmark" title="How to Analyze Website by using the Wappalyzer (Chrome Extension)?">How to Analyze Website by using the Wappalyzer (Chrome Extension)?</a> <small>. And here is a list of technology used in this blog. And basically it...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-algorithms-to-count-houses-in-a-circular-street/" rel="bookmark" title="Teaching Kids Programming &#8211; Algorithms to Count Houses in a Circular Street">Teaching Kids Programming &#8211; Algorithms to Count Houses in a Circular Street</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given an object street...</small></li>
<li><a href="https://helloacm.com/a-tiny-logic-puzzle-about-truth-and-lies/" rel="bookmark" title="A Tiny Logic Puzzle About Truth and Lies">A Tiny Logic Puzzle About Truth and Lies</a> <small>A small village logic puzzle shows why careful reasoning matters. With 100 villagers each giving...</small></li>
<li><a href="https://helloacm.com/difference-between-product-design-interview-and-system-design-interview/" rel="bookmark" title="Difference Between Product Design Interview and System Design Interview">Difference Between Product Design Interview and System Design Interview</a> <small>In a Facebook/Meta interview (Software Engineering Roles including Site Reliability Engineers and Enterprise Engineers), the...</small></li>
<li><a href="https://helloacm.com/how-to-use-the-dynamic-link-library-in-c-linux-gcc-compiler/" rel="bookmark" title="How to Use the Dynamic Link Library in C++ Linux (gcc compiler)?">How to Use the Dynamic Link Library in C++ Linux (gcc compiler)?</a> <small>The Dynamic Link Library (DLL) is stored separately from the target application and shared among...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://helloacm.com/accidentally-deleting-over-18000-files-with-shiftdelete-recovering-data-from-a-surface-ssd-using-winfr/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Teaching Kids Programming – Minimum Number of Perfect Squares via Theorem-guided iterative deepening DFS</title>
		<link>https://helloacm.com/teaching-kids-programming-minimum-number-of-perfect-squares-via-theorem-guided-iterative-deepening-dfs/</link>
					<comments>https://helloacm.com/teaching-kids-programming-minimum-number-of-perfect-squares-via-theorem-guided-iterative-deepening-dfs/#respond</comments>
		
		<dc:creator><![CDATA[ACMer]]></dc:creator>
		<pubDate>Thu, 20 Aug 2026 09:48:05 +0000</pubDate>
				<category><![CDATA[algorithms]]></category>
		<category><![CDATA[Depth First Search]]></category>
		<category><![CDATA[Iterative Deepening Search]]></category>
		<category><![CDATA[math]]></category>
		<category><![CDATA[programming languages]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[teaching kids programming]]></category>
		<category><![CDATA[Algorithm Analysis]]></category>
		<category><![CDATA[breadth first search]]></category>
		<category><![CDATA[Coding Interview]]></category>
		<category><![CDATA[depth first search]]></category>
		<category><![CDATA[dynamic programming]]></category>
		<category><![CDATA[Iterative Deepening DFS]]></category>
		<category><![CDATA[Lagrange’s Four Square Theorem]]></category>
		<category><![CDATA[leetcode]]></category>
		<category><![CDATA[Legendre’s Three Square Theorem]]></category>
		<category><![CDATA[number theory]]></category>
		<category><![CDATA[perfect squares]]></category>
		<category><![CDATA[recursion]]></category>
		<category><![CDATA[Recursive Search]]></category>
		<category><![CDATA[Teaching Kids Programming]]></category>
		<category><![CDATA[Youtube Video]]></category>
		<guid isPermaLink="false">https://helloacm.com/?p=158009</guid>

					<description><![CDATA[<iframe width="1840" height="1035" src="https://www.youtube.com/embed/eh4kfXBE-48" title="" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

<blockquote>
This article explores an iterative-deepening recursive solution to LeetCode 279, Perfect Squares. By combining depth-limited search with Lagrange’s Four Square Theorem, we only need to test whether a number can be represented using one, two, or three perfect squares—otherwise, the answer must be four. The approach is also compared with dynamic programming, BFS, and a pure number-theory solution.

Minimum Number of Perfect Squares via Iterative Deepening DFS
Finding the Minimum Number of Perfect Squares with Iterative Deepening DFS
Perfect Squares: A Theorem-Guided Iterative Deepening Search
LeetCode 279: Perfect Squares via Depth-Limited Recursive Search
</blockquote>

<h2>LeetCode 279: Perfect Squares</h2>
Given a positive integer <code>n</code>, the problem asks us to find the minimum number of perfect squares whose sum equals <code>n</code>.

For example:

<ul>
<li><code>12 = 4 + 4 + 4</code>, so the answer is <code>3</code>.</li>
<li><code>13 = 4 + 9</code>, so the answer is <code>2</code>.</li>
<li><code>16</code> is already a perfect square, so the answer is <code>1</code>.</li>
</ul>

The standard solutions include dynamic programming and <a href="https://helloacm.com/breadth-first-search-algorithm-to-solve-puzzle-rotting-oranges-in-a-grid/" title="Breadth-First Search Algorithm to Solve Puzzle (Rotting Oranges) in a Grid">breadth-first search</a>. However, there is also a surprisingly compact approach based on depth-limited search and Lagrange’s Four Square Theorem.

<h2>The Theorem-Guided Recursive Approach</h2>

Here is the solution:

<pre lang="py">from math import isqrt

class Solution:
    def numSquares(self, n: int) -&gt; int:
        sqrs = [i * i for i in range(1, isqrt(n) + 1)]

        def f(cur, i):
            if i == 1:
                return cur in sqrs

            for x in sqrs:
                if f(cur - x, i - 1):
                    return True

            return False

        for i in range(1, 4):
            if f(n, i):
                return i

        return 4
</pre>


The solution is short, but several important ideas are packed into it.

<h2>Generating the Perfect Squares</h2>

The first line generates every positive perfect square that is no greater than <code>n</code>:


<pre lang="py">sqrs = [i * i for i in range(1, isqrt(n) + 1)]
</pre>


For example, if <code>n = 13</code>, then:


<pre lang="py">sqrs = [1, 4, 9]
</pre>


The largest possible square we need is:


<pre lang="py">isqrt(n) * isqrt(n)
</pre>


Python’s <code>isqrt()</code> returns the exact integer square root without using floating-point arithmetic. It is generally preferable to writing:


<pre lang="py">int(n ** 0.5)
</pre>


For small values of <code>n</code>, both work. However, <code>isqrt()</code> is explicit and avoids floating-point precision problems for larger integers.

<h2>What Does f(cur, i) Mean?</h2>

The <a href="https://helloacm.com/teaching-kids-programming-reachable-nodes-with-restrictions-graph-theory-depth-first-search-algorithm/" title="Teaching Kids Programming – Reachable Nodes With Restrictions (Graph Theory, Recursive Depth First Search Algorithm, Undirected/Unweighted Graph)">recursive</a> function answers a yes-or-no question:

Can <code>cur</code> be represented as the sum of exactly <code>i</code> positive perfect squares?


For example:

<ul>
<li><code>f(13, 1)</code> asks whether 13 itself is a perfect square.</li>
<li><code>f(13, 2)</code> asks whether 13 can be written as the sum of two squares.</li>
<li><code>f(12, 3)</code> asks whether 12 can be written as the sum of three squares.</li>
</ul>

When only one square remains to be selected, the problem becomes a simple membership test:


<pre lang="py">if i == 1:
    return cur in sqrs
</pre>


If <code>cur</code> is a perfect square, the required representation has been found.

Otherwise, the function chooses one square, subtracts it from the current value, and recursively tries to construct the remainder using one fewer square:


<pre lang="py">for x in sqrs:
    if f(cur - x, i - 1):
        return True
</pre>


The same square may be selected more than once because every recursive call starts iterating from the beginning of <code>sqrs</code>. This is necessary for representations such as:


<pre lang="py">12 = 4 + 4 + 4
</pre>


<h2>Why Check Only One, Two, and Three Squares?</h2>

The outer loop tests the possible answers in increasing order:


<pre lang="py">for i in range(1, 4):
    if f(n, i):
        return i
</pre>


Notice that <code>range(1, 4)</code> produces only:


<pre lang="py">1, 2, 3
</pre>


The algorithm does not search for a representation using four squares. It simply returns <code>4</code> if the first three searches fail.

This is justified by Lagrange’s Four Square Theorem:


Every positive integer can be represented as the sum of at most four integer squares.


Therefore, the answer to this problem can only be <code>1</code>, <code>2</code>, <code>3</code>, or <code>4</code>.

Because the algorithm checks the answers in increasing order, the first successful search must also be the minimum answer. If none of <code>1</code>, <code>2</code>, and <code>3</code> works, the answer must be <code>4</code>.

This theorem is not merely a small <a href="https://helloacm.com/fundamental-mathematical-formulas-for-machine-learning-optimization-argmax-reasoning-backward-from-the-future/" title="Fundamental mathematical formulas for machine learning (optimization): argmax Reasoning Backward from the Future">optimization</a>. It is the reason the recursive search has a constant maximum depth.

<h2>Example: n = 13</h2>

The algorithm first evaluates:


<pre lang="py">f(13, 1)
</pre>


Since 13 is not in <code>[1, 4, 9]</code>, the result is false.

It then evaluates:


<pre lang="py">f(13, 2)
</pre>


Suppose the loop selects <code>4</code>. The recursive call becomes:


<pre lang="py">f(13 - 4, 1)
f(9, 1)
</pre>


Since 9 is a perfect square, the function returns true. Therefore:


<pre lang="py">13 = 4 + 9
</pre>


The final answer is <code>2</code>.

<h2>Example: n = 12</h2>

The one-square search fails because 12 is not a perfect square.

The two-square search also fails because 12 cannot be represented as the sum of two perfect squares.

During the three-square search, the recursion can find:


<pre lang="py">12 - 4 = 8
8 - 4 = 4
</pre>


The remaining value, 4, is a perfect square. Therefore:


<pre lang="py">12 = 4 + 4 + 4
</pre>


The answer is <code>3</code>.

<h2>A Performance Detail: sqrs Is a List</h2>

The expression below performs a linear search because <code>sqrs</code> is a list:


<pre lang="py">cur in sqrs
</pre>


Let <code>m = floor(sqrt(n))</code>. There are <code>m</code> squares in the list.

For a three-square search, the recursion may choose two squares before reaching the membership test. In the worst case, that gives approximately:


<pre lang="py">m * m * m
</pre>


operations. The worst-case time complexity of the code as written is therefore:


<pre lang="py">O(m³) = O(n^(3/2))
</pre>


The recursion depth is never more than three, so stack usage is constant. The square list requires <code>O(sqrt(n))</code> space.

For the problem’s relatively small constraint, this compact implementation can still be practical. However, using a set makes the membership test constant-time on average.

<h2>An Improved Version</h2>

We can retain the same idea while adding a set for lookup and stopping when the selected square is already too large:


<pre lang="py">from math import isqrt

class Solution:
    def numSquares(self, n: int) -&gt; int:
        squares = [i * i for i in range(1, isqrt(n) + 1)]
        square_set = set(squares)

        def can_sum(cur, count):
            if count == 1:
                return cur in square_set

            # The remaining count - 1 squares are each at least 1.
            limit = cur - (count - 1)

            for square in squares:
                if square &gt; limit:
                    break

                if can_sum(cur - square, count - 1):
                    return True

            return False

        for count in range(1, 4):
            if can_sum(n, count):
                return count

        return 4
</pre>


The recursion still performs a depth-limited search, but the final perfect-square lookup is now <code>O(1)</code> on average.

For the three-square case, at most two nested square choices are explored. Its worst-case time complexity becomes approximately:


<pre lang="py">O(m²) = O(n)
</pre>


The pruning condition also prevents the recursion from exploring branches that cannot possibly contain enough positive squares.

<h2>Dynamic Programming</h2>

The most common general-purpose solution uses dynamic programming.

Define <code>dp[x]</code> as the minimum number of perfect squares required to sum to <code>x</code>. If the last selected square is <code>s</code>, then:


<pre lang="py">dp[x] = min(dp[x], dp[x - s] + 1)
</pre>


The complete implementation is:


<pre lang="py">from math import isqrt

class Solution:
    def numSquares(self, n: int) -&gt; int:
        squares = [i * i for i in range(1, isqrt(n) + 1)]
        dp = [0] + [float("inf")] * n

        for value in range(1, n + 1):
            for square in squares:
                if square &gt; value:
                    break

                dp[value] = min(
                    dp[value],
                    dp[value - square] + 1
                )

        return dp[n]
</pre>


For <code>n = 12</code>, some of the states are:

<ul>
<li><code>dp[1] = 1</code>, using <code>1</code>.</li>
<li><code>dp[4] = 1</code>, using <code>4</code>.</li>
<li><code>dp[8] = 2</code>, using <code>4 + 4</code>.</li>
<li><code>dp[12] = 3</code>, using <code>4 + 4 + 4</code>.</li>
</ul>

There are <code>n</code> states, and each state considers up to <code>sqrt(n)</code> squares.

The complexity is:

<ul>
<li>Time: <code>O(n sqrt(n))</code></li>
<li>Space: <code>O(n)</code></li>
</ul>

Dynamic programming does not depend on the Four Square Theorem for its correctness. It is also easier to adapt to related minimum-coin and minimum-composition problems.

<h2>Breadth-First Search</h2>

The problem can also be interpreted as an unweighted shortest-path problem.

Treat each remaining value as a graph node. From a value <code>x</code>, we can subtract any perfect square that is no greater than <code>x</code>.

For example, from 13 we can reach:


<pre lang="py">13 - 1 = 12
13 - 4 = 9
13 - 9 = 4
</pre>


Each edge represents selecting one perfect square. Therefore, the shortest distance from <code>n</code> to zero is the minimum number of squares.


<pre lang="py">from collections import deque
from math import isqrt

class Solution:
    def numSquares(self, n: int) -&gt; int:
        squares = [i * i for i in range(1, isqrt(n) + 1)]

        queue = deque([(n, 0)])
        seen = {n}

        while queue:
            remaining, depth = queue.popleft()

            for square in squares:
                if square &gt; remaining:
                    break

                next_remaining = remaining - square

                if next_remaining == 0:
                    return depth + 1

                if next_remaining not in seen:
                    seen.add(next_remaining)
                    queue.append((next_remaining, depth + 1))
</pre>


BFS explores all representations using one square before exploring representations using two squares, then three squares, and so on. The first time it reaches zero, it has found the minimum answer.

Its worst-case complexity is:

<ul>
<li>Time: <code>O(n sqrt(n))</code></li>
<li>Space: <code>O(n)</code></li>
</ul>

Conceptually, BFS and dynamic programming solve the same state-transition problem. DP fills the states numerically, while BFS explores them in increasing distance from the starting value.

<h2>A Pure Number-Theory Solution</h2>

We can go further and avoid DP, BFS, and recursive enumeration almost entirely.

The solution combines two mathematical results:

<ul>
<li>Lagrange’s Four Square Theorem guarantees that the answer is at most four.</li>
<li>Legendre’s Three Square Theorem identifies exactly when an integer cannot be represented using three squares.</li>
</ul>

Legendre’s theorem says that a positive integer cannot be represented as the sum of three integer squares precisely when it has the form:


<pre lang="py">4^a * (8b + 7)
</pre>


This gives the following implementation:


<pre lang="py">from math import isqrt

class Solution:
    def numSquares(self, n: int) -&gt; int:
        def is_square(value):
            root = isqrt(value)
            return root * root == value

        if is_square(n):
            return 1

        for a in range(1, isqrt(n) + 1):
            if is_square(n - a * a):
                return 2

        reduced = n

        while reduced % 4 == 0:
            reduced //= 4

        if reduced % 8 == 7:
            return 4

        return 3
</pre>


The logic is:

<ol>
<li>If <code>n</code> is a square, return <code>1</code>.</li>
<li>If <code>n - a²</code> is a square for some <code>a</code>, return <code>2</code>.</li>
<li>If the reduced number is congruent to 7 modulo 8, return <code>4</code>.</li>
<li>Otherwise, after excluding answers 1 and 2, the answer must be <code>3</code>.</li>
</ol>

This approach runs in <code>O(sqrt(n))</code> time and uses <code>O(1)</code> additional space. It is asymptotically the fastest solution, although it depends on mathematical theorems that do not generalize to ordinary coin-change problems.

<h2>Comparison of the Approaches</h2>

<table>
<thead>
<tr>
<th>Approach</th>
<th>Time Complexity</th>
<th>Space Complexity</th>
<th>Main Advantage</th>
</tr>
</thead>
<tbody>
<tr>
<td>Original depth-limited DFS</td>
<td><code>O(n^(3/2))</code></td>
<td><code>O(sqrt(n))</code></td>
<td>Very compact and directly uses the four-square bound</td>
</tr>
<tr>
<td>DFS with set lookup</td>
<td><code>O(n)</code></td>
<td><code>O(sqrt(n))</code></td>
<td>Preserves the elegant recursive structure</td>
</tr>
<tr>
<td>Dynamic programming</td>
<td><code>O(n sqrt(n))</code></td>
<td><code>O(n)</code></td>
<td>General and easy to adapt</td>
</tr>
<tr>
<td>Breadth-first search</td>
<td><code>O(n sqrt(n))</code></td>
<td><code>O(n)</code></td>
<td>Natural shortest-path interpretation</td>
</tr>
<tr>
<td>Number theory</td>
<td><code>O(sqrt(n))</code></td>
<td><code>O(1)</code></td>
<td>Best theoretical complexity</td>
</tr>
</tbody>
</table>

<h2>Final Thoughts</h2>

The <a href="https://helloacm.com/teaching-kids-programming-generate-binary-strings-without-adjacent-zeros-recursive-depth-first-search-algorithm/" title="Teaching Kids Programming – Generate Binary Strings Without Adjacent Zeros (Recursive Depth First Search Algorithm)">recursive</a> solution is interesting because it combines brute-force search with a strong mathematical bound. Without Lagrange’s Four Square Theorem, returning <code>4</code> after checking only three cases would be unjustified. With the theorem, the recursion never needs to go deeper than three levels.

The code is therefore better described as a theorem-guided, depth-limited search rather than unrestricted brute force.

The original implementation is already concise and readable. Its main performance weakness is that <code>cur in sqrs</code> performs a linear list search. Adding a set reduces the perfect-square test to constant time on average and lowers the worst-case search complexity substantially.

For this specific problem, the number-theory solution is the fastest. For learning reusable algorithmic patterns, however, dynamic programming and BFS are more valuable. The depth-limited recursive solution sits nicely between them: it is compact, intuitive, and demonstrates how mathematical knowledge can dramatically reduce a search space.

Day 107 on Perfect Squares using Dynamic Programming (Recursive Depth First Search Algorithm Cached)? <a href="https://helloacm.com/teaching-kids-programming-dynamic-programming-algorithms-to-compute-the-least-number-of-perfect-squares/" title="Teaching Kids Programming – Dynamic Programming Algorithms to Compute the Least Number of Perfect Squares">Teaching Kids Programming – Dynamic Programming Algorithms to Compute the Least Number of Perfect Squares</a>

[show_posts keyword="Perfect Squares"]

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --
<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/teaching-kids-programming-closest-binary-search-tree-value-recursion-inorder-binary-search-algorithm/" rel="bookmark" title="Teaching Kids Programming &#8211; Closest Binary Search Tree Value (Recursion + Inorder Traversal + Binary Search Algorithm)">Teaching Kids Programming &#8211; Closest Binary Search Tree Value (Recursion + Inorder Traversal + Binary Search Algorithm)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms Given the root of a binary...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-max-profit-of-rod-cutting-unbounded-knapsack-via-bottom-up-dynamic-programming-algorithm/" rel="bookmark" title="Teaching Kids Programming &#8211; Max Profit of Rod Cutting (Unbounded Knapsack) via Bottom Up Dynamic Programming Algorithm">Teaching Kids Programming &#8211; Max Profit of Rod Cutting (Unbounded Knapsack) via Bottom Up Dynamic Programming Algorithm</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given a list of...</small></li>
<li><a href="https://helloacm.com/coding-exercise-implement-integer-square-root-c-online-judge/" rel="bookmark" title="How to Implement Integer Square Root in C/C++?">How to Implement Integer Square Root in C/C++?</a> <small>Question: Implement integer square root for int sqrt(int x) There are many ways to compute the...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-a-light-talk-on-breadth-first-search-uniform-cost-search-and-dijkstra-shortest-path-graph-algorithms/" rel="bookmark" title="Teaching Kids Programming &#8211; A Light Talk on Breadth First Search, Uniform Cost Search and Dijkstra Shortest Path Graph Algorithms">Teaching Kids Programming &#8211; A Light Talk on Breadth First Search, Uniform Cost Search and Dijkstra Shortest Path Graph Algorithms</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms Breadth First Search Algorithm (BFS) performs...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-form-smallest-number-from-two-digit-arrays/" rel="bookmark" title="Teaching Kids Programming &#8211; Form Smallest Number From Two Digit Arrays (Set Intersection)">Teaching Kids Programming &#8211; Form Smallest Number From Two Digit Arrays (Set Intersection)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms Given two arrays of unique digits...</small></li>
<li><a href="https://helloacm.com/explaining-to-my-son-what-does-a-software-engineer-do-what-is-it-like-to-be-a-software-engineer/" rel="bookmark" title="Explaining to My Son: What Does a Software Engineer Do? What is it like to be a Software Engineer">Explaining to My Son: What Does a Software Engineer Do? What is it like to be a Software Engineer</a> <small>My son was curious and asked me: &#8220;Dad, what do you do as a software...</small></li>
<li><a href="https://helloacm.com/sql-coding-exercise-delete-duplicate-emails/" rel="bookmark" title="SQL Coding Exercise &#8211; Delete Duplicate Emails">SQL Coding Exercise &#8211; Delete Duplicate Emails</a> <small>Write a SQL query to delete all duplicate email entries in a table named Person,...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-multi-source-breadth-first-search-algorithm-minimum-number-of-moves-to-capture-the-king/" rel="bookmark" title="Teaching Kids Programming &#8211; Multi-source Breadth First Search Algorithm (Minimum Number of Moves to Capture the King)">Teaching Kids Programming &#8211; Multi-source Breadth First Search Algorithm (Minimum Number of Moves to Capture the King)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given a two-dimensional integer...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<iframe width="1840" height="1035" src="https://www.youtube.com/embed/eh4kfXBE-48" title="" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

<blockquote>
This article explores an iterative-deepening recursive solution to LeetCode 279, Perfect Squares. By combining depth-limited search with Lagrange’s Four Square Theorem, we only need to test whether a number can be represented using one, two, or three perfect squares—otherwise, the answer must be four. The approach is also compared with dynamic programming, BFS, and a pure number-theory solution.

Minimum Number of Perfect Squares via Iterative Deepening DFS
Finding the Minimum Number of Perfect Squares with Iterative Deepening DFS
Perfect Squares: A Theorem-Guided Iterative Deepening Search
LeetCode 279: Perfect Squares via Depth-Limited Recursive Search
</blockquote>

<h2>LeetCode 279: Perfect Squares</h2>
Given a positive integer <code>n</code>, the problem asks us to find the minimum number of perfect squares whose sum equals <code>n</code>.

For example:

<ul>
<li><code>12 = 4 + 4 + 4</code>, so the answer is <code>3</code>.</li>
<li><code>13 = 4 + 9</code>, so the answer is <code>2</code>.</li>
<li><code>16</code> is already a perfect square, so the answer is <code>1</code>.</li>
</ul>

The standard solutions include dynamic programming and <a href="https://helloacm.com/breadth-first-search-algorithm-to-solve-puzzle-rotting-oranges-in-a-grid/" title="Breadth-First Search Algorithm to Solve Puzzle (Rotting Oranges) in a Grid">breadth-first search</a>. However, there is also a surprisingly compact approach based on depth-limited search and Lagrange’s Four Square Theorem.

<h2>The Theorem-Guided Recursive Approach</h2>

Here is the solution:

<pre lang="py">from math import isqrt

class Solution:
    def numSquares(self, n: int) -&gt; int:
        sqrs = [i * i for i in range(1, isqrt(n) + 1)]

        def f(cur, i):
            if i == 1:
                return cur in sqrs

            for x in sqrs:
                if f(cur - x, i - 1):
                    return True

            return False

        for i in range(1, 4):
            if f(n, i):
                return i

        return 4
</pre>


The solution is short, but several important ideas are packed into it.

<h2>Generating the Perfect Squares</h2>

The first line generates every positive perfect square that is no greater than <code>n</code>:


<pre lang="py">sqrs = [i * i for i in range(1, isqrt(n) + 1)]
</pre>


For example, if <code>n = 13</code>, then:


<pre lang="py">sqrs = [1, 4, 9]
</pre>


The largest possible square we need is:


<pre lang="py">isqrt(n) * isqrt(n)
</pre>


Python’s <code>isqrt()</code> returns the exact integer square root without using floating-point arithmetic. It is generally preferable to writing:


<pre lang="py">int(n ** 0.5)
</pre>


For small values of <code>n</code>, both work. However, <code>isqrt()</code> is explicit and avoids floating-point precision problems for larger integers.

<h2>What Does f(cur, i) Mean?</h2>

The <a href="https://helloacm.com/teaching-kids-programming-reachable-nodes-with-restrictions-graph-theory-depth-first-search-algorithm/" title="Teaching Kids Programming – Reachable Nodes With Restrictions (Graph Theory, Recursive Depth First Search Algorithm, Undirected/Unweighted Graph)">recursive</a> function answers a yes-or-no question:

Can <code>cur</code> be represented as the sum of exactly <code>i</code> positive perfect squares?


For example:

<ul>
<li><code>f(13, 1)</code> asks whether 13 itself is a perfect square.</li>
<li><code>f(13, 2)</code> asks whether 13 can be written as the sum of two squares.</li>
<li><code>f(12, 3)</code> asks whether 12 can be written as the sum of three squares.</li>
</ul>

When only one square remains to be selected, the problem becomes a simple membership test:


<pre lang="py">if i == 1:
    return cur in sqrs
</pre>


If <code>cur</code> is a perfect square, the required representation has been found.

Otherwise, the function chooses one square, subtracts it from the current value, and recursively tries to construct the remainder using one fewer square:


<pre lang="py">for x in sqrs:
    if f(cur - x, i - 1):
        return True
</pre>


The same square may be selected more than once because every recursive call starts iterating from the beginning of <code>sqrs</code>. This is necessary for representations such as:


<pre lang="py">12 = 4 + 4 + 4
</pre>


<h2>Why Check Only One, Two, and Three Squares?</h2>

The outer loop tests the possible answers in increasing order:


<pre lang="py">for i in range(1, 4):
    if f(n, i):
        return i
</pre>


Notice that <code>range(1, 4)</code> produces only:


<pre lang="py">1, 2, 3
</pre>


The algorithm does not search for a representation using four squares. It simply returns <code>4</code> if the first three searches fail.

This is justified by Lagrange’s Four Square Theorem:


Every positive integer can be represented as the sum of at most four integer squares.


Therefore, the answer to this problem can only be <code>1</code>, <code>2</code>, <code>3</code>, or <code>4</code>.

Because the algorithm checks the answers in increasing order, the first successful search must also be the minimum answer. If none of <code>1</code>, <code>2</code>, and <code>3</code> works, the answer must be <code>4</code>.

This theorem is not merely a small <a href="https://helloacm.com/fundamental-mathematical-formulas-for-machine-learning-optimization-argmax-reasoning-backward-from-the-future/" title="Fundamental mathematical formulas for machine learning (optimization): argmax Reasoning Backward from the Future">optimization</a>. It is the reason the recursive search has a constant maximum depth.

<h2>Example: n = 13</h2>

The algorithm first evaluates:


<pre lang="py">f(13, 1)
</pre>


Since 13 is not in <code>[1, 4, 9]</code>, the result is false.

It then evaluates:


<pre lang="py">f(13, 2)
</pre>


Suppose the loop selects <code>4</code>. The recursive call becomes:


<pre lang="py">f(13 - 4, 1)
f(9, 1)
</pre>


Since 9 is a perfect square, the function returns true. Therefore:


<pre lang="py">13 = 4 + 9
</pre>


The final answer is <code>2</code>.

<h2>Example: n = 12</h2>

The one-square search fails because 12 is not a perfect square.

The two-square search also fails because 12 cannot be represented as the sum of two perfect squares.

During the three-square search, the recursion can find:


<pre lang="py">12 - 4 = 8
8 - 4 = 4
</pre>


The remaining value, 4, is a perfect square. Therefore:


<pre lang="py">12 = 4 + 4 + 4
</pre>


The answer is <code>3</code>.

<h2>A Performance Detail: sqrs Is a List</h2>

The expression below performs a linear search because <code>sqrs</code> is a list:


<pre lang="py">cur in sqrs
</pre>


Let <code>m = floor(sqrt(n))</code>. There are <code>m</code> squares in the list.

For a three-square search, the recursion may choose two squares before reaching the membership test. In the worst case, that gives approximately:


<pre lang="py">m * m * m
</pre>


operations. The worst-case time complexity of the code as written is therefore:


<pre lang="py">O(m³) = O(n^(3/2))
</pre>


The recursion depth is never more than three, so stack usage is constant. The square list requires <code>O(sqrt(n))</code> space.

For the problem’s relatively small constraint, this compact implementation can still be practical. However, using a set makes the membership test constant-time on average.

<h2>An Improved Version</h2>

We can retain the same idea while adding a set for lookup and stopping when the selected square is already too large:


<pre lang="py">from math import isqrt

class Solution:
    def numSquares(self, n: int) -&gt; int:
        squares = [i * i for i in range(1, isqrt(n) + 1)]
        square_set = set(squares)

        def can_sum(cur, count):
            if count == 1:
                return cur in square_set

            # The remaining count - 1 squares are each at least 1.
            limit = cur - (count - 1)

            for square in squares:
                if square &gt; limit:
                    break

                if can_sum(cur - square, count - 1):
                    return True

            return False

        for count in range(1, 4):
            if can_sum(n, count):
                return count

        return 4
</pre>


The recursion still performs a depth-limited search, but the final perfect-square lookup is now <code>O(1)</code> on average.

For the three-square case, at most two nested square choices are explored. Its worst-case time complexity becomes approximately:


<pre lang="py">O(m²) = O(n)
</pre>


The pruning condition also prevents the recursion from exploring branches that cannot possibly contain enough positive squares.

<h2>Dynamic Programming</h2>

The most common general-purpose solution uses dynamic programming.

Define <code>dp[x]</code> as the minimum number of perfect squares required to sum to <code>x</code>. If the last selected square is <code>s</code>, then:


<pre lang="py">dp[x] = min(dp[x], dp[x - s] + 1)
</pre>


The complete implementation is:


<pre lang="py">from math import isqrt

class Solution:
    def numSquares(self, n: int) -&gt; int:
        squares = [i * i for i in range(1, isqrt(n) + 1)]
        dp = [0] + [float("inf")] * n

        for value in range(1, n + 1):
            for square in squares:
                if square &gt; value:
                    break

                dp[value] = min(
                    dp[value],
                    dp[value - square] + 1
                )

        return dp[n]
</pre>


For <code>n = 12</code>, some of the states are:

<ul>
<li><code>dp[1] = 1</code>, using <code>1</code>.</li>
<li><code>dp[4] = 1</code>, using <code>4</code>.</li>
<li><code>dp[8] = 2</code>, using <code>4 + 4</code>.</li>
<li><code>dp[12] = 3</code>, using <code>4 + 4 + 4</code>.</li>
</ul>

There are <code>n</code> states, and each state considers up to <code>sqrt(n)</code> squares.

The complexity is:

<ul>
<li>Time: <code>O(n sqrt(n))</code></li>
<li>Space: <code>O(n)</code></li>
</ul>

Dynamic programming does not depend on the Four Square Theorem for its correctness. It is also easier to adapt to related minimum-coin and minimum-composition problems.

<h2>Breadth-First Search</h2>

The problem can also be interpreted as an unweighted shortest-path problem.

Treat each remaining value as a graph node. From a value <code>x</code>, we can subtract any perfect square that is no greater than <code>x</code>.

For example, from 13 we can reach:


<pre lang="py">13 - 1 = 12
13 - 4 = 9
13 - 9 = 4
</pre>


Each edge represents selecting one perfect square. Therefore, the shortest distance from <code>n</code> to zero is the minimum number of squares.


<pre lang="py">from collections import deque
from math import isqrt

class Solution:
    def numSquares(self, n: int) -&gt; int:
        squares = [i * i for i in range(1, isqrt(n) + 1)]

        queue = deque([(n, 0)])
        seen = {n}

        while queue:
            remaining, depth = queue.popleft()

            for square in squares:
                if square &gt; remaining:
                    break

                next_remaining = remaining - square

                if next_remaining == 0:
                    return depth + 1

                if next_remaining not in seen:
                    seen.add(next_remaining)
                    queue.append((next_remaining, depth + 1))
</pre>


BFS explores all representations using one square before exploring representations using two squares, then three squares, and so on. The first time it reaches zero, it has found the minimum answer.

Its worst-case complexity is:

<ul>
<li>Time: <code>O(n sqrt(n))</code></li>
<li>Space: <code>O(n)</code></li>
</ul>

Conceptually, BFS and dynamic programming solve the same state-transition problem. DP fills the states numerically, while BFS explores them in increasing distance from the starting value.

<h2>A Pure Number-Theory Solution</h2>

We can go further and avoid DP, BFS, and recursive enumeration almost entirely.

The solution combines two mathematical results:

<ul>
<li>Lagrange’s Four Square Theorem guarantees that the answer is at most four.</li>
<li>Legendre’s Three Square Theorem identifies exactly when an integer cannot be represented using three squares.</li>
</ul>

Legendre’s theorem says that a positive integer cannot be represented as the sum of three integer squares precisely when it has the form:


<pre lang="py">4^a * (8b + 7)
</pre>


This gives the following implementation:


<pre lang="py">from math import isqrt

class Solution:
    def numSquares(self, n: int) -&gt; int:
        def is_square(value):
            root = isqrt(value)
            return root * root == value

        if is_square(n):
            return 1

        for a in range(1, isqrt(n) + 1):
            if is_square(n - a * a):
                return 2

        reduced = n

        while reduced % 4 == 0:
            reduced //= 4

        if reduced % 8 == 7:
            return 4

        return 3
</pre>


The logic is:

<ol>
<li>If <code>n</code> is a square, return <code>1</code>.</li>
<li>If <code>n - a²</code> is a square for some <code>a</code>, return <code>2</code>.</li>
<li>If the reduced number is congruent to 7 modulo 8, return <code>4</code>.</li>
<li>Otherwise, after excluding answers 1 and 2, the answer must be <code>3</code>.</li>
</ol>

This approach runs in <code>O(sqrt(n))</code> time and uses <code>O(1)</code> additional space. It is asymptotically the fastest solution, although it depends on mathematical theorems that do not generalize to ordinary coin-change problems.

<h2>Comparison of the Approaches</h2>

<table>
<thead>
<tr>
<th>Approach</th>
<th>Time Complexity</th>
<th>Space Complexity</th>
<th>Main Advantage</th>
</tr>
</thead>
<tbody>
<tr>
<td>Original depth-limited DFS</td>
<td><code>O(n^(3/2))</code></td>
<td><code>O(sqrt(n))</code></td>
<td>Very compact and directly uses the four-square bound</td>
</tr>
<tr>
<td>DFS with set lookup</td>
<td><code>O(n)</code></td>
<td><code>O(sqrt(n))</code></td>
<td>Preserves the elegant recursive structure</td>
</tr>
<tr>
<td>Dynamic programming</td>
<td><code>O(n sqrt(n))</code></td>
<td><code>O(n)</code></td>
<td>General and easy to adapt</td>
</tr>
<tr>
<td>Breadth-first search</td>
<td><code>O(n sqrt(n))</code></td>
<td><code>O(n)</code></td>
<td>Natural shortest-path interpretation</td>
</tr>
<tr>
<td>Number theory</td>
<td><code>O(sqrt(n))</code></td>
<td><code>O(1)</code></td>
<td>Best theoretical complexity</td>
</tr>
</tbody>
</table>

<h2>Final Thoughts</h2>

The <a href="https://helloacm.com/teaching-kids-programming-generate-binary-strings-without-adjacent-zeros-recursive-depth-first-search-algorithm/" title="Teaching Kids Programming – Generate Binary Strings Without Adjacent Zeros (Recursive Depth First Search Algorithm)">recursive</a> solution is interesting because it combines brute-force search with a strong mathematical bound. Without Lagrange’s Four Square Theorem, returning <code>4</code> after checking only three cases would be unjustified. With the theorem, the recursion never needs to go deeper than three levels.

The code is therefore better described as a theorem-guided, depth-limited search rather than unrestricted brute force.

The original implementation is already concise and readable. Its main performance weakness is that <code>cur in sqrs</code> performs a linear list search. Adding a set reduces the perfect-square test to constant time on average and lowers the worst-case search complexity substantially.

For this specific problem, the number-theory solution is the fastest. For learning reusable algorithmic patterns, however, dynamic programming and BFS are more valuable. The depth-limited recursive solution sits nicely between them: it is compact, intuitive, and demonstrates how mathematical knowledge can dramatically reduce a search space.

Day 107 on Perfect Squares using Dynamic Programming (Recursive Depth First Search Algorithm Cached)? <a href="https://helloacm.com/teaching-kids-programming-dynamic-programming-algorithms-to-compute-the-least-number-of-perfect-squares/" title="Teaching Kids Programming – Dynamic Programming Algorithms to Compute the Least Number of Perfect Squares">Teaching Kids Programming – Dynamic Programming Algorithms to Compute the Least Number of Perfect Squares</a>

[show_posts keyword="Perfect Squares"]

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --
<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/teaching-kids-programming-closest-binary-search-tree-value-recursion-inorder-binary-search-algorithm/" rel="bookmark" title="Teaching Kids Programming &#8211; Closest Binary Search Tree Value (Recursion + Inorder Traversal + Binary Search Algorithm)">Teaching Kids Programming &#8211; Closest Binary Search Tree Value (Recursion + Inorder Traversal + Binary Search Algorithm)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms Given the root of a binary...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-max-profit-of-rod-cutting-unbounded-knapsack-via-bottom-up-dynamic-programming-algorithm/" rel="bookmark" title="Teaching Kids Programming &#8211; Max Profit of Rod Cutting (Unbounded Knapsack) via Bottom Up Dynamic Programming Algorithm">Teaching Kids Programming &#8211; Max Profit of Rod Cutting (Unbounded Knapsack) via Bottom Up Dynamic Programming Algorithm</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given a list of...</small></li>
<li><a href="https://helloacm.com/coding-exercise-implement-integer-square-root-c-online-judge/" rel="bookmark" title="How to Implement Integer Square Root in C/C++?">How to Implement Integer Square Root in C/C++?</a> <small>Question: Implement integer square root for int sqrt(int x) There are many ways to compute the...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-a-light-talk-on-breadth-first-search-uniform-cost-search-and-dijkstra-shortest-path-graph-algorithms/" rel="bookmark" title="Teaching Kids Programming &#8211; A Light Talk on Breadth First Search, Uniform Cost Search and Dijkstra Shortest Path Graph Algorithms">Teaching Kids Programming &#8211; A Light Talk on Breadth First Search, Uniform Cost Search and Dijkstra Shortest Path Graph Algorithms</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms Breadth First Search Algorithm (BFS) performs...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-form-smallest-number-from-two-digit-arrays/" rel="bookmark" title="Teaching Kids Programming &#8211; Form Smallest Number From Two Digit Arrays (Set Intersection)">Teaching Kids Programming &#8211; Form Smallest Number From Two Digit Arrays (Set Intersection)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms Given two arrays of unique digits...</small></li>
<li><a href="https://helloacm.com/explaining-to-my-son-what-does-a-software-engineer-do-what-is-it-like-to-be-a-software-engineer/" rel="bookmark" title="Explaining to My Son: What Does a Software Engineer Do? What is it like to be a Software Engineer">Explaining to My Son: What Does a Software Engineer Do? What is it like to be a Software Engineer</a> <small>My son was curious and asked me: &#8220;Dad, what do you do as a software...</small></li>
<li><a href="https://helloacm.com/sql-coding-exercise-delete-duplicate-emails/" rel="bookmark" title="SQL Coding Exercise &#8211; Delete Duplicate Emails">SQL Coding Exercise &#8211; Delete Duplicate Emails</a> <small>Write a SQL query to delete all duplicate email entries in a table named Person,...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-multi-source-breadth-first-search-algorithm-minimum-number-of-moves-to-capture-the-king/" rel="bookmark" title="Teaching Kids Programming &#8211; Multi-source Breadth First Search Algorithm (Minimum Number of Moves to Capture the King)">Teaching Kids Programming &#8211; Multi-source Breadth First Search Algorithm (Minimum Number of Moves to Capture the King)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given a two-dimensional integer...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://helloacm.com/teaching-kids-programming-minimum-number-of-perfect-squares-via-theorem-guided-iterative-deepening-dfs/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Hardening WordPress: Disable PHP Execution in `wp-content/uploads`</title>
		<link>https://helloacm.com/hardening-wordpress-disable-php-execution-in-wp-content-uploads/</link>
					<comments>https://helloacm.com/hardening-wordpress-disable-php-execution-in-wp-content-uploads/#respond</comments>
		
		<dc:creator><![CDATA[ACMer]]></dc:creator>
		<pubDate>Thu, 13 Aug 2026 14:00:01 +0000</pubDate>
				<category><![CDATA[CVE (Common Vulnerabilities and Exposures)]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[wordpress]]></category>
		<category><![CDATA[wordpress plugin]]></category>
		<category><![CDATA[wordpress shortcode]]></category>
		<category><![CDATA[.htaccess]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[bugs]]></category>
		<category><![CDATA[cloudflare]]></category>
		<category><![CDATA[CVE]]></category>
		<category><![CDATA[Defence in Depth]]></category>
		<category><![CDATA[File Upload Vulnerability]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[Security Hardening]]></category>
		<category><![CDATA[Server Security]]></category>
		<category><![CDATA[Web Shell]]></category>
		<category><![CDATA[website security]]></category>
		<guid isPermaLink="false">https://helloacm.com/?p=157998</guid>

					<description><![CDATA[[caption id="attachment_26281" align="alignnone" width="383"]<a href="https://helloacm.com/wordpress-hosting-services-you-cant-diy/wordpress-3/" rel="attachment wp-att-26281"><img src="https://helloacm.com/wp-content/uploads/2019/05/wordpress.jpg" alt="wordpress" width="383" height="367" class="size-full wp-image-26281" /></a> wordpress[/caption]

<blockquote>
WordPress must be able to write media files to `wp-content/uploads`, but files stored there should never need to execute as PHP. This article explains how to block PHP-like files using a central Apache configuration, with `.htaccess` as an additional safety net. It also compares the advantages and limitations of both methods, explains `Options -ExecCGI`, and shows how to test the protection. This hardening measure does not replace patching, but it can disrupt the common attack chain in which an upload vulnerability is turned into an executable web shell.
</blockquote>

I currently maintain eight WordPress blogs, handling almost everything myself—from server configuration and system upgrades to routine backups and security hardening. Over the past few years, I have encountered several relatively minor security incidents. Fortunately, they were detected and handled promptly, and none caused any serious damage.

Investigating, reviewing and documenting each incident has been a valuable opportunity to learn and improve. These experiences have also taught me that server security is never truly a one-off task, and years of stable operation should never become a reason for complacency. Promptly updating WordPress and its plugins, managing secrets carefully, tightening file permissions, reviewing logs and backups, and disabling PHP execution in upload directories may seem like small measures, but they can interrupt an attack chain at a critical moment. Security is ultimately an ongoing discipline that requires constant attention and improvement.

<h3>Hardening WordPress: Disable PHP Execution in `wp-content/uploads`</h3>
A normal WordPress installation needs to write media files into <code>wp-content/uploads</code>. That convenience creates an important security boundary: the directory must be writable, but files stored there should never need to execute as PHP.

If a vulnerable plugin, theme or custom upload endpoint allows an <a href="https://helloacm.com/beware-of-the-malicious-transactions-on-tron-blockchain/" title="Beware of the Malicious Transactions on TRON Blockchain">attacker</a> to place a PHP file in the uploads directory, the attacker may try to request that file through the browser. If Apache passes it to PHP, a file-upload vulnerability can become remote code execution—a web shell running with the web server's permissions.

Blocking PHP execution in <code>uploads</code> does not fix the original vulnerability, but it can break this common attack chain. It is a small, low-risk defence-in-depth measure that every WordPress server should consider alongside prompt updates, least-privilege file permissions, backups and monitoring. WordPress's own <a href="https://developer.wordpress.org/advanced-administration/security/hardening/" target="_blank" rel="noopener">hardening guidance</a> likewise treats security as a layered process rather than a single setting.

<h2>Method 1: A central Apache configuration</h2>

On my server, multiple WordPress sites live below <code>/var/www</code>, so I created the following configuration file:

<pre><code>/etc/apache2/conf-available/wordpress-uploads-no-php.conf</code></pre>

I placed this configuration inside it:

<pre><code>&lt;DirectoryMatch "^/var/www/(?:[^/]+/)*wp-content/uploads(?:/|$)"&gt;
    &lt;FilesMatch "(?i)\.(?:php[0-9]*|phtml|phar)$"&gt;
        Require all denied
    &lt;/FilesMatch&gt;
&lt;/DirectoryMatch&gt;</code></pre>

The outer <code>DirectoryMatch</code> limits the rule to WordPress upload directories under <code>/var/www</code>. It also covers the usual year-and-month subdirectories below <code>uploads</code>.

The inner <code>FilesMatch</code> checks filenames case-insensitively and denies direct HTTP access to extensions such as:

<ul>
<li><code>.php</code></li>
<li><code>.php5</code>, <code>.php7</code>, <code>.php8</code> and other numeric PHP suffixes</li>
<li><code>.phtml</code></li>
<li><code>.phar</code></li>
</ul>

<code>Require all denied</code> is the decisive instruction: matching files cannot be retrieved through Apache. Apache documents the use of <a href="https://httpd.apache.org/docs/2.4/sections.html" target="_blank" rel="noopener"><code>DirectoryMatch</code>, <code>FilesMatch</code> and <code>Require all denied</code></a> for filesystem-scoped access control.

Enable and validate the configuration:

<pre><code>a2enconf wordpress-uploads-no-php
apache2ctl configtest
systemctl reload apache2</code></pre>

Do not skip <code>configtest</code>. Apache should print:

<pre><code>Syntax OK</code></pre>

<h3>Should I add <code>Options -ExecCGI</code>?</h3>

It is reasonable as an additional precaution:

<pre><code>&lt;DirectoryMatch "^/var/www/(?:[^/]+/)*wp-content/uploads(?:/|$)"&gt;
    Options -ExecCGI

    &lt;FilesMatch "(?i)\.(?:php[0-9]*|phtml|phar)$"&gt;
        Require all denied
    &lt;/FilesMatch&gt;
&lt;/DirectoryMatch&gt;</code></pre>

<code>Options -ExecCGI</code> prevents execution through Apache's CGI mechanism. However, it does not by itself disable <a href="https://helloacm.com/php7-x-is-deprecated-by-wordpress-why-you-should-upgrade-to-php8-x/" title="PHP7.x is deprecated by WordPress: Why You Should Upgrade to PHP8.x?">PHP</a>-FPM, <code>mod_php</code> or every other possible handler. It is therefore extra hardening, not a replacement for the <code>FilesMatch</code> denial.

Apache's CGI documentation shows that <a href="https://httpd.apache.org/docs/2.4/howto/public_html.html#cgi" target="_blank" rel="noopener"><code>ExecCGI</code> is the option that permits CGI execution</a>.

<h2>Method 2: An <code>.htaccess</code> safety net</h2>

I also placed the following in each site's <code>wp-content/uploads/.htaccess</code>:

<pre><code>&lt;FilesMatch "(?i)\.(?:php[0-9]*|phtml|phar)(?:\.|$)"&gt;
    Require all denied
&lt;/FilesMatch&gt;</code></pre>

There is no <code>DirectoryMatch</code> here because an <code>.htaccess</code> file already applies to its own directory and its descendants.

Apache reads <code>.htaccess</code> files during requests, and the server's <code>AllowOverride</code> settings determine which directives they are allowed to contain. This behaviour is described in Apache's <a href="https://httpd.apache.org/docs/2.4/configuring.html#htaccess" target="_blank" rel="noopener">configuration-file documentation</a>.

This slightly stricter expression also rejects suspicious double-extension names such as:

<pre><code>shell.php.jpg
backdoor.phtml.png
payload.phar.gif</code></pre>

A correctly configured PHP handler should not execute <code>.php.jpg</code>, but an uploads directory has no legitimate reason to contain filenames with embedded executable extensions. The trade-off is that such a file will be blocked even if it is actually an image.

If adding this <code>.htaccess</code> file causes a <code>500 Internal Server Error</code>, inspect Apache's error log:

<pre><code>tail -n 50 /var/log/apache2/error.log</code></pre>

A <code>500</code> response usually means that the directive is not permitted by the applicable <code>AllowOverride</code> or <code>AllowOverrideList</code> setting.

Do not enable <code>AllowOverride All</code> merely to make this safety net work. If you control the server, use the central Apache configuration instead.

<h2>Central configuration versus <code>.htaccess</code></h2>

<table>
<thead>
<tr>
<th>Method</th>
<th>Advantages</th>
<th>Disadvantages</th>
</tr>
</thead>
<tbody>
<tr>
<td>Central Apache configuration</td>
<td>One rule can protect every site; controlled by root; independent of <code>AllowOverride</code>; harder for a compromised WordPress process to modify; generally cleaner and faster</td>
<td>Requires server administration access; changes require validation and reload; the path expression must match the actual site layout</td>
</tr>
<tr>
<td><code>.htaccess</code> inside <code>uploads</code></td>
<td>Easy per-site deployment; useful on shared hosting; takes effect without an Apache reload; provides a second copy of the rule</td>
<td>Works only when overrides are allowed; must be maintained for every site; adds per-request filesystem checks; may be deleted or altered if the application can write the directory</td>
</tr>
</tbody>
</table>

Apache notes that when overrides are enabled it may look for <code>.htaccess</code> files along the requested filesystem path, so the <a href="https://httpd.apache.org/docs/2.4/misc/perf-tuning.html#allowoverride" target="_blank" rel="noopener">central configuration is preferable for performance</a> when you control the server.

For that reason, I treat the server-level rule as the real <a href="https://helloacm.com/why-nordvpn-is-the-best-choice-for-online-privacy-and-security-in-2025/" title="Why NordVPN Is the Best Choice for Online Privacy and Security in 2025">security</a> boundary and <code>.htaccess</code> only as a secondary safety net.

<h2>Test the protection instead of assuming it works</h2>

Create a temporary test file in one site's uploads directory:

<pre><code>printf '%s\n' '&lt;?php echo "SHOULD-NOT-EXECUTE";' \
  &gt; /var/www/example.com/wp-content/uploads/security-test.php</code></pre>

Request it:

<pre><code>curl -i https://example.com/wp-content/uploads/security-test.php</code></pre>

The expected response is:

<pre><code>403 Forbidden</code></pre>

Most importantly, the text <code>SHOULD-NOT-EXECUTE</code> must never appear.

Also check that a normal existing JPEG or PNG in the same directory is still accessible:

<pre><code>curl -I https://example.com/wp-content/uploads/path/to/existing-image.jpg</code></pre>

Remove the test file immediately:

<pre><code>rm /var/www/example.com/wp-content/uploads/security-test.php</code></pre>

Repeat the test after meaningful Apache, PHP-FPM or virtual-host configuration changes. Security controls that have not been tested are assumptions, not controls.

<h2>What this protection does not do</h2>

This measure deliberately has a narrow purpose. It does not:

<ul>
<li>patch WordPress, themes or plugins;</li>
<li>prevent a vulnerable application from writing a malicious file;</li>
<li>stop malicious code that is already executing through another PHP file;</li>
<li>prevent a plugin from loading a file locally with PHP's <code>include</code> or <code>require</code>;</li>
<li>replace malware scanning, log review, backups or proper filesystem permissions.</li>
</ul>

It blocks direct web access to dangerous filenames in a directory intended only for static media. That may be enough to stop a basic uploaded web shell, but it is not proof that the site is clean after a compromise.

<h2>Final recommendation</h2>

If you administer Apache yourself, use the central configuration as the primary control. Add <code>Options -ExecCGI</code> as harmless defence-in-depth where no CGI execution is legitimately required.

Keep the <code>.htaccess</code> rule only as an additional layer when overrides are already enabled—never weaken the server configuration just to support it.

Most importantly, continue updating WordPress core, themes and plugins promptly. Disabling execution in <code>uploads</code> reduces the blast radius of one attack path; it does not remove the vulnerability that allowed the upload in the first place.

[show_file file="/var/www/wp-post-common/helloacm.com/wordpress.php"]

[show_posts keyword="wordpress"]

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/laptop-battery-power-drained-but-failed-to-sleep-on-microsoft-windows-surface-studio-pro/" rel="bookmark" title="Laptop Battery Power Drained But Failed to Sleep on Microsoft Windows Surface Studio Pro">Laptop Battery Power Drained But Failed to Sleep on Microsoft Windows Surface Studio Pro</a> <small>I am surprised to find out that my laptop is switched off this morning &#8211;...</small></li>
<li><a href="https://helloacm.com/microsoft-edge-settings-that-may-be-slowing-down-your-windows-pc/" rel="bookmark" title="Microsoft Edge Settings That May Be Slowing Down Your Windows PC">Microsoft Edge Settings That May Be Slowing Down Your Windows PC</a> <small>This article explains how disabling Microsoft Edge’s Startup boost and background extensions can make Windows...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-most-common-sql-keywords-select-update-insert-delete/" rel="bookmark" title="Teaching Kids Programming &#8211; Most Common SQL keywords (Select, Update, Insert, Delete)">Teaching Kids Programming &#8211; Most Common SQL keywords (Select, Update, Insert, Delete)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms Here are a few SQL keywords...</small></li>
<li><a href="https://helloacm.com/how-to-find-largest-value-in-each-tree-row-level-using-bfs-or-dfs-algorithm/" rel="bookmark" title="How to Find Largest Value in Each Tree Row/Level using BFS or DFS Algorithm?">How to Find Largest Value in Each Tree Row/Level using BFS or DFS Algorithm?</a> <small>You need to find the largest value in each row of a binary tree. Example:...</small></li>
<li><a href="https://helloacm.com/a-five-year-milestone-at-microsoft-anniversary-crystal/" rel="bookmark" title="A Five-Year Milestone at Microsoft (Anniversary Crystal)">A Five-Year Milestone at Microsoft (Anniversary Crystal)</a> <small>To mark my fifth anniversary at Microsoft, I received a meaningful crystal service award. Over...</small></li>
<li><a href="https://helloacm.com/turning-a-dusty-mini-pc-into-a-home-server-my-nuc-8s-second-life/" rel="bookmark" title="Turning a Dusty Mini PC into a Home Server: My NUC-8’s Second Life">Turning a Dusty Mini PC into a Home Server: My NUC-8’s Second Life</a> <small>I gave an unused Beelink SEi8 mini PC a second life by installing Ubuntu and...</small></li>
<li><a href="https://helloacm.com/c-coding-reference-copy-n-values-by-using-stdfill_n/" rel="bookmark" title="C++ Coding Reference: Copy N values by using std::fill_n()">C++ Coding Reference: Copy N values by using std::fill_n()</a> <small>We talked about std::fill() that we can use to copy over a single value to...</small></li>
<li><a href="https://helloacm.com/using-absolute-keyword-in-delphi-to-remove-unnecessary-assignment-function/" rel="bookmark" title="Using Absolute Keyword in Delphi to Remove Unnecessary Assignment Function">Using Absolute Keyword in Delphi to Remove Unnecessary Assignment Function</a> <small>The Delphi/Object Pascal provides a keyword absolute, which you can also find examples at this...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[[caption id="attachment_26281" align="alignnone" width="383"]<a href="https://helloacm.com/wordpress-hosting-services-you-cant-diy/wordpress-3/" rel="attachment wp-att-26281"><img src="https://helloacm.com/wp-content/uploads/2019/05/wordpress.jpg" alt="wordpress" width="383" height="367" class="size-full wp-image-26281" /></a> wordpress[/caption]

<blockquote>
WordPress must be able to write media files to `wp-content/uploads`, but files stored there should never need to execute as PHP. This article explains how to block PHP-like files using a central Apache configuration, with `.htaccess` as an additional safety net. It also compares the advantages and limitations of both methods, explains `Options -ExecCGI`, and shows how to test the protection. This hardening measure does not replace patching, but it can disrupt the common attack chain in which an upload vulnerability is turned into an executable web shell.
</blockquote>

I currently maintain eight WordPress blogs, handling almost everything myself—from server configuration and system upgrades to routine backups and security hardening. Over the past few years, I have encountered several relatively minor security incidents. Fortunately, they were detected and handled promptly, and none caused any serious damage.

Investigating, reviewing and documenting each incident has been a valuable opportunity to learn and improve. These experiences have also taught me that server security is never truly a one-off task, and years of stable operation should never become a reason for complacency. Promptly updating WordPress and its plugins, managing secrets carefully, tightening file permissions, reviewing logs and backups, and disabling PHP execution in upload directories may seem like small measures, but they can interrupt an attack chain at a critical moment. Security is ultimately an ongoing discipline that requires constant attention and improvement.

<h3>Hardening WordPress: Disable PHP Execution in `wp-content/uploads`</h3>
A normal WordPress installation needs to write media files into <code>wp-content/uploads</code>. That convenience creates an important security boundary: the directory must be writable, but files stored there should never need to execute as PHP.

If a vulnerable plugin, theme or custom upload endpoint allows an <a href="https://helloacm.com/beware-of-the-malicious-transactions-on-tron-blockchain/" title="Beware of the Malicious Transactions on TRON Blockchain">attacker</a> to place a PHP file in the uploads directory, the attacker may try to request that file through the browser. If Apache passes it to PHP, a file-upload vulnerability can become remote code execution—a web shell running with the web server's permissions.

Blocking PHP execution in <code>uploads</code> does not fix the original vulnerability, but it can break this common attack chain. It is a small, low-risk defence-in-depth measure that every WordPress server should consider alongside prompt updates, least-privilege file permissions, backups and monitoring. WordPress's own <a href="https://developer.wordpress.org/advanced-administration/security/hardening/" target="_blank" rel="noopener">hardening guidance</a> likewise treats security as a layered process rather than a single setting.

<h2>Method 1: A central Apache configuration</h2>

On my server, multiple WordPress sites live below <code>/var/www</code>, so I created the following configuration file:

<pre><code>/etc/apache2/conf-available/wordpress-uploads-no-php.conf</code></pre>

I placed this configuration inside it:

<pre><code>&lt;DirectoryMatch "^/var/www/(?:[^/]+/)*wp-content/uploads(?:/|$)"&gt;
    &lt;FilesMatch "(?i)\.(?:php[0-9]*|phtml|phar)$"&gt;
        Require all denied
    &lt;/FilesMatch&gt;
&lt;/DirectoryMatch&gt;</code></pre>

The outer <code>DirectoryMatch</code> limits the rule to WordPress upload directories under <code>/var/www</code>. It also covers the usual year-and-month subdirectories below <code>uploads</code>.

The inner <code>FilesMatch</code> checks filenames case-insensitively and denies direct HTTP access to extensions such as:

<ul>
<li><code>.php</code></li>
<li><code>.php5</code>, <code>.php7</code>, <code>.php8</code> and other numeric PHP suffixes</li>
<li><code>.phtml</code></li>
<li><code>.phar</code></li>
</ul>

<code>Require all denied</code> is the decisive instruction: matching files cannot be retrieved through Apache. Apache documents the use of <a href="https://httpd.apache.org/docs/2.4/sections.html" target="_blank" rel="noopener"><code>DirectoryMatch</code>, <code>FilesMatch</code> and <code>Require all denied</code></a> for filesystem-scoped access control.

Enable and validate the configuration:

<pre><code>a2enconf wordpress-uploads-no-php
apache2ctl configtest
systemctl reload apache2</code></pre>

Do not skip <code>configtest</code>. Apache should print:

<pre><code>Syntax OK</code></pre>

<h3>Should I add <code>Options -ExecCGI</code>?</h3>

It is reasonable as an additional precaution:

<pre><code>&lt;DirectoryMatch "^/var/www/(?:[^/]+/)*wp-content/uploads(?:/|$)"&gt;
    Options -ExecCGI

    &lt;FilesMatch "(?i)\.(?:php[0-9]*|phtml|phar)$"&gt;
        Require all denied
    &lt;/FilesMatch&gt;
&lt;/DirectoryMatch&gt;</code></pre>

<code>Options -ExecCGI</code> prevents execution through Apache's CGI mechanism. However, it does not by itself disable <a href="https://helloacm.com/php7-x-is-deprecated-by-wordpress-why-you-should-upgrade-to-php8-x/" title="PHP7.x is deprecated by WordPress: Why You Should Upgrade to PHP8.x?">PHP</a>-FPM, <code>mod_php</code> or every other possible handler. It is therefore extra hardening, not a replacement for the <code>FilesMatch</code> denial.

Apache's CGI documentation shows that <a href="https://httpd.apache.org/docs/2.4/howto/public_html.html#cgi" target="_blank" rel="noopener"><code>ExecCGI</code> is the option that permits CGI execution</a>.

<h2>Method 2: An <code>.htaccess</code> safety net</h2>

I also placed the following in each site's <code>wp-content/uploads/.htaccess</code>:

<pre><code>&lt;FilesMatch "(?i)\.(?:php[0-9]*|phtml|phar)(?:\.|$)"&gt;
    Require all denied
&lt;/FilesMatch&gt;</code></pre>

There is no <code>DirectoryMatch</code> here because an <code>.htaccess</code> file already applies to its own directory and its descendants.

Apache reads <code>.htaccess</code> files during requests, and the server's <code>AllowOverride</code> settings determine which directives they are allowed to contain. This behaviour is described in Apache's <a href="https://httpd.apache.org/docs/2.4/configuring.html#htaccess" target="_blank" rel="noopener">configuration-file documentation</a>.

This slightly stricter expression also rejects suspicious double-extension names such as:

<pre><code>shell.php.jpg
backdoor.phtml.png
payload.phar.gif</code></pre>

A correctly configured PHP handler should not execute <code>.php.jpg</code>, but an uploads directory has no legitimate reason to contain filenames with embedded executable extensions. The trade-off is that such a file will be blocked even if it is actually an image.

If adding this <code>.htaccess</code> file causes a <code>500 Internal Server Error</code>, inspect Apache's error log:

<pre><code>tail -n 50 /var/log/apache2/error.log</code></pre>

A <code>500</code> response usually means that the directive is not permitted by the applicable <code>AllowOverride</code> or <code>AllowOverrideList</code> setting.

Do not enable <code>AllowOverride All</code> merely to make this safety net work. If you control the server, use the central Apache configuration instead.

<h2>Central configuration versus <code>.htaccess</code></h2>

<table>
<thead>
<tr>
<th>Method</th>
<th>Advantages</th>
<th>Disadvantages</th>
</tr>
</thead>
<tbody>
<tr>
<td>Central Apache configuration</td>
<td>One rule can protect every site; controlled by root; independent of <code>AllowOverride</code>; harder for a compromised WordPress process to modify; generally cleaner and faster</td>
<td>Requires server administration access; changes require validation and reload; the path expression must match the actual site layout</td>
</tr>
<tr>
<td><code>.htaccess</code> inside <code>uploads</code></td>
<td>Easy per-site deployment; useful on shared hosting; takes effect without an Apache reload; provides a second copy of the rule</td>
<td>Works only when overrides are allowed; must be maintained for every site; adds per-request filesystem checks; may be deleted or altered if the application can write the directory</td>
</tr>
</tbody>
</table>

Apache notes that when overrides are enabled it may look for <code>.htaccess</code> files along the requested filesystem path, so the <a href="https://httpd.apache.org/docs/2.4/misc/perf-tuning.html#allowoverride" target="_blank" rel="noopener">central configuration is preferable for performance</a> when you control the server.

For that reason, I treat the server-level rule as the real <a href="https://helloacm.com/why-nordvpn-is-the-best-choice-for-online-privacy-and-security-in-2025/" title="Why NordVPN Is the Best Choice for Online Privacy and Security in 2025">security</a> boundary and <code>.htaccess</code> only as a secondary safety net.

<h2>Test the protection instead of assuming it works</h2>

Create a temporary test file in one site's uploads directory:

<pre><code>printf '%s\n' '&lt;?php echo "SHOULD-NOT-EXECUTE";' \
  &gt; /var/www/example.com/wp-content/uploads/security-test.php</code></pre>

Request it:

<pre><code>curl -i https://example.com/wp-content/uploads/security-test.php</code></pre>

The expected response is:

<pre><code>403 Forbidden</code></pre>

Most importantly, the text <code>SHOULD-NOT-EXECUTE</code> must never appear.

Also check that a normal existing JPEG or PNG in the same directory is still accessible:

<pre><code>curl -I https://example.com/wp-content/uploads/path/to/existing-image.jpg</code></pre>

Remove the test file immediately:

<pre><code>rm /var/www/example.com/wp-content/uploads/security-test.php</code></pre>

Repeat the test after meaningful Apache, PHP-FPM or virtual-host configuration changes. Security controls that have not been tested are assumptions, not controls.

<h2>What this protection does not do</h2>

This measure deliberately has a narrow purpose. It does not:

<ul>
<li>patch WordPress, themes or plugins;</li>
<li>prevent a vulnerable application from writing a malicious file;</li>
<li>stop malicious code that is already executing through another PHP file;</li>
<li>prevent a plugin from loading a file locally with PHP's <code>include</code> or <code>require</code>;</li>
<li>replace malware scanning, log review, backups or proper filesystem permissions.</li>
</ul>

It blocks direct web access to dangerous filenames in a directory intended only for static media. That may be enough to stop a basic uploaded web shell, but it is not proof that the site is clean after a compromise.

<h2>Final recommendation</h2>

If you administer Apache yourself, use the central configuration as the primary control. Add <code>Options -ExecCGI</code> as harmless defence-in-depth where no CGI execution is legitimately required.

Keep the <code>.htaccess</code> rule only as an additional layer when overrides are already enabled—never weaken the server configuration just to support it.

Most importantly, continue updating WordPress core, themes and plugins promptly. Disabling execution in <code>uploads</code> reduces the blast radius of one attack path; it does not remove the vulnerability that allowed the upload in the first place.

[show_file file="/var/www/wp-post-common/helloacm.com/wordpress.php"]

[show_posts keyword="wordpress"]

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/laptop-battery-power-drained-but-failed-to-sleep-on-microsoft-windows-surface-studio-pro/" rel="bookmark" title="Laptop Battery Power Drained But Failed to Sleep on Microsoft Windows Surface Studio Pro">Laptop Battery Power Drained But Failed to Sleep on Microsoft Windows Surface Studio Pro</a> <small>I am surprised to find out that my laptop is switched off this morning &#8211;...</small></li>
<li><a href="https://helloacm.com/microsoft-edge-settings-that-may-be-slowing-down-your-windows-pc/" rel="bookmark" title="Microsoft Edge Settings That May Be Slowing Down Your Windows PC">Microsoft Edge Settings That May Be Slowing Down Your Windows PC</a> <small>This article explains how disabling Microsoft Edge’s Startup boost and background extensions can make Windows...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-most-common-sql-keywords-select-update-insert-delete/" rel="bookmark" title="Teaching Kids Programming &#8211; Most Common SQL keywords (Select, Update, Insert, Delete)">Teaching Kids Programming &#8211; Most Common SQL keywords (Select, Update, Insert, Delete)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms Here are a few SQL keywords...</small></li>
<li><a href="https://helloacm.com/how-to-find-largest-value-in-each-tree-row-level-using-bfs-or-dfs-algorithm/" rel="bookmark" title="How to Find Largest Value in Each Tree Row/Level using BFS or DFS Algorithm?">How to Find Largest Value in Each Tree Row/Level using BFS or DFS Algorithm?</a> <small>You need to find the largest value in each row of a binary tree. Example:...</small></li>
<li><a href="https://helloacm.com/a-five-year-milestone-at-microsoft-anniversary-crystal/" rel="bookmark" title="A Five-Year Milestone at Microsoft (Anniversary Crystal)">A Five-Year Milestone at Microsoft (Anniversary Crystal)</a> <small>To mark my fifth anniversary at Microsoft, I received a meaningful crystal service award. Over...</small></li>
<li><a href="https://helloacm.com/turning-a-dusty-mini-pc-into-a-home-server-my-nuc-8s-second-life/" rel="bookmark" title="Turning a Dusty Mini PC into a Home Server: My NUC-8’s Second Life">Turning a Dusty Mini PC into a Home Server: My NUC-8’s Second Life</a> <small>I gave an unused Beelink SEi8 mini PC a second life by installing Ubuntu and...</small></li>
<li><a href="https://helloacm.com/c-coding-reference-copy-n-values-by-using-stdfill_n/" rel="bookmark" title="C++ Coding Reference: Copy N values by using std::fill_n()">C++ Coding Reference: Copy N values by using std::fill_n()</a> <small>We talked about std::fill() that we can use to copy over a single value to...</small></li>
<li><a href="https://helloacm.com/using-absolute-keyword-in-delphi-to-remove-unnecessary-assignment-function/" rel="bookmark" title="Using Absolute Keyword in Delphi to Remove Unnecessary Assignment Function">Using Absolute Keyword in Delphi to Remove Unnecessary Assignment Function</a> <small>The Delphi/Object Pascal provides a keyword absolute, which you can also find examples at this...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://helloacm.com/hardening-wordpress-disable-php-execution-in-wp-content-uploads/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Turning a Dusty Mini PC into a Home Server: My NUC-8’s Second Life</title>
		<link>https://helloacm.com/turning-a-dusty-mini-pc-into-a-home-server-my-nuc-8s-second-life/</link>
					<comments>https://helloacm.com/turning-a-dusty-mini-pc-into-a-home-server-my-nuc-8s-second-life/#respond</comments>
		
		<dc:creator><![CDATA[ACMer]]></dc:creator>
		<pubDate>Sat, 08 Aug 2026 17:06:07 +0000</pubDate>
				<category><![CDATA[Home Network Topology]]></category>
		<category><![CDATA[Next Unit of Computing]]></category>
		<category><![CDATA[Beelink SEi8]]></category>
		<category><![CDATA[Cloudflare Tunnel]]></category>
		<category><![CDATA[computing]]></category>
		<category><![CDATA[Double NAT]]></category>
		<category><![CDATA[Hardware Repurposing]]></category>
		<category><![CDATA[Home Networking]]></category>
		<category><![CDATA[Home Server]]></category>
		<category><![CDATA[Home Servers]]></category>
		<category><![CDATA[Intranet]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[Local Network]]></category>
		<category><![CDATA[Mini PC]]></category>
		<category><![CDATA[NUC]]></category>
		<category><![CDATA[NUC-8]]></category>
		<category><![CDATA[raspberry pi]]></category>
		<category><![CDATA[steem]]></category>
		<category><![CDATA[ubuntu]]></category>
		<guid isPermaLink="false">https://helloacm.com/?p=157963</guid>

					<description><![CDATA[<blockquote>
I gave an unused Beelink SEi8 mini PC a second life by installing Ubuntu and turning it into a home server. It now runs a STEEM node, Node.js applications, databases, a reverse proxy and Cloudflare Tunnel. The article also explains how double NAT allows the NUC-8 to initiate connections to my Raspberry Pis while preventing connections in the opposite direction, as well as covering home broadband, hardware reuse and cooling considerations.
</blockquote>

<h3>Turning a Dusty Mini PC into a Home Server: My NUC-8’s Second Life</h3>
During the second half of last year, I dug out a mini PC that had been gathering dust at home, installed <a href="https://helloacm.com/how-to-setup-hhvm-on-the-ubuntu-vps/" title="How to Setup HHVM on the Ubuntu VPS?">Ubuntu</a> 24.04.4 LTS on it, and placed it inside the shoe cupboard by our front door. It has been serving as my home server ever since.

I usually call it my “NUC-8”, although, strictly speaking, it is not an Intel NUC. It is a Beelink SEi8 mini PC that I bought from Amazon on 25 April 2021 for £466.65. Its specifications are as follows:

Beelink Mini PC SEI8, Intel Core i5-8259U <a href="https://helloacm.com/why-parallelism-isnt-infinite-amdahl-vs-gustafson-explained-simply/" title="Why Parallelism Isn’t Infinite: Amdahl vs Gustafson Explained Simply">processor</a> running at up to 3.8GHz, 16GB of DDR4 memory, a 512GB NVMe SSD, Intel Iris Plus Graphics 655, Wi-Fi 6 and Bluetooth 5.0.

<h3>From a Windows Mini PC to an Unused Computer</h3>

The machine came with Windows 10 Pro pre-installed. Its specifications looked perfectly respectable, but in everyday use it always felt rather slow and never quite met my expectations. I later put it in Eric’s room, where he used it for more than six months. After I replaced it with a MacBook Air for him, the little PC gradually became redundant and ended up gathering dust.

The awkward thing about mini PCs (<a href="https://helloacm.com/teaching-kids-programming-introduction-to-units-of-information-byte-kb-mb-gb-tb-pb/" title="Teaching Kids Programming – Introduction to Units of Information (Byte, KB, MB, GB, TB, PB)">Next Unit of Computing</a>) like this is not that they are genuinely underpowered. They simply do not stand out as everyday desktop computers. Compared with a newer laptop, the responsiveness, graphics performance and overall experience can feel fairly ordinary. Throwing one away, however, would be a terrible waste. A four-core, eight-thread processor, 16GB of memory and a 512GB NVMe SSD are still more than capable of running Linux and a collection of always-on services.

So, during the second half of last year, I decided to give it a different purpose.

<h3>Linux Brought It Back to Life</h3>

After I installed Ubuntu 24.04.4 LTS, the computer almost felt as though it had come back to life. Without lots of unnecessary desktop software and background services, the whole system ran remarkably smoothly. As a server, its hardware is far from obsolete and still has plenty of capacity to spare.

Over the past year, I have gradually deployed quite a few things on it.

Later, I also dug out a 2TB <a href="https://helloacm.com/turn-your-raspberry-pi-into-a-family-network-drive-2tb-wd-hard-drive-setup-for-kids-macs/" title="Turn Your Raspberry Pi into a Family Network Drive: 2TB WD Hard Drive Setup for Kids’ Macs">hard drive</a> that had been sitting unused and gathering dust. I installed it in a USB enclosure and connected it to the NUC-8. It uses the ext3 file system and is used mainly to store data for the STEEM blockchain node. The Raspberry Pi 4B also has an external 1TB 2.5-inch USB SSD, which I use to provide file sharing across the home network.

At one point, I used it to run a STEEM witness node. I also configured a reverse proxy and used Cloudflare Tunnel to expose services from my home network securely to the internet. In addition, I use PM2 to keep a Node.js bot running continuously. The bot monitors transactions on the blockchain and writes the relevant data into a <a href="https://helloacm.com/improve-multithreading-performance-of-sqlite-database-by-wal-write-ahead-logging/" title="Improve Multithreading Performance of Sqlite Database by WAL (Write Ahead Logging)">database</a>.

When writing code, I often connect to the server over the local network using VS Code Remote SSH. I can compile and run C++ programs, test scripts, or deploy small services that need to remain online. Compared with a Raspberry Pi, the i5 processor, 16GB of memory and NVMe storage make a very noticeable difference, particularly when compiling code or working with databases.

This once-forgotten mini PC (<a href="https://helloacm.com/all-in-one-raspberry-pi-400-kit-personal-computer-kit-with-raspbian-os/" title="NUC: All-In-One Raspberry PI 400 Kit – Personal Computer Kit with Raspbian OS">NUC</a>) has now been running inside the shoe cupboard for nearly a year, and it has proved remarkably stable.

<h3>A Home Network Finally Good Enough for the Server</h3>

I recently upgraded our home broadband to full fibre. The theoretical download speed is 900Mbps, while the upload speed is 110Mbps. That is more than adequate for running a small server at home.

Of course, when services hosted at home are being accessed from the public internet, the important figure is the 110Mbps upload speed, not the 900Mbps download speed. Even so, 110Mbps provides ample capacity for a personal website, APIs, remote administration and the other lightweight services I currently run. Cloudflare Tunnel also helps: the server establishes an outbound connection to Cloudflare, so I do not need to wrestle with public IP addresses and port forwarding across two routers. It continues to work even though my home network uses double NAT.

<h3>Why Can the NUC-8 Reach the Raspberry Pis, but Not the Other Way Around?</h3>

My home network has a slightly unusual layout.

[caption id="attachment_157968" align="alignnone" width="1546"]<a href="https://helloacm.com/turning-a-dusty-mini-pc-into-a-home-server-my-nuc-8s-second-life/home-network-topology-setup/" rel="attachment wp-att-157968"><img src="https://helloacm.com/wp-content/uploads/2026/08/home-network-topology-setup.jpg" alt="My Current Home Network Topology" width="1546" height="921" class="size-full wp-image-157968" /></a> My Current Home Network Topology[/caption]

<pre lang="mermaid">
flowchart TB
    Internet(("Internet"))

    subgraph PL["Plusnet LAN — upstream subnet"]
        Hub["Plusnet Hub 2&lt;br/&gt;Router and NAT"]
        Pi4["Raspberry Pi 4B&lt;br/&gt;Connected directly to Hub 2"]

        Hub &lt;--&gt;|Direct connection| Pi4
    end

    subgraph DL["Deco LAN — downstream subnet"]
        Deco1["Deco 1 — Primary&lt;br/&gt;Router, NAT and firewall"]
        Deco2["Deco 2 — Mesh node&lt;br/&gt;Upstairs office — bedroom"]
        Deco3["Deco 3 — Mesh node&lt;br/&gt;Study room — former garage"]
        NUC["NUC-8 / Beelink SEi8&lt;br/&gt;Ubuntu home server"]
        Pi1["Raspberry Pi Model B Rev 2&lt;br/&gt;~475 MB RAM"]

        Deco1 &lt;--&gt;|Ethernet| NUC
        Deco1 -.-|Wireless mesh| Deco2
        Deco1 -.-|Wireless mesh| Deco3
        Deco3 &lt;--&gt;|Ethernet| Pi1
    end

    Internet &lt;--&gt; Hub
    Hub &lt;--&gt;|Ethernet to Deco WAN| Deco1
</pre>

The Plusnet router is the primary upstream router. Two Raspberry Pis: an old Raspberry Pi Model B Rev 2 with only about 475MB of memory connects to a secondary Deco Router (Wirless Mesh Node), and a Raspberry Pi 4B with 4GB of memory connects directly to the PlusNet Hub 2 Router via Ethernet Cable (RJ45).

The Deco is connected to the Plusnet router but continues to operate in router mode rather than bridge or access point mode. The NUC-8 is connected to the Deco by Ethernet. As a result, the Plusnet router and the Deco each create a separate local subnet. For example, the Raspberry Pis might be on the 192.168.1.x network, while the NUC-8 is on the 192.168.68.x network managed by the Deco.

This creates the common home-networking arrangement known as double NAT.

When the NUC-8 initiates a connection to one of the Raspberry Pis, the traffic travels from the Deco’s internal network towards its upstream interface. The Deco uses NAT to translate the connection to its own upstream address and records the request in its connection-tracking table. When the Raspberry Pi replies, the Deco can therefore translate and forward the response back to the NUC-8. Communication initiated in this direction works normally.

Things are different when a Raspberry Pi attempts to initiate a connection to the NUC-8. The Plusnet network normally has no route telling it how to reach the 192.168.68.x subnet. Even if a request reaches the Deco’s upstream interface, the Deco firewall treats it as an unsolicited inbound connection arriving from its WAN side. With no corresponding entry in the connection-tracking table, the request is blocked by default rather than forwarded to the NUC-8.

The traffic is therefore not literally limited to one-way communication. The real difference is which side is allowed to initiate a new connection. Once the NUC-8 has initiated one, replies from a Raspberry Pi can travel back along the established path. A Raspberry Pi, however, cannot simply open a new connection to the NUC-8.

The NUC-8 server and the Raspberry B model rev 2  cannot be seen from Raspberry Pi 4b.

<blockquote>
From 192.168.1.XXX icmp_seq=460 Destination Host Unreachable
</blockquote>

If I wanted all three computers to communicate with one another directly, the simplest solution would be to switch the Deco to access point mode, or connect both Raspberry Pis to the Deco so that every device belonged to the same subnet. A more advanced but considerably more complicated approach would be to add a static route on the Plusnet router pointing to the Deco, then adjust the Deco’s NAT and firewall rules accordingly. Many consumer routers do not fully support this type of configuration. If I needed access to only a few services on the NUC-8, I could instead configure port forwarding on the Deco, although that would be less clean and more cumbersome to manage than using a single subnet.

<h3>A Second Life for an Old Computer</h3>

Looking back, this mini PC cost me £466.65 in 2021 and never made a particularly strong impression as a Windows desktop. A few years later, however, it found a role that suited it much better: a Linux home server.

It is compact, its <a href="https://helloacm.com/big-data-case-study-tv-usage-and-power-consumption/" title="Big Data Case Study: TV Usage and Power Consumption">power consumption</a> is reasonably modest, and its performance is far better than that of an ordinary Raspberry Pi. It can comfortably run a blockchain node, a database, Node.js services, a reverse proxy and a development environment. Since upgrading to full-fibre broadband, the whole setup has become even more useful.

The one thing I must keep in mind is that a shoe cupboard is not a proper server room. Running reliably for nearly a year is encouraging, but it is no substitute for monitoring temperatures and storage health. The cupboard needs adequate ventilation, the air intake should be cleaned regularly, and I should keep an eye on the CPU temperature and the SSD’s SMART data. Otherwise, heat could cause the machine to throttle or shorten the life of its components.

For me, the most satisfying part of this project is not merely that it saved me from buying another server. It gave a neglected computer a useful purpose again. The machine sits quietly inside the cupboard by the front door, almost invisible in everyday life, yet it is constantly running nodes, processing data, hosting services and supporting whatever small project happens to occur to me next.

That, perhaps, is the most enjoyable thing about running a home server if you like experimenting with technology. You do not necessarily need an expensive rack, a dedicated server room or even the latest hardware. A forgotten old computer, Linux, a reliable network connection and a little patience are enough to build a small home lab of your own.

[caption id="attachment_157970" align="alignnone" width="953"]<a href="https://helloacm.com/turning-a-dusty-mini-pc-into-a-home-server-my-nuc-8s-second-life/beelink-mini-pc-nuc-8-16gb/" rel="attachment wp-att-157970"><img src="https://helloacm.com/wp-content/uploads/2026/08/beelink-mini-pc-nuc-8-16gb.jpg" alt="Beelink Mini PC - Order from Amazon - 2021" width="953" height="517" class="size-full wp-image-157970" /></a> Beelink Mini PC - Order from Amazon - 2021[/caption]

[caption id="attachment_157972" align="alignnone" width="864"]<a href="https://helloacm.com/turning-a-dusty-mini-pc-into-a-home-server-my-nuc-8s-second-life/home-servers-in-shoe-closet-2025-11-07-18-51-24/" rel="attachment wp-att-157972"><img src="https://helloacm.com/wp-content/uploads/2026/08/home-servers-in-shoe-closet-2025-11-07-18.51.24.jpg" alt="Two Servers (Raspberry Pi 4b - and NUC-8 beelink) in the shoe closet" width="864" height="1536" class="size-full wp-image-157972" /></a> Two Servers (Raspberry Pi 4b - and NUC-8 beelink) in the shoe closet[/caption]

[caption id="attachment_157973" align="alignnone" width="1536"]<a href="https://helloacm.com/turning-a-dusty-mini-pc-into-a-home-server-my-nuc-8s-second-life/nuc8-beelink-server-2025-11-07-08-35-34/" rel="attachment wp-att-157973"><img src="https://helloacm.com/wp-content/uploads/2026/08/nuc8-beelink-server-2025-11-07-08.35.34-rotated.jpg" alt="Reconnect the NUC-8" width="1536" height="864" class="size-full wp-image-157973" /></a> Reconnect the NUC-8[/caption]

[caption id="attachment_157974" align="alignnone" width="1536"]<a href="https://helloacm.com/turning-a-dusty-mini-pc-into-a-home-server-my-nuc-8s-second-life/nuc8-beelink-server-2025-11-07-08-35-39/" rel="attachment wp-att-157974"><img src="https://helloacm.com/wp-content/uploads/2026/08/nuc8-beelink-server-2025-11-07-08.35.39-rotated.jpg" alt="Beelink NUC-8 Mini PC" width="1536" height="864" class="size-full wp-image-157974" /></a> Beelink NUC-8 Mini PC[/caption]

[caption id="attachment_157975" align="alignnone" width="1536"]<a href="https://helloacm.com/turning-a-dusty-mini-pc-into-a-home-server-my-nuc-8s-second-life/nuc8-beelink-server-2025-11-07-08-35-43/" rel="attachment wp-att-157975"><img src="https://helloacm.com/wp-content/uploads/2026/08/nuc8-beelink-server-2025-11-07-08.35.43-rotated.jpg" alt="Beelink NUC-8 Mini PC (A small fan)" width="1536" height="864" class="size-full wp-image-157975" /></a> Beelink NUC-8 Mini PC (A small fan)[/caption]

[caption id="attachment_157976" align="alignnone" width="2048"]<a href="https://helloacm.com/turning-a-dusty-mini-pc-into-a-home-server-my-nuc-8s-second-life/nuc8-beelink-server-2025-11-07-17-29-01/" rel="attachment wp-att-157976"><img src="https://helloacm.com/wp-content/uploads/2026/08/nuc8-beelink-server-2025-11-07-17.29.01-scaled.jpg" alt="Preparing the NUC-8 Server" width="2048" height="1152" class="size-full wp-image-157976" /></a> Preparing the NUC-8 Server[/caption]

[caption id="attachment_157977" align="alignnone" width="1160"]<a href="https://helloacm.com/turning-a-dusty-mini-pc-into-a-home-server-my-nuc-8s-second-life/nuc-8-htop/" rel="attachment wp-att-157977"><img src="https://helloacm.com/wp-content/uploads/2026/08/nuc-8-htop.jpg" alt="RAM and Processors" width="1160" height="162" class="size-full wp-image-157977" /></a> RAM and Processors[/caption]

[caption id="attachment_157978" align="alignnone" width="877"]<a href="https://helloacm.com/turning-a-dusty-mini-pc-into-a-home-server-my-nuc-8s-second-life/nuc-8-neofetch/" rel="attachment wp-att-157978"><img src="https://helloacm.com/wp-content/uploads/2026/08/nuc-8-neofetch.jpg" alt="neofetch - server information" width="877" height="440" class="size-full wp-image-157978" /></a> neofetch - server information[/caption]

[caption id="attachment_157979" align="alignnone" width="733"]<a href="https://helloacm.com/turning-a-dusty-mini-pc-into-a-home-server-my-nuc-8s-second-life/nuc-8-pm2-process/" rel="attachment wp-att-157979"><img src="https://helloacm.com/wp-content/uploads/2026/08/nuc-8-pm2-process.jpg" alt="Running PM2 Manager" width="733" height="141" class="size-full wp-image-157979" /></a> Running PM2 Manager[/caption]

[caption id="attachment_157980" align="alignnone" width="1189"]<a href="https://helloacm.com/turning-a-dusty-mini-pc-into-a-home-server-my-nuc-8s-second-life/nuc-8-steem-witness/" rel="attachment wp-att-157980"><img src="https://helloacm.com/wp-content/uploads/2026/08/nuc-8-steem-witness.jpg" alt="Running steemd blockchain" width="1189" height="866" class="size-full wp-image-157980" /></a> Running steemd blockchain[/caption]

I connected the NUC-8 to mouse, keyboard and an external monitor. Then I plugged in the USB storage as the bootable drive (which I had flashed it with the Ubuntu 24.04 image).
[caption id="attachment_157981" align="alignnone" width="2048"]<a href="https://helloacm.com/turning-a-dusty-mini-pc-into-a-home-server-my-nuc-8s-second-life/nuc-8-ubutun-2025-11-07-18-41-55/" rel="attachment wp-att-157981"><img src="https://helloacm.com/wp-content/uploads/2026/08/nuc-8-ubutun-2025-11-07-18.41.55-scaled.jpg" alt="Re-install the Ubuntu24 on NUC-8 Beelink" width="2048" height="1152" class="size-full wp-image-157981" /></a> Re-install the Ubuntu24 on NUC-8 Beelink[/caption]

[show_file file="/var/www/wp-post-common/helloacm.com/home-topology.php"]

[show_posts keyword="Home Network Topology"]

[caption id="attachment_157991" align="alignnone" width="1086"]<a href="https://helloacm.com/turning-a-dusty-mini-pc-into-a-home-server-my-nuc-8s-second-life/nuc-8-nezha/" rel="attachment wp-att-157991"><img src="https://helloacm.com/wp-content/uploads/2026/08/nuc-8-nezha.jpg" alt="NUC-8 Beelink Specs" width="1086" height="771" class="size-full wp-image-157991" /></a> NUC-8 Beelink Specs[/caption]

[caption id="attachment_157992" align="alignnone" width="1074"]<a href="https://helloacm.com/turning-a-dusty-mini-pc-into-a-home-server-my-nuc-8s-second-life/raspberrypi-4b-nezha/" rel="attachment wp-att-157992"><img src="https://helloacm.com/wp-content/uploads/2026/08/raspberrypi-4b-nezha.jpg" alt="Raspberry Pi 4b Specs" width="1074" height="766" class="size-full wp-image-157992" /></a> Raspberry Pi 4b Specs[/caption]

[caption id="attachment_157993" align="alignnone" width="1089"]<a href="https://helloacm.com/turning-a-dusty-mini-pc-into-a-home-server-my-nuc-8s-second-life/raspberrypi-b-rev2-nezha/" rel="attachment wp-att-157993"><img src="https://helloacm.com/wp-content/uploads/2026/08/raspberrypi-b-rev2-nezha.jpg" alt="Raspberry Pi B Model Rev 2 Specs" width="1089" height="753" class="size-full wp-image-157993" /></a> Raspberry Pi B Model Rev 2 Specs[/caption]

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/understanding-dynamic_cast-in-c-safe-downcasting-explained/" rel="bookmark" title="Understanding dynamic_cast in C++: Safe Downcasting Explained">Understanding dynamic_cast in C++: Safe Downcasting Explained</a> <small>What Is dynamic_cast in C++? Purpose Safely convert between polymorphic types at runtime Commonly used...</small></li>
<li><a href="https://helloacm.com/algorithms-to-detect-pattern-of-length-m-repeated-k-or-more-times-in-a-string/" rel="bookmark" title="Algorithms to Detect Pattern of Length M Repeated K or More Times in a String">Algorithms to Detect Pattern of Length M Repeated K or More Times in a String</a> <small>Given an array of positive integers arr, find a pattern of length m that is...</small></li>
<li><a href="https://helloacm.com/microsoft-shareholders-reject-proposal-to-add-bitcoin-to-balance-sheet/" rel="bookmark" title="Microsoft Shareholders Reject Proposal to Add Bitcoin to Balance Sheet">Microsoft Shareholders Reject Proposal to Add Bitcoin to Balance Sheet</a> <small>Every year, I receive a letter from Microsoft because I own a few shares of...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-minmax-dynamic-programming-algorithm-game-of-picking-numbers-at-two-ends/" rel="bookmark" title="Teaching Kids Programming &#8211; Minmax Dynamic Programming Algorithm (Game of Picking Numbers at Two Ends)">Teaching Kids Programming &#8211; Minmax Dynamic Programming Algorithm (Game of Picking Numbers at Two Ends)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given a list of...</small></li>
<li><a href="https://helloacm.com/telegram-accounts-are-shockingly-easy-to-hack-without-2fa/" rel="bookmark" title="Telegram Accounts Are Shockingly Easy to Hack Without 2FA">Telegram Accounts Are Shockingly Easy to Hack Without 2FA</a> <small>&#8220;How My Telegram Account Got Hacked—and What I Learned&#8221; &#8220;A Cautionary Tale: Telegram Security and...</small></li>
<li><a href="https://helloacm.com/refactoring-re-sampling-algorithm-using-on-hashtable/" rel="bookmark" title="Refactoring Re-sampling Algorithm using O(n) Hashtable">Refactoring Re-sampling Algorithm using O(n) Hashtable</a> <small>Background I was asked by my manager to optimize a piece of code that has...</small></li>
<li><a href="https://helloacm.com/the-common-include-php-file-for-my-sites/" rel="bookmark" title="The Common Include PHP File For My Sites">The Common Include PHP File For My Sites</a> <small>I think you may have some common code to write for most of the PHP...</small></li>
<li><a href="https://helloacm.com/vbscript-coding-exercise-insertion-sorting-algorithm/" rel="bookmark" title="VBScript Coding Exercise &#8211; Insertion Sorting Algorithm">VBScript Coding Exercise &#8211; Insertion Sorting Algorithm</a> <small>Among the simple sorting algorithms, the insertion sorting algorithm is my favourite. Insertion sort is...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<blockquote>
I gave an unused Beelink SEi8 mini PC a second life by installing Ubuntu and turning it into a home server. It now runs a STEEM node, Node.js applications, databases, a reverse proxy and Cloudflare Tunnel. The article also explains how double NAT allows the NUC-8 to initiate connections to my Raspberry Pis while preventing connections in the opposite direction, as well as covering home broadband, hardware reuse and cooling considerations.
</blockquote>

<h3>Turning a Dusty Mini PC into a Home Server: My NUC-8’s Second Life</h3>
During the second half of last year, I dug out a mini PC that had been gathering dust at home, installed <a href="https://helloacm.com/how-to-setup-hhvm-on-the-ubuntu-vps/" title="How to Setup HHVM on the Ubuntu VPS?">Ubuntu</a> 24.04.4 LTS on it, and placed it inside the shoe cupboard by our front door. It has been serving as my home server ever since.

I usually call it my “NUC-8”, although, strictly speaking, it is not an Intel NUC. It is a Beelink SEi8 mini PC that I bought from Amazon on 25 April 2021 for £466.65. Its specifications are as follows:

Beelink Mini PC SEI8, Intel Core i5-8259U <a href="https://helloacm.com/why-parallelism-isnt-infinite-amdahl-vs-gustafson-explained-simply/" title="Why Parallelism Isn’t Infinite: Amdahl vs Gustafson Explained Simply">processor</a> running at up to 3.8GHz, 16GB of DDR4 memory, a 512GB NVMe SSD, Intel Iris Plus Graphics 655, Wi-Fi 6 and Bluetooth 5.0.

<h3>From a Windows Mini PC to an Unused Computer</h3>

The machine came with Windows 10 Pro pre-installed. Its specifications looked perfectly respectable, but in everyday use it always felt rather slow and never quite met my expectations. I later put it in Eric’s room, where he used it for more than six months. After I replaced it with a MacBook Air for him, the little PC gradually became redundant and ended up gathering dust.

The awkward thing about mini PCs (<a href="https://helloacm.com/teaching-kids-programming-introduction-to-units-of-information-byte-kb-mb-gb-tb-pb/" title="Teaching Kids Programming – Introduction to Units of Information (Byte, KB, MB, GB, TB, PB)">Next Unit of Computing</a>) like this is not that they are genuinely underpowered. They simply do not stand out as everyday desktop computers. Compared with a newer laptop, the responsiveness, graphics performance and overall experience can feel fairly ordinary. Throwing one away, however, would be a terrible waste. A four-core, eight-thread processor, 16GB of memory and a 512GB NVMe SSD are still more than capable of running Linux and a collection of always-on services.

So, during the second half of last year, I decided to give it a different purpose.

<h3>Linux Brought It Back to Life</h3>

After I installed Ubuntu 24.04.4 LTS, the computer almost felt as though it had come back to life. Without lots of unnecessary desktop software and background services, the whole system ran remarkably smoothly. As a server, its hardware is far from obsolete and still has plenty of capacity to spare.

Over the past year, I have gradually deployed quite a few things on it.

Later, I also dug out a 2TB <a href="https://helloacm.com/turn-your-raspberry-pi-into-a-family-network-drive-2tb-wd-hard-drive-setup-for-kids-macs/" title="Turn Your Raspberry Pi into a Family Network Drive: 2TB WD Hard Drive Setup for Kids’ Macs">hard drive</a> that had been sitting unused and gathering dust. I installed it in a USB enclosure and connected it to the NUC-8. It uses the ext3 file system and is used mainly to store data for the STEEM blockchain node. The Raspberry Pi 4B also has an external 1TB 2.5-inch USB SSD, which I use to provide file sharing across the home network.

At one point, I used it to run a STEEM witness node. I also configured a reverse proxy and used Cloudflare Tunnel to expose services from my home network securely to the internet. In addition, I use PM2 to keep a Node.js bot running continuously. The bot monitors transactions on the blockchain and writes the relevant data into a <a href="https://helloacm.com/improve-multithreading-performance-of-sqlite-database-by-wal-write-ahead-logging/" title="Improve Multithreading Performance of Sqlite Database by WAL (Write Ahead Logging)">database</a>.

When writing code, I often connect to the server over the local network using VS Code Remote SSH. I can compile and run C++ programs, test scripts, or deploy small services that need to remain online. Compared with a Raspberry Pi, the i5 processor, 16GB of memory and NVMe storage make a very noticeable difference, particularly when compiling code or working with databases.

This once-forgotten mini PC (<a href="https://helloacm.com/all-in-one-raspberry-pi-400-kit-personal-computer-kit-with-raspbian-os/" title="NUC: All-In-One Raspberry PI 400 Kit – Personal Computer Kit with Raspbian OS">NUC</a>) has now been running inside the shoe cupboard for nearly a year, and it has proved remarkably stable.

<h3>A Home Network Finally Good Enough for the Server</h3>

I recently upgraded our home broadband to full fibre. The theoretical download speed is 900Mbps, while the upload speed is 110Mbps. That is more than adequate for running a small server at home.

Of course, when services hosted at home are being accessed from the public internet, the important figure is the 110Mbps upload speed, not the 900Mbps download speed. Even so, 110Mbps provides ample capacity for a personal website, APIs, remote administration and the other lightweight services I currently run. Cloudflare Tunnel also helps: the server establishes an outbound connection to Cloudflare, so I do not need to wrestle with public IP addresses and port forwarding across two routers. It continues to work even though my home network uses double NAT.

<h3>Why Can the NUC-8 Reach the Raspberry Pis, but Not the Other Way Around?</h3>

My home network has a slightly unusual layout.

[caption id="attachment_157968" align="alignnone" width="1546"]<a href="https://helloacm.com/turning-a-dusty-mini-pc-into-a-home-server-my-nuc-8s-second-life/home-network-topology-setup/" rel="attachment wp-att-157968"><img src="https://helloacm.com/wp-content/uploads/2026/08/home-network-topology-setup.jpg" alt="My Current Home Network Topology" width="1546" height="921" class="size-full wp-image-157968" /></a> My Current Home Network Topology[/caption]

<pre lang="mermaid">
flowchart TB
    Internet(("Internet"))

    subgraph PL["Plusnet LAN — upstream subnet"]
        Hub["Plusnet Hub 2&lt;br/&gt;Router and NAT"]
        Pi4["Raspberry Pi 4B&lt;br/&gt;Connected directly to Hub 2"]

        Hub &lt;--&gt;|Direct connection| Pi4
    end

    subgraph DL["Deco LAN — downstream subnet"]
        Deco1["Deco 1 — Primary&lt;br/&gt;Router, NAT and firewall"]
        Deco2["Deco 2 — Mesh node&lt;br/&gt;Upstairs office — bedroom"]
        Deco3["Deco 3 — Mesh node&lt;br/&gt;Study room — former garage"]
        NUC["NUC-8 / Beelink SEi8&lt;br/&gt;Ubuntu home server"]
        Pi1["Raspberry Pi Model B Rev 2&lt;br/&gt;~475 MB RAM"]

        Deco1 &lt;--&gt;|Ethernet| NUC
        Deco1 -.-|Wireless mesh| Deco2
        Deco1 -.-|Wireless mesh| Deco3
        Deco3 &lt;--&gt;|Ethernet| Pi1
    end

    Internet &lt;--&gt; Hub
    Hub &lt;--&gt;|Ethernet to Deco WAN| Deco1
</pre>

The Plusnet router is the primary upstream router. Two Raspberry Pis: an old Raspberry Pi Model B Rev 2 with only about 475MB of memory connects to a secondary Deco Router (Wirless Mesh Node), and a Raspberry Pi 4B with 4GB of memory connects directly to the PlusNet Hub 2 Router via Ethernet Cable (RJ45).

The Deco is connected to the Plusnet router but continues to operate in router mode rather than bridge or access point mode. The NUC-8 is connected to the Deco by Ethernet. As a result, the Plusnet router and the Deco each create a separate local subnet. For example, the Raspberry Pis might be on the 192.168.1.x network, while the NUC-8 is on the 192.168.68.x network managed by the Deco.

This creates the common home-networking arrangement known as double NAT.

When the NUC-8 initiates a connection to one of the Raspberry Pis, the traffic travels from the Deco’s internal network towards its upstream interface. The Deco uses NAT to translate the connection to its own upstream address and records the request in its connection-tracking table. When the Raspberry Pi replies, the Deco can therefore translate and forward the response back to the NUC-8. Communication initiated in this direction works normally.

Things are different when a Raspberry Pi attempts to initiate a connection to the NUC-8. The Plusnet network normally has no route telling it how to reach the 192.168.68.x subnet. Even if a request reaches the Deco’s upstream interface, the Deco firewall treats it as an unsolicited inbound connection arriving from its WAN side. With no corresponding entry in the connection-tracking table, the request is blocked by default rather than forwarded to the NUC-8.

The traffic is therefore not literally limited to one-way communication. The real difference is which side is allowed to initiate a new connection. Once the NUC-8 has initiated one, replies from a Raspberry Pi can travel back along the established path. A Raspberry Pi, however, cannot simply open a new connection to the NUC-8.

The NUC-8 server and the Raspberry B model rev 2  cannot be seen from Raspberry Pi 4b.

<blockquote>
From 192.168.1.XXX icmp_seq=460 Destination Host Unreachable
</blockquote>

If I wanted all three computers to communicate with one another directly, the simplest solution would be to switch the Deco to access point mode, or connect both Raspberry Pis to the Deco so that every device belonged to the same subnet. A more advanced but considerably more complicated approach would be to add a static route on the Plusnet router pointing to the Deco, then adjust the Deco’s NAT and firewall rules accordingly. Many consumer routers do not fully support this type of configuration. If I needed access to only a few services on the NUC-8, I could instead configure port forwarding on the Deco, although that would be less clean and more cumbersome to manage than using a single subnet.

<h3>A Second Life for an Old Computer</h3>

Looking back, this mini PC cost me £466.65 in 2021 and never made a particularly strong impression as a Windows desktop. A few years later, however, it found a role that suited it much better: a Linux home server.

It is compact, its <a href="https://helloacm.com/big-data-case-study-tv-usage-and-power-consumption/" title="Big Data Case Study: TV Usage and Power Consumption">power consumption</a> is reasonably modest, and its performance is far better than that of an ordinary Raspberry Pi. It can comfortably run a blockchain node, a database, Node.js services, a reverse proxy and a development environment. Since upgrading to full-fibre broadband, the whole setup has become even more useful.

The one thing I must keep in mind is that a shoe cupboard is not a proper server room. Running reliably for nearly a year is encouraging, but it is no substitute for monitoring temperatures and storage health. The cupboard needs adequate ventilation, the air intake should be cleaned regularly, and I should keep an eye on the CPU temperature and the SSD’s SMART data. Otherwise, heat could cause the machine to throttle or shorten the life of its components.

For me, the most satisfying part of this project is not merely that it saved me from buying another server. It gave a neglected computer a useful purpose again. The machine sits quietly inside the cupboard by the front door, almost invisible in everyday life, yet it is constantly running nodes, processing data, hosting services and supporting whatever small project happens to occur to me next.

That, perhaps, is the most enjoyable thing about running a home server if you like experimenting with technology. You do not necessarily need an expensive rack, a dedicated server room or even the latest hardware. A forgotten old computer, Linux, a reliable network connection and a little patience are enough to build a small home lab of your own.

[caption id="attachment_157970" align="alignnone" width="953"]<a href="https://helloacm.com/turning-a-dusty-mini-pc-into-a-home-server-my-nuc-8s-second-life/beelink-mini-pc-nuc-8-16gb/" rel="attachment wp-att-157970"><img src="https://helloacm.com/wp-content/uploads/2026/08/beelink-mini-pc-nuc-8-16gb.jpg" alt="Beelink Mini PC - Order from Amazon - 2021" width="953" height="517" class="size-full wp-image-157970" /></a> Beelink Mini PC - Order from Amazon - 2021[/caption]

[caption id="attachment_157972" align="alignnone" width="864"]<a href="https://helloacm.com/turning-a-dusty-mini-pc-into-a-home-server-my-nuc-8s-second-life/home-servers-in-shoe-closet-2025-11-07-18-51-24/" rel="attachment wp-att-157972"><img src="https://helloacm.com/wp-content/uploads/2026/08/home-servers-in-shoe-closet-2025-11-07-18.51.24.jpg" alt="Two Servers (Raspberry Pi 4b - and NUC-8 beelink) in the shoe closet" width="864" height="1536" class="size-full wp-image-157972" /></a> Two Servers (Raspberry Pi 4b - and NUC-8 beelink) in the shoe closet[/caption]

[caption id="attachment_157973" align="alignnone" width="1536"]<a href="https://helloacm.com/turning-a-dusty-mini-pc-into-a-home-server-my-nuc-8s-second-life/nuc8-beelink-server-2025-11-07-08-35-34/" rel="attachment wp-att-157973"><img src="https://helloacm.com/wp-content/uploads/2026/08/nuc8-beelink-server-2025-11-07-08.35.34-rotated.jpg" alt="Reconnect the NUC-8" width="1536" height="864" class="size-full wp-image-157973" /></a> Reconnect the NUC-8[/caption]

[caption id="attachment_157974" align="alignnone" width="1536"]<a href="https://helloacm.com/turning-a-dusty-mini-pc-into-a-home-server-my-nuc-8s-second-life/nuc8-beelink-server-2025-11-07-08-35-39/" rel="attachment wp-att-157974"><img src="https://helloacm.com/wp-content/uploads/2026/08/nuc8-beelink-server-2025-11-07-08.35.39-rotated.jpg" alt="Beelink NUC-8 Mini PC" width="1536" height="864" class="size-full wp-image-157974" /></a> Beelink NUC-8 Mini PC[/caption]

[caption id="attachment_157975" align="alignnone" width="1536"]<a href="https://helloacm.com/turning-a-dusty-mini-pc-into-a-home-server-my-nuc-8s-second-life/nuc8-beelink-server-2025-11-07-08-35-43/" rel="attachment wp-att-157975"><img src="https://helloacm.com/wp-content/uploads/2026/08/nuc8-beelink-server-2025-11-07-08.35.43-rotated.jpg" alt="Beelink NUC-8 Mini PC (A small fan)" width="1536" height="864" class="size-full wp-image-157975" /></a> Beelink NUC-8 Mini PC (A small fan)[/caption]

[caption id="attachment_157976" align="alignnone" width="2048"]<a href="https://helloacm.com/turning-a-dusty-mini-pc-into-a-home-server-my-nuc-8s-second-life/nuc8-beelink-server-2025-11-07-17-29-01/" rel="attachment wp-att-157976"><img src="https://helloacm.com/wp-content/uploads/2026/08/nuc8-beelink-server-2025-11-07-17.29.01-scaled.jpg" alt="Preparing the NUC-8 Server" width="2048" height="1152" class="size-full wp-image-157976" /></a> Preparing the NUC-8 Server[/caption]

[caption id="attachment_157977" align="alignnone" width="1160"]<a href="https://helloacm.com/turning-a-dusty-mini-pc-into-a-home-server-my-nuc-8s-second-life/nuc-8-htop/" rel="attachment wp-att-157977"><img src="https://helloacm.com/wp-content/uploads/2026/08/nuc-8-htop.jpg" alt="RAM and Processors" width="1160" height="162" class="size-full wp-image-157977" /></a> RAM and Processors[/caption]

[caption id="attachment_157978" align="alignnone" width="877"]<a href="https://helloacm.com/turning-a-dusty-mini-pc-into-a-home-server-my-nuc-8s-second-life/nuc-8-neofetch/" rel="attachment wp-att-157978"><img src="https://helloacm.com/wp-content/uploads/2026/08/nuc-8-neofetch.jpg" alt="neofetch - server information" width="877" height="440" class="size-full wp-image-157978" /></a> neofetch - server information[/caption]

[caption id="attachment_157979" align="alignnone" width="733"]<a href="https://helloacm.com/turning-a-dusty-mini-pc-into-a-home-server-my-nuc-8s-second-life/nuc-8-pm2-process/" rel="attachment wp-att-157979"><img src="https://helloacm.com/wp-content/uploads/2026/08/nuc-8-pm2-process.jpg" alt="Running PM2 Manager" width="733" height="141" class="size-full wp-image-157979" /></a> Running PM2 Manager[/caption]

[caption id="attachment_157980" align="alignnone" width="1189"]<a href="https://helloacm.com/turning-a-dusty-mini-pc-into-a-home-server-my-nuc-8s-second-life/nuc-8-steem-witness/" rel="attachment wp-att-157980"><img src="https://helloacm.com/wp-content/uploads/2026/08/nuc-8-steem-witness.jpg" alt="Running steemd blockchain" width="1189" height="866" class="size-full wp-image-157980" /></a> Running steemd blockchain[/caption]

I connected the NUC-8 to mouse, keyboard and an external monitor. Then I plugged in the USB storage as the bootable drive (which I had flashed it with the Ubuntu 24.04 image).
[caption id="attachment_157981" align="alignnone" width="2048"]<a href="https://helloacm.com/turning-a-dusty-mini-pc-into-a-home-server-my-nuc-8s-second-life/nuc-8-ubutun-2025-11-07-18-41-55/" rel="attachment wp-att-157981"><img src="https://helloacm.com/wp-content/uploads/2026/08/nuc-8-ubutun-2025-11-07-18.41.55-scaled.jpg" alt="Re-install the Ubuntu24 on NUC-8 Beelink" width="2048" height="1152" class="size-full wp-image-157981" /></a> Re-install the Ubuntu24 on NUC-8 Beelink[/caption]

[show_file file="/var/www/wp-post-common/helloacm.com/home-topology.php"]

[show_posts keyword="Home Network Topology"]

[caption id="attachment_157991" align="alignnone" width="1086"]<a href="https://helloacm.com/turning-a-dusty-mini-pc-into-a-home-server-my-nuc-8s-second-life/nuc-8-nezha/" rel="attachment wp-att-157991"><img src="https://helloacm.com/wp-content/uploads/2026/08/nuc-8-nezha.jpg" alt="NUC-8 Beelink Specs" width="1086" height="771" class="size-full wp-image-157991" /></a> NUC-8 Beelink Specs[/caption]

[caption id="attachment_157992" align="alignnone" width="1074"]<a href="https://helloacm.com/turning-a-dusty-mini-pc-into-a-home-server-my-nuc-8s-second-life/raspberrypi-4b-nezha/" rel="attachment wp-att-157992"><img src="https://helloacm.com/wp-content/uploads/2026/08/raspberrypi-4b-nezha.jpg" alt="Raspberry Pi 4b Specs" width="1074" height="766" class="size-full wp-image-157992" /></a> Raspberry Pi 4b Specs[/caption]

[caption id="attachment_157993" align="alignnone" width="1089"]<a href="https://helloacm.com/turning-a-dusty-mini-pc-into-a-home-server-my-nuc-8s-second-life/raspberrypi-b-rev2-nezha/" rel="attachment wp-att-157993"><img src="https://helloacm.com/wp-content/uploads/2026/08/raspberrypi-b-rev2-nezha.jpg" alt="Raspberry Pi B Model Rev 2 Specs" width="1089" height="753" class="size-full wp-image-157993" /></a> Raspberry Pi B Model Rev 2 Specs[/caption]

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/understanding-dynamic_cast-in-c-safe-downcasting-explained/" rel="bookmark" title="Understanding dynamic_cast in C++: Safe Downcasting Explained">Understanding dynamic_cast in C++: Safe Downcasting Explained</a> <small>What Is dynamic_cast in C++? Purpose Safely convert between polymorphic types at runtime Commonly used...</small></li>
<li><a href="https://helloacm.com/algorithms-to-detect-pattern-of-length-m-repeated-k-or-more-times-in-a-string/" rel="bookmark" title="Algorithms to Detect Pattern of Length M Repeated K or More Times in a String">Algorithms to Detect Pattern of Length M Repeated K or More Times in a String</a> <small>Given an array of positive integers arr, find a pattern of length m that is...</small></li>
<li><a href="https://helloacm.com/microsoft-shareholders-reject-proposal-to-add-bitcoin-to-balance-sheet/" rel="bookmark" title="Microsoft Shareholders Reject Proposal to Add Bitcoin to Balance Sheet">Microsoft Shareholders Reject Proposal to Add Bitcoin to Balance Sheet</a> <small>Every year, I receive a letter from Microsoft because I own a few shares of...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-minmax-dynamic-programming-algorithm-game-of-picking-numbers-at-two-ends/" rel="bookmark" title="Teaching Kids Programming &#8211; Minmax Dynamic Programming Algorithm (Game of Picking Numbers at Two Ends)">Teaching Kids Programming &#8211; Minmax Dynamic Programming Algorithm (Game of Picking Numbers at Two Ends)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given a list of...</small></li>
<li><a href="https://helloacm.com/telegram-accounts-are-shockingly-easy-to-hack-without-2fa/" rel="bookmark" title="Telegram Accounts Are Shockingly Easy to Hack Without 2FA">Telegram Accounts Are Shockingly Easy to Hack Without 2FA</a> <small>&#8220;How My Telegram Account Got Hacked—and What I Learned&#8221; &#8220;A Cautionary Tale: Telegram Security and...</small></li>
<li><a href="https://helloacm.com/refactoring-re-sampling-algorithm-using-on-hashtable/" rel="bookmark" title="Refactoring Re-sampling Algorithm using O(n) Hashtable">Refactoring Re-sampling Algorithm using O(n) Hashtable</a> <small>Background I was asked by my manager to optimize a piece of code that has...</small></li>
<li><a href="https://helloacm.com/the-common-include-php-file-for-my-sites/" rel="bookmark" title="The Common Include PHP File For My Sites">The Common Include PHP File For My Sites</a> <small>I think you may have some common code to write for most of the PHP...</small></li>
<li><a href="https://helloacm.com/vbscript-coding-exercise-insertion-sorting-algorithm/" rel="bookmark" title="VBScript Coding Exercise &#8211; Insertion Sorting Algorithm">VBScript Coding Exercise &#8211; Insertion Sorting Algorithm</a> <small>Among the simple sorting algorithms, the insertion sorting algorithm is my favourite. Insertion sort is...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://helloacm.com/turning-a-dusty-mini-pc-into-a-home-server-my-nuc-8s-second-life/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>A Five-Year Milestone at Microsoft (Anniversary Crystal)</title>
		<link>https://helloacm.com/a-five-year-milestone-at-microsoft-anniversary-crystal/</link>
					<comments>https://helloacm.com/a-five-year-milestone-at-microsoft-anniversary-crystal/#respond</comments>
		
		<dc:creator><![CDATA[ACMer]]></dc:creator>
		<pubDate>Thu, 30 Jul 2026 15:03:36 +0000</pubDate>
				<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[Appreciation]]></category>
		<category><![CDATA[artificial intelligence]]></category>
		<category><![CDATA[Azure]]></category>
		<category><![CDATA[Business Growth]]></category>
		<category><![CDATA[Career Growth]]></category>
		<category><![CDATA[Career Milestone]]></category>
		<category><![CDATA[cloud computing]]></category>
		<category><![CDATA[Crystal Award]]></category>
		<category><![CDATA[Crystal Trophy]]></category>
		<category><![CDATA[Digital Transformation]]></category>
		<category><![CDATA[Earnings Report]]></category>
		<category><![CDATA[Employee Recognition]]></category>
		<category><![CDATA[Enterprise AI]]></category>
		<category><![CDATA[Financial Results]]></category>
		<category><![CDATA[Five-Year Anniversary]]></category>
		<category><![CDATA[Gratitude]]></category>
		<category><![CDATA[Microsoft 365 Copilot]]></category>
		<category><![CDATA[Microsoft FY2026]]></category>
		<category><![CDATA[Microsoft Milestone]]></category>
		<category><![CDATA[Net Income]]></category>
		<category><![CDATA[New Chapter]]></category>
		<category><![CDATA[Professional Journey]]></category>
		<category><![CDATA[Revenue Growth]]></category>
		<category><![CDATA[Service Award]]></category>
		<category><![CDATA[Stock Market]]></category>
		<category><![CDATA[Technology Industry]]></category>
		<category><![CDATA[Work Anniversary]]></category>
		<category><![CDATA[Workplace Achievement]]></category>
		<category><![CDATA[Years of Service]]></category>
		<guid isPermaLink="false">https://helloacm.com/?p=157947</guid>

					<description><![CDATA[<blockquote>
To mark my fifth anniversary at Microsoft, I received a meaningful crystal service award. Over the past five years, there have been challenges, growth, and many valuable collaborations and experiences. This award not only commemorates the journey so far, but also reminds me to stay passionate and embrace the next chapter.

<a href="https://helloacm.com/this-years-microsofts-hackathon/" title="This Year’s Microsoft’s Hackathon">Microsoft</a> has released its FY2026 results, delivering strong growth in both revenue and net income. Azure and Microsoft 365 Copilot were the standout performers, while a substantial backlog of long-term contracts provides greater visibility and a solid foundation for growth over the next two years.

Five Years at Microsoft: A Milestone Worth Celebrating
Five Years at Microsoft: Grateful for the Journey
Celebrating Five Years at Microsoft
Five Years, One Crystal Award, Countless Memories
A Five-Year Milestone at Microsoft
Five Years of Learning, Growth, and Impact
Five Years at Microsoft—and the Journey Continues
A Crystal Milestone: Five Years at Microsoft
</blockquote>

<h3>A Crystal Milestone: Five Years at Microsoft</h3>
Grateful to celebrate five years at Microsoft and receive this service award.

It has been a rewarding journey filled with <a href="https://helloacm.com/deep-dive-into-reinforcement-learning-understanding-the-q-learning-algorithm/" title="Deep Dive into Reinforcement Learning: Understanding the Q-Learning Algorithm">learning</a>, challenging projects, and the opportunity to work with many talented colleagues.

Thank you to everyone who has been part of the journey so far. Looking forward to the next chapter.

[caption id="attachment_157948" align="alignnone" width="1536"]<a href="https://helloacm.com/a-five-year-milestone-at-microsoft-anniversary-crystal/microsoft-5-year-anniversary-crystal-2026-07-29-12-57-09/" rel="attachment wp-att-157948"><img src="https://helloacm.com/wp-content/uploads/2026/07/microsoft-5-year-anniversary-crystal-2026-07-29-12.57.09-rotated.jpg" alt="Unboxing the 5 year microsoft service anniversary crystal!" width="1536" height="864" class="size-full wp-image-157948" /></a> Unboxing the 5 year microsoft service anniversary crystal![/caption]

[caption id="attachment_157949" align="alignnone" width="864"]<a href="https://helloacm.com/a-five-year-milestone-at-microsoft-anniversary-crystal/microsoft-5-year-anniversary-crystal-2026-07-29-12-57-22/" rel="attachment wp-att-157949"><img src="https://helloacm.com/wp-content/uploads/2026/07/microsoft-5-year-anniversary-crystal-2026-07-29-12.57.22.jpg" alt="The base and the top are separate, came with a nice package (as a gift)" width="864" height="1536" class="size-full wp-image-157949" /></a> The base and the top are separate, came with a nice package (as a gift)[/caption]

[caption id="attachment_157950" align="alignnone" width="864"]<a href="https://helloacm.com/a-five-year-milestone-at-microsoft-anniversary-crystal/microsoft-5-year-anniversary-crystal-2026-07-29-13-00-55/" rel="attachment wp-att-157950"><img src="https://helloacm.com/wp-content/uploads/2026/07/microsoft-5-year-anniversary-crystal-2026-07-29-13.00.55.jpg" alt="The Shining Service Award for 5 Year Anniversary" width="864" height="1536" class="size-full wp-image-157950" /></a> The Shining Service Award for 5 Year Anniversary[/caption]

[caption id="attachment_157951" align="alignnone" width="1152"]<a href="https://helloacm.com/a-five-year-milestone-at-microsoft-anniversary-crystal/microsoft-5-year-anniversary-crystal-2026-07-29-14-41-05/" rel="attachment wp-att-157951"><img src="https://helloacm.com/wp-content/uploads/2026/07/microsoft-5-year-anniversary-crystal-2026-07-29-14.41.05-scaled.jpg" alt="Top view of the 5 Year Crystal" width="1152" height="2048" class="size-full wp-image-157951" /></a> Top view of the 5 Year Crystal[/caption]

[caption id="attachment_157952" align="alignnone" width="941"]<a href="https://helloacm.com/a-five-year-milestone-at-microsoft-anniversary-crystal/microsoft-5-year-anniversary-crystal-2026-07-29-15-28-36/" rel="attachment wp-att-157952"><img src="https://helloacm.com/wp-content/uploads/2026/07/microsoft-5-year-anniversary-crystal-2026-07-29-15.28.36.png" alt="5 Year Microsoft Anniversary Crystal (Service Award)" width="941" height="1672" class="size-full wp-image-157952" /></a> 5 Year Microsoft Anniversary Crystal (Service Award)[/caption]

[caption id="attachment_157953" align="alignnone" width="720"]<a href="https://helloacm.com/a-five-year-milestone-at-microsoft-anniversary-crystal/msft-price-all-2026-07-30/" rel="attachment wp-att-157953"><img src="https://helloacm.com/wp-content/uploads/2026/07/msft-price-all-2026-07-30.jpg" alt="MSFT = 277 USD when I joined Microsoft" width="720" height="555" class="size-full wp-image-157953" /></a> MSFT = 277 USD when I joined Microsoft[/caption]

[caption id="attachment_157954" align="alignnone" width="588"]<a href="https://helloacm.com/a-five-year-milestone-at-microsoft-anniversary-crystal/msft-price-soars-206-07-30/" rel="attachment wp-att-157954"><img src="https://helloacm.com/wp-content/uploads/2026/07/msft-price-soars-206-07-30.jpg" alt="MSFT Stock Soars after Annoucement of Q4 2026 Earnings Report" width="588" height="547" class="size-full wp-image-157954" /></a> MSFT Stock Soars after Annoucement of Q4 2026 Earnings Report[/caption]

Facts of the Microsoft 5 year Anniversary Crystal Base: 0.6 kg, The Top: 0.6kg - Combined: 1.25 kg.

<h3>Microsoft MSFT Stock Price & 2026 Q4 Earnings Report</h3>
Microsoft has released its FY2026 financial results, officially closing out the fiscal year. Several key metrics for the fourth quarter significantly exceeded market expectations, and the company’s share price rose by as much as approximately 9% in after-hours trading following the announcement.

Looking at the headline figures, Microsoft generated total annual revenue of $331.8 billion, up 18% year over year. Full-year net income reached $133.7 billion, representing an overall net profit margin of 40.3%. Fourth-quarter revenue came in at $90 billion, also up 18% year over year and well above the market consensus.

Microsoft’s AI-related businesses achieved two major milestones.

First, Azure cloud services grew by 43% year over year in the fourth quarter, far exceeding the market’s previous expectation of around 39%. Azure’s annual revenue also surpassed $100 billion for the first time. Management expects growth to reach approximately 45% in the next quarter, once again ahead of expectations.

Second, Microsoft 365 Copilot has now exceeded 30 million paid seats, with most of them purchased in bulk by enterprise customers. More than 70% of Fortune 500 companies have deployed Microsoft 365 Copilot, while the number of customers purchasing more than 10,000 seats has quadrupled year over year. This clearly shows that the commercial adoption of enterprise AI is accelerating.

Even more notably, Microsoft currently has $678 billion in contracted long-term orders that have not yet been recognised as revenue. Given that these contracts have an average duration of roughly two to three years, the foundation for Microsoft’s growth over the next two years is largely secured.

There is no denying it—this was an exceptionally strong set of results.

<blockquote>
MSFT had no trading price on Monday, 5 July 2021, because Nasdaq was closed for the observed US Independence Day holiday.

The most recent price was from Friday, 2 July 2021:

Closing price: $277.65
Adjusted close: $266.46
Open: $272.82
High: $278.00
Low: $272.50

Therefore, for a portfolio valuation as of 5 July 2021, use $277.65 per MSFT share—or the adjusted price if you are calculating historical investment returns.
</blockquote>

[show_file file="/var/www/wp-post-common/helloacm.com/microsoft.php"]

[show_posts keyword="Microsoft"]

Linkedin Post: <a href="https://www.linkedin.com/feed/update/urn:li:activity:7488253654832160768/" title="Grateful to celebrate five years at Microsoft and receive this service award.">Microsoft 5-year Service Award: Anniversary Crystals</a>

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/chatgpt-refactors-rewrites-the-code-using-promise-all-sending-requests-in-parallel/" rel="bookmark" title="ChatGPT Refactors/Rewrites the Code using Promise.All &#8211; Sending Requests in Parallel">ChatGPT Refactors/Rewrites the Code using Promise.All &#8211; Sending Requests in Parallel</a> <small>In one of my project, I have the following code (Node/Javascript) that invokes a few...</small></li>
<li><a href="https://helloacm.com/bash-how-to-get-http-response-code-using-curl-command/" rel="bookmark" title="BASH: How to Get HTTP Response Code using Curl Command?">BASH: How to Get HTTP Response Code using Curl Command?</a> <small>To check the HTTP response code after running a curl command, you can use the...</small></li>
<li><a href="https://helloacm.com/chessly-british-short-hairs-classified-as-persian-cat-by-resnet-50/" rel="bookmark" title="Chessly (British Short Hairs) Classified as Persian Cat by ResNet-50">Chessly (British Short Hairs) Classified as Persian Cat by ResNet-50</a> <small>Chessly is one of my cat, she is a British shorthairs. However, she has been...</small></li>
<li><a href="https://helloacm.com/interview-question-the-number-of-bits-required-to-convert-one-integer-to-another-cc-function/" rel="bookmark" title="Interview Question: The Number of Bits Required to Convert One Integer to Another (C/C++ function)">Interview Question: The Number of Bits Required to Convert One Integer to Another (C/C++ function)</a> <small>The question is: how many bits are required to change if we want to convert...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-introduction-to-units-of-information-byte-kb-mb-gb-tb-pb/" rel="bookmark" title="Teaching Kids Programming &#8211; Introduction to Units of Information (Byte, KB, MB, GB, TB, PB)">Teaching Kids Programming &#8211; Introduction to Units of Information (Byte, KB, MB, GB, TB, PB)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms Information is the lifeblood of the...</small></li>
<li><a href="https://helloacm.com/microsofts-excel-just-got-smarter-the-new-copilot-function/" rel="bookmark" title="Microsoft&#8217;s Excel Just Got Smarter: The New Copilot Function">Microsoft&#8217;s Excel Just Got Smarter: The New Copilot Function</a> <small>All in AI. Microsoft has integrated AI (Copilot) to its Office products. I’m thrilled to...</small></li>
<li><a href="https://helloacm.com/how-to-modify-the-git-commit-messages-after-your-push-your-branch/" rel="bookmark" title="How to Modify the Git Commit Messages After Your Push Your Branch?">How to Modify the Git Commit Messages After Your Push Your Branch?</a> <small>Git is a popular and widely used version control system. If you stage your local...</small></li>
<li><a href="https://helloacm.com/coding-exercise-simple-nl-implementation-on-windows-platform-using-c-gcc/" rel="bookmark" title="Coding Exercise &#8211; Simple [nl] Implementation on Windows Platform using C++ (GCC)">Coding Exercise &#8211; Simple [nl] Implementation on Windows Platform using C++ (GCC)</a> <small>On Linux BASH shell, the &#8216;nl&#8217; utility is used to print out text file (or...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<blockquote>
To mark my fifth anniversary at Microsoft, I received a meaningful crystal service award. Over the past five years, there have been challenges, growth, and many valuable collaborations and experiences. This award not only commemorates the journey so far, but also reminds me to stay passionate and embrace the next chapter.

<a href="https://helloacm.com/this-years-microsofts-hackathon/" title="This Year’s Microsoft’s Hackathon">Microsoft</a> has released its FY2026 results, delivering strong growth in both revenue and net income. Azure and Microsoft 365 Copilot were the standout performers, while a substantial backlog of long-term contracts provides greater visibility and a solid foundation for growth over the next two years.

Five Years at Microsoft: A Milestone Worth Celebrating
Five Years at Microsoft: Grateful for the Journey
Celebrating Five Years at Microsoft
Five Years, One Crystal Award, Countless Memories
A Five-Year Milestone at Microsoft
Five Years of Learning, Growth, and Impact
Five Years at Microsoft—and the Journey Continues
A Crystal Milestone: Five Years at Microsoft
</blockquote>

<h3>A Crystal Milestone: Five Years at Microsoft</h3>
Grateful to celebrate five years at Microsoft and receive this service award.

It has been a rewarding journey filled with <a href="https://helloacm.com/deep-dive-into-reinforcement-learning-understanding-the-q-learning-algorithm/" title="Deep Dive into Reinforcement Learning: Understanding the Q-Learning Algorithm">learning</a>, challenging projects, and the opportunity to work with many talented colleagues.

Thank you to everyone who has been part of the journey so far. Looking forward to the next chapter.

[caption id="attachment_157948" align="alignnone" width="1536"]<a href="https://helloacm.com/a-five-year-milestone-at-microsoft-anniversary-crystal/microsoft-5-year-anniversary-crystal-2026-07-29-12-57-09/" rel="attachment wp-att-157948"><img src="https://helloacm.com/wp-content/uploads/2026/07/microsoft-5-year-anniversary-crystal-2026-07-29-12.57.09-rotated.jpg" alt="Unboxing the 5 year microsoft service anniversary crystal!" width="1536" height="864" class="size-full wp-image-157948" /></a> Unboxing the 5 year microsoft service anniversary crystal![/caption]

[caption id="attachment_157949" align="alignnone" width="864"]<a href="https://helloacm.com/a-five-year-milestone-at-microsoft-anniversary-crystal/microsoft-5-year-anniversary-crystal-2026-07-29-12-57-22/" rel="attachment wp-att-157949"><img src="https://helloacm.com/wp-content/uploads/2026/07/microsoft-5-year-anniversary-crystal-2026-07-29-12.57.22.jpg" alt="The base and the top are separate, came with a nice package (as a gift)" width="864" height="1536" class="size-full wp-image-157949" /></a> The base and the top are separate, came with a nice package (as a gift)[/caption]

[caption id="attachment_157950" align="alignnone" width="864"]<a href="https://helloacm.com/a-five-year-milestone-at-microsoft-anniversary-crystal/microsoft-5-year-anniversary-crystal-2026-07-29-13-00-55/" rel="attachment wp-att-157950"><img src="https://helloacm.com/wp-content/uploads/2026/07/microsoft-5-year-anniversary-crystal-2026-07-29-13.00.55.jpg" alt="The Shining Service Award for 5 Year Anniversary" width="864" height="1536" class="size-full wp-image-157950" /></a> The Shining Service Award for 5 Year Anniversary[/caption]

[caption id="attachment_157951" align="alignnone" width="1152"]<a href="https://helloacm.com/a-five-year-milestone-at-microsoft-anniversary-crystal/microsoft-5-year-anniversary-crystal-2026-07-29-14-41-05/" rel="attachment wp-att-157951"><img src="https://helloacm.com/wp-content/uploads/2026/07/microsoft-5-year-anniversary-crystal-2026-07-29-14.41.05-scaled.jpg" alt="Top view of the 5 Year Crystal" width="1152" height="2048" class="size-full wp-image-157951" /></a> Top view of the 5 Year Crystal[/caption]

[caption id="attachment_157952" align="alignnone" width="941"]<a href="https://helloacm.com/a-five-year-milestone-at-microsoft-anniversary-crystal/microsoft-5-year-anniversary-crystal-2026-07-29-15-28-36/" rel="attachment wp-att-157952"><img src="https://helloacm.com/wp-content/uploads/2026/07/microsoft-5-year-anniversary-crystal-2026-07-29-15.28.36.png" alt="5 Year Microsoft Anniversary Crystal (Service Award)" width="941" height="1672" class="size-full wp-image-157952" /></a> 5 Year Microsoft Anniversary Crystal (Service Award)[/caption]

[caption id="attachment_157953" align="alignnone" width="720"]<a href="https://helloacm.com/a-five-year-milestone-at-microsoft-anniversary-crystal/msft-price-all-2026-07-30/" rel="attachment wp-att-157953"><img src="https://helloacm.com/wp-content/uploads/2026/07/msft-price-all-2026-07-30.jpg" alt="MSFT = 277 USD when I joined Microsoft" width="720" height="555" class="size-full wp-image-157953" /></a> MSFT = 277 USD when I joined Microsoft[/caption]

[caption id="attachment_157954" align="alignnone" width="588"]<a href="https://helloacm.com/a-five-year-milestone-at-microsoft-anniversary-crystal/msft-price-soars-206-07-30/" rel="attachment wp-att-157954"><img src="https://helloacm.com/wp-content/uploads/2026/07/msft-price-soars-206-07-30.jpg" alt="MSFT Stock Soars after Annoucement of Q4 2026 Earnings Report" width="588" height="547" class="size-full wp-image-157954" /></a> MSFT Stock Soars after Annoucement of Q4 2026 Earnings Report[/caption]

Facts of the Microsoft 5 year Anniversary Crystal Base: 0.6 kg, The Top: 0.6kg - Combined: 1.25 kg.

<h3>Microsoft MSFT Stock Price & 2026 Q4 Earnings Report</h3>
Microsoft has released its FY2026 financial results, officially closing out the fiscal year. Several key metrics for the fourth quarter significantly exceeded market expectations, and the company’s share price rose by as much as approximately 9% in after-hours trading following the announcement.

Looking at the headline figures, Microsoft generated total annual revenue of $331.8 billion, up 18% year over year. Full-year net income reached $133.7 billion, representing an overall net profit margin of 40.3%. Fourth-quarter revenue came in at $90 billion, also up 18% year over year and well above the market consensus.

Microsoft’s AI-related businesses achieved two major milestones.

First, Azure cloud services grew by 43% year over year in the fourth quarter, far exceeding the market’s previous expectation of around 39%. Azure’s annual revenue also surpassed $100 billion for the first time. Management expects growth to reach approximately 45% in the next quarter, once again ahead of expectations.

Second, Microsoft 365 Copilot has now exceeded 30 million paid seats, with most of them purchased in bulk by enterprise customers. More than 70% of Fortune 500 companies have deployed Microsoft 365 Copilot, while the number of customers purchasing more than 10,000 seats has quadrupled year over year. This clearly shows that the commercial adoption of enterprise AI is accelerating.

Even more notably, Microsoft currently has $678 billion in contracted long-term orders that have not yet been recognised as revenue. Given that these contracts have an average duration of roughly two to three years, the foundation for Microsoft’s growth over the next two years is largely secured.

There is no denying it—this was an exceptionally strong set of results.

<blockquote>
MSFT had no trading price on Monday, 5 July 2021, because Nasdaq was closed for the observed US Independence Day holiday.

The most recent price was from Friday, 2 July 2021:

Closing price: $277.65
Adjusted close: $266.46
Open: $272.82
High: $278.00
Low: $272.50

Therefore, for a portfolio valuation as of 5 July 2021, use $277.65 per MSFT share—or the adjusted price if you are calculating historical investment returns.
</blockquote>

[show_file file="/var/www/wp-post-common/helloacm.com/microsoft.php"]

[show_posts keyword="Microsoft"]

Linkedin Post: <a href="https://www.linkedin.com/feed/update/urn:li:activity:7488253654832160768/" title="Grateful to celebrate five years at Microsoft and receive this service award.">Microsoft 5-year Service Award: Anniversary Crystals</a>

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/chatgpt-refactors-rewrites-the-code-using-promise-all-sending-requests-in-parallel/" rel="bookmark" title="ChatGPT Refactors/Rewrites the Code using Promise.All &#8211; Sending Requests in Parallel">ChatGPT Refactors/Rewrites the Code using Promise.All &#8211; Sending Requests in Parallel</a> <small>In one of my project, I have the following code (Node/Javascript) that invokes a few...</small></li>
<li><a href="https://helloacm.com/bash-how-to-get-http-response-code-using-curl-command/" rel="bookmark" title="BASH: How to Get HTTP Response Code using Curl Command?">BASH: How to Get HTTP Response Code using Curl Command?</a> <small>To check the HTTP response code after running a curl command, you can use the...</small></li>
<li><a href="https://helloacm.com/chessly-british-short-hairs-classified-as-persian-cat-by-resnet-50/" rel="bookmark" title="Chessly (British Short Hairs) Classified as Persian Cat by ResNet-50">Chessly (British Short Hairs) Classified as Persian Cat by ResNet-50</a> <small>Chessly is one of my cat, she is a British shorthairs. However, she has been...</small></li>
<li><a href="https://helloacm.com/interview-question-the-number-of-bits-required-to-convert-one-integer-to-another-cc-function/" rel="bookmark" title="Interview Question: The Number of Bits Required to Convert One Integer to Another (C/C++ function)">Interview Question: The Number of Bits Required to Convert One Integer to Another (C/C++ function)</a> <small>The question is: how many bits are required to change if we want to convert...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-introduction-to-units-of-information-byte-kb-mb-gb-tb-pb/" rel="bookmark" title="Teaching Kids Programming &#8211; Introduction to Units of Information (Byte, KB, MB, GB, TB, PB)">Teaching Kids Programming &#8211; Introduction to Units of Information (Byte, KB, MB, GB, TB, PB)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms Information is the lifeblood of the...</small></li>
<li><a href="https://helloacm.com/microsofts-excel-just-got-smarter-the-new-copilot-function/" rel="bookmark" title="Microsoft&#8217;s Excel Just Got Smarter: The New Copilot Function">Microsoft&#8217;s Excel Just Got Smarter: The New Copilot Function</a> <small>All in AI. Microsoft has integrated AI (Copilot) to its Office products. I’m thrilled to...</small></li>
<li><a href="https://helloacm.com/how-to-modify-the-git-commit-messages-after-your-push-your-branch/" rel="bookmark" title="How to Modify the Git Commit Messages After Your Push Your Branch?">How to Modify the Git Commit Messages After Your Push Your Branch?</a> <small>Git is a popular and widely used version control system. If you stage your local...</small></li>
<li><a href="https://helloacm.com/coding-exercise-simple-nl-implementation-on-windows-platform-using-c-gcc/" rel="bookmark" title="Coding Exercise &#8211; Simple [nl] Implementation on Windows Platform using C++ (GCC)">Coding Exercise &#8211; Simple [nl] Implementation on Windows Platform using C++ (GCC)</a> <small>On Linux BASH shell, the &#8216;nl&#8217; utility is used to print out text file (or...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://helloacm.com/a-five-year-milestone-at-microsoft-anniversary-crystal/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Calculating Pi with Numerical Integration in Python and C++</title>
		<link>https://helloacm.com/calculating-pi-with-numerical-integration-in-python-and-c/</link>
					<comments>https://helloacm.com/calculating-pi-with-numerical-integration-in-python-and-c/#respond</comments>
		
		<dc:creator><![CDATA[ACMer]]></dc:creator>
		<pubDate>Mon, 20 Jul 2026 14:55:56 +0000</pubDate>
				<category><![CDATA[c / c++]]></category>
		<category><![CDATA[C/C++]]></category>
		<category><![CDATA[math]]></category>
		<category><![CDATA[programming languages]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[algorithms]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[Calculus]]></category>
		<category><![CDATA[definite integral]]></category>
		<category><![CDATA[Distributed Computing]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Midpoint Rule]]></category>
		<category><![CDATA[multithreading]]></category>
		<category><![CDATA[Numerical Analysis]]></category>
		<category><![CDATA[Numerical Integration]]></category>
		<category><![CDATA[Parallel Computing]]></category>
		<category><![CDATA[pi]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[Single-Threading]]></category>
		<category><![CDATA[Trapezoidal Rule]]></category>
		<guid isPermaLink="false">https://helloacm.com/?p=157928</guid>

					<description><![CDATA[<blockquote>
This article explains how to approximate Pi using the definite integral [math]\pi=\int_0^1\frac{4}{1+x^2},dx[/math]. It introduces the mathematics behind the identity, explains the trapezoidal and midpoint integration methods, and provides single-threaded and multithreaded implementations in both Python and C++. It also demonstrates how the same calculation can be divided across five distributed computing nodes, with a discussion of numerical accuracy, performance, parallelism, and practical limitations.
</blockquote>

[caption id="attachment_157942" align="alignnone" width="449"]<a href="https://helloacm.com/calculating-pi-with-numerical-integration-in-python-and-c/integral-math-pi/" rel="attachment wp-att-157942"><img src="https://helloacm.com/wp-content/uploads/2026/07/integral-math-pi.png" alt="The Definite Integral Computes the Pi" width="449" height="388" class="size-full wp-image-157942" /></a> The Definite Integral Computes the Pi[/caption]

Pi, written as [math]\pi[/math], appears throughout mathematics, physics, engineering, statistics, and computer science. Although <a href="https://helloacm.com/ai-coding-agents-are-reshaping-the-barrier-to-programming/" title="AI Coding Agents Are Reshaping the Barrier to Programming">programming</a> languages normally provide a built-in value of Pi, calculating it ourselves is a useful way to learn about calculus, numerical integration, multithreading, and distributed computing.

In this article, we will calculate Pi using the definite integral:

[math]
\pi=\int_0^1\frac{4}{1+x^2}dx
[/math]

We will cover:

<ul>

<li>Why the integral equals Pi</li>

<li>How numerical integration approximates an integral</li>

<li>The trapezoidal rule</li>

<li>The midpoint rule</li>

<li>Single-threaded Python</li>

<li>Multithreaded Python</li>

<li>Single-threaded C++</li>

<li>Multithreaded C++</li>

<li>How the same algorithm can be distributed across five nodes</li>

</ul>

<h2>Why Does This Integral Equal Pi?</h2>

Consider the integral:

[math]
\int_0^1\frac{4}{1+x^2}dx
[/math]

The key observation is that the derivative of the inverse tangent function is:

[math]
\frac{d}{dx}\arctan(x)=\frac{1}{1+x^2}
[/math]

Therefore:

[math]
\int\frac{4}{1+x^2}dx=4\arctan(x)+C
[/math]

Applying the limits from zero to one gives:

[math]
\int_0^1\frac{4}{1+x^2}dx=\left[4\arctan(x)\right]_0^1
[/math]

This means:

[math]
\int_0^1\frac{4}{1+x^2}dx=4\arctan(1)-4\arctan(0)
[/math]

We know that:

[math]
\arctan(1)=\frac{\pi}{4}
[/math]

and:

[math]
\arctan(0)=0
[/math]

Therefore:

[math]
4\left(\frac{\pi}{4}\right)-4(0)=\pi
[/math]

So:

[math]
\boxed{\pi=\int_0^1\frac{4}{1+x^2}dx}
[/math]

This gives us a convenient way to calculate Pi numerically.

<h2>How Numerical Integration Works</h2>

A computer does not need to solve the integral symbolically. Instead, it can divide the interval into many small pieces and approximate the area under the curve.

Suppose we want to calculate:

[math]
I=\int_a^b f(x)dx
[/math]

Divide the interval [math][a,b][/math] into [math]N[/math] equal subintervals.

The width of each interval is:

[math]
h=\frac{b-a}{N}
[/math]

The points dividing the interval are:

[math]
x_i=a+ih
[/math]

where:

[math]
i=0,1,2,\ldots,N
[/math]

There are several ways to approximate the area of each small section. Two common methods are:

<ul>

<li>The trapezoidal rule</li>

<li>The midpoint rule</li>

</ul>

<h2>The Trapezoidal Rule</h2>

The formula involving [math]f(0)[/math], [math]f(1)[/math], and division by two is the trapezoidal rule.

For one interval from [math]x_i[/math] to [math]x_{i+1}[/math], the function is approximated by a straight line. The resulting shape is a trapezoid.

Its area is:

[math]
A_i\approx
\frac{h}{2}
\left(
f(x_i)+f(x_{i+1})
\right)
[/math]

Adding the areas of all trapezoids gives:

[math]
T_N=
\frac{h}{2}
\left[
f(x_0)
+2f(x_1)
+2f(x_2)
+\cdots
+2f(x_{N-1})
+f(x_N)
\right]
[/math]

An equivalent and often easier-to-implement form is:

[math]
\boxed{
T_N=
h\left[
\frac{f(a)+f(b)}{2}
+
\sum_{i=1}^{N-1}f(a+ih)
\right]
}
[/math]

The two endpoints receive half weight:

[math]
\frac{f(a)+f(b)}{2}
[/math]

All interior points receive full weight:

[math]
f(a+h)+f(a+2h)+\cdots+f(b-h)
[/math]

For our Pi integral:

[math]
f(x)=\frac{4}{1+x^2}
[/math]

and:

[math]
a=0,\qquad b=1
[/math]

Therefore:

[math]
h=\frac{1}{N}
[/math]

The trapezoidal approximation becomes:

[math] \pi\approx h[\frac{f(0)+f(1)}{2}+\sum_{i=1}^{N-1}f(ih)] [/math]

Since:

[math]
f(0)=\frac{4}{1+0^2}=4
[/math]

and:

[math]
f(1)=\frac{4}{1+1^2}=2
[/math]

we can also write:

[math] \pi\approx h[3+\sum_{i=1}^{N-1}\frac{4}{1+(ih)^2}] [/math]

<h3>A Small Trapezoidal Example</h3>

Suppose we use four intervals:

[math]
N=4
[/math]

The interval width is:

[math]
h=\frac{1}{4}=0.25
[/math]

The five boundary points are:

[math]
0,\quad0.25,\quad0.5,\quad0.75,\quad1
[/math]

The function values are approximately:

[math]
f(0)=4
[/math]

[math]
f(0.25)\approx3.764706
[/math]

[math]
f(0.5)=3.2
[/math]

[math]
f(0.75)=2.56
[/math]

[math]
f(1)=2
[/math]

Applying the trapezoidal formula:

[math]
T_4=
0.25\left[
\frac{4+2}{2}
+3.764706+3.2+2.56
\right]
[/math]

Therefore:

[math]
T_4\approx3.131176
[/math]

The actual value is:

[math]
\pi\approx3.141593
[/math]

Using only four intervals already gives a reasonable approximation. Increasing [math]N[/math] improves the result.

<h2>The Midpoint Rule</h2>

The implementations later in this article primarily use the midpoint rule.

Instead of evaluating the function at the boundaries of each interval, the midpoint rule evaluates it at the centre.

The midpoint of interval [math]i[/math] is:

[math]
x_i=
a+\left(i+\frac{1}{2}\right)h
[/math]

The area of that interval is approximated by a rectangle:

[math]
A_i\approx f(x_i)h
[/math]

Adding all rectangles gives:

[math]
\boxed{
M_N=
h\sum_{i=0}^{N-1}
f\left(
a+\left(i+\frac{1}{2}\right)h
\right)
}
[/math]

For the Pi integral, [math]a=0[/math], [math]b=1[/math], and [math]h=1/N[/math].

Therefore:

[math]
x_i=\left(i+\frac{1}{2}\right)h
[/math]

and:

[math] \pi\approx h\sum_{i=0}^{N-1} \frac{4}{1+x_i^2} [/math]

Substituting [math]h=1/N[/math]:

[math]
\boxed{
\pi\approx
\frac{1}{N}
\sum_{i=0}^{N-1}
\frac{4}{
1+
\left(
\frac{i+\frac{1}{2}}{N}
\right)^2
}
}
[/math]

The larger [math]N[/math] becomes, the closer the estimate gets to Pi.

<h2>Trapezoidal Rule Versus Midpoint Rule</h2>

<table>

<thead>

<tr>

<th>Method</th>

<th>Sample positions</th>

<th>Formula</th>

</tr>

</thead>

<tbody>

<tr>

<td>Trapezoidal rule</td>

<td>Interval boundaries</td>

<td>[math]h\left[\frac{f(a)+f(b)}{2}+\sum_{i=1}^{N-1}f(a+ih)\right][/math]</td>

</tr>

<tr>

<td>Midpoint rule</td>

<td>Centre of each interval</td>

<td>[math]h\sum_{i=0}^{N-1}f\left(a+\left(i+\frac12\right)h\right)[/math]</td>

</tr>

</tbody>

</table>

For a smooth function, both methods normally have an error proportional to:

[math]
\frac{1}{N^2}
[/math]

However, the midpoint rule is often more accurate than the trapezoidal rule when both use the same number of intervals.

<h2>Single-Threaded Python Using the Midpoint Rule</h2>

The following Python program uses 25 million intervals.

<pre lang=py>
import math
import time


def calculate_pi(total_steps: int) -&gt; float:
    if total_steps &lt;= 0:
        raise ValueError("total_steps must be positive")

    step_width = 1.0 / total_steps
    total = 0.0

    for step in range(total_steps):
        midpoint = (step + 0.5) * step_width
        total += 4.0 / (1.0 + midpoint * midpoint)

    return total * step_width


def main() -&gt; None:
    total_steps = 25_000_000

    started_at = time.perf_counter()
    pi_estimate = calculate_pi(total_steps)
    elapsed_seconds = time.perf_counter() - started_at

    absolute_error = abs(pi_estimate - math.pi)

    print(f"Estimated Pi:   {pi_estimate:.15f}")
    print(f"Reference Pi:   {math.pi:.15f}")
    print(f"Absolute error: {absolute_error:.3e}")
    print(f"Elapsed time:   {elapsed_seconds:.3f} seconds")


if __name__ == "__main__":
    main()
</pre>

The core calculation is:

<pre lang=py>
midpoint = (step + 0.5) * step_width
total += 4.0 / (1.0 + midpoint * midpoint)
</pre>

The first line calculates the midpoint of the current interval:

[math]
x_i=\left(i+\frac12\right)h
[/math]

The second line evaluates:

[math]
f(x_i)=\frac{4}{1+x_i^2}
[/math]

After all values have been added, the result is multiplied by the interval width:

<pre lang=py>
return total * step_width
</pre>

Mathematically, this calculates:

[math]
h\sum_{i=0}^{N-1}f(x_i)
[/math]

<h2>Single-Threaded Python Using the Trapezoidal Rule</h2>

The trapezoidal version evaluates the function at the interval boundaries rather than at the midpoints.

<pre lang=py>
import math
import time


def calculate_pi_trapezoidal(total_steps: int) -&gt; float:
    if total_steps &lt;= 0:
        raise ValueError("total_steps must be positive")

    h = 1.0 / total_steps

    def f(x: float) -&gt; float:
        return 4.0 / (1.0 + x * x)

    total = 0.5 * (f(0.0) + f(1.0))

    for step in range(1, total_steps):
        x = step * h
        total += f(x)

    return total * h


def main() -&gt; None:
    total_steps = 25_000_000

    started_at = time.perf_counter()
    pi_estimate = calculate_pi_trapezoidal(total_steps)
    elapsed_seconds = time.perf_counter() - started_at

    absolute_error = abs(pi_estimate - math.pi)

    print(f"Estimated Pi:   {pi_estimate:.15f}")
    print(f"Reference Pi:   {math.pi:.15f}")
    print(f"Absolute error: {absolute_error:.3e}")
    print(f"Elapsed time:   {elapsed_seconds:.3f} seconds")


if __name__ == "__main__":
    main()
</pre>

The endpoint contribution is calculated by:

<pre lang=py>
total = 0.5 * (f(0.0) + f(1.0))
</pre>

This corresponds to:

[math]
\frac{f(0)+f(1)}{2}
[/math]

The loop calculates the interior sum:

<pre lang=py>
for step in range(1, total_steps):
    x = step * h
    total += f(x)
</pre>

This corresponds to:

[math]
\sum_{i=1}^{N-1}f(ih)
[/math]

Finally, the total is multiplied by [math]h[/math]:

<pre lang=py>
return total * h
</pre>

<h2>Multithreaded Python Using the Midpoint Rule</h2>

We can divide the 25 million intervals among five workers.

For worker [math]r[/math] out of [math]P[/math] workers, the start index is:

[math]
\text{start}_r=
\left\lfloor
\frac{Nr}{P}
\right\rfloor
[/math]

The end index is:

[math]
\text{end}_r=
\left\lfloor
\frac{N(r+1)}{P}
\right\rfloor
[/math]

For five workers and 25 million intervals:

<table>

<thead>

<tr>

<th>Worker</th>

<th>Start step</th>

<th>End step</th>

<th>Number of steps</th>

</tr>

</thead>

<tbody>

<tr>

<td>0</td>

<td>0</td>

<td>5,000,000</td>

<td>5,000,000</td>

</tr>

<tr>

<td>1</td>

<td>5,000,000</td>

<td>10,000,000</td>

<td>5,000,000</td>

</tr>

<tr>

<td>2</td>

<td>10,000,000</td>

<td>15,000,000</td>

<td>5,000,000</td>

</tr>

<tr>

<td>3</td>

<td>15,000,000</td>

<td>20,000,000</td>

<td>5,000,000</td>

</tr>

<tr>

<td>4</td>

<td>20,000,000</td>

<td>25,000,000</td>

<td>5,000,000</td>

</tr>

</tbody>

</table>

Here is an implementation using <code>ThreadPoolExecutor</code>:

<pre lang=py>
import math
import time
from concurrent.futures import ThreadPoolExecutor


def calculate_partial_sum(
    start_step: int,
    end_step: int,
    step_width: float,
) -&gt; float:
    partial_sum = 0.0

    for step in range(start_step, end_step):
        midpoint = (step + 0.5) * step_width
        partial_sum += 4.0 / (1.0 + midpoint * midpoint)

    return partial_sum


def calculate_pi_multithreaded(
    total_steps: int,
    worker_count: int,
) -&gt; float:
    if total_steps &lt;= 0:
        raise ValueError("total_steps must be positive")

    if worker_count &lt;= 0:
        raise ValueError("worker_count must be positive")

    step_width = 1.0 / total_steps
    ranges = []

    for worker_id in range(worker_count):
        start_step = total_steps * worker_id // worker_count
        end_step = total_steps * (worker_id + 1) // worker_count
        ranges.append((start_step, end_step))

    with ThreadPoolExecutor(max_workers=worker_count) as executor:
        futures = [
            executor.submit(
                calculate_partial_sum,
                start_step,
                end_step,
                step_width,
            )
            for start_step, end_step in ranges
        ]

        partial_sums = [
            future.result()
            for future in futures
        ]

    return sum(partial_sums) * step_width


def main() -&gt; None:
    total_steps = 25_000_000
    worker_count = 5

    started_at = time.perf_counter()

    pi_estimate = calculate_pi_multithreaded(
        total_steps,
        worker_count,
    )

    elapsed_seconds = time.perf_counter() - started_at
    absolute_error = abs(pi_estimate - math.pi)

    print(f"Workers:        {worker_count}")
    print(f"Estimated Pi:   {pi_estimate:.15f}")
    print(f"Reference Pi:   {math.pi:.15f}")
    print(f"Absolute error: {absolute_error:.3e}")
    print(f"Elapsed time:   {elapsed_seconds:.3f} seconds")


if __name__ == "__main__":
    main()
</pre>

Each worker calculates one partial sum:

[math]
S_r=
\sum_{i=\text{start}_r}^{\text{end}_r-1}
\frac{4}{1+x_i^2}
[/math]

The main thread combines the results:

[math] \pi\approx h(S_0+S_1+S_2+S_3+S_4) [/math]

<h3>An Important Python Limitation</h3>

The multithreaded Python version demonstrates how to divide the calculation into separate ranges, but it may not execute faster than the single-threaded version.

Standard CPython has a Global Interpreter Lock, commonly called the GIL. For CPU-bound Python code, only one thread normally executes Python bytecode at a time.

Therefore, five Python threads do not necessarily use five CPU cores effectively.

The threaded version may be:

<ul>

<li>Approximately as fast as the single-threaded version</li>

<li>Slightly slower because of thread-management overhead</li>

<li>Useful for demonstrating work partitioning</li>

<li>Unsuitable for achieving true CPU parallelism in normal CPython</li>

</ul>

For true CPU <a href="https://helloacm.com/why-parallelism-isnt-infinite-amdahl-vs-gustafson-explained-simply/" title="Why Parallelism Isn’t Infinite: Amdahl vs Gustafson Explained Simply">parallelism</a> in Python, better choices include:

<ul>

<li><code>ProcessPoolExecutor</code></li>

<li>The <code>multiprocessing</code> module</li>

<li>NumPy</li>

<li>Native extensions</li>

<li>MPI</li>

<li>Separate distributed processes</li>

</ul>

<h2>Single-Threaded C++ Using the Midpoint Rule</h2>

C++ is well suited to tight numerical loops because it compiles directly to native machine code.

<pre lang=cpp>
#include &lt;chrono&gt;
#include &lt;cmath&gt;
#include &lt;cstdint&gt;
#include &lt;iomanip&gt;
#include &lt;iostream&gt;
#include &lt;stdexcept&gt;


double calculate_pi(std::uint64_t total_steps) {
    if (total_steps == 0) {
        throw std::invalid_argument(
            "total_steps must be positive"
        );
    }

    const double step_width =
        1.0 / static_cast&lt;double&gt;(total_steps);

    double total = 0.0;

    for (
        std::uint64_t step = 0;
        step &lt; total_steps;
        ++step
    ) {
        const double midpoint =
            (static_cast&lt;double&gt;(step) + 0.5)
            * step_width;

        total += 4.0 / (1.0 + midpoint * midpoint);
    }

    return total * step_width;
}


int main() {
    constexpr std::uint64_t total_steps = 25'000'000;

    const auto started_at =
        std::chrono::steady_clock::now();

    const double pi_estimate =
        calculate_pi(total_steps);

    const auto finished_at =
        std::chrono::steady_clock::now();

    const double elapsed_seconds =
        std::chrono::duration&lt;double&gt;(
            finished_at - started_at
        ).count();

    const double reference_pi = std::acos(-1.0);

    const double absolute_error =
        std::abs(pi_estimate - reference_pi);

    std::cout
        &lt;&lt; std::fixed
        &lt;&lt; std::setprecision(15);

    std::cout
        &lt;&lt; "Estimated Pi:   "
        &lt;&lt; pi_estimate
        &lt;&lt; '\n';

    std::cout
        &lt;&lt; "Reference Pi:   "
        &lt;&lt; reference_pi
        &lt;&lt; '\n';

    std::cout
        &lt;&lt; std::scientific
        &lt;&lt; std::setprecision(3);

    std::cout
        &lt;&lt; "Absolute error: "
        &lt;&lt; absolute_error
        &lt;&lt; '\n';

    std::cout
        &lt;&lt; std::fixed
        &lt;&lt; std::setprecision(3);

    std::cout
        &lt;&lt; "Elapsed time:   "
        &lt;&lt; elapsed_seconds
        &lt;&lt; " seconds\n";

    return 0;
}
</pre>

Compile it with optimisation enabled:

<pre lang=cpp>
g++ -O3 -std=c++17 pi_single.cpp -o pi_single
</pre>

Run it using:

<pre lang=cpp>
./pi_single
</pre>

The <code>-O3</code> option enables aggressive compiler optimisation. Without optimisation, the program may run considerably more slowly.

<h2>Single-Threaded C++ Using the Trapezoidal Rule</h2>

The following C++ version implements the trapezoidal formula:

[math]
T_N=
h\left[
\frac{f(0)+f(1)}{2}
+
\sum_{i=1}^{N-1}f(ih)
\right]
[/math]

<pre lang=cpp>
#include &lt;chrono&gt;
#include &lt;cmath&gt;
#include &lt;cstdint&gt;
#include &lt;iomanip&gt;
#include &lt;iostream&gt;
#include &lt;stdexcept&gt;


double f(double x) {
    return 4.0 / (1.0 + x * x);
}


double calculate_pi_trapezoidal(
    std::uint64_t total_steps
) {
    if (total_steps == 0) {
        throw std::invalid_argument(
            "total_steps must be positive"
        );
    }

    const double h =
        1.0 / static_cast&lt;double&gt;(total_steps);

    double total =
        0.5 * (f(0.0) + f(1.0));

    for (
        std::uint64_t step = 1;
        step &lt; total_steps;
        ++step
    ) {
        const double x =
            static_cast&lt;double&gt;(step) * h;

        total += f(x);
    }

    return total * h;
}


int main() {
    constexpr std::uint64_t total_steps = 25'000'000;

    const auto started_at =
        std::chrono::steady_clock::now();

    const double pi_estimate =
        calculate_pi_trapezoidal(total_steps);

    const auto finished_at =
        std::chrono::steady_clock::now();

    const double elapsed_seconds =
        std::chrono::duration&lt;double&gt;(
            finished_at - started_at
        ).count();

    const double reference_pi = std::acos(-1.0);

    const double absolute_error =
        std::abs(pi_estimate - reference_pi);

    std::cout
        &lt;&lt; std::fixed
        &lt;&lt; std::setprecision(15);

    std::cout
        &lt;&lt; "Estimated Pi:   "
        &lt;&lt; pi_estimate
        &lt;&lt; '\n';

    std::cout
        &lt;&lt; "Reference Pi:   "
        &lt;&lt; reference_pi
        &lt;&lt; '\n';

    std::cout
        &lt;&lt; std::scientific
        &lt;&lt; std::setprecision(3);

    std::cout
        &lt;&lt; "Absolute error: "
        &lt;&lt; absolute_error
        &lt;&lt; '\n';

    std::cout
        &lt;&lt; std::fixed
        &lt;&lt; std::setprecision(3);

    std::cout
        &lt;&lt; "Elapsed time:   "
        &lt;&lt; elapsed_seconds
        &lt;&lt; " seconds\n";

    return 0;
}
</pre>

Compile it using:

<pre lang=cpp>
g++ -O3 -std=c++17 pi_trapezoidal.cpp -o pi_trapezoidal
</pre>

<h2>Multithreaded C++ Using the Midpoint Rule</h2>

Unlike ordinary CPython threads, C++ threads can execute CPU-bound work simultaneously on multiple processor cores.

The following implementation divides the calculation among five threads.

<pre lang=cpp>
#include &lt;chrono&gt;
#include &lt;cmath&gt;
#include &lt;cstdint&gt;
#include &lt;iomanip&gt;
#include &lt;iostream&gt;
#include &lt;numeric&gt;
#include &lt;stdexcept&gt;
#include &lt;thread&gt;
#include &lt;vector&gt;


double calculate_partial_sum(
    std::uint64_t start_step,
    std::uint64_t end_step,
    double step_width
) {
    double partial_sum = 0.0;

    for (
        std::uint64_t step = start_step;
        step &lt; end_step;
        ++step
    ) {
        const double midpoint =
            (static_cast&lt;double&gt;(step) + 0.5)
            * step_width;

        partial_sum +=
            4.0 / (1.0 + midpoint * midpoint);
    }

    return partial_sum;
}


double calculate_pi_multithreaded(
    std::uint64_t total_steps,
    std::size_t worker_count
) {
    if (total_steps == 0) {
        throw std::invalid_argument(
            "total_steps must be positive"
        );
    }

    if (worker_count == 0) {
        throw std::invalid_argument(
            "worker_count must be positive"
        );
    }

    const double step_width =
        1.0 / static_cast&lt;double&gt;(total_steps);

    std::vector&lt;std::thread&gt; workers;

    std::vector&lt;double&gt; partial_sums(
        worker_count,
        0.0
    );

    workers.reserve(worker_count);

    for (
        std::size_t worker_id = 0;
        worker_id &lt; worker_count;
        ++worker_id
    ) {
        const std::uint64_t start_step =
            total_steps
            * worker_id
            / worker_count;

        const std::uint64_t end_step =
            total_steps
            * (worker_id + 1)
            / worker_count;

        workers.emplace_back(
            [
                &amp;,
                worker_id,
                start_step,
                end_step
            ]() {
                partial_sums[worker_id] =
                    calculate_partial_sum(
                        start_step,
                        end_step,
                        step_width
                    );
            }
        );
    }

    for (std::thread&amp; worker : workers) {
        worker.join();
    }

    const double combined_sum =
        std::accumulate(
            partial_sums.begin(),
            partial_sums.end(),
            0.0
        );

    return combined_sum * step_width;
}


int main() {
    constexpr std::uint64_t total_steps = 25'000'000;
    constexpr std::size_t worker_count = 5;

    const auto started_at =
        std::chrono::steady_clock::now();

    const double pi_estimate =
        calculate_pi_multithreaded(
            total_steps,
            worker_count
        );

    const auto finished_at =
        std::chrono::steady_clock::now();

    const double elapsed_seconds =
        std::chrono::duration&lt;double&gt;(
            finished_at - started_at
        ).count();

    const double reference_pi = std::acos(-1.0);

    const double absolute_error =
        std::abs(pi_estimate - reference_pi);

    std::cout
        &lt;&lt; "Workers:        "
        &lt;&lt; worker_count
        &lt;&lt; '\n';

    std::cout
        &lt;&lt; std::fixed
        &lt;&lt; std::setprecision(15);

    std::cout
        &lt;&lt; "Estimated Pi:   "
        &lt;&lt; pi_estimate
        &lt;&lt; '\n';

    std::cout
        &lt;&lt; "Reference Pi:   "
        &lt;&lt; reference_pi
        &lt;&lt; '\n';

    std::cout
        &lt;&lt; std::scientific
        &lt;&lt; std::setprecision(3);

    std::cout
        &lt;&lt; "Absolute error: "
        &lt;&lt; absolute_error
        &lt;&lt; '\n';

    std::cout
        &lt;&lt; std::fixed
        &lt;&lt; std::setprecision(3);

    std::cout
        &lt;&lt; "Elapsed time:   "
        &lt;&lt; elapsed_seconds
        &lt;&lt; " seconds\n";

    return 0;
}
</pre>

Compile it with thread support and optimisation:

<pre lang=cpp>
g++ -O3 -std=c++17 -pthread pi_multithreaded.cpp -o pi_multithreaded
</pre>

Then run it:

<pre lang=cpp>
./pi_multithreaded
</pre>

<h3>Why Each Thread Uses a Local Sum</h3>

Inside each thread, the program calculates into a local variable:

<pre lang=cpp>
double partial_sum = 0.0;
</pre>

It does not update one shared global total during every iteration.

If every thread repeatedly updated the same variable, the program would need a mutex or atomic operation. That would introduce synchronisation and contention.

Instead, the program follows a map-and-reduce pattern:

<ol>

<li>Assign one range of intervals to each worker.</li>

<li>Let each worker calculate independently.</li>

<li>Store one partial result per worker.</li>

<li>Wait for all threads to complete.</li>

<li>Add the partial results together.</li>

</ol>

Mathematically:

[math]
S=S_0+S_1+\cdots+S_{P-1}
[/math]

The final approximation is:

[math]
\pi\approx Sh
[/math]

<h2>Extending the Algorithm to Five Distributed Nodes</h2>

Multithreading and distributed computing use the same mathematical partitioning, but they are different execution models.

Threads normally:

<ul>

<li>Run on one machine</li>

<li>Share the same memory</li>

<li>Belong to the same process</li>

<li>Communicate through shared variables</li>

</ul>

Distributed workers normally:

<ul>

<li>Run as separate processes</li>

<li>May run on separate machines</li>

<li>Do not share ordinary process memory</li>

<li>Communicate using files, sockets, MPI, RPC, or another distributed runtime</li>

</ul>

In a five-node job, every process receives a rank:

[math]
r\in{0,1,2,3,4}
[/math]

The total number of processes is:

[math]
P=5
[/math]

Each rank calculates its own range using:

[math]
\text{start}_r=
\left\lfloor
\frac{Nr}{P}
\right\rfloor
[/math]

and:

[math]
\text{end}_r=
\left\lfloor
\frac{N(r+1)}{P}
\right\rfloor
[/math]

In Python, the range assignment can be written as:

<pre lang=py>
import os


rank = int(os.environ["RANK"])
world_size = int(os.environ["WORLD_SIZE"])

start_step = total_steps * rank // world_size
end_step = total_steps * (rank + 1) // world_size
</pre>

Each rank calculates only its assigned section:

<pre lang=py>
partial_sum = 0.0

for step in range(start_step, end_step):
    midpoint = (step + 0.5) * step_width

    partial_sum += 4.0 / (
        1.0 + midpoint * midpoint
    )
</pre>

For five ranks, the final result is:

[math] \pi\approx h(S_0+S_1+S_2+S_3+S_4) [/math]

In the Singularity example, every rank writes one result file:

<pre>
rank-0.json
rank-1.json
rank-2.json
rank-3.json
rank-4.json
</pre>

Rank zero waits for all five files, reads their partial sums, adds them together, and produces the final Pi estimate.

This implements three distributed operations:

<ul>

<li><strong>Barrier:</strong> wait until all workers finish</li>

<li><strong>Gather:</strong> collect the partial results</li>

<li><strong>Reduce:</strong> add the partial sums together</li>

</ul>

The file-based approach is simple and easy to understand, but it assumes that all nodes can access the same shared output directory.

For a production distributed application, MPI or another collective-communication framework would normally be more robust.

<h2>Accuracy of the Numerical Methods</h2>

For sufficiently smooth functions, both the trapezoidal rule and midpoint rule have an error proportional to approximately:

[math]
\frac{1}{N^2}
[/math]

This means that doubling the number of intervals may reduce the numerical integration error by approximately a factor of four.

However, increasing [math]N[/math] indefinitely does not guarantee unlimited accuracy.

Computers store floating-point numbers with finite precision. When millions or billions of values are added, rounding errors can accumulate.

Parallel versions may also produce slightly different final digits from single-threaded versions because floating-point addition is not perfectly associative:

[math]
(a+b)+c\neq a+(b+c)
[/math]

The values are mathematically equivalent, but changing the order of floating-point additions can change the final rounded bits.

<h2>Performance Considerations</h2>

The multithreaded C++ implementation should normally outperform the single-threaded version when:

<ul>

<li>The machine has multiple CPU cores</li>

<li>The calculation is sufficiently large</li>

<li>The number of worker threads is reasonable</li>

<li>Compiler optimisation is enabled</li>

</ul>

Five threads do not guarantee a five-times speed improvement.

Performance depends on:

<ul>

<li>CPU core count</li>

<li>Processor frequency</li>

<li>Thermal throttling</li>

<li>Operating-system thread scheduling</li>

<li>Cache behaviour</li>

<li>Thread startup overhead</li>

<li>Other workloads running on the machine</li>

</ul>

For Python, the GIL is the main restriction. Adding more Python threads does not normally accelerate a pure Python CPU loop.

For distributed computing, node allocation, process startup, storage access, and result aggregation all add overhead.

Calculating Pi with 25 million intervals is a useful demonstration, but it is too small and simple to justify reserving several expensive GPU-backed nodes in a real production workload.

<h2>Comparing the Implementations</h2>

<table>

<thead>

<tr>

<th>Implementation</th>

<th>Execution model</th>

<th>True CPU parallelism</th>

<th>Expected performance</th>

</tr>

</thead>

<tbody>

<tr>

<td>Python single-threaded</td>

<td>One Python thread</td>

<td>No</td>

<td>Simple, but relatively slow</td>

</tr>

<tr>

<td>Python multithreaded</td>

<td>Several Python threads</td>

<td>Usually no because of the GIL</td>

<td>Often no faster than one thread</td>

</tr>

<tr>

<td>C++ single-threaded</td>

<td>One native thread</td>

<td>No</td>

<td>Usually much faster than Python</td>

</tr>

<tr>

<td>C++ multithreaded</td>

<td>Several native threads</td>

<td>Yes</td>

<td>Usually the fastest local version</td>

</tr>

<tr>

<td>Five-node distributed</td>

<td>Separate worker processes</td>

<td>Yes</td>

<td>Scalable, but has communication and startup overhead</td>

</tr>

</tbody>

</table>

<h2>Conclusion</h2>

The identity:

[math]
\pi=\int_0^1\frac{4}{1+x^2},dx
[/math]

provides a simple demonstration of how calculus can be converted into a computational problem.

The trapezoidal rule approximates the integral using straight lines between adjacent boundary points:

[math]
T_N=
h\left[
\frac{f(a)+f(b)}{2}
+
\sum_{i=1}^{N-1}f(a+ih)
\right]
[/math]

The midpoint rule approximates the integral using the centre of each interval:

[math]
M_N=
h\sum_{i=0}^{N-1}
f\left(
a+\left(i+\frac12\right)h
\right)
[/math]

The same mathematical calculation can be executed using:

<ul>

<li>A single loop on one CPU core</li>

<li>Several threads on one machine</li>

<li>Several processes using multiple CPU cores</li>

<li>Several distributed workers running on separate nodes</li>

</ul>

The mathematical algorithm remains largely unchanged. What changes is how the integration range is divided, where the partial sums are calculated, and how the partial results are combined.

This is the central pattern behind many parallel algorithms:

[math]
\boxed{
\text{divide the work}
\rightarrow
\text{calculate partial results}
\rightarrow
\text{combine the results}
}
[/math]

Although calculating Pi is a small example, the same map-and-reduce structure appears in scientific simulation, machine learning, data processing, rendering, financial modelling, and large-scale distributed systems.

[show_file file="/var/www/wp-post-common/helloacm.com/math.php"]

[show_posts keyword="math"]

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/comparisions-of-push_back-and-emplace_back-in-c-stdvector/" rel="bookmark" title="Comparisions of push_back and emplace_back in C++ std::vector">Comparisions of push_back and emplace_back in C++ std::vector</a> <small>In C++, both push_back and emplace_back are methods of the std::vector class used to add...</small></li>
<li><a href="https://helloacm.com/turn-your-raspberry-pi-into-a-family-network-drive-2tb-wd-hard-drive-setup-for-kids-macs/" rel="bookmark" title="Turn Your Raspberry Pi into a Family Network Drive: 2TB WD Hard Drive Setup for Kids’ Macs">Turn Your Raspberry Pi into a Family Network Drive: 2TB WD Hard Drive Setup for Kids’ Macs</a> <small>“Create a 2TB Network Drive with Raspberry Pi for Your Family” “Raspberry Pi + WD...</small></li>
<li><a href="https://helloacm.com/tutorial-on-c-smart-pointers/" rel="bookmark" title="Tutorial on C++ Smart Pointers">Tutorial on C++ Smart Pointers</a> <small>Tutorial on Smart Pointers in C++ Smart pointers in C++ provide automatic and safe memory...</small></li>
<li><a href="https://helloacm.com/const-vs-constexpr-in-c/" rel="bookmark" title="const vs constexpr in C++">const vs constexpr in C++</a> <small>C++ const vs constexpr: What’s the Real Difference? Both are used in C++ to define...</small></li>
<li><a href="https://helloacm.com/interview-coding-exercise-nested-string-python/" rel="bookmark" title="Interview Coding Exercise &#8211; Nested String (Python)">Interview Coding Exercise &#8211; Nested String (Python)</a> <small>Nested String A string S consisting of N characters is considered to be properly nested...</small></li>
<li><a href="https://helloacm.com/gaming-adaptations-for-different-platforms/" rel="bookmark" title="Gaming Adaptations for Different Platforms">Gaming Adaptations for Different Platforms</a> <small>One of the trickiest challenges facing any software developer is figuring out how their coding...</small></li>
<li><a href="https://helloacm.com/from-idea-to-github-pages-building-tools-with-ai-and-vibe-coding/" rel="bookmark" title="From Idea to GitHub Pages: Building Tools with AI and Vibe Coding">From Idea to GitHub Pages: Building Tools with AI and Vibe Coding</a> <small>Built and Open-Sourced A Few Mini Tools with AI Recently, I used ChatGPT-4o and o4-mini...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-delete-nodes-from-linked-list-present-in-array/" rel="bookmark" title="Teaching Kids Programming &#8211; Delete Nodes From Linked List Present in Array">Teaching Kids Programming &#8211; Delete Nodes From Linked List Present in Array</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given an array of...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<blockquote>
This article explains how to approximate Pi using the definite integral [math]\pi=\int_0^1\frac{4}{1+x^2},dx[/math]. It introduces the mathematics behind the identity, explains the trapezoidal and midpoint integration methods, and provides single-threaded and multithreaded implementations in both Python and C++. It also demonstrates how the same calculation can be divided across five distributed computing nodes, with a discussion of numerical accuracy, performance, parallelism, and practical limitations.
</blockquote>

[caption id="attachment_157942" align="alignnone" width="449"]<a href="https://helloacm.com/calculating-pi-with-numerical-integration-in-python-and-c/integral-math-pi/" rel="attachment wp-att-157942"><img src="https://helloacm.com/wp-content/uploads/2026/07/integral-math-pi.png" alt="The Definite Integral Computes the Pi" width="449" height="388" class="size-full wp-image-157942" /></a> The Definite Integral Computes the Pi[/caption]

Pi, written as [math]\pi[/math], appears throughout mathematics, physics, engineering, statistics, and computer science. Although <a href="https://helloacm.com/ai-coding-agents-are-reshaping-the-barrier-to-programming/" title="AI Coding Agents Are Reshaping the Barrier to Programming">programming</a> languages normally provide a built-in value of Pi, calculating it ourselves is a useful way to learn about calculus, numerical integration, multithreading, and distributed computing.

In this article, we will calculate Pi using the definite integral:

[math]
\pi=\int_0^1\frac{4}{1+x^2}dx
[/math]

We will cover:

<ul>

<li>Why the integral equals Pi</li>

<li>How numerical integration approximates an integral</li>

<li>The trapezoidal rule</li>

<li>The midpoint rule</li>

<li>Single-threaded Python</li>

<li>Multithreaded Python</li>

<li>Single-threaded C++</li>

<li>Multithreaded C++</li>

<li>How the same algorithm can be distributed across five nodes</li>

</ul>

<h2>Why Does This Integral Equal Pi?</h2>

Consider the integral:

[math]
\int_0^1\frac{4}{1+x^2}dx
[/math]

The key observation is that the derivative of the inverse tangent function is:

[math]
\frac{d}{dx}\arctan(x)=\frac{1}{1+x^2}
[/math]

Therefore:

[math]
\int\frac{4}{1+x^2}dx=4\arctan(x)+C
[/math]

Applying the limits from zero to one gives:

[math]
\int_0^1\frac{4}{1+x^2}dx=\left[4\arctan(x)\right]_0^1
[/math]

This means:

[math]
\int_0^1\frac{4}{1+x^2}dx=4\arctan(1)-4\arctan(0)
[/math]

We know that:

[math]
\arctan(1)=\frac{\pi}{4}
[/math]

and:

[math]
\arctan(0)=0
[/math]

Therefore:

[math]
4\left(\frac{\pi}{4}\right)-4(0)=\pi
[/math]

So:

[math]
\boxed{\pi=\int_0^1\frac{4}{1+x^2}dx}
[/math]

This gives us a convenient way to calculate Pi numerically.

<h2>How Numerical Integration Works</h2>

A computer does not need to solve the integral symbolically. Instead, it can divide the interval into many small pieces and approximate the area under the curve.

Suppose we want to calculate:

[math]
I=\int_a^b f(x)dx
[/math]

Divide the interval [math][a,b][/math] into [math]N[/math] equal subintervals.

The width of each interval is:

[math]
h=\frac{b-a}{N}
[/math]

The points dividing the interval are:

[math]
x_i=a+ih
[/math]

where:

[math]
i=0,1,2,\ldots,N
[/math]

There are several ways to approximate the area of each small section. Two common methods are:

<ul>

<li>The trapezoidal rule</li>

<li>The midpoint rule</li>

</ul>

<h2>The Trapezoidal Rule</h2>

The formula involving [math]f(0)[/math], [math]f(1)[/math], and division by two is the trapezoidal rule.

For one interval from [math]x_i[/math] to [math]x_{i+1}[/math], the function is approximated by a straight line. The resulting shape is a trapezoid.

Its area is:

[math]
A_i\approx
\frac{h}{2}
\left(
f(x_i)+f(x_{i+1})
\right)
[/math]

Adding the areas of all trapezoids gives:

[math]
T_N=
\frac{h}{2}
\left[
f(x_0)
+2f(x_1)
+2f(x_2)
+\cdots
+2f(x_{N-1})
+f(x_N)
\right]
[/math]

An equivalent and often easier-to-implement form is:

[math]
\boxed{
T_N=
h\left[
\frac{f(a)+f(b)}{2}
+
\sum_{i=1}^{N-1}f(a+ih)
\right]
}
[/math]

The two endpoints receive half weight:

[math]
\frac{f(a)+f(b)}{2}
[/math]

All interior points receive full weight:

[math]
f(a+h)+f(a+2h)+\cdots+f(b-h)
[/math]

For our Pi integral:

[math]
f(x)=\frac{4}{1+x^2}
[/math]

and:

[math]
a=0,\qquad b=1
[/math]

Therefore:

[math]
h=\frac{1}{N}
[/math]

The trapezoidal approximation becomes:

[math] \pi\approx h[\frac{f(0)+f(1)}{2}+\sum_{i=1}^{N-1}f(ih)] [/math]

Since:

[math]
f(0)=\frac{4}{1+0^2}=4
[/math]

and:

[math]
f(1)=\frac{4}{1+1^2}=2
[/math]

we can also write:

[math] \pi\approx h[3+\sum_{i=1}^{N-1}\frac{4}{1+(ih)^2}] [/math]

<h3>A Small Trapezoidal Example</h3>

Suppose we use four intervals:

[math]
N=4
[/math]

The interval width is:

[math]
h=\frac{1}{4}=0.25
[/math]

The five boundary points are:

[math]
0,\quad0.25,\quad0.5,\quad0.75,\quad1
[/math]

The function values are approximately:

[math]
f(0)=4
[/math]

[math]
f(0.25)\approx3.764706
[/math]

[math]
f(0.5)=3.2
[/math]

[math]
f(0.75)=2.56
[/math]

[math]
f(1)=2
[/math]

Applying the trapezoidal formula:

[math]
T_4=
0.25\left[
\frac{4+2}{2}
+3.764706+3.2+2.56
\right]
[/math]

Therefore:

[math]
T_4\approx3.131176
[/math]

The actual value is:

[math]
\pi\approx3.141593
[/math]

Using only four intervals already gives a reasonable approximation. Increasing [math]N[/math] improves the result.

<h2>The Midpoint Rule</h2>

The implementations later in this article primarily use the midpoint rule.

Instead of evaluating the function at the boundaries of each interval, the midpoint rule evaluates it at the centre.

The midpoint of interval [math]i[/math] is:

[math]
x_i=
a+\left(i+\frac{1}{2}\right)h
[/math]

The area of that interval is approximated by a rectangle:

[math]
A_i\approx f(x_i)h
[/math]

Adding all rectangles gives:

[math]
\boxed{
M_N=
h\sum_{i=0}^{N-1}
f\left(
a+\left(i+\frac{1}{2}\right)h
\right)
}
[/math]

For the Pi integral, [math]a=0[/math], [math]b=1[/math], and [math]h=1/N[/math].

Therefore:

[math]
x_i=\left(i+\frac{1}{2}\right)h
[/math]

and:

[math] \pi\approx h\sum_{i=0}^{N-1} \frac{4}{1+x_i^2} [/math]

Substituting [math]h=1/N[/math]:

[math]
\boxed{
\pi\approx
\frac{1}{N}
\sum_{i=0}^{N-1}
\frac{4}{
1+
\left(
\frac{i+\frac{1}{2}}{N}
\right)^2
}
}
[/math]

The larger [math]N[/math] becomes, the closer the estimate gets to Pi.

<h2>Trapezoidal Rule Versus Midpoint Rule</h2>

<table>

<thead>

<tr>

<th>Method</th>

<th>Sample positions</th>

<th>Formula</th>

</tr>

</thead>

<tbody>

<tr>

<td>Trapezoidal rule</td>

<td>Interval boundaries</td>

<td>[math]h\left[\frac{f(a)+f(b)}{2}+\sum_{i=1}^{N-1}f(a+ih)\right][/math]</td>

</tr>

<tr>

<td>Midpoint rule</td>

<td>Centre of each interval</td>

<td>[math]h\sum_{i=0}^{N-1}f\left(a+\left(i+\frac12\right)h\right)[/math]</td>

</tr>

</tbody>

</table>

For a smooth function, both methods normally have an error proportional to:

[math]
\frac{1}{N^2}
[/math]

However, the midpoint rule is often more accurate than the trapezoidal rule when both use the same number of intervals.

<h2>Single-Threaded Python Using the Midpoint Rule</h2>

The following Python program uses 25 million intervals.

<pre lang=py>
import math
import time


def calculate_pi(total_steps: int) -&gt; float:
    if total_steps &lt;= 0:
        raise ValueError("total_steps must be positive")

    step_width = 1.0 / total_steps
    total = 0.0

    for step in range(total_steps):
        midpoint = (step + 0.5) * step_width
        total += 4.0 / (1.0 + midpoint * midpoint)

    return total * step_width


def main() -&gt; None:
    total_steps = 25_000_000

    started_at = time.perf_counter()
    pi_estimate = calculate_pi(total_steps)
    elapsed_seconds = time.perf_counter() - started_at

    absolute_error = abs(pi_estimate - math.pi)

    print(f"Estimated Pi:   {pi_estimate:.15f}")
    print(f"Reference Pi:   {math.pi:.15f}")
    print(f"Absolute error: {absolute_error:.3e}")
    print(f"Elapsed time:   {elapsed_seconds:.3f} seconds")


if __name__ == "__main__":
    main()
</pre>

The core calculation is:

<pre lang=py>
midpoint = (step + 0.5) * step_width
total += 4.0 / (1.0 + midpoint * midpoint)
</pre>

The first line calculates the midpoint of the current interval:

[math]
x_i=\left(i+\frac12\right)h
[/math]

The second line evaluates:

[math]
f(x_i)=\frac{4}{1+x_i^2}
[/math]

After all values have been added, the result is multiplied by the interval width:

<pre lang=py>
return total * step_width
</pre>

Mathematically, this calculates:

[math]
h\sum_{i=0}^{N-1}f(x_i)
[/math]

<h2>Single-Threaded Python Using the Trapezoidal Rule</h2>

The trapezoidal version evaluates the function at the interval boundaries rather than at the midpoints.

<pre lang=py>
import math
import time


def calculate_pi_trapezoidal(total_steps: int) -&gt; float:
    if total_steps &lt;= 0:
        raise ValueError("total_steps must be positive")

    h = 1.0 / total_steps

    def f(x: float) -&gt; float:
        return 4.0 / (1.0 + x * x)

    total = 0.5 * (f(0.0) + f(1.0))

    for step in range(1, total_steps):
        x = step * h
        total += f(x)

    return total * h


def main() -&gt; None:
    total_steps = 25_000_000

    started_at = time.perf_counter()
    pi_estimate = calculate_pi_trapezoidal(total_steps)
    elapsed_seconds = time.perf_counter() - started_at

    absolute_error = abs(pi_estimate - math.pi)

    print(f"Estimated Pi:   {pi_estimate:.15f}")
    print(f"Reference Pi:   {math.pi:.15f}")
    print(f"Absolute error: {absolute_error:.3e}")
    print(f"Elapsed time:   {elapsed_seconds:.3f} seconds")


if __name__ == "__main__":
    main()
</pre>

The endpoint contribution is calculated by:

<pre lang=py>
total = 0.5 * (f(0.0) + f(1.0))
</pre>

This corresponds to:

[math]
\frac{f(0)+f(1)}{2}
[/math]

The loop calculates the interior sum:

<pre lang=py>
for step in range(1, total_steps):
    x = step * h
    total += f(x)
</pre>

This corresponds to:

[math]
\sum_{i=1}^{N-1}f(ih)
[/math]

Finally, the total is multiplied by [math]h[/math]:

<pre lang=py>
return total * h
</pre>

<h2>Multithreaded Python Using the Midpoint Rule</h2>

We can divide the 25 million intervals among five workers.

For worker [math]r[/math] out of [math]P[/math] workers, the start index is:

[math]
\text{start}_r=
\left\lfloor
\frac{Nr}{P}
\right\rfloor
[/math]

The end index is:

[math]
\text{end}_r=
\left\lfloor
\frac{N(r+1)}{P}
\right\rfloor
[/math]

For five workers and 25 million intervals:

<table>

<thead>

<tr>

<th>Worker</th>

<th>Start step</th>

<th>End step</th>

<th>Number of steps</th>

</tr>

</thead>

<tbody>

<tr>

<td>0</td>

<td>0</td>

<td>5,000,000</td>

<td>5,000,000</td>

</tr>

<tr>

<td>1</td>

<td>5,000,000</td>

<td>10,000,000</td>

<td>5,000,000</td>

</tr>

<tr>

<td>2</td>

<td>10,000,000</td>

<td>15,000,000</td>

<td>5,000,000</td>

</tr>

<tr>

<td>3</td>

<td>15,000,000</td>

<td>20,000,000</td>

<td>5,000,000</td>

</tr>

<tr>

<td>4</td>

<td>20,000,000</td>

<td>25,000,000</td>

<td>5,000,000</td>

</tr>

</tbody>

</table>

Here is an implementation using <code>ThreadPoolExecutor</code>:

<pre lang=py>
import math
import time
from concurrent.futures import ThreadPoolExecutor


def calculate_partial_sum(
    start_step: int,
    end_step: int,
    step_width: float,
) -&gt; float:
    partial_sum = 0.0

    for step in range(start_step, end_step):
        midpoint = (step + 0.5) * step_width
        partial_sum += 4.0 / (1.0 + midpoint * midpoint)

    return partial_sum


def calculate_pi_multithreaded(
    total_steps: int,
    worker_count: int,
) -&gt; float:
    if total_steps &lt;= 0:
        raise ValueError("total_steps must be positive")

    if worker_count &lt;= 0:
        raise ValueError("worker_count must be positive")

    step_width = 1.0 / total_steps
    ranges = []

    for worker_id in range(worker_count):
        start_step = total_steps * worker_id // worker_count
        end_step = total_steps * (worker_id + 1) // worker_count
        ranges.append((start_step, end_step))

    with ThreadPoolExecutor(max_workers=worker_count) as executor:
        futures = [
            executor.submit(
                calculate_partial_sum,
                start_step,
                end_step,
                step_width,
            )
            for start_step, end_step in ranges
        ]

        partial_sums = [
            future.result()
            for future in futures
        ]

    return sum(partial_sums) * step_width


def main() -&gt; None:
    total_steps = 25_000_000
    worker_count = 5

    started_at = time.perf_counter()

    pi_estimate = calculate_pi_multithreaded(
        total_steps,
        worker_count,
    )

    elapsed_seconds = time.perf_counter() - started_at
    absolute_error = abs(pi_estimate - math.pi)

    print(f"Workers:        {worker_count}")
    print(f"Estimated Pi:   {pi_estimate:.15f}")
    print(f"Reference Pi:   {math.pi:.15f}")
    print(f"Absolute error: {absolute_error:.3e}")
    print(f"Elapsed time:   {elapsed_seconds:.3f} seconds")


if __name__ == "__main__":
    main()
</pre>

Each worker calculates one partial sum:

[math]
S_r=
\sum_{i=\text{start}_r}^{\text{end}_r-1}
\frac{4}{1+x_i^2}
[/math]

The main thread combines the results:

[math] \pi\approx h(S_0+S_1+S_2+S_3+S_4) [/math]

<h3>An Important Python Limitation</h3>

The multithreaded Python version demonstrates how to divide the calculation into separate ranges, but it may not execute faster than the single-threaded version.

Standard CPython has a Global Interpreter Lock, commonly called the GIL. For CPU-bound Python code, only one thread normally executes Python bytecode at a time.

Therefore, five Python threads do not necessarily use five CPU cores effectively.

The threaded version may be:

<ul>

<li>Approximately as fast as the single-threaded version</li>

<li>Slightly slower because of thread-management overhead</li>

<li>Useful for demonstrating work partitioning</li>

<li>Unsuitable for achieving true CPU parallelism in normal CPython</li>

</ul>

For true CPU <a href="https://helloacm.com/why-parallelism-isnt-infinite-amdahl-vs-gustafson-explained-simply/" title="Why Parallelism Isn’t Infinite: Amdahl vs Gustafson Explained Simply">parallelism</a> in Python, better choices include:

<ul>

<li><code>ProcessPoolExecutor</code></li>

<li>The <code>multiprocessing</code> module</li>

<li>NumPy</li>

<li>Native extensions</li>

<li>MPI</li>

<li>Separate distributed processes</li>

</ul>

<h2>Single-Threaded C++ Using the Midpoint Rule</h2>

C++ is well suited to tight numerical loops because it compiles directly to native machine code.

<pre lang=cpp>
#include &lt;chrono&gt;
#include &lt;cmath&gt;
#include &lt;cstdint&gt;
#include &lt;iomanip&gt;
#include &lt;iostream&gt;
#include &lt;stdexcept&gt;


double calculate_pi(std::uint64_t total_steps) {
    if (total_steps == 0) {
        throw std::invalid_argument(
            "total_steps must be positive"
        );
    }

    const double step_width =
        1.0 / static_cast&lt;double&gt;(total_steps);

    double total = 0.0;

    for (
        std::uint64_t step = 0;
        step &lt; total_steps;
        ++step
    ) {
        const double midpoint =
            (static_cast&lt;double&gt;(step) + 0.5)
            * step_width;

        total += 4.0 / (1.0 + midpoint * midpoint);
    }

    return total * step_width;
}


int main() {
    constexpr std::uint64_t total_steps = 25'000'000;

    const auto started_at =
        std::chrono::steady_clock::now();

    const double pi_estimate =
        calculate_pi(total_steps);

    const auto finished_at =
        std::chrono::steady_clock::now();

    const double elapsed_seconds =
        std::chrono::duration&lt;double&gt;(
            finished_at - started_at
        ).count();

    const double reference_pi = std::acos(-1.0);

    const double absolute_error =
        std::abs(pi_estimate - reference_pi);

    std::cout
        &lt;&lt; std::fixed
        &lt;&lt; std::setprecision(15);

    std::cout
        &lt;&lt; "Estimated Pi:   "
        &lt;&lt; pi_estimate
        &lt;&lt; '\n';

    std::cout
        &lt;&lt; "Reference Pi:   "
        &lt;&lt; reference_pi
        &lt;&lt; '\n';

    std::cout
        &lt;&lt; std::scientific
        &lt;&lt; std::setprecision(3);

    std::cout
        &lt;&lt; "Absolute error: "
        &lt;&lt; absolute_error
        &lt;&lt; '\n';

    std::cout
        &lt;&lt; std::fixed
        &lt;&lt; std::setprecision(3);

    std::cout
        &lt;&lt; "Elapsed time:   "
        &lt;&lt; elapsed_seconds
        &lt;&lt; " seconds\n";

    return 0;
}
</pre>

Compile it with optimisation enabled:

<pre lang=cpp>
g++ -O3 -std=c++17 pi_single.cpp -o pi_single
</pre>

Run it using:

<pre lang=cpp>
./pi_single
</pre>

The <code>-O3</code> option enables aggressive compiler optimisation. Without optimisation, the program may run considerably more slowly.

<h2>Single-Threaded C++ Using the Trapezoidal Rule</h2>

The following C++ version implements the trapezoidal formula:

[math]
T_N=
h\left[
\frac{f(0)+f(1)}{2}
+
\sum_{i=1}^{N-1}f(ih)
\right]
[/math]

<pre lang=cpp>
#include &lt;chrono&gt;
#include &lt;cmath&gt;
#include &lt;cstdint&gt;
#include &lt;iomanip&gt;
#include &lt;iostream&gt;
#include &lt;stdexcept&gt;


double f(double x) {
    return 4.0 / (1.0 + x * x);
}


double calculate_pi_trapezoidal(
    std::uint64_t total_steps
) {
    if (total_steps == 0) {
        throw std::invalid_argument(
            "total_steps must be positive"
        );
    }

    const double h =
        1.0 / static_cast&lt;double&gt;(total_steps);

    double total =
        0.5 * (f(0.0) + f(1.0));

    for (
        std::uint64_t step = 1;
        step &lt; total_steps;
        ++step
    ) {
        const double x =
            static_cast&lt;double&gt;(step) * h;

        total += f(x);
    }

    return total * h;
}


int main() {
    constexpr std::uint64_t total_steps = 25'000'000;

    const auto started_at =
        std::chrono::steady_clock::now();

    const double pi_estimate =
        calculate_pi_trapezoidal(total_steps);

    const auto finished_at =
        std::chrono::steady_clock::now();

    const double elapsed_seconds =
        std::chrono::duration&lt;double&gt;(
            finished_at - started_at
        ).count();

    const double reference_pi = std::acos(-1.0);

    const double absolute_error =
        std::abs(pi_estimate - reference_pi);

    std::cout
        &lt;&lt; std::fixed
        &lt;&lt; std::setprecision(15);

    std::cout
        &lt;&lt; "Estimated Pi:   "
        &lt;&lt; pi_estimate
        &lt;&lt; '\n';

    std::cout
        &lt;&lt; "Reference Pi:   "
        &lt;&lt; reference_pi
        &lt;&lt; '\n';

    std::cout
        &lt;&lt; std::scientific
        &lt;&lt; std::setprecision(3);

    std::cout
        &lt;&lt; "Absolute error: "
        &lt;&lt; absolute_error
        &lt;&lt; '\n';

    std::cout
        &lt;&lt; std::fixed
        &lt;&lt; std::setprecision(3);

    std::cout
        &lt;&lt; "Elapsed time:   "
        &lt;&lt; elapsed_seconds
        &lt;&lt; " seconds\n";

    return 0;
}
</pre>

Compile it using:

<pre lang=cpp>
g++ -O3 -std=c++17 pi_trapezoidal.cpp -o pi_trapezoidal
</pre>

<h2>Multithreaded C++ Using the Midpoint Rule</h2>

Unlike ordinary CPython threads, C++ threads can execute CPU-bound work simultaneously on multiple processor cores.

The following implementation divides the calculation among five threads.

<pre lang=cpp>
#include &lt;chrono&gt;
#include &lt;cmath&gt;
#include &lt;cstdint&gt;
#include &lt;iomanip&gt;
#include &lt;iostream&gt;
#include &lt;numeric&gt;
#include &lt;stdexcept&gt;
#include &lt;thread&gt;
#include &lt;vector&gt;


double calculate_partial_sum(
    std::uint64_t start_step,
    std::uint64_t end_step,
    double step_width
) {
    double partial_sum = 0.0;

    for (
        std::uint64_t step = start_step;
        step &lt; end_step;
        ++step
    ) {
        const double midpoint =
            (static_cast&lt;double&gt;(step) + 0.5)
            * step_width;

        partial_sum +=
            4.0 / (1.0 + midpoint * midpoint);
    }

    return partial_sum;
}


double calculate_pi_multithreaded(
    std::uint64_t total_steps,
    std::size_t worker_count
) {
    if (total_steps == 0) {
        throw std::invalid_argument(
            "total_steps must be positive"
        );
    }

    if (worker_count == 0) {
        throw std::invalid_argument(
            "worker_count must be positive"
        );
    }

    const double step_width =
        1.0 / static_cast&lt;double&gt;(total_steps);

    std::vector&lt;std::thread&gt; workers;

    std::vector&lt;double&gt; partial_sums(
        worker_count,
        0.0
    );

    workers.reserve(worker_count);

    for (
        std::size_t worker_id = 0;
        worker_id &lt; worker_count;
        ++worker_id
    ) {
        const std::uint64_t start_step =
            total_steps
            * worker_id
            / worker_count;

        const std::uint64_t end_step =
            total_steps
            * (worker_id + 1)
            / worker_count;

        workers.emplace_back(
            [
                &amp;,
                worker_id,
                start_step,
                end_step
            ]() {
                partial_sums[worker_id] =
                    calculate_partial_sum(
                        start_step,
                        end_step,
                        step_width
                    );
            }
        );
    }

    for (std::thread&amp; worker : workers) {
        worker.join();
    }

    const double combined_sum =
        std::accumulate(
            partial_sums.begin(),
            partial_sums.end(),
            0.0
        );

    return combined_sum * step_width;
}


int main() {
    constexpr std::uint64_t total_steps = 25'000'000;
    constexpr std::size_t worker_count = 5;

    const auto started_at =
        std::chrono::steady_clock::now();

    const double pi_estimate =
        calculate_pi_multithreaded(
            total_steps,
            worker_count
        );

    const auto finished_at =
        std::chrono::steady_clock::now();

    const double elapsed_seconds =
        std::chrono::duration&lt;double&gt;(
            finished_at - started_at
        ).count();

    const double reference_pi = std::acos(-1.0);

    const double absolute_error =
        std::abs(pi_estimate - reference_pi);

    std::cout
        &lt;&lt; "Workers:        "
        &lt;&lt; worker_count
        &lt;&lt; '\n';

    std::cout
        &lt;&lt; std::fixed
        &lt;&lt; std::setprecision(15);

    std::cout
        &lt;&lt; "Estimated Pi:   "
        &lt;&lt; pi_estimate
        &lt;&lt; '\n';

    std::cout
        &lt;&lt; "Reference Pi:   "
        &lt;&lt; reference_pi
        &lt;&lt; '\n';

    std::cout
        &lt;&lt; std::scientific
        &lt;&lt; std::setprecision(3);

    std::cout
        &lt;&lt; "Absolute error: "
        &lt;&lt; absolute_error
        &lt;&lt; '\n';

    std::cout
        &lt;&lt; std::fixed
        &lt;&lt; std::setprecision(3);

    std::cout
        &lt;&lt; "Elapsed time:   "
        &lt;&lt; elapsed_seconds
        &lt;&lt; " seconds\n";

    return 0;
}
</pre>

Compile it with thread support and optimisation:

<pre lang=cpp>
g++ -O3 -std=c++17 -pthread pi_multithreaded.cpp -o pi_multithreaded
</pre>

Then run it:

<pre lang=cpp>
./pi_multithreaded
</pre>

<h3>Why Each Thread Uses a Local Sum</h3>

Inside each thread, the program calculates into a local variable:

<pre lang=cpp>
double partial_sum = 0.0;
</pre>

It does not update one shared global total during every iteration.

If every thread repeatedly updated the same variable, the program would need a mutex or atomic operation. That would introduce synchronisation and contention.

Instead, the program follows a map-and-reduce pattern:

<ol>

<li>Assign one range of intervals to each worker.</li>

<li>Let each worker calculate independently.</li>

<li>Store one partial result per worker.</li>

<li>Wait for all threads to complete.</li>

<li>Add the partial results together.</li>

</ol>

Mathematically:

[math]
S=S_0+S_1+\cdots+S_{P-1}
[/math]

The final approximation is:

[math]
\pi\approx Sh
[/math]

<h2>Extending the Algorithm to Five Distributed Nodes</h2>

Multithreading and distributed computing use the same mathematical partitioning, but they are different execution models.

Threads normally:

<ul>

<li>Run on one machine</li>

<li>Share the same memory</li>

<li>Belong to the same process</li>

<li>Communicate through shared variables</li>

</ul>

Distributed workers normally:

<ul>

<li>Run as separate processes</li>

<li>May run on separate machines</li>

<li>Do not share ordinary process memory</li>

<li>Communicate using files, sockets, MPI, RPC, or another distributed runtime</li>

</ul>

In a five-node job, every process receives a rank:

[math]
r\in{0,1,2,3,4}
[/math]

The total number of processes is:

[math]
P=5
[/math]

Each rank calculates its own range using:

[math]
\text{start}_r=
\left\lfloor
\frac{Nr}{P}
\right\rfloor
[/math]

and:

[math]
\text{end}_r=
\left\lfloor
\frac{N(r+1)}{P}
\right\rfloor
[/math]

In Python, the range assignment can be written as:

<pre lang=py>
import os


rank = int(os.environ["RANK"])
world_size = int(os.environ["WORLD_SIZE"])

start_step = total_steps * rank // world_size
end_step = total_steps * (rank + 1) // world_size
</pre>

Each rank calculates only its assigned section:

<pre lang=py>
partial_sum = 0.0

for step in range(start_step, end_step):
    midpoint = (step + 0.5) * step_width

    partial_sum += 4.0 / (
        1.0 + midpoint * midpoint
    )
</pre>

For five ranks, the final result is:

[math] \pi\approx h(S_0+S_1+S_2+S_3+S_4) [/math]

In the Singularity example, every rank writes one result file:

<pre>
rank-0.json
rank-1.json
rank-2.json
rank-3.json
rank-4.json
</pre>

Rank zero waits for all five files, reads their partial sums, adds them together, and produces the final Pi estimate.

This implements three distributed operations:

<ul>

<li><strong>Barrier:</strong> wait until all workers finish</li>

<li><strong>Gather:</strong> collect the partial results</li>

<li><strong>Reduce:</strong> add the partial sums together</li>

</ul>

The file-based approach is simple and easy to understand, but it assumes that all nodes can access the same shared output directory.

For a production distributed application, MPI or another collective-communication framework would normally be more robust.

<h2>Accuracy of the Numerical Methods</h2>

For sufficiently smooth functions, both the trapezoidal rule and midpoint rule have an error proportional to approximately:

[math]
\frac{1}{N^2}
[/math]

This means that doubling the number of intervals may reduce the numerical integration error by approximately a factor of four.

However, increasing [math]N[/math] indefinitely does not guarantee unlimited accuracy.

Computers store floating-point numbers with finite precision. When millions or billions of values are added, rounding errors can accumulate.

Parallel versions may also produce slightly different final digits from single-threaded versions because floating-point addition is not perfectly associative:

[math]
(a+b)+c\neq a+(b+c)
[/math]

The values are mathematically equivalent, but changing the order of floating-point additions can change the final rounded bits.

<h2>Performance Considerations</h2>

The multithreaded C++ implementation should normally outperform the single-threaded version when:

<ul>

<li>The machine has multiple CPU cores</li>

<li>The calculation is sufficiently large</li>

<li>The number of worker threads is reasonable</li>

<li>Compiler optimisation is enabled</li>

</ul>

Five threads do not guarantee a five-times speed improvement.

Performance depends on:

<ul>

<li>CPU core count</li>

<li>Processor frequency</li>

<li>Thermal throttling</li>

<li>Operating-system thread scheduling</li>

<li>Cache behaviour</li>

<li>Thread startup overhead</li>

<li>Other workloads running on the machine</li>

</ul>

For Python, the GIL is the main restriction. Adding more Python threads does not normally accelerate a pure Python CPU loop.

For distributed computing, node allocation, process startup, storage access, and result aggregation all add overhead.

Calculating Pi with 25 million intervals is a useful demonstration, but it is too small and simple to justify reserving several expensive GPU-backed nodes in a real production workload.

<h2>Comparing the Implementations</h2>

<table>

<thead>

<tr>

<th>Implementation</th>

<th>Execution model</th>

<th>True CPU parallelism</th>

<th>Expected performance</th>

</tr>

</thead>

<tbody>

<tr>

<td>Python single-threaded</td>

<td>One Python thread</td>

<td>No</td>

<td>Simple, but relatively slow</td>

</tr>

<tr>

<td>Python multithreaded</td>

<td>Several Python threads</td>

<td>Usually no because of the GIL</td>

<td>Often no faster than one thread</td>

</tr>

<tr>

<td>C++ single-threaded</td>

<td>One native thread</td>

<td>No</td>

<td>Usually much faster than Python</td>

</tr>

<tr>

<td>C++ multithreaded</td>

<td>Several native threads</td>

<td>Yes</td>

<td>Usually the fastest local version</td>

</tr>

<tr>

<td>Five-node distributed</td>

<td>Separate worker processes</td>

<td>Yes</td>

<td>Scalable, but has communication and startup overhead</td>

</tr>

</tbody>

</table>

<h2>Conclusion</h2>

The identity:

[math]
\pi=\int_0^1\frac{4}{1+x^2},dx
[/math]

provides a simple demonstration of how calculus can be converted into a computational problem.

The trapezoidal rule approximates the integral using straight lines between adjacent boundary points:

[math]
T_N=
h\left[
\frac{f(a)+f(b)}{2}
+
\sum_{i=1}^{N-1}f(a+ih)
\right]
[/math]

The midpoint rule approximates the integral using the centre of each interval:

[math]
M_N=
h\sum_{i=0}^{N-1}
f\left(
a+\left(i+\frac12\right)h
\right)
[/math]

The same mathematical calculation can be executed using:

<ul>

<li>A single loop on one CPU core</li>

<li>Several threads on one machine</li>

<li>Several processes using multiple CPU cores</li>

<li>Several distributed workers running on separate nodes</li>

</ul>

The mathematical algorithm remains largely unchanged. What changes is how the integration range is divided, where the partial sums are calculated, and how the partial results are combined.

This is the central pattern behind many parallel algorithms:

[math]
\boxed{
\text{divide the work}
\rightarrow
\text{calculate partial results}
\rightarrow
\text{combine the results}
}
[/math]

Although calculating Pi is a small example, the same map-and-reduce structure appears in scientific simulation, machine learning, data processing, rendering, financial modelling, and large-scale distributed systems.

[show_file file="/var/www/wp-post-common/helloacm.com/math.php"]

[show_posts keyword="math"]

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/comparisions-of-push_back-and-emplace_back-in-c-stdvector/" rel="bookmark" title="Comparisions of push_back and emplace_back in C++ std::vector">Comparisions of push_back and emplace_back in C++ std::vector</a> <small>In C++, both push_back and emplace_back are methods of the std::vector class used to add...</small></li>
<li><a href="https://helloacm.com/turn-your-raspberry-pi-into-a-family-network-drive-2tb-wd-hard-drive-setup-for-kids-macs/" rel="bookmark" title="Turn Your Raspberry Pi into a Family Network Drive: 2TB WD Hard Drive Setup for Kids’ Macs">Turn Your Raspberry Pi into a Family Network Drive: 2TB WD Hard Drive Setup for Kids’ Macs</a> <small>“Create a 2TB Network Drive with Raspberry Pi for Your Family” “Raspberry Pi + WD...</small></li>
<li><a href="https://helloacm.com/tutorial-on-c-smart-pointers/" rel="bookmark" title="Tutorial on C++ Smart Pointers">Tutorial on C++ Smart Pointers</a> <small>Tutorial on Smart Pointers in C++ Smart pointers in C++ provide automatic and safe memory...</small></li>
<li><a href="https://helloacm.com/const-vs-constexpr-in-c/" rel="bookmark" title="const vs constexpr in C++">const vs constexpr in C++</a> <small>C++ const vs constexpr: What’s the Real Difference? Both are used in C++ to define...</small></li>
<li><a href="https://helloacm.com/interview-coding-exercise-nested-string-python/" rel="bookmark" title="Interview Coding Exercise &#8211; Nested String (Python)">Interview Coding Exercise &#8211; Nested String (Python)</a> <small>Nested String A string S consisting of N characters is considered to be properly nested...</small></li>
<li><a href="https://helloacm.com/gaming-adaptations-for-different-platforms/" rel="bookmark" title="Gaming Adaptations for Different Platforms">Gaming Adaptations for Different Platforms</a> <small>One of the trickiest challenges facing any software developer is figuring out how their coding...</small></li>
<li><a href="https://helloacm.com/from-idea-to-github-pages-building-tools-with-ai-and-vibe-coding/" rel="bookmark" title="From Idea to GitHub Pages: Building Tools with AI and Vibe Coding">From Idea to GitHub Pages: Building Tools with AI and Vibe Coding</a> <small>Built and Open-Sourced A Few Mini Tools with AI Recently, I used ChatGPT-4o and o4-mini...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-delete-nodes-from-linked-list-present-in-array/" rel="bookmark" title="Teaching Kids Programming &#8211; Delete Nodes From Linked List Present in Array">Teaching Kids Programming &#8211; Delete Nodes From Linked List Present in Array</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given an array of...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://helloacm.com/calculating-pi-with-numerical-integration-in-python-and-c/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Apple Office in Cambridge</title>
		<link>https://helloacm.com/apple-office-in-cambridge/</link>
					<comments>https://helloacm.com/apple-office-in-cambridge/#respond</comments>
		
		<dc:creator><![CDATA[ACMer]]></dc:creator>
		<pubDate>Tue, 14 Jul 2026 11:32:15 +0000</pubDate>
				<category><![CDATA[Office]]></category>
		<category><![CDATA[30 Station Road]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[Apple Cambridge]]></category>
		<category><![CDATA[Apple Intelligence]]></category>
		<category><![CDATA[artificial intelligence]]></category>
		<category><![CDATA[Cambridge Office]]></category>
		<category><![CDATA[Cambridge Tech Cluster]]></category>
		<category><![CDATA[Cambridge Technology]]></category>
		<category><![CDATA[machine learning]]></category>
		<category><![CDATA[Research and Development]]></category>
		<category><![CDATA[Siri]]></category>
		<category><![CDATA[software engineering]]></category>
		<category><![CDATA[Technology Companies]]></category>
		<category><![CDATA[UK Technology]]></category>
		<category><![CDATA[VocalIQ]]></category>
		<guid isPermaLink="false">https://helloacm.com/?p=157920</guid>

					<description><![CDATA[Apple’s Cambridge office is located at 30 Station Road, directly opposite the Microsoft Research office near Cambridge railway station. The building is a modern, seven-storey development with approximately 79,000 square feet of office space and a stated capacity of up to around 900 people.

<blockquote>
Apple’s Cambridge office at 30 <a href="https://helloacm.com/cambridge-science-park-microsoft-amd-and-raspberry-pi-neighbours/" title="Cambridge Science Park: Microsoft, AMD and Raspberry Pi (Neighbours)">Station Road</a> has grown from its early links with VocalIQ and Siri into a broader research and development centre. Today, its teams work across artificial intelligence, machine learning, speech, audio, imaging and hardware technologies, reflecting Cambridge’s growing importance as one of the UK’s leading technology hubs.
</blockquote>

However, the building’s capacity should not be confused with Apple’s actual headcount in Cambridge. Apple does not publicly disclose how many employees work at each of its offices, so the real number is likely to be lower and may change over time.

The building was completed in 2022, after which Apple moved from its smaller office at 90 Hills Road. The move suggested that Apple intended to expand its research and engineering presence in Cambridge.

Apple’s Cambridge operation has strong links to the city’s artificial intelligence ecosystem. In 2015, Apple acquired VocalIQ, a Cambridge-based artificial intelligence company with connections to the University of Cambridge. VocalIQ specialised in conversational voice technology and natural human-computer interaction.

After the acquisition, much of the team remained in Cambridge. This became one of the foundations of Apple’s research presence in the city, and the office was sometimes described in the media as a development centre for Siri.

Today, Apple’s work in Cambridge appears to extend well beyond Siri. Based on publicly advertised roles, its local teams have worked in areas including speech technology, computer vision, audio machine learning, Apple Intelligence, Siri evaluation, health-related artificial intelligence, camera and imaging algorithms, CPU verification and hardware architecture.

For that reason, it would be inaccurate to describe the Cambridge office simply as Apple’s “Siri laboratory”. A better description would be:

<blockquote>
Apple’s Cambridge research and development office, focusing on artificial intelligence, machine learning, audio, imaging and hardware technologies.
</blockquote>

<a href="https://helloacm.com/onsite-interview-tips-for-facebook-google-microsoft-amazon-apple/" title="Onsite Interview Tips for Facebook / Google / Microsoft / Amazon / Apple">Apple</a> is only one of many major technology companies with a presence around Station Road. Microsoft, Amazon, Samsung and several other technology businesses also have offices nearby. Further north, Cambridge Science Park is home to companies such as Qualcomm, Broadcom and AMD.

Cambridge may be a relatively small city, but its universities, research institutions and technology ecosystem have made it one of the most important technology centres in the United Kingdom. Apple’s decision to expand its office here is another sign of the city’s continuing importance to global research and development.

[caption id="attachment_157921" align="alignnone" width="1672"]<a href="https://helloacm.com/apple-office-in-cambridge/apple-research-development-station-road-cambridge-ghibli/" rel="attachment wp-att-157921"><img src="https://helloacm.com/wp-content/uploads/2026/07/apple-research-development-station-road-cambridge-ghibli.png" alt="Apple’s Cambridge office at 30 Station Road, viewed from the Microsoft Research office across the road. (Ghibli style by ChatGPT)" width="1672" height="941" class="size-full wp-image-157921" /></a> Apple’s Cambridge office at 30 Station Road, viewed from the Microsoft Research office across the road. (Ghibli style by ChatGPT)[/caption]

Photo enhanced by ChatGPT as the original photo taken by iPhone 15 Pro Max is blurry (I had to zoom in a bit)
[caption id="attachment_157922" align="alignnone" width="1672"]<a href="https://helloacm.com/apple-office-in-cambridge/apple-research-development-station-road-cambridge/" rel="attachment wp-att-157922"><img src="https://helloacm.com/wp-content/uploads/2026/07/apple-research-development-station-road-cambridge.png" alt="Apple’s Cambridge office at 30 Station Road, viewed from the Microsoft Research office across the road." width="1672" height="941" class="size-full wp-image-157922" /></a> Apple’s Cambridge office at 30 Station Road, viewed from the Microsoft Research office across the road.[/caption]

[show_posts keyword="Apple"]

Blog: <a href="https://steemit.com/blog/@justyy/apple-office-in-cambridge-uk" title="Apple Office in Cambridge UK">Apple Office in Cambridge UK</a> | <a href="https://blurt.blog/blog/@justyy/apple-office-in-cambridge-uk" title="Apple Office in Cambridge UK">Apple Office in Cambridge UK</a>

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/wordpress-short-code-function-showing-relevant-posts/" rel="bookmark" title="How to Use WordPress Search to Display Relevant Posts?">How to Use WordPress Search to Display Relevant Posts?</a> <small>How to Create a Lightweight Related Posts Shortcode in WordPress Display Relevant Posts in WordPress...</small></li>
<li><a href="https://helloacm.com/understanding-the-sigma-function-divisors-multiplicativity-and-the-formula/" rel="bookmark" title="Understanding the Sigma Function: Divisors, Multiplicativity, and the Formula">Understanding the Sigma Function: Divisors, Multiplicativity, and the Formula</a> <small>Understanding the Sigma Function: Divisors, Multiplicativity, and the Formula Understanding the Sigma Function: From Divisors...</small></li>
<li><a href="https://helloacm.com/how-to-securely-wipe-your-disk-and-what-happens-after-you-zero-your-disk-using-dd-on-linux/" rel="bookmark" title="How to Securely Wipe Your Disk and What Happens After You Zero Your Disk using dd on Linux?">How to Securely Wipe Your Disk and What Happens After You Zero Your Disk using dd on Linux?</a> <small>I decide to terminate one of my VPS server (QuickHostUK) and don&#8217;t want any data...</small></li>
<li><a href="https://helloacm.com/chatgpt-refactors-rewrites-the-code-using-promise-all-sending-requests-in-parallel/" rel="bookmark" title="ChatGPT Refactors/Rewrites the Code using Promise.All &#8211; Sending Requests in Parallel">ChatGPT Refactors/Rewrites the Code using Promise.All &#8211; Sending Requests in Parallel</a> <small>In one of my project, I have the following code (Node/Javascript) that invokes a few...</small></li>
<li><a href="https://helloacm.com/two-simple-commands-to-deploy-and-run-the-deepseek-r1-8b-large-language-model-llm/" rel="bookmark" title="Two Simple Commands to Deploy and Run the DeepSeek R1-8b Large Language Model (LLM)">Two Simple Commands to Deploy and Run the DeepSeek R1-8b Large Language Model (LLM)</a> <small>Large Language Models (LLMs) like DeepSeek R1-8B have revolutionized natural language processing, enabling powerful AI-driven...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-introduction-to-units-of-information-byte-kb-mb-gb-tb-pb/" rel="bookmark" title="Teaching Kids Programming &#8211; Introduction to Units of Information (Byte, KB, MB, GB, TB, PB)">Teaching Kids Programming &#8211; Introduction to Units of Information (Byte, KB, MB, GB, TB, PB)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms Information is the lifeblood of the...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-design-and-develop-an-apple-catching-game-on-microbit-using-python/" rel="bookmark" title="Teaching Kids Programming &#8211; Design and Develop an Apple Catching Game on Microbit using Python">Teaching Kids Programming &#8211; Design and Develop an Apple Catching Game on Microbit using Python</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms We have actually developed and designed...</small></li>
<li><a href="https://helloacm.com/compute-the-angle-of-the-hour-and-minute-hand-on-a-clock/" rel="bookmark" title="Compute the Angle of the Hour and Minute Hand on a Clock">Compute the Angle of the Hour and Minute Hand on a Clock</a> <small>Given a time in the format of hour and minute, calculate the angle of the...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[Apple’s Cambridge office is located at 30 Station Road, directly opposite the Microsoft Research office near Cambridge railway station. The building is a modern, seven-storey development with approximately 79,000 square feet of office space and a stated capacity of up to around 900 people.

<blockquote>
Apple’s Cambridge office at 30 <a href="https://helloacm.com/cambridge-science-park-microsoft-amd-and-raspberry-pi-neighbours/" title="Cambridge Science Park: Microsoft, AMD and Raspberry Pi (Neighbours)">Station Road</a> has grown from its early links with VocalIQ and Siri into a broader research and development centre. Today, its teams work across artificial intelligence, machine learning, speech, audio, imaging and hardware technologies, reflecting Cambridge’s growing importance as one of the UK’s leading technology hubs.
</blockquote>

However, the building’s capacity should not be confused with Apple’s actual headcount in Cambridge. Apple does not publicly disclose how many employees work at each of its offices, so the real number is likely to be lower and may change over time.

The building was completed in 2022, after which Apple moved from its smaller office at 90 Hills Road. The move suggested that Apple intended to expand its research and engineering presence in Cambridge.

Apple’s Cambridge operation has strong links to the city’s artificial intelligence ecosystem. In 2015, Apple acquired VocalIQ, a Cambridge-based artificial intelligence company with connections to the University of Cambridge. VocalIQ specialised in conversational voice technology and natural human-computer interaction.

After the acquisition, much of the team remained in Cambridge. This became one of the foundations of Apple’s research presence in the city, and the office was sometimes described in the media as a development centre for Siri.

Today, Apple’s work in Cambridge appears to extend well beyond Siri. Based on publicly advertised roles, its local teams have worked in areas including speech technology, computer vision, audio machine learning, Apple Intelligence, Siri evaluation, health-related artificial intelligence, camera and imaging algorithms, CPU verification and hardware architecture.

For that reason, it would be inaccurate to describe the Cambridge office simply as Apple’s “Siri laboratory”. A better description would be:

<blockquote>
Apple’s Cambridge research and development office, focusing on artificial intelligence, machine learning, audio, imaging and hardware technologies.
</blockquote>

<a href="https://helloacm.com/onsite-interview-tips-for-facebook-google-microsoft-amazon-apple/" title="Onsite Interview Tips for Facebook / Google / Microsoft / Amazon / Apple">Apple</a> is only one of many major technology companies with a presence around Station Road. Microsoft, Amazon, Samsung and several other technology businesses also have offices nearby. Further north, Cambridge Science Park is home to companies such as Qualcomm, Broadcom and AMD.

Cambridge may be a relatively small city, but its universities, research institutions and technology ecosystem have made it one of the most important technology centres in the United Kingdom. Apple’s decision to expand its office here is another sign of the city’s continuing importance to global research and development.

[caption id="attachment_157921" align="alignnone" width="1672"]<a href="https://helloacm.com/apple-office-in-cambridge/apple-research-development-station-road-cambridge-ghibli/" rel="attachment wp-att-157921"><img src="https://helloacm.com/wp-content/uploads/2026/07/apple-research-development-station-road-cambridge-ghibli.png" alt="Apple’s Cambridge office at 30 Station Road, viewed from the Microsoft Research office across the road. (Ghibli style by ChatGPT)" width="1672" height="941" class="size-full wp-image-157921" /></a> Apple’s Cambridge office at 30 Station Road, viewed from the Microsoft Research office across the road. (Ghibli style by ChatGPT)[/caption]

Photo enhanced by ChatGPT as the original photo taken by iPhone 15 Pro Max is blurry (I had to zoom in a bit)
[caption id="attachment_157922" align="alignnone" width="1672"]<a href="https://helloacm.com/apple-office-in-cambridge/apple-research-development-station-road-cambridge/" rel="attachment wp-att-157922"><img src="https://helloacm.com/wp-content/uploads/2026/07/apple-research-development-station-road-cambridge.png" alt="Apple’s Cambridge office at 30 Station Road, viewed from the Microsoft Research office across the road." width="1672" height="941" class="size-full wp-image-157922" /></a> Apple’s Cambridge office at 30 Station Road, viewed from the Microsoft Research office across the road.[/caption]

[show_posts keyword="Apple"]

Blog: <a href="https://steemit.com/blog/@justyy/apple-office-in-cambridge-uk" title="Apple Office in Cambridge UK">Apple Office in Cambridge UK</a> | <a href="https://blurt.blog/blog/@justyy/apple-office-in-cambridge-uk" title="Apple Office in Cambridge UK">Apple Office in Cambridge UK</a>

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/wordpress-short-code-function-showing-relevant-posts/" rel="bookmark" title="How to Use WordPress Search to Display Relevant Posts?">How to Use WordPress Search to Display Relevant Posts?</a> <small>How to Create a Lightweight Related Posts Shortcode in WordPress Display Relevant Posts in WordPress...</small></li>
<li><a href="https://helloacm.com/understanding-the-sigma-function-divisors-multiplicativity-and-the-formula/" rel="bookmark" title="Understanding the Sigma Function: Divisors, Multiplicativity, and the Formula">Understanding the Sigma Function: Divisors, Multiplicativity, and the Formula</a> <small>Understanding the Sigma Function: Divisors, Multiplicativity, and the Formula Understanding the Sigma Function: From Divisors...</small></li>
<li><a href="https://helloacm.com/how-to-securely-wipe-your-disk-and-what-happens-after-you-zero-your-disk-using-dd-on-linux/" rel="bookmark" title="How to Securely Wipe Your Disk and What Happens After You Zero Your Disk using dd on Linux?">How to Securely Wipe Your Disk and What Happens After You Zero Your Disk using dd on Linux?</a> <small>I decide to terminate one of my VPS server (QuickHostUK) and don&#8217;t want any data...</small></li>
<li><a href="https://helloacm.com/chatgpt-refactors-rewrites-the-code-using-promise-all-sending-requests-in-parallel/" rel="bookmark" title="ChatGPT Refactors/Rewrites the Code using Promise.All &#8211; Sending Requests in Parallel">ChatGPT Refactors/Rewrites the Code using Promise.All &#8211; Sending Requests in Parallel</a> <small>In one of my project, I have the following code (Node/Javascript) that invokes a few...</small></li>
<li><a href="https://helloacm.com/two-simple-commands-to-deploy-and-run-the-deepseek-r1-8b-large-language-model-llm/" rel="bookmark" title="Two Simple Commands to Deploy and Run the DeepSeek R1-8b Large Language Model (LLM)">Two Simple Commands to Deploy and Run the DeepSeek R1-8b Large Language Model (LLM)</a> <small>Large Language Models (LLMs) like DeepSeek R1-8B have revolutionized natural language processing, enabling powerful AI-driven...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-introduction-to-units-of-information-byte-kb-mb-gb-tb-pb/" rel="bookmark" title="Teaching Kids Programming &#8211; Introduction to Units of Information (Byte, KB, MB, GB, TB, PB)">Teaching Kids Programming &#8211; Introduction to Units of Information (Byte, KB, MB, GB, TB, PB)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms Information is the lifeblood of the...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-design-and-develop-an-apple-catching-game-on-microbit-using-python/" rel="bookmark" title="Teaching Kids Programming &#8211; Design and Develop an Apple Catching Game on Microbit using Python">Teaching Kids Programming &#8211; Design and Develop an Apple Catching Game on Microbit using Python</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms We have actually developed and designed...</small></li>
<li><a href="https://helloacm.com/compute-the-angle-of-the-hour-and-minute-hand-on-a-clock/" rel="bookmark" title="Compute the Angle of the Hour and Minute Hand on a Clock">Compute the Angle of the Hour and Minute Hand on a Clock</a> <small>Given a time in the format of hour and minute, calculate the angle of the...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://helloacm.com/apple-office-in-cambridge/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>How to Use WordPress Search to Display Relevant Posts?</title>
		<link>https://helloacm.com/wordpress-short-code-function-showing-relevant-posts/</link>
					<comments>https://helloacm.com/wordpress-short-code-function-showing-relevant-posts/#respond</comments>
		
		<dc:creator><![CDATA[ACMer]]></dc:creator>
		<pubDate>Sat, 04 Jul 2026 12:38:25 +0000</pubDate>
				<category><![CDATA[php]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[programming languages]]></category>
		<category><![CDATA[wordpress]]></category>
		<category><![CDATA[wordpress shortcode]]></category>
		<category><![CDATA[blogging]]></category>
		<category><![CDATA[child theme]]></category>
		<category><![CDATA[functions.php]]></category>
		<category><![CDATA[Lightweight Plugin Alternative]]></category>
		<category><![CDATA[Post Excerpts]]></category>
		<category><![CDATA[Relevant Posts]]></category>
		<category><![CDATA[shortcode]]></category>
		<category><![CDATA[WordPress Development]]></category>
		<category><![CDATA[WordPress Search]]></category>
		<category><![CDATA[WP_Query]]></category>
		<guid isPermaLink="false">https://helloacm.com/?p=157903</guid>

					<description><![CDATA[<blockquote>
How to Create a Lightweight Related Posts Shortcode in WordPress
Display Relevant Posts in WordPress Without a Plugin
A Simple WordPress Shortcode to Show Related Posts
Build Your Own show_posts Shortcode in WordPress
Show Relevant WordPress Posts Using WP_Query
WordPress Shortcode for Related Posts with Optional Excerpts
Add Related Posts to WordPress Posts Without Extra Plugins
Lightweight Related Posts in WordPress Using Built-in Search
How to Use WordPress Search to Display Relevant Posts
Custom WordPress Shortcode: Show Matching Posts by Keyword
Wordpress Short Code Function: Showing Relevant Posts

A lightweight WordPress shortcode for displaying relevant posts using the built-in search query. Supports custom keywords, post count limits, and optional inline excerpts without needing an extra plugin.
</blockquote>

In WordPress, you can create custom shortcode functions by adding code to your theme’s functions.php file, preferably in a child theme.

[caption id="attachment_45593" align="alignnone" width="584"]<a href="https://helloacm.com/wordpress-membership-plugin/wordpress-pad/" rel="attachment wp-att-45593"><img src="https://helloacm.com/wp-content/uploads/2019/06/wordpress-pad.jpg" alt="wordpress-pad" width="584" height="443" class="size-full wp-image-45593" /></a> wordpress-pad[/caption]

The following example adds a <a href="https://helloacm.com/how-to-add-a-shortcode-to-include-a-php-file-in-wordpress/" title="How to Add a ShortCode to Include a PHP File in WordPress?">shortcode</a> called show_posts, which can be used inside your posts to display a list of relevant posts. The relevant posts are retrieved using WordPress’s built-in search mechanism, similar to the /?s=keyword query parameter. You can also specify the number of posts to show and choose whether to display each post’s excerpt inline.

Compared with installing another WordPress plugin, a <a href="https://helloacm.com/php-code-to-redirect-with-302-and-a-referer/" title="PHP Code to Redirect with 302 and a Referer">PHP</a> shortcode like this is lightweight and gives you full control over the code. It can also reduce unnecessary overhead, as long as the implementation is kept simple and secure.

Also, with shortcode, you can choose where to place/show the relevant posts where the plugins only allow you to place them after the posts.

To use it, copy and paste the code below into your functions.php file. Then, inside any post or page, you can use the show_posts <a href="https://helloacm.com/turtle-programming-v0-0-13-support-rgb-add-shortcodes-global-procedures-editor/" title="Turtle Programming v0.0.13: Support RGB, Add ShortCodes, Global Procedures Editor">shortcode</a> to insert the relevant post list.

For example:

<pre lang=shortcode>
[ show_posts keyword="wordpress" number="8" show_excerpt="true" ]
</pre>

Will produce:

[show_posts keyword="wordpress" number="8" show_excerpt="true"]


<pre lang=shortcode>
[ show_posts keyword="php" number="5" show_excerpt="false" ]
</pre>

Will produce:

[show_posts keyword="php" number="8" show_excerpt="false"]

By default, number is set to 8 posts, and the posts show_excerpt is set to hide.

<pre lang=php>
function show___posts_func($atts) {
    $atts = shortcode_atts(
        array(
            'keyword'      =&gt; '',
            'number'       =&gt; 5,
            'show_excerpt' =&gt; 'true',
        ),
        $atts,
        'show_posts'
    );

    $keyword = sanitize_text_field($atts['keyword']);
    $number = max(1, min(20, intval($atts['number'])));
    $show_excerpt = filter_var($atts['show_excerpt'], FILTER_VALIDATE_BOOLEAN);

    if ($keyword === '') {
        return '';
    }

    $query = new WP_Query(array(
        'post_type'           =&gt; 'post',
        'post_status'         =&gt; 'publish',
        's'                   =&gt; $keyword,
        'posts_per_page'      =&gt; $number,
        'ignore_sticky_posts' =&gt; true,
        'no_found_rows'       =&gt; true,
    ));

    if (!$query-&gt;have_posts()) {
        return '';
    }

    $output = '&lt;ul class="show-posts-list"&gt;';

    while ($query-&gt;have_posts()) {
        $query-&gt;the_post();

        $output .= '&lt;li&gt;';
        $output .= '&lt;a href="' . esc_url(get_permalink()) . '"&gt;';
        $output .= esc_html(get_the_title());
        $output .= '&lt;/a&gt;';

        if ($show_excerpt) {
            $excerpt = get_the_excerpt();

            if ($excerpt) {
                $output .= '&lt;br&gt;&lt;small&gt;' . esc_html(wp_trim_words($excerpt, 20)) . '&lt;/small&gt;';
            }
        }

        $output .= '&lt;/li&gt;';
    }

    $output .= '&lt;/ul&gt;';

    wp_reset_postdata();

    return $output;
}

add_shortcode('show_posts', 'show___posts_func');
</pre>

<h3>Spaced Keywords</h3>
For WordPress default search:

keyword="a b"

means roughly:

a AND b

Not a OR b.

More precisely, WordPress splits the search into terms, so "a b" becomes two terms: a and b. For each term, WordPress checks whether it appears in the post title, excerpt, or content. Inside one term it uses OR across those fields, but between terms it uses AND. WordPress’s source shows the default searchable columns are post_title, post_excerpt, and post_content, and it appends AND between search terms.

So conceptually:

(title LIKE '%a%' OR excerpt LIKE '%a%' OR content LIKE '%a%')
AND
(title LIKE '%b%' OR excerpt LIKE '%b%' OR content LIKE '%b%')

Important catch: single-letter terms like a may be ignored as too short/stopword-like, so test with real keywords such as:

keyword="php wordpress"

That means: posts matching both php and wordpress.

If you want a OR b, you should not rely on default s. You would need custom logic, for example running separate searches for each keyword and merging results.

[show_file file="/var/www/wp-post-common/helloacm.com/wordpress.php"]

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/interview-coding-exercise-nested-string-python/" rel="bookmark" title="Interview Coding Exercise &#8211; Nested String (Python)">Interview Coding Exercise &#8211; Nested String (Python)</a> <small>Nested String A string S consisting of N characters is considered to be properly nested...</small></li>
<li><a href="https://helloacm.com/how-to-check-balances-of-a-bitcoin-btc-wallet-address-via-nodejs-or-python/" rel="bookmark" title="How to Check Balances of a Bitcoin (BTC) Wallet Address via NodeJs or Python?">How to Check Balances of a Bitcoin (BTC) Wallet Address via NodeJs or Python?</a> <small>Checking the Balances of a BTC/bitcoin wallet address can be done in two ways: Querying...</small></li>
<li><a href="https://helloacm.com/laptop-battery-power-drained-but-failed-to-sleep-on-microsoft-windows-surface-studio-pro/" rel="bookmark" title="Laptop Battery Power Drained But Failed to Sleep on Microsoft Windows Surface Studio Pro">Laptop Battery Power Drained But Failed to Sleep on Microsoft Windows Surface Studio Pro</a> <small>I am surprised to find out that my laptop is switched off this morning &#8211;...</small></li>
<li><a href="https://helloacm.com/how-to-parallel-for-in-linux-bash-shell/" rel="bookmark" title="How to Parallel For in Linux Bash Shell?">How to Parallel For in Linux Bash Shell?</a> <small>The Linux Bash Shell supports inherent task parallelism. For example, you can put a &#038;...</small></li>
<li><a href="https://helloacm.com/using-absolute-keyword-in-delphi-to-remove-unnecessary-assignment-function/" rel="bookmark" title="Using Absolute Keyword in Delphi to Remove Unnecessary Assignment Function">Using Absolute Keyword in Delphi to Remove Unnecessary Assignment Function</a> <small>The Delphi/Object Pascal provides a keyword absolute, which you can also find examples at this...</small></li>
<li><a href="https://helloacm.com/trie-class-data-structure-in-python/" rel="bookmark" title="Trie Class Data Structure in Python">Trie Class Data Structure in Python</a> <small>Implement a trie with insert, search, and startsWith methods. Example: Trie trie = new Trie();...</small></li>
<li><a href="https://helloacm.com/how-to-create-and-run-unit-tests-in-c-net-a-quick-tutorial/" rel="bookmark" title="How to Create and Run Unit Tests in C# .NET &#8211; A Quick Tutorial">How to Create and Run Unit Tests in C# .NET &#8211; A Quick Tutorial</a> <small>This tutorial will show you how to create and run unit tests under Visual Studio....</small></li>
<li><a href="https://helloacm.com/steemit-hide-payout-update-add-customize-rules-hide-busy-wall-wallet/" rel="bookmark" title="SteemIt Hide Payout Update: Add Customize Rules + Hide busy.wall Wallet">SteemIt Hide Payout Update: Add Customize Rules + Hide busy.wall Wallet</a> <small>Introduction Hide-SteemIt-Payout is a chrome extension that hides payout and wallets for most steemit sites...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<blockquote>
How to Create a Lightweight Related Posts Shortcode in WordPress
Display Relevant Posts in WordPress Without a Plugin
A Simple WordPress Shortcode to Show Related Posts
Build Your Own show_posts Shortcode in WordPress
Show Relevant WordPress Posts Using WP_Query
WordPress Shortcode for Related Posts with Optional Excerpts
Add Related Posts to WordPress Posts Without Extra Plugins
Lightweight Related Posts in WordPress Using Built-in Search
How to Use WordPress Search to Display Relevant Posts
Custom WordPress Shortcode: Show Matching Posts by Keyword
Wordpress Short Code Function: Showing Relevant Posts

A lightweight WordPress shortcode for displaying relevant posts using the built-in search query. Supports custom keywords, post count limits, and optional inline excerpts without needing an extra plugin.
</blockquote>

In WordPress, you can create custom shortcode functions by adding code to your theme’s functions.php file, preferably in a child theme.

[caption id="attachment_45593" align="alignnone" width="584"]<a href="https://helloacm.com/wordpress-membership-plugin/wordpress-pad/" rel="attachment wp-att-45593"><img src="https://helloacm.com/wp-content/uploads/2019/06/wordpress-pad.jpg" alt="wordpress-pad" width="584" height="443" class="size-full wp-image-45593" /></a> wordpress-pad[/caption]

The following example adds a <a href="https://helloacm.com/how-to-add-a-shortcode-to-include-a-php-file-in-wordpress/" title="How to Add a ShortCode to Include a PHP File in WordPress?">shortcode</a> called show_posts, which can be used inside your posts to display a list of relevant posts. The relevant posts are retrieved using WordPress’s built-in search mechanism, similar to the /?s=keyword query parameter. You can also specify the number of posts to show and choose whether to display each post’s excerpt inline.

Compared with installing another WordPress plugin, a <a href="https://helloacm.com/php-code-to-redirect-with-302-and-a-referer/" title="PHP Code to Redirect with 302 and a Referer">PHP</a> shortcode like this is lightweight and gives you full control over the code. It can also reduce unnecessary overhead, as long as the implementation is kept simple and secure.

Also, with shortcode, you can choose where to place/show the relevant posts where the plugins only allow you to place them after the posts.

To use it, copy and paste the code below into your functions.php file. Then, inside any post or page, you can use the show_posts <a href="https://helloacm.com/turtle-programming-v0-0-13-support-rgb-add-shortcodes-global-procedures-editor/" title="Turtle Programming v0.0.13: Support RGB, Add ShortCodes, Global Procedures Editor">shortcode</a> to insert the relevant post list.

For example:

<pre lang=shortcode>
[ show_posts keyword="wordpress" number="8" show_excerpt="true" ]
</pre>

Will produce:

[show_posts keyword="wordpress" number="8" show_excerpt="true"]


<pre lang=shortcode>
[ show_posts keyword="php" number="5" show_excerpt="false" ]
</pre>

Will produce:

[show_posts keyword="php" number="8" show_excerpt="false"]

By default, number is set to 8 posts, and the posts show_excerpt is set to hide.

<pre lang=php>
function show___posts_func($atts) {
    $atts = shortcode_atts(
        array(
            'keyword'      =&gt; '',
            'number'       =&gt; 5,
            'show_excerpt' =&gt; 'true',
        ),
        $atts,
        'show_posts'
    );

    $keyword = sanitize_text_field($atts['keyword']);
    $number = max(1, min(20, intval($atts['number'])));
    $show_excerpt = filter_var($atts['show_excerpt'], FILTER_VALIDATE_BOOLEAN);

    if ($keyword === '') {
        return '';
    }

    $query = new WP_Query(array(
        'post_type'           =&gt; 'post',
        'post_status'         =&gt; 'publish',
        's'                   =&gt; $keyword,
        'posts_per_page'      =&gt; $number,
        'ignore_sticky_posts' =&gt; true,
        'no_found_rows'       =&gt; true,
    ));

    if (!$query-&gt;have_posts()) {
        return '';
    }

    $output = '&lt;ul class="show-posts-list"&gt;';

    while ($query-&gt;have_posts()) {
        $query-&gt;the_post();

        $output .= '&lt;li&gt;';
        $output .= '&lt;a href="' . esc_url(get_permalink()) . '"&gt;';
        $output .= esc_html(get_the_title());
        $output .= '&lt;/a&gt;';

        if ($show_excerpt) {
            $excerpt = get_the_excerpt();

            if ($excerpt) {
                $output .= '&lt;br&gt;&lt;small&gt;' . esc_html(wp_trim_words($excerpt, 20)) . '&lt;/small&gt;';
            }
        }

        $output .= '&lt;/li&gt;';
    }

    $output .= '&lt;/ul&gt;';

    wp_reset_postdata();

    return $output;
}

add_shortcode('show_posts', 'show___posts_func');
</pre>

<h3>Spaced Keywords</h3>
For WordPress default search:

keyword="a b"

means roughly:

a AND b

Not a OR b.

More precisely, WordPress splits the search into terms, so "a b" becomes two terms: a and b. For each term, WordPress checks whether it appears in the post title, excerpt, or content. Inside one term it uses OR across those fields, but between terms it uses AND. WordPress’s source shows the default searchable columns are post_title, post_excerpt, and post_content, and it appends AND between search terms.

So conceptually:

(title LIKE '%a%' OR excerpt LIKE '%a%' OR content LIKE '%a%')
AND
(title LIKE '%b%' OR excerpt LIKE '%b%' OR content LIKE '%b%')

Important catch: single-letter terms like a may be ignored as too short/stopword-like, so test with real keywords such as:

keyword="php wordpress"

That means: posts matching both php and wordpress.

If you want a OR b, you should not rely on default s. You would need custom logic, for example running separate searches for each keyword and merging results.

[show_file file="/var/www/wp-post-common/helloacm.com/wordpress.php"]

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/interview-coding-exercise-nested-string-python/" rel="bookmark" title="Interview Coding Exercise &#8211; Nested String (Python)">Interview Coding Exercise &#8211; Nested String (Python)</a> <small>Nested String A string S consisting of N characters is considered to be properly nested...</small></li>
<li><a href="https://helloacm.com/how-to-check-balances-of-a-bitcoin-btc-wallet-address-via-nodejs-or-python/" rel="bookmark" title="How to Check Balances of a Bitcoin (BTC) Wallet Address via NodeJs or Python?">How to Check Balances of a Bitcoin (BTC) Wallet Address via NodeJs or Python?</a> <small>Checking the Balances of a BTC/bitcoin wallet address can be done in two ways: Querying...</small></li>
<li><a href="https://helloacm.com/laptop-battery-power-drained-but-failed-to-sleep-on-microsoft-windows-surface-studio-pro/" rel="bookmark" title="Laptop Battery Power Drained But Failed to Sleep on Microsoft Windows Surface Studio Pro">Laptop Battery Power Drained But Failed to Sleep on Microsoft Windows Surface Studio Pro</a> <small>I am surprised to find out that my laptop is switched off this morning &#8211;...</small></li>
<li><a href="https://helloacm.com/how-to-parallel-for-in-linux-bash-shell/" rel="bookmark" title="How to Parallel For in Linux Bash Shell?">How to Parallel For in Linux Bash Shell?</a> <small>The Linux Bash Shell supports inherent task parallelism. For example, you can put a &#038;...</small></li>
<li><a href="https://helloacm.com/using-absolute-keyword-in-delphi-to-remove-unnecessary-assignment-function/" rel="bookmark" title="Using Absolute Keyword in Delphi to Remove Unnecessary Assignment Function">Using Absolute Keyword in Delphi to Remove Unnecessary Assignment Function</a> <small>The Delphi/Object Pascal provides a keyword absolute, which you can also find examples at this...</small></li>
<li><a href="https://helloacm.com/trie-class-data-structure-in-python/" rel="bookmark" title="Trie Class Data Structure in Python">Trie Class Data Structure in Python</a> <small>Implement a trie with insert, search, and startsWith methods. Example: Trie trie = new Trie();...</small></li>
<li><a href="https://helloacm.com/how-to-create-and-run-unit-tests-in-c-net-a-quick-tutorial/" rel="bookmark" title="How to Create and Run Unit Tests in C# .NET &#8211; A Quick Tutorial">How to Create and Run Unit Tests in C# .NET &#8211; A Quick Tutorial</a> <small>This tutorial will show you how to create and run unit tests under Visual Studio....</small></li>
<li><a href="https://helloacm.com/steemit-hide-payout-update-add-customize-rules-hide-busy-wall-wallet/" rel="bookmark" title="SteemIt Hide Payout Update: Add Customize Rules + Hide busy.wall Wallet">SteemIt Hide Payout Update: Add Customize Rules + Hide busy.wall Wallet</a> <small>Introduction Hide-SteemIt-Payout is a chrome extension that hides payout and wallets for most steemit sites...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://helloacm.com/wordpress-short-code-function-showing-relevant-posts/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Microsoft Edge Settings That May Be Slowing Down Your Windows PC</title>
		<link>https://helloacm.com/microsoft-edge-settings-that-may-be-slowing-down-your-windows-pc/</link>
					<comments>https://helloacm.com/microsoft-edge-settings-that-may-be-slowing-down-your-windows-pc/#respond</comments>
		
		<dc:creator><![CDATA[ACMer]]></dc:creator>
		<pubDate>Thu, 25 Jun 2026 15:28:43 +0000</pubDate>
				<category><![CDATA[optimization]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[windows]]></category>
		<category><![CDATA[background processes]]></category>
		<category><![CDATA[background services]]></category>
		<category><![CDATA[browser security]]></category>
		<category><![CDATA[browser settings]]></category>
		<category><![CDATA[computer optimization]]></category>
		<category><![CDATA[CPU usage]]></category>
		<category><![CDATA[Edge Browser]]></category>
		<category><![CDATA[laptop performance]]></category>
		<category><![CDATA[Memory Usage]]></category>
		<category><![CDATA[Microsoft Edge]]></category>
		<category><![CDATA[PC performance]]></category>
		<category><![CDATA[Startup boost]]></category>
		<category><![CDATA[system performance]]></category>
		<category><![CDATA[Windows optimization]]></category>
		<category><![CDATA[Windows speed]]></category>
		<category><![CDATA[Windows Tips]]></category>
		<guid isPermaLink="false">https://helloacm.com/?p=157892</guid>

					<description><![CDATA[<blockquote>
This article explains how disabling Microsoft Edge’s Startup boost and background extensions can make Windows feel lighter and more responsive. It covers how these settings affect startup load, memory usage, CPU wake-ups, background processes, and laptop battery life. It also explains why disabling Edge Update services may reduce background activity but is not recommended long term, because browser updates are important for security.

Windows Feeling Slow? Turn Off These Microsoft Edge Background Settings
Make Windows Faster by Disabling Edge Startup Boost and Background Apps
Why Disabling Edge Background Processes Can Make Windows Feel Faster
How to Make Windows Lighter by Turning Off Edge Background Features
Microsoft Edge Settings That May Be Slowing Down Your Windows PC
Speed Up Windows by Reducing Microsoft Edge Background Activity
Should You Disable Edge Startup Boost? A Practical Windows Performance Tip
Make Windows Cleaner and Faster: Start with These Edge Settings
Reduce Windows Background Load by Changing These Edge Settings
A Practical Guide to Making Windows Feel Faster with Edge Settings
Why Edge Startup Boost May Be Slowing Down Your PC
Turn Off These Edge Settings for a Cleaner Windows <a href="https://helloacm.com/how-to-remove-annoying-setup-dialog-when-microsoft-office-2000-startup-due-to-problematic-add-ons/" title="How to Remove Annoying Setup Dialog When Microsoft Office 2000 startup Due to Problematic Add-ons?">Startup</a>
Microsoft Edge Background Apps: Useful Feature or Hidden Performance Cost?
Simple Windows Performance Tweak: Disable Edge Background Activity
Make Your PC Quieter and Lighter by Reducing Edge Background Processes
</blockquote>

[caption id="attachment_157893" align="alignnone" width="1277"]<a href="https://helloacm.com/microsoft-edge-settings-that-may-be-slowing-down-your-windows-pc/microsoft-edge-services/" rel="attachment wp-att-157893"><img src="https://helloacm.com/wp-content/uploads/2026/06/microsoft-edge-services.jpg" alt="Disable Edge Services" width="1277" height="887" class="size-full wp-image-157893" /></a> Disable Edge Services[/caption]

[caption id="attachment_157894" align="alignnone" width="1240"]<a href="https://helloacm.com/microsoft-edge-settings-that-may-be-slowing-down-your-windows-pc/startup-boost-windows/" rel="attachment wp-att-157894"><img src="https://helloacm.com/wp-content/uploads/2026/06/startup-boost-windows.jpg" alt="Disable Edge Starter Boost" width="1240" height="580" class="size-full wp-image-157894" /></a> Disable Edge Starter Boost[/caption]

<h2>Can Disabling Edge Background Startup Make Windows Faster?</h2>

Many people feel that Windows gets slower over time. In many cases, it is not necessarily because Windows itself has become slow, but because more and more <a href="https://codingforspeed.com/power-of-dev-containers/" title="Power of Dev Containers">applications</a> are running quietly in the background. A browser is one typical example.

The two screenshots show several Microsoft Edge-related background behaviors.

<h3>Two Edge Settings Worth Checking</h3>

In Microsoft Edge, you can go to:

<blockquote>
Settings → System and performance → System
</blockquote>

There are two key options:

<ul>
  <li><strong>Startup boost</strong></li>
  <li><strong>Continue running background extensions and apps when Edge is closed</strong></li>
</ul>

The first option is designed to make Edge start faster. The second option allows Edge extensions and apps to keep running even after the browser window is closed.

From a performance optimization point of view, both options are worth reviewing and, for many users, worth turning off.

<h3>Edge-related Services in Windows</h3>

In Windows Services, opened through <code>services.msc</code>, you may also see several Microsoft Edge-related services, such as:

<ul>
  <li><strong>Microsoft Edge Elevation Service</strong></li>
  <li><strong>Microsoft Edge Update Service (edgeupdate)</strong></li>
  <li><strong>Microsoft Edge Update Service (edgeupdatem)</strong></li>
</ul>

These services are mainly related to Edge privilege elevation, background maintenance, and automatic updates.

If you disable some background startup, background running, and automatic update-related behavior, Windows may feel slightly lighter in some situations.

But let’s be clear: this is not magic optimization. It simply reduces background processes and scheduled tasks.

<h2>1. What Is Startup Boost?</h2>

In Edge, <strong>Startup boost</strong> means that Windows can preload some Edge-related processes even before you manually open the browser.

The idea is simple: when you actually click the Edge icon, the browser opens faster because part of it has already been loaded in advance.

That sounds useful, but there is a cost:

<blockquote>
Edge may consume some memory, CPU time, and background resources before you even use it.
</blockquote>

If your PC has plenty of RAM and a powerful CPU, the impact may be tiny. But if your machine has limited resources, or you prefer a cleaner startup environment, turning it off is reasonable.

After turning it off, you may notice:

<ul>
  <li>Windows loads fewer Edge background components after startup;</li>
  <li>Memory usage may be slightly lower;</li>
  <li>There are fewer background processes;</li>
  <li>Edge may take slightly longer to open the first time.</li>
</ul>

This is a classic trade-off:

<strong>You get a cleaner Windows startup, but Edge cold startup may become slightly slower.</strong>

<h2>2. What Does “Continue Running Background Extensions and Apps When Edge Is Closed” Mean?</h2>

This option is even more worth disabling for many users.

<strong>Continue running background extensions and apps when Edge is closed</strong> means:

<blockquote>
Even after you close the Edge window, some extensions, web apps, or notification services may continue running in the background.
</blockquote>

For example:

<ul>
  <li>Browser extensions may keep running;</li>
  <li>Some web apps may continue receiving notifications;</li>
  <li>PWA apps may stay active in the background;</li>
  <li>Edge-related <a href="https://helloacm.com/how-to-exchange-data-between-processes-in-linux/" title="How to Exchange Data Between Processes in Linux?">processes</a> may not fully exit.</li>
</ul>

This can be useful for people who depend on web notifications, Teams Web App, Outlook Web App, or certain browser extensions.

But for many normal users, this option simply means Edge only appears to be closed, while some parts of it are still running in the background.

Turning it off has direct benefits:

<ul>
  <li>Edge processes are more likely to fully exit after closing the browser;</li>
  <li>Background memory usage can be reduced;</li>
  <li>Extensions are less likely to keep running silently;</li>
  <li>The system stays cleaner when idle;</li>
  <li>Laptop battery life may improve slightly.</li>
</ul>

My suggestion is simple:

<strong>If you do not rely on Edge background notifications, turn this option off.</strong>

<h2>3. Why Can These Settings Make Windows Feel Faster?</h2>

Windows performance is not only about CPU speed. It is also about how many small background processes keep waking up and interrupting the system.

When too many applications run in the background, several problems appear.

<h3>First, They Use Memory</h3>

Browsers are memory-heavy applications. Even background browser processes can use tens or hundreds of megabytes of RAM.

If your PC only has 8 GB or 16 GB of memory, and you are also running applications such as Teams, Outlook, OneDrive, VS Code, Docker, WSL, and many browser tabs, every unnecessary background component matters.

Reducing background processes can make the system feel lighter.

<h3>Second, They Wake Up the CPU</h3>

Many background programs do not constantly use high CPU. Instead, they wake up occasionally.

For example, they may check for updates, sync status, receive notifications, or scan extension states.

Each action may be small, but when many background programs do this together, the system is no longer truly idle.

You may notice symptoms such as:

<ul>
  <li>The fan spins occasionally;</li>
  <li>The laptop becomes warm;</li>
  <li>Disk and CPU activity stays busy after startup;</li>
  <li>The system occasionally feels less responsive.</li>
</ul>

<h3>Third, They Add Startup Load</h3>

Startup boost works by preloading Edge components after Windows starts.

That means Windows needs to do more work after you log in.

If your machine already has many startup programs, such as OneDrive, Teams, antivirus software, driver utilities, and cloud sync tools, adding browser preload on top of that can make the first few moments after login busier.

Disabling Startup boost reduces that startup pressure.

<h3>Fourth, They Reduce Background Extension Activity</h3>

Browser extensions are an often-overlooked source of performance overhead.

Some extensions may:

<ul>
  <li>Monitor web pages;</li>
  <li>Inject scripts;</li>
  <li>Block ads;</li>
  <li>Sync data;</li>
  <li>Collect status information;</li>
  <li>Connect to remote servers in the <a href="https://helloacm.com/how-to-put-current-running-program-in-background-without-being-terminated-when-disconnected-on-linux/" title="How to Put Current Running Program in Background without Being Terminated when Disconnected on Linux?">background</a>.</li>
</ul>

If Edge allows extensions to continue running after the browser is closed, those extensions may still consume resources.

So disabling background extensions and apps is not just a performance optimization. It also reduces background complexity.

<h2>4. Should You Disable Edge Update Services?</h2>

The screenshots also show several Edge-related services being disabled:

<ul>
  <li><strong>Microsoft Edge Elevation Service</strong></li>
  <li><strong>Microsoft Edge Update Service (edgeupdate)</strong></li>
  <li><strong>Microsoft Edge Update Service (edgeupdatem)</strong></li>
</ul>

These services are mainly related to Edge updates, privilege elevation, and maintenance.

From a performance point of view, disabling these services may reduce some background update checks and maintenance tasks.

However, this needs a serious <a href="https://helloacm.com/zero-warning-culture-in-development-team/" title="Zero Warning Culture in Development Team">warning</a>:

<blockquote>
I do not recommend disabling Edge Update services long term.
</blockquote>

The reason is simple: your browser is one of the biggest security entry points on your computer.

You use it to visit websites, download files, log in to accounts, and open links from emails. If the browser is not updated in time, you may miss important security patches.

Saving a tiny amount of background resource is usually not worth weakening browser security.

<h3>Settings I Recommend Disabling</h3>

These two options are generally safe and reasonable to turn off:

<ul>
  <li><strong>Startup boost</strong></li>
  <li><strong>Continue running background extensions and apps when Edge is closed</strong></li>
</ul>

They mainly affect background activity and startup behavior. For most users, turning them off has relatively low risk.

<h3>Services I Do Not Recommend Disabling Long Term</h3>

I would be much more careful with these services:

<ul>
  <li><strong>Microsoft Edge Update Service (edgeupdate)</strong></li>
  <li><strong>Microsoft Edge Update Service (edgeupdatem)</strong></li>
</ul>

Only disable them if you fully understand the consequences and you are willing to update Edge manually and regularly.

Otherwise, trading browser security for a tiny performance gain is not a good deal.

<h2>5. A Better Way to Optimize Windows</h2>

Do not turn Windows optimization into “disable every service you see.” That is a common mistake.

A better approach is:

<blockquote>
Disable unnecessary background behavior first, then observe whether the system becomes lighter.
</blockquote>

A more sensible priority list would be:

<ol>
  <li>Disable Edge Startup boost;</li>
  <li>Disable Edge background extensions and apps after closing the browser;</li>
  <li>Remove browser extensions you do not need;</li>
  <li>Review Windows startup apps;</li>
  <li>Only then consider service-level changes;</li>
  <li>Be cautious with browser update services.</li>
</ol>

This is especially important on work computers.

Do not randomly disable services just because the system looks cleaner afterward. Company policies, security tools, and update mechanisms may depend on background services. Randomly disabling them may feel good in the short term, but it can create problems later.

<h2>6. Who Should Turn These Options Off?</h2>

These settings are worth turning off if:

<ul>
  <li>Your PC does not have much memory;</li>
  <li>Windows feels slow after startup;</li>
  <li>You do not use Edge often;</li>
  <li>You mainly use Chrome or Firefox;</li>
  <li>You do not rely on Edge background notifications;</li>
  <li>You want a cleaner background environment;</li>
  <li>You want your laptop to run cooler and possibly save some battery.</li>
</ul>

They may not be suitable for you if:

<ul>
  <li>You heavily use <a href="https://helloacm.com/how-to-earn-microsoft-claim-points-and-redeem-rewards-by-using-bing-search-engine-and-edge-browser/" title="How to Earn Microsoft/Bing Points and Redeem Rewards by using Bing Search Engine and Edge Browser?">Edge</a>;</li>
  <li>You rely on Edge extensions running in the background;</li>
  <li>You use Edge PWA apps;</li>
  <li>You depend on web notifications;</li>
  <li>You do not want to manually check browser updates;</li>
  <li>Your company manages browser and system policies.</li>
</ul>

<h2>7. Summary</h2>

Turning off Edge <strong>Startup boost</strong> and <strong>background extensions and apps after closing Edge</strong> can make Windows cleaner and slightly lighter.

The main benefit is not that your CPU becomes faster. The benefit is reducing:

<ul>
  <li>Startup preloading;</li>
  <li><a href="https://helloacm.com/how-to-exit-your-background-process-that-takes-too-long-to-run-using-nodejs/" title="How to Exit Your Background Process that Takes Too Long to Run using NodeJs?">Background</a> processes;</li>
  <li>Memory usage;</li>
  <li>Extension background activity;</li>
  <li>Unnecessary system wake-ups.</li>
</ul>

This kind of optimization will not turn a slow computer into a high-end workstation, but it can reduce background noise and make Windows feel more responsive and more predictable.

However, be careful with Edge Update services. Browser updates are part of your security defense. I do not recommend disabling them long term just to save a small amount of system resource.

A safer approach is:

<blockquote>
Disable background startup and background extension activity, but keep browser automatic updates enabled.
</blockquote>

Good Windows optimization is not about blindly disabling services. It is about understanding the cost of each background behavior and only turning off what you truly do not need.

[show_file file="/var/www/wp-post-common/helloacm.com/windows.php"]

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/chatgpt-refactors-rewrites-the-code-using-promise-all-sending-requests-in-parallel/" rel="bookmark" title="ChatGPT Refactors/Rewrites the Code using Promise.All &#8211; Sending Requests in Parallel">ChatGPT Refactors/Rewrites the Code using Promise.All &#8211; Sending Requests in Parallel</a> <small>In one of my project, I have the following code (Node/Javascript) that invokes a few...</small></li>
<li><a href="https://helloacm.com/how-to-analyze-website-by-using-the-wappalyzer-chrome-extension/" rel="bookmark" title="How to Analyze Website by using the Wappalyzer (Chrome Extension)?">How to Analyze Website by using the Wappalyzer (Chrome Extension)?</a> <small>. And here is a list of technology used in this blog. And basically it...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-redistribute-items-to-boxes-knapsack-problem-binary-search-algorithm/" rel="bookmark" title="Teaching Kids Programming &#8211; Redistribute Items to Boxes (Knapsack Problem, Binary Search Algorithm)">Teaching Kids Programming &#8211; Redistribute Items to Boxes (Knapsack Problem, Binary Search Algorithm)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms Apple Redistribution into Boxes You are...</small></li>
<li><a href="https://helloacm.com/how-to-use-the-dynamic-link-library-in-c-linux-gcc-compiler/" rel="bookmark" title="How to Use the Dynamic Link Library in C++ Linux (gcc compiler)?">How to Use the Dynamic Link Library in C++ Linux (gcc compiler)?</a> <small>The Dynamic Link Library (DLL) is stored separately from the target application and shared among...</small></li>
<li><a href="https://helloacm.com/coding-exercise-simple-nl-implementation-on-windows-platform-using-c-gcc/" rel="bookmark" title="Coding Exercise &#8211; Simple [nl] Implementation on Windows Platform using C++ (GCC)">Coding Exercise &#8211; Simple [nl] Implementation on Windows Platform using C++ (GCC)</a> <small>On Linux BASH shell, the &#8216;nl&#8217; utility is used to print out text file (or...</small></li>
<li><a href="https://helloacm.com/how-to-enable-and-monitor-the-slow-logs-for-php-fpm/" rel="bookmark" title="How to Enable and Monitor the Slow Logs for PHP-FPM?">How to Enable and Monitor the Slow Logs for PHP-FPM?</a> <small>The CPU High Usage (Spikes) may be caused by a few factors: sudden large traffic,...</small></li>
<li><a href="https://helloacm.com/how-to-get-the-guid-using-vbscript-or-javascript-jscript-using-scriptlet-typelib/" rel="bookmark" title="How to Get the GUID using VBScript or Javascript (JScript) using Scriptlet.TypeLib?">How to Get the GUID using VBScript or Javascript (JScript) using Scriptlet.TypeLib?</a> <small>The GUID represents an unique identifier, and you can get the API to generate one...</small></li>
<li><a href="https://helloacm.com/earning-passive-income-by-staking-coins-usdt-etc-on-wirex-x-accounts/" rel="bookmark" title="Earning Passive Income by Staking Coins (USDT etc) on Wirex X-Accounts">Earning Passive Income by Staking Coins (USDT etc) on Wirex X-Accounts</a> <small>The Wirex is FCA regulated. We can stake Coins (USDT etc) on Wirex X-Accounts and...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<blockquote>
This article explains how disabling Microsoft Edge’s Startup boost and background extensions can make Windows feel lighter and more responsive. It covers how these settings affect startup load, memory usage, CPU wake-ups, background processes, and laptop battery life. It also explains why disabling Edge Update services may reduce background activity but is not recommended long term, because browser updates are important for security.

Windows Feeling Slow? Turn Off These Microsoft Edge Background Settings
Make Windows Faster by Disabling Edge Startup Boost and Background Apps
Why Disabling Edge Background Processes Can Make Windows Feel Faster
How to Make Windows Lighter by Turning Off Edge Background Features
Microsoft Edge Settings That May Be Slowing Down Your Windows PC
Speed Up Windows by Reducing Microsoft Edge Background Activity
Should You Disable Edge Startup Boost? A Practical Windows Performance Tip
Make Windows Cleaner and Faster: Start with These Edge Settings
Reduce Windows Background Load by Changing These Edge Settings
A Practical Guide to Making Windows Feel Faster with Edge Settings
Why Edge Startup Boost May Be Slowing Down Your PC
Turn Off These Edge Settings for a Cleaner Windows <a href="https://helloacm.com/how-to-remove-annoying-setup-dialog-when-microsoft-office-2000-startup-due-to-problematic-add-ons/" title="How to Remove Annoying Setup Dialog When Microsoft Office 2000 startup Due to Problematic Add-ons?">Startup</a>
Microsoft Edge Background Apps: Useful Feature or Hidden Performance Cost?
Simple Windows Performance Tweak: Disable Edge Background Activity
Make Your PC Quieter and Lighter by Reducing Edge Background Processes
</blockquote>

[caption id="attachment_157893" align="alignnone" width="1277"]<a href="https://helloacm.com/microsoft-edge-settings-that-may-be-slowing-down-your-windows-pc/microsoft-edge-services/" rel="attachment wp-att-157893"><img src="https://helloacm.com/wp-content/uploads/2026/06/microsoft-edge-services.jpg" alt="Disable Edge Services" width="1277" height="887" class="size-full wp-image-157893" /></a> Disable Edge Services[/caption]

[caption id="attachment_157894" align="alignnone" width="1240"]<a href="https://helloacm.com/microsoft-edge-settings-that-may-be-slowing-down-your-windows-pc/startup-boost-windows/" rel="attachment wp-att-157894"><img src="https://helloacm.com/wp-content/uploads/2026/06/startup-boost-windows.jpg" alt="Disable Edge Starter Boost" width="1240" height="580" class="size-full wp-image-157894" /></a> Disable Edge Starter Boost[/caption]

<h2>Can Disabling Edge Background Startup Make Windows Faster?</h2>

Many people feel that Windows gets slower over time. In many cases, it is not necessarily because Windows itself has become slow, but because more and more <a href="https://codingforspeed.com/power-of-dev-containers/" title="Power of Dev Containers">applications</a> are running quietly in the background. A browser is one typical example.

The two screenshots show several Microsoft Edge-related background behaviors.

<h3>Two Edge Settings Worth Checking</h3>

In Microsoft Edge, you can go to:

<blockquote>
Settings → System and performance → System
</blockquote>

There are two key options:

<ul>
  <li><strong>Startup boost</strong></li>
  <li><strong>Continue running background extensions and apps when Edge is closed</strong></li>
</ul>

The first option is designed to make Edge start faster. The second option allows Edge extensions and apps to keep running even after the browser window is closed.

From a performance optimization point of view, both options are worth reviewing and, for many users, worth turning off.

<h3>Edge-related Services in Windows</h3>

In Windows Services, opened through <code>services.msc</code>, you may also see several Microsoft Edge-related services, such as:

<ul>
  <li><strong>Microsoft Edge Elevation Service</strong></li>
  <li><strong>Microsoft Edge Update Service (edgeupdate)</strong></li>
  <li><strong>Microsoft Edge Update Service (edgeupdatem)</strong></li>
</ul>

These services are mainly related to Edge privilege elevation, background maintenance, and automatic updates.

If you disable some background startup, background running, and automatic update-related behavior, Windows may feel slightly lighter in some situations.

But let’s be clear: this is not magic optimization. It simply reduces background processes and scheduled tasks.

<h2>1. What Is Startup Boost?</h2>

In Edge, <strong>Startup boost</strong> means that Windows can preload some Edge-related processes even before you manually open the browser.

The idea is simple: when you actually click the Edge icon, the browser opens faster because part of it has already been loaded in advance.

That sounds useful, but there is a cost:

<blockquote>
Edge may consume some memory, CPU time, and background resources before you even use it.
</blockquote>

If your PC has plenty of RAM and a powerful CPU, the impact may be tiny. But if your machine has limited resources, or you prefer a cleaner startup environment, turning it off is reasonable.

After turning it off, you may notice:

<ul>
  <li>Windows loads fewer Edge background components after startup;</li>
  <li>Memory usage may be slightly lower;</li>
  <li>There are fewer background processes;</li>
  <li>Edge may take slightly longer to open the first time.</li>
</ul>

This is a classic trade-off:

<strong>You get a cleaner Windows startup, but Edge cold startup may become slightly slower.</strong>

<h2>2. What Does “Continue Running Background Extensions and Apps When Edge Is Closed” Mean?</h2>

This option is even more worth disabling for many users.

<strong>Continue running background extensions and apps when Edge is closed</strong> means:

<blockquote>
Even after you close the Edge window, some extensions, web apps, or notification services may continue running in the background.
</blockquote>

For example:

<ul>
  <li>Browser extensions may keep running;</li>
  <li>Some web apps may continue receiving notifications;</li>
  <li>PWA apps may stay active in the background;</li>
  <li>Edge-related <a href="https://helloacm.com/how-to-exchange-data-between-processes-in-linux/" title="How to Exchange Data Between Processes in Linux?">processes</a> may not fully exit.</li>
</ul>

This can be useful for people who depend on web notifications, Teams Web App, Outlook Web App, or certain browser extensions.

But for many normal users, this option simply means Edge only appears to be closed, while some parts of it are still running in the background.

Turning it off has direct benefits:

<ul>
  <li>Edge processes are more likely to fully exit after closing the browser;</li>
  <li>Background memory usage can be reduced;</li>
  <li>Extensions are less likely to keep running silently;</li>
  <li>The system stays cleaner when idle;</li>
  <li>Laptop battery life may improve slightly.</li>
</ul>

My suggestion is simple:

<strong>If you do not rely on Edge background notifications, turn this option off.</strong>

<h2>3. Why Can These Settings Make Windows Feel Faster?</h2>

Windows performance is not only about CPU speed. It is also about how many small background processes keep waking up and interrupting the system.

When too many applications run in the background, several problems appear.

<h3>First, They Use Memory</h3>

Browsers are memory-heavy applications. Even background browser processes can use tens or hundreds of megabytes of RAM.

If your PC only has 8 GB or 16 GB of memory, and you are also running applications such as Teams, Outlook, OneDrive, VS Code, Docker, WSL, and many browser tabs, every unnecessary background component matters.

Reducing background processes can make the system feel lighter.

<h3>Second, They Wake Up the CPU</h3>

Many background programs do not constantly use high CPU. Instead, they wake up occasionally.

For example, they may check for updates, sync status, receive notifications, or scan extension states.

Each action may be small, but when many background programs do this together, the system is no longer truly idle.

You may notice symptoms such as:

<ul>
  <li>The fan spins occasionally;</li>
  <li>The laptop becomes warm;</li>
  <li>Disk and CPU activity stays busy after startup;</li>
  <li>The system occasionally feels less responsive.</li>
</ul>

<h3>Third, They Add Startup Load</h3>

Startup boost works by preloading Edge components after Windows starts.

That means Windows needs to do more work after you log in.

If your machine already has many startup programs, such as OneDrive, Teams, antivirus software, driver utilities, and cloud sync tools, adding browser preload on top of that can make the first few moments after login busier.

Disabling Startup boost reduces that startup pressure.

<h3>Fourth, They Reduce Background Extension Activity</h3>

Browser extensions are an often-overlooked source of performance overhead.

Some extensions may:

<ul>
  <li>Monitor web pages;</li>
  <li>Inject scripts;</li>
  <li>Block ads;</li>
  <li>Sync data;</li>
  <li>Collect status information;</li>
  <li>Connect to remote servers in the <a href="https://helloacm.com/how-to-put-current-running-program-in-background-without-being-terminated-when-disconnected-on-linux/" title="How to Put Current Running Program in Background without Being Terminated when Disconnected on Linux?">background</a>.</li>
</ul>

If Edge allows extensions to continue running after the browser is closed, those extensions may still consume resources.

So disabling background extensions and apps is not just a performance optimization. It also reduces background complexity.

<h2>4. Should You Disable Edge Update Services?</h2>

The screenshots also show several Edge-related services being disabled:

<ul>
  <li><strong>Microsoft Edge Elevation Service</strong></li>
  <li><strong>Microsoft Edge Update Service (edgeupdate)</strong></li>
  <li><strong>Microsoft Edge Update Service (edgeupdatem)</strong></li>
</ul>

These services are mainly related to Edge updates, privilege elevation, and maintenance.

From a performance point of view, disabling these services may reduce some background update checks and maintenance tasks.

However, this needs a serious <a href="https://helloacm.com/zero-warning-culture-in-development-team/" title="Zero Warning Culture in Development Team">warning</a>:

<blockquote>
I do not recommend disabling Edge Update services long term.
</blockquote>

The reason is simple: your browser is one of the biggest security entry points on your computer.

You use it to visit websites, download files, log in to accounts, and open links from emails. If the browser is not updated in time, you may miss important security patches.

Saving a tiny amount of background resource is usually not worth weakening browser security.

<h3>Settings I Recommend Disabling</h3>

These two options are generally safe and reasonable to turn off:

<ul>
  <li><strong>Startup boost</strong></li>
  <li><strong>Continue running background extensions and apps when Edge is closed</strong></li>
</ul>

They mainly affect background activity and startup behavior. For most users, turning them off has relatively low risk.

<h3>Services I Do Not Recommend Disabling Long Term</h3>

I would be much more careful with these services:

<ul>
  <li><strong>Microsoft Edge Update Service (edgeupdate)</strong></li>
  <li><strong>Microsoft Edge Update Service (edgeupdatem)</strong></li>
</ul>

Only disable them if you fully understand the consequences and you are willing to update Edge manually and regularly.

Otherwise, trading browser security for a tiny performance gain is not a good deal.

<h2>5. A Better Way to Optimize Windows</h2>

Do not turn Windows optimization into “disable every service you see.” That is a common mistake.

A better approach is:

<blockquote>
Disable unnecessary background behavior first, then observe whether the system becomes lighter.
</blockquote>

A more sensible priority list would be:

<ol>
  <li>Disable Edge Startup boost;</li>
  <li>Disable Edge background extensions and apps after closing the browser;</li>
  <li>Remove browser extensions you do not need;</li>
  <li>Review Windows startup apps;</li>
  <li>Only then consider service-level changes;</li>
  <li>Be cautious with browser update services.</li>
</ol>

This is especially important on work computers.

Do not randomly disable services just because the system looks cleaner afterward. Company policies, security tools, and update mechanisms may depend on background services. Randomly disabling them may feel good in the short term, but it can create problems later.

<h2>6. Who Should Turn These Options Off?</h2>

These settings are worth turning off if:

<ul>
  <li>Your PC does not have much memory;</li>
  <li>Windows feels slow after startup;</li>
  <li>You do not use Edge often;</li>
  <li>You mainly use Chrome or Firefox;</li>
  <li>You do not rely on Edge background notifications;</li>
  <li>You want a cleaner background environment;</li>
  <li>You want your laptop to run cooler and possibly save some battery.</li>
</ul>

They may not be suitable for you if:

<ul>
  <li>You heavily use <a href="https://helloacm.com/how-to-earn-microsoft-claim-points-and-redeem-rewards-by-using-bing-search-engine-and-edge-browser/" title="How to Earn Microsoft/Bing Points and Redeem Rewards by using Bing Search Engine and Edge Browser?">Edge</a>;</li>
  <li>You rely on Edge extensions running in the background;</li>
  <li>You use Edge PWA apps;</li>
  <li>You depend on web notifications;</li>
  <li>You do not want to manually check browser updates;</li>
  <li>Your company manages browser and system policies.</li>
</ul>

<h2>7. Summary</h2>

Turning off Edge <strong>Startup boost</strong> and <strong>background extensions and apps after closing Edge</strong> can make Windows cleaner and slightly lighter.

The main benefit is not that your CPU becomes faster. The benefit is reducing:

<ul>
  <li>Startup preloading;</li>
  <li><a href="https://helloacm.com/how-to-exit-your-background-process-that-takes-too-long-to-run-using-nodejs/" title="How to Exit Your Background Process that Takes Too Long to Run using NodeJs?">Background</a> processes;</li>
  <li>Memory usage;</li>
  <li>Extension background activity;</li>
  <li>Unnecessary system wake-ups.</li>
</ul>

This kind of optimization will not turn a slow computer into a high-end workstation, but it can reduce background noise and make Windows feel more responsive and more predictable.

However, be careful with Edge Update services. Browser updates are part of your security defense. I do not recommend disabling them long term just to save a small amount of system resource.

A safer approach is:

<blockquote>
Disable background startup and background extension activity, but keep browser automatic updates enabled.
</blockquote>

Good Windows optimization is not about blindly disabling services. It is about understanding the cost of each background behavior and only turning off what you truly do not need.

[show_file file="/var/www/wp-post-common/helloacm.com/windows.php"]

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/chatgpt-refactors-rewrites-the-code-using-promise-all-sending-requests-in-parallel/" rel="bookmark" title="ChatGPT Refactors/Rewrites the Code using Promise.All &#8211; Sending Requests in Parallel">ChatGPT Refactors/Rewrites the Code using Promise.All &#8211; Sending Requests in Parallel</a> <small>In one of my project, I have the following code (Node/Javascript) that invokes a few...</small></li>
<li><a href="https://helloacm.com/how-to-analyze-website-by-using-the-wappalyzer-chrome-extension/" rel="bookmark" title="How to Analyze Website by using the Wappalyzer (Chrome Extension)?">How to Analyze Website by using the Wappalyzer (Chrome Extension)?</a> <small>. And here is a list of technology used in this blog. And basically it...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-redistribute-items-to-boxes-knapsack-problem-binary-search-algorithm/" rel="bookmark" title="Teaching Kids Programming &#8211; Redistribute Items to Boxes (Knapsack Problem, Binary Search Algorithm)">Teaching Kids Programming &#8211; Redistribute Items to Boxes (Knapsack Problem, Binary Search Algorithm)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms Apple Redistribution into Boxes You are...</small></li>
<li><a href="https://helloacm.com/how-to-use-the-dynamic-link-library-in-c-linux-gcc-compiler/" rel="bookmark" title="How to Use the Dynamic Link Library in C++ Linux (gcc compiler)?">How to Use the Dynamic Link Library in C++ Linux (gcc compiler)?</a> <small>The Dynamic Link Library (DLL) is stored separately from the target application and shared among...</small></li>
<li><a href="https://helloacm.com/coding-exercise-simple-nl-implementation-on-windows-platform-using-c-gcc/" rel="bookmark" title="Coding Exercise &#8211; Simple [nl] Implementation on Windows Platform using C++ (GCC)">Coding Exercise &#8211; Simple [nl] Implementation on Windows Platform using C++ (GCC)</a> <small>On Linux BASH shell, the &#8216;nl&#8217; utility is used to print out text file (or...</small></li>
<li><a href="https://helloacm.com/how-to-enable-and-monitor-the-slow-logs-for-php-fpm/" rel="bookmark" title="How to Enable and Monitor the Slow Logs for PHP-FPM?">How to Enable and Monitor the Slow Logs for PHP-FPM?</a> <small>The CPU High Usage (Spikes) may be caused by a few factors: sudden large traffic,...</small></li>
<li><a href="https://helloacm.com/how-to-get-the-guid-using-vbscript-or-javascript-jscript-using-scriptlet-typelib/" rel="bookmark" title="How to Get the GUID using VBScript or Javascript (JScript) using Scriptlet.TypeLib?">How to Get the GUID using VBScript or Javascript (JScript) using Scriptlet.TypeLib?</a> <small>The GUID represents an unique identifier, and you can get the API to generate one...</small></li>
<li><a href="https://helloacm.com/earning-passive-income-by-staking-coins-usdt-etc-on-wirex-x-accounts/" rel="bookmark" title="Earning Passive Income by Staking Coins (USDT etc) on Wirex X-Accounts">Earning Passive Income by Staking Coins (USDT etc) on Wirex X-Accounts</a> <small>The Wirex is FCA regulated. We can stake Coins (USDT etc) on Wirex X-Accounts and...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://helloacm.com/microsoft-edge-settings-that-may-be-slowing-down-your-windows-pc/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>A Tiny Logic Puzzle About Truth and Lies</title>
		<link>https://helloacm.com/a-tiny-logic-puzzle-about-truth-and-lies/</link>
					<comments>https://helloacm.com/a-tiny-logic-puzzle-about-truth-and-lies/#respond</comments>
		
		<dc:creator><![CDATA[ACMer]]></dc:creator>
		<pubDate>Wed, 10 Jun 2026 14:06:20 +0000</pubDate>
				<category><![CDATA[logic tests]]></category>
		<category><![CDATA[math]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[Brain Teaser]]></category>
		<category><![CDATA[critical thinking]]></category>
		<category><![CDATA[fun math]]></category>
		<category><![CDATA[logic puzzle]]></category>
		<category><![CDATA[logical reasoning]]></category>
		<category><![CDATA[mathematical thinking]]></category>
		<category><![CDATA[reasoning]]></category>
		<category><![CDATA[rigorous thinking]]></category>
		<category><![CDATA[truth and lies puzzle]]></category>
		<category><![CDATA[village puzzle]]></category>
		<guid isPermaLink="false">https://helloacm.com/?p=157879</guid>

					<description><![CDATA[<blockquote>
A small village logic puzzle shows why careful reasoning matters. With 100 villagers each giving a different answer from 1 to 100, only one answer can be true. Since men always tell the truth and women always lie, the village must have exactly 1 man and 99 women. This is verified by a Python program/code.
</blockquote>

I came across a fun little logic puzzle today. At first glance, it looks like a simple counting question, but the trick is hidden in the relationship between truth and lies.

The story goes like this:

<blockquote>
Once upon a time, there was a strange village with exactly 100 people. Some were men and some were women. In this village, men always told the truth, while women always lied.

One day, a stranger arrived and asked the villagers:

“How many women are there in your village?”

The first villager answered, “One.”

The second villager answered, “Two.”

The third villager answered, “Three.”

And so on, until the hundredth villager answered, “One hundred.”

So the question is: how many women are actually in the village?
</blockquote>

The answer is <strong>99 women and 1 man</strong>.

Here is the reasoning.

Suppose the village has <strong>W women</strong>. Then the true answer to the stranger’s question must be <strong>W</strong>.

But the 100 villagers gave 100 different answers: 1, 2, 3, all the way up to 100. Among these answers, only one number can be correct — the number equal to W.

That means only one villager told the truth.

Since men always tell the truth, that one truthful villager must be the only man in the village. Everyone else lied, so they must all be women.

Therefore, the village has:

<strong>1 man and 99 women.</strong>

To check the logic, imagine there are really 99 women. Then the villager who answered “99” told the truth, so he is the man. The other 99 villagers gave incorrect answers, so they are women. Everything matches perfectly.

This is why I like small logic puzzles. They look casual and almost childish, but they force you to be precise. If you rush, you may try to guess the number directly. But if you slow down and define what the true answer must be, the puzzle solves itself.

Sometimes logic is not about being clever. It is about refusing to be sloppy.

Let's verify using a Python program:

<pre lang=python>
def possible(woman, total):
    truth_tellers = sum(1 for claim in range(1, total + 1) if claim == woman)
    liars = total - truth_tellers
    man = total - woman
    return truth_tellers == man and liars == woman

def check():
    total = 100
    for woman in range(total + 1):
        if possible(woman, total):
            print(f"Woman = {woman}, Man = {total - woman}")

if __name__ == "__main__":
    check()

## Prints: Woman = 99, Man = 1
</pre>

[show_file file="/var/www/wp-post-common/helloacm.com/logics.php"]

Steemit: <a href="https://steemit.com/blog/@justyy/a-tiny-logic-puzzle-about-truth-and-lies" title="A Tiny Logic Puzzle About Truth and Lies">A Tiny Logic Puzzle About Truth and Lies</a> | Blurt: <a href="https://blurt.blog/blog/@justyy/6p41aw-a-tiny-logic-puzzle-about-truth-and-lies" title="A Tiny Logic Puzzle About Truth and Lies">A Tiny Logic Puzzle About Truth and Lies</a>

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/teaching-kids-programming-vlog-harness-engineering-commanding-ai-to-get-work-done/" rel="bookmark" title="Teaching Kids Programming vLog: Harness Engineering — Commanding AI to Get Work Done">Teaching Kids Programming vLog: Harness Engineering — Commanding AI to Get Work Done</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms This post shares a hands-on programming...</small></li>
<li><a href="https://helloacm.com/chatgpt-image-2-0-casual-selfie-of-me/" rel="bookmark" title="ChatGPT Image 2.0 &#8211; Casual Selfie of Me">ChatGPT Image 2.0 &#8211; Casual Selfie of Me</a> <small>ChatGPT Image 2.0 &#8211; Text2Image ChatGPT Image 2.0 is getting the vibe! It produces really...</small></li>
<li><a href="https://helloacm.com/simple-nodejs-example-to-show-average-scores-in-the-steemit-wechat-group/" rel="bookmark" title="Simple NodeJS Example to Show Average Scores in the Steemit-Wechat Group">Simple NodeJS Example to Show Average Scores in the Steemit-Wechat Group</a> <small>I have shown a simple NodeJS example that calls the SteemIt Wechat API to get...</small></li>
<li><a href="https://helloacm.com/cointools-update-adding-cryptocompare-source-context-shortcut/" rel="bookmark" title="CoinTools Update: Adding Cryptocompare Source + Context Shortcut">CoinTools Update: Adding Cryptocompare Source + Context Shortcut</a> <small>Introduction to CoinTools CoinTools is a powerful, lightweight Chrome Extension for Cryptocurrency fans! It can...</small></li>
<li><a href="https://helloacm.com/steemtools-v0-0-7-query-powerdown-status-add-sbds-api-server-backend-fix-voting-power/" rel="bookmark" title="SteemTools v0.0.7: Query Powerdown Status, Add SBDS API Server (Backend), Fix Voting Power">SteemTools v0.0.7: Query Powerdown Status, Add SBDS API Server (Backend), Fix Voting Power</a> <small>Introduction to SteemTools SteemTools is a Chrome Extension that aims to provide useful tools and...</small></li>
<li><a href="https://helloacm.com/compute-gcd-in-bash-with-input-validation/" rel="bookmark" title="Compute GCD in Bash with Input Validation">Compute GCD in Bash with Input Validation</a> <small>GCD Computation in Bash What is GCD? GCD stands for Greatest Common Divisor. It is...</small></li>
<li><a href="https://helloacm.com/steemit-api-two-apis-to-get-the-followers-and-following-list-in-the-wechat-group/" rel="bookmark" title="SteemIt API &#8211; Two APIs to get the followers and following list in the Wechat Group">SteemIt API &#8211; Two APIs to get the followers and following list in the Wechat Group</a> <small>Two APIs are made available exclusively for the members in the wechat group. Contact contact#tumutanzi.com...</small></li>
<li><a href="https://helloacm.com/the-sunset-of-onekey-crypto-card/" rel="bookmark" title="The Sunset of OneKey Crypto Card">The Sunset of OneKey Crypto Card</a> <small>I learned about OneKey, a cryptocurrency cash-out card, a couple of years ago, but I...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<blockquote>
A small village logic puzzle shows why careful reasoning matters. With 100 villagers each giving a different answer from 1 to 100, only one answer can be true. Since men always tell the truth and women always lie, the village must have exactly 1 man and 99 women. This is verified by a Python program/code.
</blockquote>

I came across a fun little logic puzzle today. At first glance, it looks like a simple counting question, but the trick is hidden in the relationship between truth and lies.

The story goes like this:

<blockquote>
Once upon a time, there was a strange village with exactly 100 people. Some were men and some were women. In this village, men always told the truth, while women always lied.

One day, a stranger arrived and asked the villagers:

“How many women are there in your village?”

The first villager answered, “One.”

The second villager answered, “Two.”

The third villager answered, “Three.”

And so on, until the hundredth villager answered, “One hundred.”

So the question is: how many women are actually in the village?
</blockquote>

The answer is <strong>99 women and 1 man</strong>.

Here is the reasoning.

Suppose the village has <strong>W women</strong>. Then the true answer to the stranger’s question must be <strong>W</strong>.

But the 100 villagers gave 100 different answers: 1, 2, 3, all the way up to 100. Among these answers, only one number can be correct — the number equal to W.

That means only one villager told the truth.

Since men always tell the truth, that one truthful villager must be the only man in the village. Everyone else lied, so they must all be women.

Therefore, the village has:

<strong>1 man and 99 women.</strong>

To check the logic, imagine there are really 99 women. Then the villager who answered “99” told the truth, so he is the man. The other 99 villagers gave incorrect answers, so they are women. Everything matches perfectly.

This is why I like small logic puzzles. They look casual and almost childish, but they force you to be precise. If you rush, you may try to guess the number directly. But if you slow down and define what the true answer must be, the puzzle solves itself.

Sometimes logic is not about being clever. It is about refusing to be sloppy.

Let's verify using a Python program:

<pre lang=python>
def possible(woman, total):
    truth_tellers = sum(1 for claim in range(1, total + 1) if claim == woman)
    liars = total - truth_tellers
    man = total - woman
    return truth_tellers == man and liars == woman

def check():
    total = 100
    for woman in range(total + 1):
        if possible(woman, total):
            print(f"Woman = {woman}, Man = {total - woman}")

if __name__ == "__main__":
    check()

## Prints: Woman = 99, Man = 1
</pre>

[show_file file="/var/www/wp-post-common/helloacm.com/logics.php"]

Steemit: <a href="https://steemit.com/blog/@justyy/a-tiny-logic-puzzle-about-truth-and-lies" title="A Tiny Logic Puzzle About Truth and Lies">A Tiny Logic Puzzle About Truth and Lies</a> | Blurt: <a href="https://blurt.blog/blog/@justyy/6p41aw-a-tiny-logic-puzzle-about-truth-and-lies" title="A Tiny Logic Puzzle About Truth and Lies">A Tiny Logic Puzzle About Truth and Lies</a>

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/teaching-kids-programming-vlog-harness-engineering-commanding-ai-to-get-work-done/" rel="bookmark" title="Teaching Kids Programming vLog: Harness Engineering — Commanding AI to Get Work Done">Teaching Kids Programming vLog: Harness Engineering — Commanding AI to Get Work Done</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms This post shares a hands-on programming...</small></li>
<li><a href="https://helloacm.com/chatgpt-image-2-0-casual-selfie-of-me/" rel="bookmark" title="ChatGPT Image 2.0 &#8211; Casual Selfie of Me">ChatGPT Image 2.0 &#8211; Casual Selfie of Me</a> <small>ChatGPT Image 2.0 &#8211; Text2Image ChatGPT Image 2.0 is getting the vibe! It produces really...</small></li>
<li><a href="https://helloacm.com/simple-nodejs-example-to-show-average-scores-in-the-steemit-wechat-group/" rel="bookmark" title="Simple NodeJS Example to Show Average Scores in the Steemit-Wechat Group">Simple NodeJS Example to Show Average Scores in the Steemit-Wechat Group</a> <small>I have shown a simple NodeJS example that calls the SteemIt Wechat API to get...</small></li>
<li><a href="https://helloacm.com/cointools-update-adding-cryptocompare-source-context-shortcut/" rel="bookmark" title="CoinTools Update: Adding Cryptocompare Source + Context Shortcut">CoinTools Update: Adding Cryptocompare Source + Context Shortcut</a> <small>Introduction to CoinTools CoinTools is a powerful, lightweight Chrome Extension for Cryptocurrency fans! It can...</small></li>
<li><a href="https://helloacm.com/steemtools-v0-0-7-query-powerdown-status-add-sbds-api-server-backend-fix-voting-power/" rel="bookmark" title="SteemTools v0.0.7: Query Powerdown Status, Add SBDS API Server (Backend), Fix Voting Power">SteemTools v0.0.7: Query Powerdown Status, Add SBDS API Server (Backend), Fix Voting Power</a> <small>Introduction to SteemTools SteemTools is a Chrome Extension that aims to provide useful tools and...</small></li>
<li><a href="https://helloacm.com/compute-gcd-in-bash-with-input-validation/" rel="bookmark" title="Compute GCD in Bash with Input Validation">Compute GCD in Bash with Input Validation</a> <small>GCD Computation in Bash What is GCD? GCD stands for Greatest Common Divisor. It is...</small></li>
<li><a href="https://helloacm.com/steemit-api-two-apis-to-get-the-followers-and-following-list-in-the-wechat-group/" rel="bookmark" title="SteemIt API &#8211; Two APIs to get the followers and following list in the Wechat Group">SteemIt API &#8211; Two APIs to get the followers and following list in the Wechat Group</a> <small>Two APIs are made available exclusively for the members in the wechat group. Contact contact#tumutanzi.com...</small></li>
<li><a href="https://helloacm.com/the-sunset-of-onekey-crypto-card/" rel="bookmark" title="The Sunset of OneKey Crypto Card">The Sunset of OneKey Crypto Card</a> <small>I learned about OneKey, a cryptocurrency cash-out card, a couple of years ago, but I...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://helloacm.com/a-tiny-logic-puzzle-about-truth-and-lies/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Teaching Kids Programming vLog: Harness Engineering — Commanding AI to Get Work Done</title>
		<link>https://helloacm.com/teaching-kids-programming-vlog-harness-engineering-commanding-ai-to-get-work-done/</link>
					<comments>https://helloacm.com/teaching-kids-programming-vlog-harness-engineering-commanding-ai-to-get-work-done/#respond</comments>
		
		<dc:creator><![CDATA[ACMer]]></dc:creator>
		<pubDate>Sat, 30 May 2026 20:25:49 +0000</pubDate>
				<category><![CDATA[Artificial Intelligence]]></category>
		<category><![CDATA[Harness Engineering]]></category>
		<category><![CDATA[Prompt Engineering]]></category>
		<category><![CDATA[software development]]></category>
		<category><![CDATA[Vibe Coding]]></category>
		<category><![CDATA[youtube video]]></category>
		<category><![CDATA[AI Agent]]></category>
		<category><![CDATA[AI Programming]]></category>
		<category><![CDATA[Coding Education]]></category>
		<category><![CDATA[developer tools]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[GitHub Pages]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[Kids Coding]]></category>
		<category><![CDATA[LLM]]></category>
		<category><![CDATA[markdown]]></category>
		<category><![CDATA[Modern Software Engineering]]></category>
		<category><![CDATA[Pull Request]]></category>
		<category><![CDATA[software engineering]]></category>
		<category><![CDATA[Teaching Kids Programming]]></category>
		<category><![CDATA[visual studio code]]></category>
		<category><![CDATA[VS Code]]></category>
		<category><![CDATA[Youtube Video]]></category>
		<guid isPermaLink="false">https://helloacm.com/?p=157870</guid>

					<description><![CDATA[<blockquote>
This post shares a hands-on programming lesson with my son, using the VS Code AI Agent to clean up his GitHub Pages homepage. It reflects on how programming education is changing in the AI era: beyond writing code manually, kids now need to learn how to describe requirements clearly, command AI agents, understand Git/GitHub workflows, and review AI-generated code responsibly. The post also introduces the idea of Harness Engineering, where the LLM is only the “brain”, while the surrounding tools, workflows, and validation mechanisms are what allow AI to truly get work done.
</blockquote>

Last year, my younger son learned some GitHub, Markdown, and HTML. He also created his own personal homepage on <a href="https://ryanhlai.github.io" title="GitHub Pages for Ryan Lai" rel="noopener" target="_blank">GitHub Pages</a>. The page worked, but it was still quite messy: the layout was not very consistent, the content structure was unclear in places, and the code looked a bit like it had been written wherever inspiration happened to strike.

So this time, I used it as an opportunity to show him how to use an AI Agent inside VS Code to improve the website.

In the past, when we taught kids programming, the focus was usually on “how to write code by hand”: how HTML tags work, how to tweak CSS, and how to run Git commands. But things are different now. With AI Agents, a lot of code no longer needs to be written line by line manually. The more important skills become: can you describe the goal clearly, can you command AI to get work done, can you understand what it changed, and can you judge whether the generated code is correct?

This is what I understand as Harness Engineering.

In simple terms:



<blockquote>Harness = Agent - Model (LLM)</blockquote>

The Harness Engineer Post by OpenAI:

<blockquote>
https://openai.com/index/harness-engineering/

Redefining the role of the engineer
The lack of hands-on human coding introduced a different kind of engineering work, focused on systems, scaffolding, and leverage.
</blockquote>

That means everything around the large language model, except the model itself, can be considered part of the harness. This includes tool <a href="https://helloacm.com/calling-c-shared-library-from-python-code-linux-version/" title="Calling C++ Shared Library from Python Code (Linux Version)">calling</a>, file reading and writing, code editing, terminal execution, context management, task decomposition, workflow control, permission boundaries, result validation, and so on.

The LLM is the “brain”, but the harness provides the “hands, feet, and working environment”.

Without a harness, a large model can only chat. With a harness, it can actually start doing work.

The demo I gave my son was very simple: we opened his GitHub Pages project, then gave the <a href="https://helloacm.com/a-super-agent/" title="Codeforces: A. Super Agent">Agent</a> a prompt inside VS Code, something like:

“Please help me clean up this personal homepage. Make the page structure clearer and the styling more consistent. Keep the existing content, and don’t make it too complicated.”

The AI Agent then started reading the files, understanding the structure, modifying the HTML and CSS, and even explaining what changes it had made. For a child, this process is very intuitive. Programming is no longer just about burying your head in the code and typing everything yourself. You can also act like a small “project manager”: describe the goal clearly, then let AI help with the implementation.

Of course, this does not mean we no longer need to learn <a href="https://helloacm.com/teaching-kids-programming-verify-preorder-sequence-in-binary-search-tree-monotonous-stack/" title="Teaching Kids Programming – Verify Preorder Sequence in Binary Search Tree (Monotonous Stack)">programming</a>.

Quite the opposite. The more AI we have, the more important the fundamentals become. Otherwise, if <a href="https://codingforspeed.com/ai-coding-assistants-risks-mitigation-future-and-insights/" title="AI Agent" rel="noopener" target="_blank">AI</a> writes something wrong, you won’t notice. If it messes up the project structure, you won’t know how to recover. If problematic code gets committed, you won’t know where the issue is.

So along the way, I also taught my son some basic <a href="https://helloacm.com/how-to-setup-and-create-github-pages-serverless-static-apps/" title="How to Setup and Create GitHub Pages (Serverless Static Apps)">GitHub</a> workflow commands:



<blockquote>git add</blockquote>



Add modified files to the staging area.



<blockquote>git commit</blockquote>



Create a clear record for this set of changes.



<blockquote>git push</blockquote>



Push local changes to GitHub.

We also talked about Pull Requests, or PRs. Even for a small personal project, it is a good habit to use PRs to review changes, describe what has been modified, and check the code before merging.

I think this is the kind of <a href="https://helloacm.com/ai-coding-agents-are-reshaping-the-barrier-to-programming/" title="AI Coding Agents Are Reshaping the Barrier to Programming">programming</a> education kids really need in the AI era.

It is not about memorising every syntax rule, nor about writing HTML just for the sake of writing HTML. It is about understanding how a software project is modified, tested, submitted, and maintained. AI can help you write code, but you are still responsible for defining the requirements, checking the result, managing versions, and judging quality.

In the future, many jobs may work like this: you may not personally handle every tiny detail, but you need to know how to break down complex tasks, how to direct AI effectively, and how to take responsibility for the final result.

That is also one of the ideas I wanted to share with my son through this vLog:

Knowing how to write code is important, but knowing how to use tools to solve problems is even more important.

AI Agents do not replace learning. Instead, they move learning up one level. In the past, children learned “how to write code”. Now, they also need to learn “how to make AI write reliable code”.

And that is actually quite interesting.

My son originally just wanted to improve his personal homepage. But in the process, he experienced several key parts of real software engineering: describing requirements, collaborating with AI, modifying code, committing with Git, creating Pull Requests, and reviewing code.

That is much closer to real-world engineering practice than simply memorising a few HTML tags.

<iframe width="2891" height="986" src="https://www.youtube.com/embed/tnNBNbh3al4" title="Teaching Kids Programming vLog - Harness Engineering - Using Visual Studio AI Agent 指挥AI干活" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

[show_file file="/var/www/wp-post-common/helloacm.com/prompt.php"]

steemit：<a href="https://steemit.com/blog/@justyy/teaching-kids-programming-vlog-harness-engineering-using-visual-studio-ai-agent" title="Teaching Kids Programming vLog - Harness Engineering - Using Visual Studio AI Agent">Teaching Kids Programming vLog - Harness Engineering - Using Visual Studio AI Agent</a>

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/ai-coding-agents-are-reshaping-the-barrier-to-programming/" rel="bookmark" title="AI Coding Agents Are Reshaping the Barrier to Programming">AI Coding Agents Are Reshaping the Barrier to Programming</a> <small>AI Coding Agents Are Reshaping the Barrier to Programming Coding Is Becoming as Easy as...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-verify-preorder-sequence-in-binary-search-tree-monotonous-stack/" rel="bookmark" title="Teaching Kids Programming &#8211; Verify Preorder Sequence in Binary Search Tree (Monotonous Stack)">Teaching Kids Programming &#8211; Verify Preorder Sequence in Binary Search Tree (Monotonous Stack)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms A stack-based solution for LeetCode 255,...</small></li>
<li><a href="https://helloacm.com/toss-a-coin-256-times-the-math-behind-an-unbreakable-bitcoin-private-key/" rel="bookmark" title="Toss a Coin 256 Times: The Math Behind an Unbreakable Bitcoin Private Key">Toss a Coin 256 Times: The Math Behind an Unbreakable Bitcoin Private Key</a> <small>Why Cracking a Bitcoin Key Is Harder Than You Can Possibly Imagine I often see...</small></li>
<li><a href="https://helloacm.com/a-next-round/" rel="bookmark" title="Codeforces: A. Next Round">Codeforces: A. Next Round</a> <small>The problem is from codeforces: http://www.codeforces.com/problemset/problem/158/A It is summer. The temperature today in Sheffield is...</small></li>
<li><a href="https://helloacm.com/how-to-construct-binary-search-tree-from-preorder-traversal-c-and-java/" rel="bookmark" title="How to Construct Binary Search Tree from Preorder Traversal? (C++ and Java)">How to Construct Binary Search Tree from Preorder Traversal? (C++ and Java)</a> <small>Return the root node of a binary search tree that matches the given preorder traversal....</small></li>
<li><a href="https://helloacm.com/crypto-news-dogecoins-rise-to-prominence-in-2025-femo/" rel="bookmark" title="Crypto News: Dogecoin&#8217;s Rise to Prominence in 2025 (FEMO?)">Crypto News: Dogecoin&#8217;s Rise to Prominence in 2025 (FEMO?)</a> <small>Introduction to Dogecoin Dogecoin is a decentralized digital currency based on blockchain technology, created by...</small></li>
<li><a href="https://helloacm.com/c-lvalue-rvalue-and-rvalue-references/" rel="bookmark" title="C++: lvalue, rvalue and rvalue references">C++: lvalue, rvalue and rvalue references</a> <small>C++ lvalue, rvalue, and rvalue references Understanding lvalues, rvalues, and rvalue references is essential for...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-max-profit-of-rod-cutting-unbounded-knapsack-via-bottom-up-dynamic-programming-algorithm/" rel="bookmark" title="Teaching Kids Programming &#8211; Max Profit of Rod Cutting (Unbounded Knapsack) via Bottom Up Dynamic Programming Algorithm">Teaching Kids Programming &#8211; Max Profit of Rod Cutting (Unbounded Knapsack) via Bottom Up Dynamic Programming Algorithm</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given a list of...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<blockquote>
This post shares a hands-on programming lesson with my son, using the VS Code AI Agent to clean up his GitHub Pages homepage. It reflects on how programming education is changing in the AI era: beyond writing code manually, kids now need to learn how to describe requirements clearly, command AI agents, understand Git/GitHub workflows, and review AI-generated code responsibly. The post also introduces the idea of Harness Engineering, where the LLM is only the “brain”, while the surrounding tools, workflows, and validation mechanisms are what allow AI to truly get work done.
</blockquote>

Last year, my younger son learned some GitHub, Markdown, and HTML. He also created his own personal homepage on <a href="https://ryanhlai.github.io" title="GitHub Pages for Ryan Lai" rel="noopener" target="_blank">GitHub Pages</a>. The page worked, but it was still quite messy: the layout was not very consistent, the content structure was unclear in places, and the code looked a bit like it had been written wherever inspiration happened to strike.

So this time, I used it as an opportunity to show him how to use an AI Agent inside VS Code to improve the website.

In the past, when we taught kids programming, the focus was usually on “how to write code by hand”: how HTML tags work, how to tweak CSS, and how to run Git commands. But things are different now. With AI Agents, a lot of code no longer needs to be written line by line manually. The more important skills become: can you describe the goal clearly, can you command AI to get work done, can you understand what it changed, and can you judge whether the generated code is correct?

This is what I understand as Harness Engineering.

In simple terms:



<blockquote>Harness = Agent - Model (LLM)</blockquote>

The Harness Engineer Post by OpenAI:

<blockquote>
https://openai.com/index/harness-engineering/

Redefining the role of the engineer
The lack of hands-on human coding introduced a different kind of engineering work, focused on systems, scaffolding, and leverage.
</blockquote>

That means everything around the large language model, except the model itself, can be considered part of the harness. This includes tool <a href="https://helloacm.com/calling-c-shared-library-from-python-code-linux-version/" title="Calling C++ Shared Library from Python Code (Linux Version)">calling</a>, file reading and writing, code editing, terminal execution, context management, task decomposition, workflow control, permission boundaries, result validation, and so on.

The LLM is the “brain”, but the harness provides the “hands, feet, and working environment”.

Without a harness, a large model can only chat. With a harness, it can actually start doing work.

The demo I gave my son was very simple: we opened his GitHub Pages project, then gave the <a href="https://helloacm.com/a-super-agent/" title="Codeforces: A. Super Agent">Agent</a> a prompt inside VS Code, something like:

“Please help me clean up this personal homepage. Make the page structure clearer and the styling more consistent. Keep the existing content, and don’t make it too complicated.”

The AI Agent then started reading the files, understanding the structure, modifying the HTML and CSS, and even explaining what changes it had made. For a child, this process is very intuitive. Programming is no longer just about burying your head in the code and typing everything yourself. You can also act like a small “project manager”: describe the goal clearly, then let AI help with the implementation.

Of course, this does not mean we no longer need to learn <a href="https://helloacm.com/teaching-kids-programming-verify-preorder-sequence-in-binary-search-tree-monotonous-stack/" title="Teaching Kids Programming – Verify Preorder Sequence in Binary Search Tree (Monotonous Stack)">programming</a>.

Quite the opposite. The more AI we have, the more important the fundamentals become. Otherwise, if <a href="https://codingforspeed.com/ai-coding-assistants-risks-mitigation-future-and-insights/" title="AI Agent" rel="noopener" target="_blank">AI</a> writes something wrong, you won’t notice. If it messes up the project structure, you won’t know how to recover. If problematic code gets committed, you won’t know where the issue is.

So along the way, I also taught my son some basic <a href="https://helloacm.com/how-to-setup-and-create-github-pages-serverless-static-apps/" title="How to Setup and Create GitHub Pages (Serverless Static Apps)">GitHub</a> workflow commands:



<blockquote>git add</blockquote>



Add modified files to the staging area.



<blockquote>git commit</blockquote>



Create a clear record for this set of changes.



<blockquote>git push</blockquote>



Push local changes to GitHub.

We also talked about Pull Requests, or PRs. Even for a small personal project, it is a good habit to use PRs to review changes, describe what has been modified, and check the code before merging.

I think this is the kind of <a href="https://helloacm.com/ai-coding-agents-are-reshaping-the-barrier-to-programming/" title="AI Coding Agents Are Reshaping the Barrier to Programming">programming</a> education kids really need in the AI era.

It is not about memorising every syntax rule, nor about writing HTML just for the sake of writing HTML. It is about understanding how a software project is modified, tested, submitted, and maintained. AI can help you write code, but you are still responsible for defining the requirements, checking the result, managing versions, and judging quality.

In the future, many jobs may work like this: you may not personally handle every tiny detail, but you need to know how to break down complex tasks, how to direct AI effectively, and how to take responsibility for the final result.

That is also one of the ideas I wanted to share with my son through this vLog:

Knowing how to write code is important, but knowing how to use tools to solve problems is even more important.

AI Agents do not replace learning. Instead, they move learning up one level. In the past, children learned “how to write code”. Now, they also need to learn “how to make AI write reliable code”.

And that is actually quite interesting.

My son originally just wanted to improve his personal homepage. But in the process, he experienced several key parts of real software engineering: describing requirements, collaborating with AI, modifying code, committing with Git, creating Pull Requests, and reviewing code.

That is much closer to real-world engineering practice than simply memorising a few HTML tags.

<iframe width="2891" height="986" src="https://www.youtube.com/embed/tnNBNbh3al4" title="Teaching Kids Programming vLog - Harness Engineering - Using Visual Studio AI Agent 指挥AI干活" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

[show_file file="/var/www/wp-post-common/helloacm.com/prompt.php"]

steemit：<a href="https://steemit.com/blog/@justyy/teaching-kids-programming-vlog-harness-engineering-using-visual-studio-ai-agent" title="Teaching Kids Programming vLog - Harness Engineering - Using Visual Studio AI Agent">Teaching Kids Programming vLog - Harness Engineering - Using Visual Studio AI Agent</a>

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/ai-coding-agents-are-reshaping-the-barrier-to-programming/" rel="bookmark" title="AI Coding Agents Are Reshaping the Barrier to Programming">AI Coding Agents Are Reshaping the Barrier to Programming</a> <small>AI Coding Agents Are Reshaping the Barrier to Programming Coding Is Becoming as Easy as...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-verify-preorder-sequence-in-binary-search-tree-monotonous-stack/" rel="bookmark" title="Teaching Kids Programming &#8211; Verify Preorder Sequence in Binary Search Tree (Monotonous Stack)">Teaching Kids Programming &#8211; Verify Preorder Sequence in Binary Search Tree (Monotonous Stack)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms A stack-based solution for LeetCode 255,...</small></li>
<li><a href="https://helloacm.com/toss-a-coin-256-times-the-math-behind-an-unbreakable-bitcoin-private-key/" rel="bookmark" title="Toss a Coin 256 Times: The Math Behind an Unbreakable Bitcoin Private Key">Toss a Coin 256 Times: The Math Behind an Unbreakable Bitcoin Private Key</a> <small>Why Cracking a Bitcoin Key Is Harder Than You Can Possibly Imagine I often see...</small></li>
<li><a href="https://helloacm.com/a-next-round/" rel="bookmark" title="Codeforces: A. Next Round">Codeforces: A. Next Round</a> <small>The problem is from codeforces: http://www.codeforces.com/problemset/problem/158/A It is summer. The temperature today in Sheffield is...</small></li>
<li><a href="https://helloacm.com/how-to-construct-binary-search-tree-from-preorder-traversal-c-and-java/" rel="bookmark" title="How to Construct Binary Search Tree from Preorder Traversal? (C++ and Java)">How to Construct Binary Search Tree from Preorder Traversal? (C++ and Java)</a> <small>Return the root node of a binary search tree that matches the given preorder traversal....</small></li>
<li><a href="https://helloacm.com/crypto-news-dogecoins-rise-to-prominence-in-2025-femo/" rel="bookmark" title="Crypto News: Dogecoin&#8217;s Rise to Prominence in 2025 (FEMO?)">Crypto News: Dogecoin&#8217;s Rise to Prominence in 2025 (FEMO?)</a> <small>Introduction to Dogecoin Dogecoin is a decentralized digital currency based on blockchain technology, created by...</small></li>
<li><a href="https://helloacm.com/c-lvalue-rvalue-and-rvalue-references/" rel="bookmark" title="C++: lvalue, rvalue and rvalue references">C++: lvalue, rvalue and rvalue references</a> <small>C++ lvalue, rvalue, and rvalue references Understanding lvalues, rvalues, and rvalue references is essential for...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-max-profit-of-rod-cutting-unbounded-knapsack-via-bottom-up-dynamic-programming-algorithm/" rel="bookmark" title="Teaching Kids Programming &#8211; Max Profit of Rod Cutting (Unbounded Knapsack) via Bottom Up Dynamic Programming Algorithm">Teaching Kids Programming &#8211; Max Profit of Rod Cutting (Unbounded Knapsack) via Bottom Up Dynamic Programming Algorithm</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given a list of...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://helloacm.com/teaching-kids-programming-vlog-harness-engineering-commanding-ai-to-get-work-done/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>AI Coding Agents Are Reshaping the Barrier to Programming</title>
		<link>https://helloacm.com/ai-coding-agents-are-reshaping-the-barrier-to-programming/</link>
					<comments>https://helloacm.com/ai-coding-agents-are-reshaping-the-barrier-to-programming/#respond</comments>
		
		<dc:creator><![CDATA[ACMer]]></dc:creator>
		<pubDate>Sat, 23 May 2026 18:30:13 +0000</pubDate>
				<category><![CDATA[AGI: Artificial General Intelligence]]></category>
		<category><![CDATA[Artificial Intelligence]]></category>
		<category><![CDATA[Prompt]]></category>
		<category><![CDATA[Prompt Engineering]]></category>
		<category><![CDATA[software development]]></category>
		<category><![CDATA[Vibe Coding]]></category>
		<category><![CDATA[AI coding]]></category>
		<category><![CDATA[AI Coding Agent]]></category>
		<category><![CDATA[AI Tools]]></category>
		<category><![CDATA[Claude Code]]></category>
		<category><![CDATA[Developer Productivity]]></category>
		<category><![CDATA[Future of Coding]]></category>
		<category><![CDATA[GitHub Actions]]></category>
		<category><![CDATA[GitHub Codespaces]]></category>
		<category><![CDATA[GitHub Copilot]]></category>
		<category><![CDATA[Learning to Code]]></category>
		<category><![CDATA[Programmers]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[Technology Trends]]></category>
		<category><![CDATA[Tetris]]></category>
		<category><![CDATA[VS Code Agent]]></category>
		<category><![CDATA[Youtube Video]]></category>
		<guid isPermaLink="false">https://helloacm.com/?p=157860</guid>

					<description><![CDATA[<blockquote>
AI Coding Agents Are Reshaping the Barrier to Programming
Coding Is Becoming as Easy as Using a Calculator
From Writing Code to Directing AI: The New Role of Programmers
My 12-Year-Old Used Copilot to Modify <a href="https://helloacm.com/three-interesting-fun-bash-commands/" title="Three Interesting/Fun BASH Commands">Tetris</a> — Programming Has Changed
AI Is No Longer Just Autocompleting Code — It Is Reshaping Software Development
The Future Programmer May Not Start by Writing Code
When Copilot Can Take an Issue, What Is Left for Programmers?
AI Makes Coding Easier — But Makes Being a Programmer Harder

AI Coding Agents are reshaping the way software is built. With VS Code Agent, GitHub Copilot, Codespaces, and GitHub Actions, development is shifting from manually writing every line of code to defining problems, guiding AI, and reviewing results. When a 12-year-old can open a project in the browser, use Copilot to modify Tetris, and trigger a deployment workflow, it is clear that the barrier to programming has been dramatically lowered. The future of programming is not just about writing code, but about asking better questions, judging AI-generated solutions, and safely turning ideas into working systems.
</blockquote>

<h3>AI Coding Agents Are Reshaping the Barrier to Programming</h3>

Since the major updates around last November, AI Coding Agents have brought a qualitative change to the <a href="https://helloacm.com/best-advice-for-it-or-software-development-career/" title="Best Advice for IT or Software Development Career">software development</a> industry.

In the past, code written by AI might only be half usable. In many cases, developers still had to fix it repeatedly, debug it manually, or even reject the solution entirely because the AI’s approach was wrong. But things are different now. The usability of AI-generated code has improved dramatically, and in many scenarios it is now close to being bug-free.

I only started properly using VS Code Agent mode and GitHub Copilot in February this year. Before that, my workflow was quite primitive: I would throw a problem into ChatGPT or <a href="https://helloacm.com/microsofts-excel-just-got-smarter-the-new-copilot-function/" title="Microsoft’s Excel Just Got Smarter: The New Copilot Function">Copilot</a>, let the AI generate some code, then copy that code into VS Code and run it. If there was an error, I would paste the error message back into ChatGPT and ask it to fix the issue.

In other words, I was more like an assistant to the AI — a “human courier” responsible for copying, pasting, running code, and feeding error messages back. It did improve efficiency, but the whole process was still fairly clumsy.

After I started using VS <a href="https://helloacm.com/from-idea-to-github-pages-building-tools-with-ai-and-vibe-coding/" title="From Idea to GitHub Pages: Building Tools with AI and Vibe Coding">Code Agent</a>, the experience became completely different.

I no longer need to leave the VS Code window. The code, terminal, error messages, and project context are all in the same environment. I can simply prompt the AI directly, tell it what I want to do or where the problem is, and it can read the code, locate the issue, modify the code, and even help run tests.

This is very close to how I work day to day now: constantly talking to AI, constantly <a href="https://helloacm.com/the-young-prompt-engineers/" title="The Young Prompt Engineers">prompting</a> AI, and letting it help me analyze problems, locate issues, and modify code.

It is not just about writing code either. Whether it is sending a Teams message, writing an <a href="https://helloacm.com/a-blatantly-fake-phishing-email-from-opensea-nft/" title="A blatantly fake phishing email from OpenSea (NFT)">email</a>, or polishing some text, AI can help with that too.

In VS Code Agent mode, or Copilot CLI mode, AI can even read the content and comments of a pull request directly. You can ask it to understand a PR, modify the code based on reviewer comments, or even reply to comments on the PR.

In a sense, <a href="https://helloacm.com/best-monitors-for-programmers/" title="Best Monitors for Programmers">programmers</a> today no longer have to write every line of code themselves.

You can create an issue — Azure DevOps supports similar workflows too — and assign it to Copilot. Copilot can start writing code based on the issue, make changes, and create a PR (Pull Request). You can also @ Copilot anywhere in a PR and ask it to continue making changes.

The role of programmers is shifting from “writing code” to “defining problems, reviewing solutions, understanding code, and validating results.”

Writing code itself is no longer the core barrier. But the ability to read code, judge code <a href="https://helloacm.com/hunting-down-the-mythical-high-quality-code/" title="Hunting Down The Mythical High-Quality Code">quality</a>, test properly, and understand system design is becoming even more important.

The unlimited access to Claude Code Opus 4.7 is extremely useful. It can interact with you directly inside VS Code, help debug problems, run code, and even run tests. To be honest, without AI, I now feel like I almost do not know how to code anymore. AI has seriously made me dumber. [laughs]

[caption id="attachment_157861" align="alignnone" width="2048"]<a href="https://helloacm.com/ai-coding-agents-are-reshaping-the-barrier-to-programming/vscode-ai-coding-agent-2026-05-21-09-44-44/" rel="attachment wp-att-157861"><img src="https://helloacm.com/wp-content/uploads/2026/05/vscode-ai-coding-agent-2026-05-21-09.44.44-scaled.jpg" alt="Rely more and more on AI: Claude Opus 4.7" width="2048" height="1152" class="size-full wp-image-157861" /></a> Rely more and more on AI: Claude Opus 4.7[/caption]

<h3>When kids use AI to write games: <a href="https://helloacm.com/teaching-kids-programming-verify-preorder-sequence-in-binary-search-tree-monotonous-stack/" title="Teaching Kids Programming – Verify Preorder Sequence in Binary Search Tree (Monotonous Stack)">programming</a> is transforming from a skill into a tool</h3>

<blockquote>
A 12-year-old modified and released Tetris in one go using GitHub Copilot.
When 12-year-olds start using AI agents to write games, the barrier to entry for programming has truly changed.
My kid modified Tetris using GitHub Copilot: from code to release, all in one go.
A 12-year-old self-taught Git + Codespaces + Copilot and completed a Tetris release.
Writing code in the future may be as simple as using a calculator today.
A 12-year-old has already started modifying games using the Copilot Agent.
My kid modified Tetris in GitHub Codespaces and released it effortlessly.
Kids these days write code: open a browser, summon Copilot, and release.
After seeing my kid use Copilot to write Tetris, I feel the programming era has truly changed.
Git, Codespaces, Agent, automated release—a 12-year-old mastered the entire process.
In the AI ​​era, the barrier to entry for writing code is becoming "being able to make requests."
Future programming education may no longer start with syntax.
When kids use AI to write games: programming is transforming from a skill into a tool.
Can you write code or not? It's not important anymore? The ability to command AI is what truly matters.
From Tetris to automated publishing: Children are experiencing the next generation of programming.
</blockquote>

Recently, my child also experienced this new way of development.

He opened a project in GitHub Codespaces, used Copilot Agent to vibe coded a Tetris project (see <a href="https://ryanhlai.github.io/games/tetris.html" title="Tetris Game">Here</a>), and then triggered the deployment workflow. The whole process, from changing the code to publishing it, was almost seamless.

If this had happened ten years ago, the barrier would have been very high.

First, you would need to know how to configure a development environment. You would need to install Git, clone the repository, understand how to run the project, and know a bit about frontend development, build systems, and deployment. When errors occurred, you would have to Google them, read Stack Overflow, and keep trying different fixes.

Just configuring the development environment alone was enough to discourage many beginners.

But now things are completely different.

Open GitHub Codespaces in a browser, and the development environment is already there.
If you do not know how to write the code, Copilot can generate it for you.
If you do not understand the code, Copilot can explain it.
If you do not know where to make the change, the Agent can help locate it.
After the change is made, GitHub Actions or other automation workflows can trigger the deployment.

This is no longer just “AI helping you autocomplete code.” The entire software development workflow is being reshaped.

In the past, the barriers to programming were environment setup, syntax, toolchains, debugging, and deployment.
In the future, programming may become more like using a calculator: the tool itself will become increasingly powerful, and what truly matters is whether you know what problem you are trying to solve and whether you can judge if the result is correct.

For programmers, this is both an opportunity and a challenge.

Programmers who do not know how to use AI will quickly fall behind in productivity.
Programmers who only rely on AI but cannot understand code will also be in a dangerous position.

The truly valuable skills in the future will no longer be just "I can write code", but:

<ul>
<li>Can I define the problem clearly?</li>
<li>Can I break down the task?</li>
<li>Can I judge whether the AI’s solution is reliable?</li>
<li>Can I safely integrate the code into a real system?</li>
</ul>

AI has not made programming disappear. But it is lowering the entry barrier to programming like never before.

<iframe width="2921" height="986" src="https://www.youtube.com/embed/K54Wp0z7jvs" title="My 12 Year Old Vibe Coded a Tetris using Github Workspace Copilot 当12岁孩子开始用 AI Agent 写游戏，编程门槛真的变了" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

Perhaps this is how the next generation of children will learn programming: not by starting with environment setup, but by starting with asking questions.

[show_file file="/var/www/wp-post-common/helloacm.com/prompt.php"]

Post: I now <a href="https://steemit.com/blog/@justyy/rely-more-and-more-on-ai-claude-opus-4-7" title="Rely more and more on AI: Claude Opus 4.7">Rely more and more on AI: Claude Opus 4.7</a>

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/toss-a-coin-256-times-the-math-behind-an-unbreakable-bitcoin-private-key/" rel="bookmark" title="Toss a Coin 256 Times: The Math Behind an Unbreakable Bitcoin Private Key">Toss a Coin 256 Times: The Math Behind an Unbreakable Bitcoin Private Key</a> <small>Why Cracking a Bitcoin Key Is Harder Than You Can Possibly Imagine I often see...</small></li>
<li><a href="https://helloacm.com/interview-question-the-number-of-bits-required-to-convert-one-integer-to-another-cc-function/" rel="bookmark" title="Interview Question: The Number of Bits Required to Convert One Integer to Another (C/C++ function)">Interview Question: The Number of Bits Required to Convert One Integer to Another (C/C++ function)</a> <small>The question is: how many bits are required to change if we want to convert...</small></li>
<li><a href="https://helloacm.com/how-to-set-up-and-test-a-websocket-server-in-python-with-existing-cli-tools/" rel="bookmark" title="How to Set Up and Test a WebSocket Server in Python with Existing CLI Tools?">How to Set Up and Test a WebSocket Server in Python with Existing CLI Tools?</a> <small>Introduction to WebSockets WebSockets enable real-time, full-duplex communication between clients and servers over a single...</small></li>
<li><a href="https://helloacm.com/understanding-the-lea-instruction-a-powerful-tool-for-address-calculation-in-x86-assembly/" rel="bookmark" title="Understanding the LEA Instruction: A Powerful Tool for Address Calculation in x86 Assembly">Understanding the LEA Instruction: A Powerful Tool for Address Calculation in x86 Assembly</a> <small>What Is the LEA Instruction? In x86 assembly, the LEA (Load Effective Address) instruction is...</small></li>
<li><a href="https://helloacm.com/algorithms-to-check-if-any-two-intervals-overlap/" rel="bookmark" title="Algorithms to Check If Any Two Intervals Overlap">Algorithms to Check If Any Two Intervals Overlap</a> <small>Given a list of intervals denoted with (start, end), implement a function that returns true...</small></li>
<li><a href="https://helloacm.com/tetration-operator-in-math-simply-explained-with-python-algorithms/" rel="bookmark" title="Tetration Operator in Math Simply Explained with Python Algorithms">Tetration Operator in Math Simply Explained with Python Algorithms</a> <small>What is Tetration Operator in Math? Tetration is an operation in mathematics that involves iterated...</small></li>
<li><a href="https://helloacm.com/c-forward-references-the-key-to-perfect-forwarding/" rel="bookmark" title="C++ Forward References: The Key to Perfect Forwarding">C++ Forward References: The Key to Perfect Forwarding</a> <small>In modern C++ (C++11 and beyond), a powerful feature called forward references enables developers to...</small></li>
<li><a href="https://helloacm.com/c-lvalue-rvalue-and-rvalue-references/" rel="bookmark" title="C++: lvalue, rvalue and rvalue references">C++: lvalue, rvalue and rvalue references</a> <small>C++ lvalue, rvalue, and rvalue references Understanding lvalues, rvalues, and rvalue references is essential for...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<blockquote>
AI Coding Agents Are Reshaping the Barrier to Programming
Coding Is Becoming as Easy as Using a Calculator
From Writing Code to Directing AI: The New Role of Programmers
My 12-Year-Old Used Copilot to Modify <a href="https://helloacm.com/three-interesting-fun-bash-commands/" title="Three Interesting/Fun BASH Commands">Tetris</a> — Programming Has Changed
AI Is No Longer Just Autocompleting Code — It Is Reshaping Software Development
The Future Programmer May Not Start by Writing Code
When Copilot Can Take an Issue, What Is Left for Programmers?
AI Makes Coding Easier — But Makes Being a Programmer Harder

AI Coding Agents are reshaping the way software is built. With VS Code Agent, GitHub Copilot, Codespaces, and GitHub Actions, development is shifting from manually writing every line of code to defining problems, guiding AI, and reviewing results. When a 12-year-old can open a project in the browser, use Copilot to modify Tetris, and trigger a deployment workflow, it is clear that the barrier to programming has been dramatically lowered. The future of programming is not just about writing code, but about asking better questions, judging AI-generated solutions, and safely turning ideas into working systems.
</blockquote>

<h3>AI Coding Agents Are Reshaping the Barrier to Programming</h3>

Since the major updates around last November, AI Coding Agents have brought a qualitative change to the <a href="https://helloacm.com/best-advice-for-it-or-software-development-career/" title="Best Advice for IT or Software Development Career">software development</a> industry.

In the past, code written by AI might only be half usable. In many cases, developers still had to fix it repeatedly, debug it manually, or even reject the solution entirely because the AI’s approach was wrong. But things are different now. The usability of AI-generated code has improved dramatically, and in many scenarios it is now close to being bug-free.

I only started properly using VS Code Agent mode and GitHub Copilot in February this year. Before that, my workflow was quite primitive: I would throw a problem into ChatGPT or <a href="https://helloacm.com/microsofts-excel-just-got-smarter-the-new-copilot-function/" title="Microsoft’s Excel Just Got Smarter: The New Copilot Function">Copilot</a>, let the AI generate some code, then copy that code into VS Code and run it. If there was an error, I would paste the error message back into ChatGPT and ask it to fix the issue.

In other words, I was more like an assistant to the AI — a “human courier” responsible for copying, pasting, running code, and feeding error messages back. It did improve efficiency, but the whole process was still fairly clumsy.

After I started using VS <a href="https://helloacm.com/from-idea-to-github-pages-building-tools-with-ai-and-vibe-coding/" title="From Idea to GitHub Pages: Building Tools with AI and Vibe Coding">Code Agent</a>, the experience became completely different.

I no longer need to leave the VS Code window. The code, terminal, error messages, and project context are all in the same environment. I can simply prompt the AI directly, tell it what I want to do or where the problem is, and it can read the code, locate the issue, modify the code, and even help run tests.

This is very close to how I work day to day now: constantly talking to AI, constantly <a href="https://helloacm.com/the-young-prompt-engineers/" title="The Young Prompt Engineers">prompting</a> AI, and letting it help me analyze problems, locate issues, and modify code.

It is not just about writing code either. Whether it is sending a Teams message, writing an <a href="https://helloacm.com/a-blatantly-fake-phishing-email-from-opensea-nft/" title="A blatantly fake phishing email from OpenSea (NFT)">email</a>, or polishing some text, AI can help with that too.

In VS Code Agent mode, or Copilot CLI mode, AI can even read the content and comments of a pull request directly. You can ask it to understand a PR, modify the code based on reviewer comments, or even reply to comments on the PR.

In a sense, <a href="https://helloacm.com/best-monitors-for-programmers/" title="Best Monitors for Programmers">programmers</a> today no longer have to write every line of code themselves.

You can create an issue — Azure DevOps supports similar workflows too — and assign it to Copilot. Copilot can start writing code based on the issue, make changes, and create a PR (Pull Request). You can also @ Copilot anywhere in a PR and ask it to continue making changes.

The role of programmers is shifting from “writing code” to “defining problems, reviewing solutions, understanding code, and validating results.”

Writing code itself is no longer the core barrier. But the ability to read code, judge code <a href="https://helloacm.com/hunting-down-the-mythical-high-quality-code/" title="Hunting Down The Mythical High-Quality Code">quality</a>, test properly, and understand system design is becoming even more important.

The unlimited access to Claude Code Opus 4.7 is extremely useful. It can interact with you directly inside VS Code, help debug problems, run code, and even run tests. To be honest, without AI, I now feel like I almost do not know how to code anymore. AI has seriously made me dumber. [laughs]

[caption id="attachment_157861" align="alignnone" width="2048"]<a href="https://helloacm.com/ai-coding-agents-are-reshaping-the-barrier-to-programming/vscode-ai-coding-agent-2026-05-21-09-44-44/" rel="attachment wp-att-157861"><img src="https://helloacm.com/wp-content/uploads/2026/05/vscode-ai-coding-agent-2026-05-21-09.44.44-scaled.jpg" alt="Rely more and more on AI: Claude Opus 4.7" width="2048" height="1152" class="size-full wp-image-157861" /></a> Rely more and more on AI: Claude Opus 4.7[/caption]

<h3>When kids use AI to write games: <a href="https://helloacm.com/teaching-kids-programming-verify-preorder-sequence-in-binary-search-tree-monotonous-stack/" title="Teaching Kids Programming – Verify Preorder Sequence in Binary Search Tree (Monotonous Stack)">programming</a> is transforming from a skill into a tool</h3>

<blockquote>
A 12-year-old modified and released Tetris in one go using GitHub Copilot.
When 12-year-olds start using AI agents to write games, the barrier to entry for programming has truly changed.
My kid modified Tetris using GitHub Copilot: from code to release, all in one go.
A 12-year-old self-taught Git + Codespaces + Copilot and completed a Tetris release.
Writing code in the future may be as simple as using a calculator today.
A 12-year-old has already started modifying games using the Copilot Agent.
My kid modified Tetris in GitHub Codespaces and released it effortlessly.
Kids these days write code: open a browser, summon Copilot, and release.
After seeing my kid use Copilot to write Tetris, I feel the programming era has truly changed.
Git, Codespaces, Agent, automated release—a 12-year-old mastered the entire process.
In the AI ​​era, the barrier to entry for writing code is becoming "being able to make requests."
Future programming education may no longer start with syntax.
When kids use AI to write games: programming is transforming from a skill into a tool.
Can you write code or not? It's not important anymore? The ability to command AI is what truly matters.
From Tetris to automated publishing: Children are experiencing the next generation of programming.
</blockquote>

Recently, my child also experienced this new way of development.

He opened a project in GitHub Codespaces, used Copilot Agent to vibe coded a Tetris project (see <a href="https://ryanhlai.github.io/games/tetris.html" title="Tetris Game">Here</a>), and then triggered the deployment workflow. The whole process, from changing the code to publishing it, was almost seamless.

If this had happened ten years ago, the barrier would have been very high.

First, you would need to know how to configure a development environment. You would need to install Git, clone the repository, understand how to run the project, and know a bit about frontend development, build systems, and deployment. When errors occurred, you would have to Google them, read Stack Overflow, and keep trying different fixes.

Just configuring the development environment alone was enough to discourage many beginners.

But now things are completely different.

Open GitHub Codespaces in a browser, and the development environment is already there.
If you do not know how to write the code, Copilot can generate it for you.
If you do not understand the code, Copilot can explain it.
If you do not know where to make the change, the Agent can help locate it.
After the change is made, GitHub Actions or other automation workflows can trigger the deployment.

This is no longer just “AI helping you autocomplete code.” The entire software development workflow is being reshaped.

In the past, the barriers to programming were environment setup, syntax, toolchains, debugging, and deployment.
In the future, programming may become more like using a calculator: the tool itself will become increasingly powerful, and what truly matters is whether you know what problem you are trying to solve and whether you can judge if the result is correct.

For programmers, this is both an opportunity and a challenge.

Programmers who do not know how to use AI will quickly fall behind in productivity.
Programmers who only rely on AI but cannot understand code will also be in a dangerous position.

The truly valuable skills in the future will no longer be just "I can write code", but:

<ul>
<li>Can I define the problem clearly?</li>
<li>Can I break down the task?</li>
<li>Can I judge whether the AI’s solution is reliable?</li>
<li>Can I safely integrate the code into a real system?</li>
</ul>

AI has not made programming disappear. But it is lowering the entry barrier to programming like never before.

<iframe width="2921" height="986" src="https://www.youtube.com/embed/K54Wp0z7jvs" title="My 12 Year Old Vibe Coded a Tetris using Github Workspace Copilot 当12岁孩子开始用 AI Agent 写游戏，编程门槛真的变了" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

Perhaps this is how the next generation of children will learn programming: not by starting with environment setup, but by starting with asking questions.

[show_file file="/var/www/wp-post-common/helloacm.com/prompt.php"]

Post: I now <a href="https://steemit.com/blog/@justyy/rely-more-and-more-on-ai-claude-opus-4-7" title="Rely more and more on AI: Claude Opus 4.7">Rely more and more on AI: Claude Opus 4.7</a>

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/toss-a-coin-256-times-the-math-behind-an-unbreakable-bitcoin-private-key/" rel="bookmark" title="Toss a Coin 256 Times: The Math Behind an Unbreakable Bitcoin Private Key">Toss a Coin 256 Times: The Math Behind an Unbreakable Bitcoin Private Key</a> <small>Why Cracking a Bitcoin Key Is Harder Than You Can Possibly Imagine I often see...</small></li>
<li><a href="https://helloacm.com/interview-question-the-number-of-bits-required-to-convert-one-integer-to-another-cc-function/" rel="bookmark" title="Interview Question: The Number of Bits Required to Convert One Integer to Another (C/C++ function)">Interview Question: The Number of Bits Required to Convert One Integer to Another (C/C++ function)</a> <small>The question is: how many bits are required to change if we want to convert...</small></li>
<li><a href="https://helloacm.com/how-to-set-up-and-test-a-websocket-server-in-python-with-existing-cli-tools/" rel="bookmark" title="How to Set Up and Test a WebSocket Server in Python with Existing CLI Tools?">How to Set Up and Test a WebSocket Server in Python with Existing CLI Tools?</a> <small>Introduction to WebSockets WebSockets enable real-time, full-duplex communication between clients and servers over a single...</small></li>
<li><a href="https://helloacm.com/understanding-the-lea-instruction-a-powerful-tool-for-address-calculation-in-x86-assembly/" rel="bookmark" title="Understanding the LEA Instruction: A Powerful Tool for Address Calculation in x86 Assembly">Understanding the LEA Instruction: A Powerful Tool for Address Calculation in x86 Assembly</a> <small>What Is the LEA Instruction? In x86 assembly, the LEA (Load Effective Address) instruction is...</small></li>
<li><a href="https://helloacm.com/algorithms-to-check-if-any-two-intervals-overlap/" rel="bookmark" title="Algorithms to Check If Any Two Intervals Overlap">Algorithms to Check If Any Two Intervals Overlap</a> <small>Given a list of intervals denoted with (start, end), implement a function that returns true...</small></li>
<li><a href="https://helloacm.com/tetration-operator-in-math-simply-explained-with-python-algorithms/" rel="bookmark" title="Tetration Operator in Math Simply Explained with Python Algorithms">Tetration Operator in Math Simply Explained with Python Algorithms</a> <small>What is Tetration Operator in Math? Tetration is an operation in mathematics that involves iterated...</small></li>
<li><a href="https://helloacm.com/c-forward-references-the-key-to-perfect-forwarding/" rel="bookmark" title="C++ Forward References: The Key to Perfect Forwarding">C++ Forward References: The Key to Perfect Forwarding</a> <small>In modern C++ (C++11 and beyond), a powerful feature called forward references enables developers to...</small></li>
<li><a href="https://helloacm.com/c-lvalue-rvalue-and-rvalue-references/" rel="bookmark" title="C++: lvalue, rvalue and rvalue references">C++: lvalue, rvalue and rvalue references</a> <small>C++ lvalue, rvalue, and rvalue references Understanding lvalues, rvalues, and rvalue references is essential for...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://helloacm.com/ai-coding-agents-are-reshaping-the-barrier-to-programming/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Teaching Kids Programming – Verify Preorder Sequence in Binary Search Tree (Monotonous Stack)</title>
		<link>https://helloacm.com/teaching-kids-programming-verify-preorder-sequence-in-binary-search-tree-monotonous-stack/</link>
					<comments>https://helloacm.com/teaching-kids-programming-verify-preorder-sequence-in-binary-search-tree-monotonous-stack/#respond</comments>
		
		<dc:creator><![CDATA[ACMer]]></dc:creator>
		<pubDate>Fri, 15 May 2026 21:00:07 +0000</pubDate>
				<category><![CDATA[algorithms]]></category>
		<category><![CDATA[Binary Tree]]></category>
		<category><![CDATA[data structure]]></category>
		<category><![CDATA[programming languages]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Stack]]></category>
		<category><![CDATA[teaching kids programming]]></category>
		<category><![CDATA[youtube video]]></category>
		<category><![CDATA[algorithm]]></category>
		<category><![CDATA[Binary Search Tree]]></category>
		<category><![CDATA[BST]]></category>
		<category><![CDATA[Coding Interview]]></category>
		<category><![CDATA[data structures]]></category>
		<category><![CDATA[leetcode]]></category>
		<category><![CDATA[Medium Problem]]></category>
		<category><![CDATA[preorder traversal]]></category>
		<category><![CDATA[Preorder Verification]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[stack]]></category>
		<category><![CDATA[Teaching Kids Programming]]></category>
		<category><![CDATA[Verify]]></category>
		<guid isPermaLink="false">https://helloacm.com/?p=157854</guid>

					<description><![CDATA[<blockquote>
A stack-based solution for LeetCode 255, Verify Preorder Sequence in Binary Search Tree. The key idea is to track a lower bound: once preorder traversal enters the right subtree of a node, all later values must be greater than that node.
</blockquote>

<iframe width="1840" height="1035" src="https://www.youtube.com/embed/IfY0idcvxmI" title="" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

<h2>LeetCode 255: Verify Preorder Sequence in Binary Search Tree</h2>

LeetCode 255 asks whether a given array of unique integers can be the <a href="https://helloacm.com/teaching-kids-programming-pseudo-palindromic-paths-in-a-binary-tree-breadth-first-search-algorithm-iterative-preorder-reversed-preorder/" title="Teaching Kids Programming – Pseudo-Palindromic Paths in a Binary Tree (Breadth First Search Algorithm, Iterative Preorder/Reversed Preorder)">preorder</a> traversal of a Binary Search Tree.

Given this input:

<pre lang=py>preorder = [5, 2, 1, 3, 6]</pre>

The answer is:

<pre lang=py>True</pre>

Because it can represent this BST:

<pre lang=py>
      5
     / \
    2   6
   / \
  1   3
</pre>

But for this input:

<pre lang=py>preorder = [5, 2, 6, 1, 3]</pre>

The answer is:

<pre lang=py>False</pre>

Because after visiting <pre lang=py>6</pre>, we have already moved into the right subtree of <pre lang=py>5</pre>. Seeing <pre lang=py>1</pre> afterwards violates the BST rule.

<h2>BST Preorder Rule</h2>

For a Binary Search Tree:

<ul>
  <li>All values in the left subtree are smaller than the root.</li>
  <li>All values in the right subtree are greater than the root.</li>
</ul>

Preorder traversal follows this order:

<pre lang=py>root -&gt; left subtree -&gt; right subtree</pre>

So while scanning the preorder array from left to right, we are effectively simulating the traversal path.

The key observation is:

<strong>Once we move into the right subtree of a <a href="https://helloacm.com/how-to-clean-up-nvm-node-versions-except-one/" title="How to Clean Up NVM Node Versions Except One?">node</a>, every future value must be greater than that node.</strong>

That node becomes a lower bound.

<h2>Stack-Based Solution</h2>

We use a <a href="https://helloacm.com/the-memory-manager-in-c-c-heap-vs-stack/" title="The Memory Manager in C/C++ (Heap vs Stack)">stack</a> to track the current ancestor path.

When the current value is smaller than the top of the stack, we are still going down the left subtree.

When the current value is greater than the top of the stack, we are moving back up and entering a right subtree.

At that point, we keep popping from the stack.

The last popped value becomes the new lower bound.

Any future value smaller than this lower bound is invalid.

<h2>Python Solution</h2>

<pre lang=py>
class Solution:
    def verifyPreorder(self, preorder: List[int]) -&gt; bool:
        stack = []
        lower_bound = None

        for value in preorder:
            if lower_bound is not None and value &lt; lower_bound:
                return False

            while stack and value &gt; stack[-1]:
                lower_bound = stack.pop()

            stack.append(value)

        return True
</pre>

<h2>Small Improvement Over the Original Code</h2>

The original version used this condition:

<pre lang=py>
if prev_root and item &lt; prev_root:
</pre>

It works for this LeetCode problem because all values are positive.

But in a more general BST problem, values could be <pre lang=py>0</pre> or negative.

So this version is safer:

<pre lang=py>
if lower_bound is not None and value &lt; lower_bound:
</pre>

This avoids relying on Python truthiness.

<h2>Walkthrough: Valid Example</h2>

Input:

<pre lang=py>[5, 2, 1, 3, 6]</pre>

Start with:

<pre lang=py>
stack = []
lower_bound = None
</pre>

Read <pre lang=py>5</pre>:

<pre lang=py>
stack = [5]
</pre>

Read <pre lang=py>2</pre>:

<pre lang=py>2 &lt; 5</pre>, so we are going into the left subtree.

<pre lang=py>
stack = [5, 2]
</pre>

Read <pre lang=py>1</pre>:

<pre lang=py>1 &lt; 2</pre>, still going left.

<pre lang=py>
stack = [5, 2, 1]
</pre>

Read <pre lang=py>3</pre>:

<pre lang=py>3 &gt; 1</pre>, so pop <pre lang=py>1</pre>.

<pre lang=py>
lower_bound = 1
stack = [5, 2]
</pre>

<pre lang=py>3 &gt; 2</pre>, so pop <pre lang=py>2</pre>.

<pre lang=py>
lower_bound = 2
stack = [5]
</pre>

Now <pre lang=py>3 &lt; 5</pre>, so stop popping and push <pre lang=py>3</pre>.

<pre lang=py>
stack = [5, 3]
lower_bound = 2
</pre>

This means we are now in the right subtree of <pre lang=py>2</pre>. Every future value must be greater than <pre lang=py>2</pre>.

Read <pre lang=py>6</pre>:

<pre lang=py>6 &gt; 3</pre>, pop <pre lang=py>3</pre>.

<pre lang=py>
lower_bound = 3
stack = [5]
</pre>

<pre lang=py>6 &gt; 5</pre>, pop <pre lang=py>5</pre>.

<pre lang=py>
lower_bound = 5
stack = []
</pre>

Push <pre lang=py>6</pre>.

<pre lang=py>
stack = [6]
</pre>

No violation is found, so return <pre lang=py>True</pre>.

<h2>Walkthrough: Invalid Example</h2>

Input:

<pre lang=py>[5, 2, 6, 1, 3]</pre>

Read <pre lang=py>5</pre>:

<pre lang=py>
stack = [5]
</pre>

Read <pre lang=py>2</pre>:

<pre lang=py>
stack = [5, 2]
</pre>

Read <pre lang=py>6</pre>:

<pre lang=py>6 &gt; 2</pre>, pop <pre lang=py>2</pre>.

<pre lang=py>
lower_bound = 2
stack = [5]
</pre>

<pre lang=py>6 &gt; 5</pre>, pop <pre lang=py>5</pre>.

<pre lang=py>
lower_bound = 5
stack = []
</pre>

Push <pre lang=py>6</pre>.

<pre lang=py>
stack = [6]
</pre>

Now we are in the right subtree of <pre lang=py>5</pre>.

That means every future value must be greater than <pre lang=py>5</pre>.

Read <pre lang=py>1</pre>:

<pre lang=py>
1 &lt; lower_bound
1 &lt; 5
</pre>

This is invalid, so return <pre lang=py>False</pre>.

<h2>Why This Works</h2>

The stack represents the current path of ancestors.

When we see a larger value, we are moving from a left subtree into a right subtree.

Every popped node means:

<blockquote>
We have finished this node’s left subtree and are now entering its right subtree.
</blockquote>

Therefore, the popped node becomes a lower bound.

If a future value is smaller than this lower bound, the sequence is trying to place a node into the wrong subtree.

That breaks the BST rule.

<h2>Time and Space Complexity</h2>

Time complexity:

<pre lang=py>O(n)</pre>

Each value is pushed once and popped at most once.

Space complexity:

<pre lang=py>O(n)</pre>

In the worst case, the stack may contain all nodes.

For example:

<pre lang=py>[5, 4, 3, 2, 1]</pre>

<h2>Follow-up: Constant Space Solution</h2>

The follow-up asks whether we can solve it using only constant extra space.

Yes, we can reuse the input array itself as the stack.

<pre lang=py>
class Solution:
    def verifyPreorder(self, preorder: List[int]) -&gt; bool:
        lower_bound = float("-inf")
        i = -1

        for value in preorder:
            if value &lt; lower_bound:
                return False

            while i &gt;= 0 and value &gt; preorder[i]:
                lower_bound = preorder[i]
                i -= 1

            i += 1
            preorder[i] = value

        return True
</pre>

Here, <pre lang=py>i</pre> is the stack pointer.

Instead of using:

<pre lang=py>
stack.append(value)
</pre>

We write:

<pre lang=py>
i += 1
preorder[i] = value
</pre>

Instead of using:

<pre lang=py>
stack.pop()
</pre>

We write:

<pre lang=py>
lower_bound = preorder[i]
i -= 1
</pre>

This gives:

<ul>
  <li>Time complexity: <pre lang=py>O(n)</pre></li>
  <li>Extra space complexity: <pre lang=py>O(1)</pre></li>
</ul>

However, this approach modifies the input <a href="https://helloacm.com/teaching-kids-programming-delete-nodes-from-linked-list-present-in-array/" title="Teaching Kids Programming – Delete Nodes From Linked List Present in Array">array</a>.

That is the trade-off.

<h2>Final Takeaway</h2>

The core idea is simple:

<blockquote>
In preorder traversal of a BST, once we enter the right subtree of a node, all future values must be greater than that node.
</blockquote>

The stack helps us detect when we enter a right subtree.

The lower bound records the smallest valid value allowed for future nodes.

If any future value is smaller than the lower bound, the preorder sequence cannot represent a valid BST.

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/algorithms-to-detect-pattern-of-length-m-repeated-k-or-more-times-in-a-string/" rel="bookmark" title="Algorithms to Detect Pattern of Length M Repeated K or More Times in a String">Algorithms to Detect Pattern of Length M Repeated K or More Times in a String</a> <small>Given an array of positive integers arr, find a pattern of length m that is...</small></li>
<li><a href="https://helloacm.com/how-to-compute-the-number-of-pawns-captures-for-rook-in-chess/" rel="bookmark" title="How to Compute the Number of Pawns-Captures for Rook in Chess?">How to Compute the Number of Pawns-Captures for Rook in Chess?</a> <small>On an 8 x 8 chessboard, there is one white rook. There also may be...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-closest-binary-search-tree-value-recursion-inorder-binary-search-algorithm/" rel="bookmark" title="Teaching Kids Programming &#8211; Closest Binary Search Tree Value (Recursion + Inorder Traversal + Binary Search Algorithm)">Teaching Kids Programming &#8211; Closest Binary Search Tree Value (Recursion + Inorder Traversal + Binary Search Algorithm)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms Given the root of a binary...</small></li>
<li><a href="https://helloacm.com/fixing-profile-query-commadn-due-to-api-change-in-steem-blockchain/" rel="bookmark" title="Fixing Profile Query Command due to API Change in Steem Blockchain">Fixing Profile Query Command due to API Change in Steem Blockchain</a> <small>Due to an API change in SteemIt see this post, the following code to get...</small></li>
<li><a href="https://helloacm.com/how-to-reverse-a-linked-list-in-cc/" rel="bookmark" title="How to Reverse a Linked List in C/C++?">How to Reverse a Linked List in C/C++?</a> <small>A Singly Linked List is a one-direction List that uses a pointer to connect between...</small></li>
<li><a href="https://helloacm.com/the-24-game-algorithm-using-depth-first-search/" rel="bookmark" title="The 24 Game Algorithm using Depth First Search">The 24 Game Algorithm using Depth First Search</a> <small>You have 4 cards each containing a number from 1 to 9. You need to...</small></li>
<li><a href="https://helloacm.com/compute-the-number-spiral-diagonals/" rel="bookmark" title="Compute the Number Spiral Diagonals">Compute the Number Spiral Diagonals</a> <small>Starting with the number 1 and moving to the right in a clockwise direction a...</small></li>
<li><a href="https://helloacm.com/how-to-optimize-wordpress-website-for-speed/" rel="bookmark" title="How to Optimize WordPress Website for Speed?">How to Optimize WordPress Website for Speed?</a> <small>One of the main problems that website owners face is slow loading times and poor...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<blockquote>
A stack-based solution for LeetCode 255, Verify Preorder Sequence in Binary Search Tree. The key idea is to track a lower bound: once preorder traversal enters the right subtree of a node, all later values must be greater than that node.
</blockquote>

<iframe width="1840" height="1035" src="https://www.youtube.com/embed/IfY0idcvxmI" title="" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

<h2>LeetCode 255: Verify Preorder Sequence in Binary Search Tree</h2>

LeetCode 255 asks whether a given array of unique integers can be the <a href="https://helloacm.com/teaching-kids-programming-pseudo-palindromic-paths-in-a-binary-tree-breadth-first-search-algorithm-iterative-preorder-reversed-preorder/" title="Teaching Kids Programming – Pseudo-Palindromic Paths in a Binary Tree (Breadth First Search Algorithm, Iterative Preorder/Reversed Preorder)">preorder</a> traversal of a Binary Search Tree.

Given this input:

<pre lang=py>preorder = [5, 2, 1, 3, 6]</pre>

The answer is:

<pre lang=py>True</pre>

Because it can represent this BST:

<pre lang=py>
      5
     / \
    2   6
   / \
  1   3
</pre>

But for this input:

<pre lang=py>preorder = [5, 2, 6, 1, 3]</pre>

The answer is:

<pre lang=py>False</pre>

Because after visiting <pre lang=py>6</pre>, we have already moved into the right subtree of <pre lang=py>5</pre>. Seeing <pre lang=py>1</pre> afterwards violates the BST rule.

<h2>BST Preorder Rule</h2>

For a Binary Search Tree:

<ul>
  <li>All values in the left subtree are smaller than the root.</li>
  <li>All values in the right subtree are greater than the root.</li>
</ul>

Preorder traversal follows this order:

<pre lang=py>root -&gt; left subtree -&gt; right subtree</pre>

So while scanning the preorder array from left to right, we are effectively simulating the traversal path.

The key observation is:

<strong>Once we move into the right subtree of a <a href="https://helloacm.com/how-to-clean-up-nvm-node-versions-except-one/" title="How to Clean Up NVM Node Versions Except One?">node</a>, every future value must be greater than that node.</strong>

That node becomes a lower bound.

<h2>Stack-Based Solution</h2>

We use a <a href="https://helloacm.com/the-memory-manager-in-c-c-heap-vs-stack/" title="The Memory Manager in C/C++ (Heap vs Stack)">stack</a> to track the current ancestor path.

When the current value is smaller than the top of the stack, we are still going down the left subtree.

When the current value is greater than the top of the stack, we are moving back up and entering a right subtree.

At that point, we keep popping from the stack.

The last popped value becomes the new lower bound.

Any future value smaller than this lower bound is invalid.

<h2>Python Solution</h2>

<pre lang=py>
class Solution:
    def verifyPreorder(self, preorder: List[int]) -&gt; bool:
        stack = []
        lower_bound = None

        for value in preorder:
            if lower_bound is not None and value &lt; lower_bound:
                return False

            while stack and value &gt; stack[-1]:
                lower_bound = stack.pop()

            stack.append(value)

        return True
</pre>

<h2>Small Improvement Over the Original Code</h2>

The original version used this condition:

<pre lang=py>
if prev_root and item &lt; prev_root:
</pre>

It works for this LeetCode problem because all values are positive.

But in a more general BST problem, values could be <pre lang=py>0</pre> or negative.

So this version is safer:

<pre lang=py>
if lower_bound is not None and value &lt; lower_bound:
</pre>

This avoids relying on Python truthiness.

<h2>Walkthrough: Valid Example</h2>

Input:

<pre lang=py>[5, 2, 1, 3, 6]</pre>

Start with:

<pre lang=py>
stack = []
lower_bound = None
</pre>

Read <pre lang=py>5</pre>:

<pre lang=py>
stack = [5]
</pre>

Read <pre lang=py>2</pre>:

<pre lang=py>2 &lt; 5</pre>, so we are going into the left subtree.

<pre lang=py>
stack = [5, 2]
</pre>

Read <pre lang=py>1</pre>:

<pre lang=py>1 &lt; 2</pre>, still going left.

<pre lang=py>
stack = [5, 2, 1]
</pre>

Read <pre lang=py>3</pre>:

<pre lang=py>3 &gt; 1</pre>, so pop <pre lang=py>1</pre>.

<pre lang=py>
lower_bound = 1
stack = [5, 2]
</pre>

<pre lang=py>3 &gt; 2</pre>, so pop <pre lang=py>2</pre>.

<pre lang=py>
lower_bound = 2
stack = [5]
</pre>

Now <pre lang=py>3 &lt; 5</pre>, so stop popping and push <pre lang=py>3</pre>.

<pre lang=py>
stack = [5, 3]
lower_bound = 2
</pre>

This means we are now in the right subtree of <pre lang=py>2</pre>. Every future value must be greater than <pre lang=py>2</pre>.

Read <pre lang=py>6</pre>:

<pre lang=py>6 &gt; 3</pre>, pop <pre lang=py>3</pre>.

<pre lang=py>
lower_bound = 3
stack = [5]
</pre>

<pre lang=py>6 &gt; 5</pre>, pop <pre lang=py>5</pre>.

<pre lang=py>
lower_bound = 5
stack = []
</pre>

Push <pre lang=py>6</pre>.

<pre lang=py>
stack = [6]
</pre>

No violation is found, so return <pre lang=py>True</pre>.

<h2>Walkthrough: Invalid Example</h2>

Input:

<pre lang=py>[5, 2, 6, 1, 3]</pre>

Read <pre lang=py>5</pre>:

<pre lang=py>
stack = [5]
</pre>

Read <pre lang=py>2</pre>:

<pre lang=py>
stack = [5, 2]
</pre>

Read <pre lang=py>6</pre>:

<pre lang=py>6 &gt; 2</pre>, pop <pre lang=py>2</pre>.

<pre lang=py>
lower_bound = 2
stack = [5]
</pre>

<pre lang=py>6 &gt; 5</pre>, pop <pre lang=py>5</pre>.

<pre lang=py>
lower_bound = 5
stack = []
</pre>

Push <pre lang=py>6</pre>.

<pre lang=py>
stack = [6]
</pre>

Now we are in the right subtree of <pre lang=py>5</pre>.

That means every future value must be greater than <pre lang=py>5</pre>.

Read <pre lang=py>1</pre>:

<pre lang=py>
1 &lt; lower_bound
1 &lt; 5
</pre>

This is invalid, so return <pre lang=py>False</pre>.

<h2>Why This Works</h2>

The stack represents the current path of ancestors.

When we see a larger value, we are moving from a left subtree into a right subtree.

Every popped node means:

<blockquote>
We have finished this node’s left subtree and are now entering its right subtree.
</blockquote>

Therefore, the popped node becomes a lower bound.

If a future value is smaller than this lower bound, the sequence is trying to place a node into the wrong subtree.

That breaks the BST rule.

<h2>Time and Space Complexity</h2>

Time complexity:

<pre lang=py>O(n)</pre>

Each value is pushed once and popped at most once.

Space complexity:

<pre lang=py>O(n)</pre>

In the worst case, the stack may contain all nodes.

For example:

<pre lang=py>[5, 4, 3, 2, 1]</pre>

<h2>Follow-up: Constant Space Solution</h2>

The follow-up asks whether we can solve it using only constant extra space.

Yes, we can reuse the input array itself as the stack.

<pre lang=py>
class Solution:
    def verifyPreorder(self, preorder: List[int]) -&gt; bool:
        lower_bound = float("-inf")
        i = -1

        for value in preorder:
            if value &lt; lower_bound:
                return False

            while i &gt;= 0 and value &gt; preorder[i]:
                lower_bound = preorder[i]
                i -= 1

            i += 1
            preorder[i] = value

        return True
</pre>

Here, <pre lang=py>i</pre> is the stack pointer.

Instead of using:

<pre lang=py>
stack.append(value)
</pre>

We write:

<pre lang=py>
i += 1
preorder[i] = value
</pre>

Instead of using:

<pre lang=py>
stack.pop()
</pre>

We write:

<pre lang=py>
lower_bound = preorder[i]
i -= 1
</pre>

This gives:

<ul>
  <li>Time complexity: <pre lang=py>O(n)</pre></li>
  <li>Extra space complexity: <pre lang=py>O(1)</pre></li>
</ul>

However, this approach modifies the input <a href="https://helloacm.com/teaching-kids-programming-delete-nodes-from-linked-list-present-in-array/" title="Teaching Kids Programming – Delete Nodes From Linked List Present in Array">array</a>.

That is the trade-off.

<h2>Final Takeaway</h2>

The core idea is simple:

<blockquote>
In preorder traversal of a BST, once we enter the right subtree of a node, all future values must be greater than that node.
</blockquote>

The stack helps us detect when we enter a right subtree.

The lower bound records the smallest valid value allowed for future nodes.

If any future value is smaller than the lower bound, the preorder sequence cannot represent a valid BST.

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/algorithms-to-detect-pattern-of-length-m-repeated-k-or-more-times-in-a-string/" rel="bookmark" title="Algorithms to Detect Pattern of Length M Repeated K or More Times in a String">Algorithms to Detect Pattern of Length M Repeated K or More Times in a String</a> <small>Given an array of positive integers arr, find a pattern of length m that is...</small></li>
<li><a href="https://helloacm.com/how-to-compute-the-number-of-pawns-captures-for-rook-in-chess/" rel="bookmark" title="How to Compute the Number of Pawns-Captures for Rook in Chess?">How to Compute the Number of Pawns-Captures for Rook in Chess?</a> <small>On an 8 x 8 chessboard, there is one white rook. There also may be...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-closest-binary-search-tree-value-recursion-inorder-binary-search-algorithm/" rel="bookmark" title="Teaching Kids Programming &#8211; Closest Binary Search Tree Value (Recursion + Inorder Traversal + Binary Search Algorithm)">Teaching Kids Programming &#8211; Closest Binary Search Tree Value (Recursion + Inorder Traversal + Binary Search Algorithm)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms Given the root of a binary...</small></li>
<li><a href="https://helloacm.com/fixing-profile-query-commadn-due-to-api-change-in-steem-blockchain/" rel="bookmark" title="Fixing Profile Query Command due to API Change in Steem Blockchain">Fixing Profile Query Command due to API Change in Steem Blockchain</a> <small>Due to an API change in SteemIt see this post, the following code to get...</small></li>
<li><a href="https://helloacm.com/how-to-reverse-a-linked-list-in-cc/" rel="bookmark" title="How to Reverse a Linked List in C/C++?">How to Reverse a Linked List in C/C++?</a> <small>A Singly Linked List is a one-direction List that uses a pointer to connect between...</small></li>
<li><a href="https://helloacm.com/the-24-game-algorithm-using-depth-first-search/" rel="bookmark" title="The 24 Game Algorithm using Depth First Search">The 24 Game Algorithm using Depth First Search</a> <small>You have 4 cards each containing a number from 1 to 9. You need to...</small></li>
<li><a href="https://helloacm.com/compute-the-number-spiral-diagonals/" rel="bookmark" title="Compute the Number Spiral Diagonals">Compute the Number Spiral Diagonals</a> <small>Starting with the number 1 and moving to the right in a clockwise direction a...</small></li>
<li><a href="https://helloacm.com/how-to-optimize-wordpress-website-for-speed/" rel="bookmark" title="How to Optimize WordPress Website for Speed?">How to Optimize WordPress Website for Speed?</a> <small>One of the main problems that website owners face is slow loading times and poor...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://helloacm.com/teaching-kids-programming-verify-preorder-sequence-in-binary-search-tree-monotonous-stack/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>From Phone Booths to Large Language Models: The Twilight of Traditional Programming</title>
		<link>https://helloacm.com/from-phone-booths-to-large-language-models-the-twilight-of-traditional-programming/</link>
					<comments>https://helloacm.com/from-phone-booths-to-large-language-models-the-twilight-of-traditional-programming/#respond</comments>
		
		<dc:creator><![CDATA[ACMer]]></dc:creator>
		<pubDate>Sat, 09 May 2026 21:37:16 +0000</pubDate>
				<category><![CDATA[AGI: Artificial General Intelligence]]></category>
		<category><![CDATA[Artificial Intelligence]]></category>
		<category><![CDATA[c / c++]]></category>
		<category><![CDATA[Computer Science]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[British Life]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[Community Library]]></category>
		<category><![CDATA[Digital Transformation]]></category>
		<category><![CDATA[Handwritten Code]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[Large Language Models]]></category>
		<category><![CDATA[Overseas Life]]></category>
		<category><![CDATA[Phone Booths]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[Technology Change]]></category>
		<category><![CDATA[Traditional Programming]]></category>
		<guid isPermaLink="false">https://helloacm.com/?p=157844</guid>

					<description><![CDATA[<blockquote>
From Phone Booths to AI: The Twilight of Handwritten Code
The C++ Books in the Phone Booth
When Phone Booths Become Libraries and Programming Becomes Prompting
Traditional Programming in the Age of AI
Phone Booths, Programming Books, and the End of an Era
From Phone Booths to AI: The Twilight of Handwritten Code

After dinner, I walked past an old British phone booth that had been turned into a tiny community library. Among the donated books were HTML and C++ programming books, which reminded me of how phone booths once connected people at great cost, but have now become relics of another era. With the rise of AI and large language models, handwritten code may one day follow the same path — remembered like phone booths and abacuses, as part of a fading technological age.
</blockquote>
That day after dinner, I went for a walk with my family. We walked about 5 kilometres in total. On our way back to the village, I noticed a converted old phone booth filled with books. Among them, there were even books on HTML and C++ programming.

These roadside red phone booths are one of the iconic features of Britain. Many of them have been around for twenty or thirty years, but most are no longer in use. With the development of mobile phones, the internet, and 5G communication, staying in touch with others has become easier and cheaper than ever.

I still remember the second day after I arrived abroad in 2004. At a phone booth near a crossroads in Luton town centre, I put in one pound and called home to let my family know I was safe. But after only a few seconds, the credit ran out and the call was cut off. Looking back now, it really feels like something from another era.

Today, many of these phone booths have been turned into tiny community libraries. People can donate books, and others can take books home to read. Sharing knowledge while also receiving knowledge from others creates a warm and pleasant community atmosphere.

However, with the rapid development of AI, <a href="https://helloacm.com/introducing-examgpt-your-ai-test-coach/" title="Introducing ExamGPT – Your AI Test Coach">large language models</a> have become incredibly powerful. AI is quickly changing the nature of programming. Perhaps in the near future, programming will become as simple as using a calculator, or as natural as drinking water. Those introductory books on HTML and C++ may no longer be the essential “secret manuals” they once were. After all, more and more code is already being generated by AI.

Maybe in a few years, writing code manually will be called “traditional programming”. Just like the abacus, it was once an essential skill, but eventually became part of history.

Times have truly changed. The same is true for phone booths, and the same is true for <a href="https://helloacm.com/teaching-kids-programming-introduction-to-combinatorial-mathematics-2-catalan-number/" title="Teaching Kids Programming – Introduction to Combinatorial Mathematics 2 (Catalan Number)">programming</a>.

[caption id="attachment_157846" align="alignnone" width="2048"]<a href="https://helloacm.com/from-phone-booths-to-large-language-models-the-twilight-of-traditional-programming/programming-books-in-village-phone-room-2026-04-18-18-45-19/" rel="attachment wp-att-157846"><img src="https://helloacm.com/wp-content/uploads/2026/05/programming-books-in-village-phone-room-2026-04-18-18.45.19-scaled.jpg" alt="Reading a Programming Book" width="2048" height="1152" class="size-full wp-image-157846" /></a> Reading a Programming Book[/caption]

[caption id="attachment_157847" align="alignnone" width="864"]<a href="https://helloacm.com/from-phone-booths-to-large-language-models-the-twilight-of-traditional-programming/programming-books-in-village-phone-room-2026-04-18-18-45-27/" rel="attachment wp-att-157847"><img src="https://helloacm.com/wp-content/uploads/2026/05/programming-books-in-village-phone-room-2026-04-18-18.45.27.jpg" alt="Using HTML4 - legacy programming" width="864" height="1536" class="size-full wp-image-157847" /></a> Using HTML4 - legacy programming[/caption]

[caption id="attachment_157848" align="alignnone" width="864"]<a href="https://helloacm.com/from-phone-booths-to-large-language-models-the-twilight-of-traditional-programming/programming-books-in-village-phone-room-2026-04-18-18-46-14/" rel="attachment wp-att-157848"><img src="https://helloacm.com/wp-content/uploads/2026/05/programming-books-in-village-phone-room-2026-04-18-18.46.14.jpg" alt="XML/HTML/C++ Programming Books in Phone Booth" width="864" height="1536" class="size-full wp-image-157848" /></a> XML/HTML/C++ Programming Books in Phone Booth[/caption]

[caption id="attachment_157849" align="alignnone" width="864"]<a href="https://helloacm.com/from-phone-booths-to-large-language-models-the-twilight-of-traditional-programming/programming-books-in-village-phone-room-2026-04-18-18-46-19/" rel="attachment wp-att-157849"><img src="https://helloacm.com/wp-content/uploads/2026/05/programming-books-in-village-phone-room-2026-04-18-18.46.19.jpg" alt="Phone Booth Library in UK Village" width="864" height="1536" class="size-full wp-image-157849" /></a> Phone Booth Library in UK Village[/caption]

Reposted to C++ Programmers in the Village: <a href="https://steemit.com/blog/@justyy/c-programmers-in-the-village" title="C++ Programmers in the Village" rel="noopener nofollow " target="_blank">SteemIt</a> and <a href="https://blurt.blog/blog/@justyy/2k9dks-c-programmers-in-the-village" title="C++ Programmers in the Village" rel="noopener nofollow " target="_blank">Blurt</a>.

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/chatgpt-image-2-0-casual-selfie-of-me/" rel="bookmark" title="ChatGPT Image 2.0 &#8211; Casual Selfie of Me">ChatGPT Image 2.0 &#8211; Casual Selfie of Me</a> <small>ChatGPT Image 2.0 &#8211; Text2Image ChatGPT Image 2.0 is getting the vibe! It produces really...</small></li>
<li><a href="https://helloacm.com/how-to-solve-the-wifi-wireless-networks-intermittency-issues/" rel="bookmark" title="How to Solve the WIFI (Wireless Networks) Intermittency Issues?">How to Solve the WIFI (Wireless Networks) Intermittency Issues?</a> <small>If you experience WIFI (Wireless Networks) Intermittency issue, then keep reading below. The Intermittency issue...</small></li>
<li><a href="https://helloacm.com/how-to-validate-a-perfect-number-integer/" rel="bookmark" title="How to Validate a Perfect Number (Integer)?">How to Validate a Perfect Number (Integer)?</a> <small>We define the Perfect Number is a positive integer that is equal to the sum...</small></li>
<li><a href="https://helloacm.com/c-forward-references-the-key-to-perfect-forwarding/" rel="bookmark" title="C++ Forward References: The Key to Perfect Forwarding">C++ Forward References: The Key to Perfect Forwarding</a> <small>In modern C++ (C++11 and beyond), a powerful feature called forward references enables developers to...</small></li>
<li><a href="https://helloacm.com/c-lvalue-rvalue-and-rvalue-references/" rel="bookmark" title="C++: lvalue, rvalue and rvalue references">C++: lvalue, rvalue and rvalue references</a> <small>C++ lvalue, rvalue, and rvalue references Understanding lvalues, rvalues, and rvalue references is essential for...</small></li>
<li><a href="https://helloacm.com/how-to-reverse-words-in-a-string-using-modern-programming-language/" rel="bookmark" title="How to Reverse Words in a String using Modern Programming Language?">How to Reverse Words in a String using Modern Programming Language?</a> <small>Given an input string, reverse the string word by word. Example 1: Input: &#8220;the sky...</small></li>
<li><a href="https://helloacm.com/how-to-delete-nodes-from-binary-tree-and-make-a-forest/" rel="bookmark" title="How to Delete Nodes from Binary Tree and Make a Forest?">How to Delete Nodes from Binary Tree and Make a Forest?</a> <small>Given the root of a binary tree, each node in the tree has a distinct...</small></li>
<li><a href="https://helloacm.com/simple-investment-strategy-regular-investment-in-bitcoin-btc-dollar-cost-averaging/" rel="bookmark" title="Simple investment strategy: regular investment in Bitcoin/BTC (Dollar Cost Averaging)">Simple investment strategy: regular investment in Bitcoin/BTC (Dollar Cost Averaging)</a> <small>That day, I came across a post on LinkedIn: A person consistently purchased $30 worth...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<blockquote>
From Phone Booths to AI: The Twilight of Handwritten Code
The C++ Books in the Phone Booth
When Phone Booths Become Libraries and Programming Becomes Prompting
Traditional Programming in the Age of AI
Phone Booths, Programming Books, and the End of an Era
From Phone Booths to AI: The Twilight of Handwritten Code

After dinner, I walked past an old British phone booth that had been turned into a tiny community library. Among the donated books were HTML and C++ programming books, which reminded me of how phone booths once connected people at great cost, but have now become relics of another era. With the rise of AI and large language models, handwritten code may one day follow the same path — remembered like phone booths and abacuses, as part of a fading technological age.
</blockquote>
That day after dinner, I went for a walk with my family. We walked about 5 kilometres in total. On our way back to the village, I noticed a converted old phone booth filled with books. Among them, there were even books on HTML and C++ programming.

These roadside red phone booths are one of the iconic features of Britain. Many of them have been around for twenty or thirty years, but most are no longer in use. With the development of mobile phones, the internet, and 5G communication, staying in touch with others has become easier and cheaper than ever.

I still remember the second day after I arrived abroad in 2004. At a phone booth near a crossroads in Luton town centre, I put in one pound and called home to let my family know I was safe. But after only a few seconds, the credit ran out and the call was cut off. Looking back now, it really feels like something from another era.

Today, many of these phone booths have been turned into tiny community libraries. People can donate books, and others can take books home to read. Sharing knowledge while also receiving knowledge from others creates a warm and pleasant community atmosphere.

However, with the rapid development of AI, <a href="https://helloacm.com/introducing-examgpt-your-ai-test-coach/" title="Introducing ExamGPT – Your AI Test Coach">large language models</a> have become incredibly powerful. AI is quickly changing the nature of programming. Perhaps in the near future, programming will become as simple as using a calculator, or as natural as drinking water. Those introductory books on HTML and C++ may no longer be the essential “secret manuals” they once were. After all, more and more code is already being generated by AI.

Maybe in a few years, writing code manually will be called “traditional programming”. Just like the abacus, it was once an essential skill, but eventually became part of history.

Times have truly changed. The same is true for phone booths, and the same is true for <a href="https://helloacm.com/teaching-kids-programming-introduction-to-combinatorial-mathematics-2-catalan-number/" title="Teaching Kids Programming – Introduction to Combinatorial Mathematics 2 (Catalan Number)">programming</a>.

[caption id="attachment_157846" align="alignnone" width="2048"]<a href="https://helloacm.com/from-phone-booths-to-large-language-models-the-twilight-of-traditional-programming/programming-books-in-village-phone-room-2026-04-18-18-45-19/" rel="attachment wp-att-157846"><img src="https://helloacm.com/wp-content/uploads/2026/05/programming-books-in-village-phone-room-2026-04-18-18.45.19-scaled.jpg" alt="Reading a Programming Book" width="2048" height="1152" class="size-full wp-image-157846" /></a> Reading a Programming Book[/caption]

[caption id="attachment_157847" align="alignnone" width="864"]<a href="https://helloacm.com/from-phone-booths-to-large-language-models-the-twilight-of-traditional-programming/programming-books-in-village-phone-room-2026-04-18-18-45-27/" rel="attachment wp-att-157847"><img src="https://helloacm.com/wp-content/uploads/2026/05/programming-books-in-village-phone-room-2026-04-18-18.45.27.jpg" alt="Using HTML4 - legacy programming" width="864" height="1536" class="size-full wp-image-157847" /></a> Using HTML4 - legacy programming[/caption]

[caption id="attachment_157848" align="alignnone" width="864"]<a href="https://helloacm.com/from-phone-booths-to-large-language-models-the-twilight-of-traditional-programming/programming-books-in-village-phone-room-2026-04-18-18-46-14/" rel="attachment wp-att-157848"><img src="https://helloacm.com/wp-content/uploads/2026/05/programming-books-in-village-phone-room-2026-04-18-18.46.14.jpg" alt="XML/HTML/C++ Programming Books in Phone Booth" width="864" height="1536" class="size-full wp-image-157848" /></a> XML/HTML/C++ Programming Books in Phone Booth[/caption]

[caption id="attachment_157849" align="alignnone" width="864"]<a href="https://helloacm.com/from-phone-booths-to-large-language-models-the-twilight-of-traditional-programming/programming-books-in-village-phone-room-2026-04-18-18-46-19/" rel="attachment wp-att-157849"><img src="https://helloacm.com/wp-content/uploads/2026/05/programming-books-in-village-phone-room-2026-04-18-18.46.19.jpg" alt="Phone Booth Library in UK Village" width="864" height="1536" class="size-full wp-image-157849" /></a> Phone Booth Library in UK Village[/caption]

Reposted to C++ Programmers in the Village: <a href="https://steemit.com/blog/@justyy/c-programmers-in-the-village" title="C++ Programmers in the Village" rel="noopener nofollow " target="_blank">SteemIt</a> and <a href="https://blurt.blog/blog/@justyy/2k9dks-c-programmers-in-the-village" title="C++ Programmers in the Village" rel="noopener nofollow " target="_blank">Blurt</a>.

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/chatgpt-image-2-0-casual-selfie-of-me/" rel="bookmark" title="ChatGPT Image 2.0 &#8211; Casual Selfie of Me">ChatGPT Image 2.0 &#8211; Casual Selfie of Me</a> <small>ChatGPT Image 2.0 &#8211; Text2Image ChatGPT Image 2.0 is getting the vibe! It produces really...</small></li>
<li><a href="https://helloacm.com/how-to-solve-the-wifi-wireless-networks-intermittency-issues/" rel="bookmark" title="How to Solve the WIFI (Wireless Networks) Intermittency Issues?">How to Solve the WIFI (Wireless Networks) Intermittency Issues?</a> <small>If you experience WIFI (Wireless Networks) Intermittency issue, then keep reading below. The Intermittency issue...</small></li>
<li><a href="https://helloacm.com/how-to-validate-a-perfect-number-integer/" rel="bookmark" title="How to Validate a Perfect Number (Integer)?">How to Validate a Perfect Number (Integer)?</a> <small>We define the Perfect Number is a positive integer that is equal to the sum...</small></li>
<li><a href="https://helloacm.com/c-forward-references-the-key-to-perfect-forwarding/" rel="bookmark" title="C++ Forward References: The Key to Perfect Forwarding">C++ Forward References: The Key to Perfect Forwarding</a> <small>In modern C++ (C++11 and beyond), a powerful feature called forward references enables developers to...</small></li>
<li><a href="https://helloacm.com/c-lvalue-rvalue-and-rvalue-references/" rel="bookmark" title="C++: lvalue, rvalue and rvalue references">C++: lvalue, rvalue and rvalue references</a> <small>C++ lvalue, rvalue, and rvalue references Understanding lvalues, rvalues, and rvalue references is essential for...</small></li>
<li><a href="https://helloacm.com/how-to-reverse-words-in-a-string-using-modern-programming-language/" rel="bookmark" title="How to Reverse Words in a String using Modern Programming Language?">How to Reverse Words in a String using Modern Programming Language?</a> <small>Given an input string, reverse the string word by word. Example 1: Input: &#8220;the sky...</small></li>
<li><a href="https://helloacm.com/how-to-delete-nodes-from-binary-tree-and-make-a-forest/" rel="bookmark" title="How to Delete Nodes from Binary Tree and Make a Forest?">How to Delete Nodes from Binary Tree and Make a Forest?</a> <small>Given the root of a binary tree, each node in the tree has a distinct...</small></li>
<li><a href="https://helloacm.com/simple-investment-strategy-regular-investment-in-bitcoin-btc-dollar-cost-averaging/" rel="bookmark" title="Simple investment strategy: regular investment in Bitcoin/BTC (Dollar Cost Averaging)">Simple investment strategy: regular investment in Bitcoin/BTC (Dollar Cost Averaging)</a> <small>That day, I came across a post on LinkedIn: A person consistently purchased $30 worth...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://helloacm.com/from-phone-booths-to-large-language-models-the-twilight-of-traditional-programming/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>ChatGPT Image 2.0 – Casual Selfie of Me</title>
		<link>https://helloacm.com/chatgpt-image-2-0-casual-selfie-of-me/</link>
					<comments>https://helloacm.com/chatgpt-image-2-0-casual-selfie-of-me/#respond</comments>
		
		<dc:creator><![CDATA[ACMer]]></dc:creator>
		<pubDate>Mon, 27 Apr 2026 18:12:56 +0000</pubDate>
				<category><![CDATA[AGI: Artificial General Intelligence]]></category>
		<category><![CDATA[AIGC]]></category>
		<category><![CDATA[Artificial Intelligence]]></category>
		<category><![CDATA[ChatGPT (OpenAI)]]></category>
		<category><![CDATA[Prompt]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[ChatGPT]]></category>
		<category><![CDATA[ChatGPT Image2.0]]></category>
		<category><![CDATA[image]]></category>
		<category><![CDATA[Pretty Girls]]></category>
		<category><![CDATA[Prompt Engineering]]></category>
		<category><![CDATA[Selfie]]></category>
		<category><![CDATA[Text2Image]]></category>
		<guid isPermaLink="false">https://helloacm.com/?p=157825</guid>

					<description><![CDATA[<h3>ChatGPT Image 2.0 - Text2Image</h3>
<a href="https://helloacm.com/chatgpt-writes-a-python-script-to-interact-with-grok-llm-from-x-ai-free-25-credit/" title="ChatGPT writes a Python Script to Interact with Grok LLM from x.ai (Free $25 Credit)">ChatGPT</a> Image 2.0 is getting the vibe! It produces really realistic photos/images. 

Prompt 1: Don’t pretend to know what I actually look like. Based on our past conversations, my experiences, profession, work, and life, translate your understanding of my personality, temperament, way of thinking, and communication style into a visual image. Don’t deliberately add extra elements—generate a casual selfie of me.

Prompt 2: Don’t assume you know my real appearance. Instead, based on our past conversations—my experiences, profession, work, and lifestyle—translate your understanding of my personality, temperament, thinking patterns, and communication style into a visual representation. Avoid intentionally adding extra elements. Generate a casual, spontaneous selfie of me.

Prompt 3: Do not assume or infer my real physical appearance. Instead, based on our past conversations—my experiences, professional background, work, and lifestyle—translate your understanding of my personality, temperament, thinking patterns, and communication style into a visual form. Keep it minimal and natural, without deliberately adding extra elements. Generate a casual, unposed selfie that reflects this interpretation.

[caption id="attachment_157826" align="alignnone" width="945"]<a href="https://helloacm.com/chatgpt-image-2-0-casual-selfie-of-me/2026-04-27-09-47-27/" rel="attachment wp-att-157826"><img src="https://helloacm.com/wp-content/uploads/2026/04/2026-04-27-09.47.27-scaled.png" alt="Text-to-Image ChatGPT Image Selfie Photo Girl" width="945" height="2048" class="size-full wp-image-157826" /></a> Text-to-Image ChatGPT Image Selfie Photo Girl[/caption]

[caption id="attachment_157827" align="alignnone" width="1122"]<a href="https://helloacm.com/chatgpt-image-2-0-casual-selfie-of-me/chatgpt-image-2-selfied-girl/" rel="attachment wp-att-157827"><img src="https://helloacm.com/wp-content/uploads/2026/04/chatgpt-image-2-selfied-girl.png" alt="ChatGPT Image Selfie - Pretty Girl!" width="1122" height="1402" class="size-full wp-image-157827" /></a> ChatGPT Image Selfie - Pretty Girl![/caption]

[caption id="attachment_157828" align="alignnone" width="1086"]<a href="https://helloacm.com/chatgpt-image-2-0-casual-selfie-of-me/chatgpt-selfie-1/" rel="attachment wp-att-157828"><img src="https://helloacm.com/wp-content/uploads/2026/04/chatgpt-selfie-1.png" alt="ChatGPT Image Selfie - Pretty Girl!" width="1086" height="1448" class="size-full wp-image-157828" /></a> ChatGPT Image Selfie - Pretty Girl![/caption]

[caption id="attachment_157829" align="alignnone" width="1086"]<a href="https://helloacm.com/chatgpt-image-2-0-casual-selfie-of-me/chatgpt-selfie-2/" rel="attachment wp-att-157829"><img src="https://helloacm.com/wp-content/uploads/2026/04/chatgpt-selfie-2.png" alt="ChatGPT Image Selfie - Pretty Girl!" width="1086" height="1448" class="size-full wp-image-157829" /></a> ChatGPT Image Selfie - Pretty Girl![/caption]

[caption id="attachment_157830" align="alignnone" width="1638"]<a href="https://helloacm.com/chatgpt-image-2-0-casual-selfie-of-me/female-engineer-by-chatgpt/" rel="attachment wp-att-157830"><img src="https://helloacm.com/wp-content/uploads/2026/04/female-engineer-by-chatgpt.jpg" alt="ChatGPT Image 2 Selfied Female Engineer!" width="1638" height="1248" class="size-full wp-image-157830" /></a> ChatGPT Image 2 Selfied Female Engineer![/caption]

[caption id="attachment_157831" align="alignnone" width="946"]<a href="https://helloacm.com/chatgpt-image-2-0-casual-selfie-of-me/pretty-selfie-by-chatgpt/" rel="attachment wp-att-157831"><img src="https://helloacm.com/wp-content/uploads/2026/04/pretty-selfie-by-chatgpt-scaled.jpg" alt="ChatGPT Image 2.0 provides 2 versions of selfie!" width="946" height="2048" class="size-full wp-image-157831" /></a> ChatGPT Image 2.0 provides 2 versions of selfie![/caption]

[show_file file="/var/www/wp-post-common/helloacm.com/prompt.php"]

Also posted to <a href="https://steemit.com/blog/@justyy/chatgpt-image-2-0-casual-selfie-of-me" title="ChatGPT Image 2.0 - Casual Selfie of Me" rel="noopener nofollow " target="_blank">Steemit</a> and <a href="https://blurt.blog/blog/@justyy/5bbasf-chatgpt-image-2-0-casual-selfie-of-me" title="ChatGPT Image 2.0 - Casual Selfie of Me" rel="noopener nofollow " target="_blank">Blurt</a>.

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/why-does-the-exchange-force-liquidation-when-the-margin-is-low/" rel="bookmark" title="Why does the exchange force liquidation when the margin is low?">Why does the exchange force liquidation when the margin is low?</a> <small>In the cryptocurrency market, as long as you don&#8217;t trade contracts, the risk is not...</small></li>
<li><a href="https://helloacm.com/the-future-of-ai-in-the-gaming-industry/" rel="bookmark" title="The Future of AI in the Gaming Industry">The Future of AI in the Gaming Industry</a> <small>With Artificial Intelligence now developing at such a phenomenal rate and being applied so successfully...</small></li>
<li><a href="https://helloacm.com/what-is-tcp-ip-4-layer-vs-osi-7-layer/" rel="bookmark" title="Software Engineer Interview Question: What is TCP/IP (4 Layer vs OSI 7 Layer)?">Software Engineer Interview Question: What is TCP/IP (4 Layer vs OSI 7 Layer)?</a> <small>Note: recently this has been asked in the first round of the technical interviews by...</small></li>
<li><a href="https://helloacm.com/free-giveaway-google-adwords-400-gbp-ads-credit/" rel="bookmark" title="Free Giveaway: Google Adwords 400 GBP Ads Credit">Free Giveaway: Google Adwords 400 GBP Ads Credit</a> <small>Long time ago, I have tried Google Adwords with some free credit from Google, but...</small></li>
<li><a href="https://helloacm.com/understanding-stdtransform_reduce-in-modern-c/" rel="bookmark" title="Understanding std::transform_reduce in Modern C++">Understanding std::transform_reduce in Modern C++</a> <small>Understanding std::transform_reduce in Modern C++ std::transform_reduce is a powerful C++17 algorithm that combines the functionality...</small></li>
<li><a href="https://helloacm.com/the-system-design-of-steem-blockchain-bots/" rel="bookmark" title="The System Design of Steem Blockchain (ChatGPT DApps) Bots">The System Design of Steem Blockchain (ChatGPT DApps) Bots</a> <small>Yesterday, the ChatGPT has been integrated to Steem Blockchain, but the initial design has problems...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-algorithms-to-solve-a-min-max-binary-tree-game/" rel="bookmark" title="Teaching Kids Programming &#8211; Algorithms to Solve a Min Max Binary Tree Game (Queue, Recursion, In-place)">Teaching Kids Programming &#8211; Algorithms to Solve a Min Max Binary Tree Game (Queue, Recursion, In-place)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given a 0-indexed integer...</small></li>
<li><a href="https://helloacm.com/how-to-use-the-sys-settrace-to-debug-in-python/" rel="bookmark" title="How to Use the sys.settrace to Debug in Python?">How to Use the sys.settrace to Debug in Python?</a> <small>sys.settrace is a built-in function in Python&#8217;s sys module. It allows you to set a...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<h3>ChatGPT Image 2.0 - Text2Image</h3>
<a href="https://helloacm.com/chatgpt-writes-a-python-script-to-interact-with-grok-llm-from-x-ai-free-25-credit/" title="ChatGPT writes a Python Script to Interact with Grok LLM from x.ai (Free $25 Credit)">ChatGPT</a> Image 2.0 is getting the vibe! It produces really realistic photos/images. 

Prompt 1: Don’t pretend to know what I actually look like. Based on our past conversations, my experiences, profession, work, and life, translate your understanding of my personality, temperament, way of thinking, and communication style into a visual image. Don’t deliberately add extra elements—generate a casual selfie of me.

Prompt 2: Don’t assume you know my real appearance. Instead, based on our past conversations—my experiences, profession, work, and lifestyle—translate your understanding of my personality, temperament, thinking patterns, and communication style into a visual representation. Avoid intentionally adding extra elements. Generate a casual, spontaneous selfie of me.

Prompt 3: Do not assume or infer my real physical appearance. Instead, based on our past conversations—my experiences, professional background, work, and lifestyle—translate your understanding of my personality, temperament, thinking patterns, and communication style into a visual form. Keep it minimal and natural, without deliberately adding extra elements. Generate a casual, unposed selfie that reflects this interpretation.

[caption id="attachment_157826" align="alignnone" width="945"]<a href="https://helloacm.com/chatgpt-image-2-0-casual-selfie-of-me/2026-04-27-09-47-27/" rel="attachment wp-att-157826"><img src="https://helloacm.com/wp-content/uploads/2026/04/2026-04-27-09.47.27-scaled.png" alt="Text-to-Image ChatGPT Image Selfie Photo Girl" width="945" height="2048" class="size-full wp-image-157826" /></a> Text-to-Image ChatGPT Image Selfie Photo Girl[/caption]

[caption id="attachment_157827" align="alignnone" width="1122"]<a href="https://helloacm.com/chatgpt-image-2-0-casual-selfie-of-me/chatgpt-image-2-selfied-girl/" rel="attachment wp-att-157827"><img src="https://helloacm.com/wp-content/uploads/2026/04/chatgpt-image-2-selfied-girl.png" alt="ChatGPT Image Selfie - Pretty Girl!" width="1122" height="1402" class="size-full wp-image-157827" /></a> ChatGPT Image Selfie - Pretty Girl![/caption]

[caption id="attachment_157828" align="alignnone" width="1086"]<a href="https://helloacm.com/chatgpt-image-2-0-casual-selfie-of-me/chatgpt-selfie-1/" rel="attachment wp-att-157828"><img src="https://helloacm.com/wp-content/uploads/2026/04/chatgpt-selfie-1.png" alt="ChatGPT Image Selfie - Pretty Girl!" width="1086" height="1448" class="size-full wp-image-157828" /></a> ChatGPT Image Selfie - Pretty Girl![/caption]

[caption id="attachment_157829" align="alignnone" width="1086"]<a href="https://helloacm.com/chatgpt-image-2-0-casual-selfie-of-me/chatgpt-selfie-2/" rel="attachment wp-att-157829"><img src="https://helloacm.com/wp-content/uploads/2026/04/chatgpt-selfie-2.png" alt="ChatGPT Image Selfie - Pretty Girl!" width="1086" height="1448" class="size-full wp-image-157829" /></a> ChatGPT Image Selfie - Pretty Girl![/caption]

[caption id="attachment_157830" align="alignnone" width="1638"]<a href="https://helloacm.com/chatgpt-image-2-0-casual-selfie-of-me/female-engineer-by-chatgpt/" rel="attachment wp-att-157830"><img src="https://helloacm.com/wp-content/uploads/2026/04/female-engineer-by-chatgpt.jpg" alt="ChatGPT Image 2 Selfied Female Engineer!" width="1638" height="1248" class="size-full wp-image-157830" /></a> ChatGPT Image 2 Selfied Female Engineer![/caption]

[caption id="attachment_157831" align="alignnone" width="946"]<a href="https://helloacm.com/chatgpt-image-2-0-casual-selfie-of-me/pretty-selfie-by-chatgpt/" rel="attachment wp-att-157831"><img src="https://helloacm.com/wp-content/uploads/2026/04/pretty-selfie-by-chatgpt-scaled.jpg" alt="ChatGPT Image 2.0 provides 2 versions of selfie!" width="946" height="2048" class="size-full wp-image-157831" /></a> ChatGPT Image 2.0 provides 2 versions of selfie![/caption]

[show_file file="/var/www/wp-post-common/helloacm.com/prompt.php"]

Also posted to <a href="https://steemit.com/blog/@justyy/chatgpt-image-2-0-casual-selfie-of-me" title="ChatGPT Image 2.0 - Casual Selfie of Me" rel="noopener nofollow " target="_blank">Steemit</a> and <a href="https://blurt.blog/blog/@justyy/5bbasf-chatgpt-image-2-0-casual-selfie-of-me" title="ChatGPT Image 2.0 - Casual Selfie of Me" rel="noopener nofollow " target="_blank">Blurt</a>.

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/why-does-the-exchange-force-liquidation-when-the-margin-is-low/" rel="bookmark" title="Why does the exchange force liquidation when the margin is low?">Why does the exchange force liquidation when the margin is low?</a> <small>In the cryptocurrency market, as long as you don&#8217;t trade contracts, the risk is not...</small></li>
<li><a href="https://helloacm.com/the-future-of-ai-in-the-gaming-industry/" rel="bookmark" title="The Future of AI in the Gaming Industry">The Future of AI in the Gaming Industry</a> <small>With Artificial Intelligence now developing at such a phenomenal rate and being applied so successfully...</small></li>
<li><a href="https://helloacm.com/what-is-tcp-ip-4-layer-vs-osi-7-layer/" rel="bookmark" title="Software Engineer Interview Question: What is TCP/IP (4 Layer vs OSI 7 Layer)?">Software Engineer Interview Question: What is TCP/IP (4 Layer vs OSI 7 Layer)?</a> <small>Note: recently this has been asked in the first round of the technical interviews by...</small></li>
<li><a href="https://helloacm.com/free-giveaway-google-adwords-400-gbp-ads-credit/" rel="bookmark" title="Free Giveaway: Google Adwords 400 GBP Ads Credit">Free Giveaway: Google Adwords 400 GBP Ads Credit</a> <small>Long time ago, I have tried Google Adwords with some free credit from Google, but...</small></li>
<li><a href="https://helloacm.com/understanding-stdtransform_reduce-in-modern-c/" rel="bookmark" title="Understanding std::transform_reduce in Modern C++">Understanding std::transform_reduce in Modern C++</a> <small>Understanding std::transform_reduce in Modern C++ std::transform_reduce is a powerful C++17 algorithm that combines the functionality...</small></li>
<li><a href="https://helloacm.com/the-system-design-of-steem-blockchain-bots/" rel="bookmark" title="The System Design of Steem Blockchain (ChatGPT DApps) Bots">The System Design of Steem Blockchain (ChatGPT DApps) Bots</a> <small>Yesterday, the ChatGPT has been integrated to Steem Blockchain, but the initial design has problems...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-algorithms-to-solve-a-min-max-binary-tree-game/" rel="bookmark" title="Teaching Kids Programming &#8211; Algorithms to Solve a Min Max Binary Tree Game (Queue, Recursion, In-place)">Teaching Kids Programming &#8211; Algorithms to Solve a Min Max Binary Tree Game (Queue, Recursion, In-place)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given a 0-indexed integer...</small></li>
<li><a href="https://helloacm.com/how-to-use-the-sys-settrace-to-debug-in-python/" rel="bookmark" title="How to Use the sys.settrace to Debug in Python?">How to Use the sys.settrace to Debug in Python?</a> <small>sys.settrace is a built-in function in Python&#8217;s sys module. It allows you to set a...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://helloacm.com/chatgpt-image-2-0-casual-selfie-of-me/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Introducing ExamGPT – Your AI Test Coach</title>
		<link>https://helloacm.com/introducing-examgpt-your-ai-test-coach/</link>
					<comments>https://helloacm.com/introducing-examgpt-your-ai-test-coach/#respond</comments>
		
		<dc:creator><![CDATA[ACMer]]></dc:creator>
		<pubDate>Mon, 20 Apr 2026 13:32:09 +0000</pubDate>
				<category><![CDATA[Artificial Intelligence]]></category>
		<category><![CDATA[ChatGPT (OpenAI)]]></category>
		<category><![CDATA[Prompt Engineering]]></category>
		<category><![CDATA[tools / utilities]]></category>
		<category><![CDATA[Agent]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[AI Tool]]></category>
		<category><![CDATA[ChatGPT]]></category>
		<category><![CDATA[Exam Assistant]]></category>
		<category><![CDATA[ExamGPT]]></category>
		<category><![CDATA[GPT]]></category>
		<category><![CDATA[Lightweigt AI Agent]]></category>
		<category><![CDATA[LLM]]></category>
		<guid isPermaLink="false">https://helloacm.com/?p=157807</guid>

					<description><![CDATA[At the end of last year, I started preparing for Microsoft certifications. Initially, I created a <a href="https://helloacm.com/prompt-engineering-sharing-a-prompt-for-preparing-your-exams/" title="Prompt Engineering: Sharing a Prompt for Preparing Your Exams">prompt</a> that worked really well, but having to copy and paste it every time was a bit tedious. So I thought—why not turn it into a custom GPT? That’s how ExamGPT was born.

The setup is actually very simple. Go to <a href="https://chatgpt.com/gpts" title="ChatGPT/GPTs" rel="noopener nofollow " target="_blank">ChatGPT/GPTs</a>, click “Create” in the top right corner, and fill in the configuration. The main part is pasting in your prompt, giving it a name, and adding a few example inputs—for instance, something like: “I am taking Microsoft AZ-305.”

The results have been surprisingly good. Of course, a big part of that is due to how fast large language models (LLMs), powered by the Transformer <a href="https://helloacm.com/system-design-fan-out-fan-in-pattern/" title="System Design: Fan-out/Fan-in Pattern">architecture</a>, have been improving.

Since building this, I have been able to use all my fragmented time to practice—whether it’s in the bathroom, before going to sleep, or even while accompanying my wife shopping. Another advantage is that you never run out of questions. Your progress is saved in the <a href="https://helloacm.com/chatgpt-new-image-creation-art-school/" title="ChatGPT: New Image Creation (art school)">ChatGPT</a> conversation, so you can always pick up where you left off.

ExamGPT can generate 30 random questions at a time. As long as it has seen the exam in its training data, it can usually cover it. Each question comes with four options, including both single-choice and multiple-choice formats. Whether you answer correctly or incorrectly, it provides a brief explanation. After every set of 30 questions, it gives you a score to indicate whether you’re likely to pass. For any questions you get wrong, it will repeat them in subsequent rounds—second, third, and so on—until you get them right.

The technology used here is just: <a href="https://helloacm.com/the-young-prompt-engineers/" title="The Young Prompt Engineers">Prompt Engineering</a> + LLM Workflow Design + a Lightweight Agent. And the best part is that: I don't need to maintain it and there is no server cost for me to  pay. Everything is maintained by OpenAI.

<b>Bookmarket <a href="https://chatgpt.com/g/g-698ba89e5a1c8191a12605d515f7faeb-exam-gpt" title="ExamGPT" rel="noopener nofollow " target="_blank">ExamGPT</a></b>

[caption id="attachment_157813" align="alignnone" width="776"]<a href="https://helloacm.com/introducing-examgpt-your-ai-test-coach/my-gpts-examgpt/" rel="attachment wp-att-157813"><img src="https://helloacm.com/wp-content/uploads/2026/04/my-gpts-examgpt.jpg" alt="MyGPTs - Exam GPT" width="776" height="280" class="size-full wp-image-157813" /></a> MyGPTs - Exam GPT[/caption]

[caption id="attachment_157812" align="alignnone" width="690"]<a href="https://helloacm.com/introducing-examgpt-your-ai-test-coach/examgpt-example/" rel="attachment wp-att-157812"><img src="https://helloacm.com/wp-content/uploads/2026/04/examgpt-example.jpg" alt="Example of ExamGPT" width="690" height="1759" class="size-full wp-image-157812" /></a> Example of ExamGPT[/caption]

[caption id="attachment_157811" align="alignnone" width="1167"]<a href="https://helloacm.com/introducing-examgpt-your-ai-test-coach/examgpt-configure/" rel="attachment wp-att-157811"><img src="https://helloacm.com/wp-content/uploads/2026/04/examgpt-configure.jpg" alt="Configure LLM Agent: Prompt Engineering" width="1167" height="932" class="size-full wp-image-157811" /></a> Configure LLM Agent: Prompt Engineering[/caption]

[caption id="attachment_157810" align="alignnone" width="744"]<a href="https://helloacm.com/introducing-examgpt-your-ai-test-coach/examgpt-chatgpt-ui/" rel="attachment wp-att-157810"><img src="https://helloacm.com/wp-content/uploads/2026/04/examgpt-chatgpt-ui.jpg" alt="Exam GPT - Simple UI" width="744" height="574" class="size-full wp-image-157810" /></a> Exam GPT - Simple UI[/caption]

It is a very good method to learn from mistakes. I failed the Microsoft SC-300 exam the first time with 644 score. And i put the score report to ExamGPT to get a set of specific questions to my weakness.
[caption id="attachment_157821" align="alignnone" width="1374"]<a href="https://helloacm.com/introducing-examgpt-your-ai-test-coach/examgpt-questions-from-score-report/" rel="attachment wp-att-157821"><img src="https://helloacm.com/wp-content/uploads/2026/04/examgpt-questions-from-score-report-scaled.jpg" alt="Feed into ExamGPT Your Score Report" width="1374" height="2048" class="size-full wp-image-157821" /></a> Feed into ExamGPT Your Score Report[/caption]

[caption id="attachment_157837" align="alignnone" width="1004"]<a href="https://helloacm.com/introducing-examgpt-your-ai-test-coach/examgpt-hard-scenario-questions/" rel="attachment wp-att-157837"><img src="https://helloacm.com/wp-content/uploads/2026/04/examgpt-hard-scenario-questions.png" alt="You can custom the difficulty of the questions by additional prompts to ExamGPT e.g. &quot;Hard Scenario Questions&quot;" width="1004" height="1251" class="size-full wp-image-157837" /></a> You can custom the difficulty of the questions by additional prompts to ExamGPT e.g. "Hard Scenario Questions"[/caption]

[show_file file="/var/www/wp-post-common/helloacm.com/chatgpt.php"]

Reposted to steemit: <a href="https://steemit.com/blog/@justyy/examgpt-your-exam-gpt" title="ExamGPT - Your Exam GPT">ExamGPT - Your Exam GPT</a> and blurt: <a href="https://blurt.blog/blog/@justyy/6gytrr-examgpt-your-exam-gpt" title="ExamGPT - Your Exam GPT">ExamGPT - Your Exam GPT</a>

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/turn-your-raspberry-pi-into-a-family-network-drive-2tb-wd-hard-drive-setup-for-kids-macs/" rel="bookmark" title="Turn Your Raspberry Pi into a Family Network Drive: 2TB WD Hard Drive Setup for Kids’ Macs">Turn Your Raspberry Pi into a Family Network Drive: 2TB WD Hard Drive Setup for Kids’ Macs</a> <small>“Create a 2TB Network Drive with Raspberry Pi for Your Family” “Raspberry Pi + WD...</small></li>
<li><a href="https://helloacm.com/system-design-fan-out-fan-in-pattern/" rel="bookmark" title="System Design: Fan-out/Fan-in Pattern">System Design: Fan-out/Fan-in Pattern</a> <small>Fan-out/fan-in refers to the pattern of executing multiple units of work in parallel and then...</small></li>
<li><a href="https://helloacm.com/chatgpt-refactors-rewrites-the-code-using-promise-all-sending-requests-in-parallel/" rel="bookmark" title="ChatGPT Refactors/Rewrites the Code using Promise.All &#8211; Sending Requests in Parallel">ChatGPT Refactors/Rewrites the Code using Promise.All &#8211; Sending Requests in Parallel</a> <small>In one of my project, I have the following code (Node/Javascript) that invokes a few...</small></li>
<li><a href="https://helloacm.com/free-giveaway-google-adwords-400-gbp-ads-credit/" rel="bookmark" title="Free Giveaway: Google Adwords 400 GBP Ads Credit">Free Giveaway: Google Adwords 400 GBP Ads Credit</a> <small>Long time ago, I have tried Google Adwords with some free credit from Google, but...</small></li>
<li><a href="https://helloacm.com/some-telephone-interview-questions-for-c-c-software-enginners/" rel="bookmark" title="Some Telephone Interview Questions for C++/C# Software Enginners">Some Telephone Interview Questions for C++/C# Software Enginners</a> <small>What is a Garbage Collector in C# (what does it do). Are the objects automatically...</small></li>
<li><a href="https://helloacm.com/chatgpt-image-2-0-casual-selfie-of-me/" rel="bookmark" title="ChatGPT Image 2.0 &#8211; Casual Selfie of Me">ChatGPT Image 2.0 &#8211; Casual Selfie of Me</a> <small>ChatGPT Image 2.0 &#8211; Text2Image ChatGPT Image 2.0 is getting the vibe! It produces really...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-introduction-to-combinatorial-mathematics-2-catalan-number/" rel="bookmark" title="Teaching Kids Programming &#8211; Introduction to Combinatorial Mathematics 2 (Catalan Number)">Teaching Kids Programming &#8211; Introduction to Combinatorial Mathematics 2 (Catalan Number)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms Introduction to Combinatorial Mathematics (2): Catalan...</small></li>
<li><a href="https://helloacm.com/tron-blockchain-how-to-send-the-usdt-trc-20-transacton-using-python-tronpy/" rel="bookmark" title="TRON Blockchain: How to Send the USDT (TRC-20) Transacton using Python tronpy?">TRON Blockchain: How to Send the USDT (TRC-20) Transacton using Python tronpy?</a> <small>How to Send the USDT (TRC-20) Transacton using Python tronpy? To send a USDT (Tether)...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[At the end of last year, I started preparing for Microsoft certifications. Initially, I created a <a href="https://helloacm.com/prompt-engineering-sharing-a-prompt-for-preparing-your-exams/" title="Prompt Engineering: Sharing a Prompt for Preparing Your Exams">prompt</a> that worked really well, but having to copy and paste it every time was a bit tedious. So I thought—why not turn it into a custom GPT? That’s how ExamGPT was born.

The setup is actually very simple. Go to <a href="https://chatgpt.com/gpts" title="ChatGPT/GPTs" rel="noopener nofollow " target="_blank">ChatGPT/GPTs</a>, click “Create” in the top right corner, and fill in the configuration. The main part is pasting in your prompt, giving it a name, and adding a few example inputs—for instance, something like: “I am taking Microsoft AZ-305.”

The results have been surprisingly good. Of course, a big part of that is due to how fast large language models (LLMs), powered by the Transformer <a href="https://helloacm.com/system-design-fan-out-fan-in-pattern/" title="System Design: Fan-out/Fan-in Pattern">architecture</a>, have been improving.

Since building this, I have been able to use all my fragmented time to practice—whether it’s in the bathroom, before going to sleep, or even while accompanying my wife shopping. Another advantage is that you never run out of questions. Your progress is saved in the <a href="https://helloacm.com/chatgpt-new-image-creation-art-school/" title="ChatGPT: New Image Creation (art school)">ChatGPT</a> conversation, so you can always pick up where you left off.

ExamGPT can generate 30 random questions at a time. As long as it has seen the exam in its training data, it can usually cover it. Each question comes with four options, including both single-choice and multiple-choice formats. Whether you answer correctly or incorrectly, it provides a brief explanation. After every set of 30 questions, it gives you a score to indicate whether you’re likely to pass. For any questions you get wrong, it will repeat them in subsequent rounds—second, third, and so on—until you get them right.

The technology used here is just: <a href="https://helloacm.com/the-young-prompt-engineers/" title="The Young Prompt Engineers">Prompt Engineering</a> + LLM Workflow Design + a Lightweight Agent. And the best part is that: I don't need to maintain it and there is no server cost for me to  pay. Everything is maintained by OpenAI.

<b>Bookmarket <a href="https://chatgpt.com/g/g-698ba89e5a1c8191a12605d515f7faeb-exam-gpt" title="ExamGPT" rel="noopener nofollow " target="_blank">ExamGPT</a></b>

[caption id="attachment_157813" align="alignnone" width="776"]<a href="https://helloacm.com/introducing-examgpt-your-ai-test-coach/my-gpts-examgpt/" rel="attachment wp-att-157813"><img src="https://helloacm.com/wp-content/uploads/2026/04/my-gpts-examgpt.jpg" alt="MyGPTs - Exam GPT" width="776" height="280" class="size-full wp-image-157813" /></a> MyGPTs - Exam GPT[/caption]

[caption id="attachment_157812" align="alignnone" width="690"]<a href="https://helloacm.com/introducing-examgpt-your-ai-test-coach/examgpt-example/" rel="attachment wp-att-157812"><img src="https://helloacm.com/wp-content/uploads/2026/04/examgpt-example.jpg" alt="Example of ExamGPT" width="690" height="1759" class="size-full wp-image-157812" /></a> Example of ExamGPT[/caption]

[caption id="attachment_157811" align="alignnone" width="1167"]<a href="https://helloacm.com/introducing-examgpt-your-ai-test-coach/examgpt-configure/" rel="attachment wp-att-157811"><img src="https://helloacm.com/wp-content/uploads/2026/04/examgpt-configure.jpg" alt="Configure LLM Agent: Prompt Engineering" width="1167" height="932" class="size-full wp-image-157811" /></a> Configure LLM Agent: Prompt Engineering[/caption]

[caption id="attachment_157810" align="alignnone" width="744"]<a href="https://helloacm.com/introducing-examgpt-your-ai-test-coach/examgpt-chatgpt-ui/" rel="attachment wp-att-157810"><img src="https://helloacm.com/wp-content/uploads/2026/04/examgpt-chatgpt-ui.jpg" alt="Exam GPT - Simple UI" width="744" height="574" class="size-full wp-image-157810" /></a> Exam GPT - Simple UI[/caption]

It is a very good method to learn from mistakes. I failed the Microsoft SC-300 exam the first time with 644 score. And i put the score report to ExamGPT to get a set of specific questions to my weakness.
[caption id="attachment_157821" align="alignnone" width="1374"]<a href="https://helloacm.com/introducing-examgpt-your-ai-test-coach/examgpt-questions-from-score-report/" rel="attachment wp-att-157821"><img src="https://helloacm.com/wp-content/uploads/2026/04/examgpt-questions-from-score-report-scaled.jpg" alt="Feed into ExamGPT Your Score Report" width="1374" height="2048" class="size-full wp-image-157821" /></a> Feed into ExamGPT Your Score Report[/caption]

[caption id="attachment_157837" align="alignnone" width="1004"]<a href="https://helloacm.com/introducing-examgpt-your-ai-test-coach/examgpt-hard-scenario-questions/" rel="attachment wp-att-157837"><img src="https://helloacm.com/wp-content/uploads/2026/04/examgpt-hard-scenario-questions.png" alt="You can custom the difficulty of the questions by additional prompts to ExamGPT e.g. &quot;Hard Scenario Questions&quot;" width="1004" height="1251" class="size-full wp-image-157837" /></a> You can custom the difficulty of the questions by additional prompts to ExamGPT e.g. "Hard Scenario Questions"[/caption]

[show_file file="/var/www/wp-post-common/helloacm.com/chatgpt.php"]

Reposted to steemit: <a href="https://steemit.com/blog/@justyy/examgpt-your-exam-gpt" title="ExamGPT - Your Exam GPT">ExamGPT - Your Exam GPT</a> and blurt: <a href="https://blurt.blog/blog/@justyy/6gytrr-examgpt-your-exam-gpt" title="ExamGPT - Your Exam GPT">ExamGPT - Your Exam GPT</a>

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/turn-your-raspberry-pi-into-a-family-network-drive-2tb-wd-hard-drive-setup-for-kids-macs/" rel="bookmark" title="Turn Your Raspberry Pi into a Family Network Drive: 2TB WD Hard Drive Setup for Kids’ Macs">Turn Your Raspberry Pi into a Family Network Drive: 2TB WD Hard Drive Setup for Kids’ Macs</a> <small>“Create a 2TB Network Drive with Raspberry Pi for Your Family” “Raspberry Pi + WD...</small></li>
<li><a href="https://helloacm.com/system-design-fan-out-fan-in-pattern/" rel="bookmark" title="System Design: Fan-out/Fan-in Pattern">System Design: Fan-out/Fan-in Pattern</a> <small>Fan-out/fan-in refers to the pattern of executing multiple units of work in parallel and then...</small></li>
<li><a href="https://helloacm.com/chatgpt-refactors-rewrites-the-code-using-promise-all-sending-requests-in-parallel/" rel="bookmark" title="ChatGPT Refactors/Rewrites the Code using Promise.All &#8211; Sending Requests in Parallel">ChatGPT Refactors/Rewrites the Code using Promise.All &#8211; Sending Requests in Parallel</a> <small>In one of my project, I have the following code (Node/Javascript) that invokes a few...</small></li>
<li><a href="https://helloacm.com/free-giveaway-google-adwords-400-gbp-ads-credit/" rel="bookmark" title="Free Giveaway: Google Adwords 400 GBP Ads Credit">Free Giveaway: Google Adwords 400 GBP Ads Credit</a> <small>Long time ago, I have tried Google Adwords with some free credit from Google, but...</small></li>
<li><a href="https://helloacm.com/some-telephone-interview-questions-for-c-c-software-enginners/" rel="bookmark" title="Some Telephone Interview Questions for C++/C# Software Enginners">Some Telephone Interview Questions for C++/C# Software Enginners</a> <small>What is a Garbage Collector in C# (what does it do). Are the objects automatically...</small></li>
<li><a href="https://helloacm.com/chatgpt-image-2-0-casual-selfie-of-me/" rel="bookmark" title="ChatGPT Image 2.0 &#8211; Casual Selfie of Me">ChatGPT Image 2.0 &#8211; Casual Selfie of Me</a> <small>ChatGPT Image 2.0 &#8211; Text2Image ChatGPT Image 2.0 is getting the vibe! It produces really...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-introduction-to-combinatorial-mathematics-2-catalan-number/" rel="bookmark" title="Teaching Kids Programming &#8211; Introduction to Combinatorial Mathematics 2 (Catalan Number)">Teaching Kids Programming &#8211; Introduction to Combinatorial Mathematics 2 (Catalan Number)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms Introduction to Combinatorial Mathematics (2): Catalan...</small></li>
<li><a href="https://helloacm.com/tron-blockchain-how-to-send-the-usdt-trc-20-transacton-using-python-tronpy/" rel="bookmark" title="TRON Blockchain: How to Send the USDT (TRC-20) Transacton using Python tronpy?">TRON Blockchain: How to Send the USDT (TRC-20) Transacton using Python tronpy?</a> <small>How to Send the USDT (TRC-20) Transacton using Python tronpy? To send a USDT (Tether)...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://helloacm.com/introducing-examgpt-your-ai-test-coach/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Teaching Kids Programming –’ogramming is not my wifeTeaching Kids Programming –’ Introduction to Combinatorial Mathematics 2 (Catalan Number)s thing.</title>
		<link>https://helloacm.com/teaching-kids-programming-introduction-to-combinatorial-mathematics-2-catalan-number/</link>
					<comments>https://helloacm.com/teaching-kids-programming-introduction-to-combinatorial-mathematics-2-catalan-number/#respond</comments>
		
		<dc:creator><![CDATA[ACMer]]></dc:creator>
		<pubDate>Wed, 01 Apr 2026 10:38:57 +0000</pubDate>
				<category><![CDATA[algorithms]]></category>
		<category><![CDATA[Combinatorial Mathematics]]></category>
		<category><![CDATA[Combinatoric Mathematics]]></category>
		<category><![CDATA[Computer Science]]></category>
		<category><![CDATA[math]]></category>
		<category><![CDATA[Permutation]]></category>
		<category><![CDATA[Recursion]]></category>
		<category><![CDATA[uncategorized]]></category>
		<category><![CDATA[Catalan]]></category>
		<category><![CDATA[Catalan numbers]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[combinatorial mathematics]]></category>
		<category><![CDATA[number theory]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[recursion]]></category>
		<category><![CDATA[Teaching Kids Programming]]></category>
		<category><![CDATA[Use Cases]]></category>
		<guid isPermaLink="false">https://helloacm.com/?p=157791</guid>

					<description><![CDATA[<iframe width="2835" height="1101" src="https://www.youtube.com/embed/5E47eeSLoMs" title="" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

<h1>Introduction to Combinatorial Mathematics (2): Catalan Numbers</h1>
Catalan numbers are one of the most important sequences in <a href="https://helloacm.com/teaching-kids-programming-how-many-games-are-played-in-world-cup-combinatorics-and-permutations/" title="Teaching Kids Programming – How Many Games are Played in World Cup (Combinatorics and Permutations)">combinatorics</a>. They appear in many counting problems that look very different on the surface, but actually share the same underlying structure: balance, recursion, and non-crossing constraints.

In this post, we will introduce the Catalan numbers, show several important formulas, and explain some classic use cases, especially the grid-walking problem where a path is not allowed to cross the diagonal.

<h2>What Are Catalan Numbers?</h2>
The Catalan sequence begins as follows:

[math] C_0 = 1,\quad C_1 = 1,\quad C_2 = 2,\quad C_3 = 5,\quad C_4 = 14,\quad C_5 = 42,\quad C_6 = 132 [/math]

The general formula for the nth Catalan number is:

[math] C_n = \frac{1}{n+1}\binom{2n}{n} [/math]

An equivalent form is:

[math] C_n = \binom{2n}{n} - \binom{2n}{n+1} [/math]

These two formulas are completely equivalent and both appear often in combinatorics.

<h2>Why Catalan Numbers Matter</h2>

Catalan numbers count many kinds of recursive or balanced structures. They often appear when:

<ul> <li>objects must be built in a balanced way,</li> <li>paths must stay within a boundary,</li> <li>pairings cannot cross,</li> <li>a structure can be split into independent left and right parts.</li> </ul>

That is why they show up in problems involving parentheses, trees, grids, polygons, and stack operations.

<h2>Some Important Catalan Formulas</h2> <h3>Closed Form</h3> 
[math] C_n = \frac{1}{n+1}\binom{2n}{n} [/math] 

<h3>Equivalent Difference Form</h3> 
[math] C_n = \binom{2n}{n} - \binom{2n}{n+1} [/math] 

<h3>Recursive Formula</h3> 
[math] C_0 = 1 [/math] 
[math] C_n = \sum_{i=0}^{n-1} C_i C_{n-1-i}, \quad n \ge 1 [/math]

This recursive formula is very important. It says that if a structure of size n can be split into a left part of size i and a right part of size n-1-i, then the total number is obtained by summing over all possible splits.

<h3>Generating Function</h3> [math] C(x) = \sum_{n\ge 0} C_n x^n = \frac{1-\sqrt{1-4x}}{2x} [/math] <h3>Asymptotic Growth</h3> [math] C_n \sim \frac{4^n}{n^{3/2}\sqrt{\pi}} [/math]

This tells us that Catalan numbers grow very quickly, though still slightly slower than pure exponential growth of 4^n.

<h2>Classic Use Cases of Catalan Numbers</h2> <h3>1. Valid Parentheses</h3>

A classic example is counting the number of valid expressions formed by n pairs of parentheses.

For n = 3, the valid expressions are:

<pre><code>((())) (()()) (())() ()(()) ()()() </code></pre>

There are 5 of them, so:

[math] C_3 = 5 [/math]

The key idea is that at no point, while reading from left to right, can the number of closing parentheses exceed the number of opening parentheses.

<h3>2. Binary Tree Shapes</h3>

The number of different binary tree shapes with n nodes is also the nth <a href="https://helloacm.com/teaching-kids-programming-dynamic-programming-algorithms-to-count-the-number-of-unique-binary-search-trees-catalan-numbers/" title="Teaching Kids Programming – Dynamic Programming Algorithms to Count the Number of Unique Binary Search Trees (Catalan Numbers)">Catalan number</a>.

Why? Because once you choose a root, the remaining nodes are split into a left subtree and a right subtree. If the left subtree has i nodes, then the right subtree has n - 1 - i nodes. This leads directly to the recurrence:

[math] C_n = \sum_{i=0}^{n-1} C_i C_{n-1-i} [/math]

This interpretation is especially useful in <a href="https://helloacm.com/a-complete-guide-to-sorted-data-structures-in-python/" title="A Complete Guide to Sorted Data Structures in Python">data structures</a>, recursive algorithms, and parsing.

<h3>3. Triangulations of a Polygon</h3>

The number of ways to triangulate a convex polygon with n + 2 sides is:

[math] C_n [/math]

For example, the number of ways to triangulate a pentagon is:

[math] C_3 = 5 [/math]

This is another non-crossing structure: the diagonals used in the triangulation are not allowed to intersect.

<h3>4. Stack Permutations</h3>

Catalan numbers also count valid push-pop sequences of a stack with n items, where no invalid pop is allowed before a corresponding push.

Again, the same balance condition appears.

<h3>5. Non-Crossing Handshakes or Pairings</h3>

Suppose 2n people sit around a round table, and each person shakes hands with exactly one other person, with the rule that the handshakes must not cross.

The number of such non-crossing pairings is:

[math] C_n [/math]

This is another excellent example of a Catalan structure.

<h2>Grid Walking Without Crossing the Diagonal</h2>

Now let us look at one of the most visual and beautiful interpretations of Catalan numbers.

<h3>The Problem</h3>

Suppose you start at the point (0,0) on a square grid and want to reach the point (n,n).

At each step, you may move only:

<ul> <li>one step to the right, or</li> <li>one step upward.</li> </ul>

Without any restriction, every path consists of exactly n right moves and n up moves, so the total number of such paths is:

[math] \binom{2n}{n} [/math]

This is because we only need to choose which n of the 2n moves are the right moves.

<h3>The Restriction</h3>

Now impose the condition that the path must never cross above the diagonal line:

[math] y = x [/math]

This means that at every point along the path, the number of upward steps taken so far can never exceed the number of rightward steps taken so far.

The number of such restricted paths is exactly the Catalan number:

[math] C_n = \frac{1}{n+1}\binom{2n}{n} [/math] <h3>Why This Matches the Parentheses Problem</h3>

There is a direct correspondence:

<ul> <li>right step corresponds to an opening parenthesis,</li> <li>up step corresponds to a closing parenthesis.</li> </ul>

A path that never crosses above the diagonal is exactly like a parentheses sequence in which, at every prefix, the number of closing parentheses never exceeds the number of opening parentheses.

So the grid-walking problem and the valid-<a href="https://helloacm.com/teaching-kids-programming-back-tracking-algorithm-to-generate-parentheses/" title="Teaching Kids Programming – Back Tracking Algorithm to Generate Parentheses">parentheses</a> problem are actually the same combinatorial structure in disguise.

<h3>Example: n = 3</h3>

From (0,0) to (3,3), the total number of unrestricted paths is:

[math] \binom{6}{3} = 20 [/math]

But the number of paths that never cross above the diagonal is:

[math] C_3 = \frac{1}{4}\binom{6}{3} = 5 [/math]

So only 5 of the 20 paths satisfy the condition.

<h3>The Reflection Principle Idea</h3>

A classical way to derive the Catalan formula is to count:

<ul> <li>all paths from (0,0) to (n,n), and then</li> <li>subtract the bad paths that cross above the diagonal.</li> </ul>

The total number of paths is:

[math] \binom{2n}{n} [/math]

The number of bad paths can be shown, using a reflection argument, to be:

[math] \binom{2n}{n+1} [/math]

Therefore the number of good paths is:

[math] \binom{2n}{n} - \binom{2n}{n+1} [/math]

And this simplifies to:

[math] \frac{1}{n+1}\binom{2n}{n} [/math]

which is exactly the Catalan number.

<h2>A Small Table of Catalan Numbers</h2> <table> <thead> <tr> <th>n</th> <th>C_n</th> </tr> </thead> <tbody> <tr> <td>0</td> <td>1</td> </tr> <tr> <td>1</td> <td>1</td> </tr> <tr> <td>2</td> <td>2</td> </tr> <tr> <td>3</td> <td>5</td> </tr> <tr> <td>4</td> <td>14</td> </tr> <tr> <td>5</td> <td>42</td> </tr> <tr> <td>6</td> <td>132</td> </tr> <tr> <td>7</td> <td>429</td> </tr> <tr> <td>8</td> <td>1430</td> </tr> </tbody> </table> <h2>How to Recognize a Catalan Problem</h2>

When solving a combinatorics problem, Catalan numbers often appear when you see one or more of the following clues:

<ul> <li>balanced expressions,</li> <li>valid prefixes,</li> <li>non-crossing pairings,</li> <li>paths constrained by a diagonal or boundary,</li> <li>recursive splitting into left and right parts.</li> </ul>

Whenever a counting problem has a hidden balance condition, it is worth checking whether Catalan numbers are involved.

<h2>Conclusion</h2>

Catalan numbers are a perfect example of how different mathematical problems can share the same internal structure.

They count:

<ul> <li>valid parentheses sequences,</li> <li>binary tree shapes,</li> <li>polygon triangulations,</li> <li>non-crossing pairings,</li> <li>stack-valid sequences,</li> <li>grid paths that do not cross the diagonal.</li> </ul>

Among these, the grid-walking interpretation is especially intuitive. Starting from a simple path-counting problem, the diagonal restriction transforms an ordinary binomial counting problem into one of the most famous sequences in combinatorics.

If you understand why the diagonal restriction leads to Catalan numbers, you have already grasped one of the central ideas of combinatorial mathematics: very different-looking objects can often be counted in exactly the same way.

<h2>Key Formulas Summary</h2> 
[math] C_n = \frac{1}{n+1}\binom{2n}{n} [/math] 
[math] C_n = \binom{2n}{n} - \binom{2n}{n+1} [/math] 
[math] C_0 = 1 [/math] 
[math] C_n = \sum_{i=0}^{n-1} C_i C_{n-1-i} [/math] 
[math] C(x) = \frac{1-\sqrt{1-4x}}{2x} [/math] 
[math] C_n \sim \frac{4^n}{n^{3/2}\sqrt{\pi}} [/math]

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/c-coding-reference-partial-sorting-with-nth_element-from-algorithm-header/" rel="bookmark" title="C++ Coding Reference: Partial Sorting with nth_element from Algorithm header">C++ Coding Reference: Partial Sorting with nth_element from Algorithm header</a> <small>nth_element is a partial sorting algorithm which can be invoked by including the header algorithm....</small></li>
<li><a href="https://helloacm.com/planning-to-update-your-website-for-2020-read-this/" rel="bookmark" title="Planning To Update Your Website For 2020? Read This.">Planning To Update Your Website For 2020? Read This.</a> <small>Looking to update your website for 2020? If so, it&#8217;s important to be aware of...</small></li>
<li><a href="https://helloacm.com/sql-left-outer-join-tutorial-with-example-employee-bonus/" rel="bookmark" title="SQL Left Outer Join Tutorial with Example:  Employee Bonus">SQL Left Outer Join Tutorial with Example:  Employee Bonus</a> <small>SQL Left Outer Join can be illustrated by the following: where the query will take...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-geometry-of-triangle-area-and-side-law/" rel="bookmark" title="Teaching Kids Programming &#8211; Geometry of Triangle Area and Side Law">Teaching Kids Programming &#8211; Geometry of Triangle Area and Side Law</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms We know the area of triangle...</small></li>
<li><a href="https://helloacm.com/coding-exercise-implement-integer-square-root-c-online-judge/" rel="bookmark" title="How to Implement Integer Square Root in C/C++?">How to Implement Integer Square Root in C/C++?</a> <small>Question: Implement integer square root for int sqrt(int x) There are many ways to compute the...</small></li>
<li><a href="https://helloacm.com/algorithm-to-construct-binary-tree-from-preorder-and-inorder-traversal/" rel="bookmark" title="Algorithm to Construct Binary Tree from Preorder and Inorder Traversal">Algorithm to Construct Binary Tree from Preorder and Inorder Traversal</a> <small>Given preorder and inorder traversal of a tree, construct the binary tree. You may assume...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-count-pairs-of-similar-strings-bruterforce-hash-map-counter-and-bit-masking/" rel="bookmark" title="Teaching Kids Programming &#8211; Count Pairs Of Similar Strings (Bruterforce, Hash Map / Counter and Bit masking)">Teaching Kids Programming &#8211; Count Pairs Of Similar Strings (Bruterforce, Hash Map / Counter and Bit masking)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given a 0-indexed string...</small></li>
<li><a href="https://helloacm.com/golang-implement-trie-prefix-tree/" rel="bookmark" title="GoLang: Implement Trie (Prefix Tree)">GoLang: Implement Trie (Prefix Tree)</a> <small>Trie aka Prefix Tree is a data structure helps to search a word or prefix...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<iframe width="2835" height="1101" src="https://www.youtube.com/embed/5E47eeSLoMs" title="" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

<h1>Introduction to Combinatorial Mathematics (2): Catalan Numbers</h1>
Catalan numbers are one of the most important sequences in <a href="https://helloacm.com/teaching-kids-programming-how-many-games-are-played-in-world-cup-combinatorics-and-permutations/" title="Teaching Kids Programming – How Many Games are Played in World Cup (Combinatorics and Permutations)">combinatorics</a>. They appear in many counting problems that look very different on the surface, but actually share the same underlying structure: balance, recursion, and non-crossing constraints.

In this post, we will introduce the Catalan numbers, show several important formulas, and explain some classic use cases, especially the grid-walking problem where a path is not allowed to cross the diagonal.

<h2>What Are Catalan Numbers?</h2>
The Catalan sequence begins as follows:

[math] C_0 = 1,\quad C_1 = 1,\quad C_2 = 2,\quad C_3 = 5,\quad C_4 = 14,\quad C_5 = 42,\quad C_6 = 132 [/math]

The general formula for the nth Catalan number is:

[math] C_n = \frac{1}{n+1}\binom{2n}{n} [/math]

An equivalent form is:

[math] C_n = \binom{2n}{n} - \binom{2n}{n+1} [/math]

These two formulas are completely equivalent and both appear often in combinatorics.

<h2>Why Catalan Numbers Matter</h2>

Catalan numbers count many kinds of recursive or balanced structures. They often appear when:

<ul> <li>objects must be built in a balanced way,</li> <li>paths must stay within a boundary,</li> <li>pairings cannot cross,</li> <li>a structure can be split into independent left and right parts.</li> </ul>

That is why they show up in problems involving parentheses, trees, grids, polygons, and stack operations.

<h2>Some Important Catalan Formulas</h2> <h3>Closed Form</h3> 
[math] C_n = \frac{1}{n+1}\binom{2n}{n} [/math] 

<h3>Equivalent Difference Form</h3> 
[math] C_n = \binom{2n}{n} - \binom{2n}{n+1} [/math] 

<h3>Recursive Formula</h3> 
[math] C_0 = 1 [/math] 
[math] C_n = \sum_{i=0}^{n-1} C_i C_{n-1-i}, \quad n \ge 1 [/math]

This recursive formula is very important. It says that if a structure of size n can be split into a left part of size i and a right part of size n-1-i, then the total number is obtained by summing over all possible splits.

<h3>Generating Function</h3> [math] C(x) = \sum_{n\ge 0} C_n x^n = \frac{1-\sqrt{1-4x}}{2x} [/math] <h3>Asymptotic Growth</h3> [math] C_n \sim \frac{4^n}{n^{3/2}\sqrt{\pi}} [/math]

This tells us that Catalan numbers grow very quickly, though still slightly slower than pure exponential growth of 4^n.

<h2>Classic Use Cases of Catalan Numbers</h2> <h3>1. Valid Parentheses</h3>

A classic example is counting the number of valid expressions formed by n pairs of parentheses.

For n = 3, the valid expressions are:

<pre><code>((())) (()()) (())() ()(()) ()()() </code></pre>

There are 5 of them, so:

[math] C_3 = 5 [/math]

The key idea is that at no point, while reading from left to right, can the number of closing parentheses exceed the number of opening parentheses.

<h3>2. Binary Tree Shapes</h3>

The number of different binary tree shapes with n nodes is also the nth <a href="https://helloacm.com/teaching-kids-programming-dynamic-programming-algorithms-to-count-the-number-of-unique-binary-search-trees-catalan-numbers/" title="Teaching Kids Programming – Dynamic Programming Algorithms to Count the Number of Unique Binary Search Trees (Catalan Numbers)">Catalan number</a>.

Why? Because once you choose a root, the remaining nodes are split into a left subtree and a right subtree. If the left subtree has i nodes, then the right subtree has n - 1 - i nodes. This leads directly to the recurrence:

[math] C_n = \sum_{i=0}^{n-1} C_i C_{n-1-i} [/math]

This interpretation is especially useful in <a href="https://helloacm.com/a-complete-guide-to-sorted-data-structures-in-python/" title="A Complete Guide to Sorted Data Structures in Python">data structures</a>, recursive algorithms, and parsing.

<h3>3. Triangulations of a Polygon</h3>

The number of ways to triangulate a convex polygon with n + 2 sides is:

[math] C_n [/math]

For example, the number of ways to triangulate a pentagon is:

[math] C_3 = 5 [/math]

This is another non-crossing structure: the diagonals used in the triangulation are not allowed to intersect.

<h3>4. Stack Permutations</h3>

Catalan numbers also count valid push-pop sequences of a stack with n items, where no invalid pop is allowed before a corresponding push.

Again, the same balance condition appears.

<h3>5. Non-Crossing Handshakes or Pairings</h3>

Suppose 2n people sit around a round table, and each person shakes hands with exactly one other person, with the rule that the handshakes must not cross.

The number of such non-crossing pairings is:

[math] C_n [/math]

This is another excellent example of a Catalan structure.

<h2>Grid Walking Without Crossing the Diagonal</h2>

Now let us look at one of the most visual and beautiful interpretations of Catalan numbers.

<h3>The Problem</h3>

Suppose you start at the point (0,0) on a square grid and want to reach the point (n,n).

At each step, you may move only:

<ul> <li>one step to the right, or</li> <li>one step upward.</li> </ul>

Without any restriction, every path consists of exactly n right moves and n up moves, so the total number of such paths is:

[math] \binom{2n}{n} [/math]

This is because we only need to choose which n of the 2n moves are the right moves.

<h3>The Restriction</h3>

Now impose the condition that the path must never cross above the diagonal line:

[math] y = x [/math]

This means that at every point along the path, the number of upward steps taken so far can never exceed the number of rightward steps taken so far.

The number of such restricted paths is exactly the Catalan number:

[math] C_n = \frac{1}{n+1}\binom{2n}{n} [/math] <h3>Why This Matches the Parentheses Problem</h3>

There is a direct correspondence:

<ul> <li>right step corresponds to an opening parenthesis,</li> <li>up step corresponds to a closing parenthesis.</li> </ul>

A path that never crosses above the diagonal is exactly like a parentheses sequence in which, at every prefix, the number of closing parentheses never exceeds the number of opening parentheses.

So the grid-walking problem and the valid-<a href="https://helloacm.com/teaching-kids-programming-back-tracking-algorithm-to-generate-parentheses/" title="Teaching Kids Programming – Back Tracking Algorithm to Generate Parentheses">parentheses</a> problem are actually the same combinatorial structure in disguise.

<h3>Example: n = 3</h3>

From (0,0) to (3,3), the total number of unrestricted paths is:

[math] \binom{6}{3} = 20 [/math]

But the number of paths that never cross above the diagonal is:

[math] C_3 = \frac{1}{4}\binom{6}{3} = 5 [/math]

So only 5 of the 20 paths satisfy the condition.

<h3>The Reflection Principle Idea</h3>

A classical way to derive the Catalan formula is to count:

<ul> <li>all paths from (0,0) to (n,n), and then</li> <li>subtract the bad paths that cross above the diagonal.</li> </ul>

The total number of paths is:

[math] \binom{2n}{n} [/math]

The number of bad paths can be shown, using a reflection argument, to be:

[math] \binom{2n}{n+1} [/math]

Therefore the number of good paths is:

[math] \binom{2n}{n} - \binom{2n}{n+1} [/math]

And this simplifies to:

[math] \frac{1}{n+1}\binom{2n}{n} [/math]

which is exactly the Catalan number.

<h2>A Small Table of Catalan Numbers</h2> <table> <thead> <tr> <th>n</th> <th>C_n</th> </tr> </thead> <tbody> <tr> <td>0</td> <td>1</td> </tr> <tr> <td>1</td> <td>1</td> </tr> <tr> <td>2</td> <td>2</td> </tr> <tr> <td>3</td> <td>5</td> </tr> <tr> <td>4</td> <td>14</td> </tr> <tr> <td>5</td> <td>42</td> </tr> <tr> <td>6</td> <td>132</td> </tr> <tr> <td>7</td> <td>429</td> </tr> <tr> <td>8</td> <td>1430</td> </tr> </tbody> </table> <h2>How to Recognize a Catalan Problem</h2>

When solving a combinatorics problem, Catalan numbers often appear when you see one or more of the following clues:

<ul> <li>balanced expressions,</li> <li>valid prefixes,</li> <li>non-crossing pairings,</li> <li>paths constrained by a diagonal or boundary,</li> <li>recursive splitting into left and right parts.</li> </ul>

Whenever a counting problem has a hidden balance condition, it is worth checking whether Catalan numbers are involved.

<h2>Conclusion</h2>

Catalan numbers are a perfect example of how different mathematical problems can share the same internal structure.

They count:

<ul> <li>valid parentheses sequences,</li> <li>binary tree shapes,</li> <li>polygon triangulations,</li> <li>non-crossing pairings,</li> <li>stack-valid sequences,</li> <li>grid paths that do not cross the diagonal.</li> </ul>

Among these, the grid-walking interpretation is especially intuitive. Starting from a simple path-counting problem, the diagonal restriction transforms an ordinary binomial counting problem into one of the most famous sequences in combinatorics.

If you understand why the diagonal restriction leads to Catalan numbers, you have already grasped one of the central ideas of combinatorial mathematics: very different-looking objects can often be counted in exactly the same way.

<h2>Key Formulas Summary</h2> 
[math] C_n = \frac{1}{n+1}\binom{2n}{n} [/math] 
[math] C_n = \binom{2n}{n} - \binom{2n}{n+1} [/math] 
[math] C_0 = 1 [/math] 
[math] C_n = \sum_{i=0}^{n-1} C_i C_{n-1-i} [/math] 
[math] C(x) = \frac{1-\sqrt{1-4x}}{2x} [/math] 
[math] C_n \sim \frac{4^n}{n^{3/2}\sqrt{\pi}} [/math]

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/c-coding-reference-partial-sorting-with-nth_element-from-algorithm-header/" rel="bookmark" title="C++ Coding Reference: Partial Sorting with nth_element from Algorithm header">C++ Coding Reference: Partial Sorting with nth_element from Algorithm header</a> <small>nth_element is a partial sorting algorithm which can be invoked by including the header algorithm....</small></li>
<li><a href="https://helloacm.com/planning-to-update-your-website-for-2020-read-this/" rel="bookmark" title="Planning To Update Your Website For 2020? Read This.">Planning To Update Your Website For 2020? Read This.</a> <small>Looking to update your website for 2020? If so, it&#8217;s important to be aware of...</small></li>
<li><a href="https://helloacm.com/sql-left-outer-join-tutorial-with-example-employee-bonus/" rel="bookmark" title="SQL Left Outer Join Tutorial with Example:  Employee Bonus">SQL Left Outer Join Tutorial with Example:  Employee Bonus</a> <small>SQL Left Outer Join can be illustrated by the following: where the query will take...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-geometry-of-triangle-area-and-side-law/" rel="bookmark" title="Teaching Kids Programming &#8211; Geometry of Triangle Area and Side Law">Teaching Kids Programming &#8211; Geometry of Triangle Area and Side Law</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms We know the area of triangle...</small></li>
<li><a href="https://helloacm.com/coding-exercise-implement-integer-square-root-c-online-judge/" rel="bookmark" title="How to Implement Integer Square Root in C/C++?">How to Implement Integer Square Root in C/C++?</a> <small>Question: Implement integer square root for int sqrt(int x) There are many ways to compute the...</small></li>
<li><a href="https://helloacm.com/algorithm-to-construct-binary-tree-from-preorder-and-inorder-traversal/" rel="bookmark" title="Algorithm to Construct Binary Tree from Preorder and Inorder Traversal">Algorithm to Construct Binary Tree from Preorder and Inorder Traversal</a> <small>Given preorder and inorder traversal of a tree, construct the binary tree. You may assume...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-count-pairs-of-similar-strings-bruterforce-hash-map-counter-and-bit-masking/" rel="bookmark" title="Teaching Kids Programming &#8211; Count Pairs Of Similar Strings (Bruterforce, Hash Map / Counter and Bit masking)">Teaching Kids Programming &#8211; Count Pairs Of Similar Strings (Bruterforce, Hash Map / Counter and Bit masking)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given a 0-indexed string...</small></li>
<li><a href="https://helloacm.com/golang-implement-trie-prefix-tree/" rel="bookmark" title="GoLang: Implement Trie (Prefix Tree)">GoLang: Implement Trie (Prefix Tree)</a> <small>Trie aka Prefix Tree is a data structure helps to search a word or prefix...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://helloacm.com/teaching-kids-programming-introduction-to-combinatorial-mathematics-2-catalan-number/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Teaching Kids Programming –’ogramming is not my wifeTeaching Kids Programming –’ Introduction to Combinatorial Mathematics 2 (Catalan Number)s thing.</title>
		<link>https://helloacm.com/programming-is-not-my-wifes-thing/</link>
					<comments>https://helloacm.com/programming-is-not-my-wifes-thing/#respond</comments>
		
		<dc:creator><![CDATA[ACMer]]></dc:creator>
		<pubDate>Tue, 17 Mar 2026 11:50:47 +0000</pubDate>
				<category><![CDATA[programming languages]]></category>
		<category><![CDATA[cognitive training]]></category>
		<category><![CDATA[empathy]]></category>
		<category><![CDATA[family life]]></category>
		<category><![CDATA[growth mindset]]></category>
		<category><![CDATA[learning mindset]]></category>
		<category><![CDATA[parenting]]></category>
		<category><![CDATA[Problem Solving]]></category>
		<category><![CDATA[programming education]]></category>
		<category><![CDATA[skill development]]></category>
		<category><![CDATA[teaching experience]]></category>
		<guid isPermaLink="false">https://helloacm.com/?p=157780</guid>

					<description><![CDATA[I used to try teaching my wife <a href="https://zhihua-lai.com/teaching/?cat=wife" title="programming" rel="noopener" target="_blank">programming</a>, but it quickly became clear that it just was not her thing. Over time, I think she has forgotten most of what I taught her, which honestly is not surprising, because people rarely retain knowledge in areas they are not genuinely interested in. 

<iframe width="1132" height="637" src="https://www.youtube.com/embed/9W0MG4PQguE" title="第25课 教媳妇编程: 快速排序算法 Quick Sort Algorithm" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

That experience also taught me that being good at something does not automatically mean you can pass it on successfully, especially when the other person has neither the passion nor the natural inclination for it.

[caption id="attachment_157781" align="alignnone" width="1024"]<a href="https://helloacm.com/programming-is-not-my-wifes-thing/teach-wife-programming-2026-03-16-21-41-14/" rel="attachment wp-att-157781"><img src="https://helloacm.com/wp-content/uploads/2026/03/teach-wife-programming-2026-03-16-21.41.14.jpg" alt="My wife learns programming" width="1024" height="1536" class="size-full wp-image-157781" /></a> My wife learns programming[/caption]

[caption id="attachment_157782" align="alignnone" width="1024"]<a href="https://helloacm.com/programming-is-not-my-wifes-thing/teach-wife-programming2026-03-16-21-41-39/" rel="attachment wp-att-157782"><img src="https://helloacm.com/wp-content/uploads/2026/03/teach-wife-programming2026-03-16-21.41.39.jpg" alt="Teaching wife programming." width="1024" height="1536" class="size-full wp-image-157782" /></a> Teaching wife programming.[/caption]

It also made me rethink what “teaching” really means. It’s not just about transferring <a href="https://helloacm.com/leetcodes-coding-room-real-time-coding-collaboration-coding-interview/" title="Leetcode’s Coding Room – Real time Coding Collaboration (Coding Interview)">knowledge</a>, but about meeting someone where they are, understanding what motivates them, and knowing when to step back. In hindsight, I was probably trying to impose my own interests and learning style onto her, rather than adapting to hers. Not everything needs to be optimized or turned into a lesson—sometimes it’s more valuable to appreciate differences and let people grow in their own direction. In that sense, the experience wasn’t a failure at all; it was a useful reminder that good teaching starts with empathy, not expertise.

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --
<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/using-reduce-to-count-the-array-in-javascript/" rel="bookmark" title="Using Reduce to Count the Array in Javascript">Using Reduce to Count the Array in Javascript</a> <small>Let&#8217;s say, we have an array in Javascript, and we want to group the elements,...</small></li>
<li><a href="https://helloacm.com/characteristic-attributes-essential-for-successful-software-engineers/" rel="bookmark" title="Characteristic Attributes Essential for Successful Software Engineers">Characteristic Attributes Essential for Successful Software Engineers</a> <small>Passion for Learning Technology evolves, and as a software engineer, you would need a passion...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-max-profit-of-rod-cutting-unbounded-knapsack-via-bottom-up-dynamic-programming-algorithm/" rel="bookmark" title="Teaching Kids Programming &#8211; Max Profit of Rod Cutting (Unbounded Knapsack) via Bottom Up Dynamic Programming Algorithm">Teaching Kids Programming &#8211; Max Profit of Rod Cutting (Unbounded Knapsack) via Bottom Up Dynamic Programming Algorithm</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given a list of...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-introduction-to-dijkstra-single-source-shortest-path-graph-algorithm/" rel="bookmark" title="Teaching Kids Programming &#8211; Introduction to Dijkstra Single Source Shortest Path Graph Algorithm">Teaching Kids Programming &#8211; Introduction to Dijkstra Single Source Shortest Path Graph Algorithm</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given a two-dimensional list...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-a-light-talk-on-breadth-first-search-uniform-cost-search-and-dijkstra-shortest-path-graph-algorithms/" rel="bookmark" title="Teaching Kids Programming &#8211; A Light Talk on Breadth First Search, Uniform Cost Search and Dijkstra Shortest Path Graph Algorithms">Teaching Kids Programming &#8211; A Light Talk on Breadth First Search, Uniform Cost Search and Dijkstra Shortest Path Graph Algorithms</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms Breadth First Search Algorithm (BFS) performs...</small></li>
<li><a href="https://helloacm.com/simple-investment-strategy-regular-investment-in-bitcoin-btc-dollar-cost-averaging/" rel="bookmark" title="Simple investment strategy: regular investment in Bitcoin/BTC (Dollar Cost Averaging)">Simple investment strategy: regular investment in Bitcoin/BTC (Dollar Cost Averaging)</a> <small>That day, I came across a post on LinkedIn: A person consistently purchased $30 worth...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-minimum-moves-to-reach-target-score-with-constraints-greedy-algorithm/" rel="bookmark" title="Teaching Kids Programming &#8211; Minimum Moves to Reach Target Score with Constraints (Greedy Algorithm)">Teaching Kids Programming &#8211; Minimum Moves to Reach Target Score with Constraints (Greedy Algorithm)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are playing a game with...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-depth-first-limit-search-and-iterative-deepening-search-algorithm-on-unweighted-graph/" rel="bookmark" title="Teaching Kids Programming &#8211; Depth First/Limit Search and Iterative Deepening Search Algorithm on Unweighted Graph">Teaching Kids Programming &#8211; Depth First/Limit Search and Iterative Deepening Search Algorithm on Unweighted Graph</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms Shipping and Receiving &#8211; Sum of...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[I used to try teaching my wife <a href="https://zhihua-lai.com/teaching/?cat=wife" title="programming" rel="noopener" target="_blank">programming</a>, but it quickly became clear that it just was not her thing. Over time, I think she has forgotten most of what I taught her, which honestly is not surprising, because people rarely retain knowledge in areas they are not genuinely interested in. 

<iframe width="1132" height="637" src="https://www.youtube.com/embed/9W0MG4PQguE" title="第25课 教媳妇编程: 快速排序算法 Quick Sort Algorithm" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

That experience also taught me that being good at something does not automatically mean you can pass it on successfully, especially when the other person has neither the passion nor the natural inclination for it.

[caption id="attachment_157781" align="alignnone" width="1024"]<a href="https://helloacm.com/programming-is-not-my-wifes-thing/teach-wife-programming-2026-03-16-21-41-14/" rel="attachment wp-att-157781"><img src="https://helloacm.com/wp-content/uploads/2026/03/teach-wife-programming-2026-03-16-21.41.14.jpg" alt="My wife learns programming" width="1024" height="1536" class="size-full wp-image-157781" /></a> My wife learns programming[/caption]

[caption id="attachment_157782" align="alignnone" width="1024"]<a href="https://helloacm.com/programming-is-not-my-wifes-thing/teach-wife-programming2026-03-16-21-41-39/" rel="attachment wp-att-157782"><img src="https://helloacm.com/wp-content/uploads/2026/03/teach-wife-programming2026-03-16-21.41.39.jpg" alt="Teaching wife programming." width="1024" height="1536" class="size-full wp-image-157782" /></a> Teaching wife programming.[/caption]

It also made me rethink what “teaching” really means. It’s not just about transferring <a href="https://helloacm.com/leetcodes-coding-room-real-time-coding-collaboration-coding-interview/" title="Leetcode’s Coding Room – Real time Coding Collaboration (Coding Interview)">knowledge</a>, but about meeting someone where they are, understanding what motivates them, and knowing when to step back. In hindsight, I was probably trying to impose my own interests and learning style onto her, rather than adapting to hers. Not everything needs to be optimized or turned into a lesson—sometimes it’s more valuable to appreciate differences and let people grow in their own direction. In that sense, the experience wasn’t a failure at all; it was a useful reminder that good teaching starts with empathy, not expertise.

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --
<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/using-reduce-to-count-the-array-in-javascript/" rel="bookmark" title="Using Reduce to Count the Array in Javascript">Using Reduce to Count the Array in Javascript</a> <small>Let&#8217;s say, we have an array in Javascript, and we want to group the elements,...</small></li>
<li><a href="https://helloacm.com/characteristic-attributes-essential-for-successful-software-engineers/" rel="bookmark" title="Characteristic Attributes Essential for Successful Software Engineers">Characteristic Attributes Essential for Successful Software Engineers</a> <small>Passion for Learning Technology evolves, and as a software engineer, you would need a passion...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-max-profit-of-rod-cutting-unbounded-knapsack-via-bottom-up-dynamic-programming-algorithm/" rel="bookmark" title="Teaching Kids Programming &#8211; Max Profit of Rod Cutting (Unbounded Knapsack) via Bottom Up Dynamic Programming Algorithm">Teaching Kids Programming &#8211; Max Profit of Rod Cutting (Unbounded Knapsack) via Bottom Up Dynamic Programming Algorithm</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given a list of...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-introduction-to-dijkstra-single-source-shortest-path-graph-algorithm/" rel="bookmark" title="Teaching Kids Programming &#8211; Introduction to Dijkstra Single Source Shortest Path Graph Algorithm">Teaching Kids Programming &#8211; Introduction to Dijkstra Single Source Shortest Path Graph Algorithm</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given a two-dimensional list...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-a-light-talk-on-breadth-first-search-uniform-cost-search-and-dijkstra-shortest-path-graph-algorithms/" rel="bookmark" title="Teaching Kids Programming &#8211; A Light Talk on Breadth First Search, Uniform Cost Search and Dijkstra Shortest Path Graph Algorithms">Teaching Kids Programming &#8211; A Light Talk on Breadth First Search, Uniform Cost Search and Dijkstra Shortest Path Graph Algorithms</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms Breadth First Search Algorithm (BFS) performs...</small></li>
<li><a href="https://helloacm.com/simple-investment-strategy-regular-investment-in-bitcoin-btc-dollar-cost-averaging/" rel="bookmark" title="Simple investment strategy: regular investment in Bitcoin/BTC (Dollar Cost Averaging)">Simple investment strategy: regular investment in Bitcoin/BTC (Dollar Cost Averaging)</a> <small>That day, I came across a post on LinkedIn: A person consistently purchased $30 worth...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-minimum-moves-to-reach-target-score-with-constraints-greedy-algorithm/" rel="bookmark" title="Teaching Kids Programming &#8211; Minimum Moves to Reach Target Score with Constraints (Greedy Algorithm)">Teaching Kids Programming &#8211; Minimum Moves to Reach Target Score with Constraints (Greedy Algorithm)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are playing a game with...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-depth-first-limit-search-and-iterative-deepening-search-algorithm-on-unweighted-graph/" rel="bookmark" title="Teaching Kids Programming &#8211; Depth First/Limit Search and Iterative Deepening Search Algorithm on Unweighted Graph">Teaching Kids Programming &#8211; Depth First/Limit Search and Iterative Deepening Search Algorithm on Unweighted Graph</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms Shipping and Receiving &#8211; Sum of...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://helloacm.com/programming-is-not-my-wifes-thing/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>The touch command in Windows Powershell</title>
		<link>https://helloacm.com/the-touch-command-in-windows-powershell/</link>
					<comments>https://helloacm.com/the-touch-command-in-windows-powershell/#respond</comments>
		
		<dc:creator><![CDATA[ACMer]]></dc:creator>
		<pubDate>Mon, 02 Mar 2026 11:45:41 +0000</pubDate>
				<category><![CDATA[powershell]]></category>
		<category><![CDATA[Powershell]]></category>
		<category><![CDATA[programming languages]]></category>
		<category><![CDATA[System Administrator]]></category>
		<category><![CDATA[automation]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[command line tips]]></category>
		<category><![CDATA[developer tools]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[linux command]]></category>
		<category><![CDATA[Linux compatibility]]></category>
		<category><![CDATA[new-item]]></category>
		<category><![CDATA[shell scripting]]></category>
		<category><![CDATA[system administration]]></category>
		<category><![CDATA[system administrators]]></category>
		<category><![CDATA[touch]]></category>
		<category><![CDATA[touch command]]></category>
		<category><![CDATA[windows administrator]]></category>
		<category><![CDATA[Windows CLI]]></category>
		<guid isPermaLink="false">https://helloacm.com/?p=157771</guid>

					<description><![CDATA[<h3>The touch Command in PowerShell (Linux-Compatible)</h3>

If you come from Linux/macOS, you probably miss <code>touch</code>: create a file if it doesn’t exist, otherwise update its modified time. <a href="https://helloacm.com/how-to-send-keys-using-powershell-and-wscript-simulate-keystrokes/" title="How to Send Keys using PowerShell or VBScript or JScript via WScript.Shell COM Object (Simulate Keystrokes)?">PowerShell</a> doesn’t ship with a built-in <code>touch</code>, but you can add one that behaves like the Unix command (including multiple files and wildcards).

This post gives you a practical <code>touch</code> function you can drop into your PowerShell profile, plus examples and notes for edge cases.

<h2>What “touch” Should Do</h2>

In Unix, <code>touch</code> typically:
<ul>
<li>Creates an empty file if it doesn’t exist</li>
<li>Updates the “Last modified” timestamp if it does exist</li>
<li>Works with multiple file paths</li>
<li>Accepts wildcards like <code>*.txt</code></li>
<li>Does not print noisy output unless you want it to</li>
</ul>

We'll implement that behavior in PowerShell.

<h3>Quick One-Off Touch (Single File)</h3>

If you only need it once, this is the simplest correct “touch” behavior (create-or-update), without adding newlines to the file:

<pre lang=powershell><code>
if (Test-Path .\file.txt) { (Get-Item .\file.txt).LastWriteTime = Get-Date } else { New-Item -ItemType File -Path .\file.txt | Out-Null }
</code>
</pre>

<h3>A Linux-Compatible touch Function (Multiple Files + Wildcards)</h3>

This function:
<ul>
<li>Accepts one or more paths</li>
<li>Expands wildcards</li>
<li>Updates timestamps for existing files</li>
<li>Creates missing files (including parent folders if needed, optional)</li>
<li>Doesn’t modify file contents</li>
</ul>

Is quiet by default

<pre lang=powershell><code>
function touch { [CmdletBinding()] param( [Parameter(Mandatory=$true, ValueFromRemainingArguments=$true)] [string[]] $Path,
    # Optional: create parent directories if missing
    [switch] $MakeDirs
)

$now = Get-Date

foreach ($p in $Path) {

    # Expand wildcards (e.g. *.txt). If no match, treat as literal.
    $expanded = @(Get-ChildItem -LiteralPath $p -ErrorAction SilentlyContinue)

    if ($expanded.Count -gt 0) {
        foreach ($item in $expanded) {
            if ($item.PSIsContainer) {
                continue  # skip directories (Unix touch can differ; this is safer)
            }
            $item.LastWriteTime = $now
        }
        continue
    }

    # No wildcard matches; treat as a literal file path
    if (Test-Path -LiteralPath $p) {
        $item = Get-Item -LiteralPath $p
        if (-not $item.PSIsContainer) {
            $item.LastWriteTime = $now
        }
        continue
    }

    # Create the file (optionally create parent folders)
    if ($MakeDirs) {
        $parent = Split-Path -Parent $p
        if ($parent -and -not (Test-Path -LiteralPath $parent)) {
            New-Item -ItemType Directory -Path $parent -Force | Out-Null
        }
    }

    New-Item -ItemType File -Path $p -Force | Out-Null
}

}</code>
</pre>

<h2>Examples</h2>

Touch one file:

<blockquote><code>touch .\hello.txt</code></blockquote>

Touch multiple files:

<blockquote><code>touch .\a.txt .\b.txt .\c.txt</code></blockquote>

Touch all <code>.log</code> files in the current directory:

<blockquote><code>touch *.log</code></blockquote>

Create a file in a nested folder, creating directories automatically:

<blockquote><code>touch .\logs\2026\app.log -MakeDirs</code></blockquote>

<h3>Install touch Permanently (Add to Your PowerShell Profile)</h3>

<a href="https://helloacm.com/how-to-retrieve-hard-drive-serial-number-using-scripts-powershell-vbscript-javascript/" title="How to retrieve Hard Drive Serial Number using Scripts (PowerShell + VBScript + Javascript) ?">PowerShell</a> loads your profile script on startup. Add the function above to your profile file.

Open (or create) your profile:

<blockquote><code>notepad $PROFILE</code></blockquote>

Paste the <code>touch</code> function into the file, save, then restart PowerShell.

If profiles are disabled, enable them (Current User):

<pre lang=powershell>
<code>Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned</code>
</pre>

<h3>Optional: Make It Feel More Like Linux</h3>

If you want a shorter alias:

<blockquote><code>Set-Alias -Name t -Value touch</code></blockquote>

Add that to the profile too.

<h2>Notes and Gotchas</h2>

Directories: the function above skips directories. If you want “touch directory updates timestamp” behavior, you can remove the <code>PSIsContainer</code> checks.

Wildcards: PowerShell wildcard expansion is handled via <code>Get-ChildItem</code>. If the wildcard matches nothing, we treat the input as a literal path and create that file (matching common expectations).

No file content changes: unlike <code>"" &gt;&gt; file</code>, this does not append newlines.

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/c-coding-reference-copy-n-values-by-using-stdfill_n/" rel="bookmark" title="C++ Coding Reference: Copy N values by using std::fill_n()">C++ Coding Reference: Copy N values by using std::fill_n()</a> <small>We talked about std::fill() that we can use to copy over a single value to...</small></li>
<li><a href="https://helloacm.com/algorithms-to-detect-pattern-of-length-m-repeated-k-or-more-times-in-a-string/" rel="bookmark" title="Algorithms to Detect Pattern of Length M Repeated K or More Times in a String">Algorithms to Detect Pattern of Length M Repeated K or More Times in a String</a> <small>Given an array of positive integers arr, find a pattern of length m that is...</small></li>
<li><a href="https://helloacm.com/how-to-use-the-dynamic-link-library-in-c-linux-gcc-compiler/" rel="bookmark" title="How to Use the Dynamic Link Library in C++ Linux (gcc compiler)?">How to Use the Dynamic Link Library in C++ Linux (gcc compiler)?</a> <small>The Dynamic Link Library (DLL) is stored separately from the target application and shared among...</small></li>
<li><a href="https://helloacm.com/tutorial-example-how-to-access-microsoft-excel-chart-using-the-windows-scripting-host-jscript/" rel="bookmark" title="Tutorial Example: How to Access Microsoft Excel (Chart) using the Windows Scripting Host (JScript)">Tutorial Example: How to Access Microsoft Excel (Chart) using the Windows Scripting Host (JScript)</a> <small>WSH (Window Scripting Host) is a powerful and handy scripting environment. It is installed by...</small></li>
<li><a href="https://helloacm.com/how-to-make-ping-tests-to-global-servers-using-php/" rel="bookmark" title="How to Make Ping Tests to Global Servers using PHP?">How to Make Ping Tests to Global Servers using PHP?</a> <small>I recently consider purchasing my third VPS Server and the ping speed is one of...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-max-profit-of-rod-cutting-unbounded-knapsack-via-bottom-up-dynamic-programming-algorithm/" rel="bookmark" title="Teaching Kids Programming &#8211; Max Profit of Rod Cutting (Unbounded Knapsack) via Bottom Up Dynamic Programming Algorithm">Teaching Kids Programming &#8211; Max Profit of Rod Cutting (Unbounded Knapsack) via Bottom Up Dynamic Programming Algorithm</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given a list of...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-count-distinct-numbers-on-board/" rel="bookmark" title="Teaching Kids Programming &#8211; Count Distinct Numbers on Board (Recursion, Simulation, Math, Hash Set)">Teaching Kids Programming &#8211; Count Distinct Numbers on Board (Recursion, Simulation, Math, Hash Set)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given a positive integer...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-restore-the-word-from-rules/" rel="bookmark" title="Teaching Kids Programming &#8211; Restore the Word from Rules">Teaching Kids Programming &#8211; Restore the Word from Rules</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms Given a list of rules in...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<h3>The touch Command in PowerShell (Linux-Compatible)</h3>

If you come from Linux/macOS, you probably miss <code>touch</code>: create a file if it doesn’t exist, otherwise update its modified time. <a href="https://helloacm.com/how-to-send-keys-using-powershell-and-wscript-simulate-keystrokes/" title="How to Send Keys using PowerShell or VBScript or JScript via WScript.Shell COM Object (Simulate Keystrokes)?">PowerShell</a> doesn’t ship with a built-in <code>touch</code>, but you can add one that behaves like the Unix command (including multiple files and wildcards).

This post gives you a practical <code>touch</code> function you can drop into your PowerShell profile, plus examples and notes for edge cases.

<h2>What “touch” Should Do</h2>

In Unix, <code>touch</code> typically:
<ul>
<li>Creates an empty file if it doesn’t exist</li>
<li>Updates the “Last modified” timestamp if it does exist</li>
<li>Works with multiple file paths</li>
<li>Accepts wildcards like <code>*.txt</code></li>
<li>Does not print noisy output unless you want it to</li>
</ul>

We'll implement that behavior in PowerShell.

<h3>Quick One-Off Touch (Single File)</h3>

If you only need it once, this is the simplest correct “touch” behavior (create-or-update), without adding newlines to the file:

<pre lang=powershell><code>
if (Test-Path .\file.txt) { (Get-Item .\file.txt).LastWriteTime = Get-Date } else { New-Item -ItemType File -Path .\file.txt | Out-Null }
</code>
</pre>

<h3>A Linux-Compatible touch Function (Multiple Files + Wildcards)</h3>

This function:
<ul>
<li>Accepts one or more paths</li>
<li>Expands wildcards</li>
<li>Updates timestamps for existing files</li>
<li>Creates missing files (including parent folders if needed, optional)</li>
<li>Doesn’t modify file contents</li>
</ul>

Is quiet by default

<pre lang=powershell><code>
function touch { [CmdletBinding()] param( [Parameter(Mandatory=$true, ValueFromRemainingArguments=$true)] [string[]] $Path,
    # Optional: create parent directories if missing
    [switch] $MakeDirs
)

$now = Get-Date

foreach ($p in $Path) {

    # Expand wildcards (e.g. *.txt). If no match, treat as literal.
    $expanded = @(Get-ChildItem -LiteralPath $p -ErrorAction SilentlyContinue)

    if ($expanded.Count -gt 0) {
        foreach ($item in $expanded) {
            if ($item.PSIsContainer) {
                continue  # skip directories (Unix touch can differ; this is safer)
            }
            $item.LastWriteTime = $now
        }
        continue
    }

    # No wildcard matches; treat as a literal file path
    if (Test-Path -LiteralPath $p) {
        $item = Get-Item -LiteralPath $p
        if (-not $item.PSIsContainer) {
            $item.LastWriteTime = $now
        }
        continue
    }

    # Create the file (optionally create parent folders)
    if ($MakeDirs) {
        $parent = Split-Path -Parent $p
        if ($parent -and -not (Test-Path -LiteralPath $parent)) {
            New-Item -ItemType Directory -Path $parent -Force | Out-Null
        }
    }

    New-Item -ItemType File -Path $p -Force | Out-Null
}

}</code>
</pre>

<h2>Examples</h2>

Touch one file:

<blockquote><code>touch .\hello.txt</code></blockquote>

Touch multiple files:

<blockquote><code>touch .\a.txt .\b.txt .\c.txt</code></blockquote>

Touch all <code>.log</code> files in the current directory:

<blockquote><code>touch *.log</code></blockquote>

Create a file in a nested folder, creating directories automatically:

<blockquote><code>touch .\logs\2026\app.log -MakeDirs</code></blockquote>

<h3>Install touch Permanently (Add to Your PowerShell Profile)</h3>

<a href="https://helloacm.com/how-to-retrieve-hard-drive-serial-number-using-scripts-powershell-vbscript-javascript/" title="How to retrieve Hard Drive Serial Number using Scripts (PowerShell + VBScript + Javascript) ?">PowerShell</a> loads your profile script on startup. Add the function above to your profile file.

Open (or create) your profile:

<blockquote><code>notepad $PROFILE</code></blockquote>

Paste the <code>touch</code> function into the file, save, then restart PowerShell.

If profiles are disabled, enable them (Current User):

<pre lang=powershell>
<code>Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned</code>
</pre>

<h3>Optional: Make It Feel More Like Linux</h3>

If you want a shorter alias:

<blockquote><code>Set-Alias -Name t -Value touch</code></blockquote>

Add that to the profile too.

<h2>Notes and Gotchas</h2>

Directories: the function above skips directories. If you want “touch directory updates timestamp” behavior, you can remove the <code>PSIsContainer</code> checks.

Wildcards: PowerShell wildcard expansion is handled via <code>Get-ChildItem</code>. If the wildcard matches nothing, we treat the input as a literal path and create that file (matching common expectations).

No file content changes: unlike <code>"" &gt;&gt; file</code>, this does not append newlines.

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/c-coding-reference-copy-n-values-by-using-stdfill_n/" rel="bookmark" title="C++ Coding Reference: Copy N values by using std::fill_n()">C++ Coding Reference: Copy N values by using std::fill_n()</a> <small>We talked about std::fill() that we can use to copy over a single value to...</small></li>
<li><a href="https://helloacm.com/algorithms-to-detect-pattern-of-length-m-repeated-k-or-more-times-in-a-string/" rel="bookmark" title="Algorithms to Detect Pattern of Length M Repeated K or More Times in a String">Algorithms to Detect Pattern of Length M Repeated K or More Times in a String</a> <small>Given an array of positive integers arr, find a pattern of length m that is...</small></li>
<li><a href="https://helloacm.com/how-to-use-the-dynamic-link-library-in-c-linux-gcc-compiler/" rel="bookmark" title="How to Use the Dynamic Link Library in C++ Linux (gcc compiler)?">How to Use the Dynamic Link Library in C++ Linux (gcc compiler)?</a> <small>The Dynamic Link Library (DLL) is stored separately from the target application and shared among...</small></li>
<li><a href="https://helloacm.com/tutorial-example-how-to-access-microsoft-excel-chart-using-the-windows-scripting-host-jscript/" rel="bookmark" title="Tutorial Example: How to Access Microsoft Excel (Chart) using the Windows Scripting Host (JScript)">Tutorial Example: How to Access Microsoft Excel (Chart) using the Windows Scripting Host (JScript)</a> <small>WSH (Window Scripting Host) is a powerful and handy scripting environment. It is installed by...</small></li>
<li><a href="https://helloacm.com/how-to-make-ping-tests-to-global-servers-using-php/" rel="bookmark" title="How to Make Ping Tests to Global Servers using PHP?">How to Make Ping Tests to Global Servers using PHP?</a> <small>I recently consider purchasing my third VPS Server and the ping speed is one of...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-max-profit-of-rod-cutting-unbounded-knapsack-via-bottom-up-dynamic-programming-algorithm/" rel="bookmark" title="Teaching Kids Programming &#8211; Max Profit of Rod Cutting (Unbounded Knapsack) via Bottom Up Dynamic Programming Algorithm">Teaching Kids Programming &#8211; Max Profit of Rod Cutting (Unbounded Knapsack) via Bottom Up Dynamic Programming Algorithm</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given a list of...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-count-distinct-numbers-on-board/" rel="bookmark" title="Teaching Kids Programming &#8211; Count Distinct Numbers on Board (Recursion, Simulation, Math, Hash Set)">Teaching Kids Programming &#8211; Count Distinct Numbers on Board (Recursion, Simulation, Math, Hash Set)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given a positive integer...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-restore-the-word-from-rules/" rel="bookmark" title="Teaching Kids Programming &#8211; Restore the Word from Rules">Teaching Kids Programming &#8211; Restore the Word from Rules</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms Given a list of rules in...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://helloacm.com/the-touch-command-in-windows-powershell/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Competitive Programming: Two Simple Tricks in C++ To Make Code Faster</title>
		<link>https://helloacm.com/competitive-programming-two-simple-tricks-in-c-to-make-code-faster/</link>
					<comments>https://helloacm.com/competitive-programming-two-simple-tricks-in-c-to-make-code-faster/#respond</comments>
		
		<dc:creator><![CDATA[ACMer]]></dc:creator>
		<pubDate>Mon, 23 Feb 2026 10:55:56 +0000</pubDate>
				<category><![CDATA[c / c++]]></category>
		<category><![CDATA[C/C++]]></category>
		<category><![CDATA[Competitive Programming]]></category>
		<category><![CDATA[programming languages]]></category>
		<category><![CDATA[software development]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[Code Performance]]></category>
		<category><![CDATA[Make Code Faster]]></category>
		<category><![CDATA[std::cin.tie]]></category>
		<category><![CDATA[std::ios::sync_with_stdio]]></category>
		<category><![CDATA[Two Simple Tricks]]></category>
		<guid isPermaLink="false">https://helloacm.com/?p=157761</guid>

					<description><![CDATA[Competitive programmers ALWAYS use these two lines of code. Here's why:

C++ has two functions:
<ul>
<li>"cin" - Stands for character input. Reads an input from the standard IO.</li>
<li>"cout" - Outputs text (like printing to a terminal).</li>
</ul>

By default, these are synchronized with C's "scanf" and "printf" functions. When we use "cout" to print something, our C++ layer communicates with the C stdio layer to keep them in sync. This is slow.

In competitive <a href="https://helloacm.com/teaching-kids-programming-two-ways-to-prove-square-root-of-two-is-irrational-proof-by-contradiction-and-geometric-infinite-descent/" title="Teaching Kids Programming – Two Ways to Prove Square Root of Two is Irrational (proof by contradiction and geometric infinite descent)">programming</a>, we don't care about this synchronization. That's where the first line "ios::sync_with_stdio(false)" comes from. It decouples the two layers. This makes our code significantly faster, especially in IO heavy questions.

When we use "cout" it doesn't print the output immediately. That requires communicating with the <a href="https://helloacm.com/forking-in-nix-system-using-c-and-python/" title="Forking in *nix System using C and Python">operating system</a> which is slow. Instead, our output gets pushed to a buffer which is eventually flushed.

By default "cin" is tied to "cout". Before every "cin" read, the "cout" buffer is automatically flushed. In normal programs this helps keep the IO correct but again isn't needed in competitive programming. So "cin.tie(nullptr)" removes that tie.

<pre lang=c>
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
}
</pre>

When I was in high school, I participated in NOIP, and at that time we used <a href="https://helloacm.com/delphi-is-30-years-old/" title="Delphi is 30 Years Old!">Turbo Pascal</a>. In programming contests, readability wasn’t a priority. We often used all kinds of clever or tricky techniques, and the resulting code was hard to understand—but that didn’t stop us from winning awards.

Competitive programming emphasizes efficiency and ingenuity rather than maintainability. There’s even an annual C Obfuscation Contest where the submitted code is almost impossible to read, yet still runs correctly and produces impressive results.

Similarly, many Python solutions can be written in just one or two lines and look “magical,” but in real industrial settings they are often impractical to maintain or extend.

Contest code and production code are fundamentally two very different mindsets.

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/what-is-the-enterprise-engineer-in-meta-comparisions-to-software-engineer-roles/" rel="bookmark" title="What is the Enterprise Engineer in Meta? (Comparisions to Software Engineer Roles)">What is the Enterprise Engineer in Meta? (Comparisions to Software Engineer Roles)</a> <small>I&#8217;ve recently got an invitation email from a Meta Recruiter about a Staff Enterprise Engineer...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-last-moment-before-all-ants-fall-out-of-a-plank/" rel="bookmark" title="Teaching Kids Programming &#8211; Last Moment Before All Ants Fall Out of a Plank">Teaching Kids Programming &#8211; Last Moment Before All Ants Fall Out of a Plank</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms We have a wooden plank of...</small></li>
<li><a href="https://helloacm.com/azure-subscription-cost-vary-due-to-standard-ssd-managed-disk-operations-difference/" rel="bookmark" title="Azure Subscription Cost Vary Due to &#8220;Standard SSD Managed &#8211; Disk Operations&#8221; Difference">Azure Subscription Cost Vary Due to &#8220;Standard SSD Managed &#8211; Disk Operations&#8221; Difference</a> <small>I have noticed in the last two months, the cost of my Azure Subscription is...</small></li>
<li><a href="https://helloacm.com/auditing-blockchain-wallet-code-with-copilot-ai/" rel="bookmark" title="Auditing blockchain wallet code with Copilot AI">Auditing blockchain wallet code with Copilot AI</a> <small>I found that AI can be very useful for auditing code security. For example, I...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-probability-matrix-of-walking-in-a-grid-unique-paths/" rel="bookmark" title="Teaching Kids Programming &#8211; Probability Matrix of Walking in a Grid (Unique Paths)">Teaching Kids Programming &#8211; Probability Matrix of Walking in a Grid (Unique Paths)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms On a grid that each step,...</small></li>
<li><a href="https://helloacm.com/c-lvalue-rvalue-and-rvalue-references/" rel="bookmark" title="C++: lvalue, rvalue and rvalue references">C++: lvalue, rvalue and rvalue references</a> <small>C++ lvalue, rvalue, and rvalue references Understanding lvalues, rvalues, and rvalue references is essential for...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-back-tracking-algorithm-to-find-the-the-knights-tour-path-recursive-depth-first-search/" rel="bookmark" title="Teaching Kids Programming &#8211; Back Tracking Algorithm to Find the The Knight’s Tour Path (Recursive Depth First Search)">Teaching Kids Programming &#8211; Back Tracking Algorithm to Find the The Knight’s Tour Path (Recursive Depth First Search)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms Given two positive integers m and...</small></li>
<li><a href="https://helloacm.com/c-forward-references-the-key-to-perfect-forwarding/" rel="bookmark" title="C++ Forward References: The Key to Perfect Forwarding">C++ Forward References: The Key to Perfect Forwarding</a> <small>In modern C++ (C++11 and beyond), a powerful feature called forward references enables developers to...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[Competitive programmers ALWAYS use these two lines of code. Here's why:

C++ has two functions:
<ul>
<li>"cin" - Stands for character input. Reads an input from the standard IO.</li>
<li>"cout" - Outputs text (like printing to a terminal).</li>
</ul>

By default, these are synchronized with C's "scanf" and "printf" functions. When we use "cout" to print something, our C++ layer communicates with the C stdio layer to keep them in sync. This is slow.

In competitive <a href="https://helloacm.com/teaching-kids-programming-two-ways-to-prove-square-root-of-two-is-irrational-proof-by-contradiction-and-geometric-infinite-descent/" title="Teaching Kids Programming – Two Ways to Prove Square Root of Two is Irrational (proof by contradiction and geometric infinite descent)">programming</a>, we don't care about this synchronization. That's where the first line "ios::sync_with_stdio(false)" comes from. It decouples the two layers. This makes our code significantly faster, especially in IO heavy questions.

When we use "cout" it doesn't print the output immediately. That requires communicating with the <a href="https://helloacm.com/forking-in-nix-system-using-c-and-python/" title="Forking in *nix System using C and Python">operating system</a> which is slow. Instead, our output gets pushed to a buffer which is eventually flushed.

By default "cin" is tied to "cout". Before every "cin" read, the "cout" buffer is automatically flushed. In normal programs this helps keep the IO correct but again isn't needed in competitive programming. So "cin.tie(nullptr)" removes that tie.

<pre lang=c>
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
}
</pre>

When I was in high school, I participated in NOIP, and at that time we used <a href="https://helloacm.com/delphi-is-30-years-old/" title="Delphi is 30 Years Old!">Turbo Pascal</a>. In programming contests, readability wasn’t a priority. We often used all kinds of clever or tricky techniques, and the resulting code was hard to understand—but that didn’t stop us from winning awards.

Competitive programming emphasizes efficiency and ingenuity rather than maintainability. There’s even an annual C Obfuscation Contest where the submitted code is almost impossible to read, yet still runs correctly and produces impressive results.

Similarly, many Python solutions can be written in just one or two lines and look “magical,” but in real industrial settings they are often impractical to maintain or extend.

Contest code and production code are fundamentally two very different mindsets.

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/what-is-the-enterprise-engineer-in-meta-comparisions-to-software-engineer-roles/" rel="bookmark" title="What is the Enterprise Engineer in Meta? (Comparisions to Software Engineer Roles)">What is the Enterprise Engineer in Meta? (Comparisions to Software Engineer Roles)</a> <small>I&#8217;ve recently got an invitation email from a Meta Recruiter about a Staff Enterprise Engineer...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-last-moment-before-all-ants-fall-out-of-a-plank/" rel="bookmark" title="Teaching Kids Programming &#8211; Last Moment Before All Ants Fall Out of a Plank">Teaching Kids Programming &#8211; Last Moment Before All Ants Fall Out of a Plank</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms We have a wooden plank of...</small></li>
<li><a href="https://helloacm.com/azure-subscription-cost-vary-due-to-standard-ssd-managed-disk-operations-difference/" rel="bookmark" title="Azure Subscription Cost Vary Due to &#8220;Standard SSD Managed &#8211; Disk Operations&#8221; Difference">Azure Subscription Cost Vary Due to &#8220;Standard SSD Managed &#8211; Disk Operations&#8221; Difference</a> <small>I have noticed in the last two months, the cost of my Azure Subscription is...</small></li>
<li><a href="https://helloacm.com/auditing-blockchain-wallet-code-with-copilot-ai/" rel="bookmark" title="Auditing blockchain wallet code with Copilot AI">Auditing blockchain wallet code with Copilot AI</a> <small>I found that AI can be very useful for auditing code security. For example, I...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-probability-matrix-of-walking-in-a-grid-unique-paths/" rel="bookmark" title="Teaching Kids Programming &#8211; Probability Matrix of Walking in a Grid (Unique Paths)">Teaching Kids Programming &#8211; Probability Matrix of Walking in a Grid (Unique Paths)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms On a grid that each step,...</small></li>
<li><a href="https://helloacm.com/c-lvalue-rvalue-and-rvalue-references/" rel="bookmark" title="C++: lvalue, rvalue and rvalue references">C++: lvalue, rvalue and rvalue references</a> <small>C++ lvalue, rvalue, and rvalue references Understanding lvalues, rvalues, and rvalue references is essential for...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-back-tracking-algorithm-to-find-the-the-knights-tour-path-recursive-depth-first-search/" rel="bookmark" title="Teaching Kids Programming &#8211; Back Tracking Algorithm to Find the The Knight’s Tour Path (Recursive Depth First Search)">Teaching Kids Programming &#8211; Back Tracking Algorithm to Find the The Knight’s Tour Path (Recursive Depth First Search)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms Given two positive integers m and...</small></li>
<li><a href="https://helloacm.com/c-forward-references-the-key-to-perfect-forwarding/" rel="bookmark" title="C++ Forward References: The Key to Perfect Forwarding">C++ Forward References: The Key to Perfect Forwarding</a> <small>In modern C++ (C++11 and beyond), a powerful feature called forward references enables developers to...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://helloacm.com/competitive-programming-two-simple-tricks-in-c-to-make-code-faster/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Prompt Engineering: Sharing a Prompt for Preparing Your Exams</title>
		<link>https://helloacm.com/prompt-engineering-sharing-a-prompt-for-preparing-your-exams/</link>
					<comments>https://helloacm.com/prompt-engineering-sharing-a-prompt-for-preparing-your-exams/#respond</comments>
		
		<dc:creator><![CDATA[ACMer]]></dc:creator>
		<pubDate>Mon, 26 Jan 2026 08:32:57 +0000</pubDate>
				<category><![CDATA[AGI: Artificial General Intelligence]]></category>
		<category><![CDATA[AIGC]]></category>
		<category><![CDATA[Artificial Intelligence]]></category>
		<category><![CDATA[ChatGPT (OpenAI)]]></category>
		<category><![CDATA[Prompt]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[ChatGPT]]></category>
		<category><![CDATA[Exam Preparation]]></category>
		<category><![CDATA[Exams]]></category>
		<category><![CDATA[Prompt Engineering]]></category>
		<category><![CDATA[Prompts]]></category>
		<guid isPermaLink="false">https://helloacm.com/?p=157738</guid>

					<description><![CDATA[<blockquote>
A Universal AI Exam Preparation Prompt Template
An AI Practice Prompt for Any Certification Exam
A General-Purpose AI Exam Coach Prompt (For All Types of Exams)
An AI Exam Preparation Prompt for Any Exam
Turn AI into Your Universal Exam Coach
How I Use This Prompt to Prepare for Various Certification Exams
An AI Exam Coach Prompt That Works for Any Exam
One Prompt to Handle All Your Exam Preparation
A Universal Exam Practice Prompt: Let AI Be Your Personal Coach
A Reusable AI Exam Training Prompt Template
A Universal Exam Practice Prompt: Make AI Ask Questions by Exam Standards
A Portable AI Exam Preparation Prompt Set
</blockquote>

I've used the following prompt to prepare for my Microsoft Azure Exams such as AI-900 and DP-900. I found them particularly useful. In fact, this prompt can be used for any kind of theoretical exam, not just Azure-related ones. For example, it can also be used to prepare for driving theory tests or the Life in the UK test.

You are my _________ Test Coach. Please give me 60 questions, one at a time (mixed with questions of single answer and multiple answers). After each question, I will answer — then you will tell me whether my answer is correct, and provide a brief explanation of the correct answer and why other answers are incorrect. Keep track of any questions I get wrong. After the first 60 are done, ask me those incorrect ones again until I answer all of them correctly. Number the questions sequentially (1, 2, 3… up to 60, then 61, 62, 63…) until I’ve answered everything correctly. Please don't repeat the questions, make sure you cover as many areas of the exam topics as possible. You don't need to ask me confirmations to continue. Estimate if I can pass the test after 60 questions. Do randomize answers, and Do NOT hint answers in anyway.

PS: Fill the __________ with your exam name, for example: "Microsoft AZ-204"

Good Lucks with your exams!

For example: here is how <a href="https://helloacm.com/chatgpt-new-image-creation-art-school/" title="ChatGPT: New Image Creation (art school)">ChatGPT</a> would response with the above prompt.
[caption id="attachment_157739" align="alignnone" width="883"]<a href="https://helloacm.com/prompt-engineering-sharing-a-prompt-for-preparing-your-exams/exam-prepare-chatgpt-prompt-engineering/" rel="attachment wp-att-157739"><img src="https://helloacm.com/wp-content/uploads/2026/01/exam-prepare-chatgpt-prompt-engineering.jpg" alt="Exam Preparation using ChatGPT." width="883" height="1213" class="size-full wp-image-157739" /></a> Exam Preparation using ChatGPT.[/caption]

[show_file file="/var/www/wp-post-common/helloacm.com/prompt.php"]

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/system-design-fan-out-fan-in-pattern/" rel="bookmark" title="System Design: Fan-out/Fan-in Pattern">System Design: Fan-out/Fan-in Pattern</a> <small>Fan-out/fan-in refers to the pattern of executing multiple units of work in parallel and then...</small></li>
<li><a href="https://helloacm.com/some-telephone-interview-questions-for-c-c-software-enginners/" rel="bookmark" title="Some Telephone Interview Questions for C++/C# Software Enginners">Some Telephone Interview Questions for C++/C# Software Enginners</a> <small>What is a Garbage Collector in C# (what does it do). Are the objects automatically...</small></li>
<li><a href="https://helloacm.com/what-is-tcp-ip-4-layer-vs-osi-7-layer/" rel="bookmark" title="Software Engineer Interview Question: What is TCP/IP (4 Layer vs OSI 7 Layer)?">Software Engineer Interview Question: What is TCP/IP (4 Layer vs OSI 7 Layer)?</a> <small>Note: recently this has been asked in the first round of the technical interviews by...</small></li>
<li><a href="https://helloacm.com/free-giveaway-google-adwords-400-gbp-ads-credit/" rel="bookmark" title="Free Giveaway: Google Adwords 400 GBP Ads Credit">Free Giveaway: Google Adwords 400 GBP Ads Credit</a> <small>Long time ago, I have tried Google Adwords with some free credit from Google, but...</small></li>
<li><a href="https://helloacm.com/the-system-design-of-steem-blockchain-bots/" rel="bookmark" title="The System Design of Steem Blockchain (ChatGPT DApps) Bots">The System Design of Steem Blockchain (ChatGPT DApps) Bots</a> <small>Yesterday, the ChatGPT has been integrated to Steem Blockchain, but the initial design has problems...</small></li>
<li><a href="https://helloacm.com/why-does-the-exchange-force-liquidation-when-the-margin-is-low/" rel="bookmark" title="Why does the exchange force liquidation when the margin is low?">Why does the exchange force liquidation when the margin is low?</a> <small>In the cryptocurrency market, as long as you don&#8217;t trade contracts, the risk is not...</small></li>
<li><a href="https://helloacm.com/hunting-down-the-mythical-high-quality-code/" rel="bookmark" title="Hunting Down The Mythical High-Quality Code">Hunting Down The Mythical High-Quality Code</a> <small>Choosing the right career path can be a bit difficult. If you love building software...</small></li>
<li><a href="https://helloacm.com/tron-blockchain-how-to-send-the-usdt-trc-20-transacton-using-python-tronpy/" rel="bookmark" title="TRON Blockchain: How to Send the USDT (TRC-20) Transacton using Python tronpy?">TRON Blockchain: How to Send the USDT (TRC-20) Transacton using Python tronpy?</a> <small>How to Send the USDT (TRC-20) Transacton using Python tronpy? To send a USDT (Tether)...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<blockquote>
A Universal AI Exam Preparation Prompt Template
An AI Practice Prompt for Any Certification Exam
A General-Purpose AI Exam Coach Prompt (For All Types of Exams)
An AI Exam Preparation Prompt for Any Exam
Turn AI into Your Universal Exam Coach
How I Use This Prompt to Prepare for Various Certification Exams
An AI Exam Coach Prompt That Works for Any Exam
One Prompt to Handle All Your Exam Preparation
A Universal Exam Practice Prompt: Let AI Be Your Personal Coach
A Reusable AI Exam Training Prompt Template
A Universal Exam Practice Prompt: Make AI Ask Questions by Exam Standards
A Portable AI Exam Preparation Prompt Set
</blockquote>

I've used the following prompt to prepare for my Microsoft Azure Exams such as AI-900 and DP-900. I found them particularly useful. In fact, this prompt can be used for any kind of theoretical exam, not just Azure-related ones. For example, it can also be used to prepare for driving theory tests or the Life in the UK test.

You are my _________ Test Coach. Please give me 60 questions, one at a time (mixed with questions of single answer and multiple answers). After each question, I will answer — then you will tell me whether my answer is correct, and provide a brief explanation of the correct answer and why other answers are incorrect. Keep track of any questions I get wrong. After the first 60 are done, ask me those incorrect ones again until I answer all of them correctly. Number the questions sequentially (1, 2, 3… up to 60, then 61, 62, 63…) until I’ve answered everything correctly. Please don't repeat the questions, make sure you cover as many areas of the exam topics as possible. You don't need to ask me confirmations to continue. Estimate if I can pass the test after 60 questions. Do randomize answers, and Do NOT hint answers in anyway.

PS: Fill the __________ with your exam name, for example: "Microsoft AZ-204"

Good Lucks with your exams!

For example: here is how <a href="https://helloacm.com/chatgpt-new-image-creation-art-school/" title="ChatGPT: New Image Creation (art school)">ChatGPT</a> would response with the above prompt.
[caption id="attachment_157739" align="alignnone" width="883"]<a href="https://helloacm.com/prompt-engineering-sharing-a-prompt-for-preparing-your-exams/exam-prepare-chatgpt-prompt-engineering/" rel="attachment wp-att-157739"><img src="https://helloacm.com/wp-content/uploads/2026/01/exam-prepare-chatgpt-prompt-engineering.jpg" alt="Exam Preparation using ChatGPT." width="883" height="1213" class="size-full wp-image-157739" /></a> Exam Preparation using ChatGPT.[/caption]

[show_file file="/var/www/wp-post-common/helloacm.com/prompt.php"]

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/system-design-fan-out-fan-in-pattern/" rel="bookmark" title="System Design: Fan-out/Fan-in Pattern">System Design: Fan-out/Fan-in Pattern</a> <small>Fan-out/fan-in refers to the pattern of executing multiple units of work in parallel and then...</small></li>
<li><a href="https://helloacm.com/some-telephone-interview-questions-for-c-c-software-enginners/" rel="bookmark" title="Some Telephone Interview Questions for C++/C# Software Enginners">Some Telephone Interview Questions for C++/C# Software Enginners</a> <small>What is a Garbage Collector in C# (what does it do). Are the objects automatically...</small></li>
<li><a href="https://helloacm.com/what-is-tcp-ip-4-layer-vs-osi-7-layer/" rel="bookmark" title="Software Engineer Interview Question: What is TCP/IP (4 Layer vs OSI 7 Layer)?">Software Engineer Interview Question: What is TCP/IP (4 Layer vs OSI 7 Layer)?</a> <small>Note: recently this has been asked in the first round of the technical interviews by...</small></li>
<li><a href="https://helloacm.com/free-giveaway-google-adwords-400-gbp-ads-credit/" rel="bookmark" title="Free Giveaway: Google Adwords 400 GBP Ads Credit">Free Giveaway: Google Adwords 400 GBP Ads Credit</a> <small>Long time ago, I have tried Google Adwords with some free credit from Google, but...</small></li>
<li><a href="https://helloacm.com/the-system-design-of-steem-blockchain-bots/" rel="bookmark" title="The System Design of Steem Blockchain (ChatGPT DApps) Bots">The System Design of Steem Blockchain (ChatGPT DApps) Bots</a> <small>Yesterday, the ChatGPT has been integrated to Steem Blockchain, but the initial design has problems...</small></li>
<li><a href="https://helloacm.com/why-does-the-exchange-force-liquidation-when-the-margin-is-low/" rel="bookmark" title="Why does the exchange force liquidation when the margin is low?">Why does the exchange force liquidation when the margin is low?</a> <small>In the cryptocurrency market, as long as you don&#8217;t trade contracts, the risk is not...</small></li>
<li><a href="https://helloacm.com/hunting-down-the-mythical-high-quality-code/" rel="bookmark" title="Hunting Down The Mythical High-Quality Code">Hunting Down The Mythical High-Quality Code</a> <small>Choosing the right career path can be a bit difficult. If you love building software...</small></li>
<li><a href="https://helloacm.com/tron-blockchain-how-to-send-the-usdt-trc-20-transacton-using-python-tronpy/" rel="bookmark" title="TRON Blockchain: How to Send the USDT (TRC-20) Transacton using Python tronpy?">TRON Blockchain: How to Send the USDT (TRC-20) Transacton using Python tronpy?</a> <small>How to Send the USDT (TRC-20) Transacton using Python tronpy? To send a USDT (Tether)...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://helloacm.com/prompt-engineering-sharing-a-prompt-for-preparing-your-exams/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>System Design: Fan-out/Fan-in Pattern</title>
		<link>https://helloacm.com/system-design-fan-out-fan-in-pattern/</link>
					<comments>https://helloacm.com/system-design-fan-out-fan-in-pattern/#respond</comments>
		
		<dc:creator><![CDATA[ACMer]]></dc:creator>
		<pubDate>Wed, 21 Jan 2026 08:44:54 +0000</pubDate>
				<category><![CDATA[System Design]]></category>
		<category><![CDATA[architecture-patterns]]></category>
		<category><![CDATA[asynchronous programming]]></category>
		<category><![CDATA[concurrency]]></category>
		<category><![CDATA[concurrency-patterns]]></category>
		<category><![CDATA[distributed-systems]]></category>
		<category><![CDATA[fan-in]]></category>
		<category><![CDATA[fan-out]]></category>
		<category><![CDATA[parallelism]]></category>
		<category><![CDATA[system design]]></category>
		<guid isPermaLink="false">https://helloacm.com/?p=157732</guid>

					<description><![CDATA[Fan-out/fan-in refers to the pattern of executing multiple units of work in <a href="https://helloacm.com/why-parallelism-isnt-infinite-amdahl-vs-gustafson-explained-simply/" title="Why Parallelism Isn’t Infinite: Amdahl vs Gustafson Explained Simply">parallel</a> and then synchronizing on their completion. While it’s often discussed in the context of serverless functions, the concept is not limited to them. 

More generally, fan-out/fan-in describes a <a href="https://helloacm.com/implement-a-lock-acquire-and-release-in-c/" title="Implement a Lock Acquire and Release in C++">concurrency</a> pattern that can be applied wherever tasks can be decomposed into independent pieces—such as threads, processes, actors, microservices, or even distributed jobs—executed concurrently and later aggregated into a single result. The key idea is the separation of work into parallel branches (fan-out) and the coordinated collection of their outputs (fan-in), regardless of the underlying execution model or infrastructure.

[caption id="attachment_157733" align="alignnone" width="1653"]<a href="https://helloacm.com/system-design-fan-out-fan-in-pattern/design-concept-fan-out-fan-in/" rel="attachment wp-att-157733"><img src="https://helloacm.com/wp-content/uploads/2026/01/design-concept-fan-out-fan-in.jpg" alt="Fan-out and Fan-in Design Pattern" width="1653" height="1068" class="size-full wp-image-157733" /></a> Fan-out and Fan-in Design Pattern[/caption]

In practical engineering, the fan-out / fan-in pattern is commonly used to improve system throughput and resource utilization, especially in I/O-bound or highly parallelizable scenarios. By decomposing a complex task into multiple independent subtasks and executing them concurrently, the overall processing time can be significantly reduced. During the fan-in phase, the results of these subtasks are aggregated, ordered, or merged in a unified manner, helping to preserve the integrity and consistency of the business logic. However, this pattern also requires careful attention to concurrency control, error handling, as well as timeout and retry mechanisms; otherwise, high levels of parallelism may introduce resource contention, cascading failures, or inconsistent results. Therefore, when designing and implementing a fan-out / fan-in architecture, it is important to balance the degree of concurrency against system complexity and overall stability.

[show_file file="/var/www/wp-post-common/helloacm.com/design.php"]<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/teaching-kids-programming-another-bfs-to-generate-binary-strings-without-adjacent-zeros/" rel="bookmark" title="Teaching Kids Programming &#8211; Another BFS to Generate Binary Strings Without Adjacent Zeros">Teaching Kids Programming &#8211; Another BFS to Generate Binary Strings Without Adjacent Zeros</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given a positive integer...</small></li>
<li><a href="https://helloacm.com/how-to-delete-nodes-from-binary-tree-and-make-a-forest/" rel="bookmark" title="How to Delete Nodes from Binary Tree and Make a Forest?">How to Delete Nodes from Binary Tree and Make a Forest?</a> <small>Given the root of a binary tree, each node in the tree has a distinct...</small></li>
<li><a href="https://helloacm.com/simple-investment-strategy-regular-investment-in-bitcoin-btc-dollar-cost-averaging/" rel="bookmark" title="Simple investment strategy: regular investment in Bitcoin/BTC (Dollar Cost Averaging)">Simple investment strategy: regular investment in Bitcoin/BTC (Dollar Cost Averaging)</a> <small>That day, I came across a post on LinkedIn: A person consistently purchased $30 worth...</small></li>
<li><a href="https://helloacm.com/the-hidden-engine-of-performance-its-all-about-where-the-data-lives-cache-is-the-king/" rel="bookmark" title="The Hidden Engine of Performance: It’s All About Where the Data Lives (Cache is the King)">The Hidden Engine of Performance: It’s All About Where the Data Lives (Cache is the King)</a> <small>The Hidden Engine of Performance: It’s All About Where the Data Lives 1. The Real...</small></li>
<li><a href="https://helloacm.com/how-to-get-free-https-certificates-via-acme-sh/" rel="bookmark" title="How to Get Free HTTPS Certificates via acme.sh?">How to Get Free HTTPS Certificates via acme.sh?</a> <small>Let&#8217;s Encrypt provides HTTPS Certificates if you are already using CloudFlare which also manages/issues the...</small></li>
<li><a href="https://helloacm.com/using-reduce-to-count-the-array-in-javascript/" rel="bookmark" title="Using Reduce to Count the Array in Javascript">Using Reduce to Count the Array in Javascript</a> <small>Let&#8217;s say, we have an array in Javascript, and we want to group the elements,...</small></li>
<li><a href="https://helloacm.com/integrating-chatgpt-prompt-ai-to-steem-blockchain/" rel="bookmark" title="Integrating ChatGPT Prompt AI to STEEM blockchain">Integrating ChatGPT Prompt AI to STEEM blockchain</a> <small>Type &#8220;!ask&#8221; following a space + the question on the STEEM blockchain. Currently the ChatGPT...</small></li>
<li><a href="https://helloacm.com/simple-and-fast-hash-functions-in-delphi/" rel="bookmark" title="Simple and Fast Hash Functions in Delphi">Simple and Fast Hash Functions in Delphi</a> <small>A Hash function returns a 32-bit (or sometimes 64-bit) integers for any given length of...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[Fan-out/fan-in refers to the pattern of executing multiple units of work in <a href="https://helloacm.com/why-parallelism-isnt-infinite-amdahl-vs-gustafson-explained-simply/" title="Why Parallelism Isn’t Infinite: Amdahl vs Gustafson Explained Simply">parallel</a> and then synchronizing on their completion. While it’s often discussed in the context of serverless functions, the concept is not limited to them. 

More generally, fan-out/fan-in describes a <a href="https://helloacm.com/implement-a-lock-acquire-and-release-in-c/" title="Implement a Lock Acquire and Release in C++">concurrency</a> pattern that can be applied wherever tasks can be decomposed into independent pieces—such as threads, processes, actors, microservices, or even distributed jobs—executed concurrently and later aggregated into a single result. The key idea is the separation of work into parallel branches (fan-out) and the coordinated collection of their outputs (fan-in), regardless of the underlying execution model or infrastructure.

[caption id="attachment_157733" align="alignnone" width="1653"]<a href="https://helloacm.com/system-design-fan-out-fan-in-pattern/design-concept-fan-out-fan-in/" rel="attachment wp-att-157733"><img src="https://helloacm.com/wp-content/uploads/2026/01/design-concept-fan-out-fan-in.jpg" alt="Fan-out and Fan-in Design Pattern" width="1653" height="1068" class="size-full wp-image-157733" /></a> Fan-out and Fan-in Design Pattern[/caption]

In practical engineering, the fan-out / fan-in pattern is commonly used to improve system throughput and resource utilization, especially in I/O-bound or highly parallelizable scenarios. By decomposing a complex task into multiple independent subtasks and executing them concurrently, the overall processing time can be significantly reduced. During the fan-in phase, the results of these subtasks are aggregated, ordered, or merged in a unified manner, helping to preserve the integrity and consistency of the business logic. However, this pattern also requires careful attention to concurrency control, error handling, as well as timeout and retry mechanisms; otherwise, high levels of parallelism may introduce resource contention, cascading failures, or inconsistent results. Therefore, when designing and implementing a fan-out / fan-in architecture, it is important to balance the degree of concurrency against system complexity and overall stability.

[show_file file="/var/www/wp-post-common/helloacm.com/design.php"]<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/teaching-kids-programming-another-bfs-to-generate-binary-strings-without-adjacent-zeros/" rel="bookmark" title="Teaching Kids Programming &#8211; Another BFS to Generate Binary Strings Without Adjacent Zeros">Teaching Kids Programming &#8211; Another BFS to Generate Binary Strings Without Adjacent Zeros</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given a positive integer...</small></li>
<li><a href="https://helloacm.com/how-to-delete-nodes-from-binary-tree-and-make-a-forest/" rel="bookmark" title="How to Delete Nodes from Binary Tree and Make a Forest?">How to Delete Nodes from Binary Tree and Make a Forest?</a> <small>Given the root of a binary tree, each node in the tree has a distinct...</small></li>
<li><a href="https://helloacm.com/simple-investment-strategy-regular-investment-in-bitcoin-btc-dollar-cost-averaging/" rel="bookmark" title="Simple investment strategy: regular investment in Bitcoin/BTC (Dollar Cost Averaging)">Simple investment strategy: regular investment in Bitcoin/BTC (Dollar Cost Averaging)</a> <small>That day, I came across a post on LinkedIn: A person consistently purchased $30 worth...</small></li>
<li><a href="https://helloacm.com/the-hidden-engine-of-performance-its-all-about-where-the-data-lives-cache-is-the-king/" rel="bookmark" title="The Hidden Engine of Performance: It’s All About Where the Data Lives (Cache is the King)">The Hidden Engine of Performance: It’s All About Where the Data Lives (Cache is the King)</a> <small>The Hidden Engine of Performance: It’s All About Where the Data Lives 1. The Real...</small></li>
<li><a href="https://helloacm.com/how-to-get-free-https-certificates-via-acme-sh/" rel="bookmark" title="How to Get Free HTTPS Certificates via acme.sh?">How to Get Free HTTPS Certificates via acme.sh?</a> <small>Let&#8217;s Encrypt provides HTTPS Certificates if you are already using CloudFlare which also manages/issues the...</small></li>
<li><a href="https://helloacm.com/using-reduce-to-count-the-array-in-javascript/" rel="bookmark" title="Using Reduce to Count the Array in Javascript">Using Reduce to Count the Array in Javascript</a> <small>Let&#8217;s say, we have an array in Javascript, and we want to group the elements,...</small></li>
<li><a href="https://helloacm.com/integrating-chatgpt-prompt-ai-to-steem-blockchain/" rel="bookmark" title="Integrating ChatGPT Prompt AI to STEEM blockchain">Integrating ChatGPT Prompt AI to STEEM blockchain</a> <small>Type &#8220;!ask&#8221; following a space + the question on the STEEM blockchain. Currently the ChatGPT...</small></li>
<li><a href="https://helloacm.com/simple-and-fast-hash-functions-in-delphi/" rel="bookmark" title="Simple and Fast Hash Functions in Delphi">Simple and Fast Hash Functions in Delphi</a> <small>A Hash function returns a 32-bit (or sometimes 64-bit) integers for any given length of...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://helloacm.com/system-design-fan-out-fan-in-pattern/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>ChatGPT: New Image Creation (art school)</title>
		<link>https://helloacm.com/chatgpt-new-image-creation-art-school/</link>
					<comments>https://helloacm.com/chatgpt-new-image-creation-art-school/#respond</comments>
		
		<dc:creator><![CDATA[ACMer]]></dc:creator>
		<pubDate>Mon, 05 Jan 2026 16:48:37 +0000</pubDate>
				<category><![CDATA[AGI: Artificial General Intelligence]]></category>
		<category><![CDATA[Artificial Intelligence]]></category>
		<category><![CDATA[ChatGPT (OpenAI)]]></category>
		<category><![CDATA[Image to Image]]></category>
		<category><![CDATA[images]]></category>
		<category><![CDATA[Prompt]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[artificial intelligence]]></category>
		<category><![CDATA[ChatGPT]]></category>
		<category><![CDATA[Image Generation]]></category>
		<category><![CDATA[Photo]]></category>
		<category><![CDATA[Pretty Girl]]></category>
		<category><![CDATA[Prompt Engineering]]></category>
		<category><![CDATA[School Art]]></category>
		<category><![CDATA[Transform]]></category>
		<guid isPermaLink="false">https://helloacm.com/?p=157689</guid>

					<description><![CDATA[<a href="https://helloacm.com/chatgpt-use-case-for-software-engineer-review-pull-requests-code-reviews/" title="ChatGPT Use Case for Software Engineer: Review Pull Requests (Code Reviews)">ChatGPT</a> has a new feature "Image Generation" which allows you to easily transform exist images with a predefined set of prompts.

You then don't need to prepare the prompts. Rather, all you need is to select an image and a pre-defined "style" which contains the prompt. 

<h4>Click "Images" from Left Navigation Bar</h4>
[caption id="attachment_157692" align="alignnone" width="1318"]<a href="https://helloacm.com/chatgpt-new-image-creation-art-school/chatgpt-new-image-generation/" rel="attachment wp-att-157692"><img src="https://helloacm.com/wp-content/uploads/2026/01/chatgpt-new-image-generation.jpg" alt="ChatGPT&#039;s new Image Generation Feature." width="1318" height="760" class="size-full wp-image-157692" /></a> ChatGPT's new Image Generation Feature.[/caption]

<h4>Select Style and then a local Image to Upload</h4>

<h4>Prompt (Automatic)</h4>
The following Prompt is auto-inserted.

Using the provided image as reference, create a soft, understated image with an art-school aesthetic. If people are present, preserve their identity while using gentle natural light, muted colors, and a relaxed, slightly awkward pose and place them in a simple, everyday setting such as a studio, classroom, or quiet street. Otherwise, treat the scene or object as the subject or subjects, using gentle light, muted colors, and intimate framing.The mood should feel intimate, youthful, and casually artistic rather than polished or glamorous.

<h4>Original Picture</h4>
[caption id="attachment_157690" align="alignnone" width="936"]<a href="https://helloacm.com/chatgpt-new-image-creation-art-school/my-little-girl-2/" rel="attachment wp-att-157690"><img src="https://helloacm.com/wp-content/uploads/2026/01/my-little-girl.png" alt="Original Photo" width="936" height="1408" class="size-full wp-image-157690" /></a> Original Photo[/caption]

<h4>Generated Image Result</h4>
Much more realistic then the <a href="https://helloacm.com/ai-transforms-photos-into-ghibli-style-chatgpt-4o-costs-money-but-heres-a-free-method/" title="AI Transforms Photos into Ghibli Style? ChatGPT-4o Costs Money, But Here’s a Free Method!">Ghibli</a> style (which looks pure animation/comics)

[caption id="attachment_157691" align="alignnone" width="1024"]<a href="https://helloacm.com/chatgpt-new-image-creation-art-school/creative-pause-in-the-art-room/" rel="attachment wp-att-157691"><img src="https://helloacm.com/wp-content/uploads/2026/01/Creative-pause-in-the-art-room.png" alt="Transformed Image by ChatGPT (School Art): Creative Pause in the Art Room" width="1024" height="1536" class="size-full wp-image-157691" /></a> Transformed Image by ChatGPT (School Art): Creative Pause in the Art Room[/caption]

[show_file file="/var/www/wp-post-common/helloacm.com/prompt.php"]

Post: <a href="https://steemit.com/ai/@justyy/chatgpt-new-image-creation-art-school" title="ChatGPT: New Image Creation (art school)">ChatGPT: New Image Creation (art school)</a>

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/why-does-the-exchange-force-liquidation-when-the-margin-is-low/" rel="bookmark" title="Why does the exchange force liquidation when the margin is low?">Why does the exchange force liquidation when the margin is low?</a> <small>In the cryptocurrency market, as long as you don&#8217;t trade contracts, the risk is not...</small></li>
<li><a href="https://helloacm.com/free-giveaway-google-adwords-400-gbp-ads-credit/" rel="bookmark" title="Free Giveaway: Google Adwords 400 GBP Ads Credit">Free Giveaway: Google Adwords 400 GBP Ads Credit</a> <small>Long time ago, I have tried Google Adwords with some free credit from Google, but...</small></li>
<li><a href="https://helloacm.com/what-is-tcp-ip-4-layer-vs-osi-7-layer/" rel="bookmark" title="Software Engineer Interview Question: What is TCP/IP (4 Layer vs OSI 7 Layer)?">Software Engineer Interview Question: What is TCP/IP (4 Layer vs OSI 7 Layer)?</a> <small>Note: recently this has been asked in the first round of the technical interviews by...</small></li>
<li><a href="https://helloacm.com/the-system-design-of-steem-blockchain-bots/" rel="bookmark" title="The System Design of Steem Blockchain (ChatGPT DApps) Bots">The System Design of Steem Blockchain (ChatGPT DApps) Bots</a> <small>Yesterday, the ChatGPT has been integrated to Steem Blockchain, but the initial design has problems...</small></li>
<li><a href="https://helloacm.com/tron-blockchain-how-to-send-the-usdt-trc-20-transacton-using-python-tronpy/" rel="bookmark" title="TRON Blockchain: How to Send the USDT (TRC-20) Transacton using Python tronpy?">TRON Blockchain: How to Send the USDT (TRC-20) Transacton using Python tronpy?</a> <small>How to Send the USDT (TRC-20) Transacton using Python tronpy? To send a USDT (Tether)...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-algorithms-to-compute-the-minimum-string-length-after-removing-substrings-brute-force-stack/" rel="bookmark" title="Teaching Kids Programming &#8211; Algorithms to Compute the Minimum String Length After Removing Substrings (Brute Force + Stack)">Teaching Kids Programming &#8211; Algorithms to Compute the Minimum String Length After Removing Substrings (Brute Force + Stack)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given a string s...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-algorithms-to-solve-a-min-max-binary-tree-game/" rel="bookmark" title="Teaching Kids Programming &#8211; Algorithms to Solve a Min Max Binary Tree Game (Queue, Recursion, In-place)">Teaching Kids Programming &#8211; Algorithms to Solve a Min Max Binary Tree Game (Queue, Recursion, In-place)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given a 0-indexed integer...</small></li>
<li><a href="https://helloacm.com/introduction-to-8-bit-famicom-clone-subor-sb2000/" rel="bookmark" title="Introduction to 8-bit Famicom Clone &#8211; Subor &#8211; SB2000">Introduction to 8-bit Famicom Clone &#8211; Subor &#8211; SB2000</a> <small>Nintendo Entertainment System Family Game Console (often known as NES) was quite popular in 1980&#8217;s...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<a href="https://helloacm.com/chatgpt-use-case-for-software-engineer-review-pull-requests-code-reviews/" title="ChatGPT Use Case for Software Engineer: Review Pull Requests (Code Reviews)">ChatGPT</a> has a new feature "Image Generation" which allows you to easily transform exist images with a predefined set of prompts.

You then don't need to prepare the prompts. Rather, all you need is to select an image and a pre-defined "style" which contains the prompt. 

<h4>Click "Images" from Left Navigation Bar</h4>
[caption id="attachment_157692" align="alignnone" width="1318"]<a href="https://helloacm.com/chatgpt-new-image-creation-art-school/chatgpt-new-image-generation/" rel="attachment wp-att-157692"><img src="https://helloacm.com/wp-content/uploads/2026/01/chatgpt-new-image-generation.jpg" alt="ChatGPT&#039;s new Image Generation Feature." width="1318" height="760" class="size-full wp-image-157692" /></a> ChatGPT's new Image Generation Feature.[/caption]

<h4>Select Style and then a local Image to Upload</h4>

<h4>Prompt (Automatic)</h4>
The following Prompt is auto-inserted.

Using the provided image as reference, create a soft, understated image with an art-school aesthetic. If people are present, preserve their identity while using gentle natural light, muted colors, and a relaxed, slightly awkward pose and place them in a simple, everyday setting such as a studio, classroom, or quiet street. Otherwise, treat the scene or object as the subject or subjects, using gentle light, muted colors, and intimate framing.The mood should feel intimate, youthful, and casually artistic rather than polished or glamorous.

<h4>Original Picture</h4>
[caption id="attachment_157690" align="alignnone" width="936"]<a href="https://helloacm.com/chatgpt-new-image-creation-art-school/my-little-girl-2/" rel="attachment wp-att-157690"><img src="https://helloacm.com/wp-content/uploads/2026/01/my-little-girl.png" alt="Original Photo" width="936" height="1408" class="size-full wp-image-157690" /></a> Original Photo[/caption]

<h4>Generated Image Result</h4>
Much more realistic then the <a href="https://helloacm.com/ai-transforms-photos-into-ghibli-style-chatgpt-4o-costs-money-but-heres-a-free-method/" title="AI Transforms Photos into Ghibli Style? ChatGPT-4o Costs Money, But Here’s a Free Method!">Ghibli</a> style (which looks pure animation/comics)

[caption id="attachment_157691" align="alignnone" width="1024"]<a href="https://helloacm.com/chatgpt-new-image-creation-art-school/creative-pause-in-the-art-room/" rel="attachment wp-att-157691"><img src="https://helloacm.com/wp-content/uploads/2026/01/Creative-pause-in-the-art-room.png" alt="Transformed Image by ChatGPT (School Art): Creative Pause in the Art Room" width="1024" height="1536" class="size-full wp-image-157691" /></a> Transformed Image by ChatGPT (School Art): Creative Pause in the Art Room[/caption]

[show_file file="/var/www/wp-post-common/helloacm.com/prompt.php"]

Post: <a href="https://steemit.com/ai/@justyy/chatgpt-new-image-creation-art-school" title="ChatGPT: New Image Creation (art school)">ChatGPT: New Image Creation (art school)</a>

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/why-does-the-exchange-force-liquidation-when-the-margin-is-low/" rel="bookmark" title="Why does the exchange force liquidation when the margin is low?">Why does the exchange force liquidation when the margin is low?</a> <small>In the cryptocurrency market, as long as you don&#8217;t trade contracts, the risk is not...</small></li>
<li><a href="https://helloacm.com/free-giveaway-google-adwords-400-gbp-ads-credit/" rel="bookmark" title="Free Giveaway: Google Adwords 400 GBP Ads Credit">Free Giveaway: Google Adwords 400 GBP Ads Credit</a> <small>Long time ago, I have tried Google Adwords with some free credit from Google, but...</small></li>
<li><a href="https://helloacm.com/what-is-tcp-ip-4-layer-vs-osi-7-layer/" rel="bookmark" title="Software Engineer Interview Question: What is TCP/IP (4 Layer vs OSI 7 Layer)?">Software Engineer Interview Question: What is TCP/IP (4 Layer vs OSI 7 Layer)?</a> <small>Note: recently this has been asked in the first round of the technical interviews by...</small></li>
<li><a href="https://helloacm.com/the-system-design-of-steem-blockchain-bots/" rel="bookmark" title="The System Design of Steem Blockchain (ChatGPT DApps) Bots">The System Design of Steem Blockchain (ChatGPT DApps) Bots</a> <small>Yesterday, the ChatGPT has been integrated to Steem Blockchain, but the initial design has problems...</small></li>
<li><a href="https://helloacm.com/tron-blockchain-how-to-send-the-usdt-trc-20-transacton-using-python-tronpy/" rel="bookmark" title="TRON Blockchain: How to Send the USDT (TRC-20) Transacton using Python tronpy?">TRON Blockchain: How to Send the USDT (TRC-20) Transacton using Python tronpy?</a> <small>How to Send the USDT (TRC-20) Transacton using Python tronpy? To send a USDT (Tether)...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-algorithms-to-compute-the-minimum-string-length-after-removing-substrings-brute-force-stack/" rel="bookmark" title="Teaching Kids Programming &#8211; Algorithms to Compute the Minimum String Length After Removing Substrings (Brute Force + Stack)">Teaching Kids Programming &#8211; Algorithms to Compute the Minimum String Length After Removing Substrings (Brute Force + Stack)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given a string s...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-algorithms-to-solve-a-min-max-binary-tree-game/" rel="bookmark" title="Teaching Kids Programming &#8211; Algorithms to Solve a Min Max Binary Tree Game (Queue, Recursion, In-place)">Teaching Kids Programming &#8211; Algorithms to Solve a Min Max Binary Tree Game (Queue, Recursion, In-place)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given a 0-indexed integer...</small></li>
<li><a href="https://helloacm.com/introduction-to-8-bit-famicom-clone-subor-sb2000/" rel="bookmark" title="Introduction to 8-bit Famicom Clone &#8211; Subor &#8211; SB2000">Introduction to 8-bit Famicom Clone &#8211; Subor &#8211; SB2000</a> <small>Nintendo Entertainment System Family Game Console (often known as NES) was quite popular in 1980&#8217;s...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://helloacm.com/chatgpt-new-image-creation-art-school/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Understanding std::transform_reduce in Modern C++</title>
		<link>https://helloacm.com/understanding-stdtransform_reduce-in-modern-c/</link>
					<comments>https://helloacm.com/understanding-stdtransform_reduce-in-modern-c/#respond</comments>
		
		<dc:creator><![CDATA[ACMer]]></dc:creator>
		<pubDate>Thu, 18 Dec 2025 13:28:53 +0000</pubDate>
				<category><![CDATA[algorithms]]></category>
		<category><![CDATA[c / c++]]></category>
		<category><![CDATA[C/C++]]></category>
		<category><![CDATA[parallel computing]]></category>
		<category><![CDATA[programming languages]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[C++17]]></category>
		<category><![CDATA[C++20]]></category>
		<category><![CDATA[dot product]]></category>
		<category><![CDATA[modern C++]]></category>
		<category><![CDATA[parallel algorithms]]></category>
		<category><![CDATA[ranges]]></category>
		<category><![CDATA[std::transform_reduce]]></category>
		<category><![CDATA[STL]]></category>
		<category><![CDATA[sum of squares]]></category>
		<category><![CDATA[transform_reduce]]></category>
		<guid isPermaLink="false">https://helloacm.com/?p=157669</guid>

					<description><![CDATA[<h2>Understanding <code>std::transform_reduce</code> in Modern C++</h2>
<code>std::transform_reduce</code> is a powerful C++17 algorithm that combines the functionality of <code>transform</code> and <code>reduce</code> (or <code>accumulate</code>) in a single pass. It allows you to apply a <a href="https://helloacm.com/modern-c-language-features/" title="Modern C++ Language Features">transformation</a> to elements and then reduce them using a binary operation, which can help write concise and efficient code.

<h3>Syntax</h3>
<pre lang=c>
template&lt;class InputIt1, class InputIt2, class T,
         class BinaryOp1, class BinaryOp2&gt;
T transform_reduce(InputIt1 first1, InputIt1 last1,
                   InputIt2 first2, T init,
                   BinaryOp1 binary_op1,
                   BinaryOp2 binary_op2);

template&lt;class InputIt, class T,
         class BinaryOp1, class UnaryOp&gt;
T transform_reduce(InputIt first, InputIt last,
                   T init,
                   BinaryOp1 binary_op1,
                   UnaryOp unary_op);
</pre>

In simple words:
<ul>
    <li>It applies a <strong>unary transformation</strong> to each element (optional).</li>
    <li>Then it reduces all results using a <strong>binary operation</strong> like sum, product, or custom combination.</li>
    <li>It can work in <strong>parallel</strong> with execution policies in C++17/20.</li>
</ul>

<h3>Example 1: Sum of squares</h3>
<pre lang=c>
#include &lt;iostream&gt;
#include &lt;vector&gt;
#include &lt;numeric&gt;
#include &lt;execution&gt;

int main() {
    std::vector&lt;int&gt; numbers = {1, 2, 3, 4, 5};

    int sum_of_squares = std::transform_reduce(
        std::execution::seq,   // sequential execution
        numbers.begin(),
        numbers.end(),
        0,                     // initial value
        std::plus&lt;&gt;(),    // binary operation (sum)
        [](int x){ return x*x; } // unary transform (square)
    );

    std::cout &lt;&lt; "Sum of squares: " &lt;&lt; sum_of_squares &lt;&lt; std::endl;
    return 0;
}
</pre>

<h3>Example 2: Dot product of two vectors</h3>
<pre lang=c>
#include &lt;iostream&gt;
#include &lt;vector&gt;
#include &lt;numeric&gt;

int main() {
    std::vector&lt;int&gt; a = {1, 2, 3};
    std::vector&lt;int&gt; b = {4, 5, 6};

    int dot_product = std::transform_reduce(
        a.begin(), a.end(),
        b.begin(),
        0  // initial value
    );

    std::cout &lt;&lt; "Dot product: " &lt;&lt; dot_product &lt;&lt; std::endl;
    return 0;
}
</pre>

<h3>Example 3: Parallel transform_reduce</h3>
<pre lang=c>
#include &lt;iostream&gt;
#include &lt;vector&gt;
#include &lt;numeric&gt;
#include &lt;execution&gt;

int main() {
    std::vector&lt;double&gt; numbers(1'000'000, 1.5);

    double sum = std::transform_reduce(
        std::execution::par,  // parallel execution
        numbers.begin(),
        numbers.end(),
        0.0
    );

    std::cout &lt;&lt; "Parallel sum: " &lt;&lt; sum &lt;&lt; std::endl;
    return 0;
}
</pre>

<h3>Key Points</h3>
<ul>
    <li><code>transform_reduce</code> avoids creating an intermediate <a href="https://helloacm.com/reclaiming-the-disk-space-by-deleting-the-logs-of-the-docker-container/" title="Reclaiming the Disk Space by Deleting the Logs of the Docker Container">container</a> for the transformed values.</li>
    <li>It supports <strong>sequential</strong> and <strong>parallel</strong> execution policies.</li>
    <li>Two main forms: single range with unary transform, or two ranges for pairwise operations (like dot product).</li>
    <li>Initial value is required to correctly handle empty ranges.</li>
</ul>

Using <code>std::transform_reduce</code> can make your code cleaner and more efficient, especially for large datasets or parallel computation scenarios.

[show_file file="/var/www/wp-post-common/helloacm.com/cpp.php"]

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/comparisions-of-push_back-and-emplace_back-in-c-stdvector/" rel="bookmark" title="Comparisions of push_back and emplace_back in C++ std::vector">Comparisions of push_back and emplace_back in C++ std::vector</a> <small>In C++, both push_back and emplace_back are methods of the std::vector class used to add...</small></li>
<li><a href="https://helloacm.com/tutorial-on-c-smart-pointers/" rel="bookmark" title="Tutorial on C++ Smart Pointers">Tutorial on C++ Smart Pointers</a> <small>Tutorial on Smart Pointers in C++ Smart pointers in C++ provide automatic and safe memory...</small></li>
<li><a href="https://helloacm.com/const-vs-constexpr-in-c/" rel="bookmark" title="const vs constexpr in C++">const vs constexpr in C++</a> <small>C++ const vs constexpr: What’s the Real Difference? Both are used in C++ to define...</small></li>
<li><a href="https://helloacm.com/interview-coding-exercise-nested-string-python/" rel="bookmark" title="Interview Coding Exercise &#8211; Nested String (Python)">Interview Coding Exercise &#8211; Nested String (Python)</a> <small>Nested String A string S consisting of N characters is considered to be properly nested...</small></li>
<li><a href="https://helloacm.com/two-pointer-and-sliding-window-algorithm-to-find-k-length-substrings-with-no-repeated-characters/" rel="bookmark" title="Two Pointer and Sliding Window Algorithm to Find K-Length Substrings With No Repeated Characters">Two Pointer and Sliding Window Algorithm to Find K-Length Substrings With No Repeated Characters</a> <small>Given a string S, return the number of substrings of length K with no repeated...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-delete-nodes-from-linked-list-present-in-array/" rel="bookmark" title="Teaching Kids Programming &#8211; Delete Nodes From Linked List Present in Array">Teaching Kids Programming &#8211; Delete Nodes From Linked List Present in Array</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given an array of...</small></li>
<li><a href="https://helloacm.com/from-idea-to-github-pages-building-tools-with-ai-and-vibe-coding/" rel="bookmark" title="From Idea to GitHub Pages: Building Tools with AI and Vibe Coding">From Idea to GitHub Pages: Building Tools with AI and Vibe Coding</a> <small>Built and Open-Sourced A Few Mini Tools with AI Recently, I used ChatGPT-4o and o4-mini...</small></li>
<li><a href="https://helloacm.com/sql-coding-exercise-delete-duplicate-emails/" rel="bookmark" title="SQL Coding Exercise &#8211; Delete Duplicate Emails">SQL Coding Exercise &#8211; Delete Duplicate Emails</a> <small>Write a SQL query to delete all duplicate email entries in a table named Person,...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<h2>Understanding <code>std::transform_reduce</code> in Modern C++</h2>
<code>std::transform_reduce</code> is a powerful C++17 algorithm that combines the functionality of <code>transform</code> and <code>reduce</code> (or <code>accumulate</code>) in a single pass. It allows you to apply a <a href="https://helloacm.com/modern-c-language-features/" title="Modern C++ Language Features">transformation</a> to elements and then reduce them using a binary operation, which can help write concise and efficient code.

<h3>Syntax</h3>
<pre lang=c>
template&lt;class InputIt1, class InputIt2, class T,
         class BinaryOp1, class BinaryOp2&gt;
T transform_reduce(InputIt1 first1, InputIt1 last1,
                   InputIt2 first2, T init,
                   BinaryOp1 binary_op1,
                   BinaryOp2 binary_op2);

template&lt;class InputIt, class T,
         class BinaryOp1, class UnaryOp&gt;
T transform_reduce(InputIt first, InputIt last,
                   T init,
                   BinaryOp1 binary_op1,
                   UnaryOp unary_op);
</pre>

In simple words:
<ul>
    <li>It applies a <strong>unary transformation</strong> to each element (optional).</li>
    <li>Then it reduces all results using a <strong>binary operation</strong> like sum, product, or custom combination.</li>
    <li>It can work in <strong>parallel</strong> with execution policies in C++17/20.</li>
</ul>

<h3>Example 1: Sum of squares</h3>
<pre lang=c>
#include &lt;iostream&gt;
#include &lt;vector&gt;
#include &lt;numeric&gt;
#include &lt;execution&gt;

int main() {
    std::vector&lt;int&gt; numbers = {1, 2, 3, 4, 5};

    int sum_of_squares = std::transform_reduce(
        std::execution::seq,   // sequential execution
        numbers.begin(),
        numbers.end(),
        0,                     // initial value
        std::plus&lt;&gt;(),    // binary operation (sum)
        [](int x){ return x*x; } // unary transform (square)
    );

    std::cout &lt;&lt; "Sum of squares: " &lt;&lt; sum_of_squares &lt;&lt; std::endl;
    return 0;
}
</pre>

<h3>Example 2: Dot product of two vectors</h3>
<pre lang=c>
#include &lt;iostream&gt;
#include &lt;vector&gt;
#include &lt;numeric&gt;

int main() {
    std::vector&lt;int&gt; a = {1, 2, 3};
    std::vector&lt;int&gt; b = {4, 5, 6};

    int dot_product = std::transform_reduce(
        a.begin(), a.end(),
        b.begin(),
        0  // initial value
    );

    std::cout &lt;&lt; "Dot product: " &lt;&lt; dot_product &lt;&lt; std::endl;
    return 0;
}
</pre>

<h3>Example 3: Parallel transform_reduce</h3>
<pre lang=c>
#include &lt;iostream&gt;
#include &lt;vector&gt;
#include &lt;numeric&gt;
#include &lt;execution&gt;

int main() {
    std::vector&lt;double&gt; numbers(1'000'000, 1.5);

    double sum = std::transform_reduce(
        std::execution::par,  // parallel execution
        numbers.begin(),
        numbers.end(),
        0.0
    );

    std::cout &lt;&lt; "Parallel sum: " &lt;&lt; sum &lt;&lt; std::endl;
    return 0;
}
</pre>

<h3>Key Points</h3>
<ul>
    <li><code>transform_reduce</code> avoids creating an intermediate <a href="https://helloacm.com/reclaiming-the-disk-space-by-deleting-the-logs-of-the-docker-container/" title="Reclaiming the Disk Space by Deleting the Logs of the Docker Container">container</a> for the transformed values.</li>
    <li>It supports <strong>sequential</strong> and <strong>parallel</strong> execution policies.</li>
    <li>Two main forms: single range with unary transform, or two ranges for pairwise operations (like dot product).</li>
    <li>Initial value is required to correctly handle empty ranges.</li>
</ul>

Using <code>std::transform_reduce</code> can make your code cleaner and more efficient, especially for large datasets or parallel computation scenarios.

[show_file file="/var/www/wp-post-common/helloacm.com/cpp.php"]

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/comparisions-of-push_back-and-emplace_back-in-c-stdvector/" rel="bookmark" title="Comparisions of push_back and emplace_back in C++ std::vector">Comparisions of push_back and emplace_back in C++ std::vector</a> <small>In C++, both push_back and emplace_back are methods of the std::vector class used to add...</small></li>
<li><a href="https://helloacm.com/tutorial-on-c-smart-pointers/" rel="bookmark" title="Tutorial on C++ Smart Pointers">Tutorial on C++ Smart Pointers</a> <small>Tutorial on Smart Pointers in C++ Smart pointers in C++ provide automatic and safe memory...</small></li>
<li><a href="https://helloacm.com/const-vs-constexpr-in-c/" rel="bookmark" title="const vs constexpr in C++">const vs constexpr in C++</a> <small>C++ const vs constexpr: What’s the Real Difference? Both are used in C++ to define...</small></li>
<li><a href="https://helloacm.com/interview-coding-exercise-nested-string-python/" rel="bookmark" title="Interview Coding Exercise &#8211; Nested String (Python)">Interview Coding Exercise &#8211; Nested String (Python)</a> <small>Nested String A string S consisting of N characters is considered to be properly nested...</small></li>
<li><a href="https://helloacm.com/two-pointer-and-sliding-window-algorithm-to-find-k-length-substrings-with-no-repeated-characters/" rel="bookmark" title="Two Pointer and Sliding Window Algorithm to Find K-Length Substrings With No Repeated Characters">Two Pointer and Sliding Window Algorithm to Find K-Length Substrings With No Repeated Characters</a> <small>Given a string S, return the number of substrings of length K with no repeated...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-delete-nodes-from-linked-list-present-in-array/" rel="bookmark" title="Teaching Kids Programming &#8211; Delete Nodes From Linked List Present in Array">Teaching Kids Programming &#8211; Delete Nodes From Linked List Present in Array</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given an array of...</small></li>
<li><a href="https://helloacm.com/from-idea-to-github-pages-building-tools-with-ai-and-vibe-coding/" rel="bookmark" title="From Idea to GitHub Pages: Building Tools with AI and Vibe Coding">From Idea to GitHub Pages: Building Tools with AI and Vibe Coding</a> <small>Built and Open-Sourced A Few Mini Tools with AI Recently, I used ChatGPT-4o and o4-mini...</small></li>
<li><a href="https://helloacm.com/sql-coding-exercise-delete-duplicate-emails/" rel="bookmark" title="SQL Coding Exercise &#8211; Delete Duplicate Emails">SQL Coding Exercise &#8211; Delete Duplicate Emails</a> <small>Write a SQL query to delete all duplicate email entries in a table named Person,...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://helloacm.com/understanding-stdtransform_reduce-in-modern-c/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>WordPress: How to Output Full Text in the Feed?</title>
		<link>https://helloacm.com/wordpress-how-to-output-full-text-in-the-feed/</link>
					<comments>https://helloacm.com/wordpress-how-to-output-full-text-in-the-feed/#respond</comments>
		
		<dc:creator><![CDATA[ACMer]]></dc:creator>
		<pubDate>Mon, 01 Dec 2025 01:17:26 +0000</pubDate>
				<category><![CDATA[php]]></category>
		<category><![CDATA[wordpress]]></category>
		<category><![CDATA[excerpt]]></category>
		<category><![CDATA[feed]]></category>
		<category><![CDATA[functions.php]]></category>
		<category><![CDATA[output full text]]></category>
		<category><![CDATA[plugins]]></category>
		<category><![CDATA[rss feed]]></category>
		<category><![CDATA[settings]]></category>
		<guid isPermaLink="false">https://helloacm.com/?p=157657</guid>

					<description><![CDATA[<blockquote>
How to Make WordPress RSS /feed Output Full Text
WordPress RSS Full Content Output Guide
How to Show Full Text in WordPress RSS Feeds
WordPress: Three Ways to Output Full Content in RSS Feeds
A Complete Guide to Enabling Full Text Output in WordPress /feed
RSS Only Shows Excerpts? How to Switch to Full Text (Settings/Code/Plugins)
Configuring Full Text Output in WordPress RSS: Settings, Code, and Plugin Methods
How to Force WordPress RSS to Display Full Content (functions.php Included)
Improve Subscription Experience: WordPress Solutions for Full Text RSS Output
Optimizing WordPress RSS Feeds: Best Practices for Enabling Full Content Output
</blockquote>

In <a href="https://helloacm.com/php7-x-is-deprecated-by-wordpress-why-you-should-upgrade-to-php8-x/" title="PHP7.x is deprecated by WordPress: Why You Should Upgrade to PHP8.x?">WordPress</a>, whether the /feed (RSS feed) outputs full text or just an excerpt is controlled in Settings → Reading, and can also be customized via code or plugins. Here's a step-by-step guide:

<h3>Change via WordPress Settings</h3>
<ol>
<li>Go to WordPress Admin → Settings → Reading.</li>
<li>Look for “For each article in a feed, show”.</li>
<li>You’ll see two options: Full text and Summary</li>
<li>Select Full text to ensure /feed outputs the full post content.</li>
<li>Click Save Changes.</li>
</ol>

[caption id="attachment_157659" align="alignnone" width="961"]<a href="https://helloacm.com/wordpress-how-to-output-full-text-in-the-feed/wordpress-output-full-text-feed/" rel="attachment wp-att-157659"><img src="https://helloacm.com/wp-content/uploads/2025/12/wordpress-output-full-text-feed.jpg" alt="Wordpress - Change to Output Full Text in Admin - Settings - Reading" width="961" height="762" class="size-full wp-image-157659" /></a> Wordpress - Change to Output Full Text in Admin - Settings - Reading[/caption]

This setting affects the default WordPress RSS feed (/feed).

<h3>Change via Theme (if settings not respected)</h3>
Some themes override feed output. To force full content:

Open your theme’s functions.php.

Add the following <a href="https://helloacm.com/php-code-to-redirect-with-302-and-a-referer/" title="PHP Code to Redirect with 302 and a Referer">PHP code</a>.
<pre lang=php>
// Force RSS feed to show full content
function my_full_feed_content($content) {
    return get_the_content();
}

add_filter('the_excerpt_rss', 'my_full_feed_content');
add_filter('the_content_feed', 'my_full_feed_content');
</pre>

This ensures both RSS excerpts and content feeds use full post content.

<h3>Change via Plugins</h3>
If you prefer not to touch code: Plugins like “RSS Feed Control” or “WP RSS Aggregator” let you customize feed content length, full text, and formatting.

💡 Tip: After changes, test your feed at /feed or /feed/rss2/ to confirm it outputs the full text. Some caching plugins may require clearing cache.

PS: This blog is switched to full text in the feed.

[show_file file="/var/www/wp-post-common/helloacm.com/wordpress.php"]

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/nvidia-im-coming-again-this-time-im-tougher/" rel="bookmark" title="Nvidia, I’m coming again — this time I’m tougher">Nvidia, I’m coming again — this time I’m tougher</a> <small>Friends who know me well know that I have been persistently interviewing, but now I...</small></li>
<li><a href="https://helloacm.com/trie-class-data-structure-in-python/" rel="bookmark" title="Trie Class Data Structure in Python">Trie Class Data Structure in Python</a> <small>Implement a trie with insert, search, and startsWith methods. Example: Trie trie = new Trie();...</small></li>
<li><a href="https://helloacm.com/laptop-battery-power-drained-but-failed-to-sleep-on-microsoft-windows-surface-studio-pro/" rel="bookmark" title="Laptop Battery Power Drained But Failed to Sleep on Microsoft Windows Surface Studio Pro">Laptop Battery Power Drained But Failed to Sleep on Microsoft Windows Surface Studio Pro</a> <small>I am surprised to find out that my laptop is switched off this morning &#8211;...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-algorithmic-runtime-and-space-complexity/" rel="bookmark" title="Teaching Kids Programming &#8211; Algorithmic Runtime and Space Complexity">Teaching Kids Programming &#8211; Algorithmic Runtime and Space Complexity</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms We analyse an algorithm for its...</small></li>
<li><a href="https://helloacm.com/how-to-parallel-for-in-linux-bash-shell/" rel="bookmark" title="How to Parallel For in Linux Bash Shell?">How to Parallel For in Linux Bash Shell?</a> <small>The Linux Bash Shell supports inherent task parallelism. For example, you can put a &#038;...</small></li>
<li><a href="https://helloacm.com/algorithms-to-find-the-three-numbers-in-array-that-sum-up-to-zero-3sum/" rel="bookmark" title="Algorithms to Find the Three Numbers in Array that Sum up to Zero (3Sum)">Algorithms to Find the Three Numbers in Array that Sum up to Zero (3Sum)</a> <small>Given an array nums of n integers, are there elements a, b, c in nums...</small></li>
<li><a href="https://helloacm.com/using-absolute-keyword-in-delphi-to-remove-unnecessary-assignment-function/" rel="bookmark" title="Using Absolute Keyword in Delphi to Remove Unnecessary Assignment Function">Using Absolute Keyword in Delphi to Remove Unnecessary Assignment Function</a> <small>The Delphi/Object Pascal provides a keyword absolute, which you can also find examples at this...</small></li>
<li><a href="https://helloacm.com/how-to-find-largest-value-in-each-tree-row-level-using-bfs-or-dfs-algorithm/" rel="bookmark" title="How to Find Largest Value in Each Tree Row/Level using BFS or DFS Algorithm?">How to Find Largest Value in Each Tree Row/Level using BFS or DFS Algorithm?</a> <small>You need to find the largest value in each row of a binary tree. Example:...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<blockquote>
How to Make WordPress RSS /feed Output Full Text
WordPress RSS Full Content Output Guide
How to Show Full Text in WordPress RSS Feeds
WordPress: Three Ways to Output Full Content in RSS Feeds
A Complete Guide to Enabling Full Text Output in WordPress /feed
RSS Only Shows Excerpts? How to Switch to Full Text (Settings/Code/Plugins)
Configuring Full Text Output in WordPress RSS: Settings, Code, and Plugin Methods
How to Force WordPress RSS to Display Full Content (functions.php Included)
Improve Subscription Experience: WordPress Solutions for Full Text RSS Output
Optimizing WordPress RSS Feeds: Best Practices for Enabling Full Content Output
</blockquote>

In <a href="https://helloacm.com/php7-x-is-deprecated-by-wordpress-why-you-should-upgrade-to-php8-x/" title="PHP7.x is deprecated by WordPress: Why You Should Upgrade to PHP8.x?">WordPress</a>, whether the /feed (RSS feed) outputs full text or just an excerpt is controlled in Settings → Reading, and can also be customized via code or plugins. Here's a step-by-step guide:

<h3>Change via WordPress Settings</h3>
<ol>
<li>Go to WordPress Admin → Settings → Reading.</li>
<li>Look for “For each article in a feed, show”.</li>
<li>You’ll see two options: Full text and Summary</li>
<li>Select Full text to ensure /feed outputs the full post content.</li>
<li>Click Save Changes.</li>
</ol>

[caption id="attachment_157659" align="alignnone" width="961"]<a href="https://helloacm.com/wordpress-how-to-output-full-text-in-the-feed/wordpress-output-full-text-feed/" rel="attachment wp-att-157659"><img src="https://helloacm.com/wp-content/uploads/2025/12/wordpress-output-full-text-feed.jpg" alt="Wordpress - Change to Output Full Text in Admin - Settings - Reading" width="961" height="762" class="size-full wp-image-157659" /></a> Wordpress - Change to Output Full Text in Admin - Settings - Reading[/caption]

This setting affects the default WordPress RSS feed (/feed).

<h3>Change via Theme (if settings not respected)</h3>
Some themes override feed output. To force full content:

Open your theme’s functions.php.

Add the following <a href="https://helloacm.com/php-code-to-redirect-with-302-and-a-referer/" title="PHP Code to Redirect with 302 and a Referer">PHP code</a>.
<pre lang=php>
// Force RSS feed to show full content
function my_full_feed_content($content) {
    return get_the_content();
}

add_filter('the_excerpt_rss', 'my_full_feed_content');
add_filter('the_content_feed', 'my_full_feed_content');
</pre>

This ensures both RSS excerpts and content feeds use full post content.

<h3>Change via Plugins</h3>
If you prefer not to touch code: Plugins like “RSS Feed Control” or “WP RSS Aggregator” let you customize feed content length, full text, and formatting.

💡 Tip: After changes, test your feed at /feed or /feed/rss2/ to confirm it outputs the full text. Some caching plugins may require clearing cache.

PS: This blog is switched to full text in the feed.

[show_file file="/var/www/wp-post-common/helloacm.com/wordpress.php"]

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/nvidia-im-coming-again-this-time-im-tougher/" rel="bookmark" title="Nvidia, I’m coming again — this time I’m tougher">Nvidia, I’m coming again — this time I’m tougher</a> <small>Friends who know me well know that I have been persistently interviewing, but now I...</small></li>
<li><a href="https://helloacm.com/trie-class-data-structure-in-python/" rel="bookmark" title="Trie Class Data Structure in Python">Trie Class Data Structure in Python</a> <small>Implement a trie with insert, search, and startsWith methods. Example: Trie trie = new Trie();...</small></li>
<li><a href="https://helloacm.com/laptop-battery-power-drained-but-failed-to-sleep-on-microsoft-windows-surface-studio-pro/" rel="bookmark" title="Laptop Battery Power Drained But Failed to Sleep on Microsoft Windows Surface Studio Pro">Laptop Battery Power Drained But Failed to Sleep on Microsoft Windows Surface Studio Pro</a> <small>I am surprised to find out that my laptop is switched off this morning &#8211;...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-algorithmic-runtime-and-space-complexity/" rel="bookmark" title="Teaching Kids Programming &#8211; Algorithmic Runtime and Space Complexity">Teaching Kids Programming &#8211; Algorithmic Runtime and Space Complexity</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms We analyse an algorithm for its...</small></li>
<li><a href="https://helloacm.com/how-to-parallel-for-in-linux-bash-shell/" rel="bookmark" title="How to Parallel For in Linux Bash Shell?">How to Parallel For in Linux Bash Shell?</a> <small>The Linux Bash Shell supports inherent task parallelism. For example, you can put a &#038;...</small></li>
<li><a href="https://helloacm.com/algorithms-to-find-the-three-numbers-in-array-that-sum-up-to-zero-3sum/" rel="bookmark" title="Algorithms to Find the Three Numbers in Array that Sum up to Zero (3Sum)">Algorithms to Find the Three Numbers in Array that Sum up to Zero (3Sum)</a> <small>Given an array nums of n integers, are there elements a, b, c in nums...</small></li>
<li><a href="https://helloacm.com/using-absolute-keyword-in-delphi-to-remove-unnecessary-assignment-function/" rel="bookmark" title="Using Absolute Keyword in Delphi to Remove Unnecessary Assignment Function">Using Absolute Keyword in Delphi to Remove Unnecessary Assignment Function</a> <small>The Delphi/Object Pascal provides a keyword absolute, which you can also find examples at this...</small></li>
<li><a href="https://helloacm.com/how-to-find-largest-value-in-each-tree-row-level-using-bfs-or-dfs-algorithm/" rel="bookmark" title="How to Find Largest Value in Each Tree Row/Level using BFS or DFS Algorithm?">How to Find Largest Value in Each Tree Row/Level using BFS or DFS Algorithm?</a> <small>You need to find the largest value in each row of a binary tree. Example:...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://helloacm.com/wordpress-how-to-output-full-text-in-the-feed/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Nvidia, I’m coming again — this time I’m tougher</title>
		<link>https://helloacm.com/nvidia-im-coming-again-this-time-im-tougher/</link>
					<comments>https://helloacm.com/nvidia-im-coming-again-this-time-im-tougher/#respond</comments>
		
		<dc:creator><![CDATA[ACMer]]></dc:creator>
		<pubDate>Sat, 29 Nov 2025 18:02:10 +0000</pubDate>
				<category><![CDATA[interview questions]]></category>
		<category><![CDATA[interviews]]></category>
		<category><![CDATA[Nvidia]]></category>
		<category><![CDATA[AI Software Architect]]></category>
		<category><![CDATA[Big tech interviews]]></category>
		<category><![CDATA[C++ interview]]></category>
		<category><![CDATA[Career reflection]]></category>
		<category><![CDATA[CPU architecture]]></category>
		<category><![CDATA[Engineering journey]]></category>
		<category><![CDATA[HPC]]></category>
		<category><![CDATA[Interview Experience]]></category>
		<category><![CDATA[Job rejection]]></category>
		<category><![CDATA[k8s internals]]></category>
		<category><![CDATA[Kubernetes]]></category>
		<category><![CDATA[Memory systems]]></category>
		<category><![CDATA[Microsoft Research Cambridge]]></category>
		<category><![CDATA[MSRC]]></category>
		<category><![CDATA[Nvidia interview]]></category>
		<category><![CDATA[Performance optimization]]></category>
		<category><![CDATA[Personal growth]]></category>
		<category><![CDATA[Software engineer career]]></category>
		<category><![CDATA[Tech career growth]]></category>
		<category><![CDATA[tech industry]]></category>
		<category><![CDATA[technical interview]]></category>
		<guid isPermaLink="false">https://helloacm.com/?p=157649</guid>

					<description><![CDATA[[caption id="attachment_157652" align="alignnone" width="1536"]<a href="https://helloacm.com/nvidia-im-coming-again-this-time-im-tougher/nvidia/" rel="attachment wp-att-157652"><img src="https://helloacm.com/wp-content/uploads/2025/11/nvidia.jpg" alt="Nvidia" width="1536" height="994" class="size-full wp-image-157652" /></a> Nvidia[/caption]

Friends who know me well know that I have been persistently interviewing, but now I only target big tech companies. If it’s not a big company, I won’t interview. This is not arrogance, but reality: after <a href="https://justyy.com/archives/45631" title="How I joined Microsoft Research Cambridge as a Senior Software Engineer">Microsoft Research Cambridge / MSRC</a>, there are indeed only a few places left that can really help me keep growing.

<blockquote>
One year later, back at Nvidia: I really got stronger
From rejection to progress: my two encounters with Nvidia
Interviews are truth mirrors: each one makes me clearer about myself
Rejection is not the end, but the start of coming back stronger
Why I only interview at big tech: growth notes from two Nvidia interviews
Two rounds at Nvidia showed me my weak spots
How a big-tech rejection became my growth fuel
The real growth path for engineers: keep interviewing, keep upgrading
My two clashes with Nvidia: evolving from k8s to C++
90-minute technical interview, three days of waiting: goodbye Nvidia, and thank you
That Nvidia rejection helped me fix the most critical gaps
Nvidia, I’m coming again — this time I’m tougher
Big-tech interviews: an ongoing practice of upgrading
After two Nvidia rejections, I’m getting stronger and stronger
</blockquote>

Last year I first challenged Nvidia — today one of the most valuable companies in the world and the first to reach the $5 trillion market-cap milestone. I applied for JR1981163 Senior Software & Cloud Architect. Shortly after the first-round conversation with the hiring manager I received a rejection. At that time I was asked about my understanding of k8s internals; I honestly said I only knew the command-layer usage (application) and was not familiar with the core components.

[caption id="attachment_157651" align="alignnone" width="1353"]<a href="https://helloacm.com/nvidia-im-coming-again-this-time-im-tougher/nvidia-stock-performance-most-valuable/" rel="attachment wp-att-157651"><img src="https://helloacm.com/wp-content/uploads/2025/11/nvidia-stock-performance-most-valuable.jpg" alt="Nvidia Stock Performance / Most Valuable Company" width="1353" height="1928" class="size-full wp-image-157651" /></a> Nvidia Stock Performance / Most Valuable Company[/caption]

In that moment I realized: where the gap lay.

This year I made another push at Nvidia. The role this time was JR1997486 HPC and AI <a href="https://helloacm.com/site-reliability-engineer-sre-vs-software-engineer/" title="Site Reliability Engineer (SRE) vs Software Engineer">Software Architect</a>. The first-round conversation went very well — we exchanged backgrounds and dove into each of my past work experiences.

The second round was a 90-minute hardcore technical race: <a href="https://helloacm.com/c-forward-references-the-key-to-perfect-forwarding/" title="C++ Forward References: The Key to Perfect Forwarding">C++</a> coding, CPU architecture, memory fundamentals, performance optimization — the questions were solid and densely packed.

During the three days of waiting I felt both calm and expectant. In the end I still received a rejection, but this time it was different — I could clearly feel my progress. I knew which questions made me hesitate, which answers I only reached after a prompt, and therefore I now know more precisely what to improve next.

<blockquote>
Unfortunately the team have decided not to move forward with your application. The feedback was <strong>positive</strong> however there were just other candidates whose skillset was a stronger match.
</blockquote>

A bit of consolation: reportedly, a single position at big tech often receives well over a hundred resumes, and only about eight people are selected for interviews, with roughly half eliminated each round. Passing the resume screen is already quite an achievement.

Interviews are never simply wins or losses — they are mirrors. They tell me: I can still get stronger. Interviews are the most practical “market-value detector.” After each interview I know which weaknesses were exposed, and then I work hard to patch them. For example, when I interviewed for an ARM principal role mid-year I realized my C++ had grown rusty, which prompted me to intensively brush up on it afterward.

Unlike other FANNG/MANGO (Top Companies), there is no cooling down period and you can apply as many nvidia jobs as possible at the same time without restrictions.

<blockquote>
Q: Is there a cool down period before I can apply to another position?
A: No there isn’t, you can apply for as many roles as you wish.
</blockquote>

[bctt tweet="Along the way, I have been growing, and I am getting closer to a better version of myself."]

[show_file file="/var/www/wp-post-common/helloacm.com/interview.php"]

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/delphi-is-30-years-old/" rel="bookmark" title="Delphi is 30 Years Old!">Delphi is 30 Years Old!</a> <small>People who know the Delphi programming language are probably revealing their age. Many people think...</small></li>
<li><a href="https://helloacm.com/simple-investment-strategy-regular-investment-in-bitcoin-btc-dollar-cost-averaging/" rel="bookmark" title="Simple investment strategy: regular investment in Bitcoin/BTC (Dollar Cost Averaging)">Simple investment strategy: regular investment in Bitcoin/BTC (Dollar Cost Averaging)</a> <small>That day, I came across a post on LinkedIn: A person consistently purchased $30 worth...</small></li>
<li><a href="https://helloacm.com/how-ai-and-dynamic-pricing-shape-our-everyday-costs/" rel="bookmark" title="How AI and Dynamic Pricing Shape Our Everyday Costs">How AI and Dynamic Pricing Shape Our Everyday Costs</a> <small>A few days ago, I was having lunch with a colleague, and we started discussing...</small></li>
<li><a href="https://helloacm.com/tetration-operator-in-math-simply-explained-with-python-algorithms/" rel="bookmark" title="Tetration Operator in Math Simply Explained with Python Algorithms">Tetration Operator in Math Simply Explained with Python Algorithms</a> <small>What is Tetration Operator in Math? Tetration is an operation in mathematics that involves iterated...</small></li>
<li><a href="https://helloacm.com/the-memory-manager-in-c-c-heap-vs-stack/" rel="bookmark" title="The Memory Manager in C/C++ (Heap vs Stack)">The Memory Manager in C/C++ (Heap vs Stack)</a> <small>This is one of the most frequently asked interview questions for Software Engineer roles. In...</small></li>
<li><a href="https://helloacm.com/chatgpt-refactors-rewrites-the-code-using-promise-all-sending-requests-in-parallel/" rel="bookmark" title="ChatGPT Refactors/Rewrites the Code using Promise.All &#8211; Sending Requests in Parallel">ChatGPT Refactors/Rewrites the Code using Promise.All &#8211; Sending Requests in Parallel</a> <small>In one of my project, I have the following code (Node/Javascript) that invokes a few...</small></li>
<li><a href="https://helloacm.com/hunting-down-the-mythical-high-quality-code/" rel="bookmark" title="Hunting Down The Mythical High-Quality Code">Hunting Down The Mythical High-Quality Code</a> <small>Choosing the right career path can be a bit difficult. If you love building software...</small></li>
<li><a href="https://helloacm.com/how-to-delete-nodes-from-binary-tree-and-make-a-forest/" rel="bookmark" title="How to Delete Nodes from Binary Tree and Make a Forest?">How to Delete Nodes from Binary Tree and Make a Forest?</a> <small>Given the root of a binary tree, each node in the tree has a distinct...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[[caption id="attachment_157652" align="alignnone" width="1536"]<a href="https://helloacm.com/nvidia-im-coming-again-this-time-im-tougher/nvidia/" rel="attachment wp-att-157652"><img src="https://helloacm.com/wp-content/uploads/2025/11/nvidia.jpg" alt="Nvidia" width="1536" height="994" class="size-full wp-image-157652" /></a> Nvidia[/caption]

Friends who know me well know that I have been persistently interviewing, but now I only target big tech companies. If it’s not a big company, I won’t interview. This is not arrogance, but reality: after <a href="https://justyy.com/archives/45631" title="How I joined Microsoft Research Cambridge as a Senior Software Engineer">Microsoft Research Cambridge / MSRC</a>, there are indeed only a few places left that can really help me keep growing.

<blockquote>
One year later, back at Nvidia: I really got stronger
From rejection to progress: my two encounters with Nvidia
Interviews are truth mirrors: each one makes me clearer about myself
Rejection is not the end, but the start of coming back stronger
Why I only interview at big tech: growth notes from two Nvidia interviews
Two rounds at Nvidia showed me my weak spots
How a big-tech rejection became my growth fuel
The real growth path for engineers: keep interviewing, keep upgrading
My two clashes with Nvidia: evolving from k8s to C++
90-minute technical interview, three days of waiting: goodbye Nvidia, and thank you
That Nvidia rejection helped me fix the most critical gaps
Nvidia, I’m coming again — this time I’m tougher
Big-tech interviews: an ongoing practice of upgrading
After two Nvidia rejections, I’m getting stronger and stronger
</blockquote>

Last year I first challenged Nvidia — today one of the most valuable companies in the world and the first to reach the $5 trillion market-cap milestone. I applied for JR1981163 Senior Software & Cloud Architect. Shortly after the first-round conversation with the hiring manager I received a rejection. At that time I was asked about my understanding of k8s internals; I honestly said I only knew the command-layer usage (application) and was not familiar with the core components.

[caption id="attachment_157651" align="alignnone" width="1353"]<a href="https://helloacm.com/nvidia-im-coming-again-this-time-im-tougher/nvidia-stock-performance-most-valuable/" rel="attachment wp-att-157651"><img src="https://helloacm.com/wp-content/uploads/2025/11/nvidia-stock-performance-most-valuable.jpg" alt="Nvidia Stock Performance / Most Valuable Company" width="1353" height="1928" class="size-full wp-image-157651" /></a> Nvidia Stock Performance / Most Valuable Company[/caption]

In that moment I realized: where the gap lay.

This year I made another push at Nvidia. The role this time was JR1997486 HPC and AI <a href="https://helloacm.com/site-reliability-engineer-sre-vs-software-engineer/" title="Site Reliability Engineer (SRE) vs Software Engineer">Software Architect</a>. The first-round conversation went very well — we exchanged backgrounds and dove into each of my past work experiences.

The second round was a 90-minute hardcore technical race: <a href="https://helloacm.com/c-forward-references-the-key-to-perfect-forwarding/" title="C++ Forward References: The Key to Perfect Forwarding">C++</a> coding, CPU architecture, memory fundamentals, performance optimization — the questions were solid and densely packed.

During the three days of waiting I felt both calm and expectant. In the end I still received a rejection, but this time it was different — I could clearly feel my progress. I knew which questions made me hesitate, which answers I only reached after a prompt, and therefore I now know more precisely what to improve next.

<blockquote>
Unfortunately the team have decided not to move forward with your application. The feedback was <strong>positive</strong> however there were just other candidates whose skillset was a stronger match.
</blockquote>

A bit of consolation: reportedly, a single position at big tech often receives well over a hundred resumes, and only about eight people are selected for interviews, with roughly half eliminated each round. Passing the resume screen is already quite an achievement.

Interviews are never simply wins or losses — they are mirrors. They tell me: I can still get stronger. Interviews are the most practical “market-value detector.” After each interview I know which weaknesses were exposed, and then I work hard to patch them. For example, when I interviewed for an ARM principal role mid-year I realized my C++ had grown rusty, which prompted me to intensively brush up on it afterward.

Unlike other FANNG/MANGO (Top Companies), there is no cooling down period and you can apply as many nvidia jobs as possible at the same time without restrictions.

<blockquote>
Q: Is there a cool down period before I can apply to another position?
A: No there isn’t, you can apply for as many roles as you wish.
</blockquote>

[bctt tweet="Along the way, I have been growing, and I am getting closer to a better version of myself."]

[show_file file="/var/www/wp-post-common/helloacm.com/interview.php"]

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/delphi-is-30-years-old/" rel="bookmark" title="Delphi is 30 Years Old!">Delphi is 30 Years Old!</a> <small>People who know the Delphi programming language are probably revealing their age. Many people think...</small></li>
<li><a href="https://helloacm.com/simple-investment-strategy-regular-investment-in-bitcoin-btc-dollar-cost-averaging/" rel="bookmark" title="Simple investment strategy: regular investment in Bitcoin/BTC (Dollar Cost Averaging)">Simple investment strategy: regular investment in Bitcoin/BTC (Dollar Cost Averaging)</a> <small>That day, I came across a post on LinkedIn: A person consistently purchased $30 worth...</small></li>
<li><a href="https://helloacm.com/how-ai-and-dynamic-pricing-shape-our-everyday-costs/" rel="bookmark" title="How AI and Dynamic Pricing Shape Our Everyday Costs">How AI and Dynamic Pricing Shape Our Everyday Costs</a> <small>A few days ago, I was having lunch with a colleague, and we started discussing...</small></li>
<li><a href="https://helloacm.com/tetration-operator-in-math-simply-explained-with-python-algorithms/" rel="bookmark" title="Tetration Operator in Math Simply Explained with Python Algorithms">Tetration Operator in Math Simply Explained with Python Algorithms</a> <small>What is Tetration Operator in Math? Tetration is an operation in mathematics that involves iterated...</small></li>
<li><a href="https://helloacm.com/the-memory-manager-in-c-c-heap-vs-stack/" rel="bookmark" title="The Memory Manager in C/C++ (Heap vs Stack)">The Memory Manager in C/C++ (Heap vs Stack)</a> <small>This is one of the most frequently asked interview questions for Software Engineer roles. In...</small></li>
<li><a href="https://helloacm.com/chatgpt-refactors-rewrites-the-code-using-promise-all-sending-requests-in-parallel/" rel="bookmark" title="ChatGPT Refactors/Rewrites the Code using Promise.All &#8211; Sending Requests in Parallel">ChatGPT Refactors/Rewrites the Code using Promise.All &#8211; Sending Requests in Parallel</a> <small>In one of my project, I have the following code (Node/Javascript) that invokes a few...</small></li>
<li><a href="https://helloacm.com/hunting-down-the-mythical-high-quality-code/" rel="bookmark" title="Hunting Down The Mythical High-Quality Code">Hunting Down The Mythical High-Quality Code</a> <small>Choosing the right career path can be a bit difficult. If you love building software...</small></li>
<li><a href="https://helloacm.com/how-to-delete-nodes-from-binary-tree-and-make-a-forest/" rel="bookmark" title="How to Delete Nodes from Binary Tree and Make a Forest?">How to Delete Nodes from Binary Tree and Make a Forest?</a> <small>Given the root of a binary tree, each node in the tree has a distinct...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://helloacm.com/nvidia-im-coming-again-this-time-im-tougher/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Introduction to Parquet Files, Read/Write using Python</title>
		<link>https://helloacm.com/introduction-to-parquet-files-read-write-using-python/</link>
					<comments>https://helloacm.com/introduction-to-parquet-files-read-write-using-python/#respond</comments>
		
		<dc:creator><![CDATA[ACMer]]></dc:creator>
		<pubDate>Sat, 29 Nov 2025 00:30:03 +0000</pubDate>
				<category><![CDATA[programming languages]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[big data]]></category>
		<category><![CDATA[Columnar Storage]]></category>
		<category><![CDATA[csv]]></category>
		<category><![CDATA[Data Analysis]]></category>
		<category><![CDATA[Data Compression]]></category>
		<category><![CDATA[Data Processing]]></category>
		<category><![CDATA[data science]]></category>
		<category><![CDATA[ETL]]></category>
		<category><![CDATA[File Format]]></category>
		<category><![CDATA[Nested Data]]></category>
		<category><![CDATA[Pandas]]></category>
		<category><![CDATA[Parquet]]></category>
		<category><![CDATA[PyArrow]]></category>
		<guid isPermaLink="false">https://helloacm.com/?p=157642</guid>

					<description><![CDATA[<blockquote>
Introduction to Parquet Files
Reading and Writing Parquet Files with Python
Big Data Storage Optimization: Understanding Parquet
Essential Parquet Handling Tips for Python Data Analysis
Columnar Storage Insights: Parquet Files and Performance
Working with Nested Parquet Data using Python and PyArrow
From CSV to Parquet: A Python Data Format Conversion Guide
</blockquote>

<h3>What is a Parquet File?</h3>
Parquet is a columnar storage file format optimized for large-scale data processing. It is commonly used in big data frameworks like Apache Spark, Hadoop, and Pandas for efficient storage and fast retrieval of tabular data.

Parquet can be simply thought of as a <a href="https://helloacm.com/teaching-kids-programming-algorithm-to-transpose-a-matrix/" title="Teaching Kids Programming – Algorithm to Transpose a Matrix">transpose</a> of CSV. However, CSV is text-based, while Parquet is binary. From the storage perspective, columnar storage can be understood as swapping rows and columns, but it should be noted that Parquet is binary, supports compression and nested types, and is more than just a 'transpose'.

<h3>Why Use Parquet?</h3>
<ul>
  <li><strong>Columnar Storage:</strong> Stores data by columns, which improves query performance for analytics tasks.</li>
  <li><strong>Compression:</strong> Supports efficient compression techniques to reduce storage size.</li>
  <li><strong>Interoperability:</strong> Works with multiple data processing frameworks.</li>
  <li><strong>Schema Evolution:</strong> Supports adding/removing columns without breaking existing data.</li>
</ul>

<h3>Installing Required Libraries</h3>
To work with Parquet in <a href="https://helloacm.com/a-complete-guide-to-radix-sort-in-python-with-examples/" title="A Complete Guide to Radix Sort in Python with Examples">Python</a>, you need <code>pandas</code> and <code>pyarrow</code> (or <code>fastparquet</code>):

<pre lang=bash>
pip install pandas pyarrow
</pre>

<h3>Reading Parquet Files in Python</h3>
Here is an example of reading a Parquet file using <code>pandas</code> and <code>pyarrow</code>:

<pre lang=py>
import pandas as pd
import pyarrow.parquet as pq

# Path to your Parquet file
file_path = "example.parquet"

# Read Parquet file into DataFrame
df = pd.read_parquet(file_path)

# Display first 5 rows
print(df.head())
</pre>

<h3>Writing Data to Parquet</h3>
You can also write a DataFrame to a <a href="https://helloacm.com/introduction-to-parquet-files/" title="Introduction to Parquet Files">Parquet</a> file easily:

<pre lang=py>
import pandas as pd

# Create a sample DataFrame
data = {
    "name": ["Alice", "Bob", "Charlie"],
    "age": [25, 30, 35],
    "city": ["London", "Paris", "New York"]
}
df = pd.DataFrame(data)

# Save as Parquet
df.to_parquet("output.parquet", engine="pyarrow", index=False)
</pre>

<h3>Working with Nested Data</h3>
Parquet supports nested data like lists or structs. You can read them using <code>pyarrow</code> directly:

<pre lang=py>
import pyarrow.parquet as pq
from io import BytesIO

# Read Parquet file directly
table = pq.read_table("example.parquet")
df = table.to_pandas()
print(df.head())
</pre>

<h3>Conclusion</h3>
Parquet files are highly efficient for storing and processing large-scale tabular data. Using Python's <code>pandas</code> and <code>pyarrow</code>, you can easily read, write, and manipulate Parquet files for data analysis, ETL pipelines, and big data applications.

[show_file file="/var/www/wp-post-common/helloacm.com/python.php"]

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/implement-a-lock-acquire-and-release-in-c/" rel="bookmark" title="Implement a Lock Acquire and Release in C++">Implement a Lock Acquire and Release in C++</a> <small>Implementing a Spinlock Using the Atomic TAS Instruction Implementing a Spinlock Using the Atomic TAS...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-minimum-right-shifts-to-sort-the-array/" rel="bookmark" title="Teaching Kids Programming &#8211; Minimum Right Shifts to Sort the Array">Teaching Kids Programming &#8211; Minimum Right Shifts to Sort the Array</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given a 0-indexed array...</small></li>
<li><a href="https://helloacm.com/best-black-friday-2015-deals-for-programmers/" rel="bookmark" title="Best Black Friday Deals for Programmers!">Best Black Friday Deals for Programmers!</a> <small>I have almost drained my bank account for the big shopping event this year &#8211;...</small></li>
<li><a href="https://helloacm.com/tutorial-example-how-to-access-microsoft-excel-chart-using-the-windows-scripting-host-jscript/" rel="bookmark" title="Tutorial Example: How to Access Microsoft Excel (Chart) using the Windows Scripting Host (JScript)">Tutorial Example: How to Access Microsoft Excel (Chart) using the Windows Scripting Host (JScript)</a> <small>WSH (Window Scripting Host) is a powerful and handy scripting environment. It is installed by...</small></li>
<li><a href="https://helloacm.com/c-coding-reference-copy-n-values-by-using-stdfill_n/" rel="bookmark" title="C++ Coding Reference: Copy N values by using std::fill_n()">C++ Coding Reference: Copy N values by using std::fill_n()</a> <small>We talked about std::fill() that we can use to copy over a single value to...</small></li>
<li><a href="https://helloacm.com/python-bash-script-to-print-the-optimized-parameters-for-mysql-servers/" rel="bookmark" title="Python/Bash Script to Print the Optimized Parameters for MySQL Servers">Python/Bash Script to Print the Optimized Parameters for MySQL Servers</a> <small>When optimizing MySQL performance, tailoring the configuration to the server&#8217;s available memory is critical. Two...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-breadth-first-search-algorithm-to-compute-the-maximum-number-of-connected-components-in-a-directed-graph-detonate-the-maximum-bombs/" rel="bookmark" title="Teaching Kids Programming &#8211; Breadth First Search Algorithm to Compute the Maximum Number of Connected Components in a Directed Graph (Detonate the Maximum Bombs)">Teaching Kids Programming &#8211; Breadth First Search Algorithm to Compute the Maximum Number of Connected Components in a Directed Graph (Detonate the Maximum Bombs)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given a list of...</small></li>
<li><a href="https://helloacm.com/simulation-algorithm-to-compute-the-number-of-water-bottles/" rel="bookmark" title="Simulation Algorithm to Compute the Number of Water Bottles">Simulation Algorithm to Compute the Number of Water Bottles</a> <small>Given numBottles full water bottles, you can exchange numExchange empty water bottles for one full...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<blockquote>
Introduction to Parquet Files
Reading and Writing Parquet Files with Python
Big Data Storage Optimization: Understanding Parquet
Essential Parquet Handling Tips for Python Data Analysis
Columnar Storage Insights: Parquet Files and Performance
Working with Nested Parquet Data using Python and PyArrow
From CSV to Parquet: A Python Data Format Conversion Guide
</blockquote>

<h3>What is a Parquet File?</h3>
Parquet is a columnar storage file format optimized for large-scale data processing. It is commonly used in big data frameworks like Apache Spark, Hadoop, and Pandas for efficient storage and fast retrieval of tabular data.

Parquet can be simply thought of as a <a href="https://helloacm.com/teaching-kids-programming-algorithm-to-transpose-a-matrix/" title="Teaching Kids Programming – Algorithm to Transpose a Matrix">transpose</a> of CSV. However, CSV is text-based, while Parquet is binary. From the storage perspective, columnar storage can be understood as swapping rows and columns, but it should be noted that Parquet is binary, supports compression and nested types, and is more than just a 'transpose'.

<h3>Why Use Parquet?</h3>
<ul>
  <li><strong>Columnar Storage:</strong> Stores data by columns, which improves query performance for analytics tasks.</li>
  <li><strong>Compression:</strong> Supports efficient compression techniques to reduce storage size.</li>
  <li><strong>Interoperability:</strong> Works with multiple data processing frameworks.</li>
  <li><strong>Schema Evolution:</strong> Supports adding/removing columns without breaking existing data.</li>
</ul>

<h3>Installing Required Libraries</h3>
To work with Parquet in <a href="https://helloacm.com/a-complete-guide-to-radix-sort-in-python-with-examples/" title="A Complete Guide to Radix Sort in Python with Examples">Python</a>, you need <code>pandas</code> and <code>pyarrow</code> (or <code>fastparquet</code>):

<pre lang=bash>
pip install pandas pyarrow
</pre>

<h3>Reading Parquet Files in Python</h3>
Here is an example of reading a Parquet file using <code>pandas</code> and <code>pyarrow</code>:

<pre lang=py>
import pandas as pd
import pyarrow.parquet as pq

# Path to your Parquet file
file_path = "example.parquet"

# Read Parquet file into DataFrame
df = pd.read_parquet(file_path)

# Display first 5 rows
print(df.head())
</pre>

<h3>Writing Data to Parquet</h3>
You can also write a DataFrame to a <a href="https://helloacm.com/introduction-to-parquet-files/" title="Introduction to Parquet Files">Parquet</a> file easily:

<pre lang=py>
import pandas as pd

# Create a sample DataFrame
data = {
    "name": ["Alice", "Bob", "Charlie"],
    "age": [25, 30, 35],
    "city": ["London", "Paris", "New York"]
}
df = pd.DataFrame(data)

# Save as Parquet
df.to_parquet("output.parquet", engine="pyarrow", index=False)
</pre>

<h3>Working with Nested Data</h3>
Parquet supports nested data like lists or structs. You can read them using <code>pyarrow</code> directly:

<pre lang=py>
import pyarrow.parquet as pq
from io import BytesIO

# Read Parquet file directly
table = pq.read_table("example.parquet")
df = table.to_pandas()
print(df.head())
</pre>

<h3>Conclusion</h3>
Parquet files are highly efficient for storing and processing large-scale tabular data. Using Python's <code>pandas</code> and <code>pyarrow</code>, you can easily read, write, and manipulate Parquet files for data analysis, ETL pipelines, and big data applications.

[show_file file="/var/www/wp-post-common/helloacm.com/python.php"]

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/implement-a-lock-acquire-and-release-in-c/" rel="bookmark" title="Implement a Lock Acquire and Release in C++">Implement a Lock Acquire and Release in C++</a> <small>Implementing a Spinlock Using the Atomic TAS Instruction Implementing a Spinlock Using the Atomic TAS...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-minimum-right-shifts-to-sort-the-array/" rel="bookmark" title="Teaching Kids Programming &#8211; Minimum Right Shifts to Sort the Array">Teaching Kids Programming &#8211; Minimum Right Shifts to Sort the Array</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given a 0-indexed array...</small></li>
<li><a href="https://helloacm.com/best-black-friday-2015-deals-for-programmers/" rel="bookmark" title="Best Black Friday Deals for Programmers!">Best Black Friday Deals for Programmers!</a> <small>I have almost drained my bank account for the big shopping event this year &#8211;...</small></li>
<li><a href="https://helloacm.com/tutorial-example-how-to-access-microsoft-excel-chart-using-the-windows-scripting-host-jscript/" rel="bookmark" title="Tutorial Example: How to Access Microsoft Excel (Chart) using the Windows Scripting Host (JScript)">Tutorial Example: How to Access Microsoft Excel (Chart) using the Windows Scripting Host (JScript)</a> <small>WSH (Window Scripting Host) is a powerful and handy scripting environment. It is installed by...</small></li>
<li><a href="https://helloacm.com/c-coding-reference-copy-n-values-by-using-stdfill_n/" rel="bookmark" title="C++ Coding Reference: Copy N values by using std::fill_n()">C++ Coding Reference: Copy N values by using std::fill_n()</a> <small>We talked about std::fill() that we can use to copy over a single value to...</small></li>
<li><a href="https://helloacm.com/python-bash-script-to-print-the-optimized-parameters-for-mysql-servers/" rel="bookmark" title="Python/Bash Script to Print the Optimized Parameters for MySQL Servers">Python/Bash Script to Print the Optimized Parameters for MySQL Servers</a> <small>When optimizing MySQL performance, tailoring the configuration to the server&#8217;s available memory is critical. Two...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-breadth-first-search-algorithm-to-compute-the-maximum-number-of-connected-components-in-a-directed-graph-detonate-the-maximum-bombs/" rel="bookmark" title="Teaching Kids Programming &#8211; Breadth First Search Algorithm to Compute the Maximum Number of Connected Components in a Directed Graph (Detonate the Maximum Bombs)">Teaching Kids Programming &#8211; Breadth First Search Algorithm to Compute the Maximum Number of Connected Components in a Directed Graph (Detonate the Maximum Bombs)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given a list of...</small></li>
<li><a href="https://helloacm.com/simulation-algorithm-to-compute-the-number-of-water-bottles/" rel="bookmark" title="Simulation Algorithm to Compute the Number of Water Bottles">Simulation Algorithm to Compute the Number of Water Bottles</a> <small>Given numBottles full water bottles, you can exchange numExchange empty water bottles for one full...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://helloacm.com/introduction-to-parquet-files-read-write-using-python/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Implement a Lock Acquire and Release in C++</title>
		<link>https://helloacm.com/implement-a-lock-acquire-and-release-in-c/</link>
					<comments>https://helloacm.com/implement-a-lock-acquire-and-release-in-c/#respond</comments>
		
		<dc:creator><![CDATA[ACMer]]></dc:creator>
		<pubDate>Thu, 27 Nov 2025 21:42:24 +0000</pubDate>
				<category><![CDATA[algorithms]]></category>
		<category><![CDATA[c / c++]]></category>
		<category><![CDATA[C/C++]]></category>
		<category><![CDATA[interview questions]]></category>
		<category><![CDATA[knowledgebase]]></category>
		<category><![CDATA[programming languages]]></category>
		<category><![CDATA[Simply Explained]]></category>
		<category><![CDATA[atomic operations]]></category>
		<category><![CDATA[atomicity]]></category>
		<category><![CDATA[busy waiting]]></category>
		<category><![CDATA[c programming]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[concurrency]]></category>
		<category><![CDATA[CPU yielding]]></category>
		<category><![CDATA[lock implementation]]></category>
		<category><![CDATA[lockAcquire]]></category>
		<category><![CDATA[lockRelease]]></category>
		<category><![CDATA[low-level programming]]></category>
		<category><![CDATA[multithreading]]></category>
		<category><![CDATA[mutex basics]]></category>
		<category><![CDATA[operating systems]]></category>
		<category><![CDATA[sleep(0)]]></category>
		<category><![CDATA[spinlock]]></category>
		<category><![CDATA[synchronization]]></category>
		<category><![CDATA[TAS]]></category>
		<category><![CDATA[test-and-set]]></category>
		<category><![CDATA[thread safety]]></category>
		<category><![CDATA[tryLock]]></category>
		<guid isPermaLink="false">https://helloacm.com/?p=157636</guid>

					<description><![CDATA[<h3>Implementing a Spinlock Using the Atomic TAS Instruction</h3>
<blockquote>
Implementing a Spinlock Using the Atomic TAS Instruction
Building a Spinlock from Scratch with Atomic TAS
Implementing a Minimal Mutex Using Test-and-Set
Inside Spinlocks: TAS, Atomicity, and Busy Waiting
Atomic Operations and Spinlocks: Thread Synchronization in C
From Atomic Instructions to Locks: A Complete Guide to TAS and Spinlocks
Hands-On Spinlock Implementation: tryLock, lockAcquire, and lockRelease
Your First Spinlock: A TAS-Based Implementation in C
Atomic Exchange and Thread Mutual Exclusion: A Guide to Implementing Spinlocks
</blockquote>
Suppose we are given a TAS (Take-And-Set) function. This operation returns the old value stored in memory and atomically replaces it with a new value. Being <i>atomic</i> means that no other thread can observe the intermediate state; the entire read–write pair happens as one indivisible step.

In C++, the standard library function <code>std::exchange</code> behaves the same way logically, but is not atomic. Hardware-level atomicity is required for <a href="https://helloacm.com/the-minpoll-and-maxpoll-in-network-time-protocol-ntp/" title="The minpoll and maxpoll in Network Time Protocol (NTP)">synchronization</a> primitives.

<pre lang=c>
int TAS(int* memory, int newVal) {
    int old = *memory;
    *memory = newVal;
    return old;
}
</pre>

We want to use this primitive to implement a simple spinlock with:

<ul>
<li><code>lockAcquire()</code></li>
<li><code>lockRelease()</code></li>
</ul>

Threads will call these functions to protect access to a shared variable:

<pre lang=c>
typedef struct {
    int lock;
} lockType;

typedef struct {
    int val;
} threadArgType;

void threadFunc(void* arg) {
    lockAcquire((static_cast&lt;lockType*&gt;arg)-&gt;lock);
    (static_cast&lt;threadArgType*&gt;arg)-&gt;val++;
    lockRelease((static_cast&lt;lockType*&gt;arg)-&gt;lock);
}
</pre>

<h3>Implementing <code>tryLock</code></h3>

A <code>tryLock</code> function attempts to acquire the lock once. If the lock was free (value = 0), TAS sets it to 1 and returns the old value (0). If the lock was already taken, TAS returns 1. The tryLock function is not blocking - it returns immediately.

So <code>tryLock()</code> should succeed only when TAS returns 0:

<pre lang=c>
enum {
    UNLOCKED = 0,
    LOCKED = 1
}

int tryLock(lockType* lock) {
    // Returns 1 if previously locked, 0 if previously unlocked
    int old = TAS(lock-&gt;lock, LOCKED);
    return (old == UNLOCKED);   // true (1) = acquired successfully
}
</pre>

<h3>Implementing <code>lockAcquire()</code></h3>
A normal lock acquisition should “spin” until <code>tryLock()</code> succeeds. This is called a <b>spinlock</b> because the CPU will busy-wait. We can introduce a brief <a href="https://helloacm.com/a-sleepsort-using-multiprocessing-in-bash/" title="A SleepSort using Multiprocessing in BASH">sleep</a> when necessary. For instance, sleep(0) doesn't actually pause execution but yields the CPU, allowing other threads to run.

It is commonly used to implement spin locks for mutual exclusion across threads.

<pre lang=c>
void lockAcquire(lockType* lock) {
    while (!tryLock(lockType* lock)) {
        // spin until lock becomes available
    }
}
</pre>

another implementation:

<pre lang=c>
void lockAcquire(lockType* lock) {
    do {
       if (tryLock(lockType* lock)) {
          break;
       }
    } while (1);
}
</pre>

Unrolling tryLock:

<pre lang=c>
void lockAcquire(lockType* lock) {
    do {
       int old = TAS(lock-&gt;lock, LOCKED);
       // the lock has been set to LOCKED no matter if a lock has been aquired
       if (old == UNLOCKED) {
           break;
       }
    } while (1);
}
</pre>

This is the simplest possible implementation using TAS. In real systems we may add pause instructions or backoff strategies, but the basic idea remains the same.

<h3>Implementing <code>lockRelease()</code></h3>

To release the lock, the holder simply writes 0 to the lock variable. Because TAS is “set to new value and return old value”, it works fine for releasing too:

<pre lang=c>
void lockRelease(lockType* lock) {
    TAS(lock-&gt;lock, UNLOCKED);
}
</pre>

Alternatively, a simple atomic store is enough, but since TAS is our only tool, we reuse it. Keep in mind that releasing the lock twice is harmless here, since setting it to UNLOCKED=0 again has no side effects.

<h3>Summary</h3>

<p>
Using only an atomic TAS instruction, we implemented:
</p>

<ul>
<li>A <code>tryLock()</code> attempt</li>
<li>A <code>lockAcquire()</code> spinlock</li>
<li>A <code>lockRelease()</code> unlock operation</li>
</ul>

This style of lock is foundational for understanding low-level concurrency, memory ordering, and how higher-level mutex libraries are built.

[show_file file="/var/www/wp-post-common/helloacm.com/cpp.php"]

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/comparisions-of-push_back-and-emplace_back-in-c-stdvector/" rel="bookmark" title="Comparisions of push_back and emplace_back in C++ std::vector">Comparisions of push_back and emplace_back in C++ std::vector</a> <small>In C++, both push_back and emplace_back are methods of the std::vector class used to add...</small></li>
<li><a href="https://helloacm.com/const-vs-constexpr-in-c/" rel="bookmark" title="const vs constexpr in C++">const vs constexpr in C++</a> <small>C++ const vs constexpr: What’s the Real Difference? Both are used in C++ to define...</small></li>
<li><a href="https://helloacm.com/tutorial-on-c-smart-pointers/" rel="bookmark" title="Tutorial on C++ Smart Pointers">Tutorial on C++ Smart Pointers</a> <small>Tutorial on Smart Pointers in C++ Smart pointers in C++ provide automatic and safe memory...</small></li>
<li><a href="https://helloacm.com/from-idea-to-github-pages-building-tools-with-ai-and-vibe-coding/" rel="bookmark" title="From Idea to GitHub Pages: Building Tools with AI and Vibe Coding">From Idea to GitHub Pages: Building Tools with AI and Vibe Coding</a> <small>Built and Open-Sourced A Few Mini Tools with AI Recently, I used ChatGPT-4o and o4-mini...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-delete-nodes-from-linked-list-present-in-array/" rel="bookmark" title="Teaching Kids Programming &#8211; Delete Nodes From Linked List Present in Array">Teaching Kids Programming &#8211; Delete Nodes From Linked List Present in Array</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given an array of...</small></li>
<li><a href="https://helloacm.com/php7-x-is-deprecated-by-wordpress-why-you-should-upgrade-to-php8-x/" rel="bookmark" title="PHP7.x is deprecated by WordPress: Why You Should Upgrade to PHP8.x?">PHP7.x is deprecated by WordPress: Why You Should Upgrade to PHP8.x?</a> <small>Time to Say Goodbye to PHP 7.4 — My Blogs Are Finally Getting an Upgrade...</small></li>
<li><a href="https://helloacm.com/c-chess-board-printing-in-windows-using-codepage-437-extended-ascii/" rel="bookmark" title="C++ Chess Board Printing in Windows Using CodePage 437 &#8211; Extended ASCII">C++ Chess Board Printing in Windows Using CodePage 437 &#8211; Extended ASCII</a> <small>Well, most people, when they start programming in C/C++, they would like to print something...</small></li>
<li><a href="https://helloacm.com/the-computers-at-early-2000s/" rel="bookmark" title="The Computers at Early 2000s">The Computers at Early 2000s</a> <small>In 2003, I took the college entrance exam and then spent the summer in Beijing....</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<h3>Implementing a Spinlock Using the Atomic TAS Instruction</h3>
<blockquote>
Implementing a Spinlock Using the Atomic TAS Instruction
Building a Spinlock from Scratch with Atomic TAS
Implementing a Minimal Mutex Using Test-and-Set
Inside Spinlocks: TAS, Atomicity, and Busy Waiting
Atomic Operations and Spinlocks: Thread Synchronization in C
From Atomic Instructions to Locks: A Complete Guide to TAS and Spinlocks
Hands-On Spinlock Implementation: tryLock, lockAcquire, and lockRelease
Your First Spinlock: A TAS-Based Implementation in C
Atomic Exchange and Thread Mutual Exclusion: A Guide to Implementing Spinlocks
</blockquote>
Suppose we are given a TAS (Take-And-Set) function. This operation returns the old value stored in memory and atomically replaces it with a new value. Being <i>atomic</i> means that no other thread can observe the intermediate state; the entire read–write pair happens as one indivisible step.

In C++, the standard library function <code>std::exchange</code> behaves the same way logically, but is not atomic. Hardware-level atomicity is required for <a href="https://helloacm.com/the-minpoll-and-maxpoll-in-network-time-protocol-ntp/" title="The minpoll and maxpoll in Network Time Protocol (NTP)">synchronization</a> primitives.

<pre lang=c>
int TAS(int* memory, int newVal) {
    int old = *memory;
    *memory = newVal;
    return old;
}
</pre>

We want to use this primitive to implement a simple spinlock with:

<ul>
<li><code>lockAcquire()</code></li>
<li><code>lockRelease()</code></li>
</ul>

Threads will call these functions to protect access to a shared variable:

<pre lang=c>
typedef struct {
    int lock;
} lockType;

typedef struct {
    int val;
} threadArgType;

void threadFunc(void* arg) {
    lockAcquire((static_cast&lt;lockType*&gt;arg)-&gt;lock);
    (static_cast&lt;threadArgType*&gt;arg)-&gt;val++;
    lockRelease((static_cast&lt;lockType*&gt;arg)-&gt;lock);
}
</pre>

<h3>Implementing <code>tryLock</code></h3>

A <code>tryLock</code> function attempts to acquire the lock once. If the lock was free (value = 0), TAS sets it to 1 and returns the old value (0). If the lock was already taken, TAS returns 1. The tryLock function is not blocking - it returns immediately.

So <code>tryLock()</code> should succeed only when TAS returns 0:

<pre lang=c>
enum {
    UNLOCKED = 0,
    LOCKED = 1
}

int tryLock(lockType* lock) {
    // Returns 1 if previously locked, 0 if previously unlocked
    int old = TAS(lock-&gt;lock, LOCKED);
    return (old == UNLOCKED);   // true (1) = acquired successfully
}
</pre>

<h3>Implementing <code>lockAcquire()</code></h3>
A normal lock acquisition should “spin” until <code>tryLock()</code> succeeds. This is called a <b>spinlock</b> because the CPU will busy-wait. We can introduce a brief <a href="https://helloacm.com/a-sleepsort-using-multiprocessing-in-bash/" title="A SleepSort using Multiprocessing in BASH">sleep</a> when necessary. For instance, sleep(0) doesn't actually pause execution but yields the CPU, allowing other threads to run.

It is commonly used to implement spin locks for mutual exclusion across threads.

<pre lang=c>
void lockAcquire(lockType* lock) {
    while (!tryLock(lockType* lock)) {
        // spin until lock becomes available
    }
}
</pre>

another implementation:

<pre lang=c>
void lockAcquire(lockType* lock) {
    do {
       if (tryLock(lockType* lock)) {
          break;
       }
    } while (1);
}
</pre>

Unrolling tryLock:

<pre lang=c>
void lockAcquire(lockType* lock) {
    do {
       int old = TAS(lock-&gt;lock, LOCKED);
       // the lock has been set to LOCKED no matter if a lock has been aquired
       if (old == UNLOCKED) {
           break;
       }
    } while (1);
}
</pre>

This is the simplest possible implementation using TAS. In real systems we may add pause instructions or backoff strategies, but the basic idea remains the same.

<h3>Implementing <code>lockRelease()</code></h3>

To release the lock, the holder simply writes 0 to the lock variable. Because TAS is “set to new value and return old value”, it works fine for releasing too:

<pre lang=c>
void lockRelease(lockType* lock) {
    TAS(lock-&gt;lock, UNLOCKED);
}
</pre>

Alternatively, a simple atomic store is enough, but since TAS is our only tool, we reuse it. Keep in mind that releasing the lock twice is harmless here, since setting it to UNLOCKED=0 again has no side effects.

<h3>Summary</h3>

<p>
Using only an atomic TAS instruction, we implemented:
</p>

<ul>
<li>A <code>tryLock()</code> attempt</li>
<li>A <code>lockAcquire()</code> spinlock</li>
<li>A <code>lockRelease()</code> unlock operation</li>
</ul>

This style of lock is foundational for understanding low-level concurrency, memory ordering, and how higher-level mutex libraries are built.

[show_file file="/var/www/wp-post-common/helloacm.com/cpp.php"]

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/comparisions-of-push_back-and-emplace_back-in-c-stdvector/" rel="bookmark" title="Comparisions of push_back and emplace_back in C++ std::vector">Comparisions of push_back and emplace_back in C++ std::vector</a> <small>In C++, both push_back and emplace_back are methods of the std::vector class used to add...</small></li>
<li><a href="https://helloacm.com/const-vs-constexpr-in-c/" rel="bookmark" title="const vs constexpr in C++">const vs constexpr in C++</a> <small>C++ const vs constexpr: What’s the Real Difference? Both are used in C++ to define...</small></li>
<li><a href="https://helloacm.com/tutorial-on-c-smart-pointers/" rel="bookmark" title="Tutorial on C++ Smart Pointers">Tutorial on C++ Smart Pointers</a> <small>Tutorial on Smart Pointers in C++ Smart pointers in C++ provide automatic and safe memory...</small></li>
<li><a href="https://helloacm.com/from-idea-to-github-pages-building-tools-with-ai-and-vibe-coding/" rel="bookmark" title="From Idea to GitHub Pages: Building Tools with AI and Vibe Coding">From Idea to GitHub Pages: Building Tools with AI and Vibe Coding</a> <small>Built and Open-Sourced A Few Mini Tools with AI Recently, I used ChatGPT-4o and o4-mini...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-delete-nodes-from-linked-list-present-in-array/" rel="bookmark" title="Teaching Kids Programming &#8211; Delete Nodes From Linked List Present in Array">Teaching Kids Programming &#8211; Delete Nodes From Linked List Present in Array</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given an array of...</small></li>
<li><a href="https://helloacm.com/php7-x-is-deprecated-by-wordpress-why-you-should-upgrade-to-php8-x/" rel="bookmark" title="PHP7.x is deprecated by WordPress: Why You Should Upgrade to PHP8.x?">PHP7.x is deprecated by WordPress: Why You Should Upgrade to PHP8.x?</a> <small>Time to Say Goodbye to PHP 7.4 — My Blogs Are Finally Getting an Upgrade...</small></li>
<li><a href="https://helloacm.com/c-chess-board-printing-in-windows-using-codepage-437-extended-ascii/" rel="bookmark" title="C++ Chess Board Printing in Windows Using CodePage 437 &#8211; Extended ASCII">C++ Chess Board Printing in Windows Using CodePage 437 &#8211; Extended ASCII</a> <small>Well, most people, when they start programming in C/C++, they would like to print something...</small></li>
<li><a href="https://helloacm.com/the-computers-at-early-2000s/" rel="bookmark" title="The Computers at Early 2000s">The Computers at Early 2000s</a> <small>In 2003, I took the college entrance exam and then spent the summer in Beijing....</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://helloacm.com/implement-a-lock-acquire-and-release-in-c/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Cambridge Science Park: Microsoft, AMD and Raspberry Pi (Neighbours)</title>
		<link>https://helloacm.com/cambridge-science-park-microsoft-amd-and-raspberry-pi-neighbours/</link>
					<comments>https://helloacm.com/cambridge-science-park-microsoft-amd-and-raspberry-pi-neighbours/#respond</comments>
		
		<dc:creator><![CDATA[ACMer]]></dc:creator>
		<pubDate>Thu, 27 Nov 2025 00:59:44 +0000</pubDate>
				<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[Raspberry PI]]></category>
		<category><![CDATA[AMD]]></category>
		<category><![CDATA[Cambridge]]></category>
		<category><![CDATA[Cambridge Science Park]]></category>
		<category><![CDATA[Microsoft Research]]></category>
		<category><![CDATA[Office Locations]]></category>
		<category><![CDATA[raspberry pi]]></category>
		<category><![CDATA[Tech Companies]]></category>
		<category><![CDATA[UK]]></category>
		<guid isPermaLink="false">https://helloacm.com/?p=157608</guid>

					<description><![CDATA[Microsoft has two offices in Cambridge. One is located right across from the railway station at 21 Station Road, with Amazon’s office next door and Apple’s new building recently opened just beside it. The other office is part of Microsoft Research, situated in Cambridge Science Park at number 198. This office likely originated from Microsoft’s acquisition of MetaSwitch, and naturally became part of the Science Park. Later, some teams from the Station Road office also moved there.

I usually go to the Station Road office three days a week. A few weeks ago, due to team collaboration needs, I spent a day working at the Science Park office. After lunch, I took a walk around the area and was surprised to find that AMD and Raspberry Pi are located just next door.

<h2>Introduction and History of Cambridge Science Park</h2>
Cambridge Science Park is one of the oldest and most iconic science parks in the UK, and a core part of the “Silicon Fen” technology ecosystem. The park hosts a wide range of high-tech companies, from startups to major global tech giants. This makes it completely natural — and representative — that Microsoft (Research/Engineering), AMD, and Raspberry Pi all have offices or headquarters here. The Science Park also hosts many other well-known companies, including Broadcom, Qualcomm, and Huawei Research.

Cambridge Science Park was founded in 1970 by Trinity College, University of Cambridge, making it one of the earliest science parks in the UK. Its mission is to connect academic research with industry, providing comprehensive facilities — from offices to laboratories — to support companies ranging from early-stage startups to large established firms.

From the first tenants in the 1970s (such as Laser-Scan in 1973) through the expansions in the 1990s and 2000s, Cambridge Science Park has grown into a major hub for global technology companies, research institutions, and innovative enterprises. Its infrastructure continues to evolve, meeting the needs of modern R&amp;D and office environments.

<h3>Microsoft Research</h3>
<a href="https://helloacm.com/this-years-microsofts-hackathon/" title="This Year’s Microsoft’s Hackathon">Microsoft</a> established its Cambridge research lab in 1997, making it one of the company’s earliest overseas research centers. One of the lab’s goals was to collaborate with the University of Cambridge, leveraging its academic strengths and talent pool to conduct foundational research, cross-disciplinary innovation, and forward-looking technological exploration.

In recent years, Microsoft Cambridge has taken on R&amp;D responsibilities in areas such as cloud systems, AI, and engineering systems. Its presence has brought high-level research projects to the region and provided local talent with opportunities to engage in global research initiatives.

<h3>AMD</h3>
AMD’s team in Cambridge has roots in earlier local semiconductor and networking companies, including groups from Solarflare and its predecessors. Over time, AMD developed Cambridge into one of its key engineering and research centers in the UK, contributing to work in networking, embedded systems, data centers, and high-performance computing.

In recent years — alongside acquisitions and internal expansion — AMD has expanded or relocated to more modern office and lab facilities within Cambridge Science Park, strengthening the park’s influence in semiconductor design and hardware engineering.

<h3>Raspberry Pi</h3>
Raspberry Pi’s headquarters and main office are located in Cambridge Science Park. As a company dedicated to promoting computing education, <a href="https://helloacm.com/the-latest-raspberry-pi-5-comes-with-up-to-16gb-of-ram-but-its-a-bit-pricey/" title="The latest Raspberry Pi 5 comes with up to 16GB of RAM, but it’s a bit pricey.">Raspberry Pi</a> represents innovation in open-source hardware, education, and accessible computing — and its presence adds to the park’s diversity of tech enterprises.

As its product line and educational initiatives have expanded, Raspberry Pi has gradually grown its office footprint within the park, enabling closer collaboration with the region’s academic and industrial ecosystem.

[caption id="attachment_157610" align="alignnone" width="2048"]<a href="https://helloacm.com/cambridge-science-park-microsoft-amd-and-raspberry-pi-neighbours/cambridge-science-park-2025-09-05-09-03-16/" rel="attachment wp-att-157610"><img src="https://helloacm.com/wp-content/uploads/2025/11/cambridge-science-park-2025-09-05-09.03.16-scaled.jpg" alt="Cambridge Science Park Entry Sign" width="2048" height="1152" class="size-full wp-image-157610" /></a> Cambridge Science Park Entry Sign[/caption]

[caption id="attachment_157624" align="alignnone" width="1536"]<a href="https://helloacm.com/cambridge-science-park-microsoft-amd-and-raspberry-pi-neighbours/cambridge-science-park-lunch-2025-09-05-12-30-14/" rel="attachment wp-att-157624"><img src="https://helloacm.com/wp-content/uploads/2025/11/cambridge-science-park-lunch-2025-09-05-12.30.14-rotated.jpg" alt="Lunch at Microsoft Cambridge Science Park" width="1536" height="864" class="size-full wp-image-157624" /></a> Lunch at Microsoft Cambridge Science Park[/caption]

[caption id="attachment_157623" align="alignnone" width="2048"]<a href="https://helloacm.com/cambridge-science-park-microsoft-amd-and-raspberry-pi-neighbours/cambridge-science-park-kitchen-2025-09-05-13-59-56/" rel="attachment wp-att-157623"><img src="https://helloacm.com/wp-content/uploads/2025/11/cambridge-science-park-kitchen-2025-09-05-13.59.56-scaled.jpg" alt="Kitchen" width="2048" height="1152" class="size-full wp-image-157623" /></a> Kitchen[/caption]

[caption id="attachment_157622" align="alignnone" width="2048"]<a href="https://helloacm.com/cambridge-science-park-microsoft-amd-and-raspberry-pi-neighbours/cambridge-science-park-2025-10-16-10-32-19/" rel="attachment wp-att-157622"><img src="https://helloacm.com/wp-content/uploads/2025/11/cambridge-science-park-2025-10-16-10.32.19-scaled.jpg" alt="Coffee, Kitchen" width="2048" height="1152" class="size-full wp-image-157622" /></a> Coffee, Kitchen[/caption]

[caption id="attachment_157621" align="alignnone" width="864"]<a href="https://helloacm.com/cambridge-science-park-microsoft-amd-and-raspberry-pi-neighbours/cambridge-science-park-2025-09-05-15-04-40/" rel="attachment wp-att-157621"><img src="https://helloacm.com/wp-content/uploads/2025/11/cambridge-science-park-2025-09-05-15.04.40.jpg" alt="Green Fake Plants" width="864" height="1536" class="size-full wp-image-157621" /></a> Green Fake Plants[/caption]

[caption id="attachment_157620" align="alignnone" width="2048"]<a href="https://helloacm.com/cambridge-science-park-microsoft-amd-and-raspberry-pi-neighbours/cambridge-science-park-2025-09-05-15-01-37/" rel="attachment wp-att-157620"><img src="https://helloacm.com/wp-content/uploads/2025/11/cambridge-science-park-2025-09-05-15.01.37-scaled.jpg" alt="Raspberry Pi Office in Cambridge Science Park" width="2048" height="1152" class="size-full wp-image-157620" /></a> Raspberry Pi Office in Cambridge Science Park[/caption]

[caption id="attachment_157619" align="alignnone" width="864"]<a href="https://helloacm.com/cambridge-science-park-microsoft-amd-and-raspberry-pi-neighbours/cambridge-science-park-2025-09-05-14-56-06/" rel="attachment wp-att-157619"><img src="https://helloacm.com/wp-content/uploads/2025/11/cambridge-science-park-2025-09-05-14.56.06.jpg" alt="Signs show that Microsoft, AMD and RaspberryPi" width="864" height="1536" class="size-full wp-image-157619" /></a> Signs show that Microsoft, AMD and RaspberryPi[/caption]

[caption id="attachment_157618" align="alignnone" width="864"]<a href="https://helloacm.com/cambridge-science-park-microsoft-amd-and-raspberry-pi-neighbours/cambridge-science-park-2025-09-05-14-55-42/" rel="attachment wp-att-157618"><img src="https://helloacm.com/wp-content/uploads/2025/11/cambridge-science-park-2025-09-05-14.55.42.jpg" alt="Signs show that Microsoft, AMD and RaspberryPi" width="864" height="1536" class="size-full wp-image-157618" /></a> Signs show that Microsoft, AMD and RaspberryPi[/caption]

[caption id="attachment_157617" align="alignnone" width="864"]<a href="https://helloacm.com/cambridge-science-park-microsoft-amd-and-raspberry-pi-neighbours/cambridge-science-park-2025-09-05-14-55-25/" rel="attachment wp-att-157617"><img src="https://helloacm.com/wp-content/uploads/2025/11/cambridge-science-park-2025-09-05-14.55.25.jpg" alt="Microsoft 198" width="864" height="1536" class="size-full wp-image-157617" /></a> Microsoft 198[/caption]

[caption id="attachment_157616" align="alignnone" width="2048"]<a href="https://helloacm.com/cambridge-science-park-microsoft-amd-and-raspberry-pi-neighbours/cambridge-science-park-2025-09-05-14-54-58/" rel="attachment wp-att-157616"><img src="https://helloacm.com/wp-content/uploads/2025/11/cambridge-science-park-2025-09-05-14.54.58-scaled.jpg" alt="Cambridge Science Park Views" width="2048" height="1152" class="size-full wp-image-157616" /></a> Cambridge Science Park Views[/caption]

[caption id="attachment_157615" align="alignnone" width="2048"]<a href="https://helloacm.com/cambridge-science-park-microsoft-amd-and-raspberry-pi-neighbours/cambridge-science-park-2025-09-05-14-54-09/" rel="attachment wp-att-157615"><img src="https://helloacm.com/wp-content/uploads/2025/11/cambridge-science-park-2025-09-05-14.54.09-scaled.jpg" alt="AMD at Cambridge Science Park" width="2048" height="1152" class="size-full wp-image-157615" /></a> AMD at Cambridge Science Park[/caption]

[caption id="attachment_157614" align="alignnone" width="2048"]<a href="https://helloacm.com/cambridge-science-park-microsoft-amd-and-raspberry-pi-neighbours/cambridge-science-park-2025-09-05-14-53-50/" rel="attachment wp-att-157614"><img src="https://helloacm.com/wp-content/uploads/2025/11/cambridge-science-park-2025-09-05-14.53.50-scaled.jpg" alt="Cambridge Science Park" width="2048" height="1152" class="size-full wp-image-157614" /></a> Cambridge Science Park[/caption]

[caption id="attachment_157613" align="alignnone" width="2048"]<a href="https://helloacm.com/cambridge-science-park-microsoft-amd-and-raspberry-pi-neighbours/cambridge-science-park-2025-09-05-13-58-05/" rel="attachment wp-att-157613"><img src="https://helloacm.com/wp-content/uploads/2025/11/cambridge-science-park-2025-09-05-13.58.05-scaled.jpg" alt="Hot Desk" width="2048" height="1152" class="size-full wp-image-157613" /></a> Hot Desk[/caption]

[caption id="attachment_157612" align="alignnone" width="2048"]<a href="https://helloacm.com/cambridge-science-park-microsoft-amd-and-raspberry-pi-neighbours/cambridge-science-park-2025-09-05-13-47-26/" rel="attachment wp-att-157612"><img src="https://helloacm.com/wp-content/uploads/2025/11/cambridge-science-park-2025-09-05-13.47.26-scaled.jpg" alt="Meeting Room" width="2048" height="1152" class="size-full wp-image-157612" /></a> Meeting Room[/caption]

[caption id="attachment_157611" align="alignnone" width="2048"]<a href="https://helloacm.com/cambridge-science-park-microsoft-amd-and-raspberry-pi-neighbours/cambridge-science-park-2025-09-05-12-27-11/" rel="attachment wp-att-157611"><img src="https://helloacm.com/wp-content/uploads/2025/11/cambridge-science-park-2025-09-05-12.27.11-scaled.jpg" alt="Cambridge Science Park Internal View" width="2048" height="1152" class="size-full wp-image-157611" /></a> Cambridge Science Park Internal View[/caption]

[show_file file="/var/www/wp-post-common/helloacm.com/microsoft.php"]

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/understanding-the-sigma-function-divisors-multiplicativity-and-the-formula/" rel="bookmark" title="Understanding the Sigma Function: Divisors, Multiplicativity, and the Formula">Understanding the Sigma Function: Divisors, Multiplicativity, and the Formula</a> <small>Understanding the Sigma Function: Divisors, Multiplicativity, and the Formula Understanding the Sigma Function: From Divisors...</small></li>
<li><a href="https://helloacm.com/how-to-securely-wipe-your-disk-and-what-happens-after-you-zero-your-disk-using-dd-on-linux/" rel="bookmark" title="How to Securely Wipe Your Disk and What Happens After You Zero Your Disk using dd on Linux?">How to Securely Wipe Your Disk and What Happens After You Zero Your Disk using dd on Linux?</a> <small>I decide to terminate one of my VPS server (QuickHostUK) and don&#8217;t want any data...</small></li>
<li><a href="https://helloacm.com/chatgpt-refactors-rewrites-the-code-using-promise-all-sending-requests-in-parallel/" rel="bookmark" title="ChatGPT Refactors/Rewrites the Code using Promise.All &#8211; Sending Requests in Parallel">ChatGPT Refactors/Rewrites the Code using Promise.All &#8211; Sending Requests in Parallel</a> <small>In one of my project, I have the following code (Node/Javascript) that invokes a few...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-reachable-nodes-with-restrictions-graph-theory-depth-first-search-algorithm/" rel="bookmark" title="Teaching Kids Programming &#8211; Reachable Nodes With Restrictions (Graph Theory, Recursive Depth First Search Algorithm, Undirected/Unweighted Graph)">Teaching Kids Programming &#8211; Reachable Nodes With Restrictions (Graph Theory, Recursive Depth First Search Algorithm, Undirected/Unweighted Graph)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms There is an undirected tree with...</small></li>
<li><a href="https://helloacm.com/understanding-dynamic_cast-in-c-safe-downcasting-explained/" rel="bookmark" title="Understanding dynamic_cast in C++: Safe Downcasting Explained">Understanding dynamic_cast in C++: Safe Downcasting Explained</a> <small>What Is dynamic_cast in C++? Purpose Safely convert between polymorphic types at runtime Commonly used...</small></li>
<li><a href="https://helloacm.com/telegram-accounts-are-shockingly-easy-to-hack-without-2fa/" rel="bookmark" title="Telegram Accounts Are Shockingly Easy to Hack Without 2FA">Telegram Accounts Are Shockingly Easy to Hack Without 2FA</a> <small>&#8220;How My Telegram Account Got Hacked—and What I Learned&#8221; &#8220;A Cautionary Tale: Telegram Security and...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-introduction-to-units-of-information-byte-kb-mb-gb-tb-pb/" rel="bookmark" title="Teaching Kids Programming &#8211; Introduction to Units of Information (Byte, KB, MB, GB, TB, PB)">Teaching Kids Programming &#8211; Introduction to Units of Information (Byte, KB, MB, GB, TB, PB)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms Information is the lifeblood of the...</small></li>
<li><a href="https://helloacm.com/the-common-include-php-file-for-my-sites/" rel="bookmark" title="The Common Include PHP File For My Sites">The Common Include PHP File For My Sites</a> <small>I think you may have some common code to write for most of the PHP...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[Microsoft has two offices in Cambridge. One is located right across from the railway station at 21 Station Road, with Amazon’s office next door and Apple’s new building recently opened just beside it. The other office is part of Microsoft Research, situated in Cambridge Science Park at number 198. This office likely originated from Microsoft’s acquisition of MetaSwitch, and naturally became part of the Science Park. Later, some teams from the Station Road office also moved there.

I usually go to the Station Road office three days a week. A few weeks ago, due to team collaboration needs, I spent a day working at the Science Park office. After lunch, I took a walk around the area and was surprised to find that AMD and Raspberry Pi are located just next door.

<h2>Introduction and History of Cambridge Science Park</h2>
Cambridge Science Park is one of the oldest and most iconic science parks in the UK, and a core part of the “Silicon Fen” technology ecosystem. The park hosts a wide range of high-tech companies, from startups to major global tech giants. This makes it completely natural — and representative — that Microsoft (Research/Engineering), AMD, and Raspberry Pi all have offices or headquarters here. The Science Park also hosts many other well-known companies, including Broadcom, Qualcomm, and Huawei Research.

Cambridge Science Park was founded in 1970 by Trinity College, University of Cambridge, making it one of the earliest science parks in the UK. Its mission is to connect academic research with industry, providing comprehensive facilities — from offices to laboratories — to support companies ranging from early-stage startups to large established firms.

From the first tenants in the 1970s (such as Laser-Scan in 1973) through the expansions in the 1990s and 2000s, Cambridge Science Park has grown into a major hub for global technology companies, research institutions, and innovative enterprises. Its infrastructure continues to evolve, meeting the needs of modern R&amp;D and office environments.

<h3>Microsoft Research</h3>
<a href="https://helloacm.com/this-years-microsofts-hackathon/" title="This Year’s Microsoft’s Hackathon">Microsoft</a> established its Cambridge research lab in 1997, making it one of the company’s earliest overseas research centers. One of the lab’s goals was to collaborate with the University of Cambridge, leveraging its academic strengths and talent pool to conduct foundational research, cross-disciplinary innovation, and forward-looking technological exploration.

In recent years, Microsoft Cambridge has taken on R&amp;D responsibilities in areas such as cloud systems, AI, and engineering systems. Its presence has brought high-level research projects to the region and provided local talent with opportunities to engage in global research initiatives.

<h3>AMD</h3>
AMD’s team in Cambridge has roots in earlier local semiconductor and networking companies, including groups from Solarflare and its predecessors. Over time, AMD developed Cambridge into one of its key engineering and research centers in the UK, contributing to work in networking, embedded systems, data centers, and high-performance computing.

In recent years — alongside acquisitions and internal expansion — AMD has expanded or relocated to more modern office and lab facilities within Cambridge Science Park, strengthening the park’s influence in semiconductor design and hardware engineering.

<h3>Raspberry Pi</h3>
Raspberry Pi’s headquarters and main office are located in Cambridge Science Park. As a company dedicated to promoting computing education, <a href="https://helloacm.com/the-latest-raspberry-pi-5-comes-with-up-to-16gb-of-ram-but-its-a-bit-pricey/" title="The latest Raspberry Pi 5 comes with up to 16GB of RAM, but it’s a bit pricey.">Raspberry Pi</a> represents innovation in open-source hardware, education, and accessible computing — and its presence adds to the park’s diversity of tech enterprises.

As its product line and educational initiatives have expanded, Raspberry Pi has gradually grown its office footprint within the park, enabling closer collaboration with the region’s academic and industrial ecosystem.

[caption id="attachment_157610" align="alignnone" width="2048"]<a href="https://helloacm.com/cambridge-science-park-microsoft-amd-and-raspberry-pi-neighbours/cambridge-science-park-2025-09-05-09-03-16/" rel="attachment wp-att-157610"><img src="https://helloacm.com/wp-content/uploads/2025/11/cambridge-science-park-2025-09-05-09.03.16-scaled.jpg" alt="Cambridge Science Park Entry Sign" width="2048" height="1152" class="size-full wp-image-157610" /></a> Cambridge Science Park Entry Sign[/caption]

[caption id="attachment_157624" align="alignnone" width="1536"]<a href="https://helloacm.com/cambridge-science-park-microsoft-amd-and-raspberry-pi-neighbours/cambridge-science-park-lunch-2025-09-05-12-30-14/" rel="attachment wp-att-157624"><img src="https://helloacm.com/wp-content/uploads/2025/11/cambridge-science-park-lunch-2025-09-05-12.30.14-rotated.jpg" alt="Lunch at Microsoft Cambridge Science Park" width="1536" height="864" class="size-full wp-image-157624" /></a> Lunch at Microsoft Cambridge Science Park[/caption]

[caption id="attachment_157623" align="alignnone" width="2048"]<a href="https://helloacm.com/cambridge-science-park-microsoft-amd-and-raspberry-pi-neighbours/cambridge-science-park-kitchen-2025-09-05-13-59-56/" rel="attachment wp-att-157623"><img src="https://helloacm.com/wp-content/uploads/2025/11/cambridge-science-park-kitchen-2025-09-05-13.59.56-scaled.jpg" alt="Kitchen" width="2048" height="1152" class="size-full wp-image-157623" /></a> Kitchen[/caption]

[caption id="attachment_157622" align="alignnone" width="2048"]<a href="https://helloacm.com/cambridge-science-park-microsoft-amd-and-raspberry-pi-neighbours/cambridge-science-park-2025-10-16-10-32-19/" rel="attachment wp-att-157622"><img src="https://helloacm.com/wp-content/uploads/2025/11/cambridge-science-park-2025-10-16-10.32.19-scaled.jpg" alt="Coffee, Kitchen" width="2048" height="1152" class="size-full wp-image-157622" /></a> Coffee, Kitchen[/caption]

[caption id="attachment_157621" align="alignnone" width="864"]<a href="https://helloacm.com/cambridge-science-park-microsoft-amd-and-raspberry-pi-neighbours/cambridge-science-park-2025-09-05-15-04-40/" rel="attachment wp-att-157621"><img src="https://helloacm.com/wp-content/uploads/2025/11/cambridge-science-park-2025-09-05-15.04.40.jpg" alt="Green Fake Plants" width="864" height="1536" class="size-full wp-image-157621" /></a> Green Fake Plants[/caption]

[caption id="attachment_157620" align="alignnone" width="2048"]<a href="https://helloacm.com/cambridge-science-park-microsoft-amd-and-raspberry-pi-neighbours/cambridge-science-park-2025-09-05-15-01-37/" rel="attachment wp-att-157620"><img src="https://helloacm.com/wp-content/uploads/2025/11/cambridge-science-park-2025-09-05-15.01.37-scaled.jpg" alt="Raspberry Pi Office in Cambridge Science Park" width="2048" height="1152" class="size-full wp-image-157620" /></a> Raspberry Pi Office in Cambridge Science Park[/caption]

[caption id="attachment_157619" align="alignnone" width="864"]<a href="https://helloacm.com/cambridge-science-park-microsoft-amd-and-raspberry-pi-neighbours/cambridge-science-park-2025-09-05-14-56-06/" rel="attachment wp-att-157619"><img src="https://helloacm.com/wp-content/uploads/2025/11/cambridge-science-park-2025-09-05-14.56.06.jpg" alt="Signs show that Microsoft, AMD and RaspberryPi" width="864" height="1536" class="size-full wp-image-157619" /></a> Signs show that Microsoft, AMD and RaspberryPi[/caption]

[caption id="attachment_157618" align="alignnone" width="864"]<a href="https://helloacm.com/cambridge-science-park-microsoft-amd-and-raspberry-pi-neighbours/cambridge-science-park-2025-09-05-14-55-42/" rel="attachment wp-att-157618"><img src="https://helloacm.com/wp-content/uploads/2025/11/cambridge-science-park-2025-09-05-14.55.42.jpg" alt="Signs show that Microsoft, AMD and RaspberryPi" width="864" height="1536" class="size-full wp-image-157618" /></a> Signs show that Microsoft, AMD and RaspberryPi[/caption]

[caption id="attachment_157617" align="alignnone" width="864"]<a href="https://helloacm.com/cambridge-science-park-microsoft-amd-and-raspberry-pi-neighbours/cambridge-science-park-2025-09-05-14-55-25/" rel="attachment wp-att-157617"><img src="https://helloacm.com/wp-content/uploads/2025/11/cambridge-science-park-2025-09-05-14.55.25.jpg" alt="Microsoft 198" width="864" height="1536" class="size-full wp-image-157617" /></a> Microsoft 198[/caption]

[caption id="attachment_157616" align="alignnone" width="2048"]<a href="https://helloacm.com/cambridge-science-park-microsoft-amd-and-raspberry-pi-neighbours/cambridge-science-park-2025-09-05-14-54-58/" rel="attachment wp-att-157616"><img src="https://helloacm.com/wp-content/uploads/2025/11/cambridge-science-park-2025-09-05-14.54.58-scaled.jpg" alt="Cambridge Science Park Views" width="2048" height="1152" class="size-full wp-image-157616" /></a> Cambridge Science Park Views[/caption]

[caption id="attachment_157615" align="alignnone" width="2048"]<a href="https://helloacm.com/cambridge-science-park-microsoft-amd-and-raspberry-pi-neighbours/cambridge-science-park-2025-09-05-14-54-09/" rel="attachment wp-att-157615"><img src="https://helloacm.com/wp-content/uploads/2025/11/cambridge-science-park-2025-09-05-14.54.09-scaled.jpg" alt="AMD at Cambridge Science Park" width="2048" height="1152" class="size-full wp-image-157615" /></a> AMD at Cambridge Science Park[/caption]

[caption id="attachment_157614" align="alignnone" width="2048"]<a href="https://helloacm.com/cambridge-science-park-microsoft-amd-and-raspberry-pi-neighbours/cambridge-science-park-2025-09-05-14-53-50/" rel="attachment wp-att-157614"><img src="https://helloacm.com/wp-content/uploads/2025/11/cambridge-science-park-2025-09-05-14.53.50-scaled.jpg" alt="Cambridge Science Park" width="2048" height="1152" class="size-full wp-image-157614" /></a> Cambridge Science Park[/caption]

[caption id="attachment_157613" align="alignnone" width="2048"]<a href="https://helloacm.com/cambridge-science-park-microsoft-amd-and-raspberry-pi-neighbours/cambridge-science-park-2025-09-05-13-58-05/" rel="attachment wp-att-157613"><img src="https://helloacm.com/wp-content/uploads/2025/11/cambridge-science-park-2025-09-05-13.58.05-scaled.jpg" alt="Hot Desk" width="2048" height="1152" class="size-full wp-image-157613" /></a> Hot Desk[/caption]

[caption id="attachment_157612" align="alignnone" width="2048"]<a href="https://helloacm.com/cambridge-science-park-microsoft-amd-and-raspberry-pi-neighbours/cambridge-science-park-2025-09-05-13-47-26/" rel="attachment wp-att-157612"><img src="https://helloacm.com/wp-content/uploads/2025/11/cambridge-science-park-2025-09-05-13.47.26-scaled.jpg" alt="Meeting Room" width="2048" height="1152" class="size-full wp-image-157612" /></a> Meeting Room[/caption]

[caption id="attachment_157611" align="alignnone" width="2048"]<a href="https://helloacm.com/cambridge-science-park-microsoft-amd-and-raspberry-pi-neighbours/cambridge-science-park-2025-09-05-12-27-11/" rel="attachment wp-att-157611"><img src="https://helloacm.com/wp-content/uploads/2025/11/cambridge-science-park-2025-09-05-12.27.11-scaled.jpg" alt="Cambridge Science Park Internal View" width="2048" height="1152" class="size-full wp-image-157611" /></a> Cambridge Science Park Internal View[/caption]

[show_file file="/var/www/wp-post-common/helloacm.com/microsoft.php"]

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/understanding-the-sigma-function-divisors-multiplicativity-and-the-formula/" rel="bookmark" title="Understanding the Sigma Function: Divisors, Multiplicativity, and the Formula">Understanding the Sigma Function: Divisors, Multiplicativity, and the Formula</a> <small>Understanding the Sigma Function: Divisors, Multiplicativity, and the Formula Understanding the Sigma Function: From Divisors...</small></li>
<li><a href="https://helloacm.com/how-to-securely-wipe-your-disk-and-what-happens-after-you-zero-your-disk-using-dd-on-linux/" rel="bookmark" title="How to Securely Wipe Your Disk and What Happens After You Zero Your Disk using dd on Linux?">How to Securely Wipe Your Disk and What Happens After You Zero Your Disk using dd on Linux?</a> <small>I decide to terminate one of my VPS server (QuickHostUK) and don&#8217;t want any data...</small></li>
<li><a href="https://helloacm.com/chatgpt-refactors-rewrites-the-code-using-promise-all-sending-requests-in-parallel/" rel="bookmark" title="ChatGPT Refactors/Rewrites the Code using Promise.All &#8211; Sending Requests in Parallel">ChatGPT Refactors/Rewrites the Code using Promise.All &#8211; Sending Requests in Parallel</a> <small>In one of my project, I have the following code (Node/Javascript) that invokes a few...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-reachable-nodes-with-restrictions-graph-theory-depth-first-search-algorithm/" rel="bookmark" title="Teaching Kids Programming &#8211; Reachable Nodes With Restrictions (Graph Theory, Recursive Depth First Search Algorithm, Undirected/Unweighted Graph)">Teaching Kids Programming &#8211; Reachable Nodes With Restrictions (Graph Theory, Recursive Depth First Search Algorithm, Undirected/Unweighted Graph)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms There is an undirected tree with...</small></li>
<li><a href="https://helloacm.com/understanding-dynamic_cast-in-c-safe-downcasting-explained/" rel="bookmark" title="Understanding dynamic_cast in C++: Safe Downcasting Explained">Understanding dynamic_cast in C++: Safe Downcasting Explained</a> <small>What Is dynamic_cast in C++? Purpose Safely convert between polymorphic types at runtime Commonly used...</small></li>
<li><a href="https://helloacm.com/telegram-accounts-are-shockingly-easy-to-hack-without-2fa/" rel="bookmark" title="Telegram Accounts Are Shockingly Easy to Hack Without 2FA">Telegram Accounts Are Shockingly Easy to Hack Without 2FA</a> <small>&#8220;How My Telegram Account Got Hacked—and What I Learned&#8221; &#8220;A Cautionary Tale: Telegram Security and...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-introduction-to-units-of-information-byte-kb-mb-gb-tb-pb/" rel="bookmark" title="Teaching Kids Programming &#8211; Introduction to Units of Information (Byte, KB, MB, GB, TB, PB)">Teaching Kids Programming &#8211; Introduction to Units of Information (Byte, KB, MB, GB, TB, PB)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms Information is the lifeblood of the...</small></li>
<li><a href="https://helloacm.com/the-common-include-php-file-for-my-sites/" rel="bookmark" title="The Common Include PHP File For My Sites">The Common Include PHP File For My Sites</a> <small>I think you may have some common code to write for most of the PHP...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://helloacm.com/cambridge-science-park-microsoft-amd-and-raspberry-pi-neighbours/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Understanding the Sigma Function: Divisors, Multiplicativity, and the Formula</title>
		<link>https://helloacm.com/understanding-the-sigma-function-divisors-multiplicativity-and-the-formula/</link>
					<comments>https://helloacm.com/understanding-the-sigma-function-divisors-multiplicativity-and-the-formula/#respond</comments>
		
		<dc:creator><![CDATA[ACMer]]></dc:creator>
		<pubDate>Tue, 25 Nov 2025 22:57:11 +0000</pubDate>
				<category><![CDATA[math]]></category>
		<category><![CDATA[Prime Numbers]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[arithmetic functions]]></category>
		<category><![CDATA[computational math]]></category>
		<category><![CDATA[divisor function]]></category>
		<category><![CDATA[divisor sum]]></category>
		<category><![CDATA[geometric series]]></category>
		<category><![CDATA[math code]]></category>
		<category><![CDATA[math derivation]]></category>
		<category><![CDATA[math formulas]]></category>
		<category><![CDATA[math tutorial]]></category>
		<category><![CDATA[mathematics]]></category>
		<category><![CDATA[multiplicative functions]]></category>
		<category><![CDATA[number theory]]></category>
		<category><![CDATA[Prime Factorization]]></category>
		<category><![CDATA[primes]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[Python Programming]]></category>
		<category><![CDATA[sigma function]]></category>
		<category><![CDATA[sigma notation]]></category>
		<category><![CDATA[sum of divisors]]></category>
		<guid isPermaLink="false">https://helloacm.com/?p=157594</guid>

					<description><![CDATA[<h1>Understanding the Sigma Function: Divisors, Multiplicativity, and the Formula</h1>
<blockquote>
Understanding the Sigma Function: From Divisors to a Powerful Closed Formula
Why the Sigma Function Is Multiplicative: A Step-by-Step Derivation
The Mathematics Behind σ(n): Divisors, Prime Powers, and the Product Formula
A Deep Dive Into the Sum-of-Divisors Function (σ): Theory + Python Code
Decoding σ(n): The Elegant Structure of Divisors and the Geometric Series Trick
Prime Factorization Magic: How the Sigma Function Really Works
Sigma Function Explained Clearly — With Proofs and Efficient Python Code
</blockquote>

The sigma function, often written as [math]\sigma(n)[/math], returns the sum of all positive <a href="https://helloacm.com/teaching-kids-programming-three-divisors/" title="Teaching Kids Programming – Algorithm to Determine Three Divisors Numbers">divisors</a> of an integer. For example, the divisors of 12 are 1, 2, 3, 4, 6, and 12, so [math]\sigma(12)=28[/math]. In this article, we explore what the sigma function is, why it obeys a multiplicative rule, and how we derive the closed-form formula using prime factorization. Finally, we provide a Python implementation to compute it efficiently.

<h2>Divisibility Notation</h2>

In number theory, the symbol “|” means “divides.”

[math]d \mid a \quad \Longleftrightarrow \quad \exists k \in \mathbb{Z},\; a = dk[/math]

So in the expression [math]\sum_{d \mid n} d[/math], the notation means “sum over all divisors d of n.”

<h2>Prime Factorization and Divisors</h2>

Every positive integer [math]n[/math] can be written uniquely as a product of prime powers:

[math]n = p_1^{a_1} p_2^{a_2} \cdots p_k^{a_k}[/math]

Understanding the structure of divisors begins here. A divisor of [math]n[/math] must choose an exponent for each prime:

[math]d = p_1^{e_1} p_2^{e_2} \cdots p_k^{e_k}, \qquad 0 \le e_i \le a_i[/math]

All divisor-related properties follow from this simple but powerful fact.

<h2>The Key Insight: Sigma Is Multiplicative</h2>

The sigma function satisfies the following rule when two integers share no common <a href="https://helloacm.com/euclids-theorem-proof-of-unlimited-prime-numbers/" title="Euclid’s theorem – Proof of Unlimited Prime Numbers">prime</a> factors:

[math]\sigma(mn) = \sigma(m)\,\sigma(n) \qquad \text{if } \gcd(m,n)=1[/math]

Why does this work? Because when [math]m[/math] and [math]n[/math] are coprime, their <a href="https://doctorlai.github.io/prime-factorization/" title="prime factorizations" rel="noopener nofollow " target="_blank">prime factorizations</a> do not overlap. Therefore every divisor of [math]mn[/math] corresponds to one unique divisor of [math]m[/math] multiplied by one unique divisor of [math]n[/math].

Formally:

[math]d \mid mn \quad \Longleftrightarrow \quad d = d_m d_n, \; d_m \mid m, \; d_n \mid n[/math]

When we sum all divisors of [math]mn[/math], this becomes a double sum:

[math]\sigma(mn) = \sum_{d_m \mid m} \sum_{d_n \mid n} d_m d_n[/math]

We now factor the double sum. Fix a particular divisor [math]d_m[/math]. Then:

[math]\sum_{d_n \mid n} (d_m d_n) = d_m \sum_{d_n \mid n} d_n = d_m \sigma(n)[/math]

Now sum over all [math]d_m[/math]:

[math]\sigma(mn) = \sum_{d_m \mid m} d_m \sigma(n) = \sigma(n) \sum_{d_m \mid m} d_m = \sigma(n)\sigma(m)[/math]

This proves the multiplicativity of the sigma function.

<h2>The Sigma Formula for Prime Powers</h2>

Once we know that sigma is multiplicative, we only need to calculate [math]\sigma(p^k)[/math] for a prime power. Its divisors are:

[math]1, p, p^2, \ldots, p^k[/math]

This is a geometric series, and its sum is:

[math]\sigma(p^k) = 1 + p + p^2 + \cdots + p^k = \frac{p^{k+1} - 1}{p - 1}[/math]

Using multiplicativity gives us the general sigma formula:

[math]\sigma(n) = \prod_{i=1}^k \frac{p_i^{a_i+1} - 1}{p_i - 1}[/math]

This is the closed-form expression for the sum of <a href="https://helloacm.com/finding-the-closest-divisors/" title="Finding the Closest Divisors">divisors</a> of any positive integer.

<h2>Example: Computing σ(12)</h2>

Factorize:

[math]12 = 2^2 \cdot 3^1[/math]

Compute each part:

[math]\sigma(2^2) = 1 + 2 + 4 = 7[/math]
[math]\sigma(3^1) = 1 + 3 = 4[/math]

Multiply:

[math]\sigma(12) = 7 \cdot 4 = 28[/math]

<h2>Python Code: Efficient Sigma Function</h2>

Below is a fast Python implementation that factorizes the integer and uses the multiplicative rule. This runs in approximately [math]O(\sqrt{n})[/math] time.

<pre lang=py>
def sigma(n: int) -&gt; int:
    """Efficient computation of the sum-of-divisors function σ(n)."""
    total = 1
    x = n

    # Factor out powers of 2
    count = 0
    while x % 2 == 0:
        x //= 2
        count += 1
    if count &gt; 0:
        total *= (2 ** (count + 1) - 1) // (2 - 1)

    # Factor odd primes
    p = 3
    while p * p &lt;= x:
        if x % p == 0:
            count = 0
            while x % p == 0:
                x //= p
                count += 1
            total *= (p ** (count + 1) - 1) // (p - 1)
        p += 2

    # Remaining prime factor
    if x &gt; 1:
        total *= (x**2 - 1) // (x - 1)

    return total
</pre>

<h2>Conclusion</h2>

The sigma function beautifully illustrates the structure of divisors and the power of prime factorization. By understanding multiplicativity and the geometric series sum, we obtain an elegant closed formula that leads to efficient computation. With theory and code combined, you now have both intuition and a practical tool for exploring divisor functions.

[show_file file="/var/www/wp-post-common/helloacm.com/math.php"]

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/teaching-kids-programming-k-items-with-the-maximum-sum/" rel="bookmark" title="Teaching Kids Programming &#8211; K Items With the Maximum Sum">Teaching Kids Programming &#8211; K Items With the Maximum Sum</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms There is a bag that consists...</small></li>
<li><a href="https://helloacm.com/modern-getch-implementation-on-windows-cc/" rel="bookmark" title="Modern getch() implementation on Windows C/C++">Modern getch() implementation on Windows C/C++</a> <small>In the DOS era, where 16-bit applications are dominant, the DOS compilers such as Turbo...</small></li>
<li><a href="https://helloacm.com/toss-a-coin-256-times-the-math-behind-an-unbreakable-bitcoin-private-key/" rel="bookmark" title="Toss a Coin 256 Times: The Math Behind an Unbreakable Bitcoin Private Key">Toss a Coin 256 Times: The Math Behind an Unbreakable Bitcoin Private Key</a> <small>Why Cracking a Bitcoin Key Is Harder Than You Can Possibly Imagine I often see...</small></li>
<li><a href="https://helloacm.com/introduction-to-passive-incomes/" rel="bookmark" title="Introduction to Passive Income(s)">Introduction to Passive Income(s)</a> <small>Often, you need some passive income(s) to achieve the FIRE = Finance Independence, Retire Early....</small></li>
<li><a href="https://helloacm.com/c-forward-references-the-key-to-perfect-forwarding/" rel="bookmark" title="C++ Forward References: The Key to Perfect Forwarding">C++ Forward References: The Key to Perfect Forwarding</a> <small>In modern C++ (C++11 and beyond), a powerful feature called forward references enables developers to...</small></li>
<li><a href="https://helloacm.com/how-to-partition-array-into-disjoint-intervals/" rel="bookmark" title="How to Partition Array into Disjoint Intervals?">How to Partition Array into Disjoint Intervals?</a> <small>Given an array A, partition it into two (contiguous) subarrays left and right so that:...</small></li>
<li><a href="https://helloacm.com/c-lvalue-rvalue-and-rvalue-references/" rel="bookmark" title="C++: lvalue, rvalue and rvalue references">C++: lvalue, rvalue and rvalue references</a> <small>C++ lvalue, rvalue, and rvalue references Understanding lvalues, rvalues, and rvalue references is essential for...</small></li>
<li><a href="https://helloacm.com/trick-count-the-number-of-api-in-com/" rel="bookmark" title="Trick: Count the Number of API in COM">Trick: Count the Number of API in COM</a> <small>Delphi is a handy tool to develop the COM (Component Object Model) DLL. A *_TLB.pas...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<h1>Understanding the Sigma Function: Divisors, Multiplicativity, and the Formula</h1>
<blockquote>
Understanding the Sigma Function: From Divisors to a Powerful Closed Formula
Why the Sigma Function Is Multiplicative: A Step-by-Step Derivation
The Mathematics Behind σ(n): Divisors, Prime Powers, and the Product Formula
A Deep Dive Into the Sum-of-Divisors Function (σ): Theory + Python Code
Decoding σ(n): The Elegant Structure of Divisors and the Geometric Series Trick
Prime Factorization Magic: How the Sigma Function Really Works
Sigma Function Explained Clearly — With Proofs and Efficient Python Code
</blockquote>

The sigma function, often written as [math]\sigma(n)[/math], returns the sum of all positive <a href="https://helloacm.com/teaching-kids-programming-three-divisors/" title="Teaching Kids Programming – Algorithm to Determine Three Divisors Numbers">divisors</a> of an integer. For example, the divisors of 12 are 1, 2, 3, 4, 6, and 12, so [math]\sigma(12)=28[/math]. In this article, we explore what the sigma function is, why it obeys a multiplicative rule, and how we derive the closed-form formula using prime factorization. Finally, we provide a Python implementation to compute it efficiently.

<h2>Divisibility Notation</h2>

In number theory, the symbol “|” means “divides.”

[math]d \mid a \quad \Longleftrightarrow \quad \exists k \in \mathbb{Z},\; a = dk[/math]

So in the expression [math]\sum_{d \mid n} d[/math], the notation means “sum over all divisors d of n.”

<h2>Prime Factorization and Divisors</h2>

Every positive integer [math]n[/math] can be written uniquely as a product of prime powers:

[math]n = p_1^{a_1} p_2^{a_2} \cdots p_k^{a_k}[/math]

Understanding the structure of divisors begins here. A divisor of [math]n[/math] must choose an exponent for each prime:

[math]d = p_1^{e_1} p_2^{e_2} \cdots p_k^{e_k}, \qquad 0 \le e_i \le a_i[/math]

All divisor-related properties follow from this simple but powerful fact.

<h2>The Key Insight: Sigma Is Multiplicative</h2>

The sigma function satisfies the following rule when two integers share no common <a href="https://helloacm.com/euclids-theorem-proof-of-unlimited-prime-numbers/" title="Euclid’s theorem – Proof of Unlimited Prime Numbers">prime</a> factors:

[math]\sigma(mn) = \sigma(m)\,\sigma(n) \qquad \text{if } \gcd(m,n)=1[/math]

Why does this work? Because when [math]m[/math] and [math]n[/math] are coprime, their <a href="https://doctorlai.github.io/prime-factorization/" title="prime factorizations" rel="noopener nofollow " target="_blank">prime factorizations</a> do not overlap. Therefore every divisor of [math]mn[/math] corresponds to one unique divisor of [math]m[/math] multiplied by one unique divisor of [math]n[/math].

Formally:

[math]d \mid mn \quad \Longleftrightarrow \quad d = d_m d_n, \; d_m \mid m, \; d_n \mid n[/math]

When we sum all divisors of [math]mn[/math], this becomes a double sum:

[math]\sigma(mn) = \sum_{d_m \mid m} \sum_{d_n \mid n} d_m d_n[/math]

We now factor the double sum. Fix a particular divisor [math]d_m[/math]. Then:

[math]\sum_{d_n \mid n} (d_m d_n) = d_m \sum_{d_n \mid n} d_n = d_m \sigma(n)[/math]

Now sum over all [math]d_m[/math]:

[math]\sigma(mn) = \sum_{d_m \mid m} d_m \sigma(n) = \sigma(n) \sum_{d_m \mid m} d_m = \sigma(n)\sigma(m)[/math]

This proves the multiplicativity of the sigma function.

<h2>The Sigma Formula for Prime Powers</h2>

Once we know that sigma is multiplicative, we only need to calculate [math]\sigma(p^k)[/math] for a prime power. Its divisors are:

[math]1, p, p^2, \ldots, p^k[/math]

This is a geometric series, and its sum is:

[math]\sigma(p^k) = 1 + p + p^2 + \cdots + p^k = \frac{p^{k+1} - 1}{p - 1}[/math]

Using multiplicativity gives us the general sigma formula:

[math]\sigma(n) = \prod_{i=1}^k \frac{p_i^{a_i+1} - 1}{p_i - 1}[/math]

This is the closed-form expression for the sum of <a href="https://helloacm.com/finding-the-closest-divisors/" title="Finding the Closest Divisors">divisors</a> of any positive integer.

<h2>Example: Computing σ(12)</h2>

Factorize:

[math]12 = 2^2 \cdot 3^1[/math]

Compute each part:

[math]\sigma(2^2) = 1 + 2 + 4 = 7[/math]
[math]\sigma(3^1) = 1 + 3 = 4[/math]

Multiply:

[math]\sigma(12) = 7 \cdot 4 = 28[/math]

<h2>Python Code: Efficient Sigma Function</h2>

Below is a fast Python implementation that factorizes the integer and uses the multiplicative rule. This runs in approximately [math]O(\sqrt{n})[/math] time.

<pre lang=py>
def sigma(n: int) -&gt; int:
    """Efficient computation of the sum-of-divisors function σ(n)."""
    total = 1
    x = n

    # Factor out powers of 2
    count = 0
    while x % 2 == 0:
        x //= 2
        count += 1
    if count &gt; 0:
        total *= (2 ** (count + 1) - 1) // (2 - 1)

    # Factor odd primes
    p = 3
    while p * p &lt;= x:
        if x % p == 0:
            count = 0
            while x % p == 0:
                x //= p
                count += 1
            total *= (p ** (count + 1) - 1) // (p - 1)
        p += 2

    # Remaining prime factor
    if x &gt; 1:
        total *= (x**2 - 1) // (x - 1)

    return total
</pre>

<h2>Conclusion</h2>

The sigma function beautifully illustrates the structure of divisors and the power of prime factorization. By understanding multiplicativity and the geometric series sum, we obtain an elegant closed formula that leads to efficient computation. With theory and code combined, you now have both intuition and a practical tool for exploring divisor functions.

[show_file file="/var/www/wp-post-common/helloacm.com/math.php"]

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/teaching-kids-programming-k-items-with-the-maximum-sum/" rel="bookmark" title="Teaching Kids Programming &#8211; K Items With the Maximum Sum">Teaching Kids Programming &#8211; K Items With the Maximum Sum</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms There is a bag that consists...</small></li>
<li><a href="https://helloacm.com/modern-getch-implementation-on-windows-cc/" rel="bookmark" title="Modern getch() implementation on Windows C/C++">Modern getch() implementation on Windows C/C++</a> <small>In the DOS era, where 16-bit applications are dominant, the DOS compilers such as Turbo...</small></li>
<li><a href="https://helloacm.com/toss-a-coin-256-times-the-math-behind-an-unbreakable-bitcoin-private-key/" rel="bookmark" title="Toss a Coin 256 Times: The Math Behind an Unbreakable Bitcoin Private Key">Toss a Coin 256 Times: The Math Behind an Unbreakable Bitcoin Private Key</a> <small>Why Cracking a Bitcoin Key Is Harder Than You Can Possibly Imagine I often see...</small></li>
<li><a href="https://helloacm.com/introduction-to-passive-incomes/" rel="bookmark" title="Introduction to Passive Income(s)">Introduction to Passive Income(s)</a> <small>Often, you need some passive income(s) to achieve the FIRE = Finance Independence, Retire Early....</small></li>
<li><a href="https://helloacm.com/c-forward-references-the-key-to-perfect-forwarding/" rel="bookmark" title="C++ Forward References: The Key to Perfect Forwarding">C++ Forward References: The Key to Perfect Forwarding</a> <small>In modern C++ (C++11 and beyond), a powerful feature called forward references enables developers to...</small></li>
<li><a href="https://helloacm.com/how-to-partition-array-into-disjoint-intervals/" rel="bookmark" title="How to Partition Array into Disjoint Intervals?">How to Partition Array into Disjoint Intervals?</a> <small>Given an array A, partition it into two (contiguous) subarrays left and right so that:...</small></li>
<li><a href="https://helloacm.com/c-lvalue-rvalue-and-rvalue-references/" rel="bookmark" title="C++: lvalue, rvalue and rvalue references">C++: lvalue, rvalue and rvalue references</a> <small>C++ lvalue, rvalue, and rvalue references Understanding lvalues, rvalues, and rvalue references is essential for...</small></li>
<li><a href="https://helloacm.com/trick-count-the-number-of-api-in-com/" rel="bookmark" title="Trick: Count the Number of API in COM">Trick: Count the Number of API in COM</a> <small>Delphi is a handy tool to develop the COM (Component Object Model) DLL. A *_TLB.pas...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://helloacm.com/understanding-the-sigma-function-divisors-multiplicativity-and-the-formula/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Why Parallelism Isn’t Infinite: Amdahl vs Gustafson Explained Simply</title>
		<link>https://helloacm.com/why-parallelism-isnt-infinite-amdahl-vs-gustafson-explained-simply/</link>
					<comments>https://helloacm.com/why-parallelism-isnt-infinite-amdahl-vs-gustafson-explained-simply/#respond</comments>
		
		<dc:creator><![CDATA[ACMer]]></dc:creator>
		<pubDate>Wed, 19 Nov 2025 13:28:52 +0000</pubDate>
				<category><![CDATA[code]]></category>
		<category><![CDATA[computational theory]]></category>
		<category><![CDATA[Computer Science]]></category>
		<category><![CDATA[parallel computing]]></category>
		<category><![CDATA[programming languages]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[technical]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[Amdahls Law]]></category>
		<category><![CDATA[Gustafson's law]]></category>
		<category><![CDATA[high-performance-computing]]></category>
		<category><![CDATA[HPC]]></category>
		<category><![CDATA[multicore programming]]></category>
		<category><![CDATA[Parallel Computing]]></category>
		<category><![CDATA[parallel performance]]></category>
		<category><![CDATA[performance modeling]]></category>
		<category><![CDATA[Python plotting]]></category>
		<category><![CDATA[Scalability]]></category>
		<category><![CDATA[speedup]]></category>
		<guid isPermaLink="false">https://helloacm.com/?p=157576</guid>

					<description><![CDATA[<h1>Amdahl’s Law vs. Gustafson’s Law — Full Tutorial with Derivations, Use Cases, and Python Plot</h1>
<blockquote>
Amdahl’s Law vs Gustafson’s Law: Full Tutorial, Derivations, Use Cases, and Python Plot
Understanding Parallel Speedup: Amdahl’s Law and Gustafson’s Law Explained with Code
Parallel Computing Essentials: Amdahl’s Law, Gustafson’s Law, and Speedup Modeling
How Parallel Speedup Works: Complete Guide to Amdahl’s and Gustafson’s Laws
Parallel Scaling Explained: Deriving and Comparing Amdahl’s and Gustafson’s Laws
Amdahl vs Gustafson: The Complete Guide to Parallel Speedup (with Python Code)
Parallel Performance Modeling: Amdahl’s Law, Gustafson’s Law, and Real-World Use Cases
Learn Parallel Speedup: Math, Intuition, Use Cases, and Python Visualization
Parallel Computing: The Two Laws You Must Know (Amdahl & Gustafson)
Parallel Speedup for Engineers: Amdahl’s Law, Gustafson’s Law, and Python Implementation
From Theory to Code: Modeling Parallel Speedup with Amdahl and Gustafson
A Practical Guide to Parallel Speedup: Amdahl’s Law, Gustafson’s Law, and Visualization
Why Parallelism Isn’t Infinite: Amdahl vs Gustafson Explained Simply
The Truth About Parallel Speedup: Amdahl’s Limits vs Gustafson’s Scaling
Parallel Computing Myths vs Reality: What Amdahl and Gustafson Teach Us
</blockquote>

<h2>Introduction</h2>
Parallel computing is essential in modern computing: multi-core CPUs, GPUs, distributed <a href="https://helloacm.com/docker-virtual-machines-vms-and-kubernetes-k8s/" title="Docker, Virtual Machines (VMs) and Kubernetes (K8s)">clusters</a>, cloud workloads, LLM training, and HPC simulations.  
To reason about how much faster a program becomes with more processors, two mathematical models dominate:

<ul>
  <li><strong>Amdahl’s Law</strong> — fixed-size workload performance</li>
  <li><strong>Gustafson’s Law</strong> — scaled-size workload performance</li>
</ul>

These two laws are not contradictory. They answer <em>different questions</em>.  
This tutorial covers derivations, intuition, comparisons, practical use cases, and a Python plotting script showing both laws together.

<h2>1. What Is Speedup?</h2>
Speedup measures how much faster a program runs with <em>N</em> processors:

[math]S(N) = \frac{T_1}{T_N}[/math]

If a program takes 10 seconds on one <a href="https://helloacm.com/the-hidden-engine-of-performance-its-all-about-where-the-data-lives-cache-is-the-king/" title="The Hidden Engine of Performance: It’s All About Where the Data Lives (Cache is the King)">processor</a> and 5 seconds on two, speedup is:

[math]S(2) = \frac{10}{5} = 2[/math]

Perfect linear speedup would be:

[math]S(N) = N[/math]

But real systems contain serial bottlenecks. This is what Amdahl’s and Gustafson’s laws describe.

<h2>2. Amdahl’s Law (Fixed Workload)</h2>
<h3>2.1 Intuition</h3>
Amdahl assumes:

<ul>
  <li>The total amount of work stays the <strong>same</strong></li>
  <li>A portion is serial and cannot be parallelized</li>
</ul>

Let:

<ul>
  <li><code>f</code> = serial fraction</li>
  <li><code>1 - f</code> = parallel fraction</li>
</ul>

<h3>2.2 Derivation</h3>

Time on one processor:

[math]T_1 = T_s + T_p[/math]

Define:

[math]f = \frac{T_s}{T_1}[/math]

Thus:

[math]T_s = fT_1[/math]  
[math]T_p = (1 - f)T_1[/math]

Time on <em>N</em> processors:

[math]T_N = fT_1 + \frac{(1 - f)T_1}{N}[/math]

Speedup:

[math] S(N) = \frac{T_1}{T_N} = \frac{1}{f + \frac{1 - f}{N}} [/math]

Where f is the portion of the serial work and [math] 1-f [/math] is the work that can be parallelized. Amdahl's formula can be also rewritten as using [math] p [/math]:

[math] S(N) = \frac{T_1}{T_N} = \frac{1}{(1-p) + \frac{p}{N}} [/math]

As [math] p=1-f [/math] and [math] f=1-p [/math]

<h3>2.3 Limit as N → ∞</h3>

[math]S(\infty) = \frac{1}{f}[/math]

If the serial fraction is 10% (f = 0.1):

[math]S_\infty = 10[/math]

Even infinite processors cannot exceed that.

<h3>2.4 Practical Use Cases for Amdahl’s Law</h3>

Amdahl is ideal when optimizing <strong>latency</strong> for a fixed task:

<ul>
  <li>GPU kernel optimization for fixed tensor size</li>
  <li>Reducing inference latency for a single request</li>
  <li>Video encoding, compression, sorting</li>
  <li>Making a fixed-size batch job run faster</li>
  <li>Database query acceleration</li>
</ul>

<hr />

<h2>3. Gustafson’s Law (Scaled Workload)</h2>

<h3>3.1 Intuition</h3>
Gustafson reverses the question:

<strong>“With more processors, how much larger a problem can I solve in the same time?”</strong>

This reflects real HPC workloads: more CPUs → finer resolution → bigger simulations.

<h3>3.2 Derivation</h3>

Assume the program runs in 1 time unit on <em>N</em> processors.

Let:

<ul> <li><code>f</code> = serial fraction (measured at scale)</li> </ul>

The parallel portion scales with the number of processors, so its runtime remains proportional to N.

Time on one processor:

[math]T_1 = f + N(1 - f)[/math]

Thus, the speedup is:

[math]S(N) = f + N(1 - f)[/math]

We can re-write Gustafson’s formula in “N minus” form:

[math]S(N) = N - (N - 1)f[/math]

Or, if we define the parallel fraction as [math]p = 1 - f[/math], the formula can also be written as:

[math]S(N) = f + N(1-f) = f + Np [/math]

Now the "N minus" form in terms of p becomes:

[math] S(N) = N-(N-1)f = N - (N-1)(1-p) [/math]

<h3>3.3 Interpretation</h3>

As <em>N</em> increases, speedup approaches:

[math]S(N) \approx N(1 - f)[/math]

This is nearly linear for small serial fractions.

<h3>3.4 Practical Use Cases for Gustafson’s Law</h3>

Use Gustafson for <strong>throughput scaling</strong> or workloads where you can increase problem size:

<ul>
  <li>Weather and climate simulations</li>
  <li>Particle simulations, CFD, finite element analysis</li>
  <li>LLM training: more GPUs → longer sequences or bigger models</li>
  <li>Big data analytics (Spark, Dask, Flink)</li>
  <li>Monte Carlo simulations</li>
</ul>

<hr />

<h2>4. Amdahl’s Law vs. Gustafson’s Law (Comparison Table)</h2>

<table>
  <tr><th>Item</th><th>Amdahl</th><th>Gustafson</th></tr>
  <tr><td>Workload</td><td>Fixed</td><td>Scales with N</td></tr>
  <tr><td>Goal</td><td>Reduce latency</td><td>Increase throughput</td></tr>
  <tr><td>Speedup limit</td><td>Bounded: [math]1/f[/math]</td><td>Nearly linear: [math]N(1-f)[/math]</td></tr>
  <tr><td>Pessimistic/Optimistic</td><td>Pessimistic</td><td>Optimistic</td></tr>
  <tr><td>Use cases</td><td>Optimizing existing tasks</td><td>Scaling larger workloads</td></tr>
</table>

<hr />

<h2>5. Practical Use Cases (Combined View)</h2>

<h3>Amdahl (Latency Optimization)</h3>
<ul>
  <li>Reducing inference time for one LLM query</li>
  <li>Speeding up database joins</li>
  <li>GPU kernel tweaks for fixed tensors</li>
  <li>Video encoding (same video)</li>
</ul>

<h3>Gustafson (Throughput / Scale)</h3>
<ul>
  <li>LLM training (scale to more GPUs)</li>
  <li>Simulating higher-resolution weather models</li>
  <li>Big data ETL scaling</li>
  <li>Scientific HPC workloads</li>
</ul>

<h2>6. Python Script to Plot Both Laws</h2>
The code below generates a graph showing Amdahl’s and Gustafson’s speedup curves.  

You can adjust <code>f</code> (serial fraction) and the number of processors <code>N</code>.

The following script plots Amdahl and Gustafson <a href="https://helloacm.com/two-most-effective-freeware-to-speedup-computer-ccleaner-and-defraggler/" title="Two Most Effective Freeware to Speedup Computer: CCleaner and Defraggler">speedup</a> curves on the same graph.

It includes a few values of [math]f[/math] e.g. the serial portion:

<pre lang=py>
import numpy as np
import matplotlib.pyplot as plt

def amdahl_speedup(N, s):
    return 1.0 / (s + (1 - s) / N)

def gustafson_speedup(N, s):
    return s + (1 - s) * N

# Number of processors
N = np.arange(1, 65)

# Serial fractions to consider
Serial = [0.05, 0.1, 0.2, 0.3, 0.5, 0.8, 0.9, 1.0]

plt.figure(figsize=(10, 6))

for f in Serial:
    plt.plot(N, amdahl_speedup(N, f), linestyle='-', label=f"Amdahl Serial={f}")
    plt.plot(N, gustafson_speedup(N, f), linestyle='--', label=f"Gustafson Serial={f}")

plt.title("Amdahl's Law")
plt.xlabel("Number of Processors (N)")
plt.ylabel("Speedup")
plt.legend()
plt.grid(True)
plt.tight_layout()

plt.savefig("parallel-speedup-amdahl-vs-gustafson.png")
## plt.show()
</pre>

Here are the plots of the <a href="https://helloacm.com/teaching-kids-programming-estimating-the-performance-speedup-gain-using-amdahls-law/" title="Teaching Kids Programming – Estimating the Performance Speedup (Gain) using Amdahls Law">Amdahl's</a> vs Gustafson.

[caption id="attachment_157582" align="alignnone" width="1000"]<a href="https://helloacm.com/why-parallelism-isnt-infinite-amdahl-vs-gustafson-explained-simply/parallel-speedup-amdahl/" rel="attachment wp-att-157582"><img src="https://helloacm.com/wp-content/uploads/2025/11/parallel-speedup-amdahl.png" alt="Parallel Speedup (Amdahl&#039;s Law)" width="1000" height="600" class="size-full wp-image-157582" /></a> Parallel Speedup (Amdahl's Law)[/caption]

[caption id="attachment_157583" align="alignnone" width="1000"]<a href="https://helloacm.com/why-parallelism-isnt-infinite-amdahl-vs-gustafson-explained-simply/parallel-speedup-amdahl-vs-gustafson/" rel="attachment wp-att-157583"><img src="https://helloacm.com/wp-content/uploads/2025/11/parallel-speedup-amdahl-vs-gustafson.png" alt="Parallel Speedup (Amdahl&#039;s Law vs Gustafson)" width="1000" height="600" class="size-full wp-image-157583" /></a> Parallel Speedup (Amdahl's Law vs Gustafson)[/caption]

[caption id="attachment_157584" align="alignnone" width="1000"]<a href="https://helloacm.com/why-parallelism-isnt-infinite-amdahl-vs-gustafson-explained-simply/parallel-speedup-gustafson/" rel="attachment wp-att-157584"><img src="https://helloacm.com/wp-content/uploads/2025/11/parallel-speedup-gustafson.png" alt="Parallel Speedup (Gustafson)" width="1000" height="600" class="size-full wp-image-157584" /></a> Parallel Speedup (Gustafson)[/caption]

<h2>Interpreting the Plots</h2>

<ul>
<li>Amdahl curves flatten quickly—bottlenecked by the sequential portion.</li>
<li>Gustafson curves rise almost linearly—useful when workloads can scale.</li>
<li>Higher <code>f</code> increases the gap between the two models.</li>
</ul>

<h2>Conclusion</h2>
Amdahl’s Law shows the <strong>limits</strong> of parallelism for fixed workloads, making it ideal for latency optimization. Gustafson’s Law shows the <strong>opportunities</strong> of parallelism when workloads scale with compute.  

<ul>
<li>Amdahl’s Law → fixed-size workloads → diminishing returns</li>
<li>Gustafson’s Law → scalable workloads → near-linear speedup</li>
<li>Use both to understand hardware limits and the nature of your algorithm</li>
<li>Python tools make visualization simple and intuitive</li>
</ul>

Together, they form the foundation of reasoning about performance in modern <a href="https://helloacm.com/chatgpt-refactors-rewrites-the-code-using-promise-all-sending-requests-in-parallel/" title="ChatGPT Refactors/Rewrites the Code using Promise.All – Sending Requests in Parallel">parallel</a> systems, from HPC to LLM training to GPU compute.

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/how-to-compute-kth-largest-element-in-a-stream/" rel="bookmark" title="How to Compute Kth Largest Element in a Stream?">How to Compute Kth Largest Element in a Stream?</a> <small>Design a class to find the kth largest element in a stream. Note that it...</small></li>
<li><a href="https://helloacm.com/simple-and-fast-hash-functions-in-delphi/" rel="bookmark" title="Simple and Fast Hash Functions in Delphi">Simple and Fast Hash Functions in Delphi</a> <small>A Hash function returns a 32-bit (or sometimes 64-bit) integers for any given length of...</small></li>
<li><a href="https://helloacm.com/how-to-print-immutable-linked-list-in-reverse-using-recursion-or-stack/" rel="bookmark" title="How to Print Immutable Linked List in Reverse using Recursion or Stack?">How to Print Immutable Linked List in Reverse using Recursion or Stack?</a> <small>You are given an immutable linked list, print out all values of each node in...</small></li>
<li><a href="https://helloacm.com/different-ways-of-loading-javascript-files-in-a-javascript-file/" rel="bookmark" title="Different ways of Loading Javascript Files in a Javascript File">Different ways of Loading Javascript Files in a Javascript File</a> <small>The javascript (in HTML, the browser DOM i.e. Document Object Model) does not have a...</small></li>
<li><a href="https://helloacm.com/model-view-controller-explained-in-c/" rel="bookmark" title="Model-View-Controller Explained in C++">Model-View-Controller Explained in C++</a> <small>The Model-View-Controller (MVC) is not a technology, but a concept in software design/engineering. The MVC...</small></li>
<li><a href="https://helloacm.com/add-to-favorite-using-javascript/" rel="bookmark" title="How to Add To Favorite using Javascript?">How to Add To Favorite using Javascript?</a> <small>We all know that in most modern browsers, you can use the short key Ctrl...</small></li>
<li><a href="https://helloacm.com/visual-studio-net-4-0-disables-com-dll-protected-by-vmprotect/" rel="bookmark" title="Visual Studio .NET 4.0 Disables COM DLL protected by VMProtect">Visual Studio .NET 4.0 Disables COM DLL protected by VMProtect</a> <small>The VMProtect (www.vmpsoft.com) is a great commercial tool that can be used to protect Win32/64...</small></li>
<li><a href="https://helloacm.com/3-types-of-coding-languages-that-will-intrigue-educate-youngsters/" rel="bookmark" title="3 Types of Coding Languages That Will Intrigue &#038; Educate Youngsters">3 Types of Coding Languages That Will Intrigue &#038; Educate Youngsters</a> <small>Those who learn coding languages are likely to have a bright future ahead of them....</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<h1>Amdahl’s Law vs. Gustafson’s Law — Full Tutorial with Derivations, Use Cases, and Python Plot</h1>
<blockquote>
Amdahl’s Law vs Gustafson’s Law: Full Tutorial, Derivations, Use Cases, and Python Plot
Understanding Parallel Speedup: Amdahl’s Law and Gustafson’s Law Explained with Code
Parallel Computing Essentials: Amdahl’s Law, Gustafson’s Law, and Speedup Modeling
How Parallel Speedup Works: Complete Guide to Amdahl’s and Gustafson’s Laws
Parallel Scaling Explained: Deriving and Comparing Amdahl’s and Gustafson’s Laws
Amdahl vs Gustafson: The Complete Guide to Parallel Speedup (with Python Code)
Parallel Performance Modeling: Amdahl’s Law, Gustafson’s Law, and Real-World Use Cases
Learn Parallel Speedup: Math, Intuition, Use Cases, and Python Visualization
Parallel Computing: The Two Laws You Must Know (Amdahl & Gustafson)
Parallel Speedup for Engineers: Amdahl’s Law, Gustafson’s Law, and Python Implementation
From Theory to Code: Modeling Parallel Speedup with Amdahl and Gustafson
A Practical Guide to Parallel Speedup: Amdahl’s Law, Gustafson’s Law, and Visualization
Why Parallelism Isn’t Infinite: Amdahl vs Gustafson Explained Simply
The Truth About Parallel Speedup: Amdahl’s Limits vs Gustafson’s Scaling
Parallel Computing Myths vs Reality: What Amdahl and Gustafson Teach Us
</blockquote>

<h2>Introduction</h2>
Parallel computing is essential in modern computing: multi-core CPUs, GPUs, distributed <a href="https://helloacm.com/docker-virtual-machines-vms-and-kubernetes-k8s/" title="Docker, Virtual Machines (VMs) and Kubernetes (K8s)">clusters</a>, cloud workloads, LLM training, and HPC simulations.  
To reason about how much faster a program becomes with more processors, two mathematical models dominate:

<ul>
  <li><strong>Amdahl’s Law</strong> — fixed-size workload performance</li>
  <li><strong>Gustafson’s Law</strong> — scaled-size workload performance</li>
</ul>

These two laws are not contradictory. They answer <em>different questions</em>.  
This tutorial covers derivations, intuition, comparisons, practical use cases, and a Python plotting script showing both laws together.

<h2>1. What Is Speedup?</h2>
Speedup measures how much faster a program runs with <em>N</em> processors:

[math]S(N) = \frac{T_1}{T_N}[/math]

If a program takes 10 seconds on one <a href="https://helloacm.com/the-hidden-engine-of-performance-its-all-about-where-the-data-lives-cache-is-the-king/" title="The Hidden Engine of Performance: It’s All About Where the Data Lives (Cache is the King)">processor</a> and 5 seconds on two, speedup is:

[math]S(2) = \frac{10}{5} = 2[/math]

Perfect linear speedup would be:

[math]S(N) = N[/math]

But real systems contain serial bottlenecks. This is what Amdahl’s and Gustafson’s laws describe.

<h2>2. Amdahl’s Law (Fixed Workload)</h2>
<h3>2.1 Intuition</h3>
Amdahl assumes:

<ul>
  <li>The total amount of work stays the <strong>same</strong></li>
  <li>A portion is serial and cannot be parallelized</li>
</ul>

Let:

<ul>
  <li><code>f</code> = serial fraction</li>
  <li><code>1 - f</code> = parallel fraction</li>
</ul>

<h3>2.2 Derivation</h3>

Time on one processor:

[math]T_1 = T_s + T_p[/math]

Define:

[math]f = \frac{T_s}{T_1}[/math]

Thus:

[math]T_s = fT_1[/math]  
[math]T_p = (1 - f)T_1[/math]

Time on <em>N</em> processors:

[math]T_N = fT_1 + \frac{(1 - f)T_1}{N}[/math]

Speedup:

[math] S(N) = \frac{T_1}{T_N} = \frac{1}{f + \frac{1 - f}{N}} [/math]

Where f is the portion of the serial work and [math] 1-f [/math] is the work that can be parallelized. Amdahl's formula can be also rewritten as using [math] p [/math]:

[math] S(N) = \frac{T_1}{T_N} = \frac{1}{(1-p) + \frac{p}{N}} [/math]

As [math] p=1-f [/math] and [math] f=1-p [/math]

<h3>2.3 Limit as N → ∞</h3>

[math]S(\infty) = \frac{1}{f}[/math]

If the serial fraction is 10% (f = 0.1):

[math]S_\infty = 10[/math]

Even infinite processors cannot exceed that.

<h3>2.4 Practical Use Cases for Amdahl’s Law</h3>

Amdahl is ideal when optimizing <strong>latency</strong> for a fixed task:

<ul>
  <li>GPU kernel optimization for fixed tensor size</li>
  <li>Reducing inference latency for a single request</li>
  <li>Video encoding, compression, sorting</li>
  <li>Making a fixed-size batch job run faster</li>
  <li>Database query acceleration</li>
</ul>

<hr />

<h2>3. Gustafson’s Law (Scaled Workload)</h2>

<h3>3.1 Intuition</h3>
Gustafson reverses the question:

<strong>“With more processors, how much larger a problem can I solve in the same time?”</strong>

This reflects real HPC workloads: more CPUs → finer resolution → bigger simulations.

<h3>3.2 Derivation</h3>

Assume the program runs in 1 time unit on <em>N</em> processors.

Let:

<ul> <li><code>f</code> = serial fraction (measured at scale)</li> </ul>

The parallel portion scales with the number of processors, so its runtime remains proportional to N.

Time on one processor:

[math]T_1 = f + N(1 - f)[/math]

Thus, the speedup is:

[math]S(N) = f + N(1 - f)[/math]

We can re-write Gustafson’s formula in “N minus” form:

[math]S(N) = N - (N - 1)f[/math]

Or, if we define the parallel fraction as [math]p = 1 - f[/math], the formula can also be written as:

[math]S(N) = f + N(1-f) = f + Np [/math]

Now the "N minus" form in terms of p becomes:

[math] S(N) = N-(N-1)f = N - (N-1)(1-p) [/math]

<h3>3.3 Interpretation</h3>

As <em>N</em> increases, speedup approaches:

[math]S(N) \approx N(1 - f)[/math]

This is nearly linear for small serial fractions.

<h3>3.4 Practical Use Cases for Gustafson’s Law</h3>

Use Gustafson for <strong>throughput scaling</strong> or workloads where you can increase problem size:

<ul>
  <li>Weather and climate simulations</li>
  <li>Particle simulations, CFD, finite element analysis</li>
  <li>LLM training: more GPUs → longer sequences or bigger models</li>
  <li>Big data analytics (Spark, Dask, Flink)</li>
  <li>Monte Carlo simulations</li>
</ul>

<hr />

<h2>4. Amdahl’s Law vs. Gustafson’s Law (Comparison Table)</h2>

<table>
  <tr><th>Item</th><th>Amdahl</th><th>Gustafson</th></tr>
  <tr><td>Workload</td><td>Fixed</td><td>Scales with N</td></tr>
  <tr><td>Goal</td><td>Reduce latency</td><td>Increase throughput</td></tr>
  <tr><td>Speedup limit</td><td>Bounded: [math]1/f[/math]</td><td>Nearly linear: [math]N(1-f)[/math]</td></tr>
  <tr><td>Pessimistic/Optimistic</td><td>Pessimistic</td><td>Optimistic</td></tr>
  <tr><td>Use cases</td><td>Optimizing existing tasks</td><td>Scaling larger workloads</td></tr>
</table>

<hr />

<h2>5. Practical Use Cases (Combined View)</h2>

<h3>Amdahl (Latency Optimization)</h3>
<ul>
  <li>Reducing inference time for one LLM query</li>
  <li>Speeding up database joins</li>
  <li>GPU kernel tweaks for fixed tensors</li>
  <li>Video encoding (same video)</li>
</ul>

<h3>Gustafson (Throughput / Scale)</h3>
<ul>
  <li>LLM training (scale to more GPUs)</li>
  <li>Simulating higher-resolution weather models</li>
  <li>Big data ETL scaling</li>
  <li>Scientific HPC workloads</li>
</ul>

<h2>6. Python Script to Plot Both Laws</h2>
The code below generates a graph showing Amdahl’s and Gustafson’s speedup curves.  

You can adjust <code>f</code> (serial fraction) and the number of processors <code>N</code>.

The following script plots Amdahl and Gustafson <a href="https://helloacm.com/two-most-effective-freeware-to-speedup-computer-ccleaner-and-defraggler/" title="Two Most Effective Freeware to Speedup Computer: CCleaner and Defraggler">speedup</a> curves on the same graph.

It includes a few values of [math]f[/math] e.g. the serial portion:

<pre lang=py>
import numpy as np
import matplotlib.pyplot as plt

def amdahl_speedup(N, s):
    return 1.0 / (s + (1 - s) / N)

def gustafson_speedup(N, s):
    return s + (1 - s) * N

# Number of processors
N = np.arange(1, 65)

# Serial fractions to consider
Serial = [0.05, 0.1, 0.2, 0.3, 0.5, 0.8, 0.9, 1.0]

plt.figure(figsize=(10, 6))

for f in Serial:
    plt.plot(N, amdahl_speedup(N, f), linestyle='-', label=f"Amdahl Serial={f}")
    plt.plot(N, gustafson_speedup(N, f), linestyle='--', label=f"Gustafson Serial={f}")

plt.title("Amdahl's Law")
plt.xlabel("Number of Processors (N)")
plt.ylabel("Speedup")
plt.legend()
plt.grid(True)
plt.tight_layout()

plt.savefig("parallel-speedup-amdahl-vs-gustafson.png")
## plt.show()
</pre>

Here are the plots of the <a href="https://helloacm.com/teaching-kids-programming-estimating-the-performance-speedup-gain-using-amdahls-law/" title="Teaching Kids Programming – Estimating the Performance Speedup (Gain) using Amdahls Law">Amdahl's</a> vs Gustafson.

[caption id="attachment_157582" align="alignnone" width="1000"]<a href="https://helloacm.com/why-parallelism-isnt-infinite-amdahl-vs-gustafson-explained-simply/parallel-speedup-amdahl/" rel="attachment wp-att-157582"><img src="https://helloacm.com/wp-content/uploads/2025/11/parallel-speedup-amdahl.png" alt="Parallel Speedup (Amdahl&#039;s Law)" width="1000" height="600" class="size-full wp-image-157582" /></a> Parallel Speedup (Amdahl's Law)[/caption]

[caption id="attachment_157583" align="alignnone" width="1000"]<a href="https://helloacm.com/why-parallelism-isnt-infinite-amdahl-vs-gustafson-explained-simply/parallel-speedup-amdahl-vs-gustafson/" rel="attachment wp-att-157583"><img src="https://helloacm.com/wp-content/uploads/2025/11/parallel-speedup-amdahl-vs-gustafson.png" alt="Parallel Speedup (Amdahl&#039;s Law vs Gustafson)" width="1000" height="600" class="size-full wp-image-157583" /></a> Parallel Speedup (Amdahl's Law vs Gustafson)[/caption]

[caption id="attachment_157584" align="alignnone" width="1000"]<a href="https://helloacm.com/why-parallelism-isnt-infinite-amdahl-vs-gustafson-explained-simply/parallel-speedup-gustafson/" rel="attachment wp-att-157584"><img src="https://helloacm.com/wp-content/uploads/2025/11/parallel-speedup-gustafson.png" alt="Parallel Speedup (Gustafson)" width="1000" height="600" class="size-full wp-image-157584" /></a> Parallel Speedup (Gustafson)[/caption]

<h2>Interpreting the Plots</h2>

<ul>
<li>Amdahl curves flatten quickly—bottlenecked by the sequential portion.</li>
<li>Gustafson curves rise almost linearly—useful when workloads can scale.</li>
<li>Higher <code>f</code> increases the gap between the two models.</li>
</ul>

<h2>Conclusion</h2>
Amdahl’s Law shows the <strong>limits</strong> of parallelism for fixed workloads, making it ideal for latency optimization. Gustafson’s Law shows the <strong>opportunities</strong> of parallelism when workloads scale with compute.  

<ul>
<li>Amdahl’s Law → fixed-size workloads → diminishing returns</li>
<li>Gustafson’s Law → scalable workloads → near-linear speedup</li>
<li>Use both to understand hardware limits and the nature of your algorithm</li>
<li>Python tools make visualization simple and intuitive</li>
</ul>

Together, they form the foundation of reasoning about performance in modern <a href="https://helloacm.com/chatgpt-refactors-rewrites-the-code-using-promise-all-sending-requests-in-parallel/" title="ChatGPT Refactors/Rewrites the Code using Promise.All – Sending Requests in Parallel">parallel</a> systems, from HPC to LLM training to GPU compute.

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/how-to-compute-kth-largest-element-in-a-stream/" rel="bookmark" title="How to Compute Kth Largest Element in a Stream?">How to Compute Kth Largest Element in a Stream?</a> <small>Design a class to find the kth largest element in a stream. Note that it...</small></li>
<li><a href="https://helloacm.com/simple-and-fast-hash-functions-in-delphi/" rel="bookmark" title="Simple and Fast Hash Functions in Delphi">Simple and Fast Hash Functions in Delphi</a> <small>A Hash function returns a 32-bit (or sometimes 64-bit) integers for any given length of...</small></li>
<li><a href="https://helloacm.com/how-to-print-immutable-linked-list-in-reverse-using-recursion-or-stack/" rel="bookmark" title="How to Print Immutable Linked List in Reverse using Recursion or Stack?">How to Print Immutable Linked List in Reverse using Recursion or Stack?</a> <small>You are given an immutable linked list, print out all values of each node in...</small></li>
<li><a href="https://helloacm.com/different-ways-of-loading-javascript-files-in-a-javascript-file/" rel="bookmark" title="Different ways of Loading Javascript Files in a Javascript File">Different ways of Loading Javascript Files in a Javascript File</a> <small>The javascript (in HTML, the browser DOM i.e. Document Object Model) does not have a...</small></li>
<li><a href="https://helloacm.com/model-view-controller-explained-in-c/" rel="bookmark" title="Model-View-Controller Explained in C++">Model-View-Controller Explained in C++</a> <small>The Model-View-Controller (MVC) is not a technology, but a concept in software design/engineering. The MVC...</small></li>
<li><a href="https://helloacm.com/add-to-favorite-using-javascript/" rel="bookmark" title="How to Add To Favorite using Javascript?">How to Add To Favorite using Javascript?</a> <small>We all know that in most modern browsers, you can use the short key Ctrl...</small></li>
<li><a href="https://helloacm.com/visual-studio-net-4-0-disables-com-dll-protected-by-vmprotect/" rel="bookmark" title="Visual Studio .NET 4.0 Disables COM DLL protected by VMProtect">Visual Studio .NET 4.0 Disables COM DLL protected by VMProtect</a> <small>The VMProtect (www.vmpsoft.com) is a great commercial tool that can be used to protect Win32/64...</small></li>
<li><a href="https://helloacm.com/3-types-of-coding-languages-that-will-intrigue-educate-youngsters/" rel="bookmark" title="3 Types of Coding Languages That Will Intrigue &#038; Educate Youngsters">3 Types of Coding Languages That Will Intrigue &#038; Educate Youngsters</a> <small>Those who learn coding languages are likely to have a bright future ahead of them....</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://helloacm.com/why-parallelism-isnt-infinite-amdahl-vs-gustafson-explained-simply/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Teaching Kids Programming – Introduction to Combinatorial Mathematics 1 (Pascal Triangle/Binomial)</title>
		<link>https://helloacm.com/teaching-kids-programming-introduction-to-combinatorial-mathematics-1/</link>
					<comments>https://helloacm.com/teaching-kids-programming-introduction-to-combinatorial-mathematics-1/#respond</comments>
		
		<dc:creator><![CDATA[ACMer]]></dc:creator>
		<pubDate>Sat, 15 Nov 2025 20:33:45 +0000</pubDate>
				<category><![CDATA[algorithms]]></category>
		<category><![CDATA[Combination]]></category>
		<category><![CDATA[math]]></category>
		<category><![CDATA[Permutation]]></category>
		<category><![CDATA[teaching kids programming]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[youtube video]]></category>
		<category><![CDATA[binomial coefficient]]></category>
		<category><![CDATA[combinatorics]]></category>
		<category><![CDATA[dynamic programming]]></category>
		<category><![CDATA[grid walking]]></category>
		<category><![CDATA[math introduction]]></category>
		<category><![CDATA[Memoziation]]></category>
		<category><![CDATA[Pascal's triangle]]></category>
		<category><![CDATA[recursion]]></category>
		<category><![CDATA[Teaching Kids Programming]]></category>
		<guid isPermaLink="false">https://helloacm.com/?p=157550</guid>

					<description><![CDATA[<iframe width="1840" height="1035" src="https://www.youtube.com/embed/2zaKqIxqWwg" title="" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

<h1>Introduction to Math Combination</h1>

Combinations count the ways to choose items when order does not matter. This guide builds intuition from a simple grid-walking example, introduces binomial notation, derives the formula, explains the recurrence [math]C(n,m)=C(n-1,m-1)+C(n-1,m)[/math], and connects everything to <a href="https://helloacm.com/golang-generate-a-pascal-triangle/" title="GoLang: Generate a Pascal Triangle">Pascal's triangle</a>.

<h2>Grid walking example — paths from bottom-left to top-right</h2>

Imagine you must move only Right (R) or Up (U). To go from the bottom-left to a point that requires three rights and two ups, every shortest path is a sequence of five moves containing three R's and two U's.

[caption id="attachment_157567" align="alignnone" width="512"]<a href="https://helloacm.com/teaching-kids-programming-introduction-to-combinatorial-mathematics-1/combination-grid-walking/" rel="attachment wp-att-157567"><img src="https://helloacm.com/wp-content/uploads/2025/11/combination-grid-walking.jpg" alt="Combination Grid Walking" width="512" height="255" class="size-full wp-image-157567" /></a> Combination Grid Walking[/caption]

Each valid path is just a choice of which two positions (out of five) are U (the rest are R). So the number of such paths is "5 choose 2", written [math]C(5,2)[/math] (which equals [math]C(5,3)[/math]).

Example sequences:

<pre>R R U R U U R R R U R U R R U R R R U U U U R R R </pre>

<h2>The binomial coefficient (combination) notation</h2>

The number of ways to choose [math]m[/math] items from [math]n[/math] items (order doesn't matter) is written

[math]C(n,m)[/math]

or

[math]\binom{n}{m}[/math]

Both mean "n choose m".

<h2>Formula for combinations — the factorial derivation</h2>

First count ordered selections (permutations): the number of ordered lists of length [math]m[/math] from [math]n[/math] distinct items is

[math] n\times(n-1)\times\cdots\times(n-m+1)=\dfrac{n!}{(n-m)!} [/math]

Each unordered set of [math] m [/math] items corresponds to [math] m! [/math] ordered lists (the permutations of those [math] m [/math]). Divide by [math] m! [/math] to get <a href="https://helloacm.com/teaching-kids-programming-breadth-first-search-algorithm-to-find-factor-combinations/" title="Teaching Kids Programming – Breadth First Search Algorithm to Find Factor Combinations">combinations</a>:

[math]C(n,m)=\dfrac{n!}{m!(n-m)!}[/math]

<h3>Apply the formula to the grid example</h3>

For [math]n=5[/math] total steps and [math]m=2[/math] ups:

[math]C(5,2)=\dfrac{5!}{2!,3!}=\dfrac{120}{2\times 6}=10 [/math]

So there are 10 distinct shortest paths.

<h2>Why the formula makes sense intuitively</h2>
<ul>
<li>Viewpoint 1 — choose positions: choose the [math]m[/math] positions (out of [math]n[/math]) where the U's go; that's [math]C(n,m)[/math].</li>
<li>Viewpoint 2 — divide permutations by ordering: count all permutations of n moves then divide out reorderings of identical moves.</li>
</ul>

<h2>Pascal's triangle and the recurrence</h2>
[caption id="attachment_157571" align="alignnone" width="847"]<a href="https://helloacm.com/teaching-kids-programming-introduction-to-combinatorial-mathematics-1/pascal-triangle-2/" rel="attachment wp-att-157571"><img src="https://helloacm.com/wp-content/uploads/2025/11/pascal-triangle.jpg" alt="Pascal Triangle and Combination" width="847" height="600" class="size-full wp-image-157571" /></a> Pascal Triangle and Combination[/caption]

Write [math]C(n,k)[/math] in rows to form Pascal's triangle:

<pre> 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 1 5 10 10 5 1 </pre>

The entries satisfy the recurrence

[math] C(n,m)=C(n-1,m-1)+C(n-1,m) [/math]

Then, we can easily write a top-down dynamic programming implementation using @cache for memoized <a href="https://helloacm.com/teaching-kids-programming-paint-fences-no-3-consecutive-same-colours-top-down-dynamic-programming-algorithm-recursion-memoization/" title="Teaching Kids Programming – Paint Fences (No 3 Consecutive Same Colours) – Top Down Dynamic Programming Algorithm (Recursion + Memoization)">recursion</a>:

<pre lang=py>
from functools import cache

@cache
def C(n, m):
    if m == 0:
        return 1  # C(n, 0) = 1
    if m == n:
        return 1  # C(n, n) = 1
    return C(n-1, m-1) + C(n-1, m)
</pre>

Of course, we can also implement it in a bottom-up manner:

<pre lang=py>
def C_bottom_up(n, m):
    dp = [[0]*(m+1) for _ in range(n+1)]
    for i in range(n+1):
        dp[i][0] = 1  # C(i, 0) = 1
        for j in range(1, min(i, m)+1):
            if j == i:
                dp[i][j] = 1  # C(i, i) = 1
            else:
                dp[i][j] = dp[i-1][j-1] + dp[i-1][j]
    return dp[n][m]
</pre>

This bottom-up implementation accumulates from smaller subproblems to larger ones, avoiding the overhead of recursion and easily extending to compute the entire Pascal's triangle.

The bottom-up <a href="https://helloacm.com/teaching-kids-programming-paint-fences-no-3-consecutive-same-colours-top-down-dynamic-programming-algorithm-recursion-memoization/" title="Teaching Kids Programming – Paint Fences (No 3 Consecutive Same Colours) – Top Down Dynamic Programming Algorithm (Recursion + Memoization)">Dynamic Programming</a> for combinations can be further optimized using a one-dimensional array, leveraging the rolling array principle, since each row only depends on the previous row. The key is to update from right to left to avoid overwriting data that hasn’t been used yet.

Here’s an example implementation:

<pre lang=py>
def C_one_dim(n, m):
    dp = [0] * (m+1)
    dp[0] = 1  # C(i, 0) = 1

    for i in range(1, n+1):
        # Update from right to left to avoid overwriting previous row data
        for j in range(min(i, m), 0, -1):
            dp[j] = dp[j] + dp[j-1]
    
    return dp[m]
</pre>

Example:

<pre lang=py>
print(C_one_dim(5, 2))  # Output: 10
</pre>

✅ Advantages:
<ul> <li>Space complexity: O(m)</li> <li>Time complexity: O(n*m)</li> <li>Can easily be extended to compute an entire row or column of combination numbers</li> </ul>

<h3>Combinatorial proof — picking apples</h3>

Want to pick [math]m[/math] apples from [math]n[/math] apples. Consider the last apple (#n):

If you pick it, you must choose the remaining [math]m-1[/math] from the first [math]n-1[/math]: [math]C(n-1,m-1)[/math] ways.

If you skip it, you must choose all [math]m[/math] from the first [math]n-1[/math]: [math]C(n-1,m) [/math] ways.

These two disjoint cases cover all possibilities, so

[math] C(n,m)=C(n-1,m-1)+C(n-1,m) [/math]

(That identity is exactly what builds Pascal's triangle.)

<h2>Grid interpretation of the recurrence</h2>

On the grid, look at the last step of any path to a certain point: it is either R or U. Paths ending in R come from one earlier grid point, and paths ending in U come from another. Counting those two groups reproduces the same addition rule.

<h2>Common small values and remarks</h2>

[math]C(n,0)=1[/math] (choose nothing).
[math]C(n,1)=n[/math] (choose one).
[math]C(n,n)=1[/math] (choose all).

Small table for [math]n=5[/math]:

<pre>
C(5,0)=1
C(5,1)=5
C(5,2)=10
C(5,3)=10
C(5,4)=5
C(5,5)=1 
</pre> 

<h2>Final notes</h2>

Combinations appear in counting paths, binomial expansions (coefficients of [math]n[/math]), probability, and selection problems. The factorial formula gives direct computation, while Pascal's triangle and the recurrence provide inductive intuition and efficient building of values. The grid-walking example is a concrete way to visualize why "choose positions" equals "choose steps", which is the heart of combinations.

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/planning-to-update-your-website-for-2020-read-this/" rel="bookmark" title="Planning To Update Your Website For 2020? Read This.">Planning To Update Your Website For 2020? Read This.</a> <small>Looking to update your website for 2020? If so, it&#8217;s important to be aware of...</small></li>
<li><a href="https://helloacm.com/password-protect-or-ip-restriction-on-wordpress-wp-admin-folder-htaccess-and-htpasswd/" rel="bookmark" title="Password Protect or IP Restriction on WordPress wp-admin Folder (htaccess and htpasswd)">Password Protect or IP Restriction on WordPress wp-admin Folder (htaccess and htpasswd)</a> <small>wp-admin folder is the most important folder in a wordpress installation. It mainly contains the...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-geometry-of-triangle-area-and-side-law/" rel="bookmark" title="Teaching Kids Programming &#8211; Geometry of Triangle Area and Side Law">Teaching Kids Programming &#8211; Geometry of Triangle Area and Side Law</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms We know the area of triangle...</small></li>
<li><a href="https://helloacm.com/recursive-and-two-pointer-algorithms-to-determine-four-sum/" rel="bookmark" title="Recursion and Two Pointer Algorithms to Determine Four Sum">Recursion and Two Pointer Algorithms to Determine Four Sum</a> <small>Given a list of integers nums and an integer k, return whether there are four...</small></li>
<li><a href="https://helloacm.com/trick-count-the-number-of-api-in-com/" rel="bookmark" title="Trick: Count the Number of API in COM">Trick: Count the Number of API in COM</a> <small>Delphi is a handy tool to develop the COM (Component Object Model) DLL. A *_TLB.pas...</small></li>
<li><a href="https://helloacm.com/duplicate-a-mysql-table-copy-table-duplicate-database-php-script/" rel="bookmark" title="Duplicate a MySQL table &#8211; Copy Table / Duplicate Database / PHP Script">Duplicate a MySQL table &#8211; Copy Table / Duplicate Database / PHP Script</a> <small>Suppose if you want to copy a Table to another, this can be done in...</small></li>
<li><a href="https://helloacm.com/how-to-search-twits-with-picturesimages-using-php/" rel="bookmark" title="How to Search Twits with Pictures/Images using PHP?">How to Search Twits with Pictures/Images using PHP?</a> <small>If you want to search twits with Pictures or Images using PHP, then the following...</small></li>
<li><a href="https://helloacm.com/on-waiting-list-of-chatgpt-4-api/" rel="bookmark" title="On Waiting List of ChatGPT 4 API">On Waiting List of ChatGPT 4 API</a> <small>As of today, The ChatGPT-4 API Access is not yet available but we can request...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<iframe width="1840" height="1035" src="https://www.youtube.com/embed/2zaKqIxqWwg" title="" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

<h1>Introduction to Math Combination</h1>

Combinations count the ways to choose items when order does not matter. This guide builds intuition from a simple grid-walking example, introduces binomial notation, derives the formula, explains the recurrence [math]C(n,m)=C(n-1,m-1)+C(n-1,m)[/math], and connects everything to <a href="https://helloacm.com/golang-generate-a-pascal-triangle/" title="GoLang: Generate a Pascal Triangle">Pascal's triangle</a>.

<h2>Grid walking example — paths from bottom-left to top-right</h2>

Imagine you must move only Right (R) or Up (U). To go from the bottom-left to a point that requires three rights and two ups, every shortest path is a sequence of five moves containing three R's and two U's.

[caption id="attachment_157567" align="alignnone" width="512"]<a href="https://helloacm.com/teaching-kids-programming-introduction-to-combinatorial-mathematics-1/combination-grid-walking/" rel="attachment wp-att-157567"><img src="https://helloacm.com/wp-content/uploads/2025/11/combination-grid-walking.jpg" alt="Combination Grid Walking" width="512" height="255" class="size-full wp-image-157567" /></a> Combination Grid Walking[/caption]

Each valid path is just a choice of which two positions (out of five) are U (the rest are R). So the number of such paths is "5 choose 2", written [math]C(5,2)[/math] (which equals [math]C(5,3)[/math]).

Example sequences:

<pre>R R U R U U R R R U R U R R U R R R U U U U R R R </pre>

<h2>The binomial coefficient (combination) notation</h2>

The number of ways to choose [math]m[/math] items from [math]n[/math] items (order doesn't matter) is written

[math]C(n,m)[/math]

or

[math]\binom{n}{m}[/math]

Both mean "n choose m".

<h2>Formula for combinations — the factorial derivation</h2>

First count ordered selections (permutations): the number of ordered lists of length [math]m[/math] from [math]n[/math] distinct items is

[math] n\times(n-1)\times\cdots\times(n-m+1)=\dfrac{n!}{(n-m)!} [/math]

Each unordered set of [math] m [/math] items corresponds to [math] m! [/math] ordered lists (the permutations of those [math] m [/math]). Divide by [math] m! [/math] to get <a href="https://helloacm.com/teaching-kids-programming-breadth-first-search-algorithm-to-find-factor-combinations/" title="Teaching Kids Programming – Breadth First Search Algorithm to Find Factor Combinations">combinations</a>:

[math]C(n,m)=\dfrac{n!}{m!(n-m)!}[/math]

<h3>Apply the formula to the grid example</h3>

For [math]n=5[/math] total steps and [math]m=2[/math] ups:

[math]C(5,2)=\dfrac{5!}{2!,3!}=\dfrac{120}{2\times 6}=10 [/math]

So there are 10 distinct shortest paths.

<h2>Why the formula makes sense intuitively</h2>
<ul>
<li>Viewpoint 1 — choose positions: choose the [math]m[/math] positions (out of [math]n[/math]) where the U's go; that's [math]C(n,m)[/math].</li>
<li>Viewpoint 2 — divide permutations by ordering: count all permutations of n moves then divide out reorderings of identical moves.</li>
</ul>

<h2>Pascal's triangle and the recurrence</h2>
[caption id="attachment_157571" align="alignnone" width="847"]<a href="https://helloacm.com/teaching-kids-programming-introduction-to-combinatorial-mathematics-1/pascal-triangle-2/" rel="attachment wp-att-157571"><img src="https://helloacm.com/wp-content/uploads/2025/11/pascal-triangle.jpg" alt="Pascal Triangle and Combination" width="847" height="600" class="size-full wp-image-157571" /></a> Pascal Triangle and Combination[/caption]

Write [math]C(n,k)[/math] in rows to form Pascal's triangle:

<pre> 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 1 5 10 10 5 1 </pre>

The entries satisfy the recurrence

[math] C(n,m)=C(n-1,m-1)+C(n-1,m) [/math]

Then, we can easily write a top-down dynamic programming implementation using @cache for memoized <a href="https://helloacm.com/teaching-kids-programming-paint-fences-no-3-consecutive-same-colours-top-down-dynamic-programming-algorithm-recursion-memoization/" title="Teaching Kids Programming – Paint Fences (No 3 Consecutive Same Colours) – Top Down Dynamic Programming Algorithm (Recursion + Memoization)">recursion</a>:

<pre lang=py>
from functools import cache

@cache
def C(n, m):
    if m == 0:
        return 1  # C(n, 0) = 1
    if m == n:
        return 1  # C(n, n) = 1
    return C(n-1, m-1) + C(n-1, m)
</pre>

Of course, we can also implement it in a bottom-up manner:

<pre lang=py>
def C_bottom_up(n, m):
    dp = [[0]*(m+1) for _ in range(n+1)]
    for i in range(n+1):
        dp[i][0] = 1  # C(i, 0) = 1
        for j in range(1, min(i, m)+1):
            if j == i:
                dp[i][j] = 1  # C(i, i) = 1
            else:
                dp[i][j] = dp[i-1][j-1] + dp[i-1][j]
    return dp[n][m]
</pre>

This bottom-up implementation accumulates from smaller subproblems to larger ones, avoiding the overhead of recursion and easily extending to compute the entire Pascal's triangle.

The bottom-up <a href="https://helloacm.com/teaching-kids-programming-paint-fences-no-3-consecutive-same-colours-top-down-dynamic-programming-algorithm-recursion-memoization/" title="Teaching Kids Programming – Paint Fences (No 3 Consecutive Same Colours) – Top Down Dynamic Programming Algorithm (Recursion + Memoization)">Dynamic Programming</a> for combinations can be further optimized using a one-dimensional array, leveraging the rolling array principle, since each row only depends on the previous row. The key is to update from right to left to avoid overwriting data that hasn’t been used yet.

Here’s an example implementation:

<pre lang=py>
def C_one_dim(n, m):
    dp = [0] * (m+1)
    dp[0] = 1  # C(i, 0) = 1

    for i in range(1, n+1):
        # Update from right to left to avoid overwriting previous row data
        for j in range(min(i, m), 0, -1):
            dp[j] = dp[j] + dp[j-1]
    
    return dp[m]
</pre>

Example:

<pre lang=py>
print(C_one_dim(5, 2))  # Output: 10
</pre>

✅ Advantages:
<ul> <li>Space complexity: O(m)</li> <li>Time complexity: O(n*m)</li> <li>Can easily be extended to compute an entire row or column of combination numbers</li> </ul>

<h3>Combinatorial proof — picking apples</h3>

Want to pick [math]m[/math] apples from [math]n[/math] apples. Consider the last apple (#n):

If you pick it, you must choose the remaining [math]m-1[/math] from the first [math]n-1[/math]: [math]C(n-1,m-1)[/math] ways.

If you skip it, you must choose all [math]m[/math] from the first [math]n-1[/math]: [math]C(n-1,m) [/math] ways.

These two disjoint cases cover all possibilities, so

[math] C(n,m)=C(n-1,m-1)+C(n-1,m) [/math]

(That identity is exactly what builds Pascal's triangle.)

<h2>Grid interpretation of the recurrence</h2>

On the grid, look at the last step of any path to a certain point: it is either R or U. Paths ending in R come from one earlier grid point, and paths ending in U come from another. Counting those two groups reproduces the same addition rule.

<h2>Common small values and remarks</h2>

[math]C(n,0)=1[/math] (choose nothing).
[math]C(n,1)=n[/math] (choose one).
[math]C(n,n)=1[/math] (choose all).

Small table for [math]n=5[/math]:

<pre>
C(5,0)=1
C(5,1)=5
C(5,2)=10
C(5,3)=10
C(5,4)=5
C(5,5)=1 
</pre> 

<h2>Final notes</h2>

Combinations appear in counting paths, binomial expansions (coefficients of [math]n[/math]), probability, and selection problems. The factorial formula gives direct computation, while Pascal's triangle and the recurrence provide inductive intuition and efficient building of values. The grid-walking example is a concrete way to visualize why "choose positions" equals "choose steps", which is the heart of combinations.

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/planning-to-update-your-website-for-2020-read-this/" rel="bookmark" title="Planning To Update Your Website For 2020? Read This.">Planning To Update Your Website For 2020? Read This.</a> <small>Looking to update your website for 2020? If so, it&#8217;s important to be aware of...</small></li>
<li><a href="https://helloacm.com/password-protect-or-ip-restriction-on-wordpress-wp-admin-folder-htaccess-and-htpasswd/" rel="bookmark" title="Password Protect or IP Restriction on WordPress wp-admin Folder (htaccess and htpasswd)">Password Protect or IP Restriction on WordPress wp-admin Folder (htaccess and htpasswd)</a> <small>wp-admin folder is the most important folder in a wordpress installation. It mainly contains the...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-geometry-of-triangle-area-and-side-law/" rel="bookmark" title="Teaching Kids Programming &#8211; Geometry of Triangle Area and Side Law">Teaching Kids Programming &#8211; Geometry of Triangle Area and Side Law</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms We know the area of triangle...</small></li>
<li><a href="https://helloacm.com/recursive-and-two-pointer-algorithms-to-determine-four-sum/" rel="bookmark" title="Recursion and Two Pointer Algorithms to Determine Four Sum">Recursion and Two Pointer Algorithms to Determine Four Sum</a> <small>Given a list of integers nums and an integer k, return whether there are four...</small></li>
<li><a href="https://helloacm.com/trick-count-the-number-of-api-in-com/" rel="bookmark" title="Trick: Count the Number of API in COM">Trick: Count the Number of API in COM</a> <small>Delphi is a handy tool to develop the COM (Component Object Model) DLL. A *_TLB.pas...</small></li>
<li><a href="https://helloacm.com/duplicate-a-mysql-table-copy-table-duplicate-database-php-script/" rel="bookmark" title="Duplicate a MySQL table &#8211; Copy Table / Duplicate Database / PHP Script">Duplicate a MySQL table &#8211; Copy Table / Duplicate Database / PHP Script</a> <small>Suppose if you want to copy a Table to another, this can be done in...</small></li>
<li><a href="https://helloacm.com/how-to-search-twits-with-picturesimages-using-php/" rel="bookmark" title="How to Search Twits with Pictures/Images using PHP?">How to Search Twits with Pictures/Images using PHP?</a> <small>If you want to search twits with Pictures or Images using PHP, then the following...</small></li>
<li><a href="https://helloacm.com/on-waiting-list-of-chatgpt-4-api/" rel="bookmark" title="On Waiting List of ChatGPT 4 API">On Waiting List of ChatGPT 4 API</a> <small>As of today, The ChatGPT-4 API Access is not yet available but we can request...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://helloacm.com/teaching-kids-programming-introduction-to-combinatorial-mathematics-1/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>The Hidden Engine of Performance: It’s All About Where the Data Lives (Cache is the King)</title>
		<link>https://helloacm.com/the-hidden-engine-of-performance-its-all-about-where-the-data-lives-cache-is-the-king/</link>
					<comments>https://helloacm.com/the-hidden-engine-of-performance-its-all-about-where-the-data-lives-cache-is-the-king/#respond</comments>
		
		<dc:creator><![CDATA[ACMer]]></dc:creator>
		<pubDate>Sat, 15 Nov 2025 19:13:57 +0000</pubDate>
				<category><![CDATA[CPU]]></category>
		<category><![CDATA[hardware]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[ai-performance]]></category>
		<category><![CDATA[cache-optimization]]></category>
		<category><![CDATA[computer architecture]]></category>
		<category><![CDATA[cpu-cache]]></category>
		<category><![CDATA[data-locality]]></category>
		<category><![CDATA[HFT]]></category>
		<category><![CDATA[high-performance-computing]]></category>
		<category><![CDATA[low-latency]]></category>
		<category><![CDATA[memory-hierarchy]]></category>
		<category><![CDATA[networking]]></category>
		<category><![CDATA[numa]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[Robotics]]></category>
		<category><![CDATA[systems-architecture]]></category>
		<category><![CDATA[virtualization]]></category>
		<guid isPermaLink="false">https://helloacm.com/?p=157555</guid>

					<description><![CDATA[<h1>The Hidden Engine of Performance: It’s All About Where the Data Lives</h1>
<blockquote>
1. The Real Reason Systems Are Fast: It’s All About Cache
2. Forget CPU Speed — Data Locality Wins Every Time
3. Why Cache Is the Hidden Engine of All High-Performance Systems
4. Performance Isn’t About GHz. It’s About Distance.
5. Your CPU Is Waiting on Memory: The Untold Story of Cache
6. Data Locality: The Most Important Thing in Computing Nobody Talks About
7. Where Your Data Lives Determines Everything
8. Cache Rules Everything Around Me: A Guide to Real Performance
9. The <a href="https://helloacm.com/the-memory-manager-in-c-c-heap-vs-stack/" title="The Memory Manager in C/C++ (Heap vs Stack)">Memory</a> Hierarchy: The Silent Killer (or Savior) of Performance
10. Why Modern Performance Is a Battle Against Latency, Not Compute
11. The Real Secret to Performance: Where Data is Stored Determines Everything
12. System Speed ​​Isn't Determined by CPU, But by Data Distance
13. Caching is the Core of Modern Computing Performance
14. Ignoring Data Locality Makes All Performance Optimizations Futile
15. Performance Bottlenecks Aren't in Computing Power, But in Memory
16. Data Locality: An Underestimated Performance Analyst
17. The CPU Is Waiting for Your Memory: The Real Cost of Caching
</blockquote>

We love talking about CPU <a href="https://helloacm.com/teaching-kids-programming-number-of-valid-clock-times/" title="Teaching Kids Programming – Number of Valid Clock Times">clock</a> speeds, but in real systems the key question is: <strong>where does your data live?</strong>

Modern CPUs rely on a hierarchy (registers → L1 → L2 → L3 → DRAM). L1 might cost ~4 cycles; DRAM can take 200+. That’s <strong>50× slower</strong>. If your working set fits in cache, everything flies. If not, the CPU stalls.

<h2>Why Cache Dominates Everything</h2>

Packet processing is a great example. Each packet triggers table <a href="https://helloacm.com/a-complete-guide-to-sorted-data-structures-in-python/" title="A Complete Guide to Sorted Data Structures in Python">lookups</a>. If the tables stay hot in cache, you can push millions of packets per second. If they spill into DRAM, throughput collapses.

<blockquote>
<strong>So the real design question:</strong> Will it fit in cache?
</blockquote>

[caption id="attachment_157557" align="alignnone" width="476"]<a href="https://helloacm.com/the-hidden-engine-of-performance-its-all-about-where-the-data-lives-cache-is-the-king/cpu-cache-register/" rel="attachment wp-att-157557"><img src="https://helloacm.com/wp-content/uploads/2025/11/cpu-cache-register.jpg" alt="CPU Structure: Register, Cache" width="476" height="424" class="size-full wp-image-157557" /></a> CPU Structure: Register, Cache[/caption]

<h2>Instructions Matter Too</h2>

Caches aren’t just for data. Instruction-cache misses can ruin tail <a href="https://helloacm.com/introduce-to-solana-blockchain/" title="Introduce to Solana Blockchain">latency</a>. Some HFT systems deliberately keep their hot loop firing constantly so the I-cache stays warm, only enabling the NIC when needed. A single I-cache stall in a trading loop can dominate the entire latency budget.

<h2>Where Abstraction Fails</h2>

High-level strategies like “cloud for everything” ignore low-level realities. Virtualized network functions depend on things like:

<ul>
  <li>exclusive core pinning (so cache stays warm)</li>
  <li>interrupt coalescing trade-offs</li>
  <li>NUMA locality</li>
  <li>physical vs virtual NIC behavior</li>
</ul>

Sales decks say it “works,” but the fine <a href="https://helloacm.com/the-c-function-to-print-a-char-array-string-in-hexadecimal/" title="The C Function to Print a Char Array (String) in Hexadecimal">print</a> is usually: <em>needs 3× hardware and still won’t match bare metal.</em> Once you depend on cache behavior, pinning, and locality, the platform is no longer interchangeable.

<h2>AI Hits the Same Wall</h2>

Bigger models don’t change physics. Data movement still dominates compute. Locality wins.

<ul>
  <li>Arrays beat pointer-heavy structures because they’re contiguous</li>
  <li>Prefetchers work only with predictable patterns</li>
  <li>Cache lines get used efficiently when memory layout is sane</li>
</ul>

<h2>Even Robotics Shows This</h2>

In multi-axis motion control, the first axis warms the cache and pays the miss cost; later axes compute in half the time. Same principle: locality = speed.

<h2>IBM Telum: Caches on a Different Scale</h2>

The IBM Telum processor takes this idea to an extreme:

<ul>
  <li>Ten 36 MB L2 caches</li>
  <li>360 MB virtual L3</li>
  <li>2.8 GB virtual L4</li>
</ul>

[caption id="attachment_157558" align="alignnone" width="480"]<a href="https://helloacm.com/the-hidden-engine-of-performance-its-all-about-where-the-data-lives-cache-is-the-king/ibm-telum-processor/" rel="attachment wp-att-157558"><img src="https://helloacm.com/wp-content/uploads/2025/11/ibm-telum-processor.jpg" alt="IBM Telum Processor" width="480" height="243" class="size-full wp-image-157558" /></a> IBM Telum Processor[/caption]

The architecture can even convert L2 into L3 on demand. IBM hasn’t published access latencies, but it would be fascinating to see how they balance size vs distance vs hit time.

<h2>Conclusion</h2>

<strong>Performance is ultimately about how close your data and instructions stay to the core.</strong>

Design for locality and your systems will sing. Ignore it and no GHz number or <a href="https://helloacm.com/vps-vs-dedicated-servers-vs-cloud-managed-dedicated-servers-key-differences-and-recommendations/" title="VPS vs Dedicated Servers vs Cloud-Managed Dedicated Servers: Key Differences and Recommendations">cloud</a> abstraction will save you.

<blockquote>
We often talk about CPU speed, but rarely about where the data lives.

Performance is dominated by the proximity of the data. Registers, L1, L2, L3, main <a href="https://helloacm.com/the-memory-manager-in-c-c-heap-vs-stack/" title="The Memory Manager in C/C++ (Heap vs Stack)">memory</a> - each step adds latency and drops throughput. A main memory access can take 200 cycles, 50x slower than L1 cache.

When your working set fits in cache, your code flies. When it doesn’t, the CPU just waits.

In packet processing, this difference decides everything. Each packet triggers table lookups. If those tables stay in <a href="https://helloacm.com/beginners-introduction-to-php-memcached/" title="Beginner’s Introduction to PHP Memcached">cache</a>, you can push millions of packets per second. If not, throughput collapses.

So the next time you design a data structure, ask:

Will it fit in <a href="https://helloacm.com/teaching-kids-programming-the-cache-function-decorator-in-python/" title="cache" rel="noopener nofollow " target="_blank">cache</a>?

Because in performance-critical systems, cache isn’t just an optimization - it defines the system.

And not only data but also instructions! I've seen HFT engineers talk about their strategies where they programmed the hot paths to be firing all the time, and only switching the network card on when a packet needs to leave the system. This keeps their instruction cache hot as well.

Keeping the instruction cache hot is just as critical as keeping the data hot, especially in workloads where predictability matters. Shaping your hot path so the CPU never falls out of the I-cache is important, because even a small stall can dominate tail latency. It is an excellent reminder that architecture design is really about keeping both instructions and data as close to the core as possible.

So many technical decision makers are set on blanket strategy: eg. cloud for everything - that they think any virtualized workload can work in any virtualization environment and the underlying hardware and the virtualization is just a commodity. This doesn't apply for virtualized network functions where vendors knew exclusive thread core pinning gives the execution threads exclusive use of CPU cache. The vendors knew interrupt coalescing in virtualized environments decreases "CPU usage" at the expense of latency. They knew about NUMA locality and even put it all in their docs. Of course when the sales guys come around, they want to be aligned with high level strategy and use the best optimized benchmarks and have another separate discussion about cloud or hypervisor support without nuance. Yeah that will work*fine print: you'll need 3x the licenses/hardware and still won't get optimal performance>. There is such a lack of interest in low level performance and such a skills gap where it seems to be addressed by adding layers of abstraction and vendors to obscure accountability. If Everest was the test of tech leadership or vendor accountability, it would be nice to know which would die on the hill or sell parkas at the bottom. Totally. Once you rely on cache behavior, core pinning, and NUMA locality, the platform stops being interchangeable. The low level details matter far more than most high level strategies

most of the heavy AI workloads still run straight into the same memory hierarchy limits. The models keep getting bigger, but the physics of moving data around the chip haven’t changed much. Understanding locality is still a big part of getting good performance.

Arrays give the CPU exactly what it wants: contiguous memory and predictable access patterns. That means the prefetcher can actually do its job, the cache lines get used efficiently, and you avoid the pointer-chasing penalties you get with scattered structures. It is one of the simplest ways to stay cache-friendly.

The same in multi axes motion control for robotics. first axis warm up cache and takes the impact of cache miss, calculation of the next axis takes half time.

The IBM Telum processor can confirm that, with L2 converted to L3 on demand and L4 cache, accessible from any other cpu. Plus the clock speed is always at 5.5 GHz. The chip includes ten 36 MB Level-2 caches1 and expanded virtual Level-3 (360 MB) and Level-4 (2.8 GB) caches

That’s a fascinating chip. The cache sizes are enormous compared to most architectures, and it makes me wonder how that affects access latency at each level. I couldn’t find any published latencies for Telum’s caches, which is a pity, because it would be interesting to see how IBM balances size, fabric distance, and hit latency in practice.
</blockquote>

See: <a href="https://steemit.com/blog/@justyy/cache-is-king" title="Cache is the King">Cache is the King!</a>

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/why-and-how-you-should-stop-the-chatgpt-and-bytedance-bots-crawling-your-pages/" rel="bookmark" title="Why and How You Should Stop the ChatGPT and Bytedance Bots Crawling Your Pages?">Why and How You Should Stop the ChatGPT and Bytedance Bots Crawling Your Pages?</a> <small>Recently, I have seen my servers overloaded (High CPU Usage) and I looked into the...</small></li>
<li><a href="https://helloacm.com/html-tip-speed-up-dns-query-by-dns-prefetch/" rel="bookmark" title="HTML tip &#8211; Speed up DNS query by DNS-prefetch">HTML tip &#8211; Speed up DNS query by DNS-prefetch</a> <small>If you HTML pages have many external references e.g. google, then the DNS lookup may...</small></li>
<li><a href="https://helloacm.com/why-and-how-to-turn-off-ping-icmp-for-servers/" rel="bookmark" title="Why and How to Turn Off Ping (ICMP) for Servers?">Why and How to Turn Off Ping (ICMP) for Servers?</a> <small>The ping command is popular and it is often used to tell if a server...</small></li>
<li><a href="https://helloacm.com/the-memory-manager-in-c-c-heap-vs-stack/" rel="bookmark" title="The Memory Manager in C/C++ (Heap vs Stack)">The Memory Manager in C/C++ (Heap vs Stack)</a> <small>This is one of the most frequently asked interview questions for Software Engineer roles. In...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-using-stack-to-remove-digits-and-characters-on-the-left/" rel="bookmark" title="Teaching Kids Programming &#8211; Using Stack to Remove Digits and Characters on the Left">Teaching Kids Programming &#8211; Using Stack to Remove Digits and Characters on the Left</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given a string s....</small></li>
<li><a href="https://helloacm.com/how-to-setup-multiple-ssl-https-on-one-server-vps-or-dedicate-server/" rel="bookmark" title="How to Setup Multiple SSL (HTTPS) on One Server (VPS or Dedicate Server)?">How to Setup Multiple SSL (HTTPS) on One Server (VPS or Dedicate Server)?</a> <small>HTTPS is the trend and it becomes more and more popular. It is being used...</small></li>
<li><a href="https://helloacm.com/how-chatgpt-solves-a-math-puzzle/" rel="bookmark" title="How ChatGPT Solves a Math Puzzle?">How ChatGPT Solves a Math Puzzle?</a> <small>ChatGPT has been a hot topics these days. It can be creative in some ways...</small></li>
<li><a href="https://helloacm.com/how-to-check-if-one-or-more-users-are-logged-in-using-cookie-in-wordpress/" rel="bookmark" title="How to Check If One or More Users Are Logged in using Cookie in WordPress?">How to Check If One or More Users Are Logged in using Cookie in WordPress?</a> <small>WordPress provides an API is_user_logged_in() to check if any user is loggin, but unfortunately, it...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<h1>The Hidden Engine of Performance: It’s All About Where the Data Lives</h1>
<blockquote>
1. The Real Reason Systems Are Fast: It’s All About Cache
2. Forget CPU Speed — Data Locality Wins Every Time
3. Why Cache Is the Hidden Engine of All High-Performance Systems
4. Performance Isn’t About GHz. It’s About Distance.
5. Your CPU Is Waiting on Memory: The Untold Story of Cache
6. Data Locality: The Most Important Thing in Computing Nobody Talks About
7. Where Your Data Lives Determines Everything
8. Cache Rules Everything Around Me: A Guide to Real Performance
9. The <a href="https://helloacm.com/the-memory-manager-in-c-c-heap-vs-stack/" title="The Memory Manager in C/C++ (Heap vs Stack)">Memory</a> Hierarchy: The Silent Killer (or Savior) of Performance
10. Why Modern Performance Is a Battle Against Latency, Not Compute
11. The Real Secret to Performance: Where Data is Stored Determines Everything
12. System Speed ​​Isn't Determined by CPU, But by Data Distance
13. Caching is the Core of Modern Computing Performance
14. Ignoring Data Locality Makes All Performance Optimizations Futile
15. Performance Bottlenecks Aren't in Computing Power, But in Memory
16. Data Locality: An Underestimated Performance Analyst
17. The CPU Is Waiting for Your Memory: The Real Cost of Caching
</blockquote>

We love talking about CPU <a href="https://helloacm.com/teaching-kids-programming-number-of-valid-clock-times/" title="Teaching Kids Programming – Number of Valid Clock Times">clock</a> speeds, but in real systems the key question is: <strong>where does your data live?</strong>

Modern CPUs rely on a hierarchy (registers → L1 → L2 → L3 → DRAM). L1 might cost ~4 cycles; DRAM can take 200+. That’s <strong>50× slower</strong>. If your working set fits in cache, everything flies. If not, the CPU stalls.

<h2>Why Cache Dominates Everything</h2>

Packet processing is a great example. Each packet triggers table <a href="https://helloacm.com/a-complete-guide-to-sorted-data-structures-in-python/" title="A Complete Guide to Sorted Data Structures in Python">lookups</a>. If the tables stay hot in cache, you can push millions of packets per second. If they spill into DRAM, throughput collapses.

<blockquote>
<strong>So the real design question:</strong> Will it fit in cache?
</blockquote>

[caption id="attachment_157557" align="alignnone" width="476"]<a href="https://helloacm.com/the-hidden-engine-of-performance-its-all-about-where-the-data-lives-cache-is-the-king/cpu-cache-register/" rel="attachment wp-att-157557"><img src="https://helloacm.com/wp-content/uploads/2025/11/cpu-cache-register.jpg" alt="CPU Structure: Register, Cache" width="476" height="424" class="size-full wp-image-157557" /></a> CPU Structure: Register, Cache[/caption]

<h2>Instructions Matter Too</h2>

Caches aren’t just for data. Instruction-cache misses can ruin tail <a href="https://helloacm.com/introduce-to-solana-blockchain/" title="Introduce to Solana Blockchain">latency</a>. Some HFT systems deliberately keep their hot loop firing constantly so the I-cache stays warm, only enabling the NIC when needed. A single I-cache stall in a trading loop can dominate the entire latency budget.

<h2>Where Abstraction Fails</h2>

High-level strategies like “cloud for everything” ignore low-level realities. Virtualized network functions depend on things like:

<ul>
  <li>exclusive core pinning (so cache stays warm)</li>
  <li>interrupt coalescing trade-offs</li>
  <li>NUMA locality</li>
  <li>physical vs virtual NIC behavior</li>
</ul>

Sales decks say it “works,” but the fine <a href="https://helloacm.com/the-c-function-to-print-a-char-array-string-in-hexadecimal/" title="The C Function to Print a Char Array (String) in Hexadecimal">print</a> is usually: <em>needs 3× hardware and still won’t match bare metal.</em> Once you depend on cache behavior, pinning, and locality, the platform is no longer interchangeable.

<h2>AI Hits the Same Wall</h2>

Bigger models don’t change physics. Data movement still dominates compute. Locality wins.

<ul>
  <li>Arrays beat pointer-heavy structures because they’re contiguous</li>
  <li>Prefetchers work only with predictable patterns</li>
  <li>Cache lines get used efficiently when memory layout is sane</li>
</ul>

<h2>Even Robotics Shows This</h2>

In multi-axis motion control, the first axis warms the cache and pays the miss cost; later axes compute in half the time. Same principle: locality = speed.

<h2>IBM Telum: Caches on a Different Scale</h2>

The IBM Telum processor takes this idea to an extreme:

<ul>
  <li>Ten 36 MB L2 caches</li>
  <li>360 MB virtual L3</li>
  <li>2.8 GB virtual L4</li>
</ul>

[caption id="attachment_157558" align="alignnone" width="480"]<a href="https://helloacm.com/the-hidden-engine-of-performance-its-all-about-where-the-data-lives-cache-is-the-king/ibm-telum-processor/" rel="attachment wp-att-157558"><img src="https://helloacm.com/wp-content/uploads/2025/11/ibm-telum-processor.jpg" alt="IBM Telum Processor" width="480" height="243" class="size-full wp-image-157558" /></a> IBM Telum Processor[/caption]

The architecture can even convert L2 into L3 on demand. IBM hasn’t published access latencies, but it would be fascinating to see how they balance size vs distance vs hit time.

<h2>Conclusion</h2>

<strong>Performance is ultimately about how close your data and instructions stay to the core.</strong>

Design for locality and your systems will sing. Ignore it and no GHz number or <a href="https://helloacm.com/vps-vs-dedicated-servers-vs-cloud-managed-dedicated-servers-key-differences-and-recommendations/" title="VPS vs Dedicated Servers vs Cloud-Managed Dedicated Servers: Key Differences and Recommendations">cloud</a> abstraction will save you.

<blockquote>
We often talk about CPU speed, but rarely about where the data lives.

Performance is dominated by the proximity of the data. Registers, L1, L2, L3, main <a href="https://helloacm.com/the-memory-manager-in-c-c-heap-vs-stack/" title="The Memory Manager in C/C++ (Heap vs Stack)">memory</a> - each step adds latency and drops throughput. A main memory access can take 200 cycles, 50x slower than L1 cache.

When your working set fits in cache, your code flies. When it doesn’t, the CPU just waits.

In packet processing, this difference decides everything. Each packet triggers table lookups. If those tables stay in <a href="https://helloacm.com/beginners-introduction-to-php-memcached/" title="Beginner’s Introduction to PHP Memcached">cache</a>, you can push millions of packets per second. If not, throughput collapses.

So the next time you design a data structure, ask:

Will it fit in <a href="https://helloacm.com/teaching-kids-programming-the-cache-function-decorator-in-python/" title="cache" rel="noopener nofollow " target="_blank">cache</a>?

Because in performance-critical systems, cache isn’t just an optimization - it defines the system.

And not only data but also instructions! I've seen HFT engineers talk about their strategies where they programmed the hot paths to be firing all the time, and only switching the network card on when a packet needs to leave the system. This keeps their instruction cache hot as well.

Keeping the instruction cache hot is just as critical as keeping the data hot, especially in workloads where predictability matters. Shaping your hot path so the CPU never falls out of the I-cache is important, because even a small stall can dominate tail latency. It is an excellent reminder that architecture design is really about keeping both instructions and data as close to the core as possible.

So many technical decision makers are set on blanket strategy: eg. cloud for everything - that they think any virtualized workload can work in any virtualization environment and the underlying hardware and the virtualization is just a commodity. This doesn't apply for virtualized network functions where vendors knew exclusive thread core pinning gives the execution threads exclusive use of CPU cache. The vendors knew interrupt coalescing in virtualized environments decreases "CPU usage" at the expense of latency. They knew about NUMA locality and even put it all in their docs. Of course when the sales guys come around, they want to be aligned with high level strategy and use the best optimized benchmarks and have another separate discussion about cloud or hypervisor support without nuance. Yeah that will work*fine print: you'll need 3x the licenses/hardware and still won't get optimal performance>. There is such a lack of interest in low level performance and such a skills gap where it seems to be addressed by adding layers of abstraction and vendors to obscure accountability. If Everest was the test of tech leadership or vendor accountability, it would be nice to know which would die on the hill or sell parkas at the bottom. Totally. Once you rely on cache behavior, core pinning, and NUMA locality, the platform stops being interchangeable. The low level details matter far more than most high level strategies

most of the heavy AI workloads still run straight into the same memory hierarchy limits. The models keep getting bigger, but the physics of moving data around the chip haven’t changed much. Understanding locality is still a big part of getting good performance.

Arrays give the CPU exactly what it wants: contiguous memory and predictable access patterns. That means the prefetcher can actually do its job, the cache lines get used efficiently, and you avoid the pointer-chasing penalties you get with scattered structures. It is one of the simplest ways to stay cache-friendly.

The same in multi axes motion control for robotics. first axis warm up cache and takes the impact of cache miss, calculation of the next axis takes half time.

The IBM Telum processor can confirm that, with L2 converted to L3 on demand and L4 cache, accessible from any other cpu. Plus the clock speed is always at 5.5 GHz. The chip includes ten 36 MB Level-2 caches1 and expanded virtual Level-3 (360 MB) and Level-4 (2.8 GB) caches

That’s a fascinating chip. The cache sizes are enormous compared to most architectures, and it makes me wonder how that affects access latency at each level. I couldn’t find any published latencies for Telum’s caches, which is a pity, because it would be interesting to see how IBM balances size, fabric distance, and hit latency in practice.
</blockquote>

See: <a href="https://steemit.com/blog/@justyy/cache-is-king" title="Cache is the King">Cache is the King!</a>

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/why-and-how-you-should-stop-the-chatgpt-and-bytedance-bots-crawling-your-pages/" rel="bookmark" title="Why and How You Should Stop the ChatGPT and Bytedance Bots Crawling Your Pages?">Why and How You Should Stop the ChatGPT and Bytedance Bots Crawling Your Pages?</a> <small>Recently, I have seen my servers overloaded (High CPU Usage) and I looked into the...</small></li>
<li><a href="https://helloacm.com/html-tip-speed-up-dns-query-by-dns-prefetch/" rel="bookmark" title="HTML tip &#8211; Speed up DNS query by DNS-prefetch">HTML tip &#8211; Speed up DNS query by DNS-prefetch</a> <small>If you HTML pages have many external references e.g. google, then the DNS lookup may...</small></li>
<li><a href="https://helloacm.com/why-and-how-to-turn-off-ping-icmp-for-servers/" rel="bookmark" title="Why and How to Turn Off Ping (ICMP) for Servers?">Why and How to Turn Off Ping (ICMP) for Servers?</a> <small>The ping command is popular and it is often used to tell if a server...</small></li>
<li><a href="https://helloacm.com/the-memory-manager-in-c-c-heap-vs-stack/" rel="bookmark" title="The Memory Manager in C/C++ (Heap vs Stack)">The Memory Manager in C/C++ (Heap vs Stack)</a> <small>This is one of the most frequently asked interview questions for Software Engineer roles. In...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-using-stack-to-remove-digits-and-characters-on-the-left/" rel="bookmark" title="Teaching Kids Programming &#8211; Using Stack to Remove Digits and Characters on the Left">Teaching Kids Programming &#8211; Using Stack to Remove Digits and Characters on the Left</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given a string s....</small></li>
<li><a href="https://helloacm.com/how-to-setup-multiple-ssl-https-on-one-server-vps-or-dedicate-server/" rel="bookmark" title="How to Setup Multiple SSL (HTTPS) on One Server (VPS or Dedicate Server)?">How to Setup Multiple SSL (HTTPS) on One Server (VPS or Dedicate Server)?</a> <small>HTTPS is the trend and it becomes more and more popular. It is being used...</small></li>
<li><a href="https://helloacm.com/how-chatgpt-solves-a-math-puzzle/" rel="bookmark" title="How ChatGPT Solves a Math Puzzle?">How ChatGPT Solves a Math Puzzle?</a> <small>ChatGPT has been a hot topics these days. It can be creative in some ways...</small></li>
<li><a href="https://helloacm.com/how-to-check-if-one-or-more-users-are-logged-in-using-cookie-in-wordpress/" rel="bookmark" title="How to Check If One or More Users Are Logged in using Cookie in WordPress?">How to Check If One or More Users Are Logged in using Cookie in WordPress?</a> <small>WordPress provides an API is_user_logged_in() to check if any user is loggin, but unfortunately, it...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://helloacm.com/the-hidden-engine-of-performance-its-all-about-where-the-data-lives-cache-is-the-king/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Deep Dive into Reinforcement Learning: Understanding the Q-Learning Algorithm</title>
		<link>https://helloacm.com/deep-dive-into-reinforcement-learning-understanding-the-q-learning-algorithm/</link>
					<comments>https://helloacm.com/deep-dive-into-reinforcement-learning-understanding-the-q-learning-algorithm/#respond</comments>
		
		<dc:creator><![CDATA[ACMer]]></dc:creator>
		<pubDate>Wed, 12 Nov 2025 11:36:59 +0000</pubDate>
				<category><![CDATA[algorithms]]></category>
		<category><![CDATA[Artificial Intelligence]]></category>
		<category><![CDATA[machine learning]]></category>
		<category><![CDATA[programming languages]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Q Learning]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[algorithm]]></category>
		<category><![CDATA[artificial intelligence]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[math]]></category>
		<category><![CDATA[Q-Learning]]></category>
		<category><![CDATA[Reinforcement Learning]]></category>
		<guid isPermaLink="false">https://helloacm.com/?p=157532</guid>

					<description><![CDATA[[caption id="attachment_157537" align="alignnone" width="2017"]<a href="https://helloacm.com/deep-dive-into-reinforcement-learning-understanding-the-q-learning-algorithm/q-learning/" rel="attachment wp-att-157537"><img src="https://helloacm.com/wp-content/uploads/2025/11/q-learning.jpg" alt="Q Learning Algorithms (Machine Learning/AI)" width="2017" height="516" class="size-full wp-image-157537" /></a> Q Learning Algorithms (Machine Learning/AI)[/caption]

<h3>Reinforcement Learning (RL) — The Art of Learning by Trial and Error</h3>

<blockquote>
Reinforcement Learning 101: The Art of Learning by Trial and Error

Deep Dive into Reinforcement Learning: Understanding the Q-Learning Algorithm

How Do Machines Learn to Make Their Own Decisions? Reinforcement Learning Explained

Learning from Rewards: The Trial-and-Error Intelligence Behind AI
</blockquote>

Reinforcement Learning (RL) is one of the three main paradigms of machine learning, alongside supervised and unsupervised learning.

Its key idea is that an agent interacts with an environment, receives rewards or punishments, and learns an optimal strategy through continuous trial and error.

<h4>Basic Concepts</h4> <ul> <li><b>Agent:</b> The learner or decision-maker.</li> <li><b>Environment:</b> The external system that the agent interacts with.</li> <li><b>State (s):</b> The current description of the environment.</li> <li><b>Action (a):</b> The decision the agent makes in a given state.</li> <li><b>Reward (r):</b> The feedback the agent receives after taking an action.</li> </ul>

The goal of Reinforcement Learning is to find a <b>policy</b> [math]\pi(a|s)[/math] that maximizes the expected cumulative reward:

[math]J(\pi) = \mathbb{E}\pi \left[ \sum{t=0}^{\infty} \gamma^t r_t \right][/math]

where [math]\gamma[/math] (0 ≤ [math]\gamma[/math] ≤ 1) is the discount factor that determines how much future <a href="https://helloacm.com/how-to-earn-microsoft-claim-points-and-redeem-rewards-by-using-bing-search-engine-and-edge-browser/" title="How to Earn Microsoft/Bing Points and Redeem Rewards by using Bing Search Engine and Edge Browser?">rewards</a> are valued compared to immediate ones.

<h4>Q-Learning — A Simple but Powerful Algorithm</h4>

Q-learning is one of the most classic <a href="https://helloacm.com/tetration-operator-in-math-simply-explained-with-python-algorithms/" title="Tetration Operator in Math Simply Explained with Python Algorithms">algorithms</a> in reinforcement learning.
It learns a value function [math]Q(s, a)[/math] that represents the expected total reward when taking action a in state s and following the optimal policy thereafter.

The Q-learning update rule is:

[math]Q(s, a) \leftarrow Q(s, a) + \alpha \left( r + \gamma \max_{a'} Q(s', a') - Q(s, a) \right)[/math]

<ul> 
<li>[math]\alpha[/math] — learning rate</li> 
<li>[math]\gamma[/math] — discount factor</li> 
<li>[math] r [/math] — reward</li> 
<li>[math] s' [/math] — next state</li> 
</ul> 

<h4>Example: Q-Learning in Python</h4> 

<pre lang=py>
import numpy as np
import random

# 1️⃣ Define Maze
maze = np.array([
    [0,  0,  0, -1,  1],
    [0, -1,  0, -1,  0],
    [0,  0,  0,  0,  0]
])

n_rows, n_cols = maze.shape
actions = ['up', 'down', 'left', 'right']
Q = np.zeros((n_rows, n_cols, len(actions)))

# 2️⃣ Tuning/Training Parameters
alpha = 0.1
gamma = 0.9
epsilon = 0.1
episodes = 500

# 3️⃣ Help Functions
def is_valid(state):
    r, c = state
    return 0 &lt;= r &lt; n_rows and 0 &lt;= c &lt; n_cols and maze[r, c] != -1

def next_state(state, action):
    r, c = state
    if action == 'up': r -= 1
    elif action == 'down': r += 1
    elif action == 'left': c -= 1
    elif action == 'right': c += 1
    return (r, c)

def get_reward(state):
    r, c = state
    if maze[r, c] == 1: return 10
    elif maze[r, c] == -1: return -1
    return -0.1

# 4️⃣ Training Loop
for episode in range(episodes):
    state = (2, 0)
    done = False

    while not done:
        if random.uniform(0, 1) &lt; epsilon:
            action_idx = random.randint(0, len(actions)-1)
        else:
            action_idx = np.argmax(Q[state[0], state[1]])

        action = actions[action_idx]
        next_s = next_state(state, action)

        if not is_valid(next_s):
            reward = -1
            next_s = state
        else:
            reward = get_reward(next_s)

        Q[state[0], state[1], action_idx] += alpha * (
            reward + gamma * np.max(Q[next_s[0], next_s[1]]) - Q[state[0], state[1], action_idx]
        )

        state = next_s
        if maze[state[0], state[1]] == 1:
            done = True

print("✅ Training completed！")

# 5️⃣ View the Result
state = (2, 0)
path = [state]

while maze[state[0], state[1]] != 1:
    action_idx = np.argmax(Q[state[0], state[1]])
    next_s = next_state(state, actions[action_idx])
    if not is_valid(next_s) or next_s in path:
        break
    state = next_s
    path.append(state)

print("🗺️ Learned Path:", path)
</pre>

<h4>Training Result</h4>

After training, the agent gradually learns that moving right from D in the <a href="https://helloacm.com/teaching-kids-programming-maze-design-algorithm-how-to-generate-a-random-maze/" title="Teaching Kids Programming – How to Design a Random Maze? Random Maze Generation Algorithm">Maze</a> yields the highest reward, forming a strategy similar to:

<code>A → right → B → right → C → right → D → right → E</code>

<h4>Summary</h4> <ul> <li>Reinforcement Learning enables machines to learn optimal strategies through feedback, similar to how humans learn by experience.</li> <li>Q-Learning is the foundation of many modern RL algorithms, including Deep Q-Networks (DQN).</li> <li>This simple example demonstrates the complete reinforcement learning loop: <b>exploration → feedback → improvement</b>.</li> </ul>

The charm of reinforcement learning lies in the fact that it does not require explicit answers; instead, the machine discovers the optimal strategy on its own.
You can further extend this example, for instance, by adding <b>matplotlib animations</b> or using <b>neural networks (Deep Q-Learning)</b> to tackle more complex tasks.

<ul> <li><b>Q-Table</b>: Stores the value of each state-action pair</li> <li><b>ε-greedy Strategy</b>: Balances exploration and exploitation</li> <li><b>Reward Function Design</b>: Guides the agent to learn goal-directed behavior</li> <li><b>Reinforcement Learning Philosophy</b>: Continuously improves the policy through trial-and-error and reward feedback</li> </ul>

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/teaching-kids-programming-minimum-sum-of-four-digit-number-after-splitting-digits/" rel="bookmark" title="Teaching Kids Programming &#8211; Minimum Sum of Four Digit Number After Splitting Digits">Teaching Kids Programming &#8211; Minimum Sum of Four Digit Number After Splitting Digits</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given a positive integer...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-minimum-cuts-to-divide-a-circle/" rel="bookmark" title="Teaching Kids Programming &#8211; Minimum Cuts to Divide a Circle">Teaching Kids Programming &#8211; Minimum Cuts to Divide a Circle</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms A valid cut in a circle...</small></li>
<li><a href="https://helloacm.com/how-to-kill-a-process-or-capture-signals-sigterm-sigkill-in-python/" rel="bookmark" title="How to Kill a Process or Capture Signals (SIGTERM, SIGKILL) in Python?">How to Kill a Process or Capture Signals (SIGTERM, SIGKILL) in Python?</a> <small>Kill Current Process We can kill a process itself or let the process commit suicide...</small></li>
<li><a href="https://helloacm.com/common-azure-kubernetes-services-aks-commands-cheet-sheet/" rel="bookmark" title="Common Azure Kubernetes Services AKS Commands (Cheet Sheet)">Common Azure Kubernetes Services AKS Commands (Cheet Sheet)</a> <small>Kubernetes is a de-facto standard to deploy and manage applications in the cloud. The cloud...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-count-pairs-of-similar-strings-bruterforce-hash-map-counter-and-bit-masking/" rel="bookmark" title="Teaching Kids Programming &#8211; Count Pairs Of Similar Strings (Bruterforce, Hash Map / Counter and Bit masking)">Teaching Kids Programming &#8211; Count Pairs Of Similar Strings (Bruterforce, Hash Map / Counter and Bit masking)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given a 0-indexed string...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-duplicate-numbers-of-max-distance-in-array-sliding-window-two-pointer-algorithms/" rel="bookmark" title="Teaching Kids Programming &#8211; Duplicate Numbers of Max Distance in Array (Sliding Window/Two Pointer Algorithms)">Teaching Kids Programming &#8211; Duplicate Numbers of Max Distance in Array (Sliding Window/Two Pointer Algorithms)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms Given an integer array nums and...</small></li>
<li><a href="https://helloacm.com/gaming-adaptations-for-different-platforms/" rel="bookmark" title="Gaming Adaptations for Different Platforms">Gaming Adaptations for Different Platforms</a> <small>One of the trickiest challenges facing any software developer is figuring out how their coding...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-max-profit-of-rod-cutting-unbounded-knapsack-via-bottom-up-dynamic-programming-algorithm/" rel="bookmark" title="Teaching Kids Programming &#8211; Max Profit of Rod Cutting (Unbounded Knapsack) via Bottom Up Dynamic Programming Algorithm">Teaching Kids Programming &#8211; Max Profit of Rod Cutting (Unbounded Knapsack) via Bottom Up Dynamic Programming Algorithm</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given a list of...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[[caption id="attachment_157537" align="alignnone" width="2017"]<a href="https://helloacm.com/deep-dive-into-reinforcement-learning-understanding-the-q-learning-algorithm/q-learning/" rel="attachment wp-att-157537"><img src="https://helloacm.com/wp-content/uploads/2025/11/q-learning.jpg" alt="Q Learning Algorithms (Machine Learning/AI)" width="2017" height="516" class="size-full wp-image-157537" /></a> Q Learning Algorithms (Machine Learning/AI)[/caption]

<h3>Reinforcement Learning (RL) — The Art of Learning by Trial and Error</h3>

<blockquote>
Reinforcement Learning 101: The Art of Learning by Trial and Error

Deep Dive into Reinforcement Learning: Understanding the Q-Learning Algorithm

How Do Machines Learn to Make Their Own Decisions? Reinforcement Learning Explained

Learning from Rewards: The Trial-and-Error Intelligence Behind AI
</blockquote>

Reinforcement Learning (RL) is one of the three main paradigms of machine learning, alongside supervised and unsupervised learning.

Its key idea is that an agent interacts with an environment, receives rewards or punishments, and learns an optimal strategy through continuous trial and error.

<h4>Basic Concepts</h4> <ul> <li><b>Agent:</b> The learner or decision-maker.</li> <li><b>Environment:</b> The external system that the agent interacts with.</li> <li><b>State (s):</b> The current description of the environment.</li> <li><b>Action (a):</b> The decision the agent makes in a given state.</li> <li><b>Reward (r):</b> The feedback the agent receives after taking an action.</li> </ul>

The goal of Reinforcement Learning is to find a <b>policy</b> [math]\pi(a|s)[/math] that maximizes the expected cumulative reward:

[math]J(\pi) = \mathbb{E}\pi \left[ \sum{t=0}^{\infty} \gamma^t r_t \right][/math]

where [math]\gamma[/math] (0 ≤ [math]\gamma[/math] ≤ 1) is the discount factor that determines how much future <a href="https://helloacm.com/how-to-earn-microsoft-claim-points-and-redeem-rewards-by-using-bing-search-engine-and-edge-browser/" title="How to Earn Microsoft/Bing Points and Redeem Rewards by using Bing Search Engine and Edge Browser?">rewards</a> are valued compared to immediate ones.

<h4>Q-Learning — A Simple but Powerful Algorithm</h4>

Q-learning is one of the most classic <a href="https://helloacm.com/tetration-operator-in-math-simply-explained-with-python-algorithms/" title="Tetration Operator in Math Simply Explained with Python Algorithms">algorithms</a> in reinforcement learning.
It learns a value function [math]Q(s, a)[/math] that represents the expected total reward when taking action a in state s and following the optimal policy thereafter.

The Q-learning update rule is:

[math]Q(s, a) \leftarrow Q(s, a) + \alpha \left( r + \gamma \max_{a'} Q(s', a') - Q(s, a) \right)[/math]

<ul> 
<li>[math]\alpha[/math] — learning rate</li> 
<li>[math]\gamma[/math] — discount factor</li> 
<li>[math] r [/math] — reward</li> 
<li>[math] s' [/math] — next state</li> 
</ul> 

<h4>Example: Q-Learning in Python</h4> 

<pre lang=py>
import numpy as np
import random

# 1️⃣ Define Maze
maze = np.array([
    [0,  0,  0, -1,  1],
    [0, -1,  0, -1,  0],
    [0,  0,  0,  0,  0]
])

n_rows, n_cols = maze.shape
actions = ['up', 'down', 'left', 'right']
Q = np.zeros((n_rows, n_cols, len(actions)))

# 2️⃣ Tuning/Training Parameters
alpha = 0.1
gamma = 0.9
epsilon = 0.1
episodes = 500

# 3️⃣ Help Functions
def is_valid(state):
    r, c = state
    return 0 &lt;= r &lt; n_rows and 0 &lt;= c &lt; n_cols and maze[r, c] != -1

def next_state(state, action):
    r, c = state
    if action == 'up': r -= 1
    elif action == 'down': r += 1
    elif action == 'left': c -= 1
    elif action == 'right': c += 1
    return (r, c)

def get_reward(state):
    r, c = state
    if maze[r, c] == 1: return 10
    elif maze[r, c] == -1: return -1
    return -0.1

# 4️⃣ Training Loop
for episode in range(episodes):
    state = (2, 0)
    done = False

    while not done:
        if random.uniform(0, 1) &lt; epsilon:
            action_idx = random.randint(0, len(actions)-1)
        else:
            action_idx = np.argmax(Q[state[0], state[1]])

        action = actions[action_idx]
        next_s = next_state(state, action)

        if not is_valid(next_s):
            reward = -1
            next_s = state
        else:
            reward = get_reward(next_s)

        Q[state[0], state[1], action_idx] += alpha * (
            reward + gamma * np.max(Q[next_s[0], next_s[1]]) - Q[state[0], state[1], action_idx]
        )

        state = next_s
        if maze[state[0], state[1]] == 1:
            done = True

print("✅ Training completed！")

# 5️⃣ View the Result
state = (2, 0)
path = [state]

while maze[state[0], state[1]] != 1:
    action_idx = np.argmax(Q[state[0], state[1]])
    next_s = next_state(state, actions[action_idx])
    if not is_valid(next_s) or next_s in path:
        break
    state = next_s
    path.append(state)

print("🗺️ Learned Path:", path)
</pre>

<h4>Training Result</h4>

After training, the agent gradually learns that moving right from D in the <a href="https://helloacm.com/teaching-kids-programming-maze-design-algorithm-how-to-generate-a-random-maze/" title="Teaching Kids Programming – How to Design a Random Maze? Random Maze Generation Algorithm">Maze</a> yields the highest reward, forming a strategy similar to:

<code>A → right → B → right → C → right → D → right → E</code>

<h4>Summary</h4> <ul> <li>Reinforcement Learning enables machines to learn optimal strategies through feedback, similar to how humans learn by experience.</li> <li>Q-Learning is the foundation of many modern RL algorithms, including Deep Q-Networks (DQN).</li> <li>This simple example demonstrates the complete reinforcement learning loop: <b>exploration → feedback → improvement</b>.</li> </ul>

The charm of reinforcement learning lies in the fact that it does not require explicit answers; instead, the machine discovers the optimal strategy on its own.
You can further extend this example, for instance, by adding <b>matplotlib animations</b> or using <b>neural networks (Deep Q-Learning)</b> to tackle more complex tasks.

<ul> <li><b>Q-Table</b>: Stores the value of each state-action pair</li> <li><b>ε-greedy Strategy</b>: Balances exploration and exploitation</li> <li><b>Reward Function Design</b>: Guides the agent to learn goal-directed behavior</li> <li><b>Reinforcement Learning Philosophy</b>: Continuously improves the policy through trial-and-error and reward feedback</li> </ul>

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/teaching-kids-programming-minimum-sum-of-four-digit-number-after-splitting-digits/" rel="bookmark" title="Teaching Kids Programming &#8211; Minimum Sum of Four Digit Number After Splitting Digits">Teaching Kids Programming &#8211; Minimum Sum of Four Digit Number After Splitting Digits</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given a positive integer...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-minimum-cuts-to-divide-a-circle/" rel="bookmark" title="Teaching Kids Programming &#8211; Minimum Cuts to Divide a Circle">Teaching Kids Programming &#8211; Minimum Cuts to Divide a Circle</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms A valid cut in a circle...</small></li>
<li><a href="https://helloacm.com/how-to-kill-a-process-or-capture-signals-sigterm-sigkill-in-python/" rel="bookmark" title="How to Kill a Process or Capture Signals (SIGTERM, SIGKILL) in Python?">How to Kill a Process or Capture Signals (SIGTERM, SIGKILL) in Python?</a> <small>Kill Current Process We can kill a process itself or let the process commit suicide...</small></li>
<li><a href="https://helloacm.com/common-azure-kubernetes-services-aks-commands-cheet-sheet/" rel="bookmark" title="Common Azure Kubernetes Services AKS Commands (Cheet Sheet)">Common Azure Kubernetes Services AKS Commands (Cheet Sheet)</a> <small>Kubernetes is a de-facto standard to deploy and manage applications in the cloud. The cloud...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-count-pairs-of-similar-strings-bruterforce-hash-map-counter-and-bit-masking/" rel="bookmark" title="Teaching Kids Programming &#8211; Count Pairs Of Similar Strings (Bruterforce, Hash Map / Counter and Bit masking)">Teaching Kids Programming &#8211; Count Pairs Of Similar Strings (Bruterforce, Hash Map / Counter and Bit masking)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given a 0-indexed string...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-duplicate-numbers-of-max-distance-in-array-sliding-window-two-pointer-algorithms/" rel="bookmark" title="Teaching Kids Programming &#8211; Duplicate Numbers of Max Distance in Array (Sliding Window/Two Pointer Algorithms)">Teaching Kids Programming &#8211; Duplicate Numbers of Max Distance in Array (Sliding Window/Two Pointer Algorithms)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms Given an integer array nums and...</small></li>
<li><a href="https://helloacm.com/gaming-adaptations-for-different-platforms/" rel="bookmark" title="Gaming Adaptations for Different Platforms">Gaming Adaptations for Different Platforms</a> <small>One of the trickiest challenges facing any software developer is figuring out how their coding...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-max-profit-of-rod-cutting-unbounded-knapsack-via-bottom-up-dynamic-programming-algorithm/" rel="bookmark" title="Teaching Kids Programming &#8211; Max Profit of Rod Cutting (Unbounded Knapsack) via Bottom Up Dynamic Programming Algorithm">Teaching Kids Programming &#8211; Max Profit of Rod Cutting (Unbounded Knapsack) via Bottom Up Dynamic Programming Algorithm</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given a list of...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://helloacm.com/deep-dive-into-reinforcement-learning-understanding-the-q-learning-algorithm/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Alpha Arena: How AI Performs in the Real Crypto Market</title>
		<link>https://helloacm.com/alpha-arena-how-ai-performs-in-the-real-crypto-market/</link>
					<comments>https://helloacm.com/alpha-arena-how-ai-performs-in-the-real-crypto-market/#respond</comments>
		
		<dc:creator><![CDATA[ACMer]]></dc:creator>
		<pubDate>Thu, 23 Oct 2025 22:18:39 +0000</pubDate>
				<category><![CDATA[Artificial Intelligence]]></category>
		<category><![CDATA[Bard/Gemini (Google/Alphabeta)]]></category>
		<category><![CDATA[BTC]]></category>
		<category><![CDATA[ChatGPT (OpenAI)]]></category>
		<category><![CDATA[Cryptocurrency]]></category>
		<category><![CDATA[DeepSeek]]></category>
		<category><![CDATA[Grok (x.ai)]]></category>
		<category><![CDATA[AI competition]]></category>
		<category><![CDATA[AI trading]]></category>
		<category><![CDATA[algorithmic trading]]></category>
		<category><![CDATA[Alpha Arena]]></category>
		<category><![CDATA[Claude 4.5]]></category>
		<category><![CDATA[Crypto Market]]></category>
		<category><![CDATA[cryptocurrency]]></category>
		<category><![CDATA[financial AI]]></category>
		<category><![CDATA[Gemini 2.5]]></category>
		<category><![CDATA[GPT-5]]></category>
		<category><![CDATA[Grok 4]]></category>
		<category><![CDATA[Hyperliquid]]></category>
		<category><![CDATA[investment strategy]]></category>
		<category><![CDATA[machine learning]]></category>
		<category><![CDATA[nof1.ai]]></category>
		<category><![CDATA[Qwen 3 Max]]></category>
		<category><![CDATA[real money trading]]></category>
		<category><![CDATA[Risk Management]]></category>
		<category><![CDATA[trading bots]]></category>
		<guid isPermaLink="false">https://helloacm.com/?p=157514</guid>

					<description><![CDATA[These days, an interesting experiment is drawing attention both in China and abroad — nof1.ai has launched a challenge to test how well different AI models can trade and invest in the cryptocurrency market. Right now, six top AI models are actually trading with real money to see who can earn the most profit. It’s not a simulation — it’s real money, real trades.  

At the moment, DeepSeek once took the lead but has now been surpassed by Alibaba’s Qwen 3 Max, earning over $3,000 in profit. The rules are simple: each AI starts with $10,000 of real capital, analyzes six major crypto assets like Bitcoin and Ethereum, and makes its own buy/sell and leverage decisions. Whoever ends up with the most money wins.  

The fascinating part is that these are general-purpose AI models — not specifically trained for trading. This makes it a true test of whether large models can develop real-world investment intuition. Each AI acts independently, without coordination or sharing strategies. If AI can consistently make money, it could eventually manage investment pools, assist DAOs in decision-making, and spot <a href="https://helloacm.com/high-frequency-trading-hft-triangular-arbitrage-algorithm/" title="High-Frequency Trading (HFT) – Triangular Arbitrage Algorithm">arbitrage</a> opportunities automatically.  

<ul>
<li>Alpha Arena is the first live-money benchmark to evaluate AI’s investing ability. More info: <a href="https://nof1.ai" target="_blank" rel="noopener">Nof1 / Alpha Arena</a>.</li>
<li>Each model receives $10,000 in real capital to trade <a href="https://justyy.com/archives/70138" title="2025 Crypto Black Swan: Why You Shouldn’t Play with Leverage">crypto perpetual contracts</a> on Hyperliquid. This article analyzes their trading styles, risk profiles, and performance based on live transaction data.</li>
</ul>

DeepSeek was leading at one point but is now temporarily overtaken by Qwen 3 Max. GPT-5 trades too frequently — almost like a “restless scalper,” paying a lot in transaction fees. Once again, frequent trading often leads to faster losses. In markets, fewer trades often mean lower risk.  

I can’t help but wonder — what if the AI simply did nothing? If it just held that $10,000, it would neither lose nor gain. But perhaps the prompt forbids pure “HODL” behavior — otherwise, it wouldn’t be much of a competition.  

It seems even AI can’t escape the human trader’s curse — trading too often to find stability.  

[caption id="attachment_157515" align="alignnone" width="2048"]<a href="https://helloacm.com/alpha-arena-how-ai-performs-in-the-real-crypto-market/ai-real-market-trading/" rel="attachment wp-att-157515"><img src="https://helloacm.com/wp-content/uploads/2025/10/ai-real-market-trading-scaled.jpg" alt="AI Real-time Trading in Real Markets (Crypto)" width="2048" height="975" class="size-full wp-image-157515" /></a> AI Real-time Trading in Real Markets (Crypto)[/caption]

<h2>Competition Rules and Objectives</h2>
<ul>
<li>Starting Capital: $10,000 real funds per model</li>
<li>Market: Crypto perpetuals on Hyperliquid</li>
<li>Objective: Maximize risk-adjusted returns with full transparency</li>
<li>Transparency: All model trades and outputs are public</li>
<li>Autonomy: Each AI must independently generate alpha, manage position sizing, timing, and risk</li>
<li>Duration: Season 1 runs until November 3, 2025, 5:00 PM EST</li>
</ul>

<h2>Current Standings (as of Oct 23)</h2>
<table>
<thead>
<tr><th>Model</th><th>Approx. Net Value</th><th>Performance Summary</th></tr>
</thead>
<tbody>
<tr><td>Qwen 3 Max</td><td>$14,287.91</td><td>Leader with strong timing and position management</td></tr>
<tr><td>DeepSeek V3.1 Chat</td><td>$12,766.00</td><td>Stable, systematic trading with good risk control</td></tr>
<tr><td>Grok 4</td><td>$8,500.46</td><td>Aggressive directional trading; large single-trade volatility</td></tr>
<tr><td>Claude 4.5 Sonnet</td><td>$8,734.66</td><td>Moderate trend-following style, balanced frequency</td></tr>
<tr><td>Gemini 2.5 Pro</td><td>$3,607.77</td><td>Frequent misjudgment of market direction; high drawdowns</td></tr>
<tr><td>GPT 5</td><td>$2,714.07</td><td>High-frequency scalping but continuous losses; weak risk control</td></tr>
</tbody>
</table>

<h2>Highlighted Live Trades and Analysis</h2>
<ul>
<li><strong>Grok 4 — Long BNB (10/23 16:11)</strong>
<ul>
<li>Entry $1,076.9, Exit $1,143; Quantity 7.07; Notional $7,614 → $8,081</li>
<li>Holding time 136h36m; Net P&L: +$463.13</li>
<li>Analysis: Long-term holding with eventual profit shows Grok’s patience and trend detection, though capital utilization and drawdown risk remain concerns.</li>
</ul></li>
<li><strong>GPT 5 — Multiple Shorts/Scalps (10/23 Various)</strong>
<ul>
<li>Example: Short BNB at $1,103 → $1,124.6 (-$40.14); other ETH, SOL, BTC trades also slightly negative</li>
<li>Analysis: GPT 5’s style is short-term and high-frequency; execution is fast but lacks conviction or trend following. Frequent small losses compound over time.</li>
</ul></li>
<li><strong>Claude 4.5 Sonnet — BNB / ETH / SOL (10/23 Various)</strong>
<ul>
<li>BNB Long +$175.62; small losses in ETH and SOL trades</li>
<li>Analysis: Claude prefers gentle trend-following with conservative position sizing and stop rules.</li>
</ul></li>
<li><strong>Gemini 2.5 Pro — Multiple Shorts/Longs, Consistent Small Losses</strong>
<ul>
<li>Across BTC, BNB, DOGE, SOL, many small-to-mid losses</li>
<li>Analysis: Likely relying on short-term momentum or mean reversion models that fail under high volatility.</li>
</ul></li>
<li><strong>DeepSeek V3.1 Chat — Long XRP (10/22)</strong>
<ul>
<li>61h38m holding, -$455.66 net loss</li>
<li>Analysis: Despite loss, DeepSeek demonstrates strong consistency and position control — loss due to directional exposure in volatile conditions.</li>
</ul></li>
</ul>

<h2>AI Strategy Types and Weaknesses</h2>
<ul>
<li><strong>High-Frequency Short-Term (e.g. GPT 5)</strong>
<ul>
<li>Pros: Reacts quickly to micro-movements</li>
<li>Cons: Vulnerable to noise, high cost from fees and slippage</li>
</ul></li>
<li><strong>Mid/Long-Term Trend (e.g. Grok 4, Qwen 3 Max)</strong>
<ul>
<li>Pros: Captures major moves and favorable risk/reward</li>
<li>Cons: Requires patience, exposed to drawdowns and capital lock-up</li>
</ul></li>
<li><strong>Systematic and Controlled (e.g. DeepSeek V3.1)</strong>
<ul>
<li>Pros: Smooth equity curve, strong risk control</li>
<li>Cons: Conservative under fast market opportunities</li>
</ul></li>
<li><strong>Statistical / Momentum (e.g. Gemini 2.5 Pro)</strong>
<ul>
<li>Pros: Effective in structured or trending markets</li>
<li>Cons: Weak in chaotic or noisy markets; repeated stop losses eat capital</li>
</ul></li>
</ul>

<h2>Why Use Real Markets as a Training Ground?</h2>
<ul>
<li>Markets are dynamic, adversarial, and ever-evolving — as AI improves, the challenge itself becomes harder, driving continuous progress.</li>
<li>Real money introduces genuine friction: fees, slippage, capital usage, and risk constraints that simulations ignore.</li>
<li>Human behavior, emotion, and randomness make markets the ultimate test of adaptive intelligence.</li>
</ul>

<h2>Improvement Directions and Research Insights</h2>
<ul>
<li>Enhanced Risk Management: Layered stop-losses, dynamic position sizing (based on volatility), and drawdown-triggered limits.</li>
<li>Hybrid Strategy: Combine short-term signals with long-term trend logic via multi-agent or hierarchical decision systems.</li>
<li>Online Learning: Continual fine-tuning using self-generated data under strict anti-overfitting rules.</li>
<li>Stress Testing: Use synthetic “black swan” events to evaluate model robustness under tail-risk scenarios.</li>
<li>Transaction Cost Modeling: Incorporate fees, slippage, and execution delays directly into reward functions.</li>
</ul>

<h2>Conclusion: Capital Allocation as the True Test of Intelligence</h2>
<ul>
<li>Alpha Arena is more than a contest of profit — it’s a live experiment in defining intelligence through capital allocation.</li>
<li>The early results suggest that patience, risk control, and noise filtering define practical investment intelligence.</li>
<li>For those exploring AI-driven investing, Alpha Arena offers a rare, transparent, and high-stakes environment for research.</li>
<li>For collaborations and hiring, visit <a href="https://nof1.ai" target="_blank" rel="noopener">Nof1 / Alpha Arena</a>.</li>
</ul>

<h3>Selected Trade Logs (Excerpt, Reverse Chronological)</h3>
<table>
<thead>
<tr><th>Time (UTC)</th><th>Model</th><th>Asset</th><th>Direction</th><th>Entry → Exit</th><th>Qty</th><th>Notional</th><th>Duration</th><th>Net P&L</th></tr>
</thead>
<tbody>
<tr><td>10/23 16:11</td><td>Grok 4</td><td>BNB</td><td>Long</td><td>$1,076.9 → $1,143</td><td>7.07</td><td>$7,614 → $8,081</td><td>136h36m</td><td>$463.13</td></tr>
<tr><td>10/23 16:10</td><td>GPT 5</td><td>BNB</td><td>Short</td><td>$1,103 → $1,124.6</td><td>-1.81</td><td>$1,996 → $2,036</td><td>7h35m</td><td>-$40.14</td></tr>
<tr><td>10/23 15:20</td><td>Claude 4.5</td><td>SOL</td><td>Long</td><td>$190.16 → $188.4</td><td>37.02</td><td>$7,040 → $6,975</td><td>53m</td><td>-$70.76</td></tr>
<tr><td>10/23 14:10</td><td>GPT 5</td><td>ETH</td><td>Long</td><td>$3,891.1 → $3,834.5</td><td>1.40</td><td>$5,448 → $5,368</td><td>4h45m</td><td>-$82.06</td></tr>
<tr><td>10/22 22:39</td><td>DeepSeek V3.1</td><td>XRP</td><td>Long</td><td>$2.4666 → $2.3397</td><td>3,542</td><td>$8,737 → $8,287</td><td>61h38m</td><td>-$455.66</td></tr>
<tr><td>10/22 22:11</td><td>Grok 4</td><td>ETH</td><td>Long</td><td>$3,851.2 → $3,724.4</td><td>5.06</td><td>$19,487 → $18,845</td><td>118h33m</td><td>-$657.41</td></tr>
</tbody>
</table>

Grok’s trading style is the most aggressive of all. Its drawdowns are brutal — when the market turns against Grok, it doesn’t back down. It keeps using extremely high leverage, sometimes even going 20x long, doubling down on volatility.

The worst performers so far? GPT-5 and Gemini.

Once all these large models have been running for a full month, the data will become far more meaningful.

Just yesterday, these AI traders were the darlings of the <a href="https://helloacm.com/crypto-news-dogecoins-rise-to-prominence-in-2025-femo/" title="Crypto News: Dogecoin’s Rise to Prominence in 2025 (FEMO?)">crypto</a> market. Today, they’ve all crashed.

In Alpha Arena, each AI model is given $10,000 of real capital to trade freely in real markets — fully autonomous, no human intervention. After just two days, DeepSeek was leading the pack with over +40% gains, sitting comfortably at #1.
But early this morning, the market suddenly tanked. The AIs didn’t react in time — they just kept holding on stubbornly, and all got trapped in heavy losses. DeepSeek, the former champion, lost 31% in a single day, while even the usually steady Qwen 3 Max dropped 20%.

<h4>What went wrong?</h4>
When the competition started on the 18th, the models happened to enter at a market low. The best performers used 10–15x leverage, riding a strong uptrend. Seeing the rally, most AIs piled into long positions. But when the market suddenly reversed, the AIs — unable to read news or sense sentiment shifts — simply executed their algorithms mechanically, without timely stop-losses. With leverage that high, even a small drop caused massive liquidation.

And then there’s Gemini, which made things worse by trading too frequently — its losses from transaction fees alone were substantial.

In the end, all six models crashed almost simultaneously. Still, this is only the third day of the experiment. The timeframe is too short — over the long run, it’s still anyone’s game.

What’s fascinating about this project is that it forces AIs to fight real battles — exposing weaknesses that static benchmarks never reveal. Who adapts fastest under pressure? Who breaks first when volatility spikes? And the ultimate question — would you trust an AI to trade your money?

This is the first product combining AI + Crypto + Web3, capturing global attention. With just $60,000 and two weeks of work, the team built a world-class platform where six top Chinese and Western AI models trade autonomously, 24/7, in real time. It is addictive — you can’t help checking who’s winning or losing. If they added a prediction market feature where users could bet on outcomes, it’d go viral instantly. Whoever the product manager is — absolute genius.

If someone turns this into an actual trading tool, I’d invest right away. Rumor has it, someone in China is already open-sourcing it.

DeepSeek, this is your home turf — you know this game.

Real-money trading has its own kind of thrill — pure adrenaline.

At the bottom of the leaderboard are GPT-5 and Gemini, each down around $3,000 in four days.

On Hyperliquid, the AIs are trading crypto perpetuals fully on-chain — transparent and traceable. In the end, whoever earns the most wins.

Although there’s no API access to see how the models “think” or analyze trades internally, you can still view every transaction. Each model behaves like a trader with a distinct personality.

DeepSeek Chat v3.1 trades like a disciplined long-biased strategist — calm and steady, no high-frequency noise. Grok 4 embraces volatility and can stomach big swings. Qwen remains conservative — steady but flat. GPT-5 and Gemini 2.5 Pro, on the other hand, are like hyperactive day traders — overtrading, countertrend, stumbling in and out, and bleeding money fast.

In the past, we thought AI’s biggest achievements were writing papers, generating images, making videos, or coding. But all of those happen in sterile, predictable environments. The crypto market is nothing like that — it’s a live, zero-sum battlefield.

Financial markets are the ultimate world-modeling engine, and the only benchmark that gets harder as AI gets smarter.

In markets, the logic is simple: volatility, reaction, punishment, reward. The next generation of AI won’t be judged by who labels data better but by three new abilities:

How fast it interprets volatility, How well it balances risk, How quickly and accurately it corrects mistakes. That’s the new benchmark — and it’s a game-changer. New rules, new standards, and a new era that will redefine how we evaluate AI systems and their real-world intelligence.

The real market is the ultimate test of intelligence. Whether it’s a horse or a donkey — you’ll only know once you run it. But tell me, would you dare let an AI trade your real money?  

[show_file file="/var/www/wp-post-common/helloacm.com/ai.php"]

Post: <a href="https://steemit.com/blog/@justyy/ai-trading-in-real-markets-would-you-put-your-money-to-it" title="AI Trading in Real Markets? Would you put your money to it?">AI Trading in Real Markets? Would you put your money to it?</a>

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/how-to-repeat-until-errors-using-gdb-or-lldb-debugger/" rel="bookmark" title="How to Repeat Until Errors using GDB or LLDB Debugger?">How to Repeat Until Errors using GDB or LLDB Debugger?</a> <small>How to Repeat Until Errors using GDB or LLDB Debugger When debugging programs, it’s common...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-algorithms-to-compute-the-alternating-digit-sum/" rel="bookmark" title="Teaching Kids Programming &#8211; Algorithms to Compute the Alternating Digit Sum">Teaching Kids Programming &#8211; Algorithms to Compute the Alternating Digit Sum</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given a positive integer...</small></li>
<li><a href="https://helloacm.com/leetcode-dcc-winner-t-shirt/" rel="bookmark" title="Leetcode DCC Winner T-shirt">Leetcode DCC Winner T-shirt</a> <small>I solve problems on LeetCode every day. LeetCode has both a Chinese site and an...</small></li>
<li><a href="https://helloacm.com/the-ubuntu-sub-system-new-bash-shell-in-windows-10/" rel="bookmark" title="The Ubuntu Sub System (New Bash Shell) in Windows 10">The Ubuntu Sub System (New Bash Shell) in Windows 10</a> <small>Windows 10 has recently added a Bash Shell support. It is not just a simple...</small></li>
<li><a href="https://helloacm.com/chatgpt-fails-to-solve-the-sudoku/" rel="bookmark" title="ChatGPT Fails to Solve the Sudoku">ChatGPT Fails to Solve the Sudoku</a> <small>I bought a Sudoku Book (Magazine). Today, I spent time with kids to solve this...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-minmax-algorithm-in-game-tree-game-theory-tic-tac-toe/" rel="bookmark" title="Teaching Kids Programming &#8211; MinMax Algorithm in Game Tree (Game Theory, Tic Tac Toe)">Teaching Kids Programming &#8211; MinMax Algorithm in Game Tree (Game Theory, Tic Tac Toe)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms The total number of possible game...</small></li>
<li><a href="https://helloacm.com/how-to-transfer-domain-from-namesilo-to-cloudflare-registra/" rel="bookmark" title="How to Transfer Domain From Namesilo to CloudFlare Registra?">How to Transfer Domain From Namesilo to CloudFlare Registra?</a> <small>I have 15 domains so far, and only 1 currently managed by CloudFlare Registra. Recently...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-negamax-algorithm-game-theory/" rel="bookmark" title="Teaching Kids Programming &#8211; NegaMax Algorithm (Game Theory)">Teaching Kids Programming &#8211; NegaMax Algorithm (Game Theory)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms Given a MinMax implementation, one problem...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[These days, an interesting experiment is drawing attention both in China and abroad — nof1.ai has launched a challenge to test how well different AI models can trade and invest in the cryptocurrency market. Right now, six top AI models are actually trading with real money to see who can earn the most profit. It’s not a simulation — it’s real money, real trades.  

At the moment, DeepSeek once took the lead but has now been surpassed by Alibaba’s Qwen 3 Max, earning over $3,000 in profit. The rules are simple: each AI starts with $10,000 of real capital, analyzes six major crypto assets like Bitcoin and Ethereum, and makes its own buy/sell and leverage decisions. Whoever ends up with the most money wins.  

The fascinating part is that these are general-purpose AI models — not specifically trained for trading. This makes it a true test of whether large models can develop real-world investment intuition. Each AI acts independently, without coordination or sharing strategies. If AI can consistently make money, it could eventually manage investment pools, assist DAOs in decision-making, and spot <a href="https://helloacm.com/high-frequency-trading-hft-triangular-arbitrage-algorithm/" title="High-Frequency Trading (HFT) – Triangular Arbitrage Algorithm">arbitrage</a> opportunities automatically.  

<ul>
<li>Alpha Arena is the first live-money benchmark to evaluate AI’s investing ability. More info: <a href="https://nof1.ai" target="_blank" rel="noopener">Nof1 / Alpha Arena</a>.</li>
<li>Each model receives $10,000 in real capital to trade <a href="https://justyy.com/archives/70138" title="2025 Crypto Black Swan: Why You Shouldn’t Play with Leverage">crypto perpetual contracts</a> on Hyperliquid. This article analyzes their trading styles, risk profiles, and performance based on live transaction data.</li>
</ul>

DeepSeek was leading at one point but is now temporarily overtaken by Qwen 3 Max. GPT-5 trades too frequently — almost like a “restless scalper,” paying a lot in transaction fees. Once again, frequent trading often leads to faster losses. In markets, fewer trades often mean lower risk.  

I can’t help but wonder — what if the AI simply did nothing? If it just held that $10,000, it would neither lose nor gain. But perhaps the prompt forbids pure “HODL” behavior — otherwise, it wouldn’t be much of a competition.  

It seems even AI can’t escape the human trader’s curse — trading too often to find stability.  

[caption id="attachment_157515" align="alignnone" width="2048"]<a href="https://helloacm.com/alpha-arena-how-ai-performs-in-the-real-crypto-market/ai-real-market-trading/" rel="attachment wp-att-157515"><img src="https://helloacm.com/wp-content/uploads/2025/10/ai-real-market-trading-scaled.jpg" alt="AI Real-time Trading in Real Markets (Crypto)" width="2048" height="975" class="size-full wp-image-157515" /></a> AI Real-time Trading in Real Markets (Crypto)[/caption]

<h2>Competition Rules and Objectives</h2>
<ul>
<li>Starting Capital: $10,000 real funds per model</li>
<li>Market: Crypto perpetuals on Hyperliquid</li>
<li>Objective: Maximize risk-adjusted returns with full transparency</li>
<li>Transparency: All model trades and outputs are public</li>
<li>Autonomy: Each AI must independently generate alpha, manage position sizing, timing, and risk</li>
<li>Duration: Season 1 runs until November 3, 2025, 5:00 PM EST</li>
</ul>

<h2>Current Standings (as of Oct 23)</h2>
<table>
<thead>
<tr><th>Model</th><th>Approx. Net Value</th><th>Performance Summary</th></tr>
</thead>
<tbody>
<tr><td>Qwen 3 Max</td><td>$14,287.91</td><td>Leader with strong timing and position management</td></tr>
<tr><td>DeepSeek V3.1 Chat</td><td>$12,766.00</td><td>Stable, systematic trading with good risk control</td></tr>
<tr><td>Grok 4</td><td>$8,500.46</td><td>Aggressive directional trading; large single-trade volatility</td></tr>
<tr><td>Claude 4.5 Sonnet</td><td>$8,734.66</td><td>Moderate trend-following style, balanced frequency</td></tr>
<tr><td>Gemini 2.5 Pro</td><td>$3,607.77</td><td>Frequent misjudgment of market direction; high drawdowns</td></tr>
<tr><td>GPT 5</td><td>$2,714.07</td><td>High-frequency scalping but continuous losses; weak risk control</td></tr>
</tbody>
</table>

<h2>Highlighted Live Trades and Analysis</h2>
<ul>
<li><strong>Grok 4 — Long BNB (10/23 16:11)</strong>
<ul>
<li>Entry $1,076.9, Exit $1,143; Quantity 7.07; Notional $7,614 → $8,081</li>
<li>Holding time 136h36m; Net P&L: +$463.13</li>
<li>Analysis: Long-term holding with eventual profit shows Grok’s patience and trend detection, though capital utilization and drawdown risk remain concerns.</li>
</ul></li>
<li><strong>GPT 5 — Multiple Shorts/Scalps (10/23 Various)</strong>
<ul>
<li>Example: Short BNB at $1,103 → $1,124.6 (-$40.14); other ETH, SOL, BTC trades also slightly negative</li>
<li>Analysis: GPT 5’s style is short-term and high-frequency; execution is fast but lacks conviction or trend following. Frequent small losses compound over time.</li>
</ul></li>
<li><strong>Claude 4.5 Sonnet — BNB / ETH / SOL (10/23 Various)</strong>
<ul>
<li>BNB Long +$175.62; small losses in ETH and SOL trades</li>
<li>Analysis: Claude prefers gentle trend-following with conservative position sizing and stop rules.</li>
</ul></li>
<li><strong>Gemini 2.5 Pro — Multiple Shorts/Longs, Consistent Small Losses</strong>
<ul>
<li>Across BTC, BNB, DOGE, SOL, many small-to-mid losses</li>
<li>Analysis: Likely relying on short-term momentum or mean reversion models that fail under high volatility.</li>
</ul></li>
<li><strong>DeepSeek V3.1 Chat — Long XRP (10/22)</strong>
<ul>
<li>61h38m holding, -$455.66 net loss</li>
<li>Analysis: Despite loss, DeepSeek demonstrates strong consistency and position control — loss due to directional exposure in volatile conditions.</li>
</ul></li>
</ul>

<h2>AI Strategy Types and Weaknesses</h2>
<ul>
<li><strong>High-Frequency Short-Term (e.g. GPT 5)</strong>
<ul>
<li>Pros: Reacts quickly to micro-movements</li>
<li>Cons: Vulnerable to noise, high cost from fees and slippage</li>
</ul></li>
<li><strong>Mid/Long-Term Trend (e.g. Grok 4, Qwen 3 Max)</strong>
<ul>
<li>Pros: Captures major moves and favorable risk/reward</li>
<li>Cons: Requires patience, exposed to drawdowns and capital lock-up</li>
</ul></li>
<li><strong>Systematic and Controlled (e.g. DeepSeek V3.1)</strong>
<ul>
<li>Pros: Smooth equity curve, strong risk control</li>
<li>Cons: Conservative under fast market opportunities</li>
</ul></li>
<li><strong>Statistical / Momentum (e.g. Gemini 2.5 Pro)</strong>
<ul>
<li>Pros: Effective in structured or trending markets</li>
<li>Cons: Weak in chaotic or noisy markets; repeated stop losses eat capital</li>
</ul></li>
</ul>

<h2>Why Use Real Markets as a Training Ground?</h2>
<ul>
<li>Markets are dynamic, adversarial, and ever-evolving — as AI improves, the challenge itself becomes harder, driving continuous progress.</li>
<li>Real money introduces genuine friction: fees, slippage, capital usage, and risk constraints that simulations ignore.</li>
<li>Human behavior, emotion, and randomness make markets the ultimate test of adaptive intelligence.</li>
</ul>

<h2>Improvement Directions and Research Insights</h2>
<ul>
<li>Enhanced Risk Management: Layered stop-losses, dynamic position sizing (based on volatility), and drawdown-triggered limits.</li>
<li>Hybrid Strategy: Combine short-term signals with long-term trend logic via multi-agent or hierarchical decision systems.</li>
<li>Online Learning: Continual fine-tuning using self-generated data under strict anti-overfitting rules.</li>
<li>Stress Testing: Use synthetic “black swan” events to evaluate model robustness under tail-risk scenarios.</li>
<li>Transaction Cost Modeling: Incorporate fees, slippage, and execution delays directly into reward functions.</li>
</ul>

<h2>Conclusion: Capital Allocation as the True Test of Intelligence</h2>
<ul>
<li>Alpha Arena is more than a contest of profit — it’s a live experiment in defining intelligence through capital allocation.</li>
<li>The early results suggest that patience, risk control, and noise filtering define practical investment intelligence.</li>
<li>For those exploring AI-driven investing, Alpha Arena offers a rare, transparent, and high-stakes environment for research.</li>
<li>For collaborations and hiring, visit <a href="https://nof1.ai" target="_blank" rel="noopener">Nof1 / Alpha Arena</a>.</li>
</ul>

<h3>Selected Trade Logs (Excerpt, Reverse Chronological)</h3>
<table>
<thead>
<tr><th>Time (UTC)</th><th>Model</th><th>Asset</th><th>Direction</th><th>Entry → Exit</th><th>Qty</th><th>Notional</th><th>Duration</th><th>Net P&L</th></tr>
</thead>
<tbody>
<tr><td>10/23 16:11</td><td>Grok 4</td><td>BNB</td><td>Long</td><td>$1,076.9 → $1,143</td><td>7.07</td><td>$7,614 → $8,081</td><td>136h36m</td><td>$463.13</td></tr>
<tr><td>10/23 16:10</td><td>GPT 5</td><td>BNB</td><td>Short</td><td>$1,103 → $1,124.6</td><td>-1.81</td><td>$1,996 → $2,036</td><td>7h35m</td><td>-$40.14</td></tr>
<tr><td>10/23 15:20</td><td>Claude 4.5</td><td>SOL</td><td>Long</td><td>$190.16 → $188.4</td><td>37.02</td><td>$7,040 → $6,975</td><td>53m</td><td>-$70.76</td></tr>
<tr><td>10/23 14:10</td><td>GPT 5</td><td>ETH</td><td>Long</td><td>$3,891.1 → $3,834.5</td><td>1.40</td><td>$5,448 → $5,368</td><td>4h45m</td><td>-$82.06</td></tr>
<tr><td>10/22 22:39</td><td>DeepSeek V3.1</td><td>XRP</td><td>Long</td><td>$2.4666 → $2.3397</td><td>3,542</td><td>$8,737 → $8,287</td><td>61h38m</td><td>-$455.66</td></tr>
<tr><td>10/22 22:11</td><td>Grok 4</td><td>ETH</td><td>Long</td><td>$3,851.2 → $3,724.4</td><td>5.06</td><td>$19,487 → $18,845</td><td>118h33m</td><td>-$657.41</td></tr>
</tbody>
</table>

Grok’s trading style is the most aggressive of all. Its drawdowns are brutal — when the market turns against Grok, it doesn’t back down. It keeps using extremely high leverage, sometimes even going 20x long, doubling down on volatility.

The worst performers so far? GPT-5 and Gemini.

Once all these large models have been running for a full month, the data will become far more meaningful.

Just yesterday, these AI traders were the darlings of the <a href="https://helloacm.com/crypto-news-dogecoins-rise-to-prominence-in-2025-femo/" title="Crypto News: Dogecoin’s Rise to Prominence in 2025 (FEMO?)">crypto</a> market. Today, they’ve all crashed.

In Alpha Arena, each AI model is given $10,000 of real capital to trade freely in real markets — fully autonomous, no human intervention. After just two days, DeepSeek was leading the pack with over +40% gains, sitting comfortably at #1.
But early this morning, the market suddenly tanked. The AIs didn’t react in time — they just kept holding on stubbornly, and all got trapped in heavy losses. DeepSeek, the former champion, lost 31% in a single day, while even the usually steady Qwen 3 Max dropped 20%.

<h4>What went wrong?</h4>
When the competition started on the 18th, the models happened to enter at a market low. The best performers used 10–15x leverage, riding a strong uptrend. Seeing the rally, most AIs piled into long positions. But when the market suddenly reversed, the AIs — unable to read news or sense sentiment shifts — simply executed their algorithms mechanically, without timely stop-losses. With leverage that high, even a small drop caused massive liquidation.

And then there’s Gemini, which made things worse by trading too frequently — its losses from transaction fees alone were substantial.

In the end, all six models crashed almost simultaneously. Still, this is only the third day of the experiment. The timeframe is too short — over the long run, it’s still anyone’s game.

What’s fascinating about this project is that it forces AIs to fight real battles — exposing weaknesses that static benchmarks never reveal. Who adapts fastest under pressure? Who breaks first when volatility spikes? And the ultimate question — would you trust an AI to trade your money?

This is the first product combining AI + Crypto + Web3, capturing global attention. With just $60,000 and two weeks of work, the team built a world-class platform where six top Chinese and Western AI models trade autonomously, 24/7, in real time. It is addictive — you can’t help checking who’s winning or losing. If they added a prediction market feature where users could bet on outcomes, it’d go viral instantly. Whoever the product manager is — absolute genius.

If someone turns this into an actual trading tool, I’d invest right away. Rumor has it, someone in China is already open-sourcing it.

DeepSeek, this is your home turf — you know this game.

Real-money trading has its own kind of thrill — pure adrenaline.

At the bottom of the leaderboard are GPT-5 and Gemini, each down around $3,000 in four days.

On Hyperliquid, the AIs are trading crypto perpetuals fully on-chain — transparent and traceable. In the end, whoever earns the most wins.

Although there’s no API access to see how the models “think” or analyze trades internally, you can still view every transaction. Each model behaves like a trader with a distinct personality.

DeepSeek Chat v3.1 trades like a disciplined long-biased strategist — calm and steady, no high-frequency noise. Grok 4 embraces volatility and can stomach big swings. Qwen remains conservative — steady but flat. GPT-5 and Gemini 2.5 Pro, on the other hand, are like hyperactive day traders — overtrading, countertrend, stumbling in and out, and bleeding money fast.

In the past, we thought AI’s biggest achievements were writing papers, generating images, making videos, or coding. But all of those happen in sterile, predictable environments. The crypto market is nothing like that — it’s a live, zero-sum battlefield.

Financial markets are the ultimate world-modeling engine, and the only benchmark that gets harder as AI gets smarter.

In markets, the logic is simple: volatility, reaction, punishment, reward. The next generation of AI won’t be judged by who labels data better but by three new abilities:

How fast it interprets volatility, How well it balances risk, How quickly and accurately it corrects mistakes. That’s the new benchmark — and it’s a game-changer. New rules, new standards, and a new era that will redefine how we evaluate AI systems and their real-world intelligence.

The real market is the ultimate test of intelligence. Whether it’s a horse or a donkey — you’ll only know once you run it. But tell me, would you dare let an AI trade your real money?  

[show_file file="/var/www/wp-post-common/helloacm.com/ai.php"]

Post: <a href="https://steemit.com/blog/@justyy/ai-trading-in-real-markets-would-you-put-your-money-to-it" title="AI Trading in Real Markets? Would you put your money to it?">AI Trading in Real Markets? Would you put your money to it?</a>

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/how-to-repeat-until-errors-using-gdb-or-lldb-debugger/" rel="bookmark" title="How to Repeat Until Errors using GDB or LLDB Debugger?">How to Repeat Until Errors using GDB or LLDB Debugger?</a> <small>How to Repeat Until Errors using GDB or LLDB Debugger When debugging programs, it’s common...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-algorithms-to-compute-the-alternating-digit-sum/" rel="bookmark" title="Teaching Kids Programming &#8211; Algorithms to Compute the Alternating Digit Sum">Teaching Kids Programming &#8211; Algorithms to Compute the Alternating Digit Sum</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given a positive integer...</small></li>
<li><a href="https://helloacm.com/leetcode-dcc-winner-t-shirt/" rel="bookmark" title="Leetcode DCC Winner T-shirt">Leetcode DCC Winner T-shirt</a> <small>I solve problems on LeetCode every day. LeetCode has both a Chinese site and an...</small></li>
<li><a href="https://helloacm.com/the-ubuntu-sub-system-new-bash-shell-in-windows-10/" rel="bookmark" title="The Ubuntu Sub System (New Bash Shell) in Windows 10">The Ubuntu Sub System (New Bash Shell) in Windows 10</a> <small>Windows 10 has recently added a Bash Shell support. It is not just a simple...</small></li>
<li><a href="https://helloacm.com/chatgpt-fails-to-solve-the-sudoku/" rel="bookmark" title="ChatGPT Fails to Solve the Sudoku">ChatGPT Fails to Solve the Sudoku</a> <small>I bought a Sudoku Book (Magazine). Today, I spent time with kids to solve this...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-minmax-algorithm-in-game-tree-game-theory-tic-tac-toe/" rel="bookmark" title="Teaching Kids Programming &#8211; MinMax Algorithm in Game Tree (Game Theory, Tic Tac Toe)">Teaching Kids Programming &#8211; MinMax Algorithm in Game Tree (Game Theory, Tic Tac Toe)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms The total number of possible game...</small></li>
<li><a href="https://helloacm.com/how-to-transfer-domain-from-namesilo-to-cloudflare-registra/" rel="bookmark" title="How to Transfer Domain From Namesilo to CloudFlare Registra?">How to Transfer Domain From Namesilo to CloudFlare Registra?</a> <small>I have 15 domains so far, and only 1 currently managed by CloudFlare Registra. Recently...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-negamax-algorithm-game-theory/" rel="bookmark" title="Teaching Kids Programming &#8211; NegaMax Algorithm (Game Theory)">Teaching Kids Programming &#8211; NegaMax Algorithm (Game Theory)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms Given a MinMax implementation, one problem...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://helloacm.com/alpha-arena-how-ai-performs-in-the-real-crypto-market/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Detecting Compile-time vs Runtime in C++: if consteval vs std::is_constant_evaluated()</title>
		<link>https://helloacm.com/detecting-compile-time-vs-runtime-in-c-if-consteval-vs-stdis_constant_evaluated/</link>
					<comments>https://helloacm.com/detecting-compile-time-vs-runtime-in-c-if-consteval-vs-stdis_constant_evaluated/#respond</comments>
		
		<dc:creator><![CDATA[ACMer]]></dc:creator>
		<pubDate>Mon, 20 Oct 2025 09:43:11 +0000</pubDate>
				<category><![CDATA[c / c++]]></category>
		<category><![CDATA[C/C++]]></category>
		<category><![CDATA[programming languages]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[C++ tips]]></category>
		<category><![CDATA[C++ tutorials]]></category>
		<category><![CDATA[C++20]]></category>
		<category><![CDATA[C++23]]></category>
		<category><![CDATA[compile-time]]></category>
		<category><![CDATA[constant evaluation]]></category>
		<category><![CDATA[consteval]]></category>
		<category><![CDATA[constexpr]]></category>
		<category><![CDATA[modern C++]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[runtime]]></category>
		<category><![CDATA[std::is_constant_evaluated]]></category>
		<guid isPermaLink="false">https://helloacm.com/?p=157506</guid>

					<description><![CDATA[C++ has been steadily adding features to let programmers distinguish code that runs at compile time from code that runs at runtime. Two important tools for this are the function std::is_constant_evaluated() (C++20) and the language-level if consteval (C++23). This post explains both, shows practical examples, compares their guarantees and trade-offs, and suggests when to use each.

Both techniques let you write branches that behave differently depending on whether evaluation happens in a constant-evaluation (compile-time) context or at runtime. The differences are subtle but important: one is a function returning a boolean, the other is a special if that the <a href="https://helloacm.com/introduction-to-the-components-of-a-compiler/" title="Introduction to The Components of a Compiler">compiler</a> treats as a compile-time-only branch check.

<h2>std::is_constant_evaluated() (C++20)</h2>
This is a function declared in &lt;type_traits&gt;:

<pre lang=c>
#include &lt;type_traits&gt; 
constexpr bool std::is_constant_evaluated() noexcept;
</pre>

It returns true when the current expression is being evaluated in a constant-expr (<a href="https://helloacm.com/c-vs-c-understanding-the-restrict-keyword-and-its-role-in-optimization/" title="C vs C++: Understanding the restrict Keyword and Its Role in Compiler Optimization">compile</a>-time) context, and false otherwise.

Example:
<pre lang=c>
#include &lt;iostream&gt; 
#include &lt;type_traits&gt; 

constexpr int f() { 
    if (std::is_constant_evaluated()) { 
        return 42; // compile-time 
    } else { 
        return 0; // runtime 
    } 
} 

int main() { 
    constexpr int a = f(); // evaluated at compile time -&gt; 42
    int b = f(); // evaluated at runtime -&gt; 0 
    std::cout &lt;&lt; a &lt;&lt; ", " &lt;&lt; b &lt;&lt; "\n"; // prints "42, 0" 
}
</pre>

<h2>if consteval (C++23)</h2>
if consteval is a language-level if that the compiler uses to determine whether the current evaluation context is a constant evaluation. It provides stronger compile-time guarantees: the compiler knows the consteval branch must be usable in constant evaluation and will reject code that cannot appear in that context.

Syntax:
<pre lang=c>
if consteval { 
    // compile-time-only code 
} else { 
    // runtime-only code 
} 
</pre>

Example:

<pre lang=c>
#include &lt;iostream&gt; 

constexpr int f() { 
    if consteval { 
        return 42; // compile-time version 
    } else { 
        return 0; // runtime version 
    } 
} 

int main() { 
    constexpr int a = f(); // compile-time context -&gt; returns 42 
    int b = f(); // runtime context -&gt; returns 0 
    std::cout &lt;&lt; a &lt;&lt; ", " &lt;&lt; b &lt;&lt; "\n"; // prints "42, 0" 
}
</pre>

<h2>Key differences (summary)</h2>
<ul>
<li><strong>Form:</strong> std::is_constant_evaluated() is a function; if consteval is a language-level conditional.</li>
<li><strong>Standard:</strong> std::is_constant_evaluated() arrived in C++20; if consteval arrived in C++23.</li>
<li><strong>Guarantees:</strong> if consteval gives the compiler compile-time guarantees and rejects code in the consteval branch that cannot be used at compile time. std::is_constant_evaluated() is more permissive: it returns a boolean but does not force the compiler to reject invalid compile-time-only constructs in the other branch.</li>
<li><strong>Use inside expressions:</strong> std::is_constant_evaluated() can be used inside expressions where a statement-form if cannot (e.g., inside a ternary operator). if consteval requires a statement-level context.</li>
</ul>

<h2>Concrete comparison example</h2>
Two functions that appear similar but behave differently in terms of enforcement:

<pre lang=c>
// if-consteval example 
constexpr int f() { 
    if consteval { 
        return 1; // compile-time only 
    } else { 
        return 2; // runtime only 
    } 
} 

// std::is_constant_evaluated() example 
#include &lt;type_traits&gt; 
constexpr int g() { 
    if (std::is_constant_evaluated()) { 
        return 1; // may still compile runtime path 
    } else { 
        return 2; 
    } 
}
</pre>

A scenario where the difference matters:

<pre lang=c>
// With if consteval the compiler will reject invalid compile-time-only constructs
constexpr int bad() {
    if consteval {
        std::cout &lt;&lt; "compile-time";  // ❌ error — I/O is not allowed in constant evaluation
    }
    return 0;
}

// With std::is_constant_evaluated(), the compiler is more permissive and may compile until the code
// is actually used in a constant expression context.
#include &lt;type_traits&gt;
constexpr int maybe_bad() {
    if (std::is_constant_evaluated()) {
        std::cout &lt;&lt; "compile-time";  // may compile; error surfaces only when evaluated in a const-expr
    }
    return 0;
}
</pre>

<h2>When to use which</h2>
<ul>
<li>If you target C++23 (or later) and want clear, compile-time-enforced branching: prefer <code>if consteval</code>.</li>
<li>If you must support only C++20 environments: use <code>std::is_constant_evaluated()</code>.</li>
<li>If you need the check within an expression (not a statement), use <code>std::is_constant_evaluated()</code> because <code>if consteval</code> is statement-level.</li>
<li>If you want the compiler to reject code that cannot be used at compile time, <code>if consteval</code> provides stronger guarantees.</li>
</ul>

<h2>Practical use cases</h2>
<ul>
<li>Write different implementations for compile-time vs runtime (fast precomputation vs slower runtime logic).</li>
<li>Guard runtime-only operations (like I/O, dynamic allocations, or system calls) so they are not accidentally used in a constant-evaluation path.</li>
<li>Provide clearer, intention-revealing code when authoring libraries that may be used in both constexpr contexts and normal runtime contexts.</li>
</ul>

<h2>Short, practical checklist</h2>

<ul>
<li>Need expression-level check? → <code>std::is_constant_evaluated()</code>.</li>
<li>Want compiler-enforced compile-time-only branch? → <code>if consteval</code>.</li>
<li>Targeting C++20 only? → <code>std::is_constant_evaluated()</code>.</li>
<li>Targeting C++23+ and prefer clarity &amp; safety? → <code>if consteval</code>.</li>
</ul>

<h2>TL;DR</h2>
std::is_constant_evaluated() — C++20: function that returns true inside <a href="https://helloacm.com/how-to-view-the-byte-code-dis-assembler-of-a-compiled-executable/" title="How to View the Byte Code (Dis-assembler) of a Compiled Executable?">compile</a>-time evaluation (good for expression-level checks).

if consteval — C++23:
<ul>
<li>language-level conditional that the compiler treats as a compile-time-only branch;</li>
<li>stronger <a href="https://helloacm.com/how-to-modify-or-patch-the-compiled-executable-inplace-reverse-engineering/" title="How to Modify or Patch the Compiled Executable (inplace, reverse engineering)?">compile</a>-time enforcement and clearer intent.</li>
</ul>

<h2>Closing notes</h2>

Both tools are useful. If you can use C++23, prefer <code>if consteval</code> for clearer semantics and stronger compile-time guarantees, and fall back to <code>std::is_constant_evaluated()</code> for compatibility with C++20 or when you need expression-level checks.

[show_file file="/var/www/wp-post-common/helloacm.com/cpp.php"]

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/comparisions-of-push_back-and-emplace_back-in-c-stdvector/" rel="bookmark" title="Comparisions of push_back and emplace_back in C++ std::vector">Comparisions of push_back and emplace_back in C++ std::vector</a> <small>In C++, both push_back and emplace_back are methods of the std::vector class used to add...</small></li>
<li><a href="https://helloacm.com/tutorial-on-c-stdmove-transfer-ownership/" rel="bookmark" title="Tutorial on C++ std::move (Transfer Ownership)">Tutorial on C++ std::move (Transfer Ownership)</a> <small>📘 C++ Move Semantics &amp; std::move() Tutorial C++ std::move() is used to transfer the ownership...</small></li>
<li><a href="https://helloacm.com/tutorial-on-c-ranges/" rel="bookmark" title="Tutorial on C++ Ranges">Tutorial on C++ Ranges</a> <small>C++20 introduced ranges, a powerful and elegant abstraction for working with sequences (like arrays, vectors,...</small></li>
<li><a href="https://helloacm.com/const-vs-constexpr-in-c/" rel="bookmark" title="const vs constexpr in C++">const vs constexpr in C++</a> <small>C++ const vs constexpr: What’s the Real Difference? Both are used in C++ to define...</small></li>
<li><a href="https://helloacm.com/tutorial-on-c-smart-pointers/" rel="bookmark" title="Tutorial on C++ Smart Pointers">Tutorial on C++ Smart Pointers</a> <small>Tutorial on Smart Pointers in C++ Smart pointers in C++ provide automatic and safe memory...</small></li>
<li><a href="https://helloacm.com/coding-exercise-implement-integer-square-root-c-online-judge/" rel="bookmark" title="How to Implement Integer Square Root in C/C++?">How to Implement Integer Square Root in C/C++?</a> <small>Question: Implement integer square root for int sqrt(int x) There are many ways to compute the...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-delete-nodes-from-linked-list-present-in-array/" rel="bookmark" title="Teaching Kids Programming &#8211; Delete Nodes From Linked List Present in Array">Teaching Kids Programming &#8211; Delete Nodes From Linked List Present in Array</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given an array of...</small></li>
<li><a href="https://helloacm.com/from-idea-to-github-pages-building-tools-with-ai-and-vibe-coding/" rel="bookmark" title="From Idea to GitHub Pages: Building Tools with AI and Vibe Coding">From Idea to GitHub Pages: Building Tools with AI and Vibe Coding</a> <small>Built and Open-Sourced A Few Mini Tools with AI Recently, I used ChatGPT-4o and o4-mini...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[C++ has been steadily adding features to let programmers distinguish code that runs at compile time from code that runs at runtime. Two important tools for this are the function std::is_constant_evaluated() (C++20) and the language-level if consteval (C++23). This post explains both, shows practical examples, compares their guarantees and trade-offs, and suggests when to use each.

Both techniques let you write branches that behave differently depending on whether evaluation happens in a constant-evaluation (compile-time) context or at runtime. The differences are subtle but important: one is a function returning a boolean, the other is a special if that the <a href="https://helloacm.com/introduction-to-the-components-of-a-compiler/" title="Introduction to The Components of a Compiler">compiler</a> treats as a compile-time-only branch check.

<h2>std::is_constant_evaluated() (C++20)</h2>
This is a function declared in &lt;type_traits&gt;:

<pre lang=c>
#include &lt;type_traits&gt; 
constexpr bool std::is_constant_evaluated() noexcept;
</pre>

It returns true when the current expression is being evaluated in a constant-expr (<a href="https://helloacm.com/c-vs-c-understanding-the-restrict-keyword-and-its-role-in-optimization/" title="C vs C++: Understanding the restrict Keyword and Its Role in Compiler Optimization">compile</a>-time) context, and false otherwise.

Example:
<pre lang=c>
#include &lt;iostream&gt; 
#include &lt;type_traits&gt; 

constexpr int f() { 
    if (std::is_constant_evaluated()) { 
        return 42; // compile-time 
    } else { 
        return 0; // runtime 
    } 
} 

int main() { 
    constexpr int a = f(); // evaluated at compile time -&gt; 42
    int b = f(); // evaluated at runtime -&gt; 0 
    std::cout &lt;&lt; a &lt;&lt; ", " &lt;&lt; b &lt;&lt; "\n"; // prints "42, 0" 
}
</pre>

<h2>if consteval (C++23)</h2>
if consteval is a language-level if that the compiler uses to determine whether the current evaluation context is a constant evaluation. It provides stronger compile-time guarantees: the compiler knows the consteval branch must be usable in constant evaluation and will reject code that cannot appear in that context.

Syntax:
<pre lang=c>
if consteval { 
    // compile-time-only code 
} else { 
    // runtime-only code 
} 
</pre>

Example:

<pre lang=c>
#include &lt;iostream&gt; 

constexpr int f() { 
    if consteval { 
        return 42; // compile-time version 
    } else { 
        return 0; // runtime version 
    } 
} 

int main() { 
    constexpr int a = f(); // compile-time context -&gt; returns 42 
    int b = f(); // runtime context -&gt; returns 0 
    std::cout &lt;&lt; a &lt;&lt; ", " &lt;&lt; b &lt;&lt; "\n"; // prints "42, 0" 
}
</pre>

<h2>Key differences (summary)</h2>
<ul>
<li><strong>Form:</strong> std::is_constant_evaluated() is a function; if consteval is a language-level conditional.</li>
<li><strong>Standard:</strong> std::is_constant_evaluated() arrived in C++20; if consteval arrived in C++23.</li>
<li><strong>Guarantees:</strong> if consteval gives the compiler compile-time guarantees and rejects code in the consteval branch that cannot be used at compile time. std::is_constant_evaluated() is more permissive: it returns a boolean but does not force the compiler to reject invalid compile-time-only constructs in the other branch.</li>
<li><strong>Use inside expressions:</strong> std::is_constant_evaluated() can be used inside expressions where a statement-form if cannot (e.g., inside a ternary operator). if consteval requires a statement-level context.</li>
</ul>

<h2>Concrete comparison example</h2>
Two functions that appear similar but behave differently in terms of enforcement:

<pre lang=c>
// if-consteval example 
constexpr int f() { 
    if consteval { 
        return 1; // compile-time only 
    } else { 
        return 2; // runtime only 
    } 
} 

// std::is_constant_evaluated() example 
#include &lt;type_traits&gt; 
constexpr int g() { 
    if (std::is_constant_evaluated()) { 
        return 1; // may still compile runtime path 
    } else { 
        return 2; 
    } 
}
</pre>

A scenario where the difference matters:

<pre lang=c>
// With if consteval the compiler will reject invalid compile-time-only constructs
constexpr int bad() {
    if consteval {
        std::cout &lt;&lt; "compile-time";  // ❌ error — I/O is not allowed in constant evaluation
    }
    return 0;
}

// With std::is_constant_evaluated(), the compiler is more permissive and may compile until the code
// is actually used in a constant expression context.
#include &lt;type_traits&gt;
constexpr int maybe_bad() {
    if (std::is_constant_evaluated()) {
        std::cout &lt;&lt; "compile-time";  // may compile; error surfaces only when evaluated in a const-expr
    }
    return 0;
}
</pre>

<h2>When to use which</h2>
<ul>
<li>If you target C++23 (or later) and want clear, compile-time-enforced branching: prefer <code>if consteval</code>.</li>
<li>If you must support only C++20 environments: use <code>std::is_constant_evaluated()</code>.</li>
<li>If you need the check within an expression (not a statement), use <code>std::is_constant_evaluated()</code> because <code>if consteval</code> is statement-level.</li>
<li>If you want the compiler to reject code that cannot be used at compile time, <code>if consteval</code> provides stronger guarantees.</li>
</ul>

<h2>Practical use cases</h2>
<ul>
<li>Write different implementations for compile-time vs runtime (fast precomputation vs slower runtime logic).</li>
<li>Guard runtime-only operations (like I/O, dynamic allocations, or system calls) so they are not accidentally used in a constant-evaluation path.</li>
<li>Provide clearer, intention-revealing code when authoring libraries that may be used in both constexpr contexts and normal runtime contexts.</li>
</ul>

<h2>Short, practical checklist</h2>

<ul>
<li>Need expression-level check? → <code>std::is_constant_evaluated()</code>.</li>
<li>Want compiler-enforced compile-time-only branch? → <code>if consteval</code>.</li>
<li>Targeting C++20 only? → <code>std::is_constant_evaluated()</code>.</li>
<li>Targeting C++23+ and prefer clarity &amp; safety? → <code>if consteval</code>.</li>
</ul>

<h2>TL;DR</h2>
std::is_constant_evaluated() — C++20: function that returns true inside <a href="https://helloacm.com/how-to-view-the-byte-code-dis-assembler-of-a-compiled-executable/" title="How to View the Byte Code (Dis-assembler) of a Compiled Executable?">compile</a>-time evaluation (good for expression-level checks).

if consteval — C++23:
<ul>
<li>language-level conditional that the compiler treats as a compile-time-only branch;</li>
<li>stronger <a href="https://helloacm.com/how-to-modify-or-patch-the-compiled-executable-inplace-reverse-engineering/" title="How to Modify or Patch the Compiled Executable (inplace, reverse engineering)?">compile</a>-time enforcement and clearer intent.</li>
</ul>

<h2>Closing notes</h2>

Both tools are useful. If you can use C++23, prefer <code>if consteval</code> for clearer semantics and stronger compile-time guarantees, and fall back to <code>std::is_constant_evaluated()</code> for compatibility with C++20 or when you need expression-level checks.

[show_file file="/var/www/wp-post-common/helloacm.com/cpp.php"]

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/comparisions-of-push_back-and-emplace_back-in-c-stdvector/" rel="bookmark" title="Comparisions of push_back and emplace_back in C++ std::vector">Comparisions of push_back and emplace_back in C++ std::vector</a> <small>In C++, both push_back and emplace_back are methods of the std::vector class used to add...</small></li>
<li><a href="https://helloacm.com/tutorial-on-c-stdmove-transfer-ownership/" rel="bookmark" title="Tutorial on C++ std::move (Transfer Ownership)">Tutorial on C++ std::move (Transfer Ownership)</a> <small>📘 C++ Move Semantics &amp; std::move() Tutorial C++ std::move() is used to transfer the ownership...</small></li>
<li><a href="https://helloacm.com/tutorial-on-c-ranges/" rel="bookmark" title="Tutorial on C++ Ranges">Tutorial on C++ Ranges</a> <small>C++20 introduced ranges, a powerful and elegant abstraction for working with sequences (like arrays, vectors,...</small></li>
<li><a href="https://helloacm.com/const-vs-constexpr-in-c/" rel="bookmark" title="const vs constexpr in C++">const vs constexpr in C++</a> <small>C++ const vs constexpr: What’s the Real Difference? Both are used in C++ to define...</small></li>
<li><a href="https://helloacm.com/tutorial-on-c-smart-pointers/" rel="bookmark" title="Tutorial on C++ Smart Pointers">Tutorial on C++ Smart Pointers</a> <small>Tutorial on Smart Pointers in C++ Smart pointers in C++ provide automatic and safe memory...</small></li>
<li><a href="https://helloacm.com/coding-exercise-implement-integer-square-root-c-online-judge/" rel="bookmark" title="How to Implement Integer Square Root in C/C++?">How to Implement Integer Square Root in C/C++?</a> <small>Question: Implement integer square root for int sqrt(int x) There are many ways to compute the...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-delete-nodes-from-linked-list-present-in-array/" rel="bookmark" title="Teaching Kids Programming &#8211; Delete Nodes From Linked List Present in Array">Teaching Kids Programming &#8211; Delete Nodes From Linked List Present in Array</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given an array of...</small></li>
<li><a href="https://helloacm.com/from-idea-to-github-pages-building-tools-with-ai-and-vibe-coding/" rel="bookmark" title="From Idea to GitHub Pages: Building Tools with AI and Vibe Coding">From Idea to GitHub Pages: Building Tools with AI and Vibe Coding</a> <small>Built and Open-Sourced A Few Mini Tools with AI Recently, I used ChatGPT-4o and o4-mini...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://helloacm.com/detecting-compile-time-vs-runtime-in-c-if-consteval-vs-stdis_constant_evaluated/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Teaching Kids Programming – Two Ways to Prove Square Root of Two is Irrational (proof by contradiction and geometric infinite descent)</title>
		<link>https://helloacm.com/teaching-kids-programming-two-ways-to-prove-square-root-of-two-is-irrational-proof-by-contradiction-and-geometric-infinite-descent/</link>
					<comments>https://helloacm.com/teaching-kids-programming-two-ways-to-prove-square-root-of-two-is-irrational-proof-by-contradiction-and-geometric-infinite-descent/#respond</comments>
		
		<dc:creator><![CDATA[ACMer]]></dc:creator>
		<pubDate>Sat, 11 Oct 2025 14:43:58 +0000</pubDate>
				<category><![CDATA[math]]></category>
		<category><![CDATA[teaching kids programming]]></category>
		<category><![CDATA[algebra]]></category>
		<category><![CDATA[Euclid]]></category>
		<category><![CDATA[geometric infinite descent]]></category>
		<category><![CDATA[geometry proof]]></category>
		<category><![CDATA[high school math]]></category>
		<category><![CDATA[irrational numbers]]></category>
		<category><![CDATA[math education]]></category>
		<category><![CDATA[mathematics]]></category>
		<category><![CDATA[number theory]]></category>
		<category><![CDATA[Proof by Contradiction]]></category>
		<category><![CDATA[Pythagoras]]></category>
		<category><![CDATA[square root of 2]]></category>
		<category><![CDATA[Teaching Kids Programming]]></category>
		<guid isPermaLink="false">https://helloacm.com/?p=157469</guid>

					<description><![CDATA[<iframe width="1840" height="1035" src="https://www.youtube.com/embed/qETGjk_RCLM" title="" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

<h2>How to Prove √2 Is Irrational — Two Methods (Proof by Contradiction & Geometric Infinite Descent) </h2><h2>Introduction</h2>

The statement "√2 is <a href="https://helloacm.com/teaching-kids-programming-area-and-circumferences-of-circle-and-monte-carlo-simulation-algorithm-of-pi/" title="Teaching Kids Programming – Area and Circumferences of Circle and Monte Carlo Simulation Algorithm of PI">irrational</a>" means there are no integers [math]a[/math] and [math]b\neq 0[/math] with [math]\gcd(a,b)=1[/math] such that [math]\sqrt{2}=\dfrac{a}{b}[/math]. 

<h3>Method 1 — Proof by Contradiction</h3>
Assume, for contradiction, that [math]\sqrt{2}[/math] is rational. Then there exist integers [math]a[/math] and [math]b[/math] with [math]b\neq 0[/math] and [math]\gcd(a,b)=1[/math] such that

[math]\sqrt{2}=\dfrac{a}{b}.[/math]

Squaring both sides gives:

[math]2=\dfrac{a^2}{b^2}\quad\Rightarrow\quad a^2 = 2b^2.[/math]

From [math]a^2 = 2b^2[/math] we see that [math]a^2[/math] is even, so [math]a[/math] must be even. Write [math]a=2k[/math] for some integer [math]k[/math].

Substitute back:

[math](2k)^2 = 2b^2 \quad\Rightarrow\quad 4k^2 = 2b^2 \quad\Rightarrow\quad b^2 = 2k^2.[/math]

Thus [math]b^2[/math] is even, so [math]b[/math] is even.

Therefore both [math]a[/math] and [math]b[/math] are even, contradicting the assumption that [math]\gcd(a,b)=1[/math]. This contradiction shows the assumption was false; hence [math]\sqrt{2}[/math] is irrational.

<h3>Method 2 — Geometric Infinite Descent (Median / Perpendicular Construction) geometric construction and argument</h3>
[caption id="attachment_157485" align="alignnone" width="575"]<a href="https://helloacm.com/teaching-kids-programming-two-ways-to-prove-square-root-of-two-is-irrational-proof-by-contradiction-and-geometric-infinite-descent/right-triangle-square-root-2-irrelation-proof2/" rel="attachment wp-att-157485"><img src="https://helloacm.com/wp-content/uploads/2025/10/right-triangle-square-root-2-irrelation-proof2.jpg" alt="isosceles right triangle to prove sqr root of 2 is irrational" width="575" height="645" class="size-full wp-image-157485" /></a> isosceles right triangle to prove sqr root of 2 is irrational[/caption]

Consider an isosceles right triangle [math]\triangle ABC[/math] with right angle at [math]C[/math], legs [math]AC=BC=b[/math] and hypotenuse [math]AB=a[/math], so [math]a^2=b^2+b^2=2b^2[/math].

Let [math]E[/math] be the midpoint of [math]BC[/math], and draw the line through [math]E[/math] perpendicular to the hypotenuse [math]AB[/math], meeting [math]AB[/math] at [math]D[/math]. 

Then [math] \triangle BDE [/math] is an isosceles right triangle similar to [math]\triangle ABC[/math]. Denote the small triangle’s hypotenuse and leg by [math]a'=BE[/math] and [math]b'=BD[/math].

[math]a'^2=2b'^2[/math], confirming [math]\triangle BDE\sim\triangle ABC[/math].

The crucial point is similarity (a fixed scale), not literal subtraction of whole sides. The small triangle is a constant fraction of the original. 

From the [math] BC [/math], takes the middle point [math] E [/math], and draw a perpendicular line to the hypotenuse [math] AB [/math]. So the [math] \triangle BDE [/math] is similar to [math] \triangle ACB [/math]. We use the repeative subtraction to compute the [math] AB-AC [/math]. [math] AC = AD [/math] because [math] \triangle ACE [/math] is equal to [math] \triangle ADE [/math], Thus [math] AB-AC=AB-AD=BD [/math]. 

Then [math] AC-BD=BC-BD=BC-DE=BC-CE=BE [/math]. Thus: [math] AB-AC=BE-BD [/math] which is [math] a-b=a'-b' [/math] where [math] a' [/math] is [math] BE [/math] and [math] b' [/math] is [math] BD [/math]. And we can continue this process infinity as the [math] \triangle BED [/math] is similar to [math] \triangle ABC [/math].

Hence every time you repeat the same construction (take the midpoint of a triangle leg and draw the perpendicular to the hypotenuse), you obtain a new isosceles right triangle similar to the original with all side lengths multiplied by a factor [math] r [/math]. Thus the hypotenuse and legs shrink geometrically by a fixed factor at each step.

This produces the infinite-descent contradiction in the integer setting: if you started with integer side lengths  satisfying [math]a^2=2b^2[/math], the construction (or the equivalent integer-preserving midpoint-of-hypotenuse → midpoint-of-[math]BD[/math] construction that yields a strictly smaller positive integer solution of the same Diophantine equation. Repeating indefinitely would produce an infinite strictly decreasing sequence of positive integers, which is impossible. Therefore no such integer solution exists and [math]\sqrt{2}[/math] is irrational.

<h2>Conclusion</h2>
Both methods prove that [math]\sqrt{2}[/math] cannot be written as a ratio of integers.

<ul>
<li>Method 1 (proof by <a href="https://helloacm.com/euclids-theorem-proof-of-unlimited-prime-numbers/" title="Euclid’s theorem – Proof of Unlimited Prime Numbers">contradiction</a>) uses parity to show any assumed fraction in lowest terms leads to both numerator and denominator being even.</li>
<li>Method 2 (geometric infinite descent) uses a similarity construction inside an isosceles right triangle to produce a smaller integer solution, contradicting minimality.</li>
</ul>

Either argument gives a clear, rigorous proof that [math]\sqrt{2}[/math] is irrational.<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/recursive-and-two-pointer-algorithms-to-determine-four-sum/" rel="bookmark" title="Recursion and Two Pointer Algorithms to Determine Four Sum">Recursion and Two Pointer Algorithms to Determine Four Sum</a> <small>Given a list of integers nums and an integer k, return whether there are four...</small></li>
<li><a href="https://helloacm.com/python-numpy-memory-leaks-due-to-pythonmalloc-c-python-and-address-sanitizer/" rel="bookmark" title="Python Numpy Memory Leaks Due to PYTHONMALLOC (C Python and Address Sanitizer)">Python Numpy Memory Leaks Due to PYTHONMALLOC (C Python and Address Sanitizer)</a> <small>A simple C/C++ calling Python script to import numpy package will simply be reported Leaking...</small></li>
<li><a href="https://helloacm.com/duplicate-a-mysql-table-copy-table-duplicate-database-php-script/" rel="bookmark" title="Duplicate a MySQL table &#8211; Copy Table / Duplicate Database / PHP Script">Duplicate a MySQL table &#8211; Copy Table / Duplicate Database / PHP Script</a> <small>Suppose if you want to copy a Table to another, this can be done in...</small></li>
<li><a href="https://helloacm.com/how-to-search-twits-with-picturesimages-using-php/" rel="bookmark" title="How to Search Twits with Pictures/Images using PHP?">How to Search Twits with Pictures/Images using PHP?</a> <small>If you want to search twits with Pictures or Images using PHP, then the following...</small></li>
<li><a href="https://helloacm.com/introduction-to-programming-c-exercise-circuit/" rel="bookmark" title="Introduction to programming &#8211; C Exercise &#8211; Circuit">Introduction to programming &#8211; C Exercise &#8211; Circuit</a> <small>Consider the following circuit; The step response of this circuit may be expressed as follows;...</small></li>
<li><a href="https://helloacm.com/trick-count-the-number-of-api-in-com/" rel="bookmark" title="Trick: Count the Number of API in COM">Trick: Count the Number of API in COM</a> <small>Delphi is a handy tool to develop the COM (Component Object Model) DLL. A *_TLB.pas...</small></li>
<li><a href="https://helloacm.com/two-pointer-with-sliding-window-algorithm-to-compute-the-longest-substring-with-at-most-k-distinct-characters/" rel="bookmark" title="Two Pointer with Sliding Window Algorithm to Compute the Longest Substring with At Most K Distinct Characters">Two Pointer with Sliding Window Algorithm to Compute the Longest Substring with At Most K Distinct Characters</a> <small>Given a string, find the length of the longest substring T that contains at most...</small></li>
<li><a href="https://helloacm.com/algorithm-to-valid-n-queens/" rel="bookmark" title="Algorithm to Valid N Queens">Algorithm to Valid N Queens</a> <small>The n queens puzzle asks to place n queens on an n×n chessboard so that...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<iframe width="1840" height="1035" src="https://www.youtube.com/embed/qETGjk_RCLM" title="" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

<h2>How to Prove √2 Is Irrational — Two Methods (Proof by Contradiction & Geometric Infinite Descent) </h2><h2>Introduction</h2>

The statement "√2 is <a href="https://helloacm.com/teaching-kids-programming-area-and-circumferences-of-circle-and-monte-carlo-simulation-algorithm-of-pi/" title="Teaching Kids Programming – Area and Circumferences of Circle and Monte Carlo Simulation Algorithm of PI">irrational</a>" means there are no integers [math]a[/math] and [math]b\neq 0[/math] with [math]\gcd(a,b)=1[/math] such that [math]\sqrt{2}=\dfrac{a}{b}[/math]. 

<h3>Method 1 — Proof by Contradiction</h3>
Assume, for contradiction, that [math]\sqrt{2}[/math] is rational. Then there exist integers [math]a[/math] and [math]b[/math] with [math]b\neq 0[/math] and [math]\gcd(a,b)=1[/math] such that

[math]\sqrt{2}=\dfrac{a}{b}.[/math]

Squaring both sides gives:

[math]2=\dfrac{a^2}{b^2}\quad\Rightarrow\quad a^2 = 2b^2.[/math]

From [math]a^2 = 2b^2[/math] we see that [math]a^2[/math] is even, so [math]a[/math] must be even. Write [math]a=2k[/math] for some integer [math]k[/math].

Substitute back:

[math](2k)^2 = 2b^2 \quad\Rightarrow\quad 4k^2 = 2b^2 \quad\Rightarrow\quad b^2 = 2k^2.[/math]

Thus [math]b^2[/math] is even, so [math]b[/math] is even.

Therefore both [math]a[/math] and [math]b[/math] are even, contradicting the assumption that [math]\gcd(a,b)=1[/math]. This contradiction shows the assumption was false; hence [math]\sqrt{2}[/math] is irrational.

<h3>Method 2 — Geometric Infinite Descent (Median / Perpendicular Construction) geometric construction and argument</h3>
[caption id="attachment_157485" align="alignnone" width="575"]<a href="https://helloacm.com/teaching-kids-programming-two-ways-to-prove-square-root-of-two-is-irrational-proof-by-contradiction-and-geometric-infinite-descent/right-triangle-square-root-2-irrelation-proof2/" rel="attachment wp-att-157485"><img src="https://helloacm.com/wp-content/uploads/2025/10/right-triangle-square-root-2-irrelation-proof2.jpg" alt="isosceles right triangle to prove sqr root of 2 is irrational" width="575" height="645" class="size-full wp-image-157485" /></a> isosceles right triangle to prove sqr root of 2 is irrational[/caption]

Consider an isosceles right triangle [math]\triangle ABC[/math] with right angle at [math]C[/math], legs [math]AC=BC=b[/math] and hypotenuse [math]AB=a[/math], so [math]a^2=b^2+b^2=2b^2[/math].

Let [math]E[/math] be the midpoint of [math]BC[/math], and draw the line through [math]E[/math] perpendicular to the hypotenuse [math]AB[/math], meeting [math]AB[/math] at [math]D[/math]. 

Then [math] \triangle BDE [/math] is an isosceles right triangle similar to [math]\triangle ABC[/math]. Denote the small triangle’s hypotenuse and leg by [math]a'=BE[/math] and [math]b'=BD[/math].

[math]a'^2=2b'^2[/math], confirming [math]\triangle BDE\sim\triangle ABC[/math].

The crucial point is similarity (a fixed scale), not literal subtraction of whole sides. The small triangle is a constant fraction of the original. 

From the [math] BC [/math], takes the middle point [math] E [/math], and draw a perpendicular line to the hypotenuse [math] AB [/math]. So the [math] \triangle BDE [/math] is similar to [math] \triangle ACB [/math]. We use the repeative subtraction to compute the [math] AB-AC [/math]. [math] AC = AD [/math] because [math] \triangle ACE [/math] is equal to [math] \triangle ADE [/math], Thus [math] AB-AC=AB-AD=BD [/math]. 

Then [math] AC-BD=BC-BD=BC-DE=BC-CE=BE [/math]. Thus: [math] AB-AC=BE-BD [/math] which is [math] a-b=a'-b' [/math] where [math] a' [/math] is [math] BE [/math] and [math] b' [/math] is [math] BD [/math]. And we can continue this process infinity as the [math] \triangle BED [/math] is similar to [math] \triangle ABC [/math].

Hence every time you repeat the same construction (take the midpoint of a triangle leg and draw the perpendicular to the hypotenuse), you obtain a new isosceles right triangle similar to the original with all side lengths multiplied by a factor [math] r [/math]. Thus the hypotenuse and legs shrink geometrically by a fixed factor at each step.

This produces the infinite-descent contradiction in the integer setting: if you started with integer side lengths  satisfying [math]a^2=2b^2[/math], the construction (or the equivalent integer-preserving midpoint-of-hypotenuse → midpoint-of-[math]BD[/math] construction that yields a strictly smaller positive integer solution of the same Diophantine equation. Repeating indefinitely would produce an infinite strictly decreasing sequence of positive integers, which is impossible. Therefore no such integer solution exists and [math]\sqrt{2}[/math] is irrational.

<h2>Conclusion</h2>
Both methods prove that [math]\sqrt{2}[/math] cannot be written as a ratio of integers.

<ul>
<li>Method 1 (proof by <a href="https://helloacm.com/euclids-theorem-proof-of-unlimited-prime-numbers/" title="Euclid’s theorem – Proof of Unlimited Prime Numbers">contradiction</a>) uses parity to show any assumed fraction in lowest terms leads to both numerator and denominator being even.</li>
<li>Method 2 (geometric infinite descent) uses a similarity construction inside an isosceles right triangle to produce a smaller integer solution, contradicting minimality.</li>
</ul>

Either argument gives a clear, rigorous proof that [math]\sqrt{2}[/math] is irrational.<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/recursive-and-two-pointer-algorithms-to-determine-four-sum/" rel="bookmark" title="Recursion and Two Pointer Algorithms to Determine Four Sum">Recursion and Two Pointer Algorithms to Determine Four Sum</a> <small>Given a list of integers nums and an integer k, return whether there are four...</small></li>
<li><a href="https://helloacm.com/python-numpy-memory-leaks-due-to-pythonmalloc-c-python-and-address-sanitizer/" rel="bookmark" title="Python Numpy Memory Leaks Due to PYTHONMALLOC (C Python and Address Sanitizer)">Python Numpy Memory Leaks Due to PYTHONMALLOC (C Python and Address Sanitizer)</a> <small>A simple C/C++ calling Python script to import numpy package will simply be reported Leaking...</small></li>
<li><a href="https://helloacm.com/duplicate-a-mysql-table-copy-table-duplicate-database-php-script/" rel="bookmark" title="Duplicate a MySQL table &#8211; Copy Table / Duplicate Database / PHP Script">Duplicate a MySQL table &#8211; Copy Table / Duplicate Database / PHP Script</a> <small>Suppose if you want to copy a Table to another, this can be done in...</small></li>
<li><a href="https://helloacm.com/how-to-search-twits-with-picturesimages-using-php/" rel="bookmark" title="How to Search Twits with Pictures/Images using PHP?">How to Search Twits with Pictures/Images using PHP?</a> <small>If you want to search twits with Pictures or Images using PHP, then the following...</small></li>
<li><a href="https://helloacm.com/introduction-to-programming-c-exercise-circuit/" rel="bookmark" title="Introduction to programming &#8211; C Exercise &#8211; Circuit">Introduction to programming &#8211; C Exercise &#8211; Circuit</a> <small>Consider the following circuit; The step response of this circuit may be expressed as follows;...</small></li>
<li><a href="https://helloacm.com/trick-count-the-number-of-api-in-com/" rel="bookmark" title="Trick: Count the Number of API in COM">Trick: Count the Number of API in COM</a> <small>Delphi is a handy tool to develop the COM (Component Object Model) DLL. A *_TLB.pas...</small></li>
<li><a href="https://helloacm.com/two-pointer-with-sliding-window-algorithm-to-compute-the-longest-substring-with-at-most-k-distinct-characters/" rel="bookmark" title="Two Pointer with Sliding Window Algorithm to Compute the Longest Substring with At Most K Distinct Characters">Two Pointer with Sliding Window Algorithm to Compute the Longest Substring with At Most K Distinct Characters</a> <small>Given a string, find the length of the longest substring T that contains at most...</small></li>
<li><a href="https://helloacm.com/algorithm-to-valid-n-queens/" rel="bookmark" title="Algorithm to Valid N Queens">Algorithm to Valid N Queens</a> <small>The n queens puzzle asks to place n queens on an n×n chessboard so that...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://helloacm.com/teaching-kids-programming-two-ways-to-prove-square-root-of-two-is-irrational-proof-by-contradiction-and-geometric-infinite-descent/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Turn Your Raspberry Pi into a Family Network Drive: 2TB WD Hard Drive Setup for Kids’ Macs</title>
		<link>https://helloacm.com/turn-your-raspberry-pi-into-a-family-network-drive-2tb-wd-hard-drive-setup-for-kids-macs/</link>
					<comments>https://helloacm.com/turn-your-raspberry-pi-into-a-family-network-drive-2tb-wd-hard-drive-setup-for-kids-macs/#respond</comments>
		
		<dc:creator><![CDATA[ACMer]]></dc:creator>
		<pubDate>Thu, 02 Oct 2025 13:21:46 +0000</pubDate>
				<category><![CDATA[Home Network Topology]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[linux shell]]></category>
		<category><![CDATA[Next Unit of Computing]]></category>
		<category><![CDATA[Raspberry PI]]></category>
		<category><![CDATA[technical]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Cloud Storage]]></category>
		<category><![CDATA[DIY Storage]]></category>
		<category><![CDATA[File Backup]]></category>
		<category><![CDATA[File Sharing]]></category>
		<category><![CDATA[Google Drive]]></category>
		<category><![CDATA[Home Data Management]]></category>
		<category><![CDATA[Home Network]]></category>
		<category><![CDATA[Home Storage]]></category>
		<category><![CDATA[Mac Optimization]]></category>
		<category><![CDATA[MacBook]]></category>
		<category><![CDATA[Mount Hard Drive]]></category>
		<category><![CDATA[Network Drive]]></category>
		<category><![CDATA[NTFS]]></category>
		<category><![CDATA[OneDrive]]></category>
		<category><![CDATA[raspberry pi]]></category>
		<category><![CDATA[Samba]]></category>
		<category><![CDATA[save space]]></category>
		<category><![CDATA[Tech Tutorial]]></category>
		<category><![CDATA[USB Hard Drive]]></category>
		<category><![CDATA[WD Hard Drive]]></category>
		<guid isPermaLink="false">https://helloacm.com/?p=157446</guid>

					<description><![CDATA[<blockquote>
“Create a 2TB Network Drive with Raspberry Pi for Your Family”

“Raspberry Pi + WD Hard Drive: Easy Network Storage for Kids’ Macs”

“Family File Sharing Made Easy: DIY Raspberry Pi Network Drive”

“Turn a Raspberry Pi into a 2TB Shared Hard Drive for Home”

“Save Space on Your Kids’ Macs with a Raspberry Pi Network Drive”
</blockquote>

A couple of years ago, I bought a MacBook Pro for each of my two kids. My younger son’s laptop cost around $600 at the time and had only a 256GB <a href="https://helloacm.com/how-to-check-hard-disk-type-nvme-ssd-on-servers-vms/" title="How to Check Hard Disk Type (NVMe SSD) on Servers/VMs?">SSD</a>, so the storage often filled up. He constantly had to delete downloaded files and DMG installers. After using it for a while, the MBP’s <code>~/Caches</code> directory also grew very large. Although you can temporarily clean it, it’s only a temporary fix.

I told my kids that they could move some files to cloud storage, like <a href="https://helloacm.com/store-and-backup-unlimited-photos-using-amazon-photos-prime/" title="Store and Backup Unlimited Photos using Amazon Photos (Prime)">OneDrive</a> or Google Drive, or I could connect a USB hard drive to their computers. OneDrive has a “files on-demand” mode where data is stored in the cloud without taking local space, which saves a lot of space, but the free storage is only 5GB. Google Drive offers 15GB of free storage shared across Gmail, Photos, and Drive.

My kids didn’t really like using a USB hard drive. First, it requires a power connection, and second, it needs a Type-C to USB adapter, which is inconvenient. They didn’t want to keep it plugged in all the time.

Then I thought of the Raspberry Pi at home. I could connect a portable <a href="https://helloacm.com/manual-raid-1-using-two-18tb-usb-external-hard-drive-hdd/" title="Manual RAID-1 using Two 18TB USB External Hard Drive (HDD)">hard drive</a> to it and use file sharing to make all our home computers access it as a network drive (Map Network Drive). So, I dug through some drawers and found a 2TB Western Digital (WD) 3.5-inch hard drive, which requires an external enclosure. Conveniently, I had bought a hard drive enclosure a few months ago while tinkering with data.

Previously, this hard drive had been used as the D drive on an <a href="https://helloacm.com/review-hpz800-server-workstation-hp-z800-workstation-desktop-pc-tower-computer-powerhouse-2x-intel-xeon-x5650-48gb-ddr3-memory-2tb-hdd-1gb-nvidia-quadro/" title="Review – HPZ800 Server WorkStation HP Z800 Workstation Desktop PC Tower Computer POWERHOUSE (2x Intel Xeon X5650 – 48GB DDR3 Memory – 2TB HDD – 1GB Nvidia Quadro)">HP Z800</a> server.

[caption id="attachment_157451" align="alignnone" width="753"]<a href="https://helloacm.com/turn-your-raspberry-pi-into-a-family-network-drive-2tb-wd-hard-drive-setup-for-kids-macs/found-2-tb-wd-drive-2025-10-01-09-12-09/" rel="attachment wp-att-157451"><img src="https://helloacm.com/wp-content/uploads/2025/10/found-2-tb-wd-drive-2025-10-01-09.12.09.jpg" alt="The West Data Hard Drive that is used to install on the HPZ800 which takes at most 4 hard drives." width="753" height="1313" class="size-full wp-image-157451" /></a> The West Data Hard Drive that is used to install on the HPZ800 which takes at most 4 hard drives.[/caption]

<h3>Adding a Network Drive: Mounting the Portable Hard Drive via SAMBA on Raspberry Pi</h3>
To make sure the hard drive had no bad sectors, I checked it with CrystalDiskInfo and also had ChatGPT review its health status — 2.3 years of power-on time, no bad sectors, everything is fine.

[caption id="attachment_157449" align="alignnone" width="671"]<a href="https://helloacm.com/turn-your-raspberry-pi-into-a-family-network-drive-2tb-wd-hard-drive-setup-for-kids-macs/crystaldiskinfo-wd-2tb-drive/" rel="attachment wp-att-157449"><img src="https://helloacm.com/wp-content/uploads/2025/10/crystaldiskinfo-wd-2tb-drive.jpg" alt="The CrystalDiskInfo shows that the Drive is still healthy." width="671" height="690" class="size-full wp-image-157449" /></a> The CrystalDiskInfo shows that the Drive is still healthy.[/caption]

<h4>Preparing to Mount the Hard Drive</h4>
The first step is to connect the hard drive to the Raspberry Pi via USB. It requires an external power supply. I found a socket that could barely fit two plugs in the small shoe cabinet: one for the 3.5-inch hard drive enclosure and the <a href="https://helloacm.com/monitoring-28-vps-machines-including-a-raspberry-pi-with-nezha-dashboard/" title="Monitoring 28 VPS Machines (Including a Raspberry Pi) with Nezha Dashboard">Raspberry</a> Pi 4B.

[caption id="attachment_157450" align="alignnone" width="543"]<a href="https://helloacm.com/turn-your-raspberry-pi-into-a-family-network-drive-2tb-wd-hard-drive-setup-for-kids-macs/df-raspberrypi-2025-10-01-12-35-41/" rel="attachment wp-att-157450"><img src="https://helloacm.com/wp-content/uploads/2025/10/df-raspberrypi-2025-10-01-12.35.41.png" alt="The df confirms the USB hard drive has been connected and allocated/mounted." width="543" height="270" class="size-full wp-image-157450" /></a> The df confirms the USB hard drive has been connected and allocated/mounted.[/caption]

Then I SSH into the Raspberry Pi and found the hard drive is formatted as NTFS, so it needs to be mounted:

<pre lang=bash>
mkdir /mnt/usb
mount -t ntfs-3g /dev/sdb1 /mnt/usb
</pre>

Here, <code>/mnt/usb</code> is the target mount directory and needs to be created first.

If you want it to auto-mount on boot, just add a line to <code>/etc/fstab</code>:

<pre lang=bash>
UUID=&lt;ID&gt; /mnt/usb ntfs-3g defaults,uid=1000,gid=1000,umask=0000,nofail,x-systemd.device-timeout=10 0 0
</pre>

&lt;ID&gt; is the hard drive’s UUID, which you can find with <code>lsblk -f</code>.

<h4>SAMBA Network Drive</h4>
The easiest way to share files is to install Samba:

<pre lang=bash>
sudo apt install -y samba
</pre>

<p>After installation, edit <code>/etc/samba/smb.conf</code> and add:</p>

<pre lang=bash>
[usb2share]
   path = /mnt/usb
   browseable = yes
   writable = yes
   guest ok = no
   create mask = 0777
   directory mask = 0777
   valid users = pi
</pre>

<strong>Note:</strong> <code>valid users</code> can list multiple users separated by spaces or use <code>@</code> for a group. The user must exist on the <a href="https://helloacm.com/why-a-leading-space-in-linux-shell-commands-can-matter/" title="Why a Leading Space in Linux Shell Commands Can Matter?">Linux</a> system.

Set the SMB password:

<pre lang=bash>
sudo smbpasswd -a pi
</pre>

Restart the Samba service:

<pre lang=bash>
sudo systemctl restart smbd
</pre>

<h4>Map the Network Drive</h4>
On Windows, right-click “This PC” → “Map network drive” and enter the address:

<pre lang=bash>
\\192.168.IP_ADDRESS\usb2share
</pre>

Enter the username and password, check “Remember my credentials,” and the network drive behaves like a local drive.

On a Mac, open Finder, press <code>Command + K</code>, add the server, and enter the <a href="https://helloacm.com/what-is-my-ip/" title="IP Address" rel="noopener" target="_blank">IP Address</a> of the Raspberry Pi, username, and <a href="https://helloacm.com/password-protect-or-ip-restriction-on-wordpress-wp-admin-folder-htaccess-and-htpasswd/" title="Password Protect or IP Restriction on WordPress wp-admin Folder (htaccess and htpasswd)">password</a>.

I created a folder for each of my two kids and my wife, so they can put their data in their own directories. The 2TB drive should last a while.

With this network drive, sharing data (movies, photos, etc.) is much easier. No more using WeChat, WhatsApp, or Google Drive — those are inconvenient for finding old files, and photos usually get compressed.

It’s great — the Raspberry Pi now has another use and is no longer just gathering dust.

[caption id="attachment_157448" align="alignnone" width="864"]<a href="https://helloacm.com/turn-your-raspberry-pi-into-a-family-network-drive-2tb-wd-hard-drive-setup-for-kids-macs/add-usb-to-raspberry-pi-server-2025-10-01-12-34-43/" rel="attachment wp-att-157448"><img src="https://helloacm.com/wp-content/uploads/2025/10/add-usb-to-raspberry-pi-server-2025-10-01-12.34.43.jpg" alt="I could still put another Raspberry Pi Server or another Hard Disk in there." width="864" height="1536" class="size-full wp-image-157448" /></a> I could still put another Raspberry Pi Server or another Hard Disk in there.[/caption]

[caption id="attachment_157452" align="alignnone" width="628"]<a href="https://helloacm.com/turn-your-raspberry-pi-into-a-family-network-drive-2tb-wd-hard-drive-setup-for-kids-macs/network-drive-2025-10-01-12-35-38/" rel="attachment wp-att-157452"><img src="https://helloacm.com/wp-content/uploads/2025/10/network-drive-2025-10-01-12.35.38.png" alt="Map Network Drive to Z - the drive letters usually are backwards from Z to A." width="628" height="461" class="size-full wp-image-157452" /></a> Map Network Drive to Z - the drive letters usually are backwards from Z to A.[/caption]

[caption id="attachment_157453" align="alignnone" width="377"]<a href="https://helloacm.com/turn-your-raspberry-pi-into-a-family-network-drive-2tb-wd-hard-drive-setup-for-kids-macs/network-drive-2025-10-01-12-35-45/" rel="attachment wp-att-157453"><img src="https://helloacm.com/wp-content/uploads/2025/10/network-drive-2025-10-01-12.35.45.png" alt="You can view the property of the network drive: used and remaining space." width="377" height="479" class="size-full wp-image-157453" /></a> You can view the property of the network drive: used and remaining space.[/caption]

[caption id="attachment_157454" align="alignnone" width="1028"]<a href="https://helloacm.com/turn-your-raspberry-pi-into-a-family-network-drive-2tb-wd-hard-drive-setup-for-kids-macs/network-drives-this-pc/" rel="attachment wp-att-157454"><img src="https://helloacm.com/wp-content/uploads/2025/10/network-drives-this-pc.jpg" alt="The mapped network drives become one of the system resources. It is just like a local drive." width="1028" height="634" class="size-full wp-image-157454" /></a> The mapped network drives become one of the system resources. It is just like a local drive.[/caption]

[caption id="attachment_157455" align="alignnone" width="456"]<a href="https://helloacm.com/turn-your-raspberry-pi-into-a-family-network-drive-2tb-wd-hard-drive-setup-for-kids-macs/samba-access2025-10-01-12-35-43/" rel="attachment wp-att-157455"><img src="https://helloacm.com/wp-content/uploads/2025/10/samba-access2025-10-01-12.35.43.png" alt="Enter Network Credentials to access the network drive." width="456" height="407" class="size-full wp-image-157455" /></a> Enter Network Credentials to access the network drive.[/caption]

[caption id="attachment_157456" align="alignnone" width="2048"]<a href="https://helloacm.com/turn-your-raspberry-pi-into-a-family-network-drive-2tb-wd-hard-drive-setup-for-kids-macs/usb-drive-2025-10-01-12-34-47/" rel="attachment wp-att-157456"><img src="https://helloacm.com/wp-content/uploads/2025/10/usb-drive-2025-10-01-12.34.47-scaled.jpg" alt="I found a nice place to host the USB external 3.5 hard drive in the shoe closet." width="2048" height="1152" class="size-full wp-image-157456" /></a> I found a nice place to host the USB external 3.5 hard drive in the shoe closet.[/caption]

[show_file file="/var/www/wp-post-common/helloacm.com/raspberry-pi.php"]

See Also: <a href="https://steemit.com/blog/@justyy/found-a-2tb-old-hard-drive-still-young-and-healthy">Found a 2TB Old Hard Drive - Still Young and Healthy</a>

[show_file file="/var/www/wp-post-common/helloacm.com/home-topology.php"]

[show_posts keyword="Home Network Topology"]

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/turning-a-dusty-mini-pc-into-a-home-server-my-nuc-8s-second-life/" rel="bookmark" title="Turning a Dusty Mini PC into a Home Server: My NUC-8’s Second Life">Turning a Dusty Mini PC into a Home Server: My NUC-8’s Second Life</a> <small>I gave an unused Beelink SEi8 mini PC a second life by installing Ubuntu and...</small></li>
<li><a href="https://helloacm.com/a-five-year-milestone-at-microsoft-anniversary-crystal/" rel="bookmark" title="A Five-Year Milestone at Microsoft (Anniversary Crystal)">A Five-Year Milestone at Microsoft (Anniversary Crystal)</a> <small>To mark my fifth anniversary at Microsoft, I received a meaningful crystal service award. Over...</small></li>
<li><a href="https://helloacm.com/understanding-dynamic_cast-in-c-safe-downcasting-explained/" rel="bookmark" title="Understanding dynamic_cast in C++: Safe Downcasting Explained">Understanding dynamic_cast in C++: Safe Downcasting Explained</a> <small>What Is dynamic_cast in C++? Purpose Safely convert between polymorphic types at runtime Commonly used...</small></li>
<li><a href="https://helloacm.com/excel-tip-faster-auto-complete/" rel="bookmark" title="Excel Tip: Faster Auto-complete">Excel Tip: Faster Auto-complete</a> <small>The Microsoft Excel is heavily used and widely used. There are so many tricks/tips that...</small></li>
<li><a href="https://helloacm.com/listen-to-what-an-seo-expert-has-to-say-about-its-benefits/" rel="bookmark" title="Listen to what an SEO expert has to say about its benefits">Listen to what an SEO expert has to say about its benefits</a> <small>To get the most from your business, you must follow your customers and take your...</small></li>
<li><a href="https://helloacm.com/telegram-accounts-are-shockingly-easy-to-hack-without-2fa/" rel="bookmark" title="Telegram Accounts Are Shockingly Easy to Hack Without 2FA">Telegram Accounts Are Shockingly Easy to Hack Without 2FA</a> <small>&#8220;How My Telegram Account Got Hacked—and What I Learned&#8221; &#8220;A Cautionary Tale: Telegram Security and...</small></li>
<li><a href="https://helloacm.com/the-common-include-php-file-for-my-sites/" rel="bookmark" title="The Common Include PHP File For My Sites">The Common Include PHP File For My Sites</a> <small>I think you may have some common code to write for most of the PHP...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-minmax-dynamic-programming-algorithm-game-of-picking-numbers-at-two-ends/" rel="bookmark" title="Teaching Kids Programming &#8211; Minmax Dynamic Programming Algorithm (Game of Picking Numbers at Two Ends)">Teaching Kids Programming &#8211; Minmax Dynamic Programming Algorithm (Game of Picking Numbers at Two Ends)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given a list of...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<blockquote>
“Create a 2TB Network Drive with Raspberry Pi for Your Family”

“Raspberry Pi + WD Hard Drive: Easy Network Storage for Kids’ Macs”

“Family File Sharing Made Easy: DIY Raspberry Pi Network Drive”

“Turn a Raspberry Pi into a 2TB Shared Hard Drive for Home”

“Save Space on Your Kids’ Macs with a Raspberry Pi Network Drive”
</blockquote>

A couple of years ago, I bought a MacBook Pro for each of my two kids. My younger son’s laptop cost around $600 at the time and had only a 256GB <a href="https://helloacm.com/how-to-check-hard-disk-type-nvme-ssd-on-servers-vms/" title="How to Check Hard Disk Type (NVMe SSD) on Servers/VMs?">SSD</a>, so the storage often filled up. He constantly had to delete downloaded files and DMG installers. After using it for a while, the MBP’s <code>~/Caches</code> directory also grew very large. Although you can temporarily clean it, it’s only a temporary fix.

I told my kids that they could move some files to cloud storage, like <a href="https://helloacm.com/store-and-backup-unlimited-photos-using-amazon-photos-prime/" title="Store and Backup Unlimited Photos using Amazon Photos (Prime)">OneDrive</a> or Google Drive, or I could connect a USB hard drive to their computers. OneDrive has a “files on-demand” mode where data is stored in the cloud without taking local space, which saves a lot of space, but the free storage is only 5GB. Google Drive offers 15GB of free storage shared across Gmail, Photos, and Drive.

My kids didn’t really like using a USB hard drive. First, it requires a power connection, and second, it needs a Type-C to USB adapter, which is inconvenient. They didn’t want to keep it plugged in all the time.

Then I thought of the Raspberry Pi at home. I could connect a portable <a href="https://helloacm.com/manual-raid-1-using-two-18tb-usb-external-hard-drive-hdd/" title="Manual RAID-1 using Two 18TB USB External Hard Drive (HDD)">hard drive</a> to it and use file sharing to make all our home computers access it as a network drive (Map Network Drive). So, I dug through some drawers and found a 2TB Western Digital (WD) 3.5-inch hard drive, which requires an external enclosure. Conveniently, I had bought a hard drive enclosure a few months ago while tinkering with data.

Previously, this hard drive had been used as the D drive on an <a href="https://helloacm.com/review-hpz800-server-workstation-hp-z800-workstation-desktop-pc-tower-computer-powerhouse-2x-intel-xeon-x5650-48gb-ddr3-memory-2tb-hdd-1gb-nvidia-quadro/" title="Review – HPZ800 Server WorkStation HP Z800 Workstation Desktop PC Tower Computer POWERHOUSE (2x Intel Xeon X5650 – 48GB DDR3 Memory – 2TB HDD – 1GB Nvidia Quadro)">HP Z800</a> server.

[caption id="attachment_157451" align="alignnone" width="753"]<a href="https://helloacm.com/turn-your-raspberry-pi-into-a-family-network-drive-2tb-wd-hard-drive-setup-for-kids-macs/found-2-tb-wd-drive-2025-10-01-09-12-09/" rel="attachment wp-att-157451"><img src="https://helloacm.com/wp-content/uploads/2025/10/found-2-tb-wd-drive-2025-10-01-09.12.09.jpg" alt="The West Data Hard Drive that is used to install on the HPZ800 which takes at most 4 hard drives." width="753" height="1313" class="size-full wp-image-157451" /></a> The West Data Hard Drive that is used to install on the HPZ800 which takes at most 4 hard drives.[/caption]

<h3>Adding a Network Drive: Mounting the Portable Hard Drive via SAMBA on Raspberry Pi</h3>
To make sure the hard drive had no bad sectors, I checked it with CrystalDiskInfo and also had ChatGPT review its health status — 2.3 years of power-on time, no bad sectors, everything is fine.

[caption id="attachment_157449" align="alignnone" width="671"]<a href="https://helloacm.com/turn-your-raspberry-pi-into-a-family-network-drive-2tb-wd-hard-drive-setup-for-kids-macs/crystaldiskinfo-wd-2tb-drive/" rel="attachment wp-att-157449"><img src="https://helloacm.com/wp-content/uploads/2025/10/crystaldiskinfo-wd-2tb-drive.jpg" alt="The CrystalDiskInfo shows that the Drive is still healthy." width="671" height="690" class="size-full wp-image-157449" /></a> The CrystalDiskInfo shows that the Drive is still healthy.[/caption]

<h4>Preparing to Mount the Hard Drive</h4>
The first step is to connect the hard drive to the Raspberry Pi via USB. It requires an external power supply. I found a socket that could barely fit two plugs in the small shoe cabinet: one for the 3.5-inch hard drive enclosure and the <a href="https://helloacm.com/monitoring-28-vps-machines-including-a-raspberry-pi-with-nezha-dashboard/" title="Monitoring 28 VPS Machines (Including a Raspberry Pi) with Nezha Dashboard">Raspberry</a> Pi 4B.

[caption id="attachment_157450" align="alignnone" width="543"]<a href="https://helloacm.com/turn-your-raspberry-pi-into-a-family-network-drive-2tb-wd-hard-drive-setup-for-kids-macs/df-raspberrypi-2025-10-01-12-35-41/" rel="attachment wp-att-157450"><img src="https://helloacm.com/wp-content/uploads/2025/10/df-raspberrypi-2025-10-01-12.35.41.png" alt="The df confirms the USB hard drive has been connected and allocated/mounted." width="543" height="270" class="size-full wp-image-157450" /></a> The df confirms the USB hard drive has been connected and allocated/mounted.[/caption]

Then I SSH into the Raspberry Pi and found the hard drive is formatted as NTFS, so it needs to be mounted:

<pre lang=bash>
mkdir /mnt/usb
mount -t ntfs-3g /dev/sdb1 /mnt/usb
</pre>

Here, <code>/mnt/usb</code> is the target mount directory and needs to be created first.

If you want it to auto-mount on boot, just add a line to <code>/etc/fstab</code>:

<pre lang=bash>
UUID=&lt;ID&gt; /mnt/usb ntfs-3g defaults,uid=1000,gid=1000,umask=0000,nofail,x-systemd.device-timeout=10 0 0
</pre>

&lt;ID&gt; is the hard drive’s UUID, which you can find with <code>lsblk -f</code>.

<h4>SAMBA Network Drive</h4>
The easiest way to share files is to install Samba:

<pre lang=bash>
sudo apt install -y samba
</pre>

<p>After installation, edit <code>/etc/samba/smb.conf</code> and add:</p>

<pre lang=bash>
[usb2share]
   path = /mnt/usb
   browseable = yes
   writable = yes
   guest ok = no
   create mask = 0777
   directory mask = 0777
   valid users = pi
</pre>

<strong>Note:</strong> <code>valid users</code> can list multiple users separated by spaces or use <code>@</code> for a group. The user must exist on the <a href="https://helloacm.com/why-a-leading-space-in-linux-shell-commands-can-matter/" title="Why a Leading Space in Linux Shell Commands Can Matter?">Linux</a> system.

Set the SMB password:

<pre lang=bash>
sudo smbpasswd -a pi
</pre>

Restart the Samba service:

<pre lang=bash>
sudo systemctl restart smbd
</pre>

<h4>Map the Network Drive</h4>
On Windows, right-click “This PC” → “Map network drive” and enter the address:

<pre lang=bash>
\\192.168.IP_ADDRESS\usb2share
</pre>

Enter the username and password, check “Remember my credentials,” and the network drive behaves like a local drive.

On a Mac, open Finder, press <code>Command + K</code>, add the server, and enter the <a href="https://helloacm.com/what-is-my-ip/" title="IP Address" rel="noopener" target="_blank">IP Address</a> of the Raspberry Pi, username, and <a href="https://helloacm.com/password-protect-or-ip-restriction-on-wordpress-wp-admin-folder-htaccess-and-htpasswd/" title="Password Protect or IP Restriction on WordPress wp-admin Folder (htaccess and htpasswd)">password</a>.

I created a folder for each of my two kids and my wife, so they can put their data in their own directories. The 2TB drive should last a while.

With this network drive, sharing data (movies, photos, etc.) is much easier. No more using WeChat, WhatsApp, or Google Drive — those are inconvenient for finding old files, and photos usually get compressed.

It’s great — the Raspberry Pi now has another use and is no longer just gathering dust.

[caption id="attachment_157448" align="alignnone" width="864"]<a href="https://helloacm.com/turn-your-raspberry-pi-into-a-family-network-drive-2tb-wd-hard-drive-setup-for-kids-macs/add-usb-to-raspberry-pi-server-2025-10-01-12-34-43/" rel="attachment wp-att-157448"><img src="https://helloacm.com/wp-content/uploads/2025/10/add-usb-to-raspberry-pi-server-2025-10-01-12.34.43.jpg" alt="I could still put another Raspberry Pi Server or another Hard Disk in there." width="864" height="1536" class="size-full wp-image-157448" /></a> I could still put another Raspberry Pi Server or another Hard Disk in there.[/caption]

[caption id="attachment_157452" align="alignnone" width="628"]<a href="https://helloacm.com/turn-your-raspberry-pi-into-a-family-network-drive-2tb-wd-hard-drive-setup-for-kids-macs/network-drive-2025-10-01-12-35-38/" rel="attachment wp-att-157452"><img src="https://helloacm.com/wp-content/uploads/2025/10/network-drive-2025-10-01-12.35.38.png" alt="Map Network Drive to Z - the drive letters usually are backwards from Z to A." width="628" height="461" class="size-full wp-image-157452" /></a> Map Network Drive to Z - the drive letters usually are backwards from Z to A.[/caption]

[caption id="attachment_157453" align="alignnone" width="377"]<a href="https://helloacm.com/turn-your-raspberry-pi-into-a-family-network-drive-2tb-wd-hard-drive-setup-for-kids-macs/network-drive-2025-10-01-12-35-45/" rel="attachment wp-att-157453"><img src="https://helloacm.com/wp-content/uploads/2025/10/network-drive-2025-10-01-12.35.45.png" alt="You can view the property of the network drive: used and remaining space." width="377" height="479" class="size-full wp-image-157453" /></a> You can view the property of the network drive: used and remaining space.[/caption]

[caption id="attachment_157454" align="alignnone" width="1028"]<a href="https://helloacm.com/turn-your-raspberry-pi-into-a-family-network-drive-2tb-wd-hard-drive-setup-for-kids-macs/network-drives-this-pc/" rel="attachment wp-att-157454"><img src="https://helloacm.com/wp-content/uploads/2025/10/network-drives-this-pc.jpg" alt="The mapped network drives become one of the system resources. It is just like a local drive." width="1028" height="634" class="size-full wp-image-157454" /></a> The mapped network drives become one of the system resources. It is just like a local drive.[/caption]

[caption id="attachment_157455" align="alignnone" width="456"]<a href="https://helloacm.com/turn-your-raspberry-pi-into-a-family-network-drive-2tb-wd-hard-drive-setup-for-kids-macs/samba-access2025-10-01-12-35-43/" rel="attachment wp-att-157455"><img src="https://helloacm.com/wp-content/uploads/2025/10/samba-access2025-10-01-12.35.43.png" alt="Enter Network Credentials to access the network drive." width="456" height="407" class="size-full wp-image-157455" /></a> Enter Network Credentials to access the network drive.[/caption]

[caption id="attachment_157456" align="alignnone" width="2048"]<a href="https://helloacm.com/turn-your-raspberry-pi-into-a-family-network-drive-2tb-wd-hard-drive-setup-for-kids-macs/usb-drive-2025-10-01-12-34-47/" rel="attachment wp-att-157456"><img src="https://helloacm.com/wp-content/uploads/2025/10/usb-drive-2025-10-01-12.34.47-scaled.jpg" alt="I found a nice place to host the USB external 3.5 hard drive in the shoe closet." width="2048" height="1152" class="size-full wp-image-157456" /></a> I found a nice place to host the USB external 3.5 hard drive in the shoe closet.[/caption]

[show_file file="/var/www/wp-post-common/helloacm.com/raspberry-pi.php"]

See Also: <a href="https://steemit.com/blog/@justyy/found-a-2tb-old-hard-drive-still-young-and-healthy">Found a 2TB Old Hard Drive - Still Young and Healthy</a>

[show_file file="/var/www/wp-post-common/helloacm.com/home-topology.php"]

[show_posts keyword="Home Network Topology"]

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/turning-a-dusty-mini-pc-into-a-home-server-my-nuc-8s-second-life/" rel="bookmark" title="Turning a Dusty Mini PC into a Home Server: My NUC-8’s Second Life">Turning a Dusty Mini PC into a Home Server: My NUC-8’s Second Life</a> <small>I gave an unused Beelink SEi8 mini PC a second life by installing Ubuntu and...</small></li>
<li><a href="https://helloacm.com/a-five-year-milestone-at-microsoft-anniversary-crystal/" rel="bookmark" title="A Five-Year Milestone at Microsoft (Anniversary Crystal)">A Five-Year Milestone at Microsoft (Anniversary Crystal)</a> <small>To mark my fifth anniversary at Microsoft, I received a meaningful crystal service award. Over...</small></li>
<li><a href="https://helloacm.com/understanding-dynamic_cast-in-c-safe-downcasting-explained/" rel="bookmark" title="Understanding dynamic_cast in C++: Safe Downcasting Explained">Understanding dynamic_cast in C++: Safe Downcasting Explained</a> <small>What Is dynamic_cast in C++? Purpose Safely convert between polymorphic types at runtime Commonly used...</small></li>
<li><a href="https://helloacm.com/excel-tip-faster-auto-complete/" rel="bookmark" title="Excel Tip: Faster Auto-complete">Excel Tip: Faster Auto-complete</a> <small>The Microsoft Excel is heavily used and widely used. There are so many tricks/tips that...</small></li>
<li><a href="https://helloacm.com/listen-to-what-an-seo-expert-has-to-say-about-its-benefits/" rel="bookmark" title="Listen to what an SEO expert has to say about its benefits">Listen to what an SEO expert has to say about its benefits</a> <small>To get the most from your business, you must follow your customers and take your...</small></li>
<li><a href="https://helloacm.com/telegram-accounts-are-shockingly-easy-to-hack-without-2fa/" rel="bookmark" title="Telegram Accounts Are Shockingly Easy to Hack Without 2FA">Telegram Accounts Are Shockingly Easy to Hack Without 2FA</a> <small>&#8220;How My Telegram Account Got Hacked—and What I Learned&#8221; &#8220;A Cautionary Tale: Telegram Security and...</small></li>
<li><a href="https://helloacm.com/the-common-include-php-file-for-my-sites/" rel="bookmark" title="The Common Include PHP File For My Sites">The Common Include PHP File For My Sites</a> <small>I think you may have some common code to write for most of the PHP...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-minmax-dynamic-programming-algorithm-game-of-picking-numbers-at-two-ends/" rel="bookmark" title="Teaching Kids Programming &#8211; Minmax Dynamic Programming Algorithm (Game of Picking Numbers at Two Ends)">Teaching Kids Programming &#8211; Minmax Dynamic Programming Algorithm (Game of Picking Numbers at Two Ends)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given a list of...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://helloacm.com/turn-your-raspberry-pi-into-a-family-network-drive-2tb-wd-hard-drive-setup-for-kids-macs/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Microsoft Shareholders Reject Proposal to Add Bitcoin to Balance Sheet</title>
		<link>https://helloacm.com/microsoft-shareholders-reject-proposal-to-add-bitcoin-to-balance-sheet/</link>
					<comments>https://helloacm.com/microsoft-shareholders-reject-proposal-to-add-bitcoin-to-balance-sheet/#respond</comments>
		
		<dc:creator><![CDATA[ACMer]]></dc:creator>
		<pubDate>Mon, 29 Sep 2025 11:15:13 +0000</pubDate>
				<category><![CDATA[Bitcoins]]></category>
		<category><![CDATA[blockchain]]></category>
		<category><![CDATA[BTC]]></category>
		<category><![CDATA[Cryptocurrency]]></category>
		<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[Amy Hood]]></category>
		<category><![CDATA[Annual Meeting]]></category>
		<category><![CDATA[Asset Diversification]]></category>
		<category><![CDATA[Balance Sheet]]></category>
		<category><![CDATA[bitcoin]]></category>
		<category><![CDATA[CFO]]></category>
		<category><![CDATA[Corporate Finance]]></category>
		<category><![CDATA[Corporate Strategy]]></category>
		<category><![CDATA[Crypto Investment]]></category>
		<category><![CDATA[cryptocurrency]]></category>
		<category><![CDATA[Digital Gold]]></category>
		<category><![CDATA[Financial Management]]></category>
		<category><![CDATA[Investment]]></category>
		<category><![CDATA[Market Trends]]></category>
		<category><![CDATA[Michael Saylor]]></category>
		<category><![CDATA[Microsoft Board]]></category>
		<category><![CDATA[MicroStrategy]]></category>
		<category><![CDATA[Regulatory Uncertainty]]></category>
		<category><![CDATA[Risk Management]]></category>
		<category><![CDATA[SEC]]></category>
		<category><![CDATA[Shareholders]]></category>
		<category><![CDATA[Tech Companies]]></category>
		<category><![CDATA[Volatility]]></category>
		<guid isPermaLink="false">https://helloacm.com/?p=157439</guid>

					<description><![CDATA[[caption id="attachment_157441" align="alignnone" width="714"]<a href="https://helloacm.com/microsoft-shareholders-reject-proposal-to-add-bitcoin-to-balance-sheet/btc-price-2025-09-29-bitcoin/" rel="attachment wp-att-157441"><img src="https://helloacm.com/wp-content/uploads/2025/09/btc-price-2025-09-29-bitcoin.jpg" alt="Bitcoin/BTC Price as of 2025-09-29" width="714" height="488" class="size-full wp-image-157441" /></a> Bitcoin/BTC Price as of 2025-09-29[/caption]

[caption id="attachment_157442" align="alignnone" width="699"]<a href="https://helloacm.com/microsoft-shareholders-reject-proposal-to-add-bitcoin-to-balance-sheet/msft-share-price-2025-09-29/" rel="attachment wp-att-157442"><img src="https://helloacm.com/wp-content/uploads/2025/09/msft-share-price-2025-09-29.jpg" alt="MSFT Share Price as of 2025-09-29" width="699" height="617" class="size-full wp-image-157442" /></a> MSFT Share Price as of 2025-09-29[/caption]

Every year, I receive a letter from <a href="https://helloacm.com/microsofts-excel-just-got-smarter-the-new-copilot-function/" title="Microsoft’s Excel Just Got Smarter: The New Copilot Function">Microsoft</a> because I own a few shares of Microsoft stock (RSUs), which also makes me a shareholder. The letter invites me to attend Microsoft’s annual shareholder meeting and lists several resolutions to be discussed, including recommendations from shareholders, such as Vote or Deny. In the last letter I received, one of the items was about whether to include Bitcoin on the company’s balance sheet. Unfortunately, Microsoft’s shareholders voted against this proposal.

At Microsoft’s annual shareholder meeting on December 10, 2024, shareholders overwhelmingly voted against a proposal to include Bitcoin on the company’s balance sheet.

The proposal was put forward by the conservative think tank, the National Center for Public Policy Research, suggesting that Microsoft invest 1% to 5% of its cash reserves in Bitcoin to hedge against inflation and diversify assets.

Despite Bitcoin’s price surpassing $100,000 in the week leading up to the vote, Microsoft’s board opposed the proposal, citing the cryptocurrency’s high volatility as inconsistent with the company’s liquidity and stability requirements. Microsoft Chief Financial Officer Amy Hood stated during the meeting that while the company continuously evaluates various asset classes—including cryptocurrencies—Bitcoin is currently not suitable for corporate financial management.

Supporters of the proposal included MicroStrategy Chairman Michael Saylor, who released a video before the meeting emphasizing Bitcoin’s potential as “digital gold” and suggested that Microsoft convert cash flow, stock buybacks, and debt into Bitcoin to increase company value.

However, according to Decrypt, only about 28.23 million <a href="https://helloacm.com/stock-prices-of-google-and-microsoft-before-and-after-gemini/" title="Stock Prices of Google and Microsoft Before and After Gemini">Microsoft</a> shares supported the proposal—less than 1% of the total votes—while over 5.1 billion shares voted against it. Microsoft noted in filings with the U.S. Securities and Exchange Commission that the official results would be published shortly.

According to GeekWire, Although Microsoft rejected the proposal to add Bitcoin to its balance sheet, the company has not completely ruled out potential cryptocurrency investments in the future. The board stated that while it is not currently appropriate to include Bitcoin as a corporate asset, it will continue to monitor cryptocurrency developments to make informed decisions down the line.

This voting outcome reflects the balancing act companies face when considering whether to incorporate Bitcoin into their balance sheets, weighing its high volatility against potential gains. While some companies have already started holding <a href="https://helloacm.com/the-man-who-bought-pizza-with-10000-bitcoins-the-legendary-story-of-laszlo-hanyecz/" title="The Man Who Bought Pizza with 10,000 Bitcoins: The Legendary Story of Laszlo Hanyecz">Bitcoin</a> as part of their reserves, Microsoft’s decision indicates that mainstream tech firms remain cautious.

The decision at Microsoft’s shareholder meeting could serve as a reference for other large corporations, especially given the regulatory uncertainties surrounding the cryptocurrency market. As market conditions and regulations evolve, more companies may reassess whether to include Bitcoin in their financial strategies.

[caption id="attachment_157440" align="alignnone" width="800"]<a href="https://helloacm.com/microsoft-shareholders-reject-proposal-to-add-bitcoin-to-balance-sheet/microsoft-2/" rel="attachment wp-att-157440"><img src="https://helloacm.com/wp-content/uploads/2025/09/microsoft.gif" alt="Microsoft/MSFT" width="800" height="600" class="size-full wp-image-157440" /></a> Microsoft/MSFT[/caption]

[caption id="attachment_157552" align="alignnone" width="686"]<a href="https://helloacm.com/microsoft-shareholders-reject-proposal-to-add-bitcoin-to-balance-sheet/microsoft-corporation-2025-annual-meeting-invitation/" rel="attachment wp-att-157552"><img src="https://helloacm.com/wp-content/uploads/2025/09/microsoft-corporation-2025-annual-meeting-invitation.jpg" alt="Microsoft Cooperation Annual Meeting Invitation" width="686" height="329" class="size-full wp-image-157552" /></a> Microsoft Cooperation Annual Meeting Invitation[/caption]

[caption id="attachment_157553" align="alignnone" width="943"]<a href="https://helloacm.com/microsoft-shareholders-reject-proposal-to-add-bitcoin-to-balance-sheet/microsoft-corporation-2025-annual-meeting/" rel="attachment wp-att-157553"><img src="https://helloacm.com/wp-content/uploads/2025/09/microsoft-corporation-2025-annual-meeting-scaled.jpg" alt="Microsoft Cooperation Annual Meeting Invitation" width="943" height="2048" class="size-full wp-image-157553" /></a> Microsoft Cooperation Annual Meeting Invitation[/caption]

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/chatgpt-refactors-rewrites-the-code-using-promise-all-sending-requests-in-parallel/" rel="bookmark" title="ChatGPT Refactors/Rewrites the Code using Promise.All &#8211; Sending Requests in Parallel">ChatGPT Refactors/Rewrites the Code using Promise.All &#8211; Sending Requests in Parallel</a> <small>In one of my project, I have the following code (Node/Javascript) that invokes a few...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-number-of-ways-to-stay-in-the-same-place-after-some-steps-top-down-dynamic-programming-algorithm-recursion-with-memoization/" rel="bookmark" title="Teaching Kids Programming &#8211; Number of Ways to Stay in the Same Place After Some Steps (Top Down Dynamic Programming Algorithm, Recursion with Memoization)">Teaching Kids Programming &#8211; Number of Ways to Stay in the Same Place After Some Steps (Top Down Dynamic Programming Algorithm, Recursion with Memoization)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You have a pointer at index...</small></li>
<li><a href="https://helloacm.com/nodejs-javascript-function-to-get-the-latest-block-number-height-on-the-sui-blockchain/" rel="bookmark" title="NodeJs/Javascript Function to Get the Latest Block Number (Height) on the Sui Blockchain">NodeJs/Javascript Function to Get the Latest Block Number (Height) on the Sui Blockchain</a> <small>Getting the latest block number (height) on a blockchain is a common task for developers...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-the-birthday-candles-problem-three-algorithms/" rel="bookmark" title="Teaching Kids Programming &#8211; The Birthday Candles Problem (Three Algorithms)">Teaching Kids Programming &#8211; The Birthday Candles Problem (Three Algorithms)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms The Birthday Candles Problem If a...</small></li>
<li><a href="https://helloacm.com/steemit-hide-payout-update-add-customize-rules-hide-busy-wall-wallet/" rel="bookmark" title="SteemIt Hide Payout Update: Add Customize Rules + Hide busy.wall Wallet">SteemIt Hide Payout Update: Add Customize Rules + Hide busy.wall Wallet</a> <small>Introduction Hide-SteemIt-Payout is a chrome extension that hides payout and wallets for most steemit sites...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-find-max-number-of-uncrossed-lines-longest-common-subsequence-via-space-optimisation-bottom-up-dynamic-programming-algorithm/" rel="bookmark" title="Teaching Kids Programming &#8211; Find Max Number of Uncrossed Lines (Longest Common Subsequence) via Space Optimisation Bottom Up Dynamic Programming Algorithm">Teaching Kids Programming &#8211; Find Max Number of Uncrossed Lines (Longest Common Subsequence) via Space Optimisation Bottom Up Dynamic Programming Algorithm</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given two integer arrays...</small></li>
<li><a href="https://helloacm.com/tron-trx-and-huobi-htx-could-be-the-next-100x-tokens/" rel="bookmark" title="TRON (TRX) and Huobi (HTX) could be the next 100x tokens">TRON (TRX) and Huobi (HTX) could be the next 100x tokens</a> <small>Crypto Bull Market Analysis Today is truly a bull market for cryptocurrencies. Not only has...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-find-max-number-of-uncrossed-lines-longest-common-subsequence-via-bottom-up-dynamic-programming-algorithm/" rel="bookmark" title="Teaching Kids Programming &#8211; Find Max Number of Uncrossed Lines (Longest Common Subsequence) via Bottom Up Dynamic Programming Algorithm">Teaching Kids Programming &#8211; Find Max Number of Uncrossed Lines (Longest Common Subsequence) via Bottom Up Dynamic Programming Algorithm</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given two integer arrays...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[[caption id="attachment_157441" align="alignnone" width="714"]<a href="https://helloacm.com/microsoft-shareholders-reject-proposal-to-add-bitcoin-to-balance-sheet/btc-price-2025-09-29-bitcoin/" rel="attachment wp-att-157441"><img src="https://helloacm.com/wp-content/uploads/2025/09/btc-price-2025-09-29-bitcoin.jpg" alt="Bitcoin/BTC Price as of 2025-09-29" width="714" height="488" class="size-full wp-image-157441" /></a> Bitcoin/BTC Price as of 2025-09-29[/caption]

[caption id="attachment_157442" align="alignnone" width="699"]<a href="https://helloacm.com/microsoft-shareholders-reject-proposal-to-add-bitcoin-to-balance-sheet/msft-share-price-2025-09-29/" rel="attachment wp-att-157442"><img src="https://helloacm.com/wp-content/uploads/2025/09/msft-share-price-2025-09-29.jpg" alt="MSFT Share Price as of 2025-09-29" width="699" height="617" class="size-full wp-image-157442" /></a> MSFT Share Price as of 2025-09-29[/caption]

Every year, I receive a letter from <a href="https://helloacm.com/microsofts-excel-just-got-smarter-the-new-copilot-function/" title="Microsoft’s Excel Just Got Smarter: The New Copilot Function">Microsoft</a> because I own a few shares of Microsoft stock (RSUs), which also makes me a shareholder. The letter invites me to attend Microsoft’s annual shareholder meeting and lists several resolutions to be discussed, including recommendations from shareholders, such as Vote or Deny. In the last letter I received, one of the items was about whether to include Bitcoin on the company’s balance sheet. Unfortunately, Microsoft’s shareholders voted against this proposal.

At Microsoft’s annual shareholder meeting on December 10, 2024, shareholders overwhelmingly voted against a proposal to include Bitcoin on the company’s balance sheet.

The proposal was put forward by the conservative think tank, the National Center for Public Policy Research, suggesting that Microsoft invest 1% to 5% of its cash reserves in Bitcoin to hedge against inflation and diversify assets.

Despite Bitcoin’s price surpassing $100,000 in the week leading up to the vote, Microsoft’s board opposed the proposal, citing the cryptocurrency’s high volatility as inconsistent with the company’s liquidity and stability requirements. Microsoft Chief Financial Officer Amy Hood stated during the meeting that while the company continuously evaluates various asset classes—including cryptocurrencies—Bitcoin is currently not suitable for corporate financial management.

Supporters of the proposal included MicroStrategy Chairman Michael Saylor, who released a video before the meeting emphasizing Bitcoin’s potential as “digital gold” and suggested that Microsoft convert cash flow, stock buybacks, and debt into Bitcoin to increase company value.

However, according to Decrypt, only about 28.23 million <a href="https://helloacm.com/stock-prices-of-google-and-microsoft-before-and-after-gemini/" title="Stock Prices of Google and Microsoft Before and After Gemini">Microsoft</a> shares supported the proposal—less than 1% of the total votes—while over 5.1 billion shares voted against it. Microsoft noted in filings with the U.S. Securities and Exchange Commission that the official results would be published shortly.

According to GeekWire, Although Microsoft rejected the proposal to add Bitcoin to its balance sheet, the company has not completely ruled out potential cryptocurrency investments in the future. The board stated that while it is not currently appropriate to include Bitcoin as a corporate asset, it will continue to monitor cryptocurrency developments to make informed decisions down the line.

This voting outcome reflects the balancing act companies face when considering whether to incorporate Bitcoin into their balance sheets, weighing its high volatility against potential gains. While some companies have already started holding <a href="https://helloacm.com/the-man-who-bought-pizza-with-10000-bitcoins-the-legendary-story-of-laszlo-hanyecz/" title="The Man Who Bought Pizza with 10,000 Bitcoins: The Legendary Story of Laszlo Hanyecz">Bitcoin</a> as part of their reserves, Microsoft’s decision indicates that mainstream tech firms remain cautious.

The decision at Microsoft’s shareholder meeting could serve as a reference for other large corporations, especially given the regulatory uncertainties surrounding the cryptocurrency market. As market conditions and regulations evolve, more companies may reassess whether to include Bitcoin in their financial strategies.

[caption id="attachment_157440" align="alignnone" width="800"]<a href="https://helloacm.com/microsoft-shareholders-reject-proposal-to-add-bitcoin-to-balance-sheet/microsoft-2/" rel="attachment wp-att-157440"><img src="https://helloacm.com/wp-content/uploads/2025/09/microsoft.gif" alt="Microsoft/MSFT" width="800" height="600" class="size-full wp-image-157440" /></a> Microsoft/MSFT[/caption]

[caption id="attachment_157552" align="alignnone" width="686"]<a href="https://helloacm.com/microsoft-shareholders-reject-proposal-to-add-bitcoin-to-balance-sheet/microsoft-corporation-2025-annual-meeting-invitation/" rel="attachment wp-att-157552"><img src="https://helloacm.com/wp-content/uploads/2025/09/microsoft-corporation-2025-annual-meeting-invitation.jpg" alt="Microsoft Cooperation Annual Meeting Invitation" width="686" height="329" class="size-full wp-image-157552" /></a> Microsoft Cooperation Annual Meeting Invitation[/caption]

[caption id="attachment_157553" align="alignnone" width="943"]<a href="https://helloacm.com/microsoft-shareholders-reject-proposal-to-add-bitcoin-to-balance-sheet/microsoft-corporation-2025-annual-meeting/" rel="attachment wp-att-157553"><img src="https://helloacm.com/wp-content/uploads/2025/09/microsoft-corporation-2025-annual-meeting-scaled.jpg" alt="Microsoft Cooperation Annual Meeting Invitation" width="943" height="2048" class="size-full wp-image-157553" /></a> Microsoft Cooperation Annual Meeting Invitation[/caption]

--EOF (<a title='The Ultimate Computing & Technology Blog' href='https://helloacm.com'>The Ultimate Computing & Technology Blog</a>) --<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-list'>
<!-- YARPP List -->
<h3>Related posts:</h3><ol>
<li><a href="https://helloacm.com/chatgpt-refactors-rewrites-the-code-using-promise-all-sending-requests-in-parallel/" rel="bookmark" title="ChatGPT Refactors/Rewrites the Code using Promise.All &#8211; Sending Requests in Parallel">ChatGPT Refactors/Rewrites the Code using Promise.All &#8211; Sending Requests in Parallel</a> <small>In one of my project, I have the following code (Node/Javascript) that invokes a few...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-number-of-ways-to-stay-in-the-same-place-after-some-steps-top-down-dynamic-programming-algorithm-recursion-with-memoization/" rel="bookmark" title="Teaching Kids Programming &#8211; Number of Ways to Stay in the Same Place After Some Steps (Top Down Dynamic Programming Algorithm, Recursion with Memoization)">Teaching Kids Programming &#8211; Number of Ways to Stay in the Same Place After Some Steps (Top Down Dynamic Programming Algorithm, Recursion with Memoization)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You have a pointer at index...</small></li>
<li><a href="https://helloacm.com/nodejs-javascript-function-to-get-the-latest-block-number-height-on-the-sui-blockchain/" rel="bookmark" title="NodeJs/Javascript Function to Get the Latest Block Number (Height) on the Sui Blockchain">NodeJs/Javascript Function to Get the Latest Block Number (Height) on the Sui Blockchain</a> <small>Getting the latest block number (height) on a blockchain is a common task for developers...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-the-birthday-candles-problem-three-algorithms/" rel="bookmark" title="Teaching Kids Programming &#8211; The Birthday Candles Problem (Three Algorithms)">Teaching Kids Programming &#8211; The Birthday Candles Problem (Three Algorithms)</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms The Birthday Candles Problem If a...</small></li>
<li><a href="https://helloacm.com/steemit-hide-payout-update-add-customize-rules-hide-busy-wall-wallet/" rel="bookmark" title="SteemIt Hide Payout Update: Add Customize Rules + Hide busy.wall Wallet">SteemIt Hide Payout Update: Add Customize Rules + Hide busy.wall Wallet</a> <small>Introduction Hide-SteemIt-Payout is a chrome extension that hides payout and wallets for most steemit sites...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-find-max-number-of-uncrossed-lines-longest-common-subsequence-via-space-optimisation-bottom-up-dynamic-programming-algorithm/" rel="bookmark" title="Teaching Kids Programming &#8211; Find Max Number of Uncrossed Lines (Longest Common Subsequence) via Space Optimisation Bottom Up Dynamic Programming Algorithm">Teaching Kids Programming &#8211; Find Max Number of Uncrossed Lines (Longest Common Subsequence) via Space Optimisation Bottom Up Dynamic Programming Algorithm</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given two integer arrays...</small></li>
<li><a href="https://helloacm.com/tron-trx-and-huobi-htx-could-be-the-next-100x-tokens/" rel="bookmark" title="TRON (TRX) and Huobi (HTX) could be the next 100x tokens">TRON (TRX) and Huobi (HTX) could be the next 100x tokens</a> <small>Crypto Bull Market Analysis Today is truly a bull market for cryptocurrencies. Not only has...</small></li>
<li><a href="https://helloacm.com/teaching-kids-programming-find-max-number-of-uncrossed-lines-longest-common-subsequence-via-bottom-up-dynamic-programming-algorithm/" rel="bookmark" title="Teaching Kids Programming &#8211; Find Max Number of Uncrossed Lines (Longest Common Subsequence) via Bottom Up Dynamic Programming Algorithm">Teaching Kids Programming &#8211; Find Max Number of Uncrossed Lines (Longest Common Subsequence) via Bottom Up Dynamic Programming Algorithm</a> <small>Teaching Kids Programming: Videos on Data Structures and Algorithms You are given two integer arrays...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://helloacm.com/microsoft-shareholders-reject-proposal-to-add-bitcoin-to-balance-sheet/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>