Skip to content

手写单例模式(双重检查锁定)。

java
public class Demo {
    
    private static Demo d;
    
    private Demo() {}
    
    public static Demo getDemo() {
        if (d == null) {
            synchronized (Demo.class) {
                if (d == null) {
                    d = new Demo();
                }
            }
        }
        return d;
    }
}

SQL题: 给定 orders (id, user_id, amount) 和 users (id, name),查询每个用户的订单总数和总金额。

sql
SELECT 
    u.id AS user_id,
    u.name AS user_name,
    COUNT(o.id) AS order_count,
    SUM(o.amount) AS total_amount
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
GROUP BY u.id, u.name
ORDER BY total_amount DESC;

二叉树的中序遍历。(递归和非递归都要会)。

递归

java
import java.util.ArrayList;
import java.util.List;

// 二叉树节点定义
class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int x) { val = x; }
}

public class BinaryTreeInorderTraversal {
    
    /**
     * 递归实现中序遍历
     * 遍历顺序:左子树 -> 根节点 -> 右子树
     */
    public List<Integer> inorderTraversalRecursive(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        inorderHelper(root, result);
        return result;
    }
    
    private void inorderHelper(TreeNode node, List<Integer> result) {
        if (node == null) {
            return;
        }
        
        // 1. 遍历左子树
        inorderHelper(node.left, result);
        // 2. 访问根节点
        result.add(node.val);
        // 3. 遍历右子树
        inorderHelper(node.right, result);
    }
}

非递归

java
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

public class BinaryTreeInorderTraversal {
    
    /**
     * 非递归实现中序遍历(使用栈)
     * 思路:
     * 1. 从根节点开始,将所有左子节点入栈
     * 2. 弹出栈顶元素并访问
     * 3. 如果有右子树,对右子树重复步骤1
     */
    public List<Integer> inorderTraversalIterative(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        Stack<TreeNode> stack = new Stack<>();
        TreeNode current = root;
        
        while (current != null || !stack.isEmpty()) {
            // 将当前节点及其所有左子节点入栈
            while (current != null) {
                stack.push(current);
                current = current.left;
            }
            
            // 弹出栈顶节点并访问
            current = stack.pop();
            result.add(current.val);
            
            // 转向右子树
            current = current.right;
        }
        
        return result;
    }
}

反转链表。

java
// 链表节点类
class ListNode {
    int val;
    ListNode next;

    ListNode(int val) {
        this.val = val;
    }

    ListNode(int val, ListNode next) {
        this.val = val;
        this.next = next;
    }
}


public class ReverseLinkedList {
    
    /**
     * 迭代法反转链表
     * 思路:使用三个指针,逐个反转节点指向
     * 时间复杂度:O(n),空间复杂度:O(1)
     */
    public ListNode reverseListIterative(ListNode head) {
        ListNode prev = null;    // 前一个节点
        ListNode current = head; // 当前节点
        
        while (current != null) {
            ListNode nextTemp = current.next; // 保存下一个节点
            current.next = prev;  // 反转指针
            prev = current;       // 移动prev
            current = nextTemp;   // 移动current
        }
        
        return prev; // 返回新的头节点
    }
}

有效的括号。(使用栈)。

java
import java.util.Stack;
import java.util.HashMap;
import java.util.Map;

public class ValidParentheses {
    /**
     * 另一种实现方式,不使用哈希表
     */
    public boolean isValid2(String s) {
        if (s.length() % 2 != 0) {
            return false;
        }
        
        Stack<Character> stack = new Stack<>();
        
        for (char c : s.toCharArray()) {
            if (c == '(' || c == '{' || c == '[') {
                stack.push(c);
            } else {
                if (stack.isEmpty()) {
                    return false;
                }
                
                char top = stack.pop();
                if ((c == ')' && top != '(') ||
                    (c == '}' && top != '{') ||
                    (c == ']' && top != '[')) {
                    return false;
                }
            }
        }
        
        return stack.isEmpty();
    }
    
    /**
     * 测试方法
     */
    public static void main(String[] args) {
        ValidParentheses solution = new ValidParentheses();
        
        // 测试用例
        String[] testCases = {
            "()",          // true
            "()[]{}",      // true  
            "(]",          // false
            "([)]",        // false
            "{[]}",        // true
            "]",           // false
            "",            // true
            "((()))",      // true
            "([{}])",      // true
            "((("          // false
        };
        
        boolean[] expected = {
            true, true, false, false, true, false, true, true, true, false
        };
        
        System.out.println("测试结果:");
        System.out.println("字符串\t\t预期\t实际\t结果");
        System.out.println("----------------------------------------");
        
        for (int i = 0; i < testCases.length; i++) {
            boolean result = solution.isValid(testCases[i]);
            String status = result == expected[i] ? "✓" : "✗";
            System.out.printf("%-10s\t%-5s\t%-5s\t%s\n", 
                testCases[i], expected[i], result, status);
        }
    }
}

快速排序 或 归并排序。

两个线程交替打印1-100。(考察 wait()/notify() 或 Lock/Condition)。

合并两个有序数组。

java
public class MergeSortedArray {
    
    /**
     * 使用额外空间合并两个有序数组
     * 时间复杂度:O(m+n)
     * 空间复杂度:O(m+n)
     */
    public void mergeWithExtraSpace(int[] nums1, int m, int[] nums2, int n) {
        int[] result = new int[m + n];
        int i = 0, j = 0, k = 0;
        
        // 合并两个有序数组
        while (i < m && j < n) {
            if (nums1[i] <= nums2[j]) {
                result[k++] = nums1[i++];
            } else {
                result[k++] = nums2[j++];
            }
        }
        
        // 处理剩余元素
        while (i < m) {
            result[k++] = nums1[i++];
        }
        while (j < n) {
            result[k++] = nums2[j++];
        }
        
        // 将结果复制回 nums1
        System.arraycopy(result, 0, nums1, 0, m + n);
    }
}

最长无重复字符的子串。(滑动窗口)。

页脚:版权前显示的信息