- 博客(95)
- 收藏
- 关注
原创 文献管理工具 Zotero 的使用
在 Zotero 中文社区的插件商店安装 Add-on Market for Zotero 插件,即可在 Zotero 软件内部安装别的插件。一个文献条目并不只属于一个分类,可以通过拖动条目到分类,把条目复制到别的分类。如果按住 Command 再移动会“剪切”。在 Add-on Market for Zotero 插件中,找到 Jasminum 并安装。浏览器保存文献到 Zotera:Command + Shift + S。在“设置-导出”中添加该引用格式。在“设置-引用”中,点击。
2025-12-16 11:55:51
449
原创 PopClip 使用攻略
设置谷歌搜索:https://www.google.com.hk/search?按住 Option 点击打开链接,将会把链接作为列表复制到剪切板,而不是打开它们。选中文本后,按住 Shift 点击复制,即可去除文本中所有格式。选中任意文本后,点击 🔍 图标,即可打开搜索引擎搜索选中文本。如:官网:https://www.popclip.app/选中包含链接的文本,点击 🔗 图标,即可自动打开链接。粘贴:需要剪贴板上有文本,并且文本字段可编辑。链接,点击打开链接即可在浏览器将这些链接。复制:需要选中文本。
2025-12-10 14:07:19
459
原创 代码随想录算法训练营第 61 天 | Floyd 算法精讲、A* 算法精讲(A star 算法)
DFSBFSPrim:稠密图,时间复杂度为 O(V^2)。Kruskal:稀疏图,时间复杂度为 O(E * logE)。BFS:无向图且权值都为 1,相当于无权图。Dijstra:有向图、单源、权值正数。朴素法:稠密图,时间复杂度为 O(V^2)。堆优化法:稀疏图,时间复杂度为 O(E * logE)。Bellman_ford:有向图、单源点、权值可以为负数 或者 检测负权环路 或者有限节点最短路径。普通:稠密图,时间复杂度为 O(V * E)。
2025-12-09 19:38:34
833
原创 八股训练营第 41 天 | 描述一下 Spring MVC 的执行流程?Spring Boot Starter 有什么用?Spring Boot 的常用注解?
Spring Boot Starter 可以简化和加速项目的配置和依赖管理。
2025-12-08 23:39:21
402
原创 代码随想录算法训练营第 60 天 | Bellman_ford 队列优化算法(又名 SPFA)、Bellman_ford 之判断负权回路、Bellman_ford 之单源有限最短路
Dijkstra 更像是贪心算法;Bellman_ford 更像是动态规划算法,所以能找负权值的和限制途经节点个数的。Dijkstra 和 Bellman_ford 的队列优化算法有点像。前者是找最小距离的节点,后者是找相连并更新的节点。前者没有用到队列,后者用到队列。二者都是找到节点后就更新节点到源点的距离。二者都要设置 minDist 数组,并把 minDist[start] = 0。
2025-12-08 15:21:58
627
原创 八股训练营第 39 天 | Bean 的作用域?Bean 的生命周期?Spring 循环依赖是怎么解决的?Spring 中用到了那些设计模式?
循环依赖是指两个或者两个以上的 Bean 互相持有对方,最终形成闭环。比如 Bean A 依赖于 Bean B,Bean B 又依赖于 Bean A。Spring IoC 容器的对象称之为 Bean。① 一级缓存:单例池,缓存已经经历了完整的生命周期,已经初始化完成的 Bean 对象。③ 三级缓存:缓存的是 ObjectFactory,表示对象工厂,用来创建某个对象的。② 二级缓存:缓存早期的 Bean 对象(生命周期还没走完)
2025-12-07 23:38:51
712
原创 八股训练营第 38 天 | 类加载机制介绍一下?介绍一下双亲委派机制?说一说你对 Spring AOP 的了解?说一说你对 Spring 中 IoC 的理解?
加载:类加载器负责去查找\的字节码,将其加载到内存中。连接:分为 3 个子阶段。验证:验证加载的类的格式是否正确,并且不包含不安全的构造。准备:在内存中为类的静态变量分配空间,并且初始化。数值类型初始化为 0,引用类型初始化为 null解析:将类、方法、接口、字段的符号引用解析为直接引用,即内存地址。初始化:执行类的静态初始化代码。包括静态变量的赋值和静态代码块的执行。静态初始化在类的首次使用时进行,包括创建实例、访问静态字段或调用静态方法。
2025-12-06 22:12:50
355
原创 代码随想录算法训练营第 58 天 | Dijkstra(堆优化版)精讲、Bellman_ford 算法精讲
对所有边松弛 n - 1 次。(因为源点通过 n - 1 条边肯定可以到达终点。对题目给出的 n 条边依次松弛,总共松弛 n - 1 轮。松弛 n - 1 次:将所有点到源点的最短距离都更新完毕。松弛一次:从源点出发,与源点一条边相连的节点的最短距离。松弛两次:从源点出发,与源点两条边相连的节点的最短距离。可以解决带负权值的问题。但是不能出现负权值环路。重点:minDist[1] 要初始化为 0。堆优化版时间复杂度:O(E * logE)朴素版时间复杂度:O(V^2)时间复杂度:O(V * E)
2025-12-06 14:07:20
293
原创 代码随想录算法训练营第 57 天 | 拓扑排序精讲、Dijkstra(朴素版)精讲
不用在重新遍历一遍 inDegree 数组,不然还得区分哪些入度为 0 的节点之前已经放到队列中了。不仅是求源点到终点的最短距离,而且它把源点到所有节点的最短距离都求出来了。用一维数组 int[] parent。指向为 parent[i] -> i。一个是从最小生成树出发,一个是从源点出发。结果集个数小于 n,成环,输出 -1。注意本题节点从 0 到 n - 1。邻接表,这样不用判 null。注意本体节点从 1 到 n。拓展:输出最短路径的每条边。
2025-12-05 17:06:02
560
原创 八股训练营第 37 天 | Java 内存区域有哪些部分?介绍一下什么是强引用、软引用、弱引用、虚引用?有哪些垃圾回收算法?有哪些垃圾回收器?
强引用:强引用是最常见、默认的引用类型。强引用的对象无论何时都不会被垃圾回收。软引用:软引用用于描述那些可能有用但非必须的对象。如果一个对象只有软引用指向它。那么当内存不足时。垃圾回收器会尝试回收这些对象。软引用通常用于实现缓存,可以在内存不足时释放缓存中的对象。弱引用:弱引用的生命周期比软引用更短暂。如果一个对象只有弱引用指向它。那么下次垃圾回收时,这些对象一定会被回收。弱引用通常用于实现对象缓存,但不希望缓存的对象影响垃圾回收的情况。虚引用:虚引用是 Java 中最弱的引用类型。
2025-12-04 23:47:57
453
原创 代码随想录算法训练营第 56 天 | 53. 寻宝(Prim + Kruskal)
可以用 HashMap 或一维数组 int[] parent。不能用一维数组 int[] parent,因为可能会出现如下情况:1 同时连 2 和 3,会被覆盖。由于 Kruskal 算法直接是针对边进行遍历的。这里直接用 List<int[]> 来保存边。遍历 n - 1 次,因为每次循环找到了一条边,只要找到 n - 1 条边即可。不能用 List<int[]>,因为会添加很多次,需要覆盖之前的添加。节点从 1 到 n。拓展:输出最小生成树的每条边。拓展:输出最小生成树的每条边。适合稠密图,点少边多。
2025-12-04 16:20:29
367
原创 八股训练营第 36 天 | 为什么要有线程池?说一说线程池有哪些常用参数?BIO、NIO、AIO 的区别?
AIO 是真正的异步 I/O,操作系统完成后通知应用线程,性能最好,但实际生产应用较少。NIO 采用多路复用,一个线程可以处理多个连接,适合高并发,Netty 基于此实现;BIO 是阻塞 I/O,一个连接一个线程,适合连接数少的场景;
2025-12-03 23:00:03
189
原创 代码随想录算法训练营第 55 天 | 108. 冗余连接、109. 冗余连接II
每添加一条边,就判断这两个节点是否在统一集合。如果是,说明它是冗余的最后一条边,立即返回;否则把这两个节点添加到一个集合中。拓展:树是一种无向无环图,n 个节点只需要 n - 1 条边就能完全联通。只有 1 条冗余边。
2025-12-03 14:56:44
275
原创 八股训练营第 35 天 | volatile 关键字的作用有那些?volatile 与synchronized 的对比?JDK8 有哪些新特性?
volatile 会发出 lock 指令对当前 cpu 缓存进行上锁,这样就会让当前 cpu 独占缓存,让其他 cpu 的此缓存段失效,因为加了 lock,接下来操作的指令会独占数据写回主存和缓存,其他 cpu 因为缓存失效就会去主存读数据重新写入缓存,就保证了不同 cpu 之间的缓存一致性。volatile 变量禁止指令重排序。针对 volatile 修饰的变量,在读写操作指令前后会插入内存屏障,指令重排序时不能把后面的指令重排序到内存屏障.volatile 关键字确保变量在多个线程的可见性。
2025-12-02 23:06:55
647
原创 八股训练营第 34 天 | synchronized 和 Lock 的区别是什么?synchronized 和 ReentrantLock 的区别是什么?
2025-12-01 22:30:29
744
原创 代码随想录算法训练营第 53 天 | 106. 岛屿的周长、110. 字符串接龙、105. 有向图的完全联通
无权图求最短路径,不需要迪杰特斯拉算法,只需要 dfs 或 bfs 即可。抽象图用 graph,二维图用 grid。邻接矩阵用graph[][],邻接表用。// 节点数量// 边数量// 节点数量// 边数量i < n + 1;i++) { // i 必须从 0 开始,创建 n + 1 个空列表。
2025-12-01 16:54:54
696
原创 八股训练营第 32 天 | 你知道 Java 中有哪些锁吗?说一说你对 synchronized 的理解?
引入了偏向锁、轻量级锁和重量级锁。当一个锁对象第一次被某个线程进入时,这个时候由于没有发送锁竞争,此时是偏向锁,线程可以直接获得锁对象。当出现别的线程也要竞争这个锁时,就会升级成轻量级锁。synchronized 的本质是获取某个对象的监视器锁(monitor lock)。线程要进入同步代码块,必须先获得指定的锁。锁是属于对象的,而不是属于代码的。当修饰代码块时,只有代码块被锁定。当修饰方法时,锁定的是 this 实例对象。当修饰代码块时,需要显示地指定锁定的对象。当修饰的是静态方法时,锁定是整个类对象。
2025-12-01 00:40:15
142
原创 代码随想录算法训练营第 51 天 | 101. 孤岛的总面积、102. 沉没孤岛、103. 高山流水、104. 建造最大岛屿
遍历第一行、最后一行、第一列、最后一列。遇到陆地就将它相邻的所有陆地都标记为 0(省去 visited 数组)。最后统计 grid 有多少个 1。被标记为 true 的节点不会再次访问。必须先把 1 变为 0,再把 2 变为 1,否则会覆盖导致数组全为 0。暴力方法:每个海洋都尝试变成陆地,然后统计最大岛屿面积。代码以 dfs 为例:dfs 很简单,主函数有点复杂。暴力时间复杂度:O(n * m * n * m)注意:题目要求的是孤岛总面积而不是孤岛个数。时间复杂度:O(n * m * n * m)
2025-11-30 23:40:14
1028
原创 八股训练营第 31 天 | Java 创建线程有哪几种方式?线程start和run的区别?
因此,虽然可以直接调用 run 方法,但这并不会创建一个新线程,而是在当前线程中执行。要想实现多线程执行,则必须调用 start 方法开启一个新线程。
2025-11-29 23:54:06
134
原创 代码随想录算法训练营第 50 天 | 99. 岛屿数量、100. 岛屿的最大面积
遍历每个地方,如果该处为陆地,且未访问过。将结果加 1.并将该处所连的陆地全部标记为已访问。dfs ——先格子赋值为 true,再进入 dfs 函数。(dfs 隐式终止条件)dfs ——判断完终止条件后,再赋值为 true。(dfs 显式终止条件)重点:队列刚一放进去元素,visited 数组就要立马标记为 true。dfs 或 bfs 时,可以只搜右下的格子。
2025-11-28 23:51:58
667
原创 代码随想录算法训练营第 49 天 | 98. 可达路径 / 797. 所有可能的路径
注意:有向无环图不需要 visited 数组。需要提前在 path 中把节点 1 加上。,在 Java 中为锯齿数组。(因为节点从 1 到 n)LeetCode 模式。
2025-11-28 00:07:54
213
原创 八股训练营第 29 天 | HashMap 为什么是线程不安全的? 如何实现线程安全?concurrentHashMap 如何保证线程安全?HashMap和ConcurrentHashMap的区别?
HashMap 内部的 get、put、自动扩容方法都不是原子性的。但有多个读写线程并发执行的情况下,就可能会出现数据不一致或者抛出异常。比如出现元素丢失、元素覆盖等情况。元素丢失:一个读线程和一个写线程并发运行。读线程已经确定了元素在数值中的位置,正要提取元素。这时写线程运行了,它往 HashMap 中插入了一个元素导致 HashMap 扩容。这导致读线程原本要读的元素在数组中的位置恰好因为扩容转移到了一个新的位置。这时读线程运行,它还读它之前计算出的那个位置。导致读到的是 null。
2025-11-27 00:01:40
396
原创 代码随想录算法训练营第 48 天 | 42. 接雨水、84. 柱状图中最大的矩形
创建两个数组,分别表示当前柱子左边最高柱子(包括自身)的高度和右边最高柱子(包括自身)的高度。根据木桶效应,某个位置能装的水的高度为左边最高柱子高度和右边最高柱子高度的最小值。但是知道它右边某个柱子的右边最高柱子高度是大于上面已经求出来的左边最高柱子的高度。左边最高柱子高度 = 它左边柱子的左边最高柱子的高度和它本身高度,取最大值。高度为右边更高的柱子和左边更高的柱子的最小值,还要减去当前柱子的高度!某个位置,已经知道它左边最高柱子的高度,它右边最高柱子的高度还没求。空间复杂度:O(n)
2025-11-26 22:00:21
1440
原创 八股训练营第 28 天 | HashMap 的底层实现是什么?解决 Hash 冲突的方法有哪些?HashMap 是如何解决 Hash 冲突的?HashMap 的 put 方法流程?HashMap 扩容
当向 HashMap 中 put 元素时,会利用 key 的 hashCode 计算出当前元素在数组中的下标。然后将元素放入数组对应的下标位置中。在存储时,如果数组该位置已经有元素,则判断 key 是否相同。如果 key 相同,则覆盖 value。当从 HashMap 中获取元素时,直接去数组中找 key 的哈希值对应的下标。再进一步判断 key 是否相同,从而获取对应的值。HashMap 的底层实现是哈希表。在 jdk 1.8 之前是数组 + 链表,jdk 1.8 之后是数组 + 链表 + 红黑树。
2025-11-26 00:38:09
380
原创 代码随想录算法训练营第 47 天 | 739. 每日温度、496. 下一个更大元素 I、503. 下一个更大元素 II
单调栈的核心是放索引,而不是具体的值。(因为直到索引可以去数组中找对应的值;而知道值不能得到索引,且值可能重复。如果是求右边第一个大的:从栈顶到栈底递增如果是求右边第一个小的:从栈顶到栈底递减单调栈其实有正序遍历和倒序遍历,暂时只掌握正序遍历就可以了。单调栈模板while 循环要判断栈非空while 结束后不要忘记 pushi < n;stack.isEmpty() && nums[i] > nums[stack.peek()]) { // 必须判断栈非空。
2025-11-25 23:04:13
433
原创 八股训练营第 27 天 | Java的集合类有哪些,那些是线程安全的,那些是线程不安全的?ArrayList 和 Array 有什么区别、ArrayList 和 LinkedList 的区别是什么?
Java 的集合类由 Collections 和 Map 这两个接口派生而出,Collections 接口又派生出了 List、Set、Queue 这三个接口。Java 所有的集合类都是 List、Set、Queue、Map 这四个接口的实现类。线程不安全的集合有:ArrayList、LinkedList、HashSet、TreeSet、HashMap、TreeMap 等。以上就是我对这个问题的理解。
2025-11-24 23:41:18
402
原创 代码随想录算法训练营第 46 天 | 647. 回文子串、516. 最长回文子序列
因为只需对矩阵右上三角便利,所以从左上到右下的对角线需初始化。:[i, j] 字符串的最长回文子序列长度。:[i, j](左闭右闭)的字符串是不是回文子串。遍历顺序:从下到上,从左到右(假设 j >= i)(因为根据递推公式,是从左下角往右上角推导的。初始化:全部初始化为 false。上题的子串:要求必须连续。前两种情况可以合并。子序列:可以不连续。从下到上,从左到右。
2025-11-24 20:59:01
169
原创 iTerm2 + Oh My Zsh + tmux 搭建好用终端
窗口左右分割:command + D上下分割:command + shift + D全屏切换:command + enter在最近使用的两个标签页之间切换:command + [ 和 command + ]切换到指定位置的屏幕:command + alt + 方向键文本编辑到行首:control + A到行尾:control + E清除当前行:control + U清屏:command + R(等于 control + L)上一条命令:ctrl + P。
2025-11-24 13:02:28
1720
原创 代码随想录算法训练营第 44 天 | 115. 不同的子序列、583. 两个字符串的删除操作、72. 编辑距离
评论区笔记评论区笔记2一般如果要是求的子数组是连续的,或者即使不是连续的,要求单调这种,都是需要定义 dp 是以 nums[i] 为结尾,最终结果是 max(dp)。因为如果不定义是以 nums[i] 为结尾,那么这时候即使做 nums[i] 的比较,也无法更新 dp[i],因为不知道 dp[i-1] 是不是以 nums[i-1] 结尾,如果不是,题目要求的数组的连续的,那就没法 dp[i] = dp[i-1]+1。
2025-11-22 23:58:17
823
原创 八股训练营第 24 天 | 说一说 Java 面向对象三大特性?说一说你对 Java 多态的理解?Java 重载和重写的区别?
重写的方法的访问级别要大于被重写的方法,返回类型和抛出异常的范围要小于被重写的方法。把一个子类对象直接赋值给父类引用变量,运行时调用引用变量的方法,其方法的行为总是表现出子类方法的行为特征,而不是父类方法的行为特征。即同一类型的变量在调用同一方法时,表现出不同的行为特征,这就是多态。运行时多态是在运行时根据对象实际的类型来确定调用的方法。编译时多态是在编译时就已经确定了调用的方法。这是由方法的重载实现的。总结一下,重载是运行一个类有多个同名方法,重写是允许子类提供特定于其父类的行为实现。
2025-11-22 00:51:08
171
原创 代码随想录算法训练营第 43 天 | 1143. 最长公共子序列、1035. 不相交的线、53. 最大子数组和、392. 判断子序列
考虑 i - 1、j - 1 的最长公共子序列的长度。(注意:不一定选,和。两个指针 p1、p2。如果字符相等就都右移一位;如果不相等就 p2 右移一位。如果 p1 先到末尾,返回 true;如果 p2 先到末尾,返回 false。值得学习——循环条件与运算的利用(不需要判断字符串为空的特殊情况),再判断最长公共子序列长度等不等于 s 的长度。(基于 i -1、j - 1 不一定选的基础):以 i 结尾的最大数组和。两个方法本质上一致。
2025-11-21 23:28:26
372
原创 八股训练营第 23 天 | String、StringBuffer、StringBuilder的区别?接口和抽象类的区别?Java常见的异常类有哪些?
Error 通常是严重的错误,这类错误是程序无法处理的,如 OutOfMemoryError,表示内存不足;它又分为两大类:编译时异常(Checked Exception)和运行时异常(Runtime Exception)。运行时异常也叫非受检异常(Unchecked Exception),这类异常在运行时抛出,不要求捕获也无法编译时提前捕获。Java 编译器要求程序必须捕获或声明所有编译时异常,强制要求程序为可能出现的异常做准备工作。总而言之,接口更像是一组规范,强调所有实现它的类都必须要遵循它的规范;
2025-11-20 22:45:58
940
原创 代码随想录算法训练营第 42 天 | 300. 最长递增子序列、674. 最长连续递增序列、718. 最长重复子数组
可以避免初始化时(dp[0][j]、dp[i][0]),初始第一行和第一列。一个小优化:把 result 更新放在 for 循环里面,使得代码更简洁。:以 i - 1、j - 1 为结尾的最长重复子数组。:以 nums[i] 结尾的最长连续子序列的长度。初始化:全赋为 1,因为最小长度就是 1。
2025-11-20 19:26:31
230
原创 八股训练营第 22 天 | 介绍一下Redis缓存雪崩、缓存穿透、缓存击穿,如何解决这些问题?如何保证数据库和缓存的一致性?
缓存雪崩:大量 Key 在同一时间失效,导致大量请求达到数据库上对数据库造成影响。给每个 Key 设置不同的随机的 ddl。不设置过期时间,改为定期更新缓存。缓存穿透:访问缓存和数据库都不存在的数据。常见于黑客构造不存在的 id 进行攻击。缓存空值:如果数据在缓存和数据库中都不存在,就在缓存中存入一个空值,下次直接返回这个空值。布隆过滤器:在 Redis 前面加一个布隆过滤器。对于不存在的数据会直接返回。缓存击穿:数据在缓存中不存在,在数据库中存在。
2025-11-20 00:23:46
230
原创 代码随想录算法训练营第 41 天 | 188. 买卖股票的最佳时机 IV、309. 买卖股票的最佳时机含冷冻期、714. 买卖股票的最佳时机含手续费
除了 0 之外,2 * k 个状态。奇数为持有(买入),偶数为不持有(卖出)。卖出时减去手续费即可。
2025-11-19 22:33:59
392
原创 八股训练营第 21 天 | Redis的数据类型有哪些?Redis是单线程的还是多线程的,为什么?说一说Redis持久化机制有哪些?
Redis 在接收客户端命令、解析命令、进行数据读写操作、发送数据给客户端这一过程是单线程的。但是 Redis 程序是多线程的。此外,在 Redis 6.0 之后,Redis 引入了多线程来处理网络 I/O 这部分,用于减少网络 I/O 阻塞带来的性能消耗。缺点是快照的频率不好把握,如果频率过低,数据可能丢失得比较多。Redis 的主要工作(网络 I/O 和执行命令)一直是单线程模型,6.0 之后,网络 I/O 引入了多线程。AOF 的优点是数据丢失得比较少,最多只有 1 秒的数据丢失;
2025-11-18 23:28:46
640
原创 代码随想录算法训练营第 40 天 | 121. 买卖股票的最佳时机、122. 买卖股票的最佳时机 II、123. 买卖股票的最佳时机 III
第 i 天持有股票的现金:前一天持有股票和当天买入的最大值。当天买入:前一天未持有股票的现金减当天买入的现金(因为可以买卖多次,前一天的初始现金未必是 0)第 i 天不持有股票的现金 = 前一天不持有和当天卖出的最大值。第 i 天持有股票的现金 = 前一天持有和当天买入的最大值。:第 i 天未持有(包括未买入和已经卖出)股票的收益。当天卖出:当天卖出的现金加上前一天未持有的负现金。:第 i 天第 1 次未持有股票。:第 i 天第 2 次未持有股票。:第 i 天第 1 次持有股票。:第 i 天未操作。
2025-11-18 21:44:21
388
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅