zoukankan      html  css  js  c++  java
  • 轻松搞定技术面系列 1——基础篇

    本文出自
    代码大湿
    代码大湿

    有段时间没有更新新文章了,接下来想把文章的更新速度放慢点,主要是想写出更高质量的文章,最近收录了多年面试的经典题目,包括答案,本系列会持续更新。


    1 线程和进程的区别

    1	资源占用:进程是系统资源分配的基本单位,进程拥有自己独立的内存空间,所属同一进程的各个线程共享进程的内存空间。线程的上下文切换更快。
    
    2	调度和运行:线程是进程的实体,是系统调度的基本单位,线程的调度要依赖进程,不能单独运行。
    

    2 谈谈Vector和ArrayList,LinkedList

    相同:
    都是实现了List接口,内部都是使用的动态数组,元素是有序的,可以根据索引来访问元素。
    
    不同:
    1  Vector是线程安全的,ArrayList和LinkedList是非线程安全的,所以ArrayLsit的执行的效率要高于Vector。
    2  Vector当需要增加长度的时候,会增加原来长度的1倍,而让ArayList会增加原来的一半。
    3  Vector设置了增长空间的方法,ArrayList没有设置此方法。
    4  LinkedList是使用的双向链表,继承了Deque接口。
    

    这2者和LinkedList的优缺点:
    很明显,LinkedList的优点是可以实现元素的插入和删除操作。而Vector和ArrayList可以实现快速的元素的随机访问。


    3 谈谈HashMap和HashTable

    1  HashTable是线程安全的,HashMap是线程非安全的,HashMap效率会比HashTable高。
    2  HashTable不能有null,HashMap可以用null做key和value。
    3  2者都可以使用iterator遍历,而HashTable还可以使用enumeration。
    4  HashTable继承比较老的Dictionary,HashMap继承AbstractMap。尽量使用ConcurrentHashMap替换HashTable,因为前者效率更高。
    5  HashTable的初始容量是11,扩容的方式是2*old+1。而HashMap初始容量是11,而且一定是2的倍数。
    

    4 String,StringBuilder和StringBuffer

    1  String是final修饰的字符串常量,对象内容不可变。后2者都是字符串变量,内容可以改变。
    2  StringBuilder是非线程安全的,StringBuffer是线程安全的。所以StringBuilder的执行效率要高于StringBuffer。
    3  StringBuilder和StringBuffer都是继承自AbstractStringBuilder。
    

    5 sleep()和wait()方法

    1  sleep是Thread的方法,wait是Object的方法。
    2  sleep会暂停线程的执行,但是不会释放锁,到了指定时间会自动释放,,而wait会释放锁,让线程进入等待锁定池。
    3  sleep需要捕获异常,而wait不用。
    4  sleep可以在任何地方使用,而wait只能在同步块或者同步方法中使用。
    

    6 UDP和TCP

    1  TCP传输数据之前需要建立连接,UDP是传送数据包,不需要建立连接。
    2  TCP提供可靠的传输,而且利用滑动窗口技术还提供差错检测,数据重传等服务。
    3  TCP是传输的二进制字节流,UDP传输数据包,而且UDP不会提供拥塞控制,当数据传输量很大的时候,并不会降低发送端的传输速率。
    4  TCP提供的是端到端的服务,UDP提供一对多,多对一,多对多的服务
    5  TCP数据包的消耗比较大,而UDP数据包消耗会很小。
    

    7 类的加载机制

    类的加载顺序是:

    加载->验证->准备->解析->初始化->使用->卸载
    其中前5个阶段是类的加载阶段。
    

    加载:

    1  获取classes文件(通过类的全限定名)或者网络中的二进制字节流。
    2  将二进制的静态存储结构转换为方法区的动态存储结构。
    3  在堆中生成Class对象,作为对方法区的访问接口。
    

    验证:

    主要验证二进制文件的格式是否有错误。
    

    准备:

    这个阶段为类的static变量分配内存,并对其赋予默认0值,只是针对static的类变量。如果是final和static同时修饰。此时就为其分配程序中指定的值。
    

    解析:

    将符号引用转换为直接引用。
    

    初始化:

    真正意义上执行程序中的代码。为变量赋予程序中指定的值。
    

    8 gc回收算法

    1  标记-清理:先标记存活的对象。然后将未标记的需要清理的对象清理掉,,效率低下,会产生内存碎片。
    2  复制算法:将堆内存划分为2部分,将存活的正在使用的对象复制到另外一个内存区域,消除了内存碎片。
    3  标记-整理:标记存活的对象,然后将存活的对象向堆内存的一边移动,消除了堆内存的内存碎片。
    4  分代回收算法:将堆内存划分为,年轻代(Eden,Survivor from,Survivor to),年老代,永久代。然后根据不同内存区域中对象的生命周期来使用不同的回收算法。一般年轻代(因为存活对象少)使用复制算法(minor gc)。年老代使用标记-整理算法(major/full gc)。
    

    9 gc回收器

    Serial收集器一般是用在Client的虚拟机。有年轻代和年老代。

    Serial:年轻代的垃圾回收器。使用复制算法。
    Serial Old:年老代的收集器,使用标记整理算法。
    

    Parallel收集器

    Parallel Scanvage收集器:年轻代的收集器,使用复制算法。目标是获取最大的吞吐量。
    Parallel Old收集器:年老代的收集器,使用标记-整理算法。
    

    CMS收集器(concurrent mark-sweep)

    用在服务器端的收集器。目标是获得最短的用户停顿时间。
    

    g1收集器

    最前沿科技的成果,但是内存布局和传统的内存布局不一样。
    

    10 TCP的3次握手和4次挥手

    TCP的建立的三次握手:

    这里写图片描述

    原始状态为Closed状态,需要建立连接的时候,
    第一次握手

    Client将数据包的SYN为置为1,序列号seq为J,将数据包发送服务server,此时Client的状态为SYN_SENT。
    

    第二次握手

    server接受数据包后,检查到SYN=1,知道client需要建立连接。server发送数据包,将SYN=1,seq=k,ACK=J+1	。server状态为SYN_RCVD。
    

    第三次握手

    Client收到数据包后,发送数据包,ACK=k+1。server收到数据后,检查ACK的值无误,连接建立。进入established。
    

    TCP断开的四次挥手:

    这里写图片描述

    原始状态为established
    第一次挥手

    client发送FIN数据包。客户端进入FIN_WAIT_1。
    

    第二次挥手

    server收到数据包后。发送ACK确认包。server进入CLOSED_WAIT。client收到数据后检查ACK无误,client进入FIN_WAIT_2。
    

    第三次挥手

    server发送FIN数据包。server进入LAST_ACK。
    

    第四次挥手
    client收到数据包后发送ACK包,client进入TIME_WAIT。client等待2MSL后,如果server没有反应,则进入Closed状态。


    11 B(B-)树和B+树

    M阶B(B-)树有以下几点特性:

    1	如果这棵树不是空树,根节点至少有2个子节点。
    2	中间节点至少有ceil(M/2)个子节点。
    3	非叶节点最多有M个子节点。
    4	有k个关键字的节点有k+1个子节点。
    5	所有叶子节点都在同一层。
    

    这里写图片描述


    12 数据库事务的隔离级别

    数据库事物有4个隔离级别(以下级别依次提高)

    READ UNCOMMITTED:读取未提交数据,此级别会造成脏读,不可重复读,幻读。
    READ COMMITTED:读取提交数据,消除了脏读,但还是会有不可重复读,幻读。大部分数据库都是这个隔离级别。oracle,sqlserver
    Repeatable read:重复读,消除了脏读和不可重复读。会有幻读。Mysql是这个隔离级别。
    Serializable:最高隔离级别,消除了幻读。
    

    13 数据库索引

    数据库索引有聚集索引和非聚集索引。

    聚集索引:聚集索引是表中的记录的物理顺序与索引的key的顺序相同,聚集索引是唯一索引,一个表只能有一个索引。相对于非聚集索引,聚集索引提供更快的查询速度。
    非聚集索引:聚集索引是表中的记录的物理顺序与索引的key的顺序不相同。不是唯一索引。
    

    14 JVM堆和栈

    堆:解决程序的存储问题,存储运行时的对象,是所有线程共享的。
    栈:解决运行问题,存储单个线程的本地变量,运行状态,和返回结果。线程运行结    束,栈也会随着消失。
    

    15 JVM运行时方法区

    JVM运行时将内存区域分为

    1  程序计数器:是线程隔离的,只是线程下一条将要执行的指令的位置。
    2  JVM栈:每个线程都有自己的虚拟机栈,主要存储线程的本地变量,自然是线程隔离的。
    3  堆:存储程序中所有的对象,是所有线程可以共享的内存区域。
    4  方法区:存储类的信息,类变量(static变量),是所有线程共享的。
    

    16 JVM内存模型

    JVM规定所有的变量都存储在主存中,而每个线程运行时都有自己的工作内存。每个线程不能自己操作主存,必须通过工作内存。一个线程不能直接访问其它线程的变量。
    

    17 数据库范式(NF)

    数据库范式有8个范式。通常我们设计数据库需要满足前面3个范式。

    1NF	数据表的字段是原子的,不可再分。
    2NF	在1NF的基础上,非主键列对主键是完全依赖,不存在非主属性对主键的部分依赖。
    3NF 在2NF的基础上,非主键列对主键是直接依赖,不存在非主键列对主键是传递依赖。(如非主属性C依赖于非主属性B,非主属性B依赖于主键A)
    

    18 数据库事务的4个特性

    1	原子性:一个事务对数据的操作要么成功,要么失败。如果有异常,会回滚到事务操作数据之前的状态。
    2	一致性:事务修改数据库之前和修改数据库之后的状态要保持一致。
    3	持久性:既事务对数据库的操作是永久性的。
    4	隔离性:多个事务之间的操作应当是隔离的。
    

    19 内存分配策略

    1	指针碰撞法:针对连续的内存空间,有内存分配的请求的时候,将指针指向一边。
    2	空闲表法:针对不连续的内存空间,所有的空闲内存都记录在一个表中,当需要分配内存的时候,查询这个表,将满足大小的内存分配。
    

    20 Java4种引用的类型

    强引用:我们平时使用到的引用都是强引用,在gc回收内存的时候。会将不可达对象回收掉。
    软引用:SoftReference<V>,在内存不足的时候会将软引用对象回收掉。
    弱引用:WeakRerence<V>,gc回收的时候会将弱引用对象回收掉。
    虚引用:PhantomRerence<V>,此引用不能引用到对象,在跟踪gc回收器的时候使用。
    

    21 乐观锁和悲观锁

    悲观锁:数据库事务获取数据之前,将数据加锁,别的线程要读取数据会blocking。
    乐观锁:数据库事务获取数据不会加锁,但是更新数据的时候会检查是否有别的线程在此期间更新数据,如果有别的事务在修改数据,此事物会回滚,可以使用版本号等机制。乐观所适用于写操作很少的情况下。
    

    22 脏读,不可重复读,幻读

    1  脏读:读取到没有提交的数据。比如老张发现自己的银行账户收进了老板打来5000元,但是老板此时还为提交事物,老发发现打钱的数来那个有误,其实是2000。老板又撤销了事物。这是后老张的银行账户其实只有2000元。
    
    2  不可重复读:比如老张的老婆在用老张的账户进行取款操作,而此时老张正在使用银行卡进行pos消费。当老张老婆查询到账户还有5000,但是在老张老婆取款前,老张pos消费了3000.然后老张老婆进行取款,会显示余额不足。
    
    3  幻读:老张老婆在银行部门工作,查询了老张这个月的消费账单,而然后老张又pos消费了一笔。然后老张老婆打印账单会发现多了一条记录。
    

    23 Stastement和PreparedStatement

    Java中是这样使用两者的:
    Statement st=connectiion.createStatement();
    st.execuseQuery(sql);

    PreparedStatement pst=connection.preparedStatement(sql);
    pst.ecxcuseQuery();

    程序中应该尽量用preparedStatement。优势如下:

    1:可使用参数化查询。参数化查询的效率比凌乱的字符串追加的方式的效率更高。
    2:会有预编译处理(jdbc引擎支持的前提),会将编译好的sql语句放进数据库系统,下次可以重新使用。对于相同查询,不同参数的查询,效率会很好。
    3:可以防止大部分的sql注入攻击。
    

    24 抽象类和接口

    1	抽象类中可以有默认的方法实现,而接口不可有有方法的实现。
    2	抽象类的方法的修饰符可以是public, private,protected.但是接口中方法只能是public(默认就是public ) 
    3	抽象类可以定义普通变量。接口中的变量只能是public static final(默认)
    4	继承抽象类后不可以继承其他类,实现接口后可以,继承其他类。
    5	抽象类可已有构造方法,接口不行。
    

    使用时机:
    当需要有一些方法的默认实现的时候,就用抽象类。
    当还有其他的父类需要继承的时候就必须用接口。

    25 TCP的滑动窗口

    点击我

    26 消息队列的作用

    1	实现解耦。
    2	用作缓冲。
    3	异步通信,送达保证。
    

    27 Java IO用到的设计模式

    IO用到的设计模式主要有装饰模式和适配器模式。
    详情请点我

    Java IO

    28 Java IO VS NIO

    1 IO是面对字节(字符)流的,NIO是面对缓冲区的。IO面对流意味着每次从流中读取一个或者更多字节,没有被缓冲到任何其它地方,数据不能前后移动。NIO面对缓冲区更具有灵活性,它将数据读取到一个缓冲区,可以在缓冲区中前后移动数据。
    2 IO是阻塞模式的。NIO是非阻塞的。阻塞意味着每次读取数据的时候,一定要读取到数据,如果没有数据,此时线程不能做其它任何事情,直到等到有数据可读(数据完全写入)为止。NIO的非阻塞模式当没有数据可读的时候线程不会阻塞,会先去干其它事情,通常会去处理其它channel的读写。所以此时一个线程就可管理多个channel。
    

    Java IO与NIO区别

    29 单例模式

    详细请点击我

    //内部类实现

    //单例模式
    
    class Single{
    	//将构造器变为私有
    	private Single(){
    		
    	}
    	//内部类
    	private static class SingleHolder{
    		private static final Single Instance=new Single();
    	}
    	public static Single getInstance(){
    		return SingleHolder.Instance;
    	}
    }
    

    30 java堆的参数

    堆内存

    -Xms:初始内存
    -Xmx:最大堆内存
    

    非堆内存

    -XX:PermSize	非堆内存初始大小
    -XX:MaxPermSize:非堆内存最大大小
    

    31 volatile的作用

    1	实现变量的可见性,让读取变量的线程及时读取到变量最新的值,禁止工作线程拷贝。
    2	防止编译器的指令重排序。
    

    32 BeanFactory和ApplicationContext的区别

    1  BeanFactory是最基本的接口,ApplicationContext是前者的扩展。功能更加强大。
    2  ApplicationContext扩展MessageSource来支持国际化功能。
    3  ApplicationContext有事件监听空能。因为其支持ApplicationEvent和ApplicationListener。
    4  ApplicationContext在容器加载的时候会初始化所有容器中的对象,BeanFactory会延迟加载,直到getBean的时候才会初始化对象。前者能更好的检查容器配置中的错误。
    5  BeanFactory的实现有XmlBeanFactory。ApplicationContext的实现有XmlWebApplicationContext,FileSystemXmlApplicationContext,ClassPathXmlApplicationContext,
    6  ApplicationContext扩展ResourceLoader(资源加载器)支持底层资源访问。
    

    33 面向对象的设计原则

    7大原则:

    1  里氏替换原则,所有子类必须都能够代替父类。
    2  依赖倒置原则,实现应该依赖与抽象,而不是具体
    3  开闭原则,所有类应该对扩展开放,对修改关闭
    4  单一职责原则,一个类应该专注与做一件事情。
    5  迪米特原则,一个软件实体应该尽可能少得访问其它实体。
    6  聚合原则,应该尽可能多得使用聚合或者复用,避免使用继承。
    7  接口隔离原则,应该尽可能为客户提供单独的小的接口,而不是大的接口。
    

    34 几种导致类加载的情况

    1  使用new关键字,读取类的静态成员,设置类的静态成员值,调用类的静态方法,如果类没有被初始化,则要先初始化类。
    2  使用java.lang.reflect中的方法进行反射调用的时候,如果类没有被初始化,则要先初始化类。
    3  加载一个子类的时候,如果父类没有被加载,则要先加载父类。
    4  JVM启动的时候,要先加载主类(带有main方法的类)、
    5  一个java.lang.invoke.MethodHandler的实例的解析结果(结果是REF_getstatic,REF_putstatic,REF_invokestatic)的方法句柄所对应的类没有被初始化,则要先初始化此类。
    

    35 css导入方式

    1 在html标签中使用style属性

    `<span style="color:blue">我是蓝色</span>`
    

    2 直接在head中写css文件,style标签

    <head>
    	<style type="text/css">
    		h1{color:red}
    	</style>
    </head>
    <body>
    	<h1>我是1号标题</h1>
    </body>
    

    3 将css文件单独写在一个文件中然后用link标签导入。

    写好的一个css文件test.css。然后在html文件中。

    <head>
    	<link href="test.css" rel="stylesheet" type="text/css"></link>
    </head>
    

    36 集合框架的UML图

    37 数据结构

    点击我

    38 二分查找算法

    详细点击我

    39 ConcurrentHashMap的原理

    ConcurrentHashMap主要有3个对象,HashMap,Segment,HashEntry。
    ConcurrentHashMap默认有16个Segment(段),一个段里面装的是HashMap的一部分Entry。操作特点:

    put,get,remove操作:都是将对应的Segment加锁。读写某个的Segment中的Entry,并不影响其它Segment的操作,这是其增加Map性能的核心方法。
    size方法会锁定整个表。

    40 视图和表

    视图就是一些sql语句的集合,是从数据表中提取的子集。
    一般可以禁止用户访问数据库表,而以视图的方式呈现给用户,这样既可以保证数据表的安全,也可以让用户或者应用程序不受到数据库修改带来的影响。
    2者区别:

    1	视图不占用物理内存。表要占用物理内存。
    2	视图是展现数据的窗口。表是数据内容。
    3	我们可以对表进行修改,但是只能通过创建视图的语句来修改视图。
    

    41 sessions和cookies

    客户端第一次通过http协议访问服务器的时候,服务器会生成一些带有限制条件的key-value键值对,cookies保存在客户端,当下次同一客户端访问的时候,条件满足的时候,会将这些数据完整地带回服务器,sessions保存在服务器端。cookies保存在客户端浏览器内存中,访问服务器的时候会返回给服务器一个name叫做JSESSIONID的一个cookie。
    

    42 ThreadPoolExecutor的及其参数

    public class ThreadPoolExecutor extends AbstractExecutorService{}
    

    其中最重要的构造器有

    public ThreadPoolExecutor(int corePoolSize,
                                  int maximumPoolSize,
                                  long keepAliveTime,
                                  TimeUnit unit,
                                  BlockingQueue<Runnable> workQueue)
    
     public ThreadPoolExecutor(int corePoolSize,
                                  int maximumPoolSize,
                                  long keepAliveTime,
                                  TimeUnit unit,
                                  BlockingQueue<Runnable> workQueue,
                                  RejectedExecutionHandler handler) 
    

    int corePoolSize:核心池的线程大小。
    int maximumPoolSize:最大容许的线程大小。
    long keepAliveTime:只有正在运行的线程数量大于corePoolSize,这个参数才生效,如果一个线程无事可做,并且线程数量大于或者等于corePoolSize,超过keepAliveTime会关闭此进程,收缩到corePoolSize大小。
    TimeUnit unit:时间单位。
    BlockingQueue<Runnable> workQueue :缓冲队列。一般可以用ArrayBlockingQueue或者LinkedBlockingQueue。
    RejectedExecutionHandler handler:饱和策略。

    其中几个最重要的方法
    submit()
    execute()
    shutDown()
    shutDownNow()

    43 线程池的饱和策略

    线程池接受任务的过程如下:
    1 提交一个任务,如果当前线程池中的数量小于corePoolSize,则创建线程运行此任务。
    2 提交一个任务,如果当前线程数量大于或者等于corePoolSize,任务队列未满,则将任务放进缓冲队列。
    3 提交一个任务,如果当前线程数量大于或者等于corePoolSize并且小于maximumPoolSize,任务队列已满,则创建线程运行。
    4 如果当前线程数量大于或者等于maximumPoolSize,缓冲队列已满。则达到饱和状态,会根据响应的饱和状态的则略来处理。默认策略是AbortPolicy。

    可以通过ThreadPoolExecutor.setRejectedExecutionHandler(RejectedExecutionHandler) 设置
    策略有4种:
    AbortPolicy:是默认的策略,在饱和状态下接受任务会抛出异常,程序员可以捕获异常来进行自己想要的处理。
    CallerRunsPolicy:会将任务交给提交任务的线程来运行。
    DiscardPolicy:直接将任务丢弃。
    DiscardOldestPolicy:将workQueue头部的任务取消掉,常事重新运行。

    44 类加载器和双亲委派模型

    类加载气有以下几种:

    1	BootstrapClassLoader(启动加载器),比如负责jre/lib/* 下面的所有包,是虚拟机自带的,底层C++实现。
    2	ExtensionClassLoader(扩展类加载器),加载jre/lib/ext/*下面的所有包。
    3 ApplicationClassLoader(应用程序类加载器),加载classPath(类路径下面的jar包)。可以用System.getSystemClassLoader()来获取这个加载器。
    4	当然也可以定义自己的加载器。
    

    从上至下,上面的加载器是下面加载器的父加载器,这里并不是继承的关系。双亲委派模型就体现在这里:
    当一个加载器收到一个类加载的请求后,会先交给父加载器去加载,如果不在父类不能加载,自己再去加载这个类。好处是类随着这种加载机制获得了一中带有优先级的层次关系。比如Object类,是在rt.jar中,这种机制会保证这个类都被引导类加载器加载,保证了Object的唯一性。

    45 CMS的几个步骤

    初始标记,并发标记,重新标记,并发清除,并发重设状态。其中初始标记,重新标记需要Stop the world。
    

    46 策略模式及其UML图

    策略模式主要是对方法进行包装,将不同的方法封装在实现了同一个接口的类中。有环境角色,策略抽象角色,策略具体角色。

    这里写图片描述


    47 常用的LINUX命令

    查看文件命令:cat head tail more less vim vi gvim
    查找命令:grep,find,locate,whereis,which

    用户管理命令:

    	groupadd user,
    	groupdel user,
    	查看当前用户所在组(groups someuser),
    	将用户组test修改为testnew(groupmod -n testnew test)
    
    将用户test添加到test2用户组并将用户目录设置为~/test
    
    usermod -d ~/test -G test2 test
    
    gpasswd -a test test2
    
    将用户test从test2中删除
    	
    gpasswd -d test test2
    

    系统性能维护命令:
    top


    48 排序算法

    交换排序:
    冒泡排序:点击我查看
    快速排序:点击我查看

    插入排序:
    直接插入排序:点击我查看
    希尔排序:点击我查看

    选择排序和堆排序:点击我查看

    本文所有代码均在Github上共享:查看Github
    更多资源
    请点击我
    还有我

    49 有关数据库

    有待更新

    50 阻塞队列

    1 非阻塞队列

    我们一般会接触到非阻塞队列  PriorityQueue,LinkedList(LinkedList实现了Deque)。但是当涉及到多线程操作的时候(比如生产者和消费者模式),就会显得很不方便。所以这里就会用到阻塞队列。
    

    2 阻塞队列的种类:

    • (1)ArrayBlockingQueue:基于数组的一个阻塞队列,比较常用 的阻塞队列。有界的阻塞队列,实例化的 时候一定要指定容量参数,还可以指定公平性,和初始化会用到的集合。当然是容量参数是一定得有的。元素是FIFO进队和出队。
    • (2)LinkedBlockingQueue:基于链表的阻塞队列,如果没有指定容量参数,默认的容量大小为 Integer.MAX_VALUE。元素是FIFO进队和出队。
    • (3)PriorityBlockingQueue:无界的阻塞队列(向其插入元素的时候不会失败),但是它不是FIFO的顺序进队和出队。它是通过元素的优先级来排序的,优先级高的元素会优先出队。
    • (4)DelayQueue(基于PriorityQueue):延迟阻塞队列。其中的元素只有在延迟了一定的时间后才能够出队列。

    3 常用到的方法

    非阻塞队列常用的方法有(非阻塞队列中的方法都没有进行线程同步):

    add(E e):向队尾添加元素,添加失败(队满)抛出异常。
    
    remove():从队首移除元素,如果移除失败会抛出异常。
    
    off(E e):向队尾添加元素,添加成功返回true,失败返回false。
    
    poll():从队首获取并且移除元素,如果成功返回队首元素,如果移除失败,则返回null;
    通常用后2中方法,因为可以根据返回值判断操作是否成功。
    

    阻塞队列常用到方法:

    阻塞队列除了有以上非阻塞队列的方法外(将以上的方法进行了同步)。还添加了以下方法:
    
    take():从队首获取元素,成功返回队首的值,失败(队列空)则阻塞等待。
    
    put(E e):向队尾添加元素,添加失败阻塞等待。
    
    offer(E e,Time t,TimeUnit unit):向队尾添加元素,如果等待一段时间后添加仍然失败则返回false。
    
    poll():从队首获取元素,如果等待一段时间后获取元素仍然失败则返回null。
    

    本文出自
    代码大湿
    代码大湿

  • 相关阅读:
    电商用户留存率比例
    转载——使用Python拆分数据量大的CSV文件(亲测有效)
    SQL中group by的注意事项
    MySQL中DELETE子句与TRUNCATE TABLE语句的区别
    TimeStamp( )函数, TimeStampAdd( )函数 , TimeStampDiff( )函数
    MySQL 练习题目 二刷
    math对象,BOM模型中常用对象
    js函数和date内置对象
    while循环和for循环
    不等于运算符、逻辑表达式、if语句及switch语句
  • 原文地址:https://www.cnblogs.com/pin-wang/p/5781172.html
Copyright © 2011-2022 走看看