JavaEE常见但容易忽略面试题-----语法篇

最近整理了一下JavaEE中常见而且比较容易忽略的面试题,供大家参考。

Java基础语法

  1. JDK JRE JVM的区别是什么?
    JDK:是专门为程序员所打造的产品,是Oracle提供的一套用于开发java应用程序的开发包。
    JRE:Java的运行环境集合。
    JVM:是Java跨平台的核心所在,用于运行字节码文件,在不同的平台、如Linux、Windows上Java的字节码文件都是相同的。

  2. 数值的范围
    在Java中,有许多的数值类型,很多人并不清楚它们的范围以及所占空间大小。

类型范围
byte-2^7 ~ 2^7-1
short-2^15 ~ 2^15-1
int-2^31 ~ 2^31-1
long-2^63 ~ 2^63-1
float-2^127 ~ 2^1277-1
double-2^1024 ~ 2^1024-1
  1. Float精度问题
    有这样一道题
float a = 12345678f;
float b = 12345678f + 1;
if(a==b){
system.out.println("yes");
}else{
system.out.println("no");
}

很多人可能都会选 no,但是正确答案却是yes,因为float在JVM中是以科学技术法的形式存在,并且只能保留到前7位,所以加一之后是没有任何变化的。

  1. 随机数的使用
    假定求出1000~3000的随机数,这时我们有两种方法。
    一、使用Romdom对象
int min = 1000;
int max = 3000;
int i = new Random.nextInt(max - min) + min;
//此时,i就是随机数,在1000到3000之间

二、使用Math对象的random方法

int min = 1000;
int max = 3000;
int i = (int)(Math.random() * (max-min)) + min;
//Math的random方法会生成一个在0~1之间的随机小数
  1. 求1~1000的质数
    一道很经典的算法题,考验双重循环
boolean flag = true;
for(int i = 2;i <= 1000; i++)
	flag = true;//假定当前外层所判断的数是质数
	for(int j = 2;j < i;j++){
		if(i%j==0){
			//发现不是质数,跳出内侧循环
			flag=false;
			break;
		}
	if(flag){
		System.out.println(i+"是质数");
	}
}
  1. 面向对象三大特征
    继承:继承是指子类从父类中继承所有的方法和变量,并且可以扩展其他方法,Java只支持单继承。
    封装:封装是指将具有相同行为的一类事务封装在一起,只留下对外调用的接口,外部无法得知内部具体怎样实现,只关注作用,最明显的应用就是Interface接口。
    多态:多态作为三大特性中最重要的特性,它实现让一个方法实现多种功能,当同名的方法有了不同的参数,就可以在其中编写针对不同参数的不同功能。
  2. 静态变量(方法)与实例变量(方法)的区别
    一、语法不同
    创建静态变量时都要加上static关键字修饰。
    二、归属不同
    静态变量属于类,可以直接调用;实例变量属于对象,对象实例化之后才可以使用
    三、创建时间、存储位置不同、垃圾回收机制不同
    静态变量在JVM加载类时自动创建,存储在JVM的方法区上,不会被自动垃圾回收
    实例变量在new的时候创建,存储在对象堆上,在不用的时候会被自动垃圾回收掉。
  3. 类的执行顺序
    一、静态先行
    二、父类随后
    三、非静态块其次
    四、构造方法最后
    如果某个子类继承自某个父类,父类中有静态方法、非静态块、构造方法,同样子类中也有相同的三个方法。
    在实例化子类后,它们的执行顺序是这样的
    父类静态>子类静态>父类非静态块>父类构造>子类非静态块>子类构造
  4. Java的异常体系
    在Java中,异常的所有父类是Throwable
    旗下有两个分支,为Error和Exception
    Error:系统出错,系统资源出错,人为不可干预,出错时只能重启系统,不可控制。
    Exception:一般由于代码出错导致异常,如除0异常等,一般可以控制 ,其中的RuntimeException可以在抛出的时候不必显式的写出try catch语句,并且在spring事务管理的时候抛出可回滚事务。
  5. String与字符串常量池
    我们都知道,String字符串在创建时默认是静态的,并且由final修饰,故此它存放在JVM的方法区上,所以在使用相同内容的字符串时,它们的地址都是相同的,如下例题
String a = "abc";
String b = "def";
String c = "abcdef";
String d = "abc" + "def"
String e = a + "def";
String s = new String("abc");
if(c==d){
	System.out.println("c==d");
}else{
	System.out.println("c!=d");
}
if(c==e){
	System.out.println("c==e");
}else{
	System.out.println("c!=e");
}
//输出结果为c==d c!=e,因为a是引用类型,在运行时才会知道a的地址,而且在此时JVM就会为e创建新的空间,和c就不是一个地址了
//同样a和s也是地址不同的,创建方式不同,地址也不同

注:String的 == 和equals作用并不相同,equals比较的是字符串的内容,而==是比较字符串的地址。

  1. String、StringBuffer、StringBuilder的区别
StringStringBufferStringBuilder
执行速度最慢中间最快
线程安全安全安全不安全
使用场景多线程下少量字符串操作多线程下大量的字符串操作单线程下的大量字符串操作

总之:在要保证安全以及快速处理字符串的前提下,最好优先使用StringBuffer

  1. Object类的HashCode()和equals()方法的区别
    一、hashCode()返回的是一个hash值,这个值是通过hash方法计算内存地址,hash值相同,表明是一个对象,不同则不一定不是同一个对象,有小概率hash值相同却不是同一个对象。
    二、equals()
    该方法通过计算对象中的属性以及方法,最终的得出一个值,该值相同,两个对象一定相同,该值不同,两个对象一定不相等。
    三、为什么不直接使用equals()?
    equals相比较hashCode()来说,运行速度太慢,一般都是两者结合使用,外层hashCode(),内层equals()。
  2. Java中IO有几种类型的流
输入流输出流
字节流InputStreamOutputStream
FileInputStreamFileOutputStream
BufferedInputStreamBufferedOutputStream
字符流ReaderWriter
FileReaderFileWriter
BufferedReaderBufferedWriter
InputStreamReaderOutputStreamWriter

注:字节流用于处理图片、视频、压缩包等二进制文件,字符流处理文章等。

  1. 使用IO进行文件复制
    以下例题使用字节流
File source = new File("d:\file.txt");
File addr = new File("d:\file\addr\file.txt");
try{
	FileInputStream input = new FileInputStream(source);
	FileOutputStream output = new FileOutputStream(addr);
	byte[] b = new byte[1024];
	int a = 0;
	while( (a = input.read(byte)) != -1){
		output.write(b,0,a);
	}
}catch(Exception e){
	
}finally{
	input.close();
	output.close();
}
  1. List、Set的区别
    List:有序且允许重复、可以有许多NULL值,主要实现类有ArrayList(内存中连续,基于数组)、LinkedList(基于链表).
    Set:无序且不允许重复、整个Set中最多允许有一个NULL值,主要实现类有HashSet、TreeSet等。
    注:HashSet无序的原因是因为插入新的元素时,HashSet会按照一定的规则为这个元素计算出hash值,之后按照hash值排序,所以插入顺序与在Set中的顺序不一定相同。

  2. List排序
    使用静态类Collections的sort()方法进行排序
    以下是对一个自定义的类进行排序。

public class Grade {
    private Integer gradeId;
    private String gradeName;
    private Date gradeCreateTime;

    public Integer getGradeId() {
        return gradeId;
    }

    public void setGradeId(Integer gradeId) {
        this.gradeId = gradeId;
    }

    public String getGradeName() {
        return gradeName;
    }

    public void setGradeName(String gradeName) {
        this.gradeName = gradeName;
    }

    public Date getGradeCreateTime() {
        return gradeCreateTime;
    }

    public void setGradeCreateTime(Date gradeCreateTime) {
        this.gradeCreateTime = gradeCreateTime;
    }

    @Override
    public String toString() {
        return "Grade{" +
                "gradeId=" + gradeId +
                ", gradeName='" + gradeName + '\'' +
                ", gradeCreateTime=" + gradeCreateTime +
                '}';
    }
}

public static void main(String[] args) {
        List<Grade> list = new ArrayList<>();
        Collections.sort(list, new Comparator<Grade>() {
            @Override
            public int compare(Grade o1, Grade o2) {
                return o1.getGradeId() - o2.getGradeId();
            }
        });
    }
  1. 创建线程有几种方式?
    一、继承Thread类,实现run()方法
    二、实现Rannable()接口,实现run()方法
  2. 当前有几个线程正在执行?
    当我们被问到当前有几个线程正在执行的时候,切记
    一、mian方法是一个独立的线程,是所有线程的父线程
    二、每创建一个线程就是一个独立的线程
    三、除了上面的线程,还有一个负责垃圾回收的线程,在mian线程创建时自动创建。
  3. 线程有哪些状态?
    如果学过计算机操作系统的话,这道题时很简单的。
    线程有五大状态,分别是创建、就绪、运行、阻塞、死亡
    其中就绪、运行、阻塞之间可以转换
    就绪---->运行 需要等到自己的时间片来临
    运行---->阻塞 一般是由于I/O(被动)、sleep() lock()(主动)的一些情况导致。
    一个正在运行的线程突然阻塞,阻塞完成后并非直接到运行状态,而是到就绪状态等待运行。
  4. 实现线程同步的方式有哪些?
    一、加锁,在方法、代码块加上synchronized关键字,表明这段代码/方法在多线程环境下只能被一个线程使用,其他只能等待该线程释放该锁时才可以使用。
    二、使用wait()、notify()方法对线程进行手动的阻塞与唤醒
    三、实现Lock接口,Lock接口是JDK1.5之后推出的更加智能的加锁方式,相比synchronized加锁,Lock在面对线程竞争激烈的时候表现的更稳定。
  5. 死锁的产生与原因
    在计算机操作系统当中,死锁是由于每个进程都在等待着对方释放自己所需要的资源,而自己却保持着对方所需的资源,线程也是如此。
  6. 垃圾回收机制与JVM的组成
    JVM作为Java重要的一块,一直是面试必问的问题,JVM共由五部分组成。
共享区私有区
方法区 Method Area程序计数器Pc
堆 Heap虚拟机栈 VM Stack
本地方法栈 Native Method Stack

其中,最重要的是堆(Heap),在这里存放着被实例化的对象,也是JVM进行垃圾回收的主要场所,是占用内存最大的区域,其次,方法区存放着所有的静态方法以及静态变量,这里一般不进行垃圾回收,除非静态变量是一个引用类型,此时可能会被回收。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值