• 面试题目总结(1) https中间人攻击,ConcurrentHashMap的原理 ,serialVersionUID常量,redis单线程,


    1.HTTPS协议中间人攻击是什么? 

    https是 对http内容的加密,中间人攻击是指攻击者通过与客户端和客户端的目标服务器同时建立连接,作为客户端和服务器的桥梁,处理双方的数据,整个会话期间的内容几乎是完全被攻击者控制的。攻击者可以拦截双方的会话并且插入新的数据内容。

    “中间人攻击”原理
    1.客户端请求被劫持(如DNS劫持等),所有的客户端请求均被转发至中间人的服务器
    2.中间人服务器返回中间人伪造的“伪证书”(包含伪公钥);
    3.客户端创建随机数,通过中间人证书的伪公钥对随机数进行加密后传输给中间人,然后凭随机数构造对称加密算法对要进行传输的数据内容进行对称加密后传输;
    4.中间人因为拥有客户端生成的随机数,从而能够通过对称加密算法进行数据内容解密;
    5.中间人再以“伪客户端”的身份向正规的服务端发起请求;
    6.因为中间人与服务器之间的通信过程是合法的,正规服务端通过建立的安全通道返回加密后的数据内容;
    7.中间人凭借与正规服务器建立的对称加密算法进行数据内容解密;
    8.中间人再通过与客户端建立的对称加密算法对正规服务器返回的数据内容进行加密传输;
    9.客户端通过中间人建立的对称加密算法对返回的数据内容进行解密;

    由于缺少对证书的真伪性验证,所有客户端即使发起了Https请求,但客户端完全不知道自己发送的请求已经被第三方拦截,导致其中传输的数据内容被中间人窃取。

    扩展 https 的工作过程 

    证书验证阶段
          1.浏览器发起Https请求;
          2.服务器端返回Https证书(包含公钥);
          3.浏览器客户端验证证书是否合法,若不合法则提示警告

    数据传输阶段
         4.当证书验证合法后,在客户端本地生成随机数;
         5.通过公钥加密随机数,并将其传输到服务端
         6.服务端通过私钥对接收到的加密随机数进行解密操作;
         7.服务端通过客户端传入的随机数构造对称加密算法,对返回结果内容进行加密操作

               后再 进行内容传输。

    为什么数据传输是用对称加密?
           首先,非对称加密的加密效率低的,而http的应用场景通常存在着端与端之间的

                     大量数据交互,从效率来说是无法接受的;
            其次,在Https场景中只有服务端保存了私钥,而一对公私钥只能实现单向的加解密(即   服务端无法使用私钥对传回浏览器客户端的数据进行加密,只能用于解密),所以         Https中内容传输加密采取的是对称加密,(此处随机数则是对称加密的介体,

       即客户端和服务器端所拥有的随机数都是一致的,能够进行双向加解密)

    浏览器如何确保CA证书的合法性

        1.证书包含的主要信息:

                颁发机构信息,公钥,公司信息,域名,有效期,指纹,等等
       2.证书的合法性依据
             首先,权威机构是需要通过认证的。其次证书的可信性基于信任制,CA认证

               机构需要  对其颁发的证书进行信用担保,只要是CA认证机构颁发的证书,

               我们就认为是合法的。CA认证机构会对证书申请人的信息进行审核的。

    3.浏览器如何验证证书的合法性?
    浏览器发起https请求时,服务器会返回网站的SSL证书,浏览器需要对证书做以下验证:

    验证域名、有效期等信息是否正确
    判断证书来源是否合法。每份签发证书都可以根据验证链查找到对应的根证书,操作系统、浏览器会在本地存储权威机构的根证书,利用本地根证书可以对对应机构签发的证书进行来源验证; 

     判断证书是否被篡改。需要与CA服务器进行对比校验;
    判断证书是否已被吊销。通过CRL(Certificate Revocation List 证书注销列表) 和 OCSP(Online Certificate Status Protocol 在线证书状态协议)实现,其中OCSP可用于第3步中以减少与CA服务器的交互,提高验证效率。
    以上任意一步都同时满足的情况下,浏览器才认为证书是合法的。

    2. ConcurrentHashMap的实现原理 

             因为 hashmap 如果插入元素超过了容量的范围(负载因子决定)就会  触发扩容操作, 他会把原来的数组内容 重新 hash 到新的扩容数组中, 在多线程的情况下,jdk 1.7 采用头插法插入链表元素,会造成 扩容死链,jdk 1.8 采用尾插法,避免了,但是他们都会出现数据丢失覆盖的情况,而 HashTable 他是线程安全 的,但是多线程操作,加上synchronized 关键字,来锁住整个table,降低了并发度   所以后来就产生 ConcurrentHashMap,      他在jdk 1.7 采用 一个大的Segment 数组和多个 HashEntry 小数组+链表,大数组能够把大的table 分割成 小的table来加锁,降低了锁的粒度, JDK 1.8 中直接用  Node数组+链表+红黑树的数据结构来实现,并发控制使用Synchronized和CAS来操作

     

     扩展  插入扩容等流程

    1.插入数据时会进行加锁处理,但锁定的不是整个数组,而是槽中的头节点。所以,                       ConcurrentHashMap中锁的粒度是槽,而不是整个数组,并发的性能很好

    2. 扩容时会进行加锁处理,锁定的仍然是头节点。并且,支持多个线程同时对数组扩容

         提高并发能力。每个线程需先以CAS操作抢任务,争抢一段连续槽位的数据转移权。

         抢到任务后,该线程会锁定槽内的头节点,然后将链表或树中的数据迁移到新的数组里。

         每个小数组的扩容相对独立,小数组在超过扩容因子时会触发扩容,每次扩容翻倍

    3. 查找数据不会加锁,在扩容的过程中,依然可以支持查找操作,如果某个槽还未进行迁              移,则直接可以从旧数组里找到数据,如果某个槽已经迁移完毕,但是整个扩容还没

            结 束,那么这个查找的线程,就会帮助扩容,直到完成,再去查找元素

    3.Serializable接口为什么需要定义serialVersionUID常量

       序列化 (将对象转换成字节序列)在运行时使用serialVersionUID 版本号,与每个可序列化的类相关联,在反序列化过程中 用于验证序列化对象的发送者   和接收者是否为   该对象加载了与序列化兼容的类,如果接收者加载的该对象的类的 serialVersionUID 与对应的发送者的类的版本号不同,则反序列化将会导致 InvalidClassException             如果类的修改会导致反序列化失败,则应该为此类分配新的serialVersionUID   如果修改类时只是修改了方法,或只是修改了静态变量  则反序列化不受影响。.如果修改类时改变了实例变量,则可能导致反序列化失败

     4.说一说Redis的单线程模型

       Redis的网络IO和键值对读写是由一个线程来完成的,但Redis的其他功能,例如持久化、异步删除、集群数据同步等操作依赖于其他线程来执行。单线程可以简化数据结构和算法的实现,并且可以避免线程切换和竞争造成的消耗。但要注意如果某个命令执行时间过长,会造成其他命令的阻塞。Redis采用了IO多路复用机制,这带给了Redis并发处理大量客户端请求的能力。

    redis 线程模型

     

  • 相关阅读:
    uniapp 开发微信小程序 出现启用组件按需注入问题如何解决
    《算法竞赛进阶指南》 雪花雪花雪花
    python笔记7(函数补充)
    【torch.nn.init】初始化参数方法解读
    Vue3的异步组件使用
    Java基础11——抽象类和接口
    进程与线程的关系,进程调度的基本过程
    Python 并发编程实战,多线程、多进程加速程序运行
    How to config secured and stable Jenkins connection
    初始JDBC 编程
  • 原文地址:https://blog.csdn.net/qq_52252193/article/details/125522381