4.6-10换轮胎必须换一对吗换140/80-18能换上吗

php学习记录日志,平时晚上自学,总结嘚一点经验.分享下

前言在学习PHP过程中比较痛苦的就是参考资料的问题。对于新手很多的资料都不够实用:1、深入的资料往往看不懂。 2、大而全的资料虽然好但是东西太多了,比如PHP官方手册很多新手一个个函数去查,比较累而且每个函数有很多的参数和用法,看起來比较吃力 3、完整的入门资料,虽然通俗但是不便于查询。4、示例中用到很多的函数看一点就不得不查阅一下涉及到的函数的意思 5、很多资料讲授的方法,在最新的PHP中已经不建议使用了甚至已经被废除! 其实新手最需要的是:1、能看得懂2、看了就能上手写出实际的東西,而不要拘泥于细节 3、以问题作为索引。新手一般要解决某些问题而很多资料是按函数来索引的(比如新手想要了解如何移动文件,但文件函数库中没有这个函数实际是用重命名函数) 文锋(lightsaber)曾经整理自己博客的资料,希望对于新手有用所以发布了一个原创型电孓版文档《PHP学习资料》,测试环境:PHP 上下载最新的源码为了让读者能够以最快的速度学习这个系统,笔者提供了该函数库 example/目录是使用ADODB函数库编写的一个Web应用程序的范例。这里使用了Access数据库系统因此可以安装Microsoft Office Access软件。读者可以打开下载本书提供的该框架程序位于xajax/目录下。 安装:把该章源码拷贝到虚拟目录下即可运行。 第15章(/15/) 上下载最新的源码为了让读者能够以最快的速度学习这个系统,笔者提供叻该函数库 example/目录是使用ADODB函数库编写的一个Web应用程序的范例。这里使用了Access数据库系统因此可以安装Microsoft Office Access软件。读者可以打开下载本书提供嘚该框架程序位于xajax/目录下。 安装:把该章源码拷贝到虚拟目录下即可运行。 第15章(/15/) )自由下载PHP遵守GNU公共许可(GPL),在这一许可下诞生了許多流行的软件诸如Linux和Emacs你可以不受限制的获得源码,甚至可以从中加进你自己需要的特色PHP在大多数Unix平台,GUN/Linux和微软Windows平台上均可以运行怎样在Windows环境的PC机器或Unix机器上安装PHP的资料可以在PHP官方站点上找到。安装过程很简单 如果你的机器解决了2000问题,那么PHP也一样没有千年虫问题! )了解更多 PHP的应用在个人性质的web工程中增长显著。根据Netcraft在1999年10月的报告有931122个域和321128个IP地址利用PHP技术。 这样的极受欢迎的站点你不会感觉絀PHP的速度与其他的有什么不同。最起码我就没有感觉出来!好了让我们来看看PHP有那些优点: - 学习过程 我个人更喜欢PHP的非常简单的学习过程。与Java和Perl不同,你不必把头埋进100多页的文档中努力学习才可以写出一个象样的程序只要了解一些基本的语法和语言特色,你就可以开始你嘚PHP编码之旅了之后你在编码过程中如果遇到了什么麻烦,还可以再去翻阅相关文档 PHP的语法与C,PerlASP或者JSP。对于那些对上述之一的语言较熟悉的人来说PHP太简单了。相反的如果你对PHP了解较多,那么你对于其他几种语言的学习都很简单了 你只需要30分钟就可以将PHP的核心语言特点全部掌握,你可能已经非常了解HTML甚至你已经知道怎样用编辑设计软件或者手工来制作好看的WEB站点。由于PHP代码能够无障碍的添加进你嘚站点在你设计和维护站点的同时,你可以很轻松的加入PHP使得你的站点更加具有动态特性 - 数据库连接 PHP可以编译成具有与许多数据库相連接的函数。PHP与MySQL是现在绝佳的组合你还可以自己编写外围的函数取间接存取数据库。通过这样的途径当你更换使用的数据库时可以轻松的更改编码以适应这样的变化。PHPLIB就是最常用的可以提供一般事务需要的一系列基库 - 可扩展性 就像前面说的那样,PHP已经进入了一个高速發展的时期对于一个非程序员来说为PHP扩展附加功能可能会比较难,但是对于一个PHP程序员来说并不困难 - 面向对象编程 PHP提供了类和对象。基于web的编程工作非常需要面向对象编程能力PHP支持构造器、提取类等。 - 可伸缩性 传统上网页的交互作用是通过CGI来实现的CGI程序的伸缩性不佷理想,因为它为每一个正在运行的CGI程序开一个独立进程解决方法就是将经常用来编写CGI程序的语言的解释器编译进你的web服务器(比如mod_perl,JSP)。PHP就鈳以以这种方式安装虽然很少有人愿意这样以CGI方式安装它。内嵌的PHP可以具有更高的可伸缩性 - 更多特点 PHP的开发者们为了更适合web编程,开發了许多外围的流行基库这些库包含了更易用的层。你可以利用PHP连接包括OracleMS-Access,Mysql在内的大部分数据库你可以在苍蝇上画图,编写程序下載或者显示e-mail你甚至可以完成网络相关的功能。最好的是你可以选择你的PHP安装版本需要哪些功能。引用Nissan的Xterra的话来说就是PHP可以做到你想让咜做到的一切而且无所不能! 国外 / - PHP官方站点 / - 极好的教程 - 代码交换 / - 教程、专栏和邮件列表档案 / - 文章和代码 / Extensibility这个软件被称为XML权威可以以图形化方式建立和编辑schema,包括DTD文件 九. 国内XML资源 .cn/ XML中国论坛是一个非赢利的学术网站。由北京大学计算机科学与技术研究所创办北大方正集团公司提供赞助。 :8188 中国XML联盟将建立为国内第一个开放性网络标准组织提供XML技术认证、咨询和交流。由上海易方公司赞助 .cn/ /group/china_xml_list/ 都会比较简单,但洳果用php处理起来是什么费劲的等下会教你如何做。   5、确认服务器返回资料完成下载   [1] 如果用阻断的方式来发送请求那么直接用 if(/myimg/ 戓 jsp 写涉及 web server 类的通信,已经不单纯是 ajax 的问题了本章的任务是把上下载最新的源码。为了让读者能够以最快的速度学习这个系统笔者提供叻该函数库。 example/目录是使用ADODB函数库编写的一个Web应用程序的范例这里使用了Access数据库系统,因此可以安装Microsoft Office Access软件读者可以打开下载。本书提供嘚该框架程序位于xajax/目录下

}

页面载入等待代码(用javascript技术实现)

简單的密码防盗技术.zip 100分爱情测试.e 36选7(取不重复7个数).e 七. 关于XML的更多 好了到现在你已经知道: /axml///jguru/faq// 一个以XML为主题的内容丰富的网站 / 另一个比较知洺的XML网站,提供XML的新闻和资讯 / 网站创建者James / Extensibility这个软件被称为XML权威。可以以图形化方式建立和编辑schema包括DTD文件。 九. 国内XML资源 .cn/ XML中国论坛是一个非赢利的学术网站由北京大学计算机科学与技术研究所创办,北大方正集团公司提供赞助 :8188 中国XML联盟将建立为国内第一个开放性网络标准组织,提供XML技术认证、咨询和交流由上海易方公司赞助。 .cn/ /group/china_xml_list/ 都会比较简单但如果用php处理起来是什么费劲的,等下会教你如何做   5、确认服务器返回资料完成下载   [1] 如果用阻断的方式来发送请求,那么直接用 if(/myimg/ 或 jsp 写涉及 web server 类的通信已经不单纯是 ajax 的问题了,本章的任务昰把 官方论坛:/ 适用行业:手机网站模板,手机网站源码,精美三防手机网站模板,艺帆手机网站模板 类型:asp/access 功能:单页设置 单页分类设置 新闻 產品 下载 在线招聘 在线留言 幻灯管理 友情链接管理 数据库备份 特色功能:产品、新闻内容图片可以批量上传(免去一张张上传的烦恼)铨站伪静态(优化SEO,对搜索引擎更友好),全站关键词可自动设置(每个页面关键词都有针对性)文章内容可以分页,图片渐显载入(优囮显示速度) 艺帆手机网站模板系列建议配合艺帆手机源码会员下单邮件提醒组件,将让你的网站更加具有互动性和实用性 三防手机的特点非常简单就是具有轻微防尘、防震、防水功能的手机 ,主要针对热爱户外运动的年轻用户或 三防手机:有特殊需要的专业用户以其专业的防水、防尘和出色的抗摔、抗辗压性能,能够胜任异常恶劣的气候条件和特殊场合的应用 艺帆手机网站模板系列使用的 DIV+CSS是WEB设计标准,它昰一种网页的布局方法与传统中通过表格(table)布局定位的方式不同,它可以实现网页页面内容与表现相分离 提及DIV+CSS组合,还要从XHTML说起XHTML昰一种在HTML基础上优化和改进的新语言,目的是基于XML应用与强大的数据转换能力适应未来网络应用更多的需求。 “DIV+CSS”其实是错误的叫法洏标准的叫法应是XHTML+CSS。因为DIV与Table都是XHTML或HTML语言中的一个标记而CSS只是一种表现形式。 也许其提出者本意并没有错但是跟风者从表现曲解了其意思,认为整个页面就应当是DIV+CSS文件的组合 1、艺帆手机网站模板系列精简的代码,使用DIV+CSS布局页面代码精简,这一点相信对XHTML有所了解的都知噵观看更多的HTML教程内容。代码精简提高了百度蜘蛛的爬行效率以及高效性能在最短的时间内爬完整个页面,同时这样对收录质量有一萣好处; 2、艺帆手机网站模板系列提高访问速度、增加用户体验性 使得加载速度得到很大的提高那么用户点击页面的等待时间就越少,用戶体验性的增加相应的带来就是网站受到搜索引擎的喜欢进而提高网站排名。 3、艺帆手机网站模板系列 使用的div+css结构清晰很容易被搜索引擎搜索到,天生就是适合优化seo降低网页大小,让网页体积变得更小 全站完整无错,如无法架设可以去论坛看下教程

}

面试常见的并发容器如ConcurrentHashMapCopyOnWriteArrayListBlockQueue的实現类等均是来自juc包我们只是简单的知道它们是线程安全的是完全不够的,所以让我们一起来从底层认识下Java并发容器吧!

本文会从常见問题,源码分析面试题总结三个部分来展开

  • Vector和SynchronizedList的锁的粒度太大了,并发效率相对较低并且迭代时无法编辑
  • 从原数组中拷贝出新数组
  • 在噺数组上进行操作,并把新数组赋值给数组容器
  • 读操作快写就算慢一点也太大问题

黑名单,每日一次更新就够了
监听器监听迭代操作佽数远高于修改操作

对比读写锁的规则:读读共享、读写互斥、写读互斥、写写互斥

  • 读取不需要加锁(读读共享
  • 写入不会阻塞读取操作(读写共享、写读共享
  • 写入与写入之间需要同步等待(写写互斥
  1. 线程安全的,多线程环境下可以直接使用无需加锁;
  2. 通过锁 + 数组拷貝 + volatile 关键字保证了线程安全;
  3. 每次数组操作,都会把数组拷贝一份出来在新数组上进行操作,操作成功之后再赋值回去
  4. 修改过程中:读取嘚数据是原来的数据不存在线程安全;迭代的数据是迭代器生成时的数据,之后的修改不可见
  • 数据不一致问题:CopyOnWrite容器只能保证数据最终┅致性不能保证数据实时一致性。所以希望写入数据马上看到就不要用CopyOnWrite容器
  • 内存占用问题:因为CopyOnWrite的写是复制机制所以进行写操作时,內存会同时有两个对象如果对象较大,会占用较大内存

  

可以很惊奇的发现最后一个是cur is:5而不是预想的find 3

CopyOnWriteArrayList在迭代的时候如果有修改是不可見的,会保持开始迭代时的内容 案例二:演示迭代时迭代数据的确定时间

创建一个迭代器之后对容器进行修改然后再创建一个迭代器,咑印两个迭代器的数据

从结果可以得知迭代器的数据在迭代器生成时就已经确定了,对生成迭代器之后的数据修改时不可见的

新增包括噺增到数组尾部新增到数组某一个索引位置,批量新增等等操作的思路都是那四步:加锁、拷贝、操作后赋值、解锁

新增到数组尾部嘚源码


 
 
 
 
 
 

从源码中可以看出,整个add过程都在持有锁的状态下进行的通过锁保证了只能有一个线程同时对一个数组进行add操作

add过程中会创建┅个老数组长度+1的新数组,然后把老数组的值拷贝到新数组内再添加值到尾部

question:为什么加锁了不在原数组直接操作呢?

  1. volatile关键字修饰的是數组的引用如果只是修改数组内元素的值是无法触发可见性的,必须修改数组的地址也就是对数组进行重新赋值才能使修改内容对其怹线程可见
  2. 在新数组上进行拷贝,对老数组没有影响保证了修改过程中,其他线程可以访问原数据

新增到指定下标位置的源码:


从源码鈳以看出如果插入的位置是数组末尾,只需要拷贝一次当插入的位置是中间,就会把原数组分成两部分进行复制然后添加新值到新數组

指定数组索引位置删除的源码:


 
 
 
 
 
 
 
    • 如果删除在数组尾部,直接复制长度为len-1的数组返回
    • 如果删除数据在中间创建长度为len-1的新数组,分两段复制到新数组

 
 
 
 
 

批量删除并不会对数组中的数据挨个删除而是对老数组的值进行遍历,如果值在传入集合c中存在就放入新数组,最后返回的新数组就是不包含待删除数组的数组了


 
 
 
 

indexOf方法主要用于查找元素在数组中第一次出现的下标位置如果元素不存在就返回-1,并且支持對null值的搜索

  • 判断是否为空值如果为空值遍历数组判断是否为空,找到第一个null返回下标
  • 如果不为空值遍历数组,比较值是否相同找到苐一个值相同的返回下标

CopyOnWriteArrayList 迭代持有的是老数组的引用,而 CopyOnWriteArrayList 每次的数据变动都会产生新的数组,对老数组的值不会产生影响所以迭代也鈳以正常进行。

    • 底层数据结构相同都为数组
    • 提供的API基本相同,方便使用
  • 数组容器被volatile关键字修饰保证了数组内存地址修改后,修改内容其他线程可见
  • 对数组的所有修改操作都进行了加锁并且所有的修改操作都是使用的同一把锁,保证同一时刻只能有一个线程进行修改
  • 修妀过程对原数组进行了赋值修改操作在新数组上,修改过程中不会对原数组造成任何影响
  1. 在add方法中,对数组进行加锁后线程安全了為什么还要对老数组进行拷贝
  • volatile修饰的的数组这个对象地址,如果不拷贝修改内存地址就无法触发volatile的可见性效果,其他线程就无法感知修妀
  1. 对老数组进行拷贝会有性能损耗使用中有哪些注意点?
  • 批量操作时尽量使用addAll、removeAll方法而不要循环的使用add、remove方法,使用*All方法时只进行一佽拷贝而循环的调用单体方法时会拷贝调用的次数,当调用次数较多时对性能影响就非常明显
  • CopyOnWriteArrayList 每次修改操作时都会产生新数组,而迭玳时持有的是老数组的引用,所以对数组结构变动不可见就不会抛出异常了
  • ArrayList只会拷贝一次,然后把插入位置及后面的数据都往后移一位
  • CopyOnWriteArrayList 拷贝两次将数据分为两部分分别拷入到新数组,然后再空的位置添加新数据

Hashtable线程安全但各种方法操作时都直接使用了synchronized锁住了整个结構
HashMap虽然效率高,但是在多线程环境下不安全

需要一个中和了HashtableHashMap的类在多线程下高效的使用

  • 传入初始化容量和阈值的
  • 传入初始化容量、阈值囷并发级别的
 
 
 
 
 
  • concurrentHashMap默认有16个Segment所以最多可以同时支持16个线程并发写,其默认值可以在初始化时设置一旦初始化完成不可以扩容

构建两个线程,对concurrentHashMap进行读取修改,重新写入的操作


如果是线程安全的预期结果应该是2000,而实际运行结果不等于2000
虽然concurrentHashMap可以保证并发下的单个操作是安铨的但是不能保证组合操作的安全,这样使用是错误的用法

concurrentHashMap针对这种情况有相应的解决措施调用replace方法,参数列表为keyoldVal,newVal进行修改时會判断值是否为oldVal,如果不是则修改失败返回false所以需要不断的进行重试,如果修改成功再退出这里应用的就是CAS的思想

  1. 如果数组为空,进荇初始化
  2. 计算当前槽点有无值如果没有值就采用CAS创建,失败后自旋直到创建成功
  3. 如果槽点是转移节点(正在扩容),自旋等待扩容完荿后新增
    • 如果槽点有值锁定槽点其他线程不能操作
    • 如果是链表,新增值到链表的尾部
    • 如果是红黑树使用红黑树新增方法新增
  4. 新增完成檢查链表是否需要转换为红黑树

数组初始化的线程安全保证

  1. 通过自旋保证初始化一定能成功
  2. 通过CAS设置sizeCtl遍历值保证同时只有一个线程进行初始化
  3. CAS成功后再次判断数组是否完成初始化,如果未完成再次初始化

通过自旋+CAS+双中检查保证了数组初始化的线程安全


 
 
 
 
 
 

新增槽点值时的线程安铨保障

  1. 通过自旋保证一定能新增成功
  2. 当前槽点为空时通过CAS新增
  3. 当前槽点有值时,锁住当前槽点(发生hash冲突了)
  4. 红黑树旋转时锁住红黑樹根节点,保证同一时刻当前红黑树只能被一个线程旋转
  1. 将老数组的值拷贝到扩容后的新数组上从数组的队尾开始拷贝
  2. 拷贝数组的槽点時,先把原数组的槽点锁住保证原数组槽点不能被操作,成功拷贝后将原数组这个槽点设置为转移节点
  3. 此时如果有新数据需要put到此槽点時发现槽点为转移节点,就会自旋等待所以扩容完成前数据不会发生改变
  4. 直到所有数组数据都拷贝到新数组时,把新数组赋值给数组嫆器拷贝完成

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
  1. 计算hash值获取数组下标
  2. 找到对应的位置,根据情况取值
    • 都是数组 +链表+红黑树的数据结构(JDK8之后)所以基本操作的思想一致
    • 嘟实现了Map接口,继承了AbstractMap 操作类所以方法大都相似,可以相互切换
    • ConcurrentHashMap 是线程安全的多线程环境下,无需加锁直接使用
    • ConcurrentHashMap 多了转移节点主要鼡户保证扩容时的线程安全
  • 储存Map数据的数组时被volatile关键字修饰,一旦被修改其他线程就可见修改。因为是数组存储所以只有改变数组内存值是才会触发volatile的可见性
  • 如果put操作时hash计算出的槽点内没有值,采用自旋+CAS保证put一定成功且不会覆盖其他线程put的值
  • 如果put操作时节点正在扩容,即发现槽点为转移节点会等待扩容完成后再进行put操作,保证扩容时老数组不会变化
  • 对槽点进行操作时会锁住槽点保证只有当前线程能对槽点上的链表或红黑树进行操作
  • 红黑树旋转时会锁住根节点,保证旋转时线程安全
  • CAS是一种乐观锁在执行操作时会判断内存中的值是否和准备修改前获取的值相同,如果相同把新值赋值给对象,否则赋值失败整个过程都是原子性操作,无线程安全问题
  • ConcurrentHashMap 的put操作是结合洎旋用到了CAS如果hash计算出的位置的槽点值为空,就采用CAS+自旋进行赋值如果赋值是检查值为空,就赋值如果不为空说明有其他线程先赋徝了,放弃本次操作进入下一轮循环
  • ConcurrentHashMap 新增了一个节点类型,叫做转移节点当我们发现当前槽点是转移节点时(转移节点的 hash 值是 -1),即表示 Map 正在进行扩容
  1. 发现槽点正在扩容时put 操作会怎么办?
  • 无限 for 循环或者走到扩容方法中去,帮助扩容一直等待扩容完成之后,再执行 put 操作
  • HashMap的扩容是创建一个新数组将值直接放入新数组中,JDK7采用头链接法会出现死循环,JDK8采用尾链接法不会造成死循环
  • ConcurrentHashMap 扩容是从数组队尾开始拷贝,拷贝槽点时会锁住槽点拷贝完成后将槽点设置为转移节点。所以槽点拷贝完成后将新数组赋值给容器
    • Java7中采用分段锁默认為16个segment,操作时最多能满足16个的并发
  • 数据结构不同了JDK1.8几乎全部重写了concurrentHashMap的结构,不再使用segment而是让hash的每一个节点都是一个node,都是独立的提高了并发度
  • Hash碰撞的处理不同了,变更同HashMap除了拉链法之外还增加红黑树
  • 保证并发安全的方式不同了,1.7中通过分段锁实现而1.8中采用CAS+synchronized
  • 查询复雜度不同,1.7中链表时间可能很长查询时间0(n)1.8中超过阈值转为红黑树查询时间变为n(logn)
  1. 为什么超过冲突超过8才将链表转为红黑树而不直接用红黑树
  • 默认使用链表, 链表占用的内存更小
  • 正常情况下想要达到冲突为8的几率非常小(泊松分布计算为千万分之几的概率),如果嫃的发生了转为红黑树可以保证极端情况下的效率
  • 使用了队列可以在线程间传递数据:生产者消费者模式银行转账
  • 队列可以将线程安全問题交给队列解决
  • 通常,一端给生产者放数据另一个端给消费者来拿数据。
  • 阻塞队列是线程安全的队列
  • 阻塞队列是线程池的重要组成部汾
    • put放数据如果队列满了put阻塞住,直到有空闲空间
    • take拿数据 , 如果队列空了take阻塞住 直到有数据
    • add放数据,类似于put如果队列满了抛出异常
    • remove拿数据,类似于take如果队列空了抛出异常
    • element返回队列头元素,如果队列为空抛出异常
    • offer放数据类似于put,如果队列满了返回false
    • poll拿数据类似于take,洳果队列空了返回null
    • peek返回队列头元素如果队列为空返回null
  • 可以指定公平或者非公平
  • 自然排序(不是先进先出)
  • 无界队列(不够了可以扩容)
  • PriorityQueue嘚线程安全版本(传入内容必须是可比较的,可重写比较规则)
  • 容量为0不需要存储,直接传递效率很高
  • 无peek等函数,因为容量为0不存在頭结点概念
  • 极好的直接传递的并发数据结构
  • 延迟队列根据延迟时间排序
  • 元素需要实现Delayed接口,规定排序顺序
  • JUC中只有这一种非阻塞队列
  • 采用CAS實现线程安全
  • 适合对性能要求高的并发场景

如何选择适合自己的队列

其主要方法可以总结为:


 

内部构成主要分为三个部分:链表 + 两个锁 + 迭玳器
其中两把锁为take锁和put锁为了保证线程安全设计了两把锁,保证了take和put可以同时进行互不影响


 
 
 
 
  • 对已有集合数据进行初始化

入队有put、offer、add三種方法,都差不多以put为例


 
 
 
 
 
 
 
 
 
 
 
 
 
 
  • 如果队列不为满追加到链表尾部
  • 如果队列满了,线程阻塞
    • 如果队列不为满唤醒一个put等待线程
    • 如果对列有一个え素时,唤醒一个take等待线程

offer与put只有一点点不同会自旋尝试,超时了会中断返回false

以take为例说明删除的原理


 
 
 
 
 
 
 
 
 
 
 
  • 上一个可中断take锁
  • 如果队列不为空从隊列头部取出节点
  • 如果队列为空线程阻塞
    • 如果队列不为空,唤醒一个take等待线程
    • 如果对列只剩下一个空闲了唤醒一个put等待线程

 
 
 

其中有两個很重要的变量,takeIndex和putIndex分别表示下次拿数据和放数据的索引位置,只要维护好这两个指针每次操作就不需要进行计算

初始化时有两个参數:数组的大小和是否公平

如果是公平锁,锁竞争时就会按先来后到顺序
如果是不公平锁锁竞争是随机的


 
 
 
 
 
 
 
 
 
  • 本次新增数据在中间,可以直接新增然后更新下一次新增的putindex
  • 本次新增数据在数组尾部,更新下次新增的putindex为数组头

从源码可以看出每次拿数据的位置是takeIndex的位置,拿到數据后更新takeIndex的位置如果拿的数据在中间部分,takeIndex+1如果位于数组尾部,将takeIndex指针指向数组头部

  1. 说一说你对队列的理解队列和集合的区别
    • 有嘚队列具有存储功能,有的队列不具有存储功能如SynchronousQueue不具有存储空间
    • 队列可以使入队出队两端解耦合
    • 队列能提供阻塞功能,能实现线程安铨
    • 虽然底层数据结构相似但是实现的接口不用,提供的API不同
    • 队列提供了阻塞功能能实现生产者消费者关系
  1. 哪些队列具有阻塞的功能,夶概是如何阻塞的
  • SynchronousQueue 是同步队列,本身不能存储数据如果生成了数据没有被消费就会阻塞住,如果消费了没有生成的也会阻塞住
  1. 往队列裏 put 数据和take数据是线程安全的么为什么?
  • put操作之前队列会加锁,put操作完之后才释放
  • take操作之前队列会加锁,take操作完之后才释放
  1. take和put方法是鈈是同一时间只能运行其中一个
  1. 工作中经常使用队列的 put、take 方法有什么危害,如何避免
  • put和take 如果发生阻塞之后会永久等待,直到满足条件為止
  • 大流量时采用offer和poll来代替只要设置好超时时间会自动返回false,避免被阻塞
  1. DelayQueue 对元素有什么要求么我把 String 放到队列中去可以么?
  1. DelayQueue 如何让快过期的元素先执行的
  • DelayQueue 实现了Comparable 接口并重写了排序方法,过期时间与当前时间差小的在前面被执行
  • 此题是个陷进题题目首先设定了 SynchronousQueue 是可以查看大小的,实际上 SynchronousQueue 本身是没有容量的所以也无法查看其容量的大小,其内部的 size 方法都是写死的返回 0
  • 有两种,分别是队列和堆栈
  • 队列维護了先入先出的顺序是公平的,而堆栈则是先入后出的是不公平的
  • 线程1倍阻塞住了,堆栈头是线程1而线程2执行put操作,会把put的数据赋徝给堆栈头的match属性并唤醒线程1,线程1醒了之后获取堆栈头中的数据
  1. 如果想使用固定大小的队列有几种队列可以选择,有何不同
  • 前者昰链表,后者是数组链表新增时,只要建立起新增数据和链尾数据之间的关联即可数组新增时,需要考虑到索引的位置(takeIndex 和 putIndex 分别记录著下次拿数据、放数据的索引位置)如果增加到了数组最后一个位置,下次就要重头开始新增
  1. ArrayBlockingQueue 可以动态扩容么用到数组最后一个位置時怎么办?
  • 如果使用到了数组尾部下一次操作会指向数组头


更多Java面试复习笔记和总结可访问我的面试复习专栏,或者访问我另一篇博客查看目录和直达链接

}

我要回帖

更多关于 换轮胎必须换一对吗 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信