面试真实经历某节跳动大厂Java和算法问答以及答案总结(一)

Java面试问题与解答

  1. 常见的GC回收器

    • Serial GC : 适合单线程环境,暂停时间较长。

    • Parallel GC : 多线程垃圾回收,适合多核处理器,停顿时间较短。

    • CMS (Concurrent Mark-Sweep) : 适合响应时间要求高的应用,通过多线程并发清除垃圾。

    • G1 GC : 适用于大内存系统,目标是尽量减少GC停顿时间,分区回收。​编辑

  2. SpringMVC的请求过程

    • 流程: 用户发起请求 → 前端控制器(DispatcherServlet)接收请求 → HandlerMapping根据请求路径找到对应的控制器 → Controller执行业务逻辑 → 返回ModelAndView → 视图解析器返回视图 → 渲染页面返回给用户。

​编辑

算法面试问题与解答​编辑

  1. 每K个节点翻转链表(链表k个一旋转)

    • 思路: 每次遍历K个节点进行翻转,翻转时注意更新连接的指针。

    • 解法: 使用一个指针来跟踪当前链表的位置,每次翻转K个节点,注意边界条件(如剩余节点数小于K):
      java public ListNode reverseKGroup(ListNode head, int k) { if (head == null || k == 1) return head; ListNode dummy = new ListNode(0); dummy.next = head; ListNode prev = dummy, curr = head, next = null; int count = 0; while (curr != null) { count++; curr = curr.next; } curr = dummy.next; while (count >= k) { curr = prev.next; next = curr.next; for (int i = 1; i < k; i++) { curr.next = next.next; next.next = prev.next; prev.next = next; next = curr.next; } prev = curr; count -= k; } return dummy.next; }

  2. 二叉搜索树转链表

    • 思路: 中序遍历二叉搜索树,将遍历结果按顺序链接为链表。

    • 解法: 使用递归或迭代的方式进行中序遍历并修改节点指针:
      java public TreeNode flatten(TreeNode root) { if (root == null) return null; flatten(root.left); flatten(root.right); TreeNode tmp = root.right; root.right = root.left; root.left = null; while (root.right != null) root = root.right; root.right = tmp; return root; }

  3. 负载均衡算法

    • 思路: 负载均衡算法有很多种,常见的有轮询(Round Robin)、加权轮询(Weighted Round Robin)、一致性哈希等。

    • 解法: 一致性哈希(Consistent Hashing)是解决分布式系统中负载均衡和节点增减的问题。​编辑

    ```java

    public class ConsistentHashing {

    private final TreeMap<Integer, String> circle = new TreeMap<>();

    private final int virtualNodeCount = 100;

public void addNode(String node) {

for (int i = 0; i < virtualNodeCount; i++) {

circle.put((node + i).hashCode(), node);

}

}

public String getNode(String key) {

int hash = key.hashCode();

if (!circle.containsKey(hash)) {

hash = circle.ceilingKey(hash);

}

return circle.get(hash);

}

}

```

  1. 排序算法哪些是稳定的

    • 稳定排序: 排序后,相等元素的顺序不变。常见的稳定排序包括:

    • 冒泡排序(Bubble Sort)

    • 插入排序(Insertion Sort)

    • 归并排序(Merge Sort)

    • 稳定的选择排序

    • 快速排序(Quick Sort)一般不稳定。

  2. 二叉树求和

    • 思路: 递归遍历二叉树并累加每个节点的值。
      java public int sumOfTree(TreeNode root) { if (root == null) return 0; return root.val + sumOfTree(root.left) + sumOfTree(root.right); }
  3. 序列化和反序列化二叉树

    • 思路: 序列化将二叉树转换为字符串,反序列化则将字符串转换回二叉树。

    • 解法: 使用前序遍历进行序列化:

    ```java

    public class Codec {

    public String serialize(TreeNode root) {

    StringBuilder sb = new StringBuilder();

    serializeHelper(root, sb);

    return sb.toString();

    }

    private void serializeHelper(TreeNode node, StringBuilder sb) {

    if (node == null) {

    sb.append("null,");

    return;

    }

    sb.append(node.val).append(",");

    serializeHelper(node.left, sb);

    serializeHelper(node.right, sb);

    }

public TreeNode deserialize(String data) {

String[] nodes = data.split(",");

Queue queue = new LinkedList<>(Arrays.asList(nodes));

return deserializeHelper(queue);

}

private TreeNode deserializeHelper(Queue queue) {

String val = queue.poll();

if (val.equals("null")) return null;

TreeNode node = new TreeNode(Integer.parseInt(val));

node.left = deserializeHelper(queue);

node.right = deserializeHelper(queue);

return node;

}

}

```

  1. 如何判断一颗树是否是完全二叉树

    • 思路: 完全二叉树的特点是:除最底层外,其他每一层都必须完全填充,且最底层节点从左到右排列。

    • 解法: 使用层序遍历,判断是否遇到空节点后还有非空节点。
      java public boolean isCompleteTree(TreeNode root) { if (root == null) return true; Queue<TreeNode> queue = new LinkedList<>(); queue.offer(root); boolean flag = false; while (!queue.isEmpty()) { TreeNode node = queue.poll(); if (node == null) flag = true; else { if (flag) return false; queue.offer(node.left); queue.offer(node.right); } } return true; }

  2. 求数组的极值点

    • 思路: 极值点是数组中比相邻两个元素大的点(局部最大)或比相邻两个元素小的点(局部最小)。

    • 解法: 使用遍历的方法找出极值点:
      java public List<Integer> findLocalExtrema(int[] nums) { List<Integer> extrema = new ArrayList<>(); for (int i = 1; i < nums.length - 1; i++) { if ((nums[i] > nums[i - 1] && nums[i] > nums[i + 1]) || (nums[i] < nums[i - 1] && nums[i] < nums[i + 1])) { extrema.add(nums[i]); } } return extrema; }

  3. 最大连续子序列

    • 思路: 采用动态规划的方法来求解最大连续子序列的和。

    • 解法:
      java public int maxSubArray(int[] nums) { int maxSum = nums[0], currentSum = nums[0]; for (int i = 1; i < nums.length; i++) { currentSum = Math.max(nums[i], currentSum + nums[i]); maxSum = Math.max(maxSum, currentSum); } return maxSum; }

  4. 回文链表

    • 思路: 使用快慢指针找中点,然后反转后半部分进行比较。

    • 解法:

    ```java

    public boolean isPalindrome(ListNode head) {

    if (head == null || head.next == null) return true;

    ListNode slow = head, fast = head;

    while (fast != null && fast.next != null) {

    slow = slow.next;

    fast = fast.next.next;

    }

    ListNode secondHalf = reverse(slow);

    ListNode firstHalf = head;

    while (secondHalf != null) {

    if (firstHalf.val != secondHalf.val) return false;

    firstHalf = firstHalf.next;

    secondHalf = secondHalf.next;

    }

    return true;

    }

private ListNode reverse(ListNode head) {

ListNode prev = null, curr = head;

while (curr != null) {

ListNode next = curr.next;

curr.next = prev;

prev = curr;

curr = next;

}

return prev;

}

```

相关推荐
上进小菜猪4 分钟前
当时序数据不再“只是时间”:金仓数据库如何在复杂场景中拉开与 InfluxDB 的差距
后端
盖世英雄酱581361 小时前
springboot 项目 从jdk 8 升级到jdk21 会面临哪些问题
java·后端
程序猿DD2 小时前
JUnit 5 中的 @ClassTemplate 实战指南
java·后端
周杰伦_Jay2 小时前
【大模型数据标注】核心技术与优秀开源框架
人工智能·机器学习·eureka·开源·github
Victor3562 小时前
Netty(14)如何处理Netty中的异常和错误?
后端
铭哥的编程日记2 小时前
后端面试通关笔记:从真题到思路(五)
面试·职场和发展
Victor3562 小时前
Netty(13)Netty中的事件和回调机制
后端
码事漫谈3 小时前
VS Code 1.107 更新:多智能体协同与开发体验升级
后端
码事漫谈3 小时前
从概念开始开始C++管道编程
后端