中科星图面试整理

本文最后更新于:2 年前

公司:中科星图股份有限公司

身份:2022届应届生

时间:2022/03/02

中科星图面试整理

Java基础

Java的数据类型

&和&&的区别

&:按位与逻辑与

&&: 短路与

序列化和反序列

定义

Java序列化:把Java对象转换为字节序列的过程

Java反序列化:指把字节序列恢复为Java对象的过程。

作用

序列化作用:

  • 在传递和保存对象,保证对象的完整性可传递性
  • 对象转换为有序字节流,便于在网络上传输或者保存在本地文件中。

反序列化的作用:

根据字节流中保存的对象状态描述信息,通过反序列化重建对象

==核心作用就是对象状态保存重建==

应用(json/xml的数据传递)

在数据传输(也可称为网络传输)前,先通过序列化工具类将Java对象序列化为json/xml文件。

在数据传输(也可称为网络传输)后,再将json/xml文件反序列化为对应语言的对象

优点

  • 将对象转为字节流存储到硬盘上,当JVM停机的话,字节流还会在硬盘上默默等待,等待下一次JVM的启动,把序列化的对象,通过反序列化为原来的对象,并且序列化的二进制序列能够减少存储空间(永久性保存对象)。
  • 序列化成字节流形式的对象可以进行网络传输(二进制形式),方便了网络传输。
  • 通过序列化可以在进程间传递对象

过程

1、实现序列化的必备要求:

只有实现了==Serializable==或者==Externalizable==接口的类的对象才能被序列化为字节序列。(不是则会抛出异常)

2、JDK中序列化和反序列化的API:

  • java.io.ObjectInputStream:对象输入流。

该类的readObject()方法从输入流中读取字节序列,然后将字节序列反序列化为一个对象并返回。

  • java.io.ObjectOutputStream:对象输出流。

该类的writeObject(Object obj)方法将将传入的obj对象进行序列化,把得到的字节序列化写入到目标输出流中进行输出

3、三种实现:

  • Student类仅仅实现了Serializable接口

ObjectOutputStream采用默认的序列化方式,对Student对象的非transient的实例变量进行序列化。
ObjcetInputStream采用默认的反序列化方式,对Student对象的非transient的实例变量进行反序列化。

  • 若Student类仅仅实现了Serializable接口,并且还定义了readObject(ObjectInputStream in)和writeObject(ObjectOutputSteam out),则采用以下方式进行序列化与反序列化。

ObjectOutputStream调用Student对象的writeObject(ObjectOutputStream out)的方法进行序列化。
ObjectInputStream会调用Student对象的readObject(ObjectInputStream in)的方法进行反序列化。

  • 若Student类实现了Externalnalizable接口,且Student类必须实现readExternal(ObjectInput in)和writeExternal(ObjectOutput out)方法,则按照以下方式进行序列化与反序列化。

ObjectOutputStream调用Student对象的writeExternal(ObjectOutput out))的方法进行序列化。
ObjectInputStream会调用Student对象的readExternal(ObjectInput in)的方法进行反序列化

Java有很多基础类已经实现了serializable接口,比如String,Vector等

堆和栈的区别

  • 堆是运行时确定内存大小,而栈在编译时即可确定内存大小

    理由便是第一节中提到的,这是区分堆和栈的初衷

  • 堆内存由用户管理(Java中由JVM管理),栈内存会被自动释放

  • 栈实现方式采用数据结构中的栈实现,具有(LIFO)的顺序特点,堆为一块一块的内存

  • 栈由于其实现方式,在分配速度上比堆快的多。分配一块栈内存不过是简单的移动一个指针

  • 在JVM中,栈不会被程序员直接使用,程序员操作的一般都是堆。

  • 栈为线程私有而堆为线程共享

类加载器有哪些

classLoader作用就是负责把磁盘上的.class文件加载到JVM内存中,并生成 java.lang.Class类的一个实例

类加载器大致分成两类

  1. 系统提供的
  2. 由 Java 应用开发人员编写的。

系统提供的类加载器主要有下面三个:

(1): 引导类加载器(Bootstrap类加载器)
它是由c++代码实现的,是虚拟机自身的一部分。拿不到他的引用,但实际存在,并且加载一些重要的类,它加载(%JAVA_HOME%\jre\lib),如rt.jar(runtime)、i18n.jar等,这些是Java的核心类。 他是用原生代码来实现的,并不继承自 java.lang.ClassLoader
(2): 扩展类加载器(Extension类加载器)
虽说能拿到,但是我们在实践中很少用到它,它主要加载扩展目录下的jar包, %JAVA_HOME%\lib\ext
(3): 系统类加载器(System类加载器)
它主要加载我们应用程序中的类,如Test,或者用到的第三方包,如jdbc驱动包等。

理解双亲委派模式

双亲委派模式中的父子关系并非通常所说的类继承关系,而是采用组合关系来复用父类加载器的相关代码。

双亲委派模式示意图

类加载器收到了类加载请求,它并不会自己先去加载,而是先委托给父类的加载器去执行,如果父类加载器还存在其父类加载器,则进一步向上委托,依次递归,请求最终将到达顶层的启动类加载器,如果父类加载器可以完成类加载任务,就成功返回,倘若父类加载器无法完成此加载任务,子加载器才会尝试自己去加载,这就是双亲委派模式,即每个儿子都很懒,每次有活就丢给父亲去干,直到父亲说这件事我也干不了时,儿子自己想办法去完成。
引用:深入理解Java类加载器(ClassLoader)

优势

  • 避免类的重复加载,当父亲已经加载了该类时,就没有必要子ClassLoader再加载一次。
  • 安全因素,java核心api中定义类型不会被随意替换,防止核心API库被随意篡改。

List的子类和Map的子类

见博客 Java集合有哪些

HashMap的默认长度

默认HashMap内部数组的长度为16,负载因子为0.75,就是在构造函数里面传的两个值。 阈值就是12(16*0.75=12),这样当第十三个元素加入时,底层数组就会扩容。

JavaWeb

controller的实现过程

标记pojo的注

@Component

AOP的通知

前置通知:在我们执行目标方法之前运行(**@Before**)

后置通知:在我们目标方法运行结束之后,不管有没有异常(**@After**)

返回通知:在我们的目标方法正常返回值后运行(**@AfterReturning**)

异常通知:在我们的目标方法出现异常后运行(**@AfterThrowing**)

环绕通知:目标方法的调用由环绕通知决定,即你可以决定是否调用目标方法,joinPoint.procced()就是执行目标方法的代码 。环绕通知可以控制返回对象(@Around)

多线程

Sleep和Write的区别

sleep是线程类(Thread)的方法,导致此线程暂停执行并指定时间,将执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复。调用sleep不会释放对象锁

wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池。只有针对此对象发出==notify方法(或notifyAll)==后,本线程才进入对象锁定池准备获得对象锁进入运行状态。

多线程的创建方法

  1. 继承Thread类创建线程类
  2. 实现Runnable接口创建线程类
  3. 通过Callable和Future接口创建线程

继承Thread类:

优点:

1、实现起来简单,而且要获取当前线程,无需调用Thread.currentThread()方法,直接使用this即可获取当前线程;

缺点:

1、线程类已经继承Thread类了,就不能再继承其他类;

2、多个线程不能共享同一份资源(如前面分析的成员变量 i );

实现Runnable接口或者Callable接口:

优点(推荐):

1、线程类只是实现了接口,还可以继承其他类

2、==线程间资源共享==。多个线程可以共用一个target对象,适合多个线程处理同一份资源的情况。

缺点:

1、通过这种方式实现多线程,相较于第一类方式,编程较复杂

2、要访问当前线程,必须调用Thread.currentThread()方法。
————————————————
参考: JAVA多线程的三种创建方式

run和start的区别

start()能够异步调用run(),直接调用run()只能是同步的,要实现多线程**只能使用 start()**。

用过哪些JUC的方法

MySQL

DML的类型

Like的匹配符

Delete和Dort的区别

事务的特性

隔离等级

SQL执行计划

Linux

常用指令

查看日志的指令

参考

序列化和反序列化的详解


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!