秋招面试准备(一)Java基础

一、面向对象和面向过程
面向对象:易维护、易复用、易拓展。因为“继承、封装、多态”的OOC特性,系统低耦合。
面向过程:性能高。根本原因:Java是半编译语言,需要将.java源代码编译为.class字节码文件,才能在不同机器上的JVM上运行。

二、Java语言的特点
1、面向对象(抽象、继承、封装、多态)
2、平台无关性(JVM)
3、支持多线程(C++11之前,C++需要依赖操作系统的多线程实现多线程)
4、支持网络编程
5、编译和解释共存

三、JDK|JVM|JRE
1、JVM:Java虚拟机,用于运行Java字节码文件(.class),特点:平台无关性、代码可移植、高效。
* 传统解释型语言:python,运行时才编译,可跨平台,执行速度慢;
* 传统编译型语言:先编译后运行,不可跨平台,执行速度快;
JVM的类加载器加载字节码(.class),通过解释器解释为CPU执行的机器码,再运行;还有JIT编译器,热点代码可以在运行时编译,并保存机器码,使CPU直接执行机器码。

2、JDK:Java开发工具。(java SDK)。典型的,javac.exe编译器,java.exe解释器。

3、JRE:Java运行时环境,JVM、类库等等。
排序:JVM(解释字节码)<JRE(包含了类库等工具)<JDK(开发工具)

四、Java和C++对比
相同点:
1、都是面向对象编程,支持“封装、继承、多态”
不同点:
1、指针:Java中没有指针的概念(但是有引用的概念),C++可以使用指针访问内存。
2、继承:Java的类是单继承,接口是多继承;C++是多继承的。
3、内存释放:Java有自动的内存管理机制;C++需要使用free()释放内存。
4、字符串:C语言中的字符串有结束符’\0’,而Java没有。

五、Java中的字符和字符串的区别
1、字符,单引号,例如‘b’,字符常量相当于一个ASCII值,可以参加表达式运算‘b’+1;属于基本数据类型位于栈区,占用2字符。
2、字符串,双引号,引用数据类型,所以String s = “b”,s是一个地址值,底层是字符数组。

六、八种基本类型和包装类型
bool–Boolean
char–Character
记住,集合的泛型只能是包装类型或者应用类型,例如List<INT[]>

七、Override和Overload
1、Overrided:常用,重写。两同、一小、一大。
发生在运行期子类对父类允许访问的方法的实现过程重新编写。
两同:方法名称、参数列表相同。
一小:抛出异常的范围小。(如果返回的是引用型,引用型也得小)
一大:方法访问修饰符大。
要求:父类的访问修饰符为private(私有)/final(不可变)/static(静态,属于类)则不可以override。**构造方法不可以override。因为构造方法和类名相同,子类和父类名称不同。**返回值如果是基本类型,要相同,如果是应用型,返回类型可以比父类返回类型小。

2、Overload:方法重载
发生在同一个类中,可以只有方法名称相同,典型的如“构造器重载”。
根据方法签名,方法名称+参数类型构成唯一的一个方法,编译器使用这种方式找到执行的方法。
所以,可以方法名称相同,而参数类型、数量不同,从而构成不同的重载方法,处理不同的逻辑。

八、静态方法为什么不能调用非静态方法?
静态方法属于类,静态方法不可以通过实例化类的方式来调用,所以也不能调用属于对象的非静态变量或者方法。

九、接口和抽象类的区别。
1、抽象类有构造方法(子类可以调用此方法)但是不可实例化。类名前使用Abstract修饰。可以存在抽象方法,也可以存在正常的方法;
2、接口无构造方法不可实例化,分为抽象方法(最常见,可省略public abstract修饰符,一定要重写)、默认方法(可继承可重写)、私有方法和静态方法等四种。
2、接口除了static final修饰的常量不可以有其他变量。
3、设计的角度:接口是一种“规范”,是对行为的抽象;抽象类是对类的抽象,是对内容的抽象。

十、==和equals
对于前者,如果是基本数据类型,就是判断值是否相等;如果是对象,则判断内存地址(这里的地址不是hashcode,可以理解为物理地址)是不是相等。(即是不是完完全全是同一个对象)
object.equals方法,默认底层和上述是相同的,等于号比较,但是可以重写一个类的hashcode和equals方法,改变equals的判断逻辑(例如改为成员变量的值相同)。

字符串的底层重写了hashcode和equals
String s1 = new String("hello"); // 位于堆区
String s2 = "hello"; // 位于方法区的字符串常量池
s1 == s2 // false,因为物理地址不同
s1.equals(s2) // true,因为hashcode相同且内容相同

十、为什么重写equals时要重写hashcode?
1、什么是hashcode?hashcode是个本地方法,用c++实现。也叫散列码,将对象的物理内存地址映射为一个值,这个值可以用于确定对象在散列表的位置。
2、有了hashcode可以减少equals的使用,**因为假设如果两个对象hashcode不同,就可以认为这两个对象不同。**这样的话,如果hashcode相同,再调用equals方法查看是否相同,减少equals调用。
3、因为hashcode不同,对象不同;也就是说,对象相同,hashcode得相同,所以如果重写了equals,就得重写hashcode。
(我的理解是hashcode可以看成一种逻辑地址,堆上的两个对象,物理地址是不相同的,即==是不相同的;)

hashcode相同也可能是不同的对象,这涉及到了散列表的碰撞问题。

十一、进程、线程、程序
程序:含有指令和数据的文件,静态的,放在磁盘中。
进程:资源分配的基本单位,包括内存、CPU、文件、IO等资源,是程序的一次调度,是动态的,存在一系列从创建到终止的状态转换。一个程序可以开启多个进程。
**线程:**轻量级的进程,CPU分配的基本单位,共享除了CPU之外的资源(如堆、代码),一个进程可以开启多个线程。

十二、Java线程的状态
1、New:初始态,线程创建,但是尚未Thread.start()
2、Runnable:运行态,start()之后。包括了RUNNING运行态(在CPU上)和REDRY就绪态(等待CPU)
3、Block:阻塞态,线程阻塞于锁(如synchronize关键词修饰的方法)
4、Waiting:等待态,需要等待其他线程完成一些动作.
Object.wait() Object.join() ==>Object.notify() Object.notifyAll()
5、Time_waiting:超时等待状态,超过一定时间就不等了
Thread.sleep()
6、Terminated:终止态,线程执行完毕
(图略)

十三、final修饰的场合
1、变量:此变量不可修改,如果为引用型,不可指向别的对象(但是可以修改指向对象的内容)
2、类:此类不可被继承(即方法不可重写覆盖,是除了private修饰方法之外,另一个“封装”的办法)
3、方法:该类不可以重写覆盖(和private修饰一样,类中private的方法会隐式地指定为final)

十四、异常机制
一个方法,想在运行期间抛出异常:
1、代码中某部分throw new Exception()
2、在方法上声明异常,表示这个异常被抛出Public void method() throws Exception
异常的层次
在这里插入图片描述
Exception是程序本身能处理的,又分为两种异常,一种是不受检查的异常,如Runtime Exception运行时异常,编译器不管,你可以catch它们也可以不管,这些异常应当在代码测试的时候被发现并且避免;一类异常是受检查异常,即编译时就会发现错误,需要处理。在实习时,经常使自己的异常类继承自RuntimeException,在运行错误的时候抛出,中断线程。

对受检查异常的处理又两种,一种是调用方try…catch…finally;一种是duck掉,即在方法上声明,异常丢给上一级调用方,方法终止。
如果是try…catch…finally,如果try…catch里有return,先执行return里的计算,再执行finally,再执行return返回。
如果是调用方duck掉异常,最终main方法也没有处理,则虚拟机线程中断。
如果catch的异常多层次,先catch子类异常,再catch父类异常即可。

十五、常用修饰
1、transient(顺时的):修饰成员变量,在实例被序列化的时候,防止该变量被序列化,如果是引用型,直接赋值null。
什么是序列化

  • 将一个对象(包含数据和方法)表示为一个字节序列,可以写入文件,同理再反序列化成为对象;序列化的只是对象所包含的**“数据”**,即属性的值或者属性指向的对象的值。
  • 如果向序列化一个对象,该对象里的引用型变量也得可序列化,因为引用型变量所指向的对象的值也得保存。
  • 反序列化:读取字节序列,在堆上创建对象(构造方法不会执行)
  • 静态变量属于类,不会被序列化。
  • 如何序列化:1、定义一个类,2、实现Serializable接口

十六、String、StringBuilder和StringBuffer
1、String:不可变字符串。底层是用final修饰的char数组private final char value[]。(可以类比数组,数组也是不可变的),这就意味着对于String的操作会生成新的String对象。
字符串比较特别,直接赋值和使用构造方法赋值有区别。这里略。
常用方法:

char charAt(int index)  常用!索引取值!
int length()  常用!
// 常用于遍历
static String valueOf(char[] data)  此方法可以将char数组或其他格式转化为String
char[] toCharArray()  字符串转化为char数组
String(char[] value) 构造方法,char数组转化为String
// 在遇到字符串的题目时,也可以先转化为char数组再操作
String substring(int beginIndex, int endIndex)  左开右闭取子串
String(byte[] bytes) 构造方法
int indexOf(int ch)  返回索引
boolean equals(Object anObject)  比较

2、StringBuffer和StringBuilder
底层时char[],但是无final修饰,说明可变。String是不可变字符串,一定是线程安全的;StringBuffer相对于StringBuilder,加了同步锁,线程安全,但是效率较低。多线程下考虑StringBuffer。

StringStringBuffer:构造方法new StringBuffer(String s) 常用 字符转转化为sb
从StringBufferStringString toString()  
StringBuffer append(char c)  增加
StringBuffer insert(int offset, boolean b)  插入
StringBuffer delete(int start, int end)  删除
StringBuffer deleteCharAt(int index)  删除指定位置
int indexOf(String str)  返回首次出现索引
void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)  复制到Char数组
char charAt(int index)  索引
StringBuffer reverse()  反转
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值