共计 8474 个字符,预计需要花费 22 分钟才能阅读完成。
汇合有哪些? 数据结构? 初始长度? 哪些线程是平安的?hashmap 的底层原理?
单列汇合:List,Set
双列汇合:Map
List 是一个有序, 可反复的汇合
ArraysList: 底层数据结构为数组, 查问快, 增删慢, 线程不平安, 效率高, 初始长度为 10, 增量 0.5 倍加 1
Vector: 底层数据结构是数组, 查问快, 增删慢, 线程平安, 效率低, 初始长度为 10, 增量 1 倍
LinkedList: 底层数据结构是链表, 查问慢, 增删快, 线程不平安, 效率高
Set 是一个无序, 不可反复的汇合
HashSet: 底层数据结构是哈希表, 都是一个寄存链表的数组, 线程不平安, 效率高, 但它不保障存储元素的迭代程序,HashSet 实际上是一个 HashMap 实例,HashSet 中的元素都寄存在 HashMap 的 key 下面, 此类容许应用 null 元素,HashSet 不容许有反复元素, 初始容量 16, 加载因子 0.75(超过汇合长度值), 扩容曾量 1;
LinkedHashSet(HashSet 的子类): 底层数据结构由链表和哈希表组成, 链表保证数据中有序, 哈希表保证数据惟一
TreeSet: 底层数据结构是红黑树(自均衡的二叉树) 增加数据通过返回值是否为 0 来决定数据的唯一性, 通过天然排序和比拟器排序这两种形式实现汇合元素的排列
双列汇合:Map 数据结构仅仅只针对键无效, 与值无关, 存储键值对像是, 键惟一, 值可反复
HashMap: 底层数据结构是哈希表(数组加链表), 线程不平安, 效率高, 容许有空值和空键, 初始容量 16, 加载因子 0.75, 扩大增量 1, 原理: 当咱们往 hashmap 中 put 元素时, 首先依据 key 的 hashcode() 冲虚计算 hash 值, 依据 hash 值得到这个元素在数组中的地位 (下标), 如果该数组在该地位上曾经寄存了其余元素, 那么在这个地位上的元素将以链表的模式寄存, 新退出的放在链头, 最先退出的放入链尾, 如果数组中该地位没有元素, 就间接将该元素放到数组的该地位上.JDK1.8 当前对 HasgMap 的实现做了优化, 当链表中的节点数据超过八个当前, 该链表会转为红黑树来进步查问效率, 从原来的 O(n) 到 O(logn),
LinkedHashMap(HashMap 的子类): 底层数据结构由哈希表和链表组成, 哈希表保证数据惟一, 链表保证数据有序;
Hashtable: 底层数据结构是哈希表, 线程平安, 效率低;
TreeMap: 底层数据结构是红黑树
线程平安:
Vector: 就比 Arraylist 多了个同步化机制(线程平安)
Hashtable: 就比 HashMap 多了个线程平安.
ConcurrentHasgMap: 是一种高效然而线程平安的汇合.
Stack: 栈, 也是线程平安, 继承于 Vector
线程的创立? 开启? 状态?sleep 和 wait 的区别? 线程池? 死锁? 如何保障线程平安?
线程的创立:
实现 Runnable 接口, 重写 run();
继承 Thread 类, 重写 run();
实现 Callanle 接口, 重写 call(), 利用 FutureTask 包装 Callable, 并作为 task 传入 Thread 构造函数;
利用线程池创立.
线程的启动:
启动线程的惟一办法就是通过 Thread 类的 start()实例办法.
线程的状态: 新建, 就绪, 运行, 阻塞, 死亡
sleep 和 wait 的区别:
sleep 属于 Thread 类中的办法,wait 属于 Object 类中的办法
调用 sleep 办法的线程对象,尽管在指定工夫内不会取得 CPU 的执行权,然而并没有开释对锁的控制权,即当休眠状态的线程取得锁的时候,其余线程不能从新取得锁,然而 wait 办法是开释锁的,使其余线程能够取得锁而取得资源的控制权;
线程池: 次要解决处理器单元内多个线程执行的问题, 能够显著缩小处理器单元的闲置工夫, 减少处理器单元的吞吐能力. 假如一个服务器实现一项工作所需工夫为:T1 创立线程工夫,T2 在线程中执行工作的工夫,T3 销毁线程工夫。如果:T1 + T3 远大于 T2,则能够采纳线程池,以进步服务器性能。
线程池包含以下四个根本组成部分:
线程池管理器(ThreadPool):用于创立并治理线程池,包含 创立线程池,销毁线程池,增加新工作;
工作线程(PoolWorker):线程池中线程,在没有工作时处于期待状态,能够循环的执行工作;
工作接口(Task):每个工作必须实现的接口,以供工作线程调度工作的执行,它次要规定了工作的入口,工作执行完后的收尾工作,工作的执行状态等;
工作队列(taskQueue):用于寄存没有解决的工作。提供一种缓冲机制。
死锁: 是指两个或两个以上的过程在执行过程中,因为竞争资源或者因为彼此通信而造成的一种阻塞的景象,若无外力作用,它们都将无奈推动上来。
死锁的四个必要条件:
互斥条件:过程对所调配到的资源不容许其余过程进行拜访,若其余过程拜访该资源,只能期待,直至占有该资源的过程应用实现后开释该资源;
申请和放弃条件:过程取得肯定的资源之后,又对其余资源发出请求,然而该资源可能被其余过程占有,此事申请阻塞,但又对本人取得的资源放弃不放
不可剥夺条件:是指过程已取得的资源,在未实现应用之前,不可被剥夺,只能在应用完后本人开释
环路期待条件:是指过程产生死锁后,若干过程之间造成一种头尾相接的循环期待资源关系
线程平安: 一般说来,确保线程平安的办法有这几个:竞争与原子操作、同步与锁、可重入、适度优化
互斥锁,能够保障线程的原子性,当线程进入办法时,会主动取得一个锁,一旦锁被取得,其余线程必须期待取得锁的线程执行完代码开释锁,会升高程序的执行效率
ThreadLocal 为每个线程提供局部变量,解决线程平安问题
== 和 equals 的区别?
== 对于根本类型来说是值比拟,对于援用类型来说是比拟的是援用;而 equals 默认状况下是援用比拟,只是很多类从新了 equals 办法,比方 String、Integer 等把它变成了值比拟,所以个别状况下 equals 比拟的是值是否相等。
对反射的了解? 获取 class 类的形式有哪些? 如何用反射取公有属性 Filed?
反射: 就是程序在运行过程中可能获取本身的信息, 即能获取 java 中反射类的字节码, 在 java 中只有给定类的名字就能通过反射机制获取该类的所有信息;
获取 class 的形式:
Class class = Class.forName(“ 被获取类的全限定类名 ”)
Class class = 类名.class
Class class= 类对象 (this).getClass()
如何用反射获取公有属性 Filed
反射获取类对象,获取公有属性和办法汇合,而后勾销拜访查看 setAccessible(true),最初调用公有属性或办法。
Field[] fields=s.getClass().getDeclaredFileds();
批改公有属性:
追加:fields.setAccessible(true);
获取对象:
Student s=(Student)class.getConstructor().newInstance();(初始化无参构造方法增强转)
罕用的设计模式有哪些? 我的项目中哪里有用到? 单例中懒汉饿汉优缺点?
罕用设计模式:
创立类 (创立一个对象):单例模式,工厂模式,形象工厂模式
结构性 (将几个对象组织成一个构造):桥接模式, 外观模式, 代理模式
行为型 (多个对象间的通信): 观察者模式, 策略模式
我的项目中用到:
数据库连接池,线程池,网站拜访计数器,mybatis 中的 SqlSessionFactory,spring 容器中的 bean 对象默认应用到了单例模式;
spring 中的 AOP 用到了代理模式
jdbc 连贯数据库用到了桥接模式
懒汉饿汉优缺点:
饿汉:在加载类时就构建,事后加载;
长处:线程平安,在类加载的同时就创立好了动态对象,调用时反应速度快;
毛病:资源效率不高
懒汉式: 在应用该类的对象时才会产生实例化对象;提早加载 (不会第一工夫 new 对象来占用内存, 而是什么时候 gets 什么时候 new); 线程平安(共享资源被多条语句操作 – 改良形式就是加锁 synchornized:双重检测,)
长处:资源利用率高
毛病:第一次加载不够快,多线程应用不必要的同步开销大
restful 设计格调:Restful 就是一个资源定位及资源操作的格调。不是规范也不是协定,只是一种格调。基于这个格调设计的软件能够更简洁,更有档次,更易于实现缓存等机制。
jdk1.8 新个性有哪些?
原来的 HashMap 汇合底层是数组加链表,1.8 当前引入了红黑树,当碰撞的元素个数大于 8 时 & 总容量大于 64,会有红黑树的引入;1.8 之后链表新进元素加到开端
Lambda 表达式
Optional 类:Optional 类曾经成为 Java 8 类库的一部分,用来解决空指针异样。
Stream API:新增加的 Stream API(java.util.stream)把真正的函数式编程格调引入到 Java 中
等…
session 的实现原理?session 的生命周期?session 如何贮存数据?
session 的实现原理: 客户向服务器端发送申请后,服务端创立 session,会把 session 对象的 id 以 cookie 模式返回给客户端,当下次发送申请时,会把 session 的 id 传给服务器,服务器依据 session 的 id 来为用户提供相应的服务。
session 的生命周期: 存储数据计时是滚动计时形式, 等到默认工夫后,主动销毁;
session 如何存储数据:
session.setAttribute(String attrName,Object attrValue)– 往 session 域中增加一个域属性, 属性名只能是字符串类型, 属性值能够是任意类型
session.getAttribute(String attrName)– 依据属性名获取域中的属性值, 返回值是一个 Object 类型
类加载机制?代码块的执行程序?
加载过程:加载,验证,筹备,解析,初始化,应用,卸载;
代码块的执行程序:
在主类中定义的动态代码块会优先于主办法(main)执行;
动态块优先于结构块执行;
结构块优先于构造方法执行,每产生一个新对象就调用一次结构块,结构块能够进行简略的逻辑操作;
有继承关系的话,在 main 办法里 new 子类,则先调用父类,再调用子类;
cookie 和 session 的区别?
cookie 数据寄存在客户的浏览器上,session 寄存在服务器上;
cookie 不平安(因为寄存在浏览器上,能够操作本地的 cookie 数据),session 平安
cookie 贮存为 String 数据,session 贮存为 Object 类型数据
cookie 能够长时间保留一些数据,session 随着会话完结,销毁数据;
Java 中字符串的办法有哪些?string、stringbuild、stringbuffer 的区别?
String 类的罕用办法:
indexOf():返回指定字符的索引。
charAt():返回指定索引处的字符。
replace():字符串替换。
trim():去除字符串两端空白。
split():宰割字符串,返回一个宰割后的字符串数组。
getBytes():返回字符串的 byte 类型数组。
length():返回字符串长度。
toLowerCase():将字符串转成小写字母。
toUpperCase():将字符串转成大写字符。
substring():截取字符串。
equals():字符串比拟。
string、stringbuild、stringbuffer 的区别:
String:不可变的字符串序列
StringBuffer:可变字符串序列、效率低、线程平安(不能同步拜访);
StringBuilder:可变字符串序列、效率高、线程不平安;
jvm 调优和垃圾回收机制?
jvm 调优:
应用 JDK 提供的内存查看工具,如 JConsole 和 Java VisualVM;
管制堆内存各个局部所占的比例;
采纳适合的垃圾收集器.
垃圾回收机制:
判断是否为垃圾(援用计数算法,可达性算法)
垃圾回收(标记革除、标记整顿、标记复制)
Java 中锁的品种和基本原理?
锁就是限度多线程中同时只有一个线程拜访到这个锁对应的对象,其余线程要期待这个线程将锁开释了能力获取到这个锁,其实锁,它锁住的并不是要拜访的对象,而是代码,如果多个线程拜访一个对象,一个线程获取到了这个对象的锁,然而其余线程依然能够拜访这个对象并进行批改,只是获取不到锁
锁品种和原理:
偏心锁:指的是依照申请的程序来获取锁
非偏心锁:线程不肯定依照申请锁的程序来获取锁
独享锁:一次只能被一个线程拜访,如:写锁
共享锁:能够被多个线程所持有,如:读锁
乐观锁:对一个数据的操作并发,是不会产生批改的。在更新数据时会采纳一直重入的形式更新数据.
乐观锁:对于同一个数据的并发操作,是肯定会产生批改的。因而对于同一个数据的并发操作,乐观锁采纳加锁的形式。乐观锁认为不加锁会出事.
分段锁:并发操作就是分段锁,其思维就是为了让锁的粒度变小;
偏差锁:指的是一段同步代码始终被一个线程拜访,那么该线程就会主动获取锁,升高取锁的代价.
collection 和 collections 的区别?
Collection 是一个接口,它是 Set、List 等容器的父接口.
Collections 是个一个工具类,提供了一系列的静态方法来辅助容器操作,这些办法包含对容器的搜寻、排序、线程平安化等等
java 如何跳出循环?
continue:停止本次循环,持续下次循环。continue 当前的循环体中的语句不会继续执行,下次循环继续执行,循环体里面的会执行;
break:间接完结一个循环,跳出循环体。break 当前的循环体中的语句不会继续执行,循环体里面的会执行
return:return 的性能是完结一个办法。一旦在循环体内执行 return,将会完结该办法,循环天然也随之完结
排序有哪些? 原理是什么?
冒泡排序:从第一个数开始,相邻元素两两比照,小的数放后面。(每循环一次,最初一个数都会被确定下来,为每轮的最大数)
抉择排序: 从第一个数开始,循环一圈找最小的数替换地位。(每循环一圈,第一个数都会被确定下来,为每轮最小的值)
插入排序: 从第二个数开始,跟前一个数比拟,若比前一个数小,则替换地位,接着跟前一个数比拟,直到比前一个数大为止。(从第一张开始整顿扑克牌,小的往前插)(可能会呈现一个数从最初比拟到最后面,比拟费时)
希尔排序属于插入类排序,是将整个有序序列宰割成若干个小的子序列别离进行插入排序。
归并排序: 归并排序有两种实现办法:自上而下的递归;自下而上的迭代。
将原数组用二分法始终分到两个数为一组,而后通过比拟将较小的数放到后面(通过一个两头数组排序);而后一层层向上排序。
疾速排序: 先找到一个基准点(个别指数组的中部),而后数组被该基准点分为两局部,顺次与该基准点数据比拟,如果比它小,放右边;反之,放左边。左右别离用一个空数组去存储比拟后的数据。最初递归执行上述操作,直到数组长度 <=1。
堆排序:堆逻辑上是一棵齐全二叉树。
计数排序:计数排序是一种不基于比拟的排序算法,次要思维是计算出待排序序列的最大值 maxValue 与 最小值 minValue,开拓一个长度为 maxValue – minValue + 1 的额定空间,统计待排序序列中每个元素的数量,记录在额定空间中,最初遍历一遍额定空间,依照程序把每个元素赋值到原始序列中。
基数排序:将整数按位数切割成不同的数字,而后按每个位数别离比拟。
桶排序:假设有 1 -100 个编号的桶(既定义一个长度为 100 的整型一维数组),每输出一个数字·就在对应的桶上插一个小旗(也就是对应下标的桶加 1 次),如果这个数字呈现了 n 次就在对应桶上插 n 个小旗,当所有数输出结束时,只须要从下标 1 开始找那些数字是 1,如果是 1 就打印 1 次,是 2 就打印 2 次,是多少就打印多少次。
什么是堆栈?什么是内存溢出?有垃圾回收机制了为什么还会呈现内存溢出的状况?
堆栈(两种不同的数据结构):
堆:程序随便
栈:先进后出
内存溢出:
内存溢出(out of memory),是指程序在申请内存时,没有足够的内存空间供其应用,呈现内存溢出。
内存泄露最终也会导致内存溢出。
有垃圾回收机制(内存满了就回收垃圾再调配空间)了为什么还会内存溢出:
垃圾回收机制只能回收没有援用的对象,也就是说只能回收没有“指针”的对象,对于非援用类对象,垃圾回收机制就不能起作用,比如说关上过多的数据库连贯,ArrayList 死循环,就不能被回收可能会造成内存溢出的状况
内存模型的了解?
因为物理计算机谋求速度,导致高速缓存的呈现,高速缓存的呈现带来了缓存一致性的问题。不同架构的物理计算机应用了不同的内存模型解决了缓存一致性。咱们 java 程序要运行在物理计算机,又要具备平台无关性。那么只能本人定义一个内存模型来屏蔽掉物理机不同的内存模型带来的影响。并且要解决缓存一致性的问题。解决了平台无关行, 缓存一致性.
泛型的了解
用于指定增加到汇合的类型
益处:
类型参数化,通用、能够像办法一样的参数一样传递,十分实用。
平安、编译时查看类型是否正确,升高类型强转报错率。
进步代码重用率。
Java 的根本类型有哪些?int 占几个字节?byte 占几个字节?
常见的异样有哪些?异样解决的形式有哪些?
Exception: 须要进行解决, 用于用户程序能够捕捉到异常情况;
error: 程序对此无能为力, 不显式的解决, 定义了不冀望被用户捕捉到的异样
异样解决形式:
在办法申明处, 显式的应用 throws+ 异样类型
try{解决形式 1}catch{解决形式 2}finally{肯定要执行的代码}
定义一个异样类:
自定义的异样类继承现有的异样类
提供一个序列号, 提供几个加载的结构器
枚举的理解?
枚举类是一种非凡的类,它和一般的类一样,有本人的变量、办法和结构器。它的结构器只能
应用 private 拜访修饰符,所以无奈从内部调用结构器,结构器只能在结构枚举值时被调用
一个 java 源文件中只能有一个 public 类型的枚举类,而且该原文件的名字也必须和该枚举类的
名字统一。也就是在一个文件中只能有一个 public 润饰的枚举类。这里不包含外部类哈,指的是
公共拜访的.java 文件的入口。
枚举类和 class,interface 位置是等同的,枚举也能实现接口。
枚举类的对象是无限且固定的,罕用于状态、类型
枚举类默认集成了 java.lang.Enum 类,并实现了 java.lang.Seriablizable 和 java.lang.Comparable
两个接口
所有的枚举值都默认是 public static final 的,不必反复申明,而且枚举值应该显式的在枚举类第一行列出,否则无奈产生实例,非形象的枚举类不能再派生子类。
枚举值列举的时候也能够实现该枚举类实现的接口办法。
final、finally、finalize 关键字的区别?volatile 关键字的理解?
final 能够润饰类、变量、办法,润饰类示意该类不能被继承、润饰办法示意该办法不能被重写、润饰变量示意该变量是一个常量不能被从新赋值。
finally 个别作用在 try-catch 代码块中,在解决异样的时候,通常咱们将肯定要执行的代码办法 finally 代码块中,示意不论是否出现异常,该代码块都会执行,个别用来寄存一些敞开资源的代码。
finalize 是一个办法,属于 Object 类的一个办法,而 Object 类是所有类的父类,该办法个别由垃圾回收器来调用,当咱们调用 System 的 gc()办法的时候,由垃圾回收器调用 finalize(), 回收垃圾。
volatile 关键字:
一旦一个共享变量(类的成员变量、类的动态成员变量)被 volatile 润饰之后,那么就具备了两层语义:
保障了不同线程对这个变量进行操作时的可见性,即一个线程批改了某个变量的值,这新值对其余线程来说是立刻可见的。
禁止进行指令重排序。
在一个 list 中寄存 string 类型的字符串,如何实现把所有带“王”的字符串从 list 中去除?
遍历汇合 for(String s:list)
判断遍历的对象中是否含有“王”if(s.indexOf(“王”)!=-1)
执行删除 list.remove(s)
如何序列化和反序列化?序列化的目标?
序列化是指将 Java 对象转换为字节序列的过程,而反序列化则是将字节序列转换为 Java 对象的过程。
实现序列化:实现 Serializable、Externalizable 接口(没有任何办法,只是作为一种标记)
实现反序列化:即反向进行序列化的过程,须要将一个 InputStream 封装在 ObjectInputStream 对象内,而后调用 readObject()办法,取得一个对象援用(它是指向一个向上转型的 Object),而后进行类型强制转换来失去该对象。
目标:
实现了数据的长久化,通过序列化能够把数据永恒地保留到硬盘上(如:存储在文件里),实现永恒保留对象。
利用序列化实现近程通信,即:可能在网络上传输对象。