1. The Hook (The "Byte-Sized" Intro)
- In a Nutshell: Static analysis = automated code review (SonarQube, Checkstyle, PMD, SpotBugs). Code reviews = peer feedback (small changes, timely, constructive).
- Logging: SLF4J facade + Logback, levels (TRACE/DEBUG/INFO/WARN/ERROR), structured logging.
- Metrics: Cyclomatic complexity (ā¤10), code duplication (<5%), coverage (ā„80%).
- CI/CD: Automate builds, tests, quality checks.
- Golden rule: Tools catch bugs early, humans catch design issues!
Think of car quality control. Static analysis = automated sensors (detect defects). Code review = human inspector (design, safety issues). Logging = flight recorder (diagnose problems). CI/CD = assembly line quality checks (every step). Metrics = performance indicators!
2. Conceptual Clarity (The "Simple" Tier)
š” The Analogy
- Static Analysis: Spell checker (finds errors automatically)
- Code Review: Editor feedback (improves quality)
- Logging: Security cameras (record what happened)
- CI/CD: Automated factory (build, test, deploy)
3. Technical Mastery (The "Deep Dive")
java
// ===========================================
// 1. STATIC ANALYSIS TOOLS
// ===========================================
// Checkstyle (coding standards)
// checkstyle.xml
<module name="LineLength">
<property name="max" value="120"/>
</module>
<module name="MethodLength">
<property name="max" value="50"/>
</module>
// PMD (potential bugs, dead code)
// pmd.xml
<rule ref="category/java/bestpractices.xml/UnusedPrivateMethod"/>
<rule ref="category/java/errorprone.xml/AvoidBranchingStatementAsLastInLoop"/>
// ā PMD will catch:
void processData() {
for (Item item : items) {
if (item.isValid()) {
continue; // ā Last statement in loop (redundant)
}
}
}
// SpotBugs (bug patterns)
// Catches:
if (s == "test") { } // ā String comparison with ==
Date d = new Date(2024, 1, 1); // ā Deprecated constructor
// SonarQube (comprehensive)
// Measures: Bugs, Vulnerabilities, Code Smells, Coverage, Duplication
// Quality Gates: Block merge if quality drops
// ===========================================
// 2. CODE REVIEW BEST PRACTICES
// ===========================================
// ā
GOOD: Small PR (200-400 lines)
// Easy to review, quick feedback
// ā BAD: Large PR (2000+ lines)
// Takes hours to review, likely to miss issues
// Review checklist:
// 1. Does it work? (tests pass)
// 2. Is it readable?
// 3. Is it maintainable?
// 4. Are there tests?
// 5. Is naming clear?
// 6. Any security issues?
// ā
GOOD: Constructive feedback
// "Consider using Optional here to avoid null checks"
// ā BAD: Personal criticism
// "Why did you write such terrible code?"
// ===========================================
// 3. LOGGING BEST PRACTICES
// ===========================================
// ā
Use SLF4J facade
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
class UserService {
private static final Logger logger = LoggerFactory.getLogger(UserService.class);
void createUser(User user) {
logger.debug("Creating user: {}", user.getId());
try {
repository.save(user);
logger.info("User created successfully: {}", user.getId());
} catch (Exception e) {
logger.error("Failed to create user: {}", user.getId(), e);
throw e;
}
}
}
// Log levels:
logger.trace("Very detailed (rarely used)");
logger.debug("Debugging info (dev environment)");
logger.info("Important events (user actions)");
logger.warn("Warnings (potential issues)");
logger.error("Errors (need attention)");
// ā BAD: Wrong log level
logger.info("NullPointerException occurred!"); // ā Should be ERROR!
logger.error("User logged in"); // ā Should be INFO!
// ā BAD: String concatenation (eager evaluation)
logger.debug("Processing: " + expensiveOperation());
// ā Calls expensiveOperation() even if DEBUG disabled!
// ā
GOOD: Parameterized (lazy evaluation)
logger.debug("Processing: {}", expensiveOperation());
// ā
Only calls if DEBUG enabled!
// ā BAD: Logging sensitive data
logger.info("User password: {}", password); // ā NEVER!
logger.info("Credit card: {}", creditCard); // ā NEVER!
// ā
GOOD: Structured logging (JSON)
logger.info("user_action",
kv("userId", userId),
kv("action", "login"),
kv("timestamp", Instant.now()));
// Output: {"userId":123,"action":"login","timestamp":"2024-01-01T00:00:00Z"}
// ===========================================
// 4. CODE QUALITY METRICS
// ===========================================
// Cyclomatic Complexity (number of paths through code)
// ā
GOOD: Complexity = 2
int max(int a, int b) {
return (a > b) ? a : b; // 2 paths
}
// ā BAD: Complexity = 10 (too high!)
void process(Order order) {
if (order.isPremium()) {
if (order.getTotal() > 1000) {
if (order.hasDiscount()) {
if (order.getCustomer().isActive()) {
// ...
}
}
}
}
}
// Rule: Keep complexity ⤠10
// Code Duplication
// ā BAD: Duplicated code
void processOrder() {
validate();
calculate();
save();
}
void processReturn() {
validate(); // ā Duplicated!
calculate(); // ā Duplicated!
refund();
}
// ā
GOOD: Extract common logic
void processOrder() {
commonProcessing();
save();
}
void processReturn() {
commonProcessing();
refund();
}
void commonProcessing() {
validate();
calculate();
}
// ===========================================
// 5. CI/CD PIPELINE
// ===========================================
// Jenkins / GitHub Actions pipeline
stages:
- name: Build
run: mvn clean compile
- name: Test
run: mvn test
- name: Quality Check
run: |
mvn checkstyle:check
mvn pmd:check
mvn spotbugs:check
- name: Coverage
run: mvn jacoco:report
fail_if: coverage < 80%
- name: SonarQube
run: mvn sonar:sonar
fail_if: quality_gate = FAILED
// ===========================================
// 6. IDE INSPECTIONS
// ===========================================
// IntelliJ IDEA warnings
// ā ļø Variable 'x' is never used
int x = 10; // Remove unused variable
// ā ļø Method can be static
void helper() { } // No instance fields used
// ā ļø Condition is always true
if (list.size() >= 0) { } // Size never negative!
// Enable inspections: File ā Settings ā Editor ā Inspections5. The Comparison & Decision Layer
| Tool | Purpose | When to Use |
|---|---|---|
| Checkstyle | Coding conventions | Always (enforce style) |
| PMD | Potential bugs, dead code | CI pipeline |
| SpotBugs | Bug patterns | CI pipeline |
| SonarQube | Comprehensive quality | CI pipeline, pre-merge |
6. The "Interview Corner" (The Edge)
The "Killer" Interview Question: "What makes a good code review?" Answer:
Good code review:
- Small changes (200-400 lines)
- Timely (reviewed within 24 hours)
- Constructive (suggest improvements, not criticize)
- Focus on code, not person
- Check: correctness, tests, readability, security
Review checklist:
text
ā
Does it work? (tests pass)
ā
Are there tests for new code?
ā
Is naming clear?
ā
Is it maintainable?
ā
Any security issues?
ā
Follows conventions?
ā
No code duplication?Pro-Tips:
- Automated quality gates (fail builds on quality drop):
xml
<!-- Maven: Fail build if coverage < 80% -->
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<configuration>
<rules>
<rule>
<element>BUNDLE</element>
<limits>
<limit>
<counter>LINE</counter>
<value>COVEREDRATIO</value>
<minimum>0.80</minimum>
</limit>
</limits>
</rule>
</rules>
</configuration>
</plugin>- Pre-commit hooks (run checks before committing):
bash
# .git/hooks/pre-commit
#!/bin/bash
mvn checkstyle:check
if [ $? -ne 0 ]; then
echo "Checkstyle failed! Fix issues before committing."
exit 1
fi