京东面经
了解哪些开源的rpc框架?dubbo的调用过程简单说一下?
1、RMI,远程方法调用;2、Hessian,基于HTTP的远程方法调用;3、Dubbo支持多种协议
dubbo调用过程:
角色:provider提供者,registry注册中心,consumer消费者
provider启动:向registry注册自己,能调用那些服务等
consumer启动:向registry注册获取provider列表,并进行本地缓存(这也就是当注册中心挂掉,consumer还能进行远程调用的原因)
consumer进行远程调用时:先根据接口进行代理找到最顶层Invoker,里面包含了可以调用的provider列表,也就是一堆invoker,通过loadBalance负载均衡选择某一个具体的invoker,然后进行filter过滤,具体的invoker使用执行的协议protocol发送数据到指定的provider,provider经过相同的协议解析数据,然后找到执行的invoker,调用具体实现的方法返回执行结果
补充:dubbo底层调用原理
shiro框架记住我的功能是怎么实现的?
在执行onSuccessfulLogin(token,info,logggedIn)方法中,有一个remeberSerializedIdentity()方法,该方法将用户信息,构造为一个SimpleCookie存放到request和response中实现记住我的功能
tcp协议建立连接、释放连接的过程。
tcp是传输层协议,建立连接需要进行三次握手,释放连接需要四次挥手
建立连接:
client发送SYN(seq=1000)到server 第一次握手
server发送SYN+ACK(seq=2000,ack=1001=client发送的seq+1)到client 第二次握手
client发送ACK(ack=2001=server发送的seq+1)到server 第三次握手
释放连接:
client发送FIN(seq=5000)到server 第一次挥手 我没有数据发送了,我想关闭连接了
server发送ACK(seq=6000,ack=5001=client发送的seq+1)到client 第二次挥手 知道了,我还没准备好
server发送FIN(seq=6001,ack=5001=client发送的seq+1)到client 第三次挥手 我也可以关闭连接了
client发送ACK(seq=5001=自己第一次发送的seq+1,ack=6002=server发送的seq+1)到server 第四次挥手,知道了拜拜
http、https的区别?
https协议需要到ca申请证书,一般免费证书很少,需要交费。
http是超文本传输协议,信息是明文传输,https 则是具有安全性的ssl加密传输协议
http和https使用的是完全不同的连接方式用的端口也不一样,前者是80,后者是443。
http的连接很简单,是无状态的
HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议 要比http协议安全
https加密的机制了解过吗?
采用对称加密+非对称加密的方式:
服务器持有公钥A,私钥A
1.服务器将公钥A通过明文方式发送给浏览器
2.浏览器生成对称加密的秘钥C,使用公钥A加密后发送给服务器
3.服务器使用私钥A将拿到的密文解密成秘钥C
4.之后浏览器跟服务器之间的数据传递都使用秘钥C加解密方式进行传输
看着好像没问题,请看下面的流程
1.服务器将公钥A通过明文方式发送给浏览器
中间人劫持到公钥A,中间人有公钥B和私钥B,他将公钥B传送给浏览器,自己保留公钥A
2.浏览器生成对称加密的秘钥C,使用公钥B加密后发送给服务器
中间人拿到浏览器生成的秘钥C的密文,使用自己的私钥B进行解密,拿到了密钥C,他再使用公钥A加密密钥C,发送到服务器
3.服务器使用私钥A将拿到的密文解密成秘钥C
4.之后浏览器跟服务器之间的数据传递都使用秘钥C加解密方式进行传输
到这里浏览器,中间人,服务器都有了秘钥C,意思是浏览器与服务器进行数据交互,中间人都可以解析成明文
这里就引入了CA证书,CA证书包含了网站信息,公钥信息,服务器传递给浏览器的就是证书
创建线程有哪几种方式?
1.直接继承Thread
2.实现Runnable接口
2.实现Callable接口
Runnable和Callable创建线程有什么区别?
Runnable:没有返回值,外面不能捕获到异常
Callable:有返回值,外面可以捕获到异常
线程池哪几种?分别说一下
corePoolSize:核心线程数,如果他们创建了,它们会一直存在于线程池中,直到线程池关闭
maximunPoolSize:线程池可创建的最大线程数(核心线程与辅线程总和),这个值必须大于corePoolSize的值,否则会抛IllegalArgumentException
keepAliveTime:辅线程的空闲等待时间,一个辅线程等待多少时间还没有任务给它处理,它就被销毁
unit:keepAliveTime的单位(天,小时,分钟,秒,毫秒等等)
workQueue:任务等待队列,如果需要处理的任务大于线程池中的线程数,未处理的任务会暂存在任务队列(ps:不一定会保存任务到队列,需要根据当前任务队列的类型来判断,后面详细讲解)
threadFactory:线程创建工厂,一般使用默认(Executors.defaultThreadFactory())即可,可以自定义
handler:拒接策略,如果线程池中线程都在处理任务,任务队列中保存的任务也达到最大值,不能再接收任务了,如何拒绝
Java里面的锁有哪些?
乐观锁:cas
悲观锁:每次读写数据都怕别人修改,就加上锁
自旋锁:如果别的线程占用了资源,自旋一段时间,不直接进入阻塞,自旋期间就获取到资源就不用进行上下文切换,提高效率
可重入锁:线程A占用了资源B,线程A需要再访问资源B可以直接访问,可重入
公平锁:资源等待队列,谁先来,下次先把资源交给谁
非公平锁:随机分配资源给某个线程,可能导致某个线程一直分配不到资源,饥饿等待
说说volatile 关键字的作用
保证了可见性,有序性(禁止指令重排)
一般的变量在使用时,线程会将变量的值拷贝一份到自己的工作内存,这就会导致有的线程更新了数据,
还未刷新到主内存,别的线程使用的还是原来的旧数据,导致程序的最终值与期望值相差很大,使用volatile
关键之修饰的变量,线程每次使用变量时,都会直接到主内存中取,保证了可见性,一个线程对该变量的修改,
对其他线程来说是立即可见的
mysql有哪些锁?
行锁(Record Locks)
间隙锁(Gap Locks)
临键锁(Next-key Locks)
共享锁/排他锁(Shared and Exclusive Locks)
意向共享锁/意向排他锁(Intention Shared and Exclusive Locks)
插入意向锁(Insert Intention Locks)
自增锁(Auto-inc Locks)
select for update是表锁还是行锁?
如果查询条件用了索引/主键,那么select ..... for update就会进行行锁。
如果是普通字段(没有索引/主键),那么select ..... for update就会进行锁表。
加了索引一定会走索引吗?索引失效的情况有哪些
不一定会走索引,有很多索引失效的情况:
1.like后匹配,例如'%张'
2.组合索引,没有按照顺序使用,例如age,name,address, 查询时直接使用name
3.如果字段为字符串类型,一定要加引号,否则存在隐式转换
4.对字段进行了计算或者使用函数的,例如left(name,2) = 'xxx'
mysql索引失效的几种情况
如果我想要强制走某个索引,能实现吗?
使用force index关键字
select *from table force index(index1,index2)
说一下Spring bean的生命周期?bean什么时候会被销毁呢?
生命周期:
1.实例化
2.设置属性
3.如果实现了BeanNameware就调用setBeanName
4.如果实现了BeanFactoryAware就调用setBeanFactory
5.如果实现了ApplicationContextAware就调用setApplicationContext
6.如果实现了BeanPostProcessor就调用postProcessorBeforeInitalization
7.如果实现了InitailzingBean方法就调用afterPropertiesSet
8.如果实现了BeanPostProcessor就调用postProcessorAfterInitalization
9.如果实现了DisposableBean就调用destroy方法
什么时候销毁:
singleton的会存放到上下文销毁时,才会销毁
prototype 又叫多例模式,用的时候就new一下,用完就没有了。
session 存在这一次会话 session 中,session没有过期它就一直存在,session过期后它就没了。
request 存在这一次请求中,请求结束了它就结束。