javaSE基础知识整理(面试问题)

1.基本数据类型(8种)

1.整数类型:byte、short、int、long(默认类型是int、其余需要强转)

2.浮点数类型:float、double(默认类型是double,如果是float类型后面需要写F)

3.字符类型:char(默认值为空,字符类型用单引号表示字符)

4.布尔类型:boolean(默认值false true、false这两个不是关键字)

2.简述什么是 JDK、JRE 和 JVM

   JDK : 开发工具包

   JRE : 运行时环境

   JVM : java虚拟机

3.& 和 && 的区别 

   &:符号的左右两边,无论真或假都要执行

   &&:符号的左边如果为假,符号的右边不再执行,提高了代码的执行效率

4.switch的参数可以是什么类型

int及以下整数包含 字符 char  byte short int char  String  枚举   

5.修饰符作用域

访问修饰符

当前类

同一包下其他类

其它包内子类

其它包内非子类

private

可以访问

default(默认的修饰符)

可以访问

可以访问

protected

可以访问

可以访问

可以访问

public

可以访问

可以访问

可以访问

可以访问

6.对面向对象的理解

面向对象即OOP是一种编程思想,对象在我们生活中处处都存在,比如说一只小狗就是一个对象,在面向对象编程中,对象是有很多特征的,比如说品种、颜色、体型等等都是对象的属性,对象还会有一些能力,比如跑、跳、打滚,这就可以理解成对象所封装的方法,简单来说就是将功能封装到对象里,我们面向对象,让对象去完成这些功能,在java中万物皆对象

7.面向对象的三大特征

封装:将不同的功能抽取出来方便调用,减少大量代码的冗余

继承:减少了类的冗余代码,让子父类之间产生关系,为多态打下基础

多态:一个接口,多个方法。通过继承实现不同的对象调用相同的方法,进而有不同的行为

8.抽象类接口的区别

接口

抽象类

不能定义构造器

可以定义构造器

接口中所有成员都是public static final

可以有抽象方法和具体方法

成员变量都是常量

抽象类中的成员可以是任何类型

接口可以多继承

类只能单继承

注意点

抽象类如果是内部类可以使用static ,外部类不行

抽象类不能使用final修饰,因为使用后就不能被继承了,就失去了抽象类存在的意义了

注:抽象类中不一定有抽象方法,有抽象方法这个类一定是一个抽象类

9.说出成员变量和局部变量的区别

1、物理位置

成员变量: 类中方法外

局部变量: 方法中或方法定义的小括号里面

2、内存位置

成员变量: 在堆内存中

局部变量: 在栈内存中

3、生命周期

成员变量: 随着对象创建而产生,随着对象的消失而消失

局部变量: 随着方法的调用而产生,随着方法调用结束而消失

4、有无默认值

成员变量: 有默认值, 整数0,小数0.0 字符 ‘\u0000’ 布尔 false 引用数据类型 null

局部变量: 没有默认值,使用的时候,必须先赋值

10.static关键字都能修饰什么? 都有什么特点

1、修饰成员变量:叫静态变量 具有共享性,节省内存空间

2、修饰方法:静态方法: 可以直接使用类名.进行调用,

3、修饰代码块:静态代码块 ,给静态变量进行赋值

4、修饰类:静态内部类

11.this和super区别

this

super

可以区分成员变量与局部变量重名问题,如果本类没有这个成员变量,也可以调用父类的成员变量

可以区分本类成员变量与父类成员变量重名问题,只能调用父类的成员变量

可以调用本类的成员方法,如果本类没有这个成员方法,也可以调用父类的成员方法

只能调用父类的成员方法

可以通过this() 或 this(参数) 让其本类的构造方法直接相互调用

子类通过super() 或 super(参数) 调用父类的构造方法

12.在使用时接口、抽象类该如何选择

抽象类:描述现实中具体的事务可以使用抽象类

接口:描述某些行为特征时可以使用接口

13.普通类和抽象类的区别

普通类

抽象类

不能包含抽象方法

可以包含抽象方法

能直接实例化(new)

不能直接实例化(需要继承重写抽象方法)

14.静态变量和实例变量的区别

静态变量:被static修饰符修饰的变量,也被称为类变量,它是属于类的,不属于类的任何一个对象,一个类不管创建多少个对象,静态变量在内存中有且仅有一个拷贝

实例变量:必须依存于某一个实例,需要先创建对象然后通过对象才能访问到它。实例变量可以实现让多个对象共享内存

15.重写和重载的区别

重写:发生在子类和父类之间,当子类继承父类时,子类中的方法与父类方法的名称,参数个数,参数类型完全一致时,称为子类重写父类方法,子类的访问修饰符必须大于等于父类的访问修饰符

重载:一个类中的多个方法的方法名称相同,参数个数或者形参类型不同,则称为方法重载,与返回值是无关的

补充

1.final修饰的不能重写,但是能重载

2.无论重载重写,必须保证方法名相同

16.构造器Constructor是否可以被override

构造器Constructor是不能被继承的,因此不能被重写Overriding,但可以被重载Overloading

public 类名(){}

补充

1、构造函数是不能被继承的,构造方法只能被隐式调用

2、构造函数是不能有返回值类型的

17.什么是 java 序列化,如何实现 java 序列化

序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。序列化是为了解决在对对象流进行读写操作时所引发的问题。

序 列 化 的 实 现 : 将 需 要 被 序 列 化 的 类 实 现 Serializable 接 口 , 该 接 口 没 有 需 要 实 现 的 方 法 , implements Serializable 只是为了标注该对象是可被序列化的,然后使用一个输出流(如:FileOutputStream)来构造一个ObjectOutputStream(对象流)对象,接着,使用 ObjectOutputStream 对象的 writeObject(Object obj)方法就可以将参数为 obj 的对象写出(即保存其状态),要恢复的话则用输入流。

18.包装类和基本数据类型的区别

基本数据类型

包装类

short

Short

int

Interger

byte

Byte

long

Long

char

Character

double

Double

float

Float

boolean

Boolean

初始值不同:基本数据类型初始值int为0,boolean为false,double为0.0,包装类型的默认值都为null

使用方式不同:基本数据类型不能用于泛型,包装类可以作用于泛型

19.基本数据类型和包装类的使用标准

1、所有的POJO类属性必须使用包装数据类型

2、所有RPC方法的返回值和参数必须使用包装数据类型

3、所有的局部变量使用基本数据类型

说明

POJO类属性没有初始值是提醒使用者在需要使用时,必须自己显示地进行赋值,任何NPE(NullPointerException)问题,或者入库检查,都由使用者来保证

数据查询的结果可能是null,因为自动拆箱,用基本数据类型接收有NPE风险

20.包装类拆箱装箱

装箱:将基本类型转换成引用类型的过程叫做装箱(将栈中的基本数据类型放到堆里面去从而转换成一个引用类型)

int i1 =1; Integer i2 = new Integer(i1);

自动装箱

int t =11; Integer t2 =t;

拆箱:将包装类型转换成引用数据类型的过程叫拆箱(将栈中的基本数据类型放到堆里面去从而转换成一个引用类型)

Integer i=new Integer(1); int i2=i.intValue();

自动拆箱

int t =11; Integer t2 =t; int t3 =t2.intValue();

方法介绍

intValue()是吧Integer对象类型变成int的基本数据类型

parseInt()是吧String转化成int类型

Valueof()是把String转化成Integer类型

21.String、StringBuffer、StringBuilder区别

String不可变字符序列,底层是一个数组不可扩容

StringBuffer、StringBuilder可变字符序列,底层是可扩容的数组,底层会有一个value 和 count,当需要追加数据时,底层的数组长度不够时,它会再创建一个扩容后的新数组,然后将原来的数据复制过去,然后再在新数组后面追加

StringBuffer:是JDK1.0的时候的,线程安全

StringBuilder:是JDK1.5的时候的,线程不安全

三者的效率区别StringBuilder>StringBuffer>String

22.说出5个String类的方法

.equals() 比较

.substring() 截取

.length() 长度

.indexOf() 查找位置

.toUpperCase() 大写

......

23. ==和equals()的区别

equals()和==最大的区别一个是方法,一个是运算符

==:如果对象是基本数据类型,则比较的是数值是否相等;

        如果是引用数据类型,比较的则是对象的地址值是否相等

equals():用来比较方法两个对象的内容是否相等

24.请说出5个异常类型

ArrayIndexOutOfBoundsException 数组下标越界

NullPointerException 空指针异常

ClassCastException 类转换异常

SQLException SQL异常

IllegalArgumentException 方法传参错误

25.异常处理方式

try{
 可能出现异常的代码 
}catch{
 捕获到的异常与catch中的异常类型进行匹配,执行里面的逻辑 可能有多重判断 
}finally{
 进行资源的关闭 
}

26.throws和throw区别

throw

1、在方法体内,表示抛出异常,由方法体内的语句处理

2、是具体向外抛出异常的动作,所以它抛出的是一个异常实例,执行 throw 一定是抛出了某种异常。

throws

1、在方法签名后面,表示如果抛出异常,由该方法的调用者来进行异常处理

2、主要是声明这个方法会抛出某种类型的异常,让它的使用者要知道需要捕获的异常的类型

3、表示出现异常的一种可能性,并不一定会发生这种异常。

27.final、finally、finalize区别

final:用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可被继承

finally:异常处理语句结构的一部分,表示不管抛不拋异常都执行

finalize:Object 类的一个方法,在垃圾回收器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。该方法无需我们调用

28.流的分类

1.流的方向

输入流,输出流

2.流的类型

字节流,字符流

字符流

字节流

输入流

Reader

inputStream

输出流

writer

outputStream

3.处理对象

节点流:可以直接从数据源或目的地读写数据,如FileInputStream、FileReader、DataInputStream等。

处理流:不直接连接到数据源或目的地,是”处理流的流”。通过对其他流的处理提高程序的性能,如BufferedInputStream、BufferedReader等。处理流也叫包装流

29.字符流、字节流的区别

1.处理数据不同

1、字节流处理的数据类型:图片、MP3、视频文件、文本数据

2、字符流处理的数据类型:纯文本数据

3、如果是文本数据优先选择字符流,除此之外都是字节流

2.流的读取单位不同

1、字节流主要操作的数据类型是byte类型数据,以byte数组为准

2、字符流处理的单元为 2 个字节的 Unicode 字符,分别操作字符、字符数组或字符串

3、字节流处理单元为 1 个字节,操作字节和字节数组

30.集合与数组的区别

数组

集合

数组的大小在创建之初就规定了,后面不能更改

集合的大小是不固定的,底层会自动扩容

数组存放的类型在创建是就规定了,只能有一种

集合在不添加泛型时数据类型并不是一种,是Object类型

31.java容器(集合)介绍

1.超级接口Iterable

2.起始接口collection继承Iterable接口

3.Map在集合框架中跟collection是并列存在的

4.三大接口

Set:Set继承Collection 集合 无序,不可重复的,元素进入集合的顺序是没有先后差别的

Queue:Queue继承Collection

List:List继承Cillection 有序的序列,允许插入重复的数据

5.第一代安全集合类

1、Vector、Hashtable

2、核心代码使用synchronized修饰符

6.第二代线程非安全集合类

1、ArrayList、HashMap

2、线程不安全但是性能好,用来替代第一代

3、要变成线程安全,使用工具类Conllections,底层也是使用synchronized代码块锁,但是相比第一代性能稍有提升

32.List、Set、Map的区别

1、List和Set都是继承Collection 接口的集合,是存储单列元素的集合,Map是存储k-v键值对双列数据的集合

2、List中存储的数据有序,允许重复 ;Set中存储的数据无序,不允许重复,但是元素的位置是由元素的hashCode决定的

33.Map集合详解

Map接口 使用键值对存储(k-v),不能有重复的key,value可以重复,键要保证唯一性,键和值存在映射关系

集合名

存值

数据结构

使用

Hashtable

不可以存入null键,null值

哈希表

如果需要保证键的唯一性需要覆写hashCode方法,和equals方法

HashMap

允许null值和null键

JDK1.7 数组+链表

JDK1.8 数组+链表+红黑树

LinkedHashMap

允许null值和null键

哈希表+双向链表

如果需要输出的顺序和输入的相同,那么用LinkedHashMap可以实现

TreeMap

key不可以为null,值可以为null

红黑树

能够把它保存的记录根据键排序,默认是键值的升序排序

34.Map的两种遍历方式

Map不能直接遍历,想要遍历有两种间接的方式

1.通过map方法的 keySet() 方法

将map中的key 取出来,存到set集合里面,之后遍历set集合,通过map中的 get(key key) 方法取出每一个value值

2.通过map中的 entrySet() 方法

将map中的key 和 value 存到 map的内部类 entry中,之后将entry对象存到set集合里面,之后通过遍历set集合,通过entry内部类中的 getKey, 和 getValue 获取每一个值

35.TreeSet和HashSet的区别

TreeSet

TreeSet底层实际使用的存储容器是TreeMap

对于TreeMap而言,它采用一种被称为红黑树的排序二叉树来保存Map中的每个Entry,每个Entry被当成红黑树的一个节点来对待

总结:

实现TreeMap

具有排序功能,有序

TreeSet中的元素必须实现comparable接口并重写compareTo(),TreeSet判断元素是否重复,以及确定元素的顺序,靠的就是这个方法

HashSet

HashSet的实现原理,封装了一个HashMap对象来存储所有的集合元素,不允许集合中有重复

的值,使用该方式时需要重写 equals()和 hashCode()方法

总结:

实现HashMap

没有排序功能,无序

重写 equals()和 hashCode()方法保证数据唯一性

35.线程和进程的区别

根本区别:进程是操作系统资源分配的基本单位,而线程是处理器任务调度和执行的基本单位

1、一个进程可以包含多个线程

2、进程崩溃后,在保护模式下不会对其他进程产生影响,但是一个线程崩溃,整个进程都死掉,所以多进程要比多线程健壮

36.线程的三种创建方式

接口/类

方法体

介绍

exteds Thread类

run()

implement Runnable接口

run()

implement callable接口

call()

方法有返回值,能够抛出异常

37.线程的5种状态

新建:new创建一个线程

就绪:.start()后,该线程处于就绪状态,只是表示可以运行,等待jvm调用

运行:线程获得cpu开始执行run()方法体

阻塞:如果其他线程抢占CPU就会阻塞,或者调用sleep()

死亡:run()、call()执行完毕,线程正常结束,或者是抛出异常、调用stop()但是容易死锁

38.线程池的四种创建方式

1.线程池的意义

创建线程整个过程的浪费是比较大的,而线程池的意义在于先创建线程需要的数据,当要用的时候直接去线程池中取出线程,这样节省了创建连接和关闭资源的开销

2.线程池创建

ExecutorService executorService=new ThreadPoolExecutor(
3,//核心线程数 
6,//最大线程数 
1L,//存活时间(多余的空闲线程的存活时间) 
TimeUnit.SECONDS,//时间单位(线程池维护线程所允许的空闲时间的单位) 
new ArrayBlockingQueue<>(3),//任务队列 
Executors.defaultThreadFactory(),//线程工厂
new ThreadPoolExecutor.AbortPolicy());//拒绝策略

任务队列:任务队列是基于阻塞队列实现的,即采用生产者消费者模式

AbortPolicy(默认):丢弃任务并抛出 RejectedExecutionException 异常。

CallerRunsPolicy:由调用线程处理该任务。

DiscardPolicy:丢弃任务,但是不抛出异常。可以配合这种模式进行自定义的处理方式。

DiscardOldestPolicy:丢弃队列最早的未处理任务,然后重新尝试执行任务。

3.线程池的四种创建方式

通过Exeutors(jdk1.5)提供的四种线程池

名称

可缓存线程池

newCachedThreadPool

如果线程池长度超过处理需要,可以灵活的回收线程,若无可回收,则新建线程

定长线程池

newFixedThreadPool

可控制线程最大并发数,超出的线程会在队列中等待

定长线程池,定时

newScheduledThreadPool

支持定时及周期任务执行

单线程化的线程池

newSingleThreadExecutor

它会用唯一的工作线程来执行任务,保证所有的任务按照指定顺序执行

39.Lock和Synchronized的区别

1、Lock是接口,synchronized是关键字

2、Lock可以选择性的获取锁,如果一段时间获取不到,可以放弃。Synchronized会一直获取,借助这个特性可以规避死锁

3、synchronized在发生异常和同步代码块结束的时候,会自动释放锁,Lock必须手动释放,所以如果忘记释放锁,也会造成死锁

40.静态锁和非静态锁的区别

1.对象锁钥匙只能有一把才能互斥,才能保证共享变量的唯一性

2.在静态方法上的锁,和实例方法上的锁,默认不是同样的,如果同步需要制定两把锁一样。

static synchronized是类锁

synchronized是对象锁

若类对象被lock,则类对象的所有同步方法(static synchronized func)全被lock。

若实例对象被lock,则该实例对象的所有同步方法(synchronized func)全被lock。

41.Synchronized、volatile

1.java的两种同步机制

同步块(或方法)和volatile变量

2.锁提供了两种主要特性

互斥和可见性

3.volatile

volatile关键字是一种轻量级的同步机制,只保证数据的可见性,而不保证数据的原子性。

4.synchronized

非原子操作都会存在线程安全问题,需要我们使用同步技术(sychronized)来让它变成一个原子操作

synchronized 是由“一个变量在同一个时刻只允许一条线程对其进行 lock 操作”这条规则获得的,此规则决定了持有同一个对象锁的两个同步块只能串行执行

Synchronized用于线程间的数据共享,而ThreadLocal则用于线程间的数据隔离。

42.悲观锁、乐观锁

1.悲观锁

在传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁、写锁等,都是在操作之前先上锁(效率低)

2.乐观锁

在数据上会为其加一个版本号,在操作后数据版本号会更新,如果使用数据版本号不一致,后面就不能操作了,乐观锁适用于多读的应用类型,这样可以提高吞吐量。

43.ArrayList 和LinkedList区别

List接口是Collection接口的子接口定义一个允许重复项的有序集合,可以动态的增长,最重要的是它保证维护元素特定的顺序

ArrayList 优点是随机访问元素,但插入和删除速度很慢

LinkedList 对顺序访问进行了优化,插入和删除的开销并不大,随机访问则相对较慢

44.线程安全的理解

是指在多线程环境下,每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的

45.什么是反射?

反射就是在程序运行时期,动态的获取类中成员信息(构造方法,成员变量,成员方法)的过程

1.反射机制

所谓的反射机制就是java语言在运行时拥有一项直观的能力。通过这种能力可以彻底地了解自身的情况为下一步的动作做准备。

Java的反射机制的实现要借助于4个类:Class,Constructor,Field,Method;

其中Class代表的是类对 象,Constructor-类的构造器对象,Field-类的属性对象,Method-类的方法对象。通过这四个对象我们可以粗略地看到一个类的各个组 成部分。

2.Java反射的作用

在Java运行时环境中,对于任意一个类,可以知道这个类有哪些属性和方法。对于任意一个对象,可以调用它的任意一个方法。这种动态获取类的信息以及动态调用对象的方法的功能来自于Java 语言的反射(Reflection)机制。

3.Java 反射机制提供功能

在运行时判断任意一个对象所属的类。

在运行时构造任意一个类的对象。

在运行时判断任意一个类所具有的成员变量和方法。

在运行时调用任意一个对象的方法

46.sleep wait notify notifyAll的作用

sleep方法是Thread类的静态方法

调用sleep方法可以让当前正在运行的线程进入睡眠状态,即暂时停止运行指定的单位时间。并且该线程在睡眠期间不会释放对象锁。

wait是Object提供的一个方法

调用wait方法可以让当前线程进入等待唤醒状态,并释放锁。该线程会处于等待唤醒状态直到另一个线程调用了object对象的notify方法或者notifyAll方法。

notify也是Object提供的一个方法

当其它线程调用该对象的notifyAll()方法(唤醒所有wait线程)或notify()方法(只随机唤醒一个wait线程),被唤醒的的线程便会进入该对象的锁池中,锁池中的线程会去公平竞争该对象锁。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值