Improving Backend Engineer Skills: Abstract Problem Solving and Code Abstractions
This article explores the core competencies of backend engineers, emphasizing accurate problem abstraction, discusses Go's ServerCodec and I/O interfaces, demonstrates algorithmic solutions to the Word Search II problem, and offers practical advice on improving coding skills through studying language features, system design, and effective learning habits.
The author, after observing many new engineers at Tencent, noticed common shortcomings and decided to share insights on how to improve backend development capabilities, especially for those transitioning from frontend to backend roles.
Backend engineers need communication, coding, and architecture design skills, but the essential ability is to accurately abstract problems, discuss core issues with peers, and collaboratively solve them.
As an illustration of abstraction, the Go standard library defines a ServerCodec interface in net/rpc that encapsulates reading RPC requests and writing responses, allowing implementations to focus on business logic rather than low‑level I/O details.
The article then compares this clean abstraction with a more tangled example, spp_handle_input , showing how a poorly designed API can hide capabilities and increase implementation complexity.
Further examples include Go’s I/O interfaces— Reader , Writer , Closer , Seeker —and their composite forms ( ReadWriter , ReadCloser , etc.), demonstrating how small, orthogonal abstractions compose into powerful, low‑cognitive‑load tools.
Read/write abstractions are illustrated with bufio.NewWriter and io.LimitReader , which add buffering or length‑limiting behavior without burdening the programmer with extra mental models.
The same principles apply in other languages; for instance, Rust and Scala achieve similar flexibility with traits, though they require explicit implementation and can complicate dependency management.
To showcase practical problem solving, the article presents the LeetCode “Word Search II” challenge and provides an optimal solution that combines depth‑first search with a Trie, implemented in Java:
public List<String> findWords(char[][] board, String[] words) {
List<String> res = new ArrayList<>();
TrieNode root = buildTrie(words);
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[0].length; j++) {
dfs(board, i, j, root, res);
}
}
return res;
}
public void dfs(char[][] board, int i, int j, TrieNode p, List<String> res) {
char c = board[i][j];
if (c == '#' || p.next[c - 'a'] == null) return;
p = p.next[c - 'a'];
if (p.word != null) { res.add(p.word); p.word = null; }
board[i][j] = '#';
if (i > 0) dfs(board, i - 1, j, p, res);
if (j > 0) dfs(board, i, j - 1, p, res);
if (i < board.length - 1) dfs(board, i + 1, j, p, res);
if (j < board[0].length - 1) dfs(board, i, j + 1, p, res);
board[i][j] = c;
}
public TrieNode buildTrie(String[] words) {
TrieNode root = new TrieNode();
for (String w : words) {
TrieNode p = root;
for (char c : w.toCharArray()) {
int i = c - 'a';
if (p.next[i] == null) p.next[i] = new TrieNode();
p = p.next[i];
}
p.word = w;
}
return root;
}
class TrieNode {
TrieNode[] next = new TrieNode[26];
String word;
}A less efficient, more verbose Go solution is also shown, illustrating how excessive abstraction and redundant data structures can lead to slower runtimes (≈400 ms vs. 15 ms) and harder‑to‑read code.
The article then abstracts a typical backend storage scenario: building a large hash or B‑tree to quickly query which friends are playing a specific game, discussing in‑memory storage, persistence, sharding, and multi‑machine synchronization.
Rust’s ownership primitives— Box<T> , Rc<T> , RefCell<T> , Weak<T> —are highlighted as another way to achieve fine‑grained safety and lifetime management without runtime overhead.
Overall, the piece stresses that precise, layered abstraction enables high‑throughput services, rapid development, and efficient resource utilization.
Practical advice includes learning Go or Rust early, reading well‑documented standard‑library code (e.g., net/http, encoding/json), and studying real‑world backend systems such as recommendation engines, shield services, CKafka, CKV+, and etcd.
The author advocates active thinking: repeatedly abstracting problems, comparing solutions, and refining one’s own methodology to achieve deeper insight and better code quality.
Advertisement: The article concludes with a promotion for the “研发效能(DevOps)工程师” certification from the Ministry of Industry and Information Technology, encouraging readers to enroll via the listed contact.
DevOps
Share premium content and events on trends, applications, and practices in development efficiency, AI and related technologies. The IDCF International DevOps Coach Federation trains end‑to‑end development‑efficiency talent, linking high‑performance organizations and individuals to achieve excellence.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.