路径总和
要点:dfs
java
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public boolean hasPathSum(TreeNode root, int targetSum) {
if(root == null){
return false;
}
targetSum -= root.val;
if(root.left == null && root.right ==null){
return targetSum == 0;
}
return hasPathSum(root.left, targetSum) || hasPathSum(root.right, targetSum);
}
}
求根节点到叶节点数字之和
要点:dfs,递归
java
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
//
public int sumNumbers(TreeNode root) {
return dfs(root, 0);
}
public int dfs(TreeNode root, int preSum){
if(root == null){
return 0;
}
int sum = preSum*10 + root.val;
if(root.left == null && root.right == null){
return sum;
}else{
return dfs(root.left, sum) + dfs(root.right,sum);
}
}
}
二叉树中的最大路径和
要点:dfs,定义max,记得和0比较
java
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public int max= Integer.MIN_VALUE;
public int maxPathSum(TreeNode root) {
dfs(root);
return max;
}
public int dfs(TreeNode root){
if(root == null){
return 0;
}
int left = dfs(root.left);
int right = dfs(root.right);
max = Math.max(max, root.val+left+right);
return Math.max(0,Math.max(left, right)+root.val);
}
}
二叉树的中序遍历
要点:
java
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<Integer>();
inorder(root, res);
return res;
}
public void inorder(TreeNode root, List<Integer> res) {
if (root == null) {
return;
}
inorder(root.left, res);
res.add(root.val);
inorder(root.right, res);
}
}
完全二叉树的节点个数
要点:dfs
java
class Solution {
public int countNodes(TreeNode root) {
if (root == null) return 0;
int leftHeight = getHeight(root.left);
int rightHeight = getHeight(root.right);
if (leftHeight == rightHeight) {
// 左子树是满二叉树,高度为 leftHeight
// 节点总数 = 左子树(2^leftHeight - 1) + 根节点(1) + 右子树节点数
return (1 << leftHeight) + countNodes(root.right);
} else {
// 右子树是满二叉树,高度为 rightHeight(此时 leftHeight = rightHeight + 1)
// 节点总数 = 右子树(2^rightHeight - 1) + 根节点(1) + 左子树节点数
return (1 << rightHeight) + countNodes(root.left);
}
}
// 计算以 node 为根的完全二叉树的高度(沿左子树一直走)
private int getHeight(TreeNode node) {
int height = 0;
while (node != null) {
height++;
node = node.left;
}
return height;
}
}
随机知识
四个核心维度对比 CMS 和 G1 收集器,分别是设计目标、内存划分、回收流程、停顿控制:
- 设计定位与目标不同 CMS 是老年代专用收集器,核心目标是最小化 STW 停顿 ,专注优化老年代回收,不处理新生代;G1 是一款全堆分代收集器,面向大内存、多核服务器,目标是可预测的停顿时间模型,能自定义最大停顿阈值,新生代、老年代统一由 G1 管理,兼顾低停顿与吞吐量。
- 堆内存划分方式完全不同 CMS 沿用传统分代模型:新生代 Eden/S0/S1 + 连续整块老年代,老年代是一整片连续内存;G1 把整个 Java 堆切分成多个大小相等的独立 Region,分 Eden 区、Survivor 区、Old 区、Humongous 大对象区,老年代不再连续,回收时只选择垃圾最多的 Region 清理,也就是 "标记整理 + 局部回收"。
- 回收算法与碎片问题差异 CMS 老年代使用标记 - 清除算法,不会整理内存,长期运行会产生大量内存碎片,内存不足时必须触发 Full GC 做压缩整理,STW 时间极长;G1 整体是标记整理,分阶段局部整理,每次只回收部分 Region,回收后自动压缩存活对象,几乎不会产生内存碎片,大幅减少 Full GC 触发概率。
- STW 阶段与并发阶段流程区别 CMS 回收分 6 步,其中只有初始标记、重新标记两段短暂 STW,并发标记、并发清除全程用户线程并行;但并发清除阶段会产生浮动垃圾,无法处理本轮新产生的垃圾。 G1 分为年轻代回收 Mixed 混合回收、Full GC,初始标记、重新标记、最终标记 STW,新增并发预估停顿机制,根据设置的停顿上限选择回收 Region 数量;同时 G1 有记忆集 Card Table 跟踪跨 Region 引用,解决扫描全堆开销,CMS 只卡表区分新生代到老年代引用,无跨老年代 Region 跟踪设计。
完整 JVM 运行时数据区(彩色标注分区)
- 线程私有区(每个线程独立,线程销毁释放)
- 程序计数器 PC:记录当前执行字节码行号,无 OOM
- 虚拟机栈 Java Stack:局部变量、方法栈帧,栈溢出 StackOverflowError
- 本地方法栈 Native Stack:管理 native 本地方法
- 线程共享堆 Heap(最大内存区域)
- 新生代:Eden 区、Survivor0、Survivor1(复制算法)
- 老年代 Old:长期存活对象(CMS 标记清除 / G1 标记整理)
- Humongous 区(G1 独有):超大对象直接分配老年代 Region
- 线程共享元空间 Metaspace(替代永久代,堆外直接内存)
- 存储类元信息、方法、常量、符号引用,本地内存分配
- 运行时常量池:元空间内部,存放字符串常量、字面量、符号引用
- 直接内存 Direct Buffer(堆外本地内存,不属于 JVM 运行时数据区) NIO 缓冲区使用,不受 - Xmx 限制,受系统内存限制,需要手动释放
碎碎念:后续会更新每天学习的八股和算法 题,开始准备秋招的第46天。努力连续更新100天!以后每天就按,秋招项目【java +agent】,科研,必做项目,算法,八股,锻炼身体来总结。
总结:实习干活,真是身体健康最重要,尽量还是多学点,现在老抵触学习了啊啊啊啊啊
1.算法面试150 91/150 2h
2.秋招项目,【java 项目】,
【agent 项目 】,
3.科研要跑一下,,
4.检测项目,6h
6.背八股,
7.锻炼身体,无