当前位置: 首页 > news >正文

网站建设公司好发信息网安吉网站建设公司

网站建设公司好发信息网,安吉网站建设公司,9.9网站怎么做,前端培训的机构目录 1.HashMap底层数据结构2.列举几个常见的线程安全容器3.HashMap线程问题4.concurrentHashMap5.ConcurrentModificationException6.Spring AOP、IOC、DI介绍下7.不使用依赖注入#xff0c;使用传统方式的声明会有什么问题8.最左前缀原则9.TCP三次握手、四次挥手 1.HashMap底… 目录 1.HashMap底层数据结构2.列举几个常见的线程安全容器3.HashMap线程问题4.concurrentHashMap5.ConcurrentModificationException6.Spring AOP、IOC、DI介绍下7.不使用依赖注入使用传统方式的声明会有什么问题8.最左前缀原则9.TCP三次握手、四次挥手 1.HashMap底层数据结构 在 JDK 1.7 中HashMap 使用的是数组 链表实现。 在 JDK 1.8 中使用的是数组 链表或红黑树实现的。 put实现原理 1先判断当前Node[]数组是不是为空为空就新建不为空就对hash值与容量-1做与运算得到数组下标 2然后会判断当前数组位置有没有元素没有的话就把值插到当前位置有的话就说明遇到了哈希碰撞 3遇到哈希碰撞后如果Hash值相同且equals内容也相同直接覆盖就会看下当前链表是不是以红黑树的方式存储是的话就会遍历红黑树看有没有相同key的元素有就覆盖没有就执行红黑树插入 4如果是普通链表则按普通链表的方式遍历链表的元素判断p.next null的情况下直接存放追加在next后面,然后我们要检查一下如果链表长度大于8且数组容量64链表转换成红黑树否则查找到链表中是否存在该key如果存在直接修改value值如果没有继续遍历 5如果size threshold(阈值)就扩容 HashMap中put的实现原理 HashMap何时会链表转红黑树 2.列举几个常见的线程安全容器 1.Vector 2.HashTable 3.ConcurrentHashMap:分段 4.CopyOnWriteArrayList写时复制 5.CopyOnWriteArraySet写时复制 3.HashMap线程问题 JDK1.8 中由于多线程对HashMap进行put操作调用了HashMap#putVal()具体原因假设两个线程A、B都在进行put操作并且hash函数计算出的插入下标是相同的当线程A执行完第六行代码后由于时间片耗尽导致被挂起而线程B得到时间片后在该下标处插入了元素完成了正常的插入然后线程A获得时间片由于之前已经进行了hash碰撞的判断所有此时不会再进行判断而是直接进行插入这就导致了线程B插入的数据被线程A覆盖了从而线程不安全。 4.concurrentHashMap ConcurrentHashMap JDK1.7ConcurrentHashMap底层实现原理: 数据结构Segment(大数组) HashEntry(小数组) 链表每个 Segment 对应一把锁如果多个线程访问不同的 Segment则不会冲突 JDK1.8ConcurrentHashMap底层实现原理: 数据结构Node 数组 链表或红黑树数组的每个头节点作为锁如果多个线程访问的头节点不同则不会冲突。首次生成头节点时如果发生竞争利用 cas 而非 syncronized进一步提升性能 ConcurrentHashMap的整体架构 数据结构Node 数组 链表或红黑树数组的每个头节点作为锁如果多个线程访问的头节点不同则不会冲突。首次生成头节点时如果发生竞争利用 cas 而非 syncronized进一步提升性能 这个是ConcurrentHashMap在JDK1.8中的存储结构它是由数组、单向链表、红黑树组成。 当我们初始化一个ConcurrentHashMap实例时默认会初始化一个长度为16的数组。由于ConcurrentHashMap它的核心仍然是hash表所以必然会存在hash冲突问题。 ConcurrentHashMap采用链式寻址法来解决hash冲突。 当hash冲突比较多的时候会造成链表长度较长这种情况会使得ConcurrentHashMap中数据元素的查询复杂度变成O(n)。因此在JDK1.8中引入了红黑树的机制。 当数组长度大于64并且链表长度大于等于8的时候单项链表就会转换为红黑树。 另外随着ConcurrentHashMap的动态扩容一旦链表长度小于8红黑树会退化成单向链表。 ConcurrentHashMap的基本功能 ConcurrentHashMap本质上是一个HashMap因此功能和HashMap一样但是ConcurrentHashMap在HashMap的基础上提供了并发安全的实现。 并发安全的主要实现是通过对指定的Node节点加锁来保证数据更新的安全性。 ConcurrentHashMap在性能方面做的优化 在JDK1.8中ConcurrentHashMap锁的粒度是数组中的某一个节点而在JDK1.7锁定的是Segment锁的范围要更大因此性能上会更低。引入红黑树降低了数据查询的时间复杂度红黑树的时间复杂度是O(logn)。当数组长度不够时ConcurrentHashMap需要对数组进行扩容在扩容的实现上ConcurrentHashMap引入了多线程并发扩容的机制简单来说就是多个线程对原始数组进行分片后每个线程负责一个分片的数据迁移从而提升了扩容过程中数据迁移的效率。 ConcurrentHashMap中有一个size()方法来获取总的元素个数而在多线程并发场景中在保证原子性的前提下来实现元素个数的累加性能是非常低的。ConcurrentHashMap在这个方面的优化主要体现在两个点当线程竞争不激烈时直接采用CAS来实现元素个数的原子递增。 如果线程竞争激烈使用一个数组来维护元素个数如果要增加总的元素个数则直接从数组中随机选择一个再通过CAS实现原子递增。它的核心思想是引入了数组来实现对并发更新的负载。 为什么不用ReentrantLock而用synchronized ? 减少内存开销:如果使用ReentrantLock则需要节点继承AQS来获得同步支持增加内存开销而1.8中只有头节点需要进行同步。 内部优化synchronized则是JVM直接支持的JVM能够在运行时作出相应的优化措施锁粗化、锁消除、锁自旋等等。 5.ConcurrentModificationException ConcurrentModificationException异常 当方法检测到对象的并发修改但不允许这种修改时抛出此异常。 modCount的作用 modCount就是修改次数在具体的实现类中的Iterator中才会使用。在List集合中ArrayList是List接口的实现类 modCount表示list集合结构上被修改的次数。在ArrayList所有涉及结构变化的方法中都增加了modCount的值 list结构上别修改是指改变了list的长度的大小或者是遍历结果中产生了不正确的结果的方式。add()和remove()方法会是modCount进行1操作。modCount被修改后会产生ConcurrentModificationException异常 这是jdk的快速失败原则。 下面进行试验 public static void main(String[] args) {ArrayListString listnew ArrayListString();list.add(1);list.add(2);list.add(3);IteratorString iterator list.iterator();while (iterator.hasNext()){String eleiterator.next();if(ele.equals(2)) //1处list.remove(ele); //(2)处}System.out.println(list);}看下ArrayList类的Iterator是如何实现的呢 可以看出调用next()方法获取下一个元素时第一行代码就是调用了checkForComodification();而该方法的核心逻辑就是比较modCount和expectedModCount这2个变量的值。 在上面的例子中刚开始modCount和expectedModCount的值都为3所以第1次获取元素1是没问题的但是当执行完下面这行代码时 list.remove(ele);modCount的值就被修改成了4。(remove方法里面调用了fastRemove) 所以在第2次获取元素时modCount和expectedModCount的值就不相等了所以抛出了java.util.ConcurrentModificationException异常。 解决方案 使用Iterator的remove()方法 可以看出每次删除一个元素都会将modCount的值重新赋值给expectedModCount这样2个变量就相等了不会触发java.util.ConcurrentModificationException异常。 6.Spring AOP、IOC、DI介绍下 IOC IOC—Inversion of Control即“控制反转”不是什么技术而是一种设计思想。在Java开发中IOC意味着将你设计好的对象交给容器控制而不是传统的在你的对象内部直接控制。 谁控制谁控制什么 传统Java SE程序设计我们直接在对象内部通过new进行创建对象是程序主动去创建依赖对象而IOC是有专门一个容器来创建这些对象即由IOC容器来控制对 象的创建谁控制谁当然是IOC 容器控制了对象控制什么那就是主要控制了外部资源获取不只是对象包括比如文件等。为何是反转哪些方面反转了? 有反转就有正转传统应用程序是由我们自己在对象中主动控制去直接获取依赖对象也就是正转而反转则是由容器来帮忙创建及注入依赖对象为何是反转因为由容器帮我们查找及注入依赖对象对象只是被动的接受依赖对象所以是反转哪些方面反转了依赖对象的获取被反转了。 IOC的好处 ioc的思想最核心的地方在于资源不由使用资源者管理而由不使用资源的第三方管理这可以带来很多好处。第一资源集中管理实现资源的可配置和易管理。第二降低了使用资源双方的依赖程度也就是我们说的耦合度。也就是说甲方要达成某种目的不需要直接依赖乙方它只需要达到的目的告诉第三方机构就可以了比如甲方需要一双袜子而乙方它卖一双袜子它要把袜子卖出去并不需要自己去直接找到一个卖家来完成袜子的卖出。它也只需要找第三方告诉别人我要卖一双袜子。这下好了甲乙双方进行交易活动都不需要自己直接去找卖家相当于程序内部开放接口卖家由第三方作为参数传入。甲乙互相不依赖而且只有在进行交易活动的时候甲才和乙产生联系。反之亦然。这样做什么好处么呢甲乙可以在对方不真实存在的情况下独立存在而且保证不交易时候无联系想交易的时候可以很容易的产生联系。甲乙交易活动不需要双方见面避免了双方的互不信任造成交易失败的问题。因为交易由第三方来负责联系而且甲乙都认为第三方可靠。那么交易就能很可靠很灵活的产生和进行了。 这就是ioc的核心思想。生活中这种例子比比皆是支付宝在整个淘宝体系里就是庞大的ioc容器交易双方之外的第三方提供可靠性可依赖可灵活变更交易方的资源管理中心。另外人事代理也是雇佣机构和个人之外的第三方。 DI 依赖注入是指将依赖的对象实例交给spring帮我们注入 管理从而释放对对象的管理权比如可以统一替换接口的实现更高效的开发程序 set方法注入构造方法注入autowire 自动注入 AOP 面向切面编程用于将那些与业务无关但却对多个对象产生影响的公共行为和逻辑抽取公共模块复用降低耦合。 你们项目中有没有使用到AOP 记录操作日志缓存spring实现的事务 核心是:使用aop中的环绕通知切点表达式(找到要记录日志的方法)通过环绕通知的参数获取请求方法的参数类、方法、注解、请求方式等)获取到这些参数以后保存到数据库 7.不使用依赖注入使用传统方式的声明会有什么问题 主要是实现类之间的解耦假如A类依赖B类在实例化A类的话也要new一个B类如果A的依赖的类换成C的话所有实例化A的代码的new B都要替换掉不利于代码维护。 8.最左前缀原则 过滤条件要使用索引必须按照索引建立时的顺序依次满足一旦跳过某个字段索引后面的字段都无法被使用。 9.TCP三次握手、四次挥手 TCP协议 保证传输过程的三个关键的步骤分别为三次握手、传输确认、四次挥手。 三次握手 三次握手是建立连接的过程当客户端向服务端发起连接时会先发一包连接请求数据过去询问一下能否与你建立连接这包数据我们称之为SYN包。如果对端同意连接则回复一包SYNACK包客户端收到之后回复一包ACK包连接建立。 因为这个过程中互相发送了三包数据所以称之为三次握手。 Q为什么要三次握手而不是两次握手服务端回复完SYNACK包之后就建立连接 A这是为了防止因为已失效的请求报文突然又传到服务器引起错误。解决网络信道不可靠的问题 如果没有第三次握手告诉服务器端客户端收的到服务器端传输的数据的话服务器端是不知道客户端有没有接收到服务器端返回的信息的。服务端就认为这个连接是可用的端口就一直开着等到客户端因超时重新发出请求时服务器就会重新开启一个端口连接。 这样一来就会有很多无效的连接端口白白地开着导致资源的浪费。 还有一种情况是已经失效的客户端发出的请求信息由于某种原因传输到了服务器端服务器端以为是客户端发出的有效请求接收后产生错误。 Q为什么不是四次握手 A因为通信不可能100%可靠而上面的三次握手已经做好了通信的准备工作再四次握手并不能显著提高可靠性而且也没有必要。 数据传输 经过三次握手之后客户端和服务端都进入了数据传输状态。tcp协议需要在不可靠的信道上保证可靠的连接。现在就有几个问题需要面对1. 一包数据有可能被拆成多包发送如何处理丢包问题 2. 这些数据包到达的先后顺序不同如何处理乱乱序问题。 针对以上的要求TCP协议为每一个连接建立了一个发送缓冲区从建立链接后的第一个字节的序列号为0后面每个字节的序列号就会增加1。发送数据时从发送缓冲区取一部分数据组成发送报文在其tcp协议头中会附带序列号和长度接受端在收到数据后需要回复确认报文。确认报文中的ACK等于接收序列号加长度也就是下一包数据需要发送的起始序列号。 这样一问一答的发送方式能够使发送端确认发送的数据已经被对方收到发送端也可以一次发送连续多包数据接收端只需要回复一次ACK就可以了这样发送端可以把待发送的数据分割成一系列的碎片发送到对端。对端根据序列号和长度在接受后重构出来完整的数据假设其中丢失了某些数据包在接收端可以要求发送端重传。比如丢失了100-199这100个字节接收端向发送端发送ACK 100 报文发送端收到后重传这一包数据接受端进行补齐。 以上过程不区分客户端和服务端TCP连接是全双工的对于两端来说均采用上述机制。 四次挥手 处于连接状态的客户端和服务端都可以发起关闭连接请求此时需要四次挥手来进行连接关闭。 1.假设客户端主动发起连接关闭请求他需要将服务端发起一包FIN包表示要关闭连接自己进入终止等待1状态这是第一次挥手。 2.服务端收到FIN包发送一包ACK包表示自己进入了关闭等待状态客户端进入终止等待2状态这是第二次挥手。 3.服务端此时还可以发送未发送的数据而客户端还可以接收数据待服务端发送完数据之后发送一包FIN包进入最后确认状态这是第三次挥手。 4.客户端收到之后回复ACK包进入超时等待状态经过超时时间后关闭连接而服务端收到ACK包后立即关闭连接这是第四次挥手。 Q为什么客户端需要等待超时时间 A为了保证对方已收到ACK包因为假设客户端发送完最后一包ACK包后就释放了连接一旦ACK包在网络中丢失服务端将一直停留在最后确认状态如果客户端发送最后一包ACK包后等待一段时间这是服务端会因为没有收到ACK包会重发FIN包客户端会响应这个FIN包重发ACK包并刷新超时时间。这个机制跟三次握手一样也是为了保证在不可靠的网络链路中进行可靠的连接断开确认。
http://www.ho-use.cn/article/10819359.html

相关文章:

  • 打开建设银行网站wordpress 审核用户
  • 个人做网站如何赚钱吗windows卸载wordpress
  • 建设银行网站上改手机免费crm系统手机版
  • cn 域名网站做网站需要的企业
  • 汕头市网站建设分站公司wordpress调用自定义文章类型文章
  • 网站定制要花多少钱平台和自建网站服务提供者
  • 网站建设世纪明珠厦门网站建设及维护
  • 制作企业网站要多少钱西宁站 网站
  • 青浦网站设计大连工程信息招标网
  • 上海网络平台网站阜阳建设网站
  • 重庆网站建设cqsday网站内容页优化
  • 工信部网站备案平台wordpress相似推荐
  • 中国建设银行网站查询密码是什么深圳网站优化包年
  • 随州网站建设外包公司青岛网络营销网络推广介绍
  • 网站的标题怎么做吸引人网站建设 设计方案 百度文库
  • wordpress旅游网站主题论述制作网站的一般过程
  • 江苏省城市建设信用手册网站茂名网站建设哪家好
  • 重庆大坪网站建设泉州市第一建设有限公司网站
  • 大理市城乡建设局网站怎样查网站用什么程序做的
  • 家具网站建设需求网站建设福建
  • 做3ds磁铁卡网站上海闵行区租房价格
  • 专业的营销网站建设公司怎样进入建设通网站
  • 网站开发实训h5总结安泽网站建设
  • 如何做外链河南网站优化
  • seo怎么做自己的网站做产品目录设计用什么网站好
  • 2015年网站设计高端品牌名字怎么取
  • 网站制作代理平台大连工业大学研究生
  • 淮安做微信网站别人做的网站域名到期怎么办
  • 美食网站建设页面要求政务网站建设目标和核心功能
  • 提供温州手机网站制作多少钱怎么做二维码进入公司网站