面试杂谈1
字符串1234567String a = "a" + "b" + "c";String b = "abc";String c = "ab";String d = c + "c";System.out.println(a == b);System.out.println(a == d);
输出
12truefalse
CMS 能不能 初始标记 并发标记 重新标记 并发清理 去掉重新标记1 浮动垃圾 如图,GC 线程便利对象树(实际是图),遍历过了A ,然后遍历过了B,遍历到了C,但是还没有遍历完C的儿子D,这时候如果 A.B=null; 那么B就变成了浮动垃圾,本次GC 过程B不会被清除。只能下次清除。
2 GC 三色标记算法过程中,白色的节点指向 黑色的节点 怎么办?
直接把黑色变成灰色,这是浮动垃圾吗?不是,因为黑色节点变成了灰色,GC线程每次暂停后开始都会重灰色线程开始,也就是说黑色变成灰色以后,会重新便利这个灰色和下面的非黑色节点。
3 三色算法 ...
面试杂谈3
·····················································
RPC和HTTP的比较
HTTP 和 RPC 其实是两个维度的东西, HTTP 指的是通信协议。
而 RPC 则是远程调用,其对应的是本地调用。
RPC 的通信可以用 HTTP 协议,也可以自定义协议,是不做约束的。
可能你常听到什么什么之间是 RPC 调用的,那你有没有想过为什么要 RPC, 我们直接 WebClient HTTP 调用不行么?
其实 RPC 调用是因为服务的拆分,或者本身公司内部的多个服务之间的通信。
服务的拆分独立部署,那服务间的调用就必然需要网络通信,用 WebClient 调用当然可行,但是比较麻烦。
我们想即使服务被拆分了但是使用起来还是和之前本地调用一样方便。
所以就出现了 RPC 框架,来屏蔽这些底层调用细节,使得我们编码上还是和之前本地调用相差不多。
并且 HTTP 协议比较的冗余,RPC 都是内部调用所以不需要太考虑通用性,只要公司内部保持格式统一即可。
所以可以做各种定制化的协议来使得通信更高效。
比如规定 yes 代表 yes的练级攻略,你 ...
面试杂谈4
1.http三次握手,状态码,交互细节2.为什么要三次握手3.四次挥手,状态码,传输细节,为什么握手要三次,挥手要四次4.数据链路层怎么传输数据的,展开说说打包成帧(framing): 在每个网络层数据报在传输之前,几乎所有的链路层协议都会将数据报用链路层封装起来。数据链路层从网络层获取数据后将其封装成为 帧,如果帧太大的话,数据链路层会将大帧拆分为一个个的小帧,小帧能够使传输控制和错误检测更加高效。
帧就是 0 1 序列的封装。
一个帧由 Header、Payload Field、Trailer 组成,网络层数据报就封装在 Payload Field 字段中。根据不同的物理介质,每个帧的结构也不同。帧的组成如下
5.Arp协议中网关怎么去转换ip地址到对应MAC地址的https://xiaorui2.github.io/2019/06/28/Ping%E5%91%BD%E4%BB%A4%E7%9A%84%E6%89%A7%E8%A1%8C%E8%BF%87%E7%A8%8B%E5%92%8C%E5%BA%94%E7%94%A8%E5%8D%8F%E8%AE%AE/
6.MySQL ...
定位问题
定位问题的先决条件需要有详细的日志记录,提前告警的监控平台,事发现场保留
日志 :业务日志,中间件日志监控 :CPU、内存、磁盘、网络,类加载、GC、线程等快照 :-XX:+HeapDumpOnOutOfMemoryError 和 -XX:HeapDumpPath
分析问题,解决问题的思路
经验+直觉,快速定位 > 逐一排查,传输链路 > 寻找规律 不要轻易怀疑监控。考虑资源。优先保证系统能正常运行。保留现场,事后排查定位问题。
逐一排查,传输链路,通过日志或工具逐一排查
内部原因,是否是客户端或者前端问题,程序发布后的Bug,回滚后可以立即解决
外部原因,比如服务,第三方服务,主机、组件的问题。
服务:错误日志邮件提醒或elk快速定位问题,查看gc日志
第三方服务:单独调用测试,联系第三方加急解决
主机: CPU相关问题,可以使用 top、vmstat、pidstat、ps 等工具排查; 内存相关问题,可以使用 free、top、ps、vmstat、cachestat、sar 等工具排查;IO 相关问题,可以使用 lsof、iostat、pidstat、sar、 ...
bitMap讲解
小知识
在实际项目中,我们经常需要聚合统计,比如统计一个年龄在20-30,喜欢看技术书籍,喜欢听音乐,喜欢宅在家的程序员等等一系列标签的用户。 如果使用mysql求并集,首先语句随着标签变长而变长,其次聚合,分组,去重严重影响语句性能。这种情况如何解决?
比如现在比较火的面试题,在10亿整数中找出100个重复的数,或者任意给定一个整数,判断是否在这个10亿数中。
bitMap原理bitMap就是使用bit位来标记元素,key为该元素,value一般为0或者1,大大节省存储空间.
现在有(2, 3, 4, 5,7)5个数,任意给定一个在0-7范围内的数字,判断是否在此集合中:
创建一个范围为(0-7)的Byte类型数组,将集合数字对应数组的bit位置置1;
然后遍历该Byte数组,如果Byte数组位置为1即代表该数存在。
同理对于10亿整数也可以这样处理,一个int型数字4个字节,32bit,如果使用bit标记正整数,就可以节省32倍的内存空间。
10亿数字,40亿字节,320亿bit,需要大约4g内存,使用bitMap标记,只需要125M内存空间即可存储,大大节省内存空间。 ...
反射机制
RPC框架手撕之路—java反射以及动态代理机制在上一篇文章中,我们提到了,RPC框架所需要的java基础,第一点就是java的动态代理机制,动态代理机制的基础是反射,无论是在实际编程或者是面试时,都是java知识的重中之重。
定义:在运行状态中,对于任意一个类,都能够知道这一个类的所有属性和方法,对于任意一个对象都能够通过反射机制调用一个类的任意方法,这种动态获取类信息以及动态调用类方法的功能称为java的反射机制。
作用:1、动态的创建类的实例,将类绑定到现有对象中,或从现有对象中获取类型。 2、应用程序需要在运行时从某个特定的程序集中载入一个特定的类。
个人理解的反射机制就是,某些类在程序运行的一开始并没有加载,但是随着程序的运行,我们发现这些类也需要用到,此时就可以通过反射机制,来获取到类的属性和方法。
代理模式:定义:委托模式,是为某个对象提供一个代理对象,并且由代理对象控制对原对象的访问。代理模式通俗来讲就是我们生活中常见的中介。代理模式可以提供非常好的访问控制,应用比较广泛。
而其中的代理模式中的动态代理不仅在rpc远程访问中有重要的应用,同样在Spring AOP和其他 ...
Redis缓存与数据库一致性问题
在做系统优化时,想到了将数据进行分级存储的思路。因为在系统中会存在一些数据,有些数据的实时性要求不高,比如一些配置信息。
基本上配置了很久才会变一次。而有一些数据实时性要求非常高,比如订单和流水的数据。所以这里根据数据要求实时性不同将数据分为三级。
第1级:订单数据和支付流水数据;这两块数据对实时性和精确性要求很高,所以不添加任何缓存,读写操作将直接操作数据库。
第2级:用户相关数据;这些数据和用户相关,具有读多写少的特征,所以我们使用redis进行缓存。
第3级:支付配置信息;这些数据和用户无关,具有数据量小,频繁读,几乎不修改的特征,所以我们使用本地内存进行缓存。
但是只要使用到缓存,无论是本地内存做缓存还是使用 redis 做缓存,那么就会存在数据同步的问题,因为配置信息缓存在内存中,而内存时无法感知到数据在数据库的修改。这样就会造成数据库中的数据与缓存中数据不一致的问题。
解决方案那么我们这里列出来所有策略,并且讨论他们优劣性。
先更新数据库,后更新缓存
先更新数据库,后删除缓存
先更新缓存,后更新数据库
先删除缓存,后更新数据库
先更新数据库,后更新缓存这种场 ...
14.ReentrantLock实现公平锁和非公平锁
准备知识
理想情况下,线程A拿到锁,执行完后释放锁,线程B恰好到来顺手接下这把锁,一切都那么完美的话,也没必要加锁了,问题就在于在A没释放锁时,后续线程也想得到这把锁,所以只好让这些等待的线程进行排队,进而需要一套数据结构来组织这个队伍:
Node结点:作为获取锁失败线程的包装类, 组合了Thread引用, 实现为FIFO双向队列。 下图为Node结点的属性描述-
下图为用Node节点构成的双向链表图示:-
链表初始化的头节点其实是一个虚拟节点,英文名称之为dummy header, 因为它不会像后继节点一样真实的存放线程,并且这个节点只会在真正产生竞争排队情况下才会延迟初始化,避免性能浪费,下面看代码的时候,我会再次提到。-AbstractQueuedSynchronizer 类是一个模版类,维护了着一个同步队列(双向链表),提供着同步队列一些操作的公共方法,JUC并发包里基于此类实现了很多常用的并发工具类,如 Semaphore, CountDownLatch等。
1234/*** The synchronization state.*/private volatile int s ...
超卖问题
常见写法安全性及效率分析假设我们的商品表的schema是下面这样的:
12345678910111213CREATE TABLE `goods` (`````` `id` int(10) NOT NULL AUTO_INCREMENT COMMENT``` `'自增id'``,```` `name` varchar(256) NOT NULL DEFAULT``` `''` `COMMENT` `'商品名称'``,```` `available` int(11) unsigned NOT NULL DEFAULT``` `'0'` `COMMENT` `'库存剩余量'``,```` `stock` int(11) unsigned NOT NULL DEFAULT``` `'0'` `COMMENT` `'总库存量'``,````PRIMARY KEY (`id`)````) ENGINE=InnoDB DEFAULT CHARSET=utf8 C ...
消息队列幂等性
RabbitMQ消费幂等性什么是幂等性
幂等性,简单来说就是对于同一个系统,在同样条件下,一次请求和重复多次请求对资源的影响是一致的,就称该操作为幂等的。比如说如果有一个接口是幂等的,当传入相同条件时,其效果必须是相同的。在RabbitMQ中消费幂等就是指给消费者发送多条同样的消息,消费者只会消费其中的一条。例如,在一次购物中提交订单进行支付时,当网络延迟等其他问题造成消费者重新支付,如果没有幂等性的支持,那么会对同一订单进行两次扣款,这是非常严重的,因此有了幂等性,当对同一个订单进行多次支付时,可以确保只对同一个订单扣款一次。
RabbitMQ消费幂等性在正常情况下,消费者在消费消息的时候,当消费完毕后,会发送一个确认ack给消息队列,消息队列就知道该消息被消费了,就会将该消息从消息队列中删除。而在前面保证生产端消息可靠性投递方案1中,当生产者发送消息给RabbitMQ后,在Broker返回确认ack之前,RabbitMQ出现了宕机(数据库保存的消息状态仍然为“投递中”),则该消息会被定时任务抓取并重新发送;或者当在网络延迟传输中,消费者出现异常或者消费者延迟消费,会造成进行Rab ...