自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(41)
  • 收藏
  • 关注

原创 腾讯四面面经

TLS 四次握手,对称加密和非对称加密都涉及到了,都是两次HTTP 主要使用 TLS 协议握手,SSL 存在安全漏洞,并且 TLS 作为 SSL 的升级版,在安全性、兼容性和标准化等方面都有诸多优势,这是在 HTTPS 通信中主要使用 TLS 协议握手而不是 SSL 协议的重要原因。所以我们主要关注 TLS 的握手过程,TLS 握手根据密钥交互算法的不同,可以分为两种:RSA 算法,ECDHE 算法。

2025-03-23 09:15:16 808

原创 Redis实现分布式锁详解

用 Redis 实现分布式锁,是我们常见的实现分布式锁的一种方式下面是 redis 实现 分布式锁的四种方式,每种方式都有一定的问题,直到最后的 zookeeper先透露一下:Redission 解决了 set ex nx 无法自动续期的问题RedLock 解决了 Redission 和 set ex nx 的单点故障问题Zookeeper 解决了 RedLock 实现复杂的问题。

2025-02-07 16:20:04 323

原创 Synchronized和ReentrantLock面试详解

接下来为大家带来的是 Java 中的两个典型锁代表:Synchronized 和 ReentrantLock 的详解。

2025-02-07 12:31:37 778

原创 Spring循环依赖,三级缓存详解

循环依赖是指多个 Bean 循环引用 形成一个闭环 导致 Spring 容器无法正常初始化他们。例如:A 要依赖 B,发现 B 没创建,于是开始创建 B,创建的过程发现 B 要依赖 A,而 A 还没创建好,因为它要等 B 创建好,这样他们就在这儿 卡 bug 了Spring是根据三级缓存解决循环依赖的。

2025-01-13 11:35:47 881

原创 Java线程中断Interrupt相关知识

这就意味着如果希望在这些方法被中断后,线程还能继续处理中断相关事宜,可能需要在catch块中重新设置中断标志(如Thread.currentThread().interrupt())。综上所述,Thread.interrupt() 只是设置线程的中断标志,线程是否响应中断取决于线程自身是否检查了中断标志,以及如何处理检查到的中断情况。Thread.interrupted():这是一个静态方法,它会检查当前线程的中断状态,并在检查后。isInterrupted():这是一个实例方法,它只检查线程的中断状态,

2024-12-19 15:22:29 211

原创 Leetcode328奇偶链表,Leetcode21合并两个有序链表,Leetcode206反转链表 三者综合题

如果大家对其中的某一道题还不熟悉的话,建议去刷一下对应的题目,这里给了传送门206. 反转链表 - 力扣(LeetCode)21. 合并两个有序链表 - 力扣(LeetCode)328. 奇偶链表 - 力扣(LeetCode)

2024-11-04 22:44:47 426

原创 Leetcode137只出现一次的数字|| 及其拓展

我们前面说过,在访问第 i 个数时,在不借助额外数据结构存储已访问的元素的情况下,我们无法判断当前访问的数有没有出现过。比如说“加法运算”,统计数组中所有的数在某个二进制位出现的次数,如果有二进制位出现的次数不是K的整数倍,说明有其他没有出现K次的数的贡献,而该数只有一个,就是答案。异或运算规则为:相同为 0,不同为 1。0 ^ 0 = 0;方法一:借用哈希表,key为出现的数字,value为出现的数字,借助这么一个结构,最后再遍历哈希表,即可找到答案,显然空间复杂度O(n),时间复杂度O(1)

2024-11-02 22:45:42 404

原创 Java - 数组实现大顶堆

jdk提供的堆结构,也就是PriorityQueue优先级队列,删除堆顶元素(remove(),poll()),会进行下。完全二叉树:在一颗二叉树中,若除最后一层外的其余层都是满的,并且最后一层要么是满的,要么在右边缺少连续若干节点。沉操作,向最后插入元素(add(),offer()),会进行上浮操作,因为有这两个操作,所以在堆中,删除。并且在上浮和下沉过程中,还需要交换元素,所以我们还需要实现一个数组中元素交换的函数。小顶堆:每个节点的值都小于或等于其子节点的值。要实现一个堆,我们首先要了解堆的概念。

2024-11-01 11:26:34 509

原创 2024快手面试算法题-生气传染

注意,一次只能传播一个人,比如示例1,第一次只会传播给第一个P,不会传播给第二个P,了解这个之后,我们再将这个问题进行转化。最后一个P变生气,是由离他最近的A传染的,所以最后一个P变生气的时间,就是最后一个P和离他最近的A的距离。生气只会向后传播,最后一个生气的人一定是最长连续没有生气的人中的最后一个人,前提是前面得有一个人生气。所以我们只要记录离最后一个P最近的A的位置,和最后一个P的位置,两个位置相减就是答案。

2024-10-31 20:55:39 423

原创 Leetcode224 -- 基本计算器及其拓展

先说一下和Leetcode224的区别,就是多了*/这两个符号,并且*/个加减不属于一个级别,*/优先于+-,所以这里扯到了优先级的概念,并且还有(),为了保证括号内的表达式先被计算,我们定义( 的优先级是最低的,这样定义了优先级之后,就很清晰了。其实这个计算器的实现并不难,因为除了括号就剩下加减法嘛,括号肯定比加减法先执行,但是加减法是同级的,只是会改变数字的正负号而已,所以实现的逻辑并不是很难,我们只需要一个栈,来保存当前的符号sign即可.2.遇到优先级,与最近加入的优先级做对比,

2024-10-30 22:04:04 456

原创 Leetcode148,109以及二者的合并 -> Tencent面试算法题 - 无序双向链表转BST

整数无序双向链表能否转BST(二叉搜索树),如果能,怎么转 (尽可能少的时间复杂度和空间复杂度),如果不能为什么?这道题是腾讯在2024/8/30考的一道面试题,整体来说,难度不大,就是代码量稍稍有点儿大,让我们一起来看一下吧。这么一拆,就清晰的多了,就能逐个击破,下面来让我们看一下代码是怎么实现的。2.利用BST的性质(中序遍历有序),将排好序的双向链表再转为BST。这道题想都不用想,一定是能转的,要不然考你干啥,接下来就看怎么转。我们可以把这个题拆成两个部分。1.整数无序双向链表进行排序。

2024-10-28 09:26:15 379

原创 Leetcode2542-最大子序列的分数

说实话,这道题我认为还是挺不好理解的,我自己刷的时候也思考了很久,这个问题转换是这道题的核心,需要注意的三个点必须理清楚(尤其是必须从第k大的元素开始计算,还有两个数组所选取元素的索引是一样的),建议读者反复观看这道题我没见过的点是:想要对一个数组进行排序,但是又想让其对应的索引不变,就创建一个索引数组,让这个索引数组按照待排序数组的元素大小,升序或者降序排列,这样就把num2数组排序后的结果,映射到了ids数组中。

2024-07-08 18:49:26 1608 1

原创 图的表示与基础--Java

稀疏图:E<<V² 一般用邻接表表示(数组+链表)稠密图:E接近V² 一般用邻接矩阵表示(二维数组)该图片来自于: https://b23.tv/KHCF2m6。G(V,E):V顶点个数,E边的个数。

2023-11-13 21:28:22 199

原创 Java-HashMap排序

在Java中,HashMap是一个不保证元素顺序的集合,因为它通过哈希算法存储键值对。如果你想对HashMap按键或值进行排序,你可以将其转换为一个List,并使用Collections类的sort方法对该List进行排序。方法对List进行排序,使用一个自定义的Comparator来比较键值对的键。最后,打印出排序后的结果。如果你想对HashMap的值进行排序,只需要修改Comparator的比较逻辑即可。方法将HashMap转换为一个包含键值对的List。

2023-10-30 18:21:17 206

原创 Java-对String进行排序

在Java中,String是一个不可变的类,不能直接对String进行排序。但是,可以将多个String对象构成一个数组或List集合,然后对数组或集合进行排序。

2023-10-30 18:05:38 3778

原创 Java-Map的遍历

无论使用哪种方式,遍历过程中注意保证线程安全。对于高并发场景建议使用ConcurrentHashMap替代HashMap。

2023-10-30 18:00:15 92

原创 Java中的ListNode

在这个示例中,ListNode类的构造函数接受一个整数参数作为节点的值,并将next指针初始化为null。在实际使用中,ListNode类的实例通常会通过next指针链接起来,形成一个链表数据结构。ListNode类通常包含一个数据域以及一个指向下一个节点的指针,这样就构成了一个链表。当涉及到更复杂的链表操作时,我们可能需要使用更多的指针和技巧。对象表示链表中的一个节点,包含一个值(例如整数)和一个指向下一个节点的指针。类提供了一个基本的数据结构,用于构建和操作链表。类,我们可以构建一个简单的单向链表。

2023-10-25 20:47:43 1984

原创 KMP-Java

KMP算法(Knuth-Morris-Pratt算法)是一种用于高效地解决字符串匹配问题的算法。该算法的核心思想是通过预处理模式串(要匹配的字符串)构建一个回退表(也称为部分匹配表),以在匹配过程中避免不必要的回溯。KMP算法的优势在于在匹配过程中,不需要回溯到文本串中之前已经比较过的位置,因此可以避免重复比较,提高匹配效率。它的核心是根据模式串构建一个回退表(部分匹配表),该表记录了模式串每个位置匹配失败时应该回退到的位置。

2023-10-24 21:10:15 51

原创 算法思想:回溯

穷举法(Exhaustive Search)也称为暴力搜索或暴力穷举,是一种简单直观的算法思想,通过穷举所有可能的解来解决问题。穷举法的基本思想是将问题的解空间中的每一个可能的解都遍历一遍,然后判断每个解是否满足问题的条件。具体步骤如下:确定问题的解空间:确定问题的解的结构和限制条件,明确解的取值范围或解的组成方式。遍历解空间:根据解空间的定义,遍历解空间中的每一个可能的解。可以使用循环、递归或迭代等方式进行遍历。判断解的有效性:对于每一个遍历得到的解,在问题的约束条件下判断其是否有效。

2023-10-23 11:37:28 293

原创 算法思想--分治

合并k个排序链表:分而治之,分到区间内只有一个链表,合并区间二分查找:减而治之,每次搜索范围内元素减少一半。

2023-10-21 17:51:07 64

原创 算法设计--动态规划

动态规划(Dynamic Programming)是一种解决复杂问题的算法思想。它通过将问题分解为一系列子问题,并将子问题的解存储起来,从而避免重复计算,提高算法效率。Dynamic:在这里指用数学方法来根据子问题求解当前问题(通俗理解就是找到递推公式)Programming:指缓存上一步结果,根据上一步结果计算当前结果(多阶段进行)最优子结构:问题的最优解包含子问题的最优解。无后效性:一个阶段的状态只受前面若干个阶段的状态影响,与未来阶段无关。

2023-10-21 15:57:33 169

原创 算法设计--贪心

Huffman树的构建过程是根据字符的出现频率来生成的,频率越高的字符在树中的路径越短。这种编码方式可以最大限度地减少数据存储空间,因为出现频率高的字符被赋予了较短的编码,而出现频率低的字符被赋予了较长的编码。贪心算法的时间复杂度是多少?简单说就是建立【字符】到【数字】的对应关系,如下面大家熟知的 ASC II 编码表,例如,可以查表得知字符【a】对应的数字是十六进制数【0x61】生成编码表:通过遍历Huffman树的路径,将左子树的路径标记为0,右子树的路径标记为1,可以得到每个字符对应的编码表。

2023-10-19 08:53:03 110 1

原创 基础数据结构在JDK中的实现方式

它提供了各种实现不同功能和特性的集合类,包括列表(List)、集合(Set)、队列(Queue)和映射(Map)等。4. 队列(Queue):队列是一种先进先出(FIFO)的数据结构,JDK提供了Queue接口和不同的实现类来实现队列数据结构,比如ArrayDeque、LinkedList等。List接口:List接口表示一个有序的集合,允许元素的重复。Collection接口:Collection接口是List、Set和Queue接口的父接口,它定义了一些基本的集合操作方法,如添加、删除、遍历和判空等。

2023-10-18 19:56:53 84 1

原创 数据结构:图

(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边∈E(G),则u在线性序列中出现在v之前。在网络设计中,节点代表着网络中的设备,边代表着设备之间的连接,而边的权重通常表示连接的成本。例如,1->6 的距离是 14,而1->3->6 的距离是11。对于当前顶点,遍历其所有未访问的邻居,并更新它们的临时距离为更小,若距离更新需加入队列。例如,1->6 的距离是 14,而1->3->6 的距离是11。

2023-10-16 20:18:21 73 1

原创 非比较排序算法

非比较排序算法时间复杂度空间复杂度稳定性计数排序O(n+k)O(n+k)稳定桶排序O(n+k)O(n+k)稳定基数排序O(d*(n+k))O(n+k)稳定其中n 是数组长度k 是桶长度d 是基数位数。

2023-10-16 19:41:21 64 1

原创 根据补码计算对应的十进制数--符号位为1

原码是用最高位表示符号位的一种表示方法,即用最高位为0表示正数,用最高位为1表示负数,其余位表示数值的大小。反码是对原码进行取反操作得到的一种表示方法,即正数的反码和原码相同,负数的反码是将原码中除符号位之外的各位取反。补码是对原码或反码进行加1操作得到的一种表示方法,即正数的补码和原码相同,负数的补码是将反码加1。原码、反码和补码在计算机中广泛使用,可以用来表示整数的范围更广,同时可以简化加法和减法运算。在认识了什么是原码反码补码是什么之后,我们再来进行下面的讲解。

2023-10-16 18:41:32 756 1

原创 二进制与十进制的转换(包含小数部分)

乘二取整的意思是,将十进制小数部分乘2,然后取对应的整数位作为对应的二进制数。

2023-10-16 18:16:26 936 3

原创 基于比较的排序算法

算法最好最坏平均空间稳定思想注意事项冒泡O(n)O(n^2)O(n^2)O(1)Y比较最好情况需要额外判断选择O(n^2)O(n^2)O(n^2)O(1)N比较交换次数一般少于冒泡堆O(nlogn)O(nlogn)O(nlogn)O(1)N选择堆排序的辅助性较强,理解前先理解堆的数据结构插入O(n)O(n^2)O(n^2)O(1)Y比较插入排序对于近乎有序的数据处理速度比较快,复杂度有所下降,可以提前结束希尔O(nlogn)

2023-10-16 17:48:37 88 1

原创 数据结构--哈希表

我们的 HashTable 中表格容量是 2 的 n 次方,很多优化都是基于这个前提,能否不用 2 的 n 次方作为表格容量?JDK 的 HashMap 中采用了将对象 hashCode 高低位相互异或的方式减少冲突,怎么理解。经验表明如果每次乘的是较大质数,可以有更好地降低 hash 冲突,因此改【乘 10】为【乘 31】【乘 31】可以等价为【乘 32 - hash】,进一步可以转为更高效地【左移5位 - hash】的不同对象,他们的 hashCode 不一样,不能够用 hash 值来反映对象的。

2023-10-15 08:46:10 53 1

原创 数据结构--二叉树

二叉树是这么一种树状结构:每个节点最多有两个孩子,左孩子和右孩子重要的二叉树结构完全二叉树(complete binary tree)是一种二叉树结构,除最后一层以外,每一层都必须填满,填充时要遵从先左后右平衡二叉树(balance binary tree)是一种二叉树结构,其中每个节点的左右子树高度相差不超过 1。

2023-10-14 16:52:58 64 1

原创 数据结构--堆

以大顶堆为例,相对于之前的优先级队列,增加了堆化等方法。

2023-10-14 16:19:24 43 1

原创 数据结构--阻塞队列

之前的队列在很多场景下都不能很好地工作,例如大部分场景要求分离向队列放入(生产者)、从队列拿出(消费者)两个角色、它们得由不同的线程来担当,而之前的实现根本没有考虑线程安全问题队列为空,那么在之前的实现里会返回 null,如果就是硬要拿到一个元素呢?只能不断循环尝试队列为满,那么再之前的实现里会返回 false,如果就是硬要塞入一个元素呢?只能不断循环尝试因此我们需要解决的问题有用锁保证线程安全用条件变量让等待非空线程与等待不满线程进入等待状态,而不是不断循环尝试,让 CPU 空转。

2023-10-14 16:08:10 78 1

原创 数据结构--优先级队列

堆总是完全二叉树,即除了最后一层可能不满外,其余层都必须填满节点,最后一层的节点都是从左到右排列的。节点 i 的左子节点为 2i+1,右子节点为 2i+2,当然它们得 < size。节点 i 的左子节点为 2i,右子节点为 2i+1,同样得 < size。节点 i 的父节点为 floor((i-1)/2),当 i>0 时。在大顶堆中,父节点的值大于或等于其子节点的值。在小顶堆中,父节点的值小于或等于其子节点的值。节点 i 的父节点为 floor(i/2),当 i > 1 时。完全二叉树可以使用数组来表示。

2023-10-14 15:42:18 38 1

原创 数据结构--双端队列

定义特点队列一端删除(头)另一端添加(尾)栈一端删除和添加(顶)双端队列两端都可以删除、添加优先级队列优先级高者先出队延时队列根据延时时间确定优先级并发非阻塞队列队列空或满时不阻塞并发阻塞队列队列空时删除阻塞、队列满时添加阻塞注1:Java 中 LinkedList 即为典型双端队列实现,不过它同时实现了 Queue 接口,也提供了栈的 push pop 等方法注2:不同语言,操作双端队列的方法命名有所不同,参见下表操作JavaJavaScriptC++尾部插入。

2023-10-14 15:14:36 77 1

原创 数据结构--栈

计算机科学中,stack是一种线性的数据结构,只能在其一端添加数据和移除数据。习惯来说,这一端称之为栈顶,另一端不能操作数据的称之为栈底,就如同生活中的一摞书。

2023-10-14 12:12:39 42 1

原创 数据结构--队列

计算机科学中,queue 是以顺序的方式维护的一组数据集合,在一端添加数据,从另一端移除数据。习惯来说,添加的一端称为尾,移除的一端称为头,就如同生活中的排队买商品。

2023-10-14 12:00:18 63 1

原创 数据结构--链表

在计算机科学中,链表是数据元素的线性集合,其每个元素都指向下一个元素,元素存储上并不连续。可以分类为5单向链表,每个元素只知道其下一个元素是谁双向链表,每个元素知道其上一个元素和下一个元素循环链表,通常的链表尾节点 tail 指向的都是 null,而循环链表的 tail 指向的是头节点 head链表内还有一种特殊的节点称为哨兵(Sentinel)节点,也叫做哑元( Dummy)节点,它不存储数据,通常用作头尾,用来简化边界判断,如下图所示1.2随机访问性能。

2023-10-14 11:11:24 283 1

原创 数据结构--数组

在计算机科学中,数组是由一组元素(值或变量)组成的数据结构,每个元素有至少一个索引或键来标识,因为数组内的元素是连续存储的,所以数组中元素的地址,可以通过其索引计算出来。小测试已知 array 的数据的起始地址是 0x7138f94c8,那么元素 3 的地址是什么?答:0x7138f94c8 + 2 * 1 = 0x7138f94ca随机访问性能即根据索引查找元素,时间复杂度是 O(1)

2023-10-14 10:08:41 128 1

原创 数据结构--总结

什么是数据结构?数据结构是计算机科学中的一个重要概念,用于组织和存储数据以便有效地使用和操作。它定义了不同类型数据的组织方式和相互之间的关系,使得数据的访问和操作更加高效和方便。计算机中常用的数据结构包括以下几种:1. 数组(Array):顺序存储的数据结构,可以通过下标访问元素。2. 链表(Linked List):由节点组成的数据结构,每个节点包含数据和指向下一个节点的指针。3. 栈(Stack):一种后进先出(LIFO)的数据结构,元素只能在栈顶进行插入和删除操作。

2023-10-13 12:56:53 47

原创 Leetcode819--最常见的单词--Java实现

该题为leetcode819,属于一道简单题,虽然题比较简单,但是用到的api对于大部分新手小伙伴来说不太熟悉,而且细节也不少,下面展示三个方法,性能是逐渐提升的。

2023-09-26 22:14:41 170 1

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除