Years ago, when I worked at Gameloft as a server leader,
after 2 years of developing the 3D MMORPG Game Order and Chaos II.
We thought it was time to publish it.

On launch day, tens of thousands of players downloaded the game from the AppStore and connected to the servers.
As we celebrated the smooth running of the servers, one server crashed, then another…
I inspected the core dump file, and discovered it’s a dangling pointer issue : a memory block modified by a dangling pointer from another thread.
The crash didn’t occur when the memory was modified but when a thread tried to read the illegal data.

It was hard to reproduce, and there was no clue as to the root cause.
We had hundreds of classes that allocated memory, so we needed to trace every applied new/delete operator, it was a huge workload, and we had already gone live, with players complaining - it was urgent.

As the server leader, the whole team was counting on me.

I started coding a memory pool template, and applied it to all classes with bi-section method.
After hours of debugging and tracing, I found a way to reproduce the issue and finally pinpointed the buggy code.

This is the most impressive bug I’ve fixed.

If you need to design a user registration system, how would you implement username conflict checking? When a user creates a new name, the system need to check if this name has already been used.

The first and easiest way you might think is using a database table to store all usernames with a unique constraint.
A simple SQL query could then determine if the name is used.
But what if the system has billions of users, and millions of users are using the system simultaneously(like Facebook)? The simple SQL query could become a huge bottleneck.

Then you might get a new idea: store all usernames in memory with a hash table(such as Redis). The query would be super fast.
Yes, it’s a solution. But storing billions of usernames would consume a lot of memory.
If one username is 32 bytes in size, one billion usernames would use 32GB of memory, which is huge.

How could we get both speed and memory efficiency?

The answer is Bloom Filter:
A Bloom Filter builds a hash table with a range of keys, where each key uses a single bit to indicate whether it is occupied.
Using this approach, one billion names would require only 128MB of memory.
To reduce hash conflicts, multiple hash tables with different hash salts are used.
It uses much less memory and maintains high performance.

My friend Robert has been obsessed with Bitcoin recently.
One day, he told me that Bitcoin’s price would increase from \$1000 to \$3000.
I didn’t believe it.
So we made a bet: If Bitcoin hit \$3000 in 6 months, He would win \$1000; otherwise I would win \$1000.

Can you see the problem with this bet?
It’s not a fair bet.
There was a strategy for me to win in any situation.

Hedge!

I spend \$1000 to buy Bitcoin.
After 6 months:

  • If Bitcoin hit \$3000, I would lose the bet and have to pay Robert \$1000.
    But my Bitcoin would now be worth \$3000+, giving me at least \$1000 in total profit.
  • If Bitcoin didn’t hit \$3000, I would win \$1000 from Robert.
    My total profit would be the value of my Bitcoin.

Either way, I won!