Backend Development 32 min read

20 Common Coding Pitfalls and How to Avoid Them

This article lists twenty typical coding mistakes that developers often encounter, such as poor formatting, unclear naming, duplicated code, long methods, excessive nesting, hard‑coded values, improper logging, and missing tests, and provides practical refactoring techniques and best‑practice recommendations to improve code quality and maintainability.

IT Services Circle
IT Services Circle
IT Services Circle
20 Common Coding Pitfalls and How to Avoid Them

The article presents twenty frequent coding problems that lead to unreadable, unmaintainable, and error‑prone software, especially in Java backend projects, and offers concrete refactoring suggestions for each.

1. Poor code formatting – Missing spaces and line breaks make code hard to read. Example of badly formatted code:

@Service
@Slf4j
public class TestService1{public void test1(){addLog("test1");if(condition1){if(condition2){if(condition3){log.info("info:{}",info);}}}}

After adding proper spaces and indentation:

@Service
@Slf4j
public class TestService1 {
    public void test1() {
        addLog("test1");
        if (condition1) {
            if (condition2) {
                if (condition3) {
                    log.info("info:{}", info);
                }
            }
        }
    }
}

2. Inconsistent or meaningless naming – Use descriptive, English‑based names and follow camelCase for variables and methods. Example of bad naming:

int a = 1;
int b = 2;
String c = "abc";
boolean b = false;

Improved naming:

int supplierCount = 1;
int purchaserCount = 2;
String userName = "abc";
boolean hasSuccess = false;

3. Duplicate code – Extract common logic into a utility class. Original duplicated methods:

private void addLog(String info) { if (log.isInfoEnabled()) { log.info("info:{}", info); } }
private void addLog(String info) { if (log.isInfoEnabled()) { log.info("info:{}", info); } }

Refactored using a shared utility:

public class LogUtil {
    private LogUtil() { throw new RuntimeException("Init failed"); }
    public static void addLog(String info) { if (log.isDebugEnabled()) { log.debug("debug:{}", info); } }
}

4. Missing comments – Add meaningful comments or use self‑explanatory code; avoid long methods without documentation.

5. Overly long methods – Split large methods into smaller, single‑purpose functions. Example:

public void run() {
    List
userList = userMapper.getAll();
    // many lines of logic ...
}

Refactored:

public void run() {
    List
userList = userMapper.getAll();
    List
updateList = filterUser(userList);
    if (CollectionUtils.isEmpty(updateList)) return;
    for (User user : updateList) { calcExpireDay(user); }
    updateUser(updateList);
    sendMq(updateList);
}
private List
filterUser(List
list) { /* ... */ }
private void calcExpireDay(User user) { /* ... */ }
private void updateUser(List
list) { /* ... */ }
private void sendMq(List
list) { /* ... */ }

6. Too many parameters – Group related parameters into a DTO or use a builder pattern.

7. Deep nesting – Apply guard clauses or use early returns to flatten the structure.

8. Excessive conditional branches – Replace long if…else chains with the Strategy pattern and a factory:

public interface IPay { void pay(); }
@Service
public class AliaPay implements IPay { @PostConstruct public void init() { PayStrategyFactory.register("aliaPay", this); } @Override public void pay() { System.out.println("===发起支付宝支付==="); } }
public class PayService3 { public void toPay(String code) { PayStrategyFactory.get(code).pay(); } }

9. Hard‑coded constants – Externalize configuration values using @Value or a configuration server.

@Value("${com.susan.maxLimit:200}")
private int maxLimit = 200;

10. Large transactions – Limit transaction scope with TransactionTemplate for only the necessary statements.

transactionTemplate.execute(status -> { userMapper.update(user); return Boolean.TRUE; });

11. Remote calls inside loops – Use batch APIs or asynchronous CompletableFuture to parallelise calls.

12. Frequent exception catching – Let a global exception handler log and format errors instead of repetitive try/catch blocks.

13. Improper logging – Guard expensive logs with if (log.isDebugEnabled()) to avoid performance impact.

14. Missing input validation – Apply Bean Validation annotations ( @NotEmpty , @Valid ) and enable @Validated on controllers.

15. Inconsistent response formats – Use a unified gateway or response wrapper to standardise API outputs.

16. Incomplete commits – Ensure code compiles and passes local tests before pushing to version control.

17. Unused code – Mark obsolete methods with @Deprecated or remove them to keep the codebase clean.

18. Changing public APIs without notice – Coordinate with teammates before renaming endpoints or parameters.

19. Using generic Map for request bodies – Define explicit DTO classes to make contracts clear and enable validation.

20. No unit tests – Write unit tests (or adopt Test‑Driven Development) to safeguard refactoring and catch regressions early.

javasoftware engineeringcode qualityrefactoringcoding best practices
IT Services Circle
Written by

IT Services Circle

Delivering cutting-edge internet insights and practical learning resources. We're a passionate and principled IT media platform.

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.