Fundamentals 41 min read

Top 15 Must‑Know System Design & Coding Interview Questions Explained

This article compiles 15 common interview topics—from sorting linked lists and encryption differences to TCP reliability, I/O models, Hystrix, delayed tasks, HTTPS flow, transaction isolation, index pitfalls, virtual memory, ranking with Redis, distributed locks, zero‑copy techniques, synchronized internals, and Snowflake ID generation—providing concise explanations, code examples, and diagrams for each.

Su San Talks Tech
Su San Talks Tech
Su San Talks Tech
Top 15 Must‑Know System Design & Coding Interview Questions Explained

Preface

Hello, I'm Su San. Recently a reader went to a Shopee interview, so I share the real interview questions.

Sort a linked list

Difference between symmetric and asymmetric encryption algorithms

How TCP guarantees reliability

Five I/O models

Hystrix working principle

Delayed task handling

HTTPS request process

Transaction isolation levels and repeatable‑read implementation

When indexes become ineffective

What is virtual memory

Ranking implementation (e.g., exam score ranking)

Distributed lock implementation

Zero‑copy

synchronized keyword

Distributed ID generation schemes and Snowflake algorithm

1. Sort a Linked List

Given the head node of a linked list, sort it in ascending order and return the sorted list.

Linked list sorting example
Linked list sorting example

Example 1:

Input: head = [4,2,1,3]
Output: [1,2,3,4]

Example 2:

Linked list sorting second example
Linked list sorting second example
Input: head = [-1,5,3,4,0]
Output: [-1,0,3,4,5]

The problem can be solved with a two‑pointer + merge sort algorithm in four steps:

Use fast and slow pointers to find the middle node.

Cut the list at the middle.

Recursively sort the left and right sub‑lists with merge sort.

Merge the two sorted sub‑lists.

Complete code:

class Solution{<br/>    public ListNode sortList(ListNode head){<br/>        if(head == null || head.next == null) return head;<br/>        ListNode slow = head;<br/>        ListNode fast = head;<br/>        while(fast.next != null && fast.next.next != null){<br/>            fast = fast.next.next;<br/>            slow = slow.next;<br/>        }<br/>        ListNode mid = slow.next;<br/>        slow.next = null;<br/>        ListNode left = sortList(head);<br/>        ListNode right = sortList(mid);<br/>        return merge(left, right);<br/>    }<br/>    public ListNode merge(ListNode left, ListNode right){<br/>        ListNode dummy = new ListNode(0);<br/>        ListNode tail = dummy;<br/>        while(left != null && right != null){<br/>            if(left.val <= right.val){<br/>                tail.next = left;<br/>                left = left.next;<br/>            }else{<br/>                tail.next = right;<br/>                right = right.next;<br/>            }<br/>            tail = tail.next;<br/>        }<br/>        if(left != null) tail.next = left;<br/>        else if(right != null) tail.next = right;<br/>        return dummy.next;<br/>    }<br/>}<br/>

2. Difference Between Symmetric and Asymmetric Encryption

Key concepts:

Plaintext: unencrypted data.

Ciphertext: encrypted data.

Key: parameter used for encryption/decryption; can be symmetric or asymmetric.

Encryption: process of turning plaintext into ciphertext.

Decryption: reverse process.

Symmetric encryption uses the same key for both encryption and decryption. Common algorithms: AES, 3DES, DES, RC5, RC6 .

Symmetric encryption algorithms
Symmetric encryption algorithms

Asymmetric encryption uses a pair of keys (public and private). The public key encrypts data; only the matching private key can decrypt. Common algorithms: RSA, ElGamal, DSA, Diffie‑Hellman, ECC .

Asymmetric encryption algorithms
Asymmetric encryption algorithms

3. How TCP Guarantees Reliability

Three‑way handshake for connection establishment and four‑way handshake for termination ensure reliable start and end.

TCP is stateful: it tracks sent, acknowledged, and missing packets, guaranteeing ordered delivery and error‑free transmission.

Control mechanisms include checksum, ACK responses, timeout retransmission, duplicate data discard, flow control (sliding window), and congestion control.

4. Five I/O Models

4.1 Blocking I/O

The calling process blocks until the kernel has prepared data and copied it to user space.

Blocking I/O diagram
Blocking I/O diagram

4.2 Non‑Blocking I/O

If the kernel data isn’t ready, the call returns an error immediately, allowing the application to poll later.

Non‑blocking I/O diagram
Non‑blocking I/O diagram

4.3 I/O Multiplexing – select

Using select, a process can monitor multiple file descriptors and returns when any become ready for reading.

select diagram
select diagram

Limitations of select:

Maximum number of connections is limited (typically 1024 on Linux).

After select returns, the kernel must iterate over the fd set to find ready descriptors.

4.4 I/O Multiplexing – epoll

epoll solves select ’s drawbacks by using an event‑driven mechanism: register a fd with epoll_ctl, and when the fd becomes ready the kernel notifies the process via callbacks, eliminating the need to scan all fds.

epoll diagram
epoll diagram

4.5 Signal‑Driven I/O

The kernel sends a signal (e.g., SIGIO) when data is ready, allowing the application to perform other work instead of polling.

Signal‑driven I/O diagram
Signal‑driven I/O diagram

4.6 Asynchronous I/O (AIO)

AIO returns immediately after the request is submitted; the kernel notifies the application via a signal when the operation completes.

AIO flow diagram
AIO flow diagram

5. Hystrix Working Principle

Hystrix provides two command objects: HystrixCommand and HystrixObservableCommand, representing a single dependency request.

HystrixCommand and HystrixObservableCommand encapsulate a request to a remote service.

Execution steps:

Build the command.

Execute the command (four ways): R execute() – synchronous, blocking. Future queue() – asynchronous, returns a Future. Observable observe() – creates and subscribes to an Observable. Observable toObservable() – cold Observable, executes on subscription.

Check if the response is cached.

Check if the circuit breaker is open; if open, go directly to fallback.

Check thread‑pool / semaphore / queue status.

Execute the actual task.

Record execution metrics for circuit‑breaker health.

If the command fails, run the user‑defined fallback.

Return the result (as an Observable or direct value).

6. Delayed Task Handling

Common scenarios: order auto‑cancellation after 30 minutes, sending SMS 15 minutes after registration, etc. Typical solutions:

JDK DelayQueue Time‑wheel algorithm

Database schedulers (e.g., Quartz)

Redis ZSET Message‑queue delayed queues

7. HTTPS Request Process

HTTPS = HTTP + SSL/TLS; SSL/TLS encrypts data, HTTP transports it.

SSL = Secure Sockets Layer, TLS = Transport Layer Security (successor of SSL 3.0).

HTTPS flow diagram
HTTPS flow diagram

HTTPS flow:

User enters an HTTPS URL; browser connects to server port 443.

Server presents its digital certificate (public key).

Client validates the certificate; if valid, it generates a symmetric session key and encrypts it with the server’s public key.

Client sends the encrypted session key to the server.

Server decrypts the session key with its private key and uses it to encrypt/decrypt subsequent data.

8. Transaction Isolation Levels and Repeatable‑Read Implementation

8.1 Four Isolation Levels

To prevent dirty reads, non‑repeatable reads, and phantom reads, databases define four isolation levels: Read Uncommitted, Read Committed, Repeatable Read, Serializable .

Read Uncommitted : allows dirty reads, non‑repeatable reads, and phantom reads.

Read Committed : prevents dirty reads but still allows non‑repeatable and phantom reads.

Repeatable Read : prevents dirty and non‑repeatable reads; phantom reads may still occur.

Serializable : highest isolation; eliminates all three anomalies but reduces concurrency.

Typical concurrency problems per level:

Read Uncommitted – dirty, non‑repeatable, phantom. Read Committed – non‑repeatable, phantom. Repeatable Read – phantom. Serializable – none.

8.2 Read View Visibility Rules

In InnoDB, a Read View determines which versions of rows are visible to a transaction. Key variables:

m_ids : list of active transaction IDs. max_limit_id : next transaction ID to be assigned. min_limit_id : smallest active transaction ID. creator_trx_id : ID of the transaction that created the read view.

Visibility checks:

If trx_id < min_limit_id, the version was committed before the read view and is visible.

If trx_id >= max_limit_id, the version was created after the read view and is invisible.

If min_limit_id ≤ trx_id < max_limit_id, three sub‑cases apply:

If trx_id is in m_ids and equals creator_trx_id, the row is visible (it was created by the current transaction).

If trx_id is in m_ids but not equal to creator_trx_id, the row is invisible (still uncommitted by another transaction).

If trx_id is not in m_ids, the row was committed before the read view and is visible.

8.3 How Repeatable Read Is Implemented

Repeatable‑read isolation is achieved via MVCC (Multi‑Version Concurrency Control). Each transaction sees a consistent snapshot (the read view) throughout its lifetime, preventing non‑repeatable reads.

Steps for a SELECT under MVCC:

Obtain the transaction’s own version ID.

Create a read view.

Fetch rows and compare each row’s version ID with the read view.

If a row is not visible, retrieve the appropriate version from the undo log.

Return the rows that satisfy the visibility rules.

In InnoDB, MVCC is realized by combining Read View with an Undo Log that stores historical snapshots.

8.4 Example of Repeatable Read

Two transactions A (ID 100) and B (ID 101) operate on a core_user table. Transaction A creates a read view (min = 100, max = 102, creator = 100). After B updates the row to “Cao Cao” and commits, A’s subsequent query still sees the original “Sun Quan” because it reuses the same read view.

9. When Indexes Fail

Using OR in the WHERE clause.

Missing quotes around string literals.

Wildcard patterns with LIKE that start with %.

Querying a composite index without using its leftmost column.

Applying MySQL built‑in functions to indexed columns.

Arithmetic operations on indexed columns.

Using != or <> on indexed columns.

Using IS NULL or IS NOT NULL on indexed columns.

Mismatched encoding in join columns.

When the optimizer estimates a full table scan to be cheaper than using the index.

10. What Is Virtual Memory

Virtual memory provides each process with its own address space. The OS maps virtual pages to physical pages, allowing programs to request virtual memory while the hardware uses physical memory.

Benefits:

Virtual address space can be larger than physical memory.

Multiple virtual pages can map to the same physical page.

Zero‑copy leverages virtual memory: by mapping the same physical page into both kernel and user spaces, data copying between them is avoided.

Zero‑copy via virtual memory
Zero‑copy via virtual memory

11. Ranking Implementation (e.g., Exam Score Ranking)

Redis zset (sorted set) is commonly used for leaderboards.

zadd key score member [score member ...]
zrank key member

Internally, Redis uses a ziplist or skiplist for storage, suitable for ranking, social likes, etc.

Redis ZSET ranking demo
Redis ZSET ranking demo

12. Distributed Lock Implementation

Distributed locks coordinate access to shared resources across multiple processes. Redis is a popular choice. SETNX + EXPIRE (separate commands) – vulnerable to lock leakage if the process crashes between the two commands. SETNX + value = expiration timestamp – requires synchronized clocks and lacks a unique owner identifier. SET key value NX EX ttl – atomic but may release the lock before the business logic finishes.

Extended SET with a unique request ID and a Lua script for safe release.

Redisson library – adds a watchdog thread that automatically extends the lock’s TTL while the holder is alive.

12.1 SETNX + EXPIRE (separate)

if (jedis.setnx(key, lock_value) == 1) {<br/>    expire(key, 100); // set TTL<br/>    try { do something } finally { jedis.del(key); }<br/>}<br/>

Problem: if the process crashes after SETNX but before EXPIRE, the lock never expires.

12.2 SETNX + expiration timestamp

long expires = System.currentTimeMillis() + expireTime;<br/>String expiresStr = String.valueOf(expires);<br/>if (jedis.setnx(key, expiresStr) == 1) return true;<br/>String current = jedis.get(key);<br/>if (current != null && Long.parseLong(current) < System.currentTimeMillis()) {<br/>    String old = jedis.getSet(key, expiresStr);<br/>    if (old != null && old.equals(current)) return true;<br/>}<br/>return false;<br/>

Drawbacks: requires synchronized clocks and may suffer from race conditions when multiple clients try to acquire an expired lock.

12.3 SET with NX and EX

if (jedis.set(key, lock_value, "NX", "EX", 100) == 1) {<br/>    try { do something } finally { jedis.del(key); }<br/>}<br/>

Issues: lock may expire before the business logic finishes; another client could delete the lock.

12.4 SET with unique request ID + Lua release

if (jedis.set(key, uni_id, "NX", "EX", 100) == 1) {<br/>    try { do something } finally {<br/>        if (uni_id.equals(jedis.get(key))) jedis.del(key);<br/>    }<br/>}<br/>

Lua script for atomic check‑and‑delete:

if redis.call('get', KEYS[1]) == ARGV[1] then<br/>    return redis.call('del', KEYS[1])<br/>else<br/>    return 0<br/>end;<br/>

12.5 Redisson

Redisson starts a watchdog thread that periodically extends the lock’s TTL while the holder thread is alive, preventing premature expiration.

Redisson watchdog
Redisson watchdog

13. Zero‑Copy

Zero‑copy eliminates copying data between user and kernel spaces.

13.1 Traditional I/O Flow

Traditional I/O flow
Traditional I/O flow

Four context switches and four data copies (two CPU copies, two DMA copies).

13.2 mmap + write

Using mmap maps a file directly into the process’s address space, sharing the same physical page with the kernel.

void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);<br/>
mmap + write zero‑copy
mmap + write zero‑copy

Result: 4 context switches, 3 copies (2 DMA, 1 CPU).

13.3 sendfile

ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count);<br/>
sendfile zero‑copy
sendfile zero‑copy

Result: 2 context switches, 3 copies (2 DMA, 1 CPU).

13.4 sendfile + DMA scatter/gather

sendfile with scatter/gather
sendfile with scatter/gather

Result: 2 context switches, 2 DMA copies – true zero‑copy (no CPU copying).

14. synchronized

The synchronized keyword provides a monitor lock for methods or code blocks.

Compiled bytecode contains monitorenter and monitorexit for synchronized blocks.

Methods marked with the ACC_SYNCHRONIZED flag are synchronized.

14.1 monitorenter / monitorexit / ACC_SYNCHRONIZED

For a synchronized block, the JVM inserts monitorenter before the block and monitorexit after it. For a synchronized method, the method’s flag includes ACC_SYNCHRONIZED.

14.2 Monitor (ObjectMonitor)

In HotSpot, each object has an associated monitor (ObjectMonitor) that manages lock ownership, wait sets, and recursion counts.

ObjectMonitor structure
ObjectMonitor structure

14.3 Java Monitor Working Mechanism

Monitor workflow
Monitor workflow

Thread attempts to acquire the monitor and enters the entry list.

When acquired, the thread becomes the owner and the lock count increments.

Calling wait() moves the thread to the wait set and releases the monitor. notify() / notifyAll() wakes waiting threads, which then try to reacquire the monitor.

Upon method/block exit, the monitor is released.

14.4 Object Header and Mark Word

Each object header contains a Mark Word (hash code, GC age, lock state, thread ID, etc.) and a class pointer. For heavyweight locks, the Mark Word points to the monitor object.

Object header layout
Object header layout

15. Distributed ID Generation Schemes and Snowflake Algorithm

Common schemes:

UUID

Database auto‑increment IDs

Snowflake algorithm

Baidu UidGenerator

Meituan Leaf

Snowflake generates 64‑bit IDs:

1 bit: sign (always 0 for positive IDs).

41 bits: timestamp (milliseconds since a custom epoch).

10 bits: machine identifier.

12 bits: sequence number within the same millisecond.

Snowflake ID structure
Snowflake ID structure
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

System DesigndatabasesAlgorithmsNetworking
Su San Talks Tech
Written by

Su San Talks Tech

Su San, former staff at several leading tech companies, is a top creator on Juejin and a premium creator on CSDN, and runs the free coding practice site www.susan.net.cn.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.