Java面试题

1.1 Java语言基础

1.1Java语言基础
Connection对象通过connection.setAutoCommit(false)设置为事务手动提交。1.1.1 Java开发环境(重要指数:
(1)请简述JVM、JRE、JDK三者之间的关系。
答:JVM是指Java虚拟机,编译器负责将Java源文件(.java)编译成字节码文件(.class),JVM加载字节码文件并运行。不同的平台使用不同的JVM,这就是Java能够跨平台的根本原因。
JRE是指java运行环境,包含了JVM和运行java程序所必须的环境。JRE=JVM+java系统类库。
JDK是Java开发工具包,JDK=JRE+编译、运行等工具。作为一个Java程序员 必须安装JDK才能正常开发。
总之,Java程序运行的最小环境为JRE,Java程序开发的最小环境为JDK。
(2)请简述Java编译运行过程。
答: Java源文件,经过编译,生成.class字节码文件,JVM加载.class并运行.class。跨平台,一次编程到处使用。
(3)安装一个JDK环境,需要完成哪些环境变量?
答: JAVA_HOME:指向jdk的安装路径
CLASSPATH:表示类的搜索路径,一般简写为.
PATH:指向jdk下的bin目录
(4)请说说你了解或使用过的IDE工具。
答:Eclipse开源而且免费,使用范围较广;
Myeclipse收费,但可以使用破解版,跟eclipse功能非常相似,有一定的市场占有率;IntelliJ IDEA,简称idea,很多公司也会使用这个作为开发工具。
1.1.2 Java语法基础(重要指数:
**)
(1)请简述Java变量的命名规则。
答:只能由字母数字_ $ 符组成
首字符不能以数字开头;区分大小写
不能使用java保留字(关键字),如 int if for break
不提倡使用中文
最好见名知意 直观专业
建议驼峰命名:myJavaScore score myScore第二个单词首字母大写.
(2)请简述Java中八种基本的数据类型。
答:int 4个字节 32位。Java代码中直接出现的整数默认为int类型,取值范围为-2147483648 到2147483647.使用时注意不要溢出。int变量整数相除,自动去除小数位 int a=5/3=1。
long, 8个字节。long time =System.currentTimeMillis();返回自1970年1月1日到此时此刻的毫秒数.
double ,浮点型 ,8字节,精度值是float类型的两倍.Java中小数直接默认为double类型.如果想表示float类型,则写成3.14F.二进制中无法精确表示1/10, 只会无限接近于0.1。如果是精确场合,需要使用BigDecimal来避免误差。
boolean 类型,只允许取值true或false; 1个字节.
char类型 ,2个字节 ,16位。Java采用unicode编码一个字符占2个字节。取值范围0-65535.
byte类型,1个字节,取值单位是-128到127;
short类型,2个字节;
float类型,4个字节,单精度小数。
(3)Java中一个char可以存放一个中文汉字吗?
答:可以。Java采用unicode编码方式,一个字符两个字节,char是2个字节,所以可以存放。
(4)Java中有哪些算数运算符?(不用背诵,会使用即可)
答:除了数学中的加减乘除 + - * /之外,还有%(取余),++ – 自增,还可以拓展出+= -+ *= /=这些运算符。

(5)Java中有哪些关系运算符?(不用背诵,会使用即可)
答:> < >=大于或者等于 ==等于 !=不等于
(6)Java中有哪些逻辑运算符?(不用背诵,会使用即可)
答:&& 并且 (逻辑与)
|| 或者(逻辑或)
! 逻辑非(取反)
(7)Java中有哪些位运算符(需要掌握)
答:位操作是程序设计中对位模式按位或二进制数的一元和二元操作。在许多古老的微处理器上, 位运算比加减运算略快。运算符包括:
& 按位与:运算规则是都1才1;
| 按位或:运算规则是都0才0;
^ 按位异或:参与运算的两数各对应的二进位相异或,当两对应的二进位相异时,结果为1。
~取反: 对参与运算的数的各二进位按位求反.
<<左移

右移
(8)Java中的条件分支结构和循环有哪些?
答:条件分支有:if(), if()… else if(),switch()…case; 循环有:for循环,while循环,do{ }while()循环。
(9)break和return ,continue有什么区别?如何跳出多层循环?
答:break是跳出一层循环,retrun是结束一个方法,continue是 当前的循环,进入下一次循环。如果想要跳出多层循环,需要设置断点。代码演示如下:
a: //设置断点a
for(int i=0;i<999;i++){
for(int i=0;i<999;i++){
break a; //跳出循环到断点a
}
}
(10)请简述数组的特点。
答:数组是最基本的一种数据结构,是相同数据类型的元素组成的集合.
数组是一种数据类型(是引用类型),一旦被声明,大小就不能改变。
数组中int long默认值为0,char默认值为’0’,boolean默认值为false。
数组的定义:int[] arr=new int[4];或者:int[] arr={1,4,7};
数组通过下标(下标从0开始)访问数组的元素,数组名.length可以用来获取数组的长度; 代码演示如下:
int[] arr=new [3];
System.out.println(arr.length);
数组的复制:System.arrycopy(a,1,a1,0,4); Arrays.copyof()。
使用reverse()方法对数组数据进行倒序排列。向数组的最后一个位置加一个新元素,使用push方法。

数组和集合的区别:
1.数组声明了他所容纳的元素的类型,而集合不声明。
2.数组是静态的,一个数组实例具有固定的大小,一旦创建了即无法改变容量。而集合可以动态扩展容量,可以根据需要动态修改大小,集合提供更多的成员方法。
3.数组的存放的类型只能是一种(基本类型/引用类型),集合存放的类型可以不是一种(不加泛型时添加的类型是Object)
4.数组是java中的内置数据类型,是线性排列的,执行效率或者类型检查都是最快的。
(11)请说说你比较熟悉的排序算法。(要求能默写冒泡排序)
答:冒泡排序,快速排序,插入排序。

1.2 面向对象(重要指数:*****)

1.2 面向对象(重要指数:*****)
(1)请简述类和对象的关系。(可以有自己的理解)
答:类相当于是模板,对象是通过模板刻画出来的带有独立特性的实际对象。
(2)面向对象三大特征。
答:封装、继承、多态。
封装的体现:将相同的属性或事物提炼封装成为一个类;将一组能够完成特定功能的代码封装成方法;将类的属性使用访问权限(public,protected,默认的,private)进行修饰,完成数据私有化,方法公开化的封装;
继承:子类继承父类,就无需重复父类的代码。
多态的体现:a.对象的多态。一个类class可以new无数个对象;向上造型也是多态的体现;b.方法的多态。重写和重载就是多态的体现。
实现多态的机制:java实现多态的机制是依靠父类或者接口的引用指向子类。从而实现了一个对象多种形态的特性。其中父类的引用是在程序运行时动态指向具体的实例,调用该方法时不是根据引用变量的类型中定义的方法来运行,而是根据具体的实例的方法。
(3)请简述重写和重载的区别?
答:在同一个类中,方法名相同,但参数不同,即为方法的重载(overload);参数的不同包括,参数的个数、类型、顺序,只要有一个不同就是参数不同,就符合重写的规则。
重写(override)发生在父子类中,方法名相同,参数相同,但方法体不同。需要符合“两同两小一大”的原则。
两同:方法名相同,参数相同。
两小:抛出的异常和返回值类型子类要比父类小,或者一样。如果返回值是基本数据类型,就要求必须一样。
一大:子类的访问权限要比父类的小,或者一样
(4)JVM在运行时,内存如何分区?
答:分为堆(新生代(伊甸园和存活区-----8:1:1)和老年代(内存空间大))、栈、方法区、常量池、寄存器、本地方法栈。
堆:存储new出来的对象(包括成员变量,对象被回收时一并消失);是线程共享区域;
栈:存储正在调用的方法中的局部变量和引用地址;调用方法时,在栈中为该方法创建对应的栈帧;方法调用结束时,栈帧被清除,局部变量一并消失;是线程私有区域。
方法区:用于存储.class文件,包含类的信息,方法等;方法只有一份,通过this来区分是哪个对象调用的方法。
其他内存分区的作用,了解即可。
(5)简述GC的作用和特点。
答:GC是Java中用来回收内存的一种机制。本质上是一个守护线程。在Java中,没有任何引用指向的对象即为垃圾。通过调用system.gc()可以建议快一些回收。因此,建议不再使用的对象及时将引用设为null。否则可能产生内存泄漏,严重时会导致系统崩溃;
GC的原理:引用计数,标记复制。"引用计数"是一种简单但速度很慢的垃圾回收技术.所有对象都有一个引用计数器,当有引用连接时计数器加1,当引用离开作用域时或者被置于NULL时,计数器-1,垃圾回收器会在所以包含对象引用的列表上进行遍历,当发现某个对象的引用计数为0时,就释放占用的空间.
"标记复制"的运行机制,垃圾回收器遍历包含所有引用的列表,当发现存活的对象引用时做上标记,这样当遍历完所有对象引用并做上标记的时候,执行垃圾回收,将没有标记的对象从堆空间释放.
(6)请简述成员变量和局部变量的区别?
答:成员变量:在类中,方法外;创建对象中存在堆中,对象被回收时消失;有默认值;
局部变量:在方法中.(包含方法的参数变量);调用方法时存在栈中,调用完毕后消失;无默认值,必须显示初始化;
(7)请简述静态变量和实例变量的区别?
答:静态变量属于类,只有一份,通过类名调用;实例变量属于对象,有几个对象就有几份成员变量。
(8)final关键字的作用是什么?
答:可以修饰变量:修饰后不能被改变(可修饰成员变量;可修饰局部变量)
修饰方法:方法不能被重写.
修饰类:不能被继承,但可以继承别人.
(9)构造方法、构造块、静态块的执行顺序时?
答:静态块>构造块>构造方法。
(10)类和接口的区别?
答:类是单一继承的;接口是多继承多实现;类有构造方法(抽象类除外),可以实例化,接口不能;接口中只能由抽象方法。
(11)接口和抽象类的区别?
答:接口中所有的东西都是public的,接口中只可以有抽象方法;抽象类可以有普通方法,可以有非公开的成员变量。抽象类是类的抽象,接口是抽象类的抽象。
(12)匿名内部类的语法。(不要背诵,能够熟练使用即可)
非静态内部类:class A{class Inner{}}Inner对象必须依赖于外部类对象存在;不能独立创建对象;非静态内部类中不能定义静态成员 A a1 = new A();Inner i = a1.new Inner();
静态内部类:class A{static class Inner{}} 静态内部类,可以独立创建对象。
Inner inner = new Inner();
局部内部类:class A{Weapon f(){class Inner implements Weapon{}Inner i = new Inner(); return i;}}定义在局部代码块中的类型,只能在局部使用。 A a = new A();Weapon w = a.f();
匿名内部类:Weapon w = new Weapon(){} 大括号:匿名类 new:新建匿名类对象 Weapon:父类型
答:对象创建后,这个类的价值就不存在了,那么这个类可以不必命名,称为匿名内部类.代码演示如下:
Aoo abc=new Aoo(){
…………方法体……….
};
(13)Debug调试的快捷键有哪些?(不需要背诵,需要熟练使用)
答:F5:单步调试,进入到方法中
F6:逐过程调试,不进入方法中
F7 结束调试
F8 跳到下一个断点调试,没有断点则结束调试

1.3 常用API使用(重要指数:*****)
(1)请简述Java中常用的包及其作用。
答:java.lang 字符串,多线程,不需要import,可以直接使用 最常用的类
java.util 工具类,如集合 随机数产生器,日历 时钟等
java.io 文件操作,输入输出操作 input 和output的简写
java.net 网络操作
java.math 数学运算相关操作
java.sql 数据库访问
(2)Object类中有哪些常用的方法?
答:eqauls(); wait();hashcode()方法。
(3)日期操作的类有哪些?
答:Date、Calendar(便于进行日期操作,弥补Date的不足)、SimpleDateFormat(用于格式化输出日期)。
(4)String类常用的方法?
答:Java .lang.String使用了final修饰,不能被继承.字符串对象一旦创建,永远无法被改变,采用Unicode编码,一个字符两个字节。String有常量池。
str.length() 获取字符串长度
str.indexOf(“java”) 查找指定字符串首字母的下标
str.substring(4,10);//截取字符串 含头不含尾
str.trim() 去除字符串前后的空格
str.charAt(10); 获取当前字符串中指定位置上的字符 可以用来检查回文
str.toUpperCase();转换大小写
str.toLowerCase()
(5)StringBuilder和StringBuffer的区别?
答: StringBuffer和StringBuilder不同于String,均是字符串变量。StringBulider是为了修改字符串的内容而出现的类该类定义了用于编辑字符串的相关方法:增 删 改 插。StringBuffer是线程安全的,同步处理,性能稍慢.方法同StringBuilder一模一样。
StringBuffer中的方法大多采用synchronized修饰,因此线程是安全的。但是由于每次都需要判断锁,所以效率较与StringBuilder慢。StringBuilder不需要加锁,不存在多线程安全,所以效率较快。
(6)Java中常用的集合有哪些?(可以自己拓展,越深越广面试越占优势)
答:Java中常用的集合基本都来自Collection和Map两个顶级接口,其中Collection包含两个子接口:
List 有序 可重复 --LinkedList:首尾增删快,遍历慢,是双向链表结构
– ArrayList:通过数组实现,增删慢,访问快。
ArrayList:底层使用数组结构,特点:查询速度快,增删操作较慢,而且线程不同步。如果保证同步,可以使用List list = Collections.synchronizedList(new ArrayList())进行包装,默认容量为10.
LinkedList:底层双向链表结构实现存储,允许所有元素(包括null)。非线程安全,要保证同步,可以使用List list = Collections.synchronizedList(new LinkedList());进行包装,可以被当作堆和栈和队列来使用。
Vector:也是一个有序集合,允许重复元素,并且线程安全。
ArrayList常用方法:add,addAll,remove,indexOf,subList,contains,isEmpty
Set 不可重复 HashSet();
而Map比较常用的实现类是HashMap:采用Key –Value的方式存储数据。键是唯一的,允许使用null值和非null值,非同步(除了非同步和允许使用null值之外,HashMap和HashTable大致相同),同步使用Map map = Collections.synchronizedMap(new HashMap(…)),通过Hascode值来确认存储的位置,通过equals方法来判断key值是否重复,如果hashcode值相同,但equals比较为false就会产生链表,链表个数达到8就会转换成红黑树结构,红黑树是一种应用很广的二叉查找树。当红黑树结构减少到6,转回链表结构。
红黑树结构:红黑树是每个节点都带有颜色属性的二叉查找树,1.每个红色节点的子节点为黑色(叶子到根的路径上不能有两个连续的红节点),2.所有节点分为红色和黑色,3.根节点为黑色,4.任一节点到其叶子的路径上的黑色节点数量相同。
常用方法:1.添加:put(key,value),当存储的键相同时,新的值会替换老的值,并将老的值返回。如果键没有重复,返回null。Void putAll(Map);
2.删除: void clear(),清空value remove(key),删除指定键。
3.判断:boolean isEmpty(),boolean containsKey(key),是否包含key boolean containsValue(value),是否包含value。
4.取出:int size(),返回长度 value get(key):通过指定键获取相应的值,如果返回null,可以判断该键不存在。Collections values(),获取map集合中的所有值。
HashMap的哈希运算过程
·内部使用Entry[]数组存放数据 ·数组默认初始长度为16 ·调用key.hashCode()方法获得一个哈希值 ·用哈希值和数组长度,计算下标i ·键值对封装成Entry对象
hashCode():Object的方法,使用内存地址作为哈希值
HashTable:底层是哈希表数据结构,不可以存入null键和null值,是线程同步的。HashTable的实例有两个参数影响其性能,初始容量和加载因子(默认为75).

Iterator接口:
·迭代器父接口 ·迭代遍历期间,不允许直接使用集合增删数据。
·方法:next();hasNext();remove()移除刚取出的数据
(7)请简述Exception和Error的区别。
答:Exception和Error都继承自Throwable类。Exception是程序出现的异常,是程序员可以处理,而且应该处理的。Error是系统级错误,是不可恢复的。
(8)请描述下Java中的异常的体系。
答:Throwable 可抛出的
–Error 错误,系统不可恢复错误
堆内存溢出错误. 引用不释放,将会造成内存泄漏问题.
–Exception例外,异常
可检查异常:也叫做编译异常IOEexception
非检查异常:RuntimeException

异常处理的两种方式:catch和throws
·底层异常,应该向前抛到前面处理 ·不知道在何处捕获异常时,应该是选择throws。
throw:手动抛出异常,执行异常的抛出动作;类比成return
If(逻辑错误){AException e = new AException(“提示消息”); throw e;}
(9)请简述final finally finalize的区别?
答:final修饰类不可被继承,修饰方法不可重写,修饰变量不可改变值;
finally是异常处理机制的代码块,无论发生异常与否都会执行的。
finalize方法来自于object类,是对象被回收之前自动会被JVM自动调用的一个方法,通常用来做最后的清理工作。
(10)创建线程的方法有哪些?
答:a.可以通过继承Thread类,并重写run方法 来定义一个具体的线程.重写的run方法;
b.实现Runnable接口并重写run方法;
c.还可以通过实现Callable接口,重写call方法来创建线程。实现Future接口创建线程。代码如下:使用FutureTask封装通过实现Callable接口的对象。
class ThreadDemo implements Callable {
@Override
public Integer call() throws Exception {
return 0;
}
}
(11)线程的生命周期是怎样的?
答: new 新建状态 , runnable就绪,running运行状态,阻塞状态,dead:结束状态.单向的运行状态,进入到结束状态后无法重新start,只能变成垃圾对象,被回收.
(12)启动一个线程使用什么方法?
答: start()。
线程中start()和run()方法的区别:
线程的处理逻辑可以在Thread类的run方法中直接实现或者通过该方法进行调用,因此run()相当于线程的任务处理逻辑的入口方法,由java虚拟机在运行相应线程时直接调用,而不是由应用代码进行调用。
而start()的作用是启动相应的线程。启动一个线程实际是请求Java虚拟机运行相应的线程,至于何时该线程能够运行取决于线程调度器何时进行调度。Start()调用结束并不表示相应线程已经开始运行,该线程可能稍后运行,也可能永不运行。
(13)线程阻塞有哪些种类?让线程进入阻塞状态的场景有哪些?
Sleep()和wait()方法的区别:
Sleep()实现线程阻塞的方法,我们称之为“线程睡眠”,方式是超市等待。Sleep()通过传入睡眠时间作为方法的参数。
Wait()方法实现线程阻塞的方法,我们称之为“线程等待”,方式一:和sleep()一样,通过传入“睡眠时间”作为参数,时间到了就醒了;方式二:不传入时间,进行一次“无限期的等待”,只能通过notify()方法来唤醒。
Wait()必须在同步方法内使用,否则会抛出IllegalMonitorException,而sleep()则可以在任意地方使用。
答:阻塞的种类包括以下三类:
a.等待阻塞:wait()进·入的阻塞状态,释放锁资源
b.同步阻塞:因为加入了同步代码块,等待获取锁对象的过程叫做同步阻塞。
c.其他阻塞:除以上两种意外的阻塞都是其他阻塞。
 以下情况会出现线程阻塞状态:
        A、线程调用sleep方法,主动放弃占用的处理器资源
        B、线程调用了阻塞式IO方法,在该方法返回前,该线程被阻塞
        C、线程试图获得一个同步监视器,但该同步监视器正被其他线程所持有。
        D、线程等待某个通知(notify)
        E、程序调用了suspend方法将该线程挂起。不过这个方法容易导致死锁,尽量不免使用该方法
(14)什么是死锁,如何避免死锁?
答:多个线程互相争夺同一个资源(锁对象),互不让步的的现象叫做死锁。发生死锁一般需要四个条件:
1)互斥条件:例如加了同步锁Sychronized;
2)请求和保持条件:指进程已经保持至少一个资源,但又提出了新的资源请求,而该资源已被其它进程占有,此时请求进程阻塞,但又对自己已获得的其它资源保持不放。
3)不剥夺条件:指进程已获得的资源,在未使用完之前,不能被剥夺,只能在使用完时由自己释放。
4)环路等待条件
避免死锁的方式:
1)加锁顺序(线程按照一定的顺序加锁)
2)加锁时限(线程尝试获取锁的时候加上一定的时限,超过时限则放弃对该锁的请求,并释放自己占有的锁)
3)死锁检测。
(15)线程池的作用?
答:控制线程的数量,减少系统的资源消耗;便于线程的复用,节约资源。
(16)如何创建线程安全的HashMap?
答:三种方式(具体原理请查看源代码或者百度):
使用Hashtable
使用java.conConcurrentHashMap
使用SynchronizedMap
(16)Java解析XML文件的方式有哪些?(了解,能看懂以下代码即可)
答:DOM4j,SaxReader;代码演示如下:
SAXReader reader=new SAXReader();
Document doc=reader.read(new File(“emplist.xml”));
Element root=doc.getRootElement();
List list=root.elements();//获取当前元素下全部元素
for(Element empEle:list){
Element nameEle=empEle.element(“name”);//获取name元素
String name=nameEle.getTextTrim();//调用文本信息
System.out.println(“name:”+name);
(17)请简述volatile关键字的作用。
答:主要起到了保证内存可见性作用。当计算机有多个cpu时,多个线程对非volatile变量进行读写的时候,该变量的值可能会被拷贝到不同的CPU cache中,可能会发生程序运行结果与理想不符的情况。使用volatile关键字,能够保证每一次读写变量值时,都跳过cpu缓存,直接操作主内存。
原理如下图:

(18)文件流Stream
·字节数据的读写,抽象成数据在管道中流动
·输入流,用来读取数据 ·输出流,用来输出数据
数据只能从头到尾顺序流动一次。
InputStream/OutputStream
·字节流的抽象父类
FileInputStream/FileOutputStream
·字节流子类 ·文件流,直接插在文件上,直接读写文件数据
ObjectInputStream/ObjectOutputStream
·对象的序列化,反序列化
·把对象的信息按照固定的字节格式,转成一串字节序列,输出
·被序列化的对象,必须实现Serializable接口(标识接口,标识一个类,可以被序列化)
·不可被序列化的成员
·static修饰的静态类不随对象一起被序列化输出
·transient临时:只在程序运行期间,在内存中临时存在,不随对象一起被序列化持久保存
Reader/Writer
·字符流的抽象父类
·InputStreamReader/OutputStreamWriter
·字符编码转换流
·InputStreamReader读取其他编码为unicode
·OutputStreamWriter把unicode转为其他编码输出
·BufferReader可以一行一行的读取文本数据 ·readLine()——读取一行数据,读取结束,再读取,得到null
对象序列化:通过对象序列化可以将传输的对象状态转换为字节数组,因为当JVM停止工作时会使对象的状态丢失,所以序列化能使对象持久化避免对象状态丢失。
(19)Java中的反射
在java程序运行时,对于任意一个类,都能够获取这个类的所有属性和方法,对于任意一个对象,能够调用它的任意一个方法和属性。这种动态获取的信息以及动态调用对象的方法的功能称为java的反射机制。

11.说出 5 个 JDK 1.8 引入的新特性?
Java 8 在 Java 历史上是一个开创新的版本,下面 JDK 8 中 5 个主要的特性:
A.Lambda 表达式:允许像对象一样传递匿名函数 Stream API;
B.充分利用现代多核 CPU:可以写出很简洁的代码 ;
C.Date 与 Time API:最终,有一个稳定、简单的日期和时间库可供你使用
D.扩展方法:现在,接口中可以有静态、默认方法;
E.重复注解:现在你可以将相同的注解在同一类型上使用多次。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值