Java中高级面试题总览(一)(4)

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: Java中高级面试题总览(一)

算法

1. 10 亿个数字里里面找最小的 10 个。

先根据数据值/机器数后的商划分到不同的机器上,最好可以让数据划分后一次读入内存这样不同的机器负责处
理不同的数值范围。得到结果后,对最小的数据范围的机器进行堆排序(构建小顶堆)。

2. 有 1 亿个数字,其中有 2 个是重复的,快速找到它,时间和空间要最优。

原理:把数字值直接映射到数组下标(时间最优),这里重复的数字只有两次,为了空间最优,就用bit来表示(只有0和1),1byte=8bit,一个byte可以存储8个数字的计数。

所以建立数组 byte[] bucket=new byte[(最大值-最小值)/8+1];

public class Test{
    public static void main(String[] args){
        long time=new Date().getTime();
        int[] arr=new int[100000000];//1亿长度
        for(int i=0;i<arr.length;i++){
            arr[i]=i+1;
        }
        arr[99999999]=2020;
        int min=arr[0];
        int max=arr[0];
        for(int i=0;i<arr.length;i++){
            if(arr[i]<min)
                min=arr[i];
            if(arr[i]>max)
                max=arr[i];
        }
        byte[] bucket=new byte[(max-min)/8+1];
        for(int i=0;i<arr.length;i++){
            int num=arr[i];
            int j=(num-min)/8;
            int k=(num-min)%8;
            if(((bucket[j]>>k)&1)>0){//重复了
                System.out.println("Number of repeats:"+num);
                break;
            }else{
               bucket[j]|=(1<<k);
            }
        }
        long time2=new Date().getTime();
        System.out.println("millisecond:"+(time2-time));
    }
}

3. 2 亿个随机生成的无序整数,找出中间大小的值。

首先我们将 int 划分为 2^16 个区域,然后读取数据统计落到各个区域里的数的个数,之

后我们根据统计结果就可以判断中位数落到那个区域,同时知道这个区域中的第几大数刚好是中位数。然后第二次扫描我们只统计落在这个区域中的那些数就可以了。

4. 给一个不知道长度的(可能很大)输入字符串,设计一种方案,将重复的字符排重。

5. 遍历二叉树。

6. 有 3n+1 个数字,其中 3n 个中是重复的,只有 1 个是不重复的,怎么找出来。

7. 写一个字符串反转函数。

8. 常用的排序算法,快排,归并、冒泡。 快排的最优时间复杂度,最差复杂度。冒泡排序的优化方案。

排序法

最差时间分析 平均时间复杂度 稳定度 空间复杂度
冒泡排序 O(n2) O(n2) 稳定 O(1)
快速排序 O(n2) O(n*log2n) 不稳定 O(log2n)~O(n)
选择排序 O(n2) O(n2) 不稳定 O(1)
二叉树排序 O(n2) O(n*log2n) 不一顶 O(n)

插入排序

O(n2) O(n2) 稳定 O(1)
堆排序 O(n*log2n) O(n*log2n) 不稳定 O(1)
归并排序 O(n*log2n) O(n*log2n) 稳定 O(n)
public void sortArray(int[] array){
    int temp;
    for(int i=0; i<array.length; i++){
        boolean isSorted = true;
        for(int j=0; j<array.length-i-1; j++){
            if(array[j] > array[j+1]){
                temp = array[j];
                array[j] = array[j+1];
                array[j+1] = temp;
                isSorted = false;
            }
        }
        if(isSorted){
            break;
        }
    }
}

定义了一个boolean类型的isSorted变量,用来判断往后的循环当中,数组是否已经是有序的,每一轮循环都会设置其值为true,当有元素对调位置时,就将isSorted的值设置为false,表示该数组还不是有序数组。每一轮都要判断isSorted的值,如果判断当前一轮操作没有元素有位置调换,那么可以提前结束所有的循环

9. 二分查找的时间复杂度,优势。

10. 一个已经构建好的 TreeSet,怎么完成倒排序。

11.md5加密的原理

MD5是输入不定长度信息,输出固定长度128-bits的算法。经过程序流程,生成四个32位数据,最后联合起来成为
一个128-bits散列。基本方式为,求余、取余、调整长度、与链接变量进行循环运算。得出结果。

MD5值算法原理 - 你好中国 - 博客园

12.给一台普通PC,2G内存,要求处理一个包含40亿个不重复并且没有排过序的无符号的int整数,给出一个整数,问如果快速地判断这个整数是否在文件40亿个数据当中?

问题思考:
40亿个int占(40亿*4)/1024/1024/1024 大概为14.9G左右,很明显内存只有2G,放不下,因此不可能将这
40亿数据放到内存中计算。要快速的解决这个问题最好的方案就是将数据搁内存了,所以现在的问题就在如何
在2G内存空间以内存储着40亿整数。一个int整数在java中是占4个字节的即要32bit位,如果能够用一个bit
位来标识一个int整数那么存储空间将大大减少,算一下40亿个int需要的内存空间为40亿/8/1024/1024大概
为476.83 mb,这样的话我们完全可以将这40亿个int数放到内存中进行处理。
具体思路:
   1个int占4字节即4*8=32位,那么我们只需要申请一个int数组长度为 int tmp[1+N/32]即可存储完这些
数据,其中N代表要进行查找的总数,tmp中的每个元素在内存在占32位可以对应表示十进制数0~31,所以可得
到BitMap表:
tmp[0]:可表示0~31
tmp[1]:可表示32~63
tmp[2]:可表示64~95
.......
那么接下来就看看十进制数如何转换为对应的bit位:
假设这40亿int数据为:6,3,8,32,36,......,那么具体的BitMap表示为:
00000000000000000000000101001001
00000000000000000000000000010000
如何判断int数字在tmp数组的哪个下标,这个其实可以通过直接除以32取整数部分,例如:整数8除以32取整
等于0,那么8就在tmp[0]上。另外,我们如何知道了8在tmp[0]中的32个位中的哪个位,这种情况直接mod上
32就ok,又如整数8,在tmp[0]中的第8 mod上32等于8,那么整数8就在tmp[0]中的第9个bit位(从右边数
起)。
解法二:
Bloom Filter 原理
下面来分析下它的实现原理。
官方的说法是:它是一个保存了很长的二进制向量,同时结合 Hash 函数实现的。
对写入的数据做 H 次 hash 运算定位到数组中的位置,同时将数据改为 1 。当有数据查询时也是同样的方式定
位到数组中。 一旦其中的有一位为 0 则认为数据肯定不存在于集合,否则数据可能存在于集合中。
布隆过滤有以下几个特点:
只要返回数据不存在,则肯定不存在。
返回数据存在,但只能是大概率存在。
同时不能清除其中的数据。
它不适合那些"零误判"的应用场合.在能容忍低误判的应用场景下,布隆过滤器通过极少的误判换区了存储空间的极大节省.

拜托,面试官别问我「布隆」了

13. 在2.5亿个整数中找出不重复的整数,注,内存不足以容纳这2.5亿个整数

解法一:将bit-map扩展一下,采用2-Bitmap(每个数分配2bit,00表示不存在,01表示出现一次,10表示多
次,11无意义)进行,共需内存2^32 * 2 bit=1 GB内存,还可以接受。然后扫描这2.5亿个整数,查看Bitmap
中相对应位,如果是00变01,01变10,10保持不变。所描完事后,查看bitmap,把对应位是01的整数输出即可。
或者我们不用2bit来进行表示,我们用两个bit-map即可模拟实现这个2bit-map,都是一样的道理。
解法二:根据数字hash,划分小文件。然后在小文件中找出不重复的整数,并排序。然后再进行归并,注意去除重复的元素。

BitMap算法_皮皮blog-CSDN博客_bitmap

14.给定 a、b 两个文件,各存放 50 亿个 URL,每个 URL 各占 64B,内存限制是 4G。请找出 a、b 两个文件共同的 URL。

每个 URL 占 64B,那么 50 亿个 URL 占用的空间大小约为 320GB。5, 000, 000, 000 _ 64B ≈ 5GB _ 64 
= 320GB 由于内存大小只有 4G,因此,我们不可能一次性把所有 URL 加载到内存中处理。对于这种类型的题
目,一般采用分治策略 ,即:把一个文件中的 URL 按照某个特征划分为多个小文件,使得每个小文件大小不
超过 4G,这样就可以把这个小文件读到内存中进行处理了。
首先遍历文件 a,对遍历到的 URL 求 hash(URL) % 1000 ,根据计算结果把遍历到的 URL 存储到 a0, a1, 
a2, ..., a999,这样每个大小约为 300MB。使用同样的方法遍历文件 b,把文件 b 中的 URL 分别存储到文
件 b0, b1, b2, ..., b999 中。这样处理过后,所有可能相同的 URL 都在对应的小文件中,即 a0 对应 
b0, ..., a999 对应 b999,不对应的小文件不可能有相同的 URL。那么接下来,我们只需要求出这 1000 对
小文件中相同的 URL 就好了。
接着遍历 ai( i∈[0,999] ),把 URL 存储到一个 HashSet 集合中。然后遍历 bi 中每个 URL,看在 
HashSet 集合中是否存在,若存在,说明这就是共同的 URL,可以把这个 URL 保存到一个单独的文件中。

如何从 100 亿 URL 中找出相同的 URL?

MySQL

1. 行转列

姓名       课程       分数

---------- ---------- -----------

张三       语文        74

张三       数学        83

张三       物理        93

李四       语文        74

李四       数学        84

李四       物理        94

SELECT 姓名,
 max(CASE 课程 WHEN'语文' THEN 分数 ELSE 0 END) 语文,
 max(CASE 课程 WHEN'数学' THEN 分数 ELSE 0 END) 数学,
 max(CASE 课程 WHEN'物理' THEN 分数 ELSE 0 END) 物理
FROM tb
GROUP BY 姓名
姓名        语文        数学        物理
---------- ----------- ----------- -----------
李四        74          84          94
张三        74          83          93

2. MySQL存储引擎- MyISAM与InnoDB区别

第一个重大区别是:InnoDB的主索引的数据文件本身就是索引文件。从上文知道,MyISAM主索引的索引文件和数据
文件是分离的,索引文件仅保存数据记录的地址。而在InnoDB中,表数据文件本身就是按B+Tree组织的一个索引
结(index=data),这棵树的叶节点data域保存了完整的数据记录。这个索引的key是数据表的主键,因此InnoDB
表数据文件本身就是主索引。
第二个重大区别是:MyISAM类型不支持事务处理等高级处理,而InnoDB类型支持事务处理与外键和行级锁。MyISAM
类型的表强调的是性能,其执行速度比InnoDB类型更快,但是不提供事务支持,而InnoDB提供事务支持以及外部
键等高级数据库功能。 所以MyISAM往往就容易被人认为只适合在小项目中使用
第三个区别是:InnoDB的辅助索引data域存储相应记录主键的值而不是地址。而MyISAM的辅助索引和主索引没
有多大区别

   不同存储引擎的索引实现方式对于正确使用和优化索引都非常有帮助,例如知道了InnoDB的索引实现后,就很容易明白为什么不建议使用过长的字段作为主键,因为所有辅助索引都引用主索引,过长的主索引会令辅助索引变得过大。再例如,用非单调的字段作为主键在InnoDB中不是个好主意,因为InnoDB数据文件本身是一颗B+Tree,非单调的主键会造成在插入新记录时数据文件为了维持B+Tree的特性而频繁的分裂调整,十分低效,而使用自增字段作为主键则是一个很好的选择。

3,数据库隔离级别有哪些,各自的含义是什么,Mysql默认的隔离级别是是什么

InnoDB使用多版本并发控制来获得高并发性,并且实现了sql标准的4种隔离级别,分别是:
1.未提交读:在未提交读级别,事务中的修改,即使没有提交,对其他事务也都是可见的
2.提交读(Read committed):大多数数据库系统的默认隔离级别都是提交读(但Mysql不是)一个事务开始
时,只能“看见”已经提交的事务所做的修改",该隔离级别有时也叫"不可重复度"
3.可重复读:可重复读解决了脏读的问题。该级别保证了在同一个事务中多次读取同样记录的结果是一致的。但是
理论上,可重复读隔离级别还是无法解决当某个事务在读取某个范围内的记录时,另外一个事务中又在该范围插入
了新的记录,当之前的事务再次读取该范围的记录时,会产生幻行。可重复读是MySQL的默认事务隔离级别。
4.可串行化:可串行化是最高的隔离级别。它通过强制事务串行执行,避免了前面所说的幻读问题。简单来说,可
串行化会在读取的每一行数据上都加上锁,所以可能导致大量的超时和锁争用问题

4.高并发下,如何做到安全的修改同一行数据,乐观锁和悲观锁是什么,INNODB的行级锁有哪2种,解释其含义

InnoDB实现了以下两种类型的行锁。
共享锁(S):允许一个事务去读一行,阻止同一Session其他事务获得相同数据集的排他锁。当事务同时增加共享锁时候,事务的更新必须等待先执行的事务 commit 后才行,如果同时并发太大可能很容易造成死锁
排他锁(X):允许获得排他锁的事务更新数据,阻止同一Session其他事务取得相同数据集的共享读锁和排他写
锁。
共享锁(S):SELECT * FROM table_name WHERE ... LOCK IN SHARE MODE
排他锁(X):SELECT * FROM table_name WHERE ... FOR UPDATE
另外,为了允许行锁和表锁共存,实现多粒度锁机制,InnoDB还有两种内部使用的意向锁(Intention 
Locks),这两种意向锁都是表锁。
意向共享锁(IS):事务打算给数据行加行共享锁,事务在给一个数据行加共享锁前必须先取得该表的IS锁。
意向排他锁(IX):事务打算给数据行加行排他锁,事务在给一个数据行加排他锁前必须先取得该表的IX锁
InnoDB行锁是通过给索引上的索引项加锁来实现的,这一点与Oracle不同,后者是通过在数据块中对相应数据行
加锁来实现的。InnoDB这种行锁实现特点意味着:只有通过索引条件检索数据,InnoDB才使用行级锁,否则,
InnoDB将使用表锁!
在实际应用中,要特别注意InnoDB行锁的这一特性,不然的话,可能导致大量的锁冲突,从而影响并发性能
锁的算法
Record Lock :单个记录上的锁。
Gap Lock:间隙锁,锁定一个范围,但不包含记录本身。
Next-key Lock: 锁定一个范围和本身 Record Lock + Gap Lock。
例如一个索引有10,11,13,20这4个值,那么索引可能被Next-key Locking的区间为:
(- ∞,10), [10,11) , [11,13), [13,20), [20,+ ∞)
Next-key Lock为了解决幻读问题

5.SQL优化的一般步骤是什么,怎么看执行计划,如何理解其中各个字段的含义,索引的原理?

6.数据库会死锁吗,举一个死锁的例子,mysql怎么解决死锁

事务A等待事务B,同时事务B等待事务A,会产生死锁。
Innodb有死锁检测进程,如果检测到死锁,会马上抛出异常并回滚一个事务(另一个继续执行)
死锁的关键在于:两个(或以上)的Session加锁的顺序不一致。
那么对应的解决死锁问题的关键就是:让不同的session加锁有次序

7.什么是 B+树,B-树,列出实际的使用场景。

在讲B+树之前必须先了解二叉查找树、平衡二叉树(AVLTree)和多路平衡查找树(B-Tree),B+树即由这些
树逐步优化而来。
B+Tree相对于B-Tree有几点不同:
1.B+非叶节点不保存数据相关信息, 只保存关键字和子节点的引用
2.B+叶子节点是顺序排列的, 并且相邻节点具有顺序引用的关系(存在一个链指针)
3.B+关键字对应的数据保存在叶子节点中
4.B+节点关键字搜索采用左闭合区间(a<= x < b)
为什么使用B+Tree
红黑树等数据结构也可以用来实现索引,但是文件系统及数据库系统普遍采用B-Tree作为索引结构,
一般来说,索引本身也很大,不可能全部存储在内存中,因此索引往往以索引文件的形式存储的磁盘上。这样的
话,索引查找过程中就要产生磁盘I/O消耗,相对于内存存取,I/O存取的消耗要高几个数量级,所以评价一个数据结构作为索引的优劣最重要的指标就是在查找过程中磁盘I/O操作次数的渐进复杂度。
根据B+Tree的定义,可知检索一次最多需要访问h个节点。数据库系统的设计者巧妙利用了磁盘预读原理,将一个节点的大小设为等于一个页,这样每个节点只需要一次I/O就可以完全载入。(Innodb的数据页是16K,1.2.x支持8K,4K压缩页)。
每次新建节点时,直接申请一个页的空间,这样就保证一个节点物理上也存储在一个页里,加之计算机存储分配都是按页对齐的,就实现了一个node只需一次I/O。
B-Tree中一次检索最多需要h-1次I/O(根节点常驻内存),渐进复杂度为O(h)=O(logdN)。
而红黑树这种结构,h明显要深的多。由于逻辑上很近的节点(父子)物理上可能很远,无法利用局部性,所以红黑树的I/O渐进复杂度也为O(h),效率明显比B-Tree差很多。
为什么使用B+Tree
B+树是B-树的变种(PLUS版)多路绝对平衡查找树, 他拥有B-树的优势
B+树扫库、 表能力更强(只需要扫描关键字和引用)
B+树的磁盘读写能力更强(B+树的根节点和支节点不保存数据区,所以根节点和支节点同样大小的情况下,保存的关键字要比B-树要多)
B+树的排序能力更强(叶子几点顺序排列)
B+树的查询效率更加稳定(和数据在叶子节点有关)

什么是 B+树,B-树

B-树B+树

8、 Select Count (*)和Select Count(1)以及Select Count(column)区别

count(*) 包括了所有的列,相当于行数,在统计结果的时候,不会忽略列值为NULL ;

count(1) 1并不是表示第一个字段,而是表示一个固定值。其实就可以想成表中有这么一个字段,这个字段就是固定值1。就是计算一共有多少个1,在统计结果的时候,不会忽略列值为NULL 。

count(字段) 会统计该字段在表中出现的次数,忽略字段为NULL值的记录数。

一般情况下,Select Count (*)和Select Count(1)两着返回结果是一样的

假如表沒有主键(Primary key), 那么count(1)比count(*)快,

如果有主键的話,那主键作为count的条件时候count(主键)最快

如果你的表只有一个字段的话那count(*)就是最快的

count(*) 跟 count(1) 的结果一样,都包括对NULL的统计,而count(column) 是不包括NULL的统计

https://blog.csdn.net/lingduo24/article/details/87621363

9、唯一索引,可以在索引列插入多个null吗

1,唯一索引可在索引列插入多次null

2,适用于表中的一些业务列,不能出现重复,但可以插入空值,比如用户表的身份证号码

10、写出一条sql查询出student(id,name)表中name相同id连续的三条记录

SELECT
  a.id,
  b.id,
  c.id
FROM
  student a,
  student b,
  student c
WHERE
  a.id - b.id = 1
AND b.id - c.id = 1
AND a.name= b.name
AND b.name= c.name

正在上传…重新上传取消image.gif

11、SQL语句关键字的执行顺序是什么

这张图与 SQL 查询的语义有关,让你知道一个查询会返回什么,并回答了以下这些问题:

  • 可以在 GRROUP BY 之后使用 WHERE 吗?(不行,WHERE 是在 GROUP BY 之前!)
  • 可以对窗口函数返回的结果进行过滤吗?(不行,窗口函数是 SELECT 语句里,而 SELECT 是在 WHERE 和 GROUP BY 之后)
  • 可以基于 GROUP BY 里的东西进行 ORDER BY 吗?(可以,ORDER BY 基本上是在最后执行的,所以可以基于任何东西进行 ORDER BY)
  • LIMIT 是在什么时候执行?(在最后!)

但数据库引擎并不一定严格按照这个顺序执行 SQL 查询,因为为了更快地执行查询,它们会做出一些优化,这些问题会在以后的文章中解释。

  • 如果你想要知道一个查询语句是否合法,或者想要知道一个查询语句会返回什么,可以参考这张图;
  • 在涉及查询性能或者与索引有关的东西时,这张图就不适用了。

SQL 查询语句总是先执行 SELECT?你们都错了

12、UUID做主键为什么查询和插入效率比自增主键低

UUID 太长了、占用空间大,作为主键性能太差了;更重要的是,UUID 不具有有序性,会导致 B+ 树索引在写的时候有过多的随机写操作(连续的 ID 可以产生部分顺序写),还有,由于在写的时候不能产生有顺序的 append 操作,而需要进行 insert 操作,将会读取整个 B+ 树节点到内存,在插入这条记录后会将整个节点写回磁盘,这种操作在记录占用空间比较大的情况下,性能下降明显

中间件

1.Dubbo有哪些均衡策略,和集群模式

均衡策略

1、随机(缺省),按权重设置随机概率。
在一个截面上碰撞的概率高,但调用量越大分布越均匀,而且按概率使用权重后也比较均匀,有利于动态调整提供者权重。
2、轮循,按公约后的权重设置轮循比率。
存在慢的提供者累积请求问题,比如:第二台机器很慢,但没挂,当请求调到第二台时就卡在那,久而久之,所有请求都卡在调到第二台上。
3、最少活跃调用数,相同活跃数的随机,活跃数指调用前后计数差。
使慢的提供者收到更少请求,因为越慢的提供者的调用前后计数差会越大。
4、一致性Hash,相同参数的请求总是发到同一提供者。
当某一台提供者挂时,原本发往该提供者的请求,基于虚拟节点,平摊到其它提供者,不会引起剧烈变动。

集群容错模式:

1、失败自动切换,当出现失败,重试其它服务器。(缺省)
通常用于读操作,但重试会带来更长延迟。
可通过retries="2"来设置重试次数(不含第一次,默认就是2)
2、快速失败,只发起一次调用,失败立即报错。
通常用于非幂等性的写操作,比如新增记录。
3、失败安全,出现异常时,直接忽略。
通常用于写入审计日志等操作。
4、失败自动恢复,后台记录失败请求,定时重发。
通常用于消息通知操作。
5、并行调用多个服务器,只要一个成功即返回。
通常用于实时性要求较高的读操作,但需要浪费更多服务资源。
可通过forks="2"来设置最大并行数。
6、广播调用所有提供者,逐个调用,任意一台报错则报错。(2.1.0开始支持)
通常用于通知所有提供者更新缓存或日志等本地资源信息。
重试次数配置如:(failover集群模式生效)

高并发下接口幂等性解决方案

1、为什么要有Dubbo的原因

各个团队的服务提供方就不要各自实现一套序列化、反序列化、网络框架、连接池、收发线程、超时处理、状态机等“业务之外”的重复技术劳动,造成整体的低效。

2.MQ分布式系统事务一致性解决方案

分布式系统事务一致性解决方案-InfoQ

3.redis分布式缓存

分布式缓存技术redis学习系列(三)——redis高级应用(主从、事务与锁、持久化)_javaloveiphone的专栏-CSDN博客

http://blog.csdn.net/javaloveiphone/article/details/52352894

4.redis和memcached的区别

1、Redis和Memcache都是将数据存放在内存中,都是内存数据库。不过memcache还可用于缓存其他东西,例如图片、视频等等;

2、Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,hash等数据结构的存储;

3、虚拟内存--Redis当物理内存用完时,可以将一些很久没用到的value 交换到磁盘;

4、过期策略--memcache在set时就指定,例如set key1 0 0 8,即永不过期。Redis可以通过例如expire 设定,例如expire name 10;

5、分布式--设定memcache集群,利用magent做一主多从;redis可以做一主多从。都可以一主一从;

6、存储数据安全--memcache挂掉后,数据没了;redis可以定期保存到磁盘(持久化);

7、灾难恢复--memcache挂掉后,数据不可恢复; redis数据丢失后可以通过aof恢复;

8、Redis支持数据的备份,即master-slave模式的数据备份;

9、应用场景不一样:Redis出来作为NoSQL数据库使用外,还能用做消息队列、数据堆栈和数据缓存等;Memcached适合于缓存SQL语句、数据集、用户临时性数据、延迟查询数据和session等。

5、Zookeeper的临时节点是否有子节点

没有

6、Dubbo 为什么要选择使用zookeeper做为注册中心,而不用redis?

zookeeper的优势:
1.当提供程序意外停止时,注册表服务器可以自动删除其信息。
2.注册表服务器重新启动时,可以自动恢复所有注册数据和订阅请求。
3.会话过期后,可以自动恢复所有注册数据和订阅请求。
redis存在的问题?
redis是通过发布订阅模式完成消息的通知 但是存在几个问题:
1.服务的非自然下线需要监护中心来维护
2.redis做注册中心服务器时间必需同步,否则出现时间不对被强制过期(删除key)!
3.zookeeper支持监听,redis不支持,因此需要客户端启动多个线程进行订阅监听,对服务器有一定压力!

 

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
4天前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
16 2
|
9天前
|
存储 算法 Java
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
本文详解自旋锁的概念、优缺点、使用场景及Java实现。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
|
14天前
|
存储 缓存 Oracle
Java I/O流面试之道
NIO的出现在于提高IO的速度,它相比传统的输入/输出流速度更快。NIO通过管道Channel和缓冲器Buffer来处理数据,可以把管道当成一个矿藏,缓冲器就是矿藏里的卡车。程序通过管道里的缓冲器进行数据交互,而不直接处理数据。程序要么从缓冲器获取数据,要么输入数据到缓冲器。
Java I/O流面试之道
|
10天前
|
存储 缓存 Java
大厂面试必看!Java基本数据类型和包装类的那些坑
本文介绍了Java中的基本数据类型和包装类,包括整数类型、浮点数类型、字符类型和布尔类型。详细讲解了每种类型的特性和应用场景,并探讨了包装类的引入原因、装箱与拆箱机制以及缓存机制。最后总结了面试中常见的相关考点,帮助读者更好地理解和应对面试中的问题。
34 4
|
11天前
|
存储 Java 程序员
Java基础的灵魂——Object类方法详解(社招面试不踩坑)
本文介绍了Java中`Object`类的几个重要方法,包括`toString`、`equals`、`hashCode`、`finalize`、`clone`、`getClass`、`notify`和`wait`。这些方法是面试中的常考点,掌握它们有助于理解Java对象的行为和实现多线程编程。作者通过具体示例和应用场景,详细解析了每个方法的作用和重写技巧,帮助读者更好地应对面试和技术开发。
51 4
|
1月前
|
存储 安全 算法
Java面试题之Java集合面试题 50道(带答案)
这篇文章提供了50道Java集合框架的面试题及其答案,涵盖了集合的基础知识、底层数据结构、不同集合类的特点和用法,以及一些高级主题如并发集合的使用。
83 1
Java面试题之Java集合面试题 50道(带答案)
|
23天前
|
存储 Java 程序员
Java面试加分点!一文读懂HashMap底层实现与扩容机制
本文详细解析了Java中经典的HashMap数据结构,包括其底层实现、扩容机制、put和查找过程、哈希函数以及JDK 1.7与1.8的差异。通过数组、链表和红黑树的组合,HashMap实现了高效的键值对存储与检索。文章还介绍了HashMap在不同版本中的优化,帮助读者更好地理解和应用这一重要工具。
51 5
|
22天前
|
存储 Java
[Java]面试官:你对异常处理了解多少,例如,finally中可以有return吗?
本文介绍了Java中`try...catch...finally`语句的使用细节及返回值问题,并探讨了JDK1.7引入的`try...with...resources`新特性,强调了异常处理机制及资源自动关闭的优势。
18 1
|
1月前
|
Java 程序员
Java 面试高频考点:static 和 final 深度剖析
本文介绍了 Java 中的 `static` 和 `final` 关键字。`static` 修饰的属性和方法属于类而非对象,所有实例共享;`final` 用于变量、方法和类,确保其不可修改或继承。两者结合可用于定义常量。文章通过具体示例详细解析了它们的用法和应用场景。
28 3
|
2月前
|
设计模式 Java 关系型数据库
【Java笔记+踩坑汇总】Java基础+JavaWeb+SSM+SpringBoot+SpringCloud+瑞吉外卖/谷粒商城/学成在线+设计模式+面试题汇总+性能调优/架构设计+源码解析
本文是“Java学习路线”专栏的导航文章,目标是为Java初学者和初中高级工程师提供一套完整的Java学习路线。
410 37