面试真实经历某节跳动大厂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;

}

```

相关推荐
IT_陈寒1 分钟前
Spring Boot 3.2性能翻倍!我仅用5个技巧就让接口响应时间从200ms降到50ms
前端·人工智能·后端
风象南12 分钟前
Spring Boot 手撸一个自助报表系统
后端
donotshow14 分钟前
Spring Boot 整合 ShedLock 处理定时任务重复
java·后端
木土雨成小小测试员14 分钟前
简单创建一个flask项目
后端·python·flask
Victor35627 分钟前
Redis(100)如何防止Redis的数据丢失?
后端
Victor35628 分钟前
Redis(101)Redis为什么是单线程的?
后端
程序员三明治1 小时前
选 Redis Stream 还是传统 MQ?队列选型全攻略(适用场景、优缺点与实践建议)
java·redis·后端·缓存·rocketmq·stream·队列
cj6341181506 小时前
【MySQL】mysqldump使用方法
java·后端
JIngJaneIL6 小时前
停车场管理|停车预约管理|基于Springboot的停车场管理系统设计与实现(源码+数据库+文档)
java·数据库·spring boot·后端·论文·毕设·停车场管理系统
雪域迷影7 小时前
Go语言中通过get请求获取api.open-meteo.com网站的天气数据
开发语言·后端·http·golang·get