首页 > 编程语言 > 详细

java面试题大全

时间:2021-04-17 11:07:29      阅读:23      评论:0      收藏:0      [点我收藏+]

进程和线程的理解

进程是系统资源分配和调度的基本单位,进程切换开销大,线程是cpu分配和调度的基本单位,线程开销小,一个进程可以有多个线程

 

线程间通信方式

synchronized:wait()等待,notify()唤醒,notifyall()唤醒全部

lock:await()等待,signal()唤醒,signalall()唤醒全部

阻塞队列 :put()放入队尾,队满则阻塞,take()取出队头,队空则阻塞

 

 

*衡二叉树和普通二叉树的区别,什么时候会用到*衡二叉树

所有结点的左右子树高度差不超过1,左子树小于父结点,右子树大于父结点,实现快速查找,因为二叉查找树有些情况会变成链表,时间复杂度为O(n),*衡二叉树时间复杂度为O(lgn)

 

红黑树比*衡二叉树好在哪里

红黑树查找效率比较低,但是插入删除效率比较高

 

在什么场景会用到红黑树,为什么它们会用红黑树

TreeMap,TreeSet,可以实现自然排序和定制排序

 

有序关联容器的底层实现

list

arraylist数组,linkedlist链表,stack动态数组

 

无序关联容器

map,set

hashmap哈希表:数组+链表,linkedhashmap哈希表+链表,treemap红黑树

 

二叉查找树

 

左根右,从小到大

时间复杂度O(lgn)

 

b树

 

二叉查找树深度太大,磁盘IO次数过多,为了减少磁盘IO的次数,瘦高变成矮胖

节点中元素从小到大排列,中间空着的划分子节点

 

b+树

相比b树,中间结点只有索引没有数据,更加矮胖

指针指向第一个叶子结点,形成链表,便于查询

 

红黑树

 

特点

1结点颜色为红色或者黑色,叶子结点为黑色,根节点为黑色

2如果一个节点是红色,那么它的子节点必须是黑色

3从一个节点到它的子孙节点必须包含相同数量的黑色节点

 

时间复杂度

O(lgn)

 

用途

解决了二叉查找树的线性问题,接*于*衡二叉查找树

存储有序的数据,如TreeMap,TreeSet

 

内存模型

 

本地方法栈:c++的native方法

程序计数器:程序当前运行的位置

栈:函数当前运行过程中的临时变量(引用类型,即地址,指向堆)

以上三个是线程私有

方法区:静态方法或变量,类加载器

堆:对象

 

 

gc(垃圾回收)

 

 可达性分析

gcroot不能删除的

栈,本地方法栈,方法区:直接或间接引用

直接或间接引用的对象

gcroot可以删除的

没有和gcroot直接或间接相连

 

gc方法

 

标记清理:先标记再清理,内存碎片

标记整理:先标记再清理,清理之后移动到空位,代价太大

复制:内存分为1区和2区,先用1区,把没有标记的复制到2区,清理1区,需要2倍内存

实际gc

young区 1:1:8

survive0

survive1

eden:新创建的对象,快满了之后用复制算法复制到survive区,两个survive区交替使用

old区

年龄>6的对象:每次gc年龄+1,满6次复制到old区

大对象

old区满了之后进行fullgc,java程序暂停,进行标记清理或者标记整理

 

什么是线程

是进程中的单个顺序控制流,是一条执行路径

一个程序只有一条执行路径就是单线程程序,一个程序有多条执行路径就是多线程程序

 

创建线程

继承thread类

实现runnable方法

线程池

newCachedThreadPool() 可缓存

newFixedThreadPool() 可指定大小

newScheduledThreadPool() 可以控制时间和周期

newSingleThreadPool() 单个线程

参数

corePoolSize核心线程池大小:最小线程数量,即使空闲也不会被销毁

maximumPoolSize线程池最大线程数量:任务被提交到线程池以后,首先会找有没有空闲线程,如果没有则缓存到工作队列,工作队列满了则创建新新线程,不能超过线程最大数量,把队头任务交给新线程,把这个任务放到队尾

keepAliveTime空闲线程存活时间:线程空闲,且数量大于corePoolSize,则指定时间后被销毁

unit:keepAliveTime的计量单位

workQueue工作队列:新任务被提交时,如果没有空闲线程,先进入工作队列队尾

 

锁/同步

synchronize关键字

发生异常自动解锁,不会发生死锁,

不能响应中断

竞争不激烈性能好

lock接口

发生异常不会自动解锁,需要手动解锁

可以用interrupt来响应中断

竞争激烈性能好

 

常用排序算法

1.冒泡排序

相邻的两个比较,把最大的放在后面,n趟排序可以把第n大的放在后面。

2.选择排序

选择最大的,和最后一个交换,剩余部分重复这个过程。

3.插入排序

分为已经有序部分和无序部分,从无序部分取一个数,从大到小比较,若有序的数大于取的数,有序的数往后移动,直到有序的数不大于取的数,可以确定位置。

4.快速排序

随机选一个数作为中心轴,左边都比它小,右边都比它大,在每个区间递归进行这个步骤。

 

项目用了哪些框架,每个框架是什么意思,用来干什么

spring:控制反转ioc,面向切面aop

springMVC:model数据承载和业务处理,view视图,controller控制器

mybatis:建立和数据库的映射

shiro:身份验证和权限管理

 

面向对象

面向过程更注重处理问题的步骤和顺序,面向对象更注重处理问题有哪些参与者、各自需要做什么。

面向过程比较直接高效,面向对象更易于复用、扩展和维护。

特性:封装、继承、多态。

封装:明确标识出允许外部使用的成员函数和数据项,内部细节对外部调用透明。

继承:子类共性的属性和方法直接使用父类的,再添加自己独有的。

多态:接口有不同的实现类。

 

JDK、JRE、JVM的区别和联系

JDK:java development kit java开发工具,提供给开发人员使用。

JRE:java runtime environment java运行时环境,提供给运行java程序的用户使用。

JVM:java virtual machine java虚拟机。

JDK包含JRE,JRE包含JVM。

.java文件经过javac编译成.class文件,.class文件可以到处运行,放到windows或者linux版本的jvm上,jvm调用lib里面的类库去解释.class文件,将.class文件翻译成机器码,映射到操作系统,然后调用。

 

重载和重写的区别

重载:发生在同一个类中,方法名相同,参数列表不同。

重写:发生在父子类中,方法名和参数列表相同,方法体不同,如果父类方法修饰符为private那么子类不能重写这个方法。

 

接口和抽象类

抽象类中可以有普通成员方法,接口中的方法必须全部是抽象方法。

抽象类只能继承一个,接口可以实现多个。

抽象类中的成员变量可以是各种类型的,接口中的成员变量只能是public static final类型的

 

权限修饰符

                      同一个类中        同一个包中        不同包的子类           不同包的无关类

private                  yes

默认                     yes                  yes       

protect                 yes                  yes                   yes

public                   yes                  yes                   yes                        yes

 

final

最终的。

修饰类:表示类不可以被继承。

修饰方法:表示方法不可以重写。

修饰变量:表示变量一旦被赋值就不可以修改它的值。

修饰引用类型:地址不可以改变,地址值可以改变。

 

static

被类的所有成员共享

可以使用类名和对象名调用,推荐使用类名调用

static修饰的方法只能调用static修饰的方法,没有被static修饰的方法可以调用任意方法

 

String、StringBuffer、StringBuilder

String是final修饰的,不可变,每次修改会产生新的String对象。

StringBuffer和StringBuilder都是在原来的对象上操作的,底层是数组,可以用append()方法增添新元素,性能StringBuilder>StringBuffer>String。

StringBuffer是线程安全的,StringBuilder是线程不安全的,StringBuffer的方法都是synchronized修饰的。

修改少时使用String,经常需要修改时使用StringBuffer和StringBuilder,多线程共享变量时使用StringBuffer。

 

List和Set的区别

List存储有序、可重复的元素,支持下标访问和迭代器访问。

Set存储无序、不可重复的元素,只能通过迭代器访问。

 

ArrayList和LinkedList

ArrayList基于动态数组,需要存储在连续的内存中,适合下标访问(随机访问),不适合插入、删除,适合查询。

扩容机制:因为数组长度固定,超出数组长度时需要新建数组,然后将老数组的数据拷贝到新数组。

插入:如果不是尾插法,后面的元素全部要向后移动,所以使用尾插法并且规定较大的初始长度可以极大提升性能。

LinkedList基于链表,可以存储在分散的内存中,适合数据插入、删除,不适合查询。

插入:需要创建node对象。

遍历:只能使用迭代器,不能使用for循环,不能使用indexOf返回元素索引。因为会对LinkedList全部遍历一遍。

 

HashMap和HashTable

HashMap是线程不安全的,HashTable是线程安全的,HashTable的方法都是synchronized修饰的。

底层是通过数组+链表实现的。

 

实现一个ioc容器

1.在配置文件中配置包扫描路径。

2.递归包扫描获取.class文件。

3.反射,确定需要交给ioc管理的类。

4.对需要进行注入的类进行依赖注入。

 

jvm体系结构

技术分享图片

 

static

static修饰的方法和类一起加载,

没有static的方法和对象一起加载

 

常见设计模式

单例模式:类只有一个实例,自己实例化自己,提供对外的接口

工厂模式:创建者和调用者分离

mvc模式:model,view,controller

java面试题大全

原文:https://www.cnblogs.com/liuhaoyu999/p/14668836.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!