1. a是64位有/无符号整型, a=0xF000000000000000-0x7FFFFFFFFFFFFFFF,求a的10进制值.
  2. 集合元素的修改
    Arrays.asList() 用此方法得到的List的长度是不可改变的
    getClass()方法得到的类为: java.util.Arrays$ArrayList
    
  3. final在java中的用法: 深入理解Final关键字
    匿名内部类中使用的外部局部变量只能是final变量
    为了避免内部类销毁时讲外部变量一同销毁,内部类拷贝了一份
    既然有两份,就有可能数据不一致,所以就定义为final
    
  4. 内部类能访问外部类的哪些属性: Java内部类详解 ``` 为何使用内部类:
  5. 隐藏你不想让别人知道的操作,也即封装性
  6. 一个内部类对象可以访问创建它的外部类对象的内容,甚至包括私有变量 ```

  7. Comparator与Comparable接口的区别
    用Comparable 简单, 只要实现Comparable 接口的对象直接就成为一个可以比较的对象,
    但是需要修改源代码, 用Comparator 的好处是不需要修改源代码, 而是另外实现一个比较器, 当某个自定义
    的对象需要作比较的时候,把比较器和对象一起传递过去就可以比大小了, 并且在Comparator 里面用户可以自
    己实现复杂的可以通用的逻辑,使其可以匹配一些比较简单的对象,那样就可以节省很多重复劳动了。
    
  8. Redis,Zookeeper实现分布式锁的应用场景区别
    Redis抢不到就放弃,不必须获得锁
    Zookeeper抢不到就等待,必须获得锁
    
  9. 类静态变量,方法内部变量,类变量 分别在JVM/栈帧什么位置
  10. Integer(64),与64是否相等: 相等
  11. System.out.print(i+=++i)输出多少: 等于3
    i=1
    问System.out.print(i+=++i)等于多少;
    
int i =2;
int res=0;
switch(i):
    case(1): res+=1;
    case(2): res+=1;
    case(3): res+=1;
问res的值
  1. JVM大小 ``` Xmn=5G, Xms=10G, Xmx=10G, -XX:SurvivorRatio=3, 选择内存比例JVM堆大小及年轻代大小 10G,1g 10G,2G 5G,1G 5G,2G

-Xmn : the size of the heap for the young generation SurvivorRatio: eden: from NewRatio: old generation : young generation

C:\herong>java -Xms20m -Xmx20m -XX:NewRatio=1 -XX:SurvivorRatio=6 -XX:+UseSerialGC -Xlog:gc+heap=info GarbageCollection … [debug][gc,heap] GC(0) Heap after GC invocations=1 (full 0): def new generation total 8960K, used 1279K [… [debug][gc,heap] GC(0) eden space 7680K, 0% used [… [debug][gc,heap] GC(0) from space 1280K, 99% used [… [debug][gc,heap] GC(0) to space 1280K, 0% used [… [debug][gc,heap] GC(0) tenured generation total 10240K, used 1590K [… [debug][gc,heap] GC(0) the space 10240K, 15% used […

12. Interface只能添加什么修饰符? public
13. 下面代码输出的值: 71.23

int b = 5; int c = 1.23; System.out.print(‘a’+b+c);

14. 子类与父类构造器的关系: 默认super调用

选择:

  1. 子类无条件继承父类无参构造器
  2. 子类需要用super调用父类构造器
  3. 其他

其实每个子类构造方法的第一条语句,都是隐含地调用super(),如果父类没有这种形式的构造函数,那么在编译的时候就会报错。

15. redis哨兵模式(如何设置哨兵模式,哨兵节点如何对其他节点监控的,如何选举出领导者节点) 
  1. 主从复制技术 每一个 Redis 启动后,都会认为自己是一个 master 节点,你可以通过以下命令通知它成为 slave 并向 master 同步数据 另一种方式就是在 Redis 启动配置文件中直接指明让它作为一个 slave 节点启动,并在启动后同步 master 节点数据。配置项和命令是一样的。 除此之外,salve 节点默认是只读的,不允许写入数据,因为如果支持写入数据,那么与 master 就无法保持数据一致性,所以我们一般会把 slave 节点作为读写分离中读服务提供者。当然,你也可以修改是否允许 slave 写入数据:

slave 同步 master 的数据主要分为两个大步骤,全量复制和部分复制。当我们执行 slaveof 命令的时候,我们的 slave 会作为一个客户端连接上 master 并向 master 发送 PSYNC 命令。 master 收到命令后,会调用 bgsave fork 一个后台子进程生产 RDB 文件,待合适的时候,在 serverCron 循环的时候发送给 slave节点。 slave 收到 RDB 文件后,丢弃目前内存中所有的数据并阻塞自己,专心做 RDB 读取,数据恢复。 在主从节点完成第一轮全量复制以后,主从节点之间已经初步实现了数据同步,往后的 master,会将收到的每一条写命令发送给 slave 并 添加到复制缓冲区并根据字节数计算更新自己的偏移量,slave 收到传输过来的命令后也一样更新自己的偏移量。

  1. 哨兵模式 通过一次全量复制和不间断的命令传播,可以达到主从节点数据同步备份的效果,一旦主节点宕机,我们可以选择一个工作正常的 slave 成为新的主节点,并让其他 slave 去同步它。 主从复制不具备生产实用性,因为毕竟是手动处理故障,而 redis 发生故障时间节点不可预知,我们需要一个自动监控组件帮我们自动处理故障转移。 Redis 哨兵模式(Sentinel)就是一个自动地监控处理 redis 间故障节点转移工作的一个「东西」,准确来说,Sentinel 其实是一个 redis 服务端程序,只不过运行在特殊的模式下,不提供数据存储服务,只进行普通 redis 节点监控管理。

Sentinel 其实也是一个 redis 的服务端程序,它也会定时执行 serverCron 函数,只是里面其他的程序用不到,用到的是对普通 redis 节点的监控以及故障转移模块。 Sentinel 会定时的对自己监控的 master 执行 info 命令,获取最新的主从关系,还会定时的给所有的 redis 节点发送 ping 心跳检测命令, 如果检测到某个 master 无法响应了,就会在给其他 Sentinel 发送消息,主观认为该 master 宕机,如果 Sentinel 集群认同该 master 下线的人数达到一个值,那么大家统一意见,下线该 master。

下线之前需要做的是找 Sentinel 集群中的某一个来执行下线操作,这个步骤叫领导者选举,选出来以后会从该 master 所有的 slave 节点中挑一个合适的作为新的 master,并让其他 slave 重新同步新的 master。

通过命令 sentinel monitor mymaster 配置当前 sentinel 需要监控的主节点 redis 以及触发客观下线参数

redis节点失败达成共识:

主观下线:每隔1秒每个sentinel对其他的redis节点(master,slave,sentinel)执行ping操作, 若超过down-after-milliseconds内没有回复,就对该节点进行主观下线,每个sentinel节点对redis节点失败的“偏见” 客观下线:当sentinel主观下线的节点是主节点时,sentinel会通过命令sentinel is-master-down-by-addr来询问其sentinel对主节点的判断,如果超过quorum个数就认为主节点需要客观下线, 所有sentinel节点对redis节点失败达成共识

选举方式: 1、每个做主观下线的sentinel节点像其他sentinel节点发送命令,要求将自己设置为领导者 2、接收到的sentinel可以同意或者拒绝 3、如果该sentinel节点发现自己的票数已经超过半数并且超过了quorum 4、如果此过程选举出了多个领导者,那么将等待一段时重新进行选举

选择主节点: 1、选择健康状态从节点(排除主观下线、断线),排除5秒钟没有心跳的、排除主节点失联超过10*down-after-millisecends 2、选择slave-priority高的从节点优先级列表 4、选择偏移量大的 5、选择runid小的

16. java泛型通配符,泛型中extends和super的区别

List<? super Number> l = new ArrayList<>(); Integer a = new Integer(1); l.add(a);

17. 泛型:List<?> la = List<A> 和List<?> lb = List<B>,la和lb的class是否相同

都是class java.util.ArrayList

18. Java对象头的长度,开启压缩之后的长度,数组的对象头有什么不同

32JVM是32bit,64JVM是64bit 64位的JVM将会比32位的JVM多耗费50%的内存。为了节约内存可以使用选项+UseCompressedOops开启指针压缩,

其中,oop即ordinary object pointer普通对象指针。开启该选项后,下列指针将压缩至32位: 每个Class的属性指针(即静态变量) 每个对象的属性指针(即对象变量) 普通对象数组的每个元素指针

如果对象是一个数组,那么对象头还需要有额外的空间用于存储数组的长度,这部分数据的长度也随着JVM架构的不同而不同 :32位的JVM上,长度为32位;64位JVM则为64位。 64位JVM如果开启+UseCompressedOops选项,该区域长度也将由64位压缩至32位。

18. 为什么需要一致性哈希

一致性哈希算法在 1997 年由麻省理工学院提出,是一种特殊的哈希算法,在移除或者添加一个服务器时, 能够尽可能小地改变已存在的服务请求与处理请求服务器之间的映射关系。一致性哈希解决了简单哈希算法 在分布式哈希表(Distributed Hash Table,DHT)中存在的动态伸缩等问题 。

平衡性:是指 hash 的结果应该平均分配到各个节点,这样从算法上解决了负载均衡问题。

单调性:是指在新增或者删减节点时,不影响系统正常运行。

分散性:是指数据应该分散地存放在分布式集群中的各个节点(节点自己可以有备份),不必每个节点都存储所有的数据。

一致性哈希算法通过一个叫作一致性哈希环的数据结构实现。这个环的起点是 0,终点是 2^32 - 1,并且起点与终点连接,故这个环的整数分布范围是 [0, 2^32-1]


19. Redis的优化

[Redis 性能优化的 13 条军规!](https://segmentfault.com/a/1190000022172968)

缩短键值对的存储长度; 使用 lazy free(延迟删除)特性; 设置键值的过期时间; 禁用长耗时的查询命令; 使用 slowlog 优化耗时命令; 使用 Pipeline 批量操作数据; 避免大量数据同时失效; 客户端使用优化; 限制 Redis 内存大小; 使用物理机而非虚拟机安装 Redis 服务; 检查数据持久化策略; 禁用 THP 特性; 使用分布式架构来增加读写速度。


20. Mysql explain

21. 如何保证TCP的传输可靠性
[https://zhuanlan.zhihu.com/p/112317245](https://zhuanlan.zhihu.com/p/112317245)

TCP主要提供了检验和、序列号/确认应答、超时重传、最大消息长度、滑动窗口控制等方法实现了可靠性传输。

22. finalize()在什么时候调用,GC的哪个阶段,调用几次?

当对象变成(GC Roots)不可达时,GC会判断该对象是否覆盖了finalize方法,若未覆盖,则直接将其回收。 否则,若对象未执行过finalize方法,将其放入F-Queue队列,由一低优先级线程执行该队列中对象的finalize方法。 执行finalize方法完毕后,GC会再次判断该对象是否可达,若不可达,则进行回收,否则,对象“复活”。 JVM只会至多调用finalize一次 但建议用于:① 清理本地对象(通过JNI创建的对象);② 作为确保某些非内存资源(如Socket、文件等)释放的一个补充:在finalize方法中显式调用其他资源释放方法。

23. 网络分层

1、物理层(即OSI模型中的第一层也是最底层):

物理层实际上就是布线、光纤、网卡和其它用来把两台网络通信设备连接在一起的东西。甚至一个信鸽也可以被认为是一个1层设备。网络故障的排除经常涉及到1层问题。

2、数据链路层:

运行以太网等协议。网桥都在2层工作,仅关注以太网上的MAC地址。有关MAC地址、交换机或者网卡和驱动程序,就是在第2层的范畴。集线器属于第1层的领域,因为它们只是电子设备,没有2层的知识。

3、网络层:

网络层的任务就是选择合适的网间路由和交换结点, 确保数据及时传送。如果你在谈论一个IP地址,那么你是在处理第3层的问题,这是“数据包”问题,而不是第2层的“帧”。 IP是第3层问题的一部分,此外还有一些路由协议和地址解析协议(ARP)。有关路由的一切事情都在第3层处理。地址解析和路由是3层的重要目的。

4、信息的传输层(TCP UDP):

第4层的数据单元也称作数据包(packets)。这个层负责获取全部信息,因此,它必须跟踪数据单元碎片、乱序到达的数据包和其它在传输过程中可能发生的危险。

理解第4层的另一种方法是,第4层提供端对端的通信管理。像TCP等一些协议非常善于保证通信的可靠性。有些协议并不在乎一些数据包是否丢失,UDP协议就是一个主要例子。

5、会话层:

这一层也可以称为会晤层或对话层,在会话层及以上的高层次中,数据传送的单位不再另外命名,统称为报文。会话层不参与具体的传输,它提供包括访问验证和会话管理在内的建立和维护应用之间通信的机制。如服务器验证用户登录便是由会话层完成的。

6、表示层:

这一层主要解决用户信息的语法表示问题。它将欲交换的数据从适合于某一用户的抽象语法,转换为适合于OSI系统内部使用的传送语法。即提供格式化的表示和转换数据服务。数据的压缩和解压缩, 加密和解密等工作都由表示层负责。

7、应用层:

是专门用于应用程序的。应用层确定进程之间通信的性质以满足用户需要以及提供网络与用户应用软件之间的接口服务。SMTP、DNS和FTP都是第7层协议。

24. 编译过程
![](/assets/笔试题记录/1.png)

25. 长连接和短连接的区别

我们模拟一下TCP短连接的情况,client向server发起连接请求,server接到请求,然后双方建立连接。client向server发送消息,server回应client, 然后一次读写就完成了,这时候双方任何一个都可以发起close操作,不过一般都是client先发起close操作。为什么呢,一般的server不会回复完client后立即关闭连接的, 当然不排除有特殊的情况。从上面的描述看,短连接一般只会在client/server间传递一次读写操作

短连接的优点是:管理起来比较简单,存在的连接都是有用的连接,不需要额外的控制手段

client向server发起连接,server接受client连接,双方建立连接。Client与server完成一次读写之后,它们之间的连接并不会主动关闭,后续的读写操作会继续使用这个连接。

服务器应用希望知道客户主机是否崩溃,从而可以代表客户使用资源。如果客户已经消失,使得服务器上保留一个半开放的连接, 而服务器又在等待来自客户端的数据,则服务器将应远等待客户端的数据,保活功能就是试图在服务器端检测到这种半开放的连接。

26. explain返回的字段

id 查询序号 select_type 查询类型 table 表名 partitions 匹配的分区 type join类型 prossible_keys 可能会选择的索引 key 实际选择的索引 key_len 索引的长度 ref 与索引作比较的列 rows 要检索的行数(估算值) filtered 查询条件过滤的行数的百分比 Extra 额外信息


27. CAP理论

(CAP)[https://developer.51cto.com/art/201909/602506.htm]

(1) CA: 优先保证一致性和可用性,放弃分区容错。 这也意味着放弃系统的扩展性,系统不再是分布式的,有违设计的初衷。

(2) CP: 优先保证一致性和分区容错性,放弃可用性。在数据一致性要求比较高的场合(譬如:zookeeper,Hbase) 是比较常见的做法,一旦发生网络故障或者消息丢失,就会牺牲用户体验,等恢复之后用户才逐渐能访问。

(3) AP: 优先保证可用性和分区容错性,放弃一致性。NoSQL中的Cassandra 就是这种架构。跟CP一样,放弃一致性不是说一致性就不保证了,而是逐渐的变得一致。

Redis Cluster:AP Zookeeper:CP leader选举时可能服务不可用 Kafka:取决于配置

28. TCP连接状态与TIME_WAIT过多

通信双方建立TCP连接后,主动关闭连接的一方就会进入TIME_WAIT状态。

客户端主动关闭连接时,会发送最后一个ack后,然后会进入TIME_WAIT状态,再停留2个MSL时间(后有MSL的解释),进入CLOSED状态。

TIME_WAIT状态存在的理由: 1、可靠地实现TCP全双工连接的终止 TCP协议在关闭连接的四次握手过程中,最终的ACK是由主动关闭连接的一端(后面统称A端)发出的,如果这个ACK丢失,对方 (后面统称B端)将重发出最终的FIN,因此A端必须维护状态信息(TIME_WAIT)允许它重发最终的ACK。如果A端不维持TIME_WAIT状态, 而是处于CLOSED 状态,那么A端将响应RST分节,B端收到后将此分节解释成一个错误 (在java中会抛出connection reset的SocketException)。

2、允许老的重复分节在网络中消逝 TCP分节可能由于路由器异常而“迷途”,在迷途期间,TCP发送端可能因确认超时而重发这个分节, 迷途的分节在路由器修复后也会被送到最终目的地,这个迟到的迷途分节到达时可能会引起问题。 在关闭“前一个连接”之后,马上又重新建立起一个相同的IP和端口之间的“新连接”, “前一个连接”的迷途重复分组在“前一个连接”终止后到达,而被“新连接”收到了。 为了避免这个情况,TCP协议不允许处于TIME_WAIT状态的连接启动一个新的可用连接, 因为TIME_WAIT状态持续2MSL,就可以保证当成功建立一个新TCP连接的时候,来自旧连接重复分组已经在网络中消逝。


29. Keep-Alive
[Keep-alive](https://www.cnblogs.com/skynet/archive/2010/12/11/1903347.html)

http 1.0中默认是关闭的,需要在http头加入”Connection: Keep-Alive”,才能启用Keep-Alive;http 1.1中默认启用Keep-Alive, 如果加入”Connection: close “,才关闭。目前大部分浏览器都是用http1.1协议,也就是说默认都会发起Keep-Alive的连接请求了, 所以是否能完成一个完整的Keep-Alive连接就看服务器设置情况。


30. kafka调优

[here](http://www.mobabel.net/%E6%80%BB%E7%BB%93kafka%E6%80%A7%E8%83%BD%E8%B0%83%E4%BC%98%E5%92%8C%E5%8F%82%E6%95%B0%E8%B0%83%E4%BC%98/)
[here](http://www.mobabel.net/%E8%BD%ACacks%E5%8F%82%E6%95%B0%E5%AF%B9%E6%B6%88%E6%81%AF%E6%8C%81%E4%B9%85%E5%8C%96%E7%9A%84%E5%BD%B1%E5%93%8D/)

Kafka配置的核心点在于磁盘刷新率。

Kafka的性能有两个指标:吞吐量、延迟率。
可以通过增加分区数、线程数、batch size,使得吞吐量得到改善:


1、Kafka JVM Heap Size 调整为不超过内存的50% 2、网络和ios操作线程配置优化: # broker处理消息的最大线程数 num.network.threads=9 # broker处理磁盘IO的线程数 num.io.threads=16 3、

生产者 linger.ms=50 batch.size=524288 compression.type=lz4 acks=1(用户要求消息至少要发送到分区 leader) max.request.size=5242880 buffer.memory=268435456

消费者: num.io.threads =8 CPU两倍

broker处理消息的最大线程数

num.network.threads=9

调整JVM大小 jstat -gcutil 增大Heap,减少GC次数 ```

  1. Kafka的缓冲池机制

深度剖析 Kafka Producer 的缓冲池机制【图解 + 源码分析】