java面试随笔

java面试随笔总结

set map list

list 有序可重复
  • Arraylist 基于动态数组实现,可随机get和set 查询效率高,线程不安全
  • LinkedList 基于双向链表实现,增加删除不用大量移动元素,省时间,有其他更通用的方法getLast,removeFirst等等,可当做堆栈,队列,双向队列用。
map键值对键唯一,值不唯一。
  • HashMap 使用对象的hashcode()进行快速查询
  • LinkedHashMap 底层使用链表来维护内部次序,速度比HashMap稍慢一点,
  • TreeMap 基于红黑树实现,得到的是排序的结果
set无序不可重复,位置由hashcode决定的位置是固定的。
  • HashSet 底层是HashMap 支持null 使用hash算法存取对象,速度较快
  • TreeSet 实现了SortedSet 接口能对对象排序
  • LinkedHashSet 双向链表维护内部次序,底层使用LinkedHashMap 方法与HashSet相同,有hsahset的查询速度。

HashMap 和HashTable

都实现了Map Cloneable Sevializable接口

  • HashMap实现 AbstractMap接口,可有一个键值为NULL,线程不安全多并发时不安全,需自增同步处理,或者使用ConcurrentHashMap (1.8之后使用CAS算法) 使用了同步锁,使用了fail-fast迭代器,当其他线程改变HashMap抛出ConcurrentModificationException异常,初始化大小为16,每次扩充的容量为原来的2倍,2的次幂大小便于位运算,侧重点在Hash的效率方面,底层用的是数组加链表,jdk1.8之后用的是数组链表红黑树(当链表的碰撞大于8时,或者或者总容量大于64时,结构转化为红黑树,除了添加效率高于其他一切)
  • HashTable 线程安全,每个方法都用了synchronized 1.8之后也使用了fail_fast 初始化大小为11 每次扩充为原来的2n+1倍,侧重点是使Hash的结果更均匀,使得Hash冲突减小,使用的使除法运算所以效率低

多线程

①用户线程 ②守护线程

java线程中有两种线程:①用户线程 ②守护线程用户线程:平时用到的普通线程均是用户线程
守护线程:指在程序运行的时候在后台提供一种通用服务的线程,守护线程是为用户线程服务的,当有用户线程在运行,那么守护线程同样需要工作,当所有的用户线程都结束时,守护线程也就会停止
设置线程的Daemon为true,且必须在thread.start()之前设置Daemon线程中产生的新线程也是Daemon
守护线程不应该去访问固有资源,如进行读写操作(文件,数据库),因为守护线程是跟随用户线程的,当没有用户线程工作时,守护线程会立即结束
不适合用于输入输出或计算操作
适用于辅助用户线程场景,如GC,内存管理

当所有的用户线程结束时,守护线程就结束了,不会继续执行

死锁

死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或造成的一种阻塞的现象

wait()与 sleep()的区别?

sleep()来自 Thread 类,wait()来自 Object 类;

调用 sleep()方法,线程不会释放对象锁。而调用 wait 方法线程会释放对象锁;

sleep()睡眠后不出让系统资源,wait 让其他线程可以占用 CPU;

sleep(milliseconds)需要指定一个睡眠时间到阻塞状态,时间一到会自动唤醒。而 wait()则是处于挂起状态需要配合 notify()

或者 notifyAll()使用唤醒到就绪状态。
wait()方法必须放在同步控制方法和同步代码块中使用,sleep()方法则可以放在任何地方使用。sleep()方法必须捕获异常,而wait()、notify()、notifyAll()不需要捕获异常。在sleep的过程中,有可能被其他对象调用他的interrupt(),产生InterruptedException。由于sleep不会释放锁标志,容易导致死锁问题的发生,因此一般情况下,推荐使用wait()方法。

GC

java 内存分配
  • 静态(方法区):主要存储静态数据,全局变量,程序编译时存在
  • 栈区:方法的局部变量的基本数据类型和引用存储于栈中,引用的对象实体存储于堆中。(属于方法中的变量,生命周期随方法而结束。)
  • 堆区:成员变量全部存储与堆中(包括基本数据类型,引用和引用的对象实体)属于类,动态内存分配,类对象终究是要被new出来使用的这部分进行GC。
java 四种引用类型
  • 强引用:不会让GC回收具有强引用的对象
  • 软引用:内存空间不足时,才会被回收
  • 弱引用:在GC时,一但发现,不管内存是否够都会被回收
  • 虚引用:任何时候可被GC,发现有虚引用时检查与之有关联的队列,判断队列是否有该对象的虚引用,来了解对象是否可被回收。
垃圾回收机制?

什么时候回收:
可达性分析:对象引用抽象为树形,GCRoot为起点,往下搜索,搜索链称引用链,一个对象无法到达GCRoot时则不可用,被判定可回收。
引用计数法:给对象添加引用计数器,每当有地方引用时计数加一,反之失效时技术减一,当计数器为零时表示不被引用则可回收
回收方法

  • 新生代 minorGC (局部变量):复制算法:内存分为两块,每次用其中一块,满之后将存活的对象按严格的顺序复制到另一块,把已使用的进行回收,可得到连续的空间,但是浪费了一半空间。
  • 老年代 MajorGC (生命周期长的对象)标记-清除算法:遍历所有的GCRoot,分别标记可达和不可达的对象,后将不可达的对象进行回收,效率低得到的是不连续的空间。
  • 分代算法 新建的对象存在新生代中,若新生代内存不够进行minorGC,释放掉不活跃的对象,不够则把部分活跃的对象复制到老年代,若换是不够进行MajorGC释放老年代,再不够会抛出OOM内存泄漏。
    Assert 断言,Assertion程序中的一条语句,对一个boolean表达式进行检查,一个正确的程序必须保证这个boolean表达式的值为True,Assertion 用于保证程序最基本关键的正确性。
    开发和测试时开启,软件发布后Assertion检查通常关闭。

String ,StringBuffer,StringBuilder

String 是字符串常量,创建不可改变,可共享,
StringBuffer 是字符串缓冲区,线程安全,内容可被修改,长度可被修改,
StringBuilder 字符串缓冲区,线程不安全,在单线程中使用效率比较高

JVM ClassLoader

Bootstrap CloassLoader 加载基础类 (resources.jar charset.jar rt.jar class)
Extonsion ClassLoader 加载扩展类
App ClassLoader 加载应用classPath中所有类
ClassLoader使用全盘负责委托机制

内存泄漏,溢出

内存泄漏:一个不在被程序使用的对象或者变量一直占据在内存中,GC无法进行回收,【长生命周期对象引用已经不需要的短生命周期对象,导致其无法进行GC】
原因

  • 单例模式
  • 非静态内部类创建静态实例
  • 资源未关闭

可能导致内存溢出,可通过代码完善
内存溢出:申请内存时没有足够的空间共申请者使用,给Int 存Long
原因

  • 代码不规范:
  • 内存抖动,一次申请过多资源

ThreadLocal 与Synchonized区别

ThreadLocal ThreadLocal为解决多线程程序的并发问题提供了一种新的思路.当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。从线程的角度看,目标变量就象是线程的本地变量,这也是类名中“Local”所要表达的意思。在ThreadLocal类中有一个Map(ThreadLocalMap),用于存储每一个线程的变量副本,Map中元素的键为线程对象,而值对应线程的变量副本。
Synchonized同步机制采用了“以时间换空间”的方式,仅提供一份变量,让不同的线程排队访问
ThreadLocal采用了“以空间换时间”的方式。它通过为每个线程提供一个独立的变量副本,因此可以同时访问而互不影响
在很多情况下,ThreadLocal比直接使用synchronized同步机制解决线程安全问题更简单,更方便,且结果程序拥有更高的并发性。
锁机制进行时间换空间,一个是存储拷贝进行空间换时间

Math

Math.round(),Math.ceil(),Math.floor()的区别
1.Math.round():根据“round”的字面意思“附近、周围”,可以猜测该函数是求一个附近的整数,看下面几个例子就明白。小数点后第一位<5正数:Math.round(11.46)=11负数:Math.round(-11.46)=-11 小数点后第一位>5正数:Math.round(11.68)=12负数:Math.round(-11.68)=-12 小数点后第一位=5正数:Math.round(11.5)=12负数:Math.round(-11.5)=-11总结:(小数点后第一位)大于五全部加,等于五正数加,小于五全不加。
2.Math.ceil():根据“ceil”的字面意思“天花板”去理解;例如:Math.ceil(11.46)=Math.ceil(11.68)=Math.ceil(11.5)=12Math.ceil(-11.46)=Math.ceil(-11.68)=Math.ceil(-11.5)=-11
**3.Math.floor():根据“floor”的字面意思“地板”去理解;**例如:Math.floor(11.46)=Math.floor(11.68)=Math.floor(11.5)=11Math.floor(-11.46)=Math.floor(-11.68)=Math.floor(-11.5)=-12

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值