共计 8685 个字符,预计需要花费 22 分钟才能阅读完成。
- 汇合有哪些?数据结构?初始长度?扩容机制?哪些线程是平安的?hashmap 的底层原理?
1. 单列汇合;1:List(有序,可反复);
1.ArrayList:底层数据结构为数组,查问快,增删慢,线程不平安,效率高,初始长度 10,增量 0.5 倍加 1;
2.Vector:底层数据结构是数组,查问快,增删慢,线程平安,效率低,初始长度 10,增量 1 倍;
3.LinkedList: 底层数据结构是链表,查问慢,增删块,线程不平安,效率高;
2:Set(无序,惟一);
1.HashSet:底层数据结构是哈希表(哈希表依赖两个办法 hashCode()和 eauals()),执行程序为首先判断 hashCode()的返回值哈希值是否雷同,是则继续执行 equals()判断地址是否雷同,是则不增加,否则增加;初始容量 16,加载因子 0.75(超过汇合长度值),扩容增量 1;
2.LinkedHashSet(HashSet 的子类):底层数据结构由链表和哈希表组成,链表保证数据有序,哈希表保证数据惟一;
3.TreeSet:底层数据结构是红黑树(自均衡的二叉树),增加数据通过返回值是否为 0 来决定数据的唯一性,通过天然排序(元素要具备比拟性,让元素所属的类实现 Comparable 接口)和比拟器排序(汇合具备比拟性,让汇合接管一个 Comparable 的实现类对象)这两种形式实现汇合元素的排列;
2. 双列汇合;3.Map(Map 汇合的数据结构仅仅只针对键无效,与值无关;贮存键值对模式,键惟一,值可反复);
1.HashMap:底层数据结构是哈希表(数组加链表),线程不平安,效率高,调用 put(),get()办法存储,获取对象,调用 put()办法存储时,会先调用键对象的 hashCode()办法来计算哈希值,而后找到 bucket 地位来贮存对象,获取对象时,通过键对象的 equals 办法找到正确的键值对,返回值对象。HashMap 应用链表来解决碰撞问题,当产生碰撞了,对象将会贮存在链表的下一个节点中。HashMap 在每个链表节点中贮存键值对对象,当两个不同键值对对象的哈希值雷同会贮存在同一个 bucket 地位的链表中,键对象的 equals 办法用来找到键值对;初始容量 16,加载因子 0.75,扩容增量 1;
2.LinkedHashMap(HashMap 的子类):底层数据结构由哈希表和链表组成,哈希表保证数据惟一,链表保证数据有序;
3.Hashtable:底层数据结构是哈希表,线程平安,效率低;
4.TreeMap:底层数据结构是红黑树
2. 线程的创立?开启?状态?sleep 和 wait 的区别?线程池?死锁?如何保障线程平安?
线程的创立:
无返回:
1. 实现 Runnable 接口,重写 run();
2. 继承 Thread 类,重写 run();
有返回:
1. 实现 Callable 接口,重写 call(),利用 FutureTask 包装 Callable,并作为 task 传入 Thread 构造函数;
2. 利用线程池
线程的启动:
启动线程的惟一办法就是通过 Thread 类的 start()实例办法。
线程的状态:新建,就绪,运行,阻塞,死亡
sleep 和 wait 的区别:
1. 所属对象不同:
sleep 属于 Thread 类中的办法,wait 属于 Object 类中的办法
2. 对锁的控制权不同:
调用 sleep 办法的线程对象,尽管在指定工夫内不会取得 CPU 的执行权,然而并没有开释对锁的控制权,即当休眠状态的线程取得锁的时候,其余线程不能从新取得锁,然而 wait 办法是开释锁的,使其余线程能够取得锁而取得资源的控制权;
线程池:服务器实现一个线程的工夫:T1 创立线程工夫 +T2 线程执行工作所需工夫 +T3 线程销毁工夫;如果 T1+T3 要远大于 T2,这个时候就能够采纳线程池;进步服务器的性能;线程池技术正是关注如何缩短和调整 T1,T3 工夫的技术,从而进步服务器性能的。它把 T1,T3 别离安顿在服务器程序启动和完结的时间段或者一些闲暇的时间段,这样在进行解决客户申请时就不会有 T1,T3 的开销了;
线程池形成:
1. 线程池管理器(ThreadPool):用于创立并治理线程池,包含创立线程池,销毁线程池,增加新工作
2. 工作线程(PoolWorker):线程池中线程,在没有工作时处于期待状态,可循环的执行工作;
3. 工作接口(Task):每个人物必须实现的接口,以供工作线程调度工作的执行,他次要规定了工作的入口,工作执行完后的收尾工作,工作执行状态等;
4. 工作队列(taskQueue):用于寄存没有解决的工作。提供一种缓冲机制。
死锁:是指两个或者两个以上的过程在执行过程中,因为资源竞争或者彼此通信造成的阻塞景象
线程平安:一般说来,确保线程平安的办法有这几个:竞争与原子操作、同步与锁、可重入、适度优化
3.== 和 equals 的区别?
:对于根本类型比拟值,对于援用类型比拟内存地址
equals:它是 object 类中的办法,该办法如果没有被重写过默认也是“”,只能用于援用类型的比拟;
4. 对反射的了解?获取 class 类的形式有哪些?如何用反射取公有属性 Filed?
反射:就是程序在运行过程中可能获取本身的信息,(即能获取 java 中反射类的字节码,)在 java 中只有给定类的名字就可能通过反射机制获取该类的所有信息;
获取 class 类的形式:
1.Class class=Class.forName(“被获取类的全限定类名”)
2.Class class= 类名.class
3.Class class= 类对象(this).getClass()
如何用反射取公有属性 Filed:
Field[] fields=s.getClass().getDeclaredFileds();
批改公有属性:
追加:fields.setAccessible(true);
获取对象:
Student s=(Student)class.getConstructor().newInstance();(初始化无参构造方法增强转)
5. 罕用设计模式有哪些?我的项目中那里有用到?单例中懒汉饿汉优缺点?
罕用设计模式:Singleton(单例模式)、Factory(工厂模式)、Proxy(代理模式)、Adapter(适配器模式)、Strategy(策略模式)、Template(模板模式);
哪里用到:
1. 数据库连接池,线程池,网站拜访计数器,mybatis 中的 SqlSessionFactory,spring 容器中的 bean 对象默认应用到了单例模式;
2.spring 中的 aop 用到了代理模式
3.jdbc 连贯数据库用到了桥接模式
懒汉饿汉优缺点:
饿汉:在加载类时就构建,事后加载;
长处:线程平安,在类加载的同时就创立好了动态对象,调用时反应速度快;
毛病:资源效率不高,
懒汉:单例实例在第一次被应用时被构建,延时加载(在单线程应用没有问题,但在多线程就可能会呈现两个或者多个 Singleton2 实例状况,尽管前面的 Singleton2 会笼罩之前的单最好防止,改良形式就是加锁 synchornized:双重检测,个别采纳饿汉式单例模式,若对外部动态资源比拟在意能够采纳动态外部类,不倡议采纳懒汉单例模式);
长处:资源利用率高
毛病:第一次加载不够快,多线程应用不必要的同步开销大
restful 设计格调:Restful 就是一个资源定位及资源操作的格调。不是规范也不是协定,只是一种格调。基于这个格调设计的软件能够更简洁,更有档次,更易于实现缓存等机制。
6.jdk1.8 新个性有哪些?
1. 原来的 HashMap 汇合底层是数组加链表,1.8 当前引入了红黑树,当碰撞的元素个数大于 8 时 & 总容量大于 64,会有红黑树的引入;1.8 之后链表新进元素加到开端
2.Lambda 表达式
3.Optional 类:Optional 类曾经成为 Java 8 类库的一部分,用来解决空指针异样。
4.Stream API:新增加的 Stream API(java.util.stream)把真正的函数式编程格调引入到 Java 中
等…
7.session 的实现原理?session 的生命周期?session 如何贮存数据?
session 的实现原理:客户向服务器端发送申请后,session 创立在服务器端,返回 session 给客户端浏览器保留在本地,当下次发送申请时,在申请头中传递 sessionId 获取服务器上的对应的 session;session 寄存在服务器,敞开浏览器 session 不会隐没;
session 生命周期:等到默认工夫后,主动销毁;
session 如何贮存数据:httpSession.setAttribute(键值对);
8. 类加载机制?代码块的执行程序?
加载过程:加载,验证,筹备,解析,初始化,应用,卸载;
代码块的执行程序:
1. 在主类中定义的动态代码块会优先于主办法(main)执行;
2. 动态块优先于结构块执行;
2.1. 无论产生多少实例化对象,动态块都只执行一次;
3. 结构块优先于构造方法执行,每产生一个新对象就调用一次结构块,结构块能够进行简略的逻辑操作;
4. 有继承关系的话,在 main 办法里 new 子类,则先调用父类,再调用子类;
9.cookie 和 session 的区别?
1.cookie 数据寄存在客户的浏览器上,session 寄存在服务器上;
2.cookie 不平安(因为寄存在浏览器上,能够操作本地的 cookie 数据),session 平安
3.cookie 贮存为 String 数据,session 贮存为 Object 类型数据
4.cookie 能够长时间保留一些数据,session 随着会话完结,销毁数据;
10.Java 中字符串的办法有哪些?string、stringbuild、stringbuffer 的区别?
String 的办法:
1.equals,只比拟字符串外面的内容;
2.charAt(0),寻找对应 ascii 码对应的字符(47-58 对应 0 -9)
3.concat 办法就是连贯字符串
4.contains 办法 是否蕴含某个字符串
5.replace 办法用新的字符串来代替旧的字符串
6.toCharArry 就是将字符串转化为字符数组
7.trim 办法 是去掉前后的空格等…
string、stringbuild、stringbuffer:
string 的值是不可变的,然而 stringbuild、stringbuffer 能够被屡次批改;
StringBuilder 类在 Java 5 中被提出,它和 StringBuffer 之间的最大不同在于 StringBuilder 的办法不是线程平安的(不能同步拜访)。
因为 StringBuilder 相较于 StringBuffer 有速度劣势,所以少数状况下倡议应用 StringBuilder 类。然而在应用程序要求线程平安的状况下,则必须应用 StringBuffer 类。
String:不可变的字符串序列
StringBuffer:可变字符串序列、效率低、线程平安;
StringBuilder:可变字符串序列、效率高、线程不平安;
11.jvm 调优和垃圾回收机制?
jvm 调优:
1. 应用 JDK 提供的内存查看工具,如 JConsole 和 Java VisualVM
2. 管制堆内存各个局部所占的比例
3. 采纳适合的垃圾收集器
垃圾回收机制:
1. 判断是否为垃圾(援用计数算法,可达性算法)
2. 垃圾回收(标记革除、标记整顿、标记复制)
12.Java 中锁的品种和基本原理?
什么是锁:锁就是限度多线程中同时只有一个线程拜访到这个锁对应的对象,其余线程要期待这个线程释将锁开释了能力获取到这个锁,其实锁,它锁住的并不是要拜访的对象,而是代码,如果多个线程拜访一个对象,一个线程获取到了这个对象的锁,然而其余线程依然能够拜访这个对象并进行批改,只是获取不到锁,
锁品种和原理:
1. 偏心锁:指的是依照申请的程序来获取锁
2. 非偏心锁:线程不肯定依照申请锁的程序来获取锁
3. 独享锁:一次只能被一个线程拜访,如:写锁
4. 共享锁:能够被多个线程所持有,如:读锁
5. 乐观锁:对一个数据的操作并发,是不会产生批改的。在更新数据时会采纳一直重入的形式更新数据;
6. 乐观锁:对于同一个数据的并发操作,是肯定会产生批改的。因而对于同一个数据的并发操作,乐观锁采纳加锁的形式。乐观锁认为不加锁会出事;
7. 分段锁:并发操作就是分段锁,其思维就是为了让锁的粒度变小;
8. 偏差锁:指的是一段同步代码始终被一个线程拜访,那么该线程就会主动获取锁,升高取锁的代价
9. 轻量级锁
10. 重量级锁
11. 自旋锁
13.collection 和 collections 的区别?
Collection 是一个接口,它是 Set、List 等容器的父接口
Collections 是个一个工具类,提供了一系列的静态方法来辅助容器操作,这些办法包含对容器的搜寻、排序、线程平安化等等
14.java 如何跳出循环?
1.continue:停止本次循环,持续下次循环。continue 当前的循环体中的语句不会继续执行,下次循环继续执行,循环体里面的会执行;
2.break:间接完结一个循环,跳出循环体。break 当前的循环体中的语句不会继续执行,循环体里面的会执行
3.return:return 的性能是完结一个办法。一旦在循环体内执行 return,将会完结该办法,循环天然也随之完结
15. 排序有哪些?原理是什么?
1. 比拟排序:
1. 冒泡排序:每次对相邻的两个元素进行比拟,若前者大于后者则进行替换,如此一趟下来最初一趟的就是最大元素,反复以上的步骤,除了曾经确定的元素;
2. 抉择排序:抉择排序改良了冒泡排序,每次遍历列表只做一次替换,为了做到这一点,一个抉择排序在遍历时寻找最大的值,并在实现遍历后,将其放到正确的中央。第二次遍历,找出下一个最大的值。遍历 n - 1 次排序 n 个项,最终项必须在 n - 1 次遍历之后
3. 插入排序:通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应地位并插入。插入排序在实现上,通常采纳 in-place 排序(即只需用到 O(1) 的额定空间的排序),因此在从后向前扫描过程中,须要重复把已排序元素逐渐向后挪位,为最新元素提供插入空间。
4. 归并排序:归并排序是一种递归算法,一直将列表拆分为一半,如果列表为空或有一个项,则按定义进行排序。如果列表有多个项,咱们宰割列表,并递归调用两个半局部的合并排序。一旦对两半排序实现,获取两个较小的排序列表并将它们组合成单个排序的新列表的过程
5. 堆排序:堆逻辑上是一棵齐全二叉树。
6. 疾速排序:先定义两个指针,一个在最后面,一个在最初面,第一次要对数组进行划分,先找出一个两头数,个别默认把第一个数作为两头数,而后从后往前找比两头数小的,把他放在前一个指针的地位,在从前往后找比两头数大的,找到后把它放在第二个指针的地位,直到后面和前面的指针指向同一个地位,咱们就把两头值放在这里即可,这样依据两头数,把整个须要排序的数组分为两局部,前一部分都小于两头数,后一部分都大于两头数,此时这两局部的数还是无序的,最初递归调用排序办法,对两局部别离进行排序即可。
2. 非比拟排序:
1. 计数排序:计数排序是一种不基于比拟的排序算法,次要思维是计算出待排序序列的最大值 maxValue 与 最小值 minValue,开拓一个长度为 maxValue – minValue + 1 的额定空间,统计待排序序列中每个元素的数量,记录在额定空间中,最初遍历一遍额定空间,依照程序把每个元素赋值到原始序列中。
2. 基数排序:将整数按位数切割成不同的数字,而后按每个位数别离比拟。
3. 桶排序:假设有 1 -100 个编号的桶(既定义一个长度为 100 的整型一维数组),每输出一个数字·就在对应的桶上插一个小旗(也就是对应下标的桶加 1 次),如果这个数字呈现了 n 次就在对应桶上插 n 个小旗,当所有数输出结束时,只须要从下标 1 开始找那些数字是 1,如果是 1 就打印 1 次,是 2 就打印 2 次,是多少就打印多少次。
16. 什么是堆栈?什么是内存溢出?有垃圾回收机制了为什么还会呈现内存溢出的状况?
堆栈(两种不同的数据结构):
堆:程序随便
栈:先进后出
内存溢出:
内存溢出(out of memory),是指程序在申请内存时,没有足够的内存空间供其应用,呈现内存溢出。
内存泄露最终也会导致内存溢出。
有垃圾回收机制(内存满了就回收垃圾再调配空间)了为什么还会内存溢出:
垃圾回收机制只能回收没有援用的对象,也就是说只能回收没有“指针”的对象,对于非援用类对象,垃圾回收机制就不能起作用,比如说关上过多的数据库连贯,ArrayList 死循环,就不能被回收可能会造成内存溢出的状况
17. 内存模型的了解?
为了解决多线程通信,变量共享的并发问题并且保障跨平台行,Java 定义了本人的内存模型. 内存模型形容了程序中各个变量之间的关系, 以及操作系统将变量存储到内存以及从内存中取出变量这样的细节. 此处的变量不包含局部变量与办法参数, 后者是线程公有的, 不会被共享. 所以说 JMM 帮忙屏蔽了操作系统底层的细节, 保障了程序的正确性.
18. 泛型的了解
用于指定增加到汇合的类型
益处:
1. 类型参数化,通用、能够像办法一样的参数一样传递,十分实用。
2. 平安、编译时查看类型是否正确,升高类型强转报错率。
3. 进步代码重用率。
19.Java 的根本类型有哪些?int 占几个字节?byte 占几个字节?
Java 的根本数据类型(8 位位 1 字节):
1.byte:1 字节,8 位
2.short:2 字节,16 位
3.int:4 字节,32 位
4.long:8 字节,64 位
5.float:4 字节,32 位
6.double:8 字节,64 位
7.char
8.boolean
20. 常见的异样有哪些?异样解决的形式有哪些?
异样:
(1) Error: jvm 监管范畴外的, 能够捕捉,然而无奈解决
(2) Exection: 既能够捕捉,也能够解决(Exception: 编译异样,强制解决,RuntimeException: 运行时异样,不强制解决)
解决形式:
1. 捕捉
2. 抛出
21. 枚举的理解?
1. 枚举类是一种非凡的类,它和一般的类一样,有本人的变量、办法和结构器。它的结构器只能
应用 private 拜访修饰符,所以无奈从内部调用结构器,结构器只能在结构枚举值时被调用
2. 一个 java 源文件中只能有一个 public 类型的枚举类,而且该原文件的名字也必须和该枚举类的
名字统一。也就是在一个文件中只能有一个 public 润饰的枚举类。这里不包含外部类哈,指的是
公共拜访的.java 文件的入口。
3. 枚举类和 class,interface 位置是等同的,枚举也能实现接口。
4. 枚举类的对象是无限且固定的,罕用于状态、类型
5. 枚举类默认集成了 java.lang.Enum 类,并实现了 java.lang.Seriablizable 和 java.lang.Comparable
两个接口
6. 所有的枚举值都默认是 public static final 的,不必反复申明,而且枚举值应该显式的在枚举类第一行列
出,否则无奈产生实例,非形象的枚举类不能再派生子类。
7. 枚举值列举的时候也能够实现该枚举类实现的接口办法。
22.final、finally、finalize 关键字的区别?volatile 关键字的理解?
1.final 能够润饰类、变量、办法,润饰类示意该类不能被继承、润饰办法示意该办法不能被重写、润饰变量示意该变量是一个常量不能被从新赋值。
2.finally 个别作用在 try-catch 代码块中,在解决异样的时候,通常咱们将肯定要执行的代码办法 finally 代码块中,示意不论是否出现异常,该代码块都会执行,个别用来寄存一些敞开资源的代码。
3.finalize 是一个办法,属于 Object 类的一个办法,而 Object 类是所有类的父类,该办法个别由垃圾回收器来调用,当咱们调用 System 的 gc()办法的时候,由垃圾回收器调用 finalize(), 回收垃圾。
volatile 关键字:
一旦一个共享变量(类的成员变量、类的动态成员变量)被 volatile 润饰之后,那么就具备了两层语义:
1. 保障了不同线程对这个变量进行操作时的可见性,即一个线程批改了某个变量的值,这新值对其余线程来说是立刻可见的。
2. 禁止进行指令重排序。
23. 在一个 list 中寄存 string 类型的字符串,如何实现把所有带“王”的字符串从 list 中去除?
1. 遍历汇合 for(String s:list)
2. 判断遍历的对象中是否含有“王”if(s.indexOf(“王”)!=-1)
3. 执行删除 list.remove(s)
24.string a=“123”;string b=“123”;a+=b;生成了几个对象?
3
25. 如何序列化和反序列化?序列化的目标?
序列化是指将 Java 对象转换为字节序列的过程,而反序列化则是将字节序列转换为 Java 对象的过程。
实现序列化:实现 Serializable、Externalizable 接口(没有任何办法,只是作为一种标记)
实现反序列化:即反向进行序列化的过程,须要将一个 InputStream 封装在 ObjectInputStream 对象内,而后调用 readObject()办法,取得一个对象援用(它是指向一个向上转型的 Object),而后进行类型强制转换来失去该对象。
目标:
1. 实现了数据的长久化,通过序列化能够把数据永恒地保留到硬盘上(如:存储在文件里),实现永恒保留对象。
2. 利用序列化实现近程通信,即:可能在网络上传输对象。