Backend Development 15 min read

20 Essential Coding Habits for Backend Developers

This article presents twenty essential coding habits for backend developers, covering self‑testing, parameter validation, interface compatibility, clear comments, proper resource handling, runtime error avoidance, avoiding remote calls in loops, concurrency safety, null checks, thread‑pool usage, SQL testing, third‑party API handling, idempotency, thread‑safe collections, master‑slave latency, cache consistency, refactoring, version control, testing, and performance monitoring.

Code Ape Tech Column
Code Ape Tech Column
Code Ape Tech Column
20 Essential Coding Habits for Backend Developers

1. Self‑test after modifying code

Always run a self‑test after any code change, even if the modification seems trivial, to catch unexpected issues early.

2. Validate method parameters thoroughly

Check incoming parameters for nullability, length, and format before using them, e.g., ensure a varchar(16) field does not receive a 32‑character string.

3. Ensure interface compatibility when modifying old APIs

When extending an existing service interface, maintain backward compatibility. Example for a Dubbo service:

void oldService(A, B) { newService(A, B, null); }
void newService(A, B, C);

4. Add clear comments for complex logic

Use concise comments to explain intricate business logic, aiding future maintainers.

5. Close IO resources promptly

Always close streams in a finally block or use try‑with‑resources (Java 7+). Example:

FileInputStream fdIn = null;
try {
    fdIn = new FileInputStream(new File("/jay.txt"));
} catch (FileNotFoundException e) {
    log.error(e);
} catch (IOException e) {
    log.error(e);
} finally {
    try { if (fdIn != null) fdIn.close(); } catch (IOException e) { log.error(e); }
}
try (FileInputStream inputStream = new FileInputStream(new File("jay.txt"))) {
    // use resources
} catch (FileNotFoundException e) {
    log.error(e);
} catch (IOException e) {
    log.error(e);
}

6. Prevent common runtime errors

Check array bounds, avoid division by zero, and guard against null pointers. Example of safe list access:

if (CollectionUtils.isNotEmpty(list) && list.size() > 1) {
    String name = list.get(1).getName();
}

7. Avoid remote or DB calls inside loops

Batch queries instead of per‑iteration calls to reduce network and I/O load.

remoteBatchQuery(param);
for (int i = 0; i < n; i++) {
    remoteSingleQuery(param);
}

8. Consider concurrency consistency

Guard "query‑then‑update" sequences with atomic DB operations or locks to avoid race conditions.

if (deleteAvailableTicketById(ticketId) == 1) {
    // add cash
} else {
    return "No available coupon";
}

9. Null‑check objects before accessing properties

if (object != null) {
    String name = object.getName();
}

10. Use appropriate thread pools and isolate them

Select thread‑pool sizes based on workload characteristics and avoid sharing a single pool across unrelated services.

11. Test manually written SQL and review execution plans

Run SQL in the database first and use EXPLAIN to verify index usage.

EXPLAIN SELECT * FROM user WHERE userid = 10086 OR age = 18;

12. Handle third‑party API exceptions, timeouts, and retries

Set connection timeout ( connect‑time ) and retry count ( retry ) when invoking external services.

13. Ensure API idempotency

Use techniques such as unique tokens, database constraints, or distributed locks to make repeated calls safe.

14. Use thread‑safe collections in concurrent environments

Prefer ConcurrentHashMap over non‑thread‑safe HashMap when multiple threads access a map.

15. Account for master‑slave replication lag

For critical reads, consider forcing queries to the master or redesigning to tolerate eventual consistency.

16. Maintain cache‑DB consistency and guard against cache pitfalls

Be aware of cache avalanche, cache penetration, and cache breakdown, and design strategies to mitigate them.

17. Refactor code regularly

Periodically clean up duplicated or overly coupled code to improve readability and maintainability.

18. Use version control and backups

Employ Git for change tracking and back up repositories to external storage.

19. Write unit and integration tests

Adopt test‑driven development (TDD) to catch defects early and verify module interactions.

20. Monitor performance and resource usage

Analyze time and space complexity, use profiling tools, and optimize algorithms and data structures for efficiency.

Javaperformancebackend developmentConcurrencycode qualitycoding best practices
Code Ape Tech Column
Written by

Code Ape Tech Column

Former Ant Group P8 engineer, pure technologist, sharing full‑stack Java, job interview and career advice through a column. Site: java-family.cn

0 followers
Reader feedback

How this landed with the community

login 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.