JAVA IO
1 IO介绍 在Java的软件设计开发中,通信架构是不可避免的,我们在进行不同系统或者不同进程之间的数据交互,或者在高并发下的通信场景下都需要用到网络通信相关的技术,对于一些经验丰富的程序员来说,Java早期的网络通信架构存在一些缺陷,其中最令人恼火的是基于性能低下的同步阻塞式的I/O通信(BIO),随着互联网开发下通信性能的高要求,Java在2002年开始支持了非阻塞式的I/O通信技术(NIO)。大多数读者在学习网络通信相关技术的时候,都只是接触到零碎的通信技术点,没有完整的技术体系架构,以至于对于Java的通信场景总是没有清晰的解决方案。本次课程将通过大量清晰直接的案例从最基础的BIO式通信开始介绍到NIO , AIO,读者可以清晰的了解到阻塞、同步、异步的现象、概念和特征以及优缺点。本课程结合了大量的案例让读者可以快速了解每种通信架构的使用。
通信技术整体解决的问题
局域网内的通信要求。
多系统间的底层消息传递机制。
高并发下,大数据量的通信场景需要。
游戏行业。无论是手游服务端,还是大型的网络游戏,Java语言都得到越来越广泛的应用。
2 Java的 ...
为什么Redis集群分片最大槽数是16384个
为什么Redis集群分片最大槽数是16384个? GitHub上已有关于这个问题的解答,why redis-cluster use 16384 slots? · Issue #2576 · redis/redis (github.com),这里只做大概解释
Redis集群通过CRC16算法对key进行哈希并对16384取模来决定该key具体放在哪个槽位,而该算法的hash结果有16位,也就是65536个值,那为啥不分配65536个槽而是16384(2^14)个?
首先翻译一下作者的解答:
正常的心跳数据包带有节点的完整配置,可以用幂等方式用旧的节点替换旧节点,以便更新旧的配置。这意味着它们包含原始节点的插槽配置,该节点使用2k的空间和16k的插槽,但是会使用8k的空间(使用65K的插槽)。同时,由于其他设计折衷,Redis集群不太可能扩展到1000个以上的主节点。因此16k处于正确的范围内,以确保每个主机具有足够的插槽,最多可容纳1000个矩阵,但数量足够少,可以轻松地将插槽配置作为原始位图传播。请注意,在小型群集中,位图将难以压缩,因为当N较小时,位图将设置的 ...
Redis持久化
1.Redis持久化Redis有两种持久化方案:
RDB持久化
AOF持久化
1.1.RDBRDB全称Redis Database Backup file(Redis数据备份文件),RDB其实就是把数据以快照的形式保存在磁盘上。什么是快照呢,你可以理解成把当前时刻的数据拍成一张照片保存下来。
RDB持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘。也是默认的持久化方式,这种方式是就是将内存中数据以快照的方式写入到二进制文件中,默认的文件名为dump.rdb。
1.1.1.RDB执行RDB持久化在四种情况下会执行:
执行save命令
执行bgsave命令
Redis停机时
触发RDB条件时
1)save命令
save命令会导致主进程执行RDB,这个过程中其它所有命令都会被阻塞。
2)bgsave命令
bgsave命令执行后Redis执行fork操作创建子进程完成RDB,主进程可以继续处理用户请求,不会阻塞。
3)停机时
Redis停机时会执行一次save命令,实现RDB持久化。
4)触发RDB条件
Redis内部有触发RDB的机制,可以在redis.conf文件中找到,格 ...
innodb行锁实现方式
InnoDB行锁是通过给索引上的索引项加锁来实现的,这一点MySQL与Oracle不同,后者是通过在数据块中对相应数据行加锁来实现的。 InnoDB这种行锁实现特点意味着:只有通过索引条件检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁!在实际应用中,要特别注意InnoDB行锁的这一特性,不然的话,可能导致大量的锁冲突,从而影响并发性能。下面通过一些实际例子来加以说明.
1、在不通过索引条件查询的时候,InnoDB确实使用的是表锁,而不是行锁
1)InnoDB存储引擎的表在不使用索引时使用表锁例子
在上如表中,看起来session_1只给一行加了排他锁,但session_2在请求其他行的排他锁时,却出现了锁等待!原因就是在没有索引的情况下,InnoDB只能使用表锁。
2)有了索引以后,在对索引字段查询时,使用的就是行级锁:添加索引:alter table tab_no_index add index ind_tab_no_index_id (id);
从上表可知,由于使用了行级锁,所以对不同行使用排它锁相互不影响。
2、 由于MySQL的行锁是针对索引加的锁,不是针对 ...
Java常见数据结构源码分析
1.数据结构
2. 一维数组2.1 数组的特点
在Java中,数组是用来存放同一种数据类型的集合,注意只能存放同一种数据类型。
//只声明了类型和长度
数据类型[] 数组名称 = new 数据类型[数组长度];
//声明了类型,初始化赋值,大小由元素个数决定
数据类型[] 数组名称 = {数组元素1,数组元素2,......}
例如:整型数组
例如:对象数组
物理结构特点:
申请内存:一次申请一大段连续的空间,一旦申请到了,内存就固定了。
不能动态扩展(初始化给大了,浪费;给小了,不够用),插入快,删除和查找慢。
存储特点:所有数据存储在这个连续的空间中,数组中的每一个元素都是一个具体的数据(或对象),所有数据都紧密排布,不能有间隔。
具体的,如下图:
2.2 自定义数组package com.atguigu01.overview.array;
/**
* @author 尚硅谷-宋红康
* @create 14:39
*/
class Array {
private Object[] elementData; ...
从链表中删去总和值为零的连续节点
题目描述1171. 从链表中删去总和值为零的连续节点 - 力扣(Leetcode)
给你一个链表的头节点 head,请你编写代码,反复删去链表中由 总和 值为 0 的连续节点组成的序列,直到不存在这样的序列为止。
删除完毕后,请你返回最终结果链表的头节点。
你可以返回任何满足题目要求的答案。
(注意,下面示例中的所有序列,都是对 ListNode 对象序列化的表示。)
示例 1:
输入:head = [1,2,-3,3,1]
输出:[3,1]
提示:答案 [1,2,1] 也是正确的。
示例 2:
输入:head = [1,2,3,-3,4]
输出:[1,2,4]
示例 3:
输入:head = [1,2,3,-3,-2]
输出:[1]
分析若链表节点的两个前缀和相等,说明两个前缀和之间的连续节点序列的和为 0,那么可以消去这部分连续节点。
我们第一次遍历链表,用哈希表 last记录前缀和以及对应的链表节点,对于同一前缀和s,后面出现的节点覆盖前面的节点。
接下来,我们再次遍历链表,若当前节点 cur 的前缀和 s在 last出现,说明 cur与 last[s]之间的所有节点和为 ...
老鼠和奶酪
题目描述2611. 老鼠和奶酪 - 力扣(Leetcode)
有两只老鼠和 n 块不同类型的奶酪,每块奶酪都只能被其中一只老鼠吃掉。
下标为 i 处的奶酪被吃掉的得分为:
如果第一只老鼠吃掉,则得分为 reward1[i] 。
如果第二只老鼠吃掉,则得分为 reward2[i] 。
给你一个正整数数组 reward1 ,一个正整数数组 reward2 ,和一个非负整数 k 。
请你返回第一只老鼠恰好吃掉 k 块奶酪的情况下,最大 得分为多少。
示例 1:
输入:reward1 = [1,1,3,4], reward2 = [4,4,1,1], k = 2
输出:15
解释:这个例子中,第一只老鼠吃掉第 2 和 3 块奶酪(下标从 0 开始),第二只老鼠吃掉第 0 和 1 块奶酪。
总得分为 4 + 4 + 3 + 4 = 15 。
15 是最高得分。
示例 2:
输入:reward1 = [1,1], reward2 = [1,1], k = 2
输出:2
解释:这个例子中,第一只老鼠吃掉第 0 和 1 块奶酪(下标从 0 开始),第二只老鼠不吃任何奶酪。
总得分为 1 + 1 ...
统计范围内的元音字符串数
题目介绍2559. 统计范围内的元音字符串数 - 力扣(Leetcode)
给你一个下标从 0 开始的字符串数组 words 以及一个二维整数数组 queries 。
每个查询 queries[i] = [li, ri] 会要求我们统计在 words 中下标在 li 到 ri 范围内(包含 这两个值)并且以元音开头和结尾的字符串的数目。
返回一个整数数组,其中数组的第 i 个元素对应第 i 个查询的答案。
注意:元音字母是 'a'、'e'、'i'、'o' 和 'u' 。
示例 1:
输入:words = ["aba","bcb","ece","aa","e"], queries = [[0,2],[1,4],[1,1]]
输出:[2,3,0]
解释:以元音开头和结尾的字符串是 "aba"、"ece"、"aa" 和 "e" 。
查询 ...
无重复字符的最长子串
题目介绍 题目链接:3. 无重复字符的最长子串 - 力扣(Leetcode)
给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: s = "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
题目思路 没啥好说的,一眼滑动窗口。。。
以示例1为例,对于“abcabcbb”,定义两个指针( left 和 right ),初始都指向字符串0位置,两个指针之间的字符串即为当前找到的子串,right指针向右遍历,使用has ...