1.Question 1
Given:
- public interface Status {
12./* insert code here */ int MY_VALUE = 10;
13.}
Which three are valid on line 12?(Choose three.)
A. final
B. static
C. Native
D. Public
E. private
F. abstract
G. Protected
知识点:接口的属性必须是public static final
2.Error、Exception和RuntimeException的区别?
Error与Exception都继承自Throwable,而RuntimeException则继承自Exception。在Java中只有Throwable类型的实例才可以被抛出(throw)或捕获(catch)。
Exception是程序正常运行中可以预料的意外情况,可能并且应该被捕获,进行相应处理。
Error则是指在正常情况下,不大可能出现的情况,绝大部分的Error都会导致程序(比如JVM)处于非正常的、不可恢复状态。
RuntimeException(运行时异常)异常自动为你所编写的程序定义
ArrayIndexOutOfBoundsException(数组下标越界)、NullPointerException(空指针异常)、ArithmeticException(算术异常)、MissingResourceException(丢失资源)等异常,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。
3. String,StringBuffer, StringBuilder的区别是什么?String 为什么是不可变的?
String 类中使⽤ final 关键字修饰字符数组来保存字符串,private final charvalue[] ,所以 String 对象是不可变的。
StringBuilder和StringBuffer中的char数组没有被final修饰,是可变的。
String 中的对象是不可变的,也就可以理解为常量,线程安全。
StringBuilder是线程不安全的,因为Stringbuilder继承了父类abstractStringBuilder的append方法,该方法中有一个count+=len的操作不是原子操作,所以在多线程中采用StringBuilder会丢失数据的准确性并且会抛ArrayIndexOutOfBoundsException的异常。
StringBuffer是线程安全的因为他的append方法被synchronized关键字修饰了,所以它能够保证线程同步和数据的准确性。
因为StringBuffer是被synchronized修饰的,所以在单线程的情况下StringBuilder的执行效率是要比StringBuffer高的。所以一般在单线程下执行大量的数据使用StringBuilder,多线程的情况下则使用StringBuffer。
4.接口是否可继承接口?抽象类是否可实现(implements)接口?抽象类是否可继承具体类(concrete class)?抽象类中是否可以有静态的main方法?
接口可以继承接口。
public interface InterfaceA { }
interface InterfaceB extends InterfaceA{ }
抽象类可以实现(implements)接口,抽象类可以继承具体类。前提是实体类必须有明确的构造函数。
public interface InterfaceA { }
abstract class TestA implements InterfaceA{ }
public class TestA{ }
abstract class TestB extends TestA{ }
抽象类中可以有静态的 main 方法。
public static void main() {}
- 多线程有几种实现,
1.继承Thread类,重写run方法
2.实现Runnable接口,重写run方法,实现Runnable接口的实现类的实例对象作为Thread构造函数的target
3.通过Callable和FutureTask创建线程
4.通过线程池创建线程
同步和并发是如何解决的,
- 信号量 Semaphore,应用场景:用于流量控制,限流
- 同步屏障 CyclicBarrier,用于多线程计算数据,最后合并计算结果,例如多个老师打分,最后合并算平均分
- Exchanger 两个线程之间进行数据交换,应用场景:用于两个线程之间交换数据,例如校对工作
- ConutDownLatch 倒计时器,应用场景:可以用于模拟高并发
ConutDownLatch 与 CyclicBarrier 区别
共同点:都能够实现线程之间的等待
不同点:
ConutDownLatch 一般用于某个线程A等待若干个其他线程执行完任务之后,它才能执行
CyclicBarrier 一般用于一组线程互相等待到某个状态,然后这一组线程在同时执行
ConutDownLatch 是不能重用的,CyclicBarrier 可以重复使用
参考链接:https://blog.csdn.net/yz2015/article/details/79436123
什么叫守护线程,用什么方法实现守护线程?
守护线程是程序运行的时候在后台提供一种通用服务的线程。所有用户线程停止,进程会停掉所有守护线程,退出程序。
守护线程创建的线程也是守护线程。
守护线程不应该访问、写入持久化资源,如文件、数据库,因为它会在任何时间被停止,导致资源未释放、数据写入中断等问题。
Java中把线程设置为守护线程的方法:在start线程之前调用线程的setDaemon(true)方法,否则会抛出IllegalThreadStateException异常,该线程仍默认为用户线程,继续执行。
6. String s ="Hello";s = S +"world!";这两行代码执行后,原始的String对象中的内容到底变了没有?
没有,因为String类是不可变类。实例的信息是在创建的时候提供,并且在整个生命周期中都不可改变。在这段代码中,s原来指向一个String对象,内容是“hello”,然后我们对s进行了+操作,那么s所指向的那个对象是否发生了改变呢?答案是没有。这时,s不指向原来那个对象了,而指向了另一个String对象,内容为”helloworld!",原来那个对象还存在内存中,只是s这个引用变量不再指向他了。
7.什么是java序列化,如何实现java序列化?或者请解释Serializable接口的作用。
把对象转换为字节序列的过程称为对象的序列化,把字节序列恢复为对象的过程称为对象的反序列化。
序列化的实现:将需要被序列化的类实现Serializable接口,该接口没有需要实现的方法,implements Serializable只是为了标注该对象是可被序列化的,然后使用一个输出流(如:FileOutputStream)来构造一个ObjectOutputStream(对象流)对象,接着,使用ObjectOutputStream对象的writeObject(Object obj)方法就可以将参数为obj的对象写出(即保存其状态),要恢复的话则用输入流。
8.反射讲一讲,主要是概念,
在 Java 中的反射机制是指在运行状态中,对于任意一个类都能够知道这个类所有的属性和方法;并且对于任意一个对象,都能够调用它的任意一个方法;这种动态获取信息以及动态调用对象方法的功能成为 Java 语言的反射机制。
都在哪需要反射机制,
编译时类型和运行时类型
编译时的类型由声明对象时实用的类型来决定,运行时的类型由实际赋值给对象的类型决定。
Person p=new Student();
其中编译时类型为 Person,运行时类型为 Student。
编译时类型无法获取具体方法
程序在运行时还可能接收到外部传入的对象,该对象的编译时类型为 Object,但是程序有需要调用该对象的运行时类型的方法。为了解决这些问题,程序需要在运行时发现对象和类的真实信息。然而,如果编译时根本无法预知该对象和类属于哪些类,程序只能依靠运行时信息来发现该对象和类的真实信息,此时就必须使用到反射了。
反射的性能如何优化
用于字段和方法接入时反射要远慢于直接代码。
目前最常见的优化反射性能的方法就是采用委托:用委托的方式调用需要反射调用的方法(或者属性、字段)。
那么如何得到委托呢? 目前最常见也就是二种方法:Emit, ExpressionTree 。其中ExpressionTree可认为是Emit方法的简化版本, 所以Emit是最根本的方法,它采用在运行时动态构造一段IL代码来包装需要反射调用的代码, 这段动态生成的代码满足某个委托的签名,因此最后可以采用委托的方式代替反射调用。
二、是操作系统中间件部分
- 说说什么是单例模式
保证整个系统中一个类只有一个对象的实例,实现这种功能的方式就叫单例模式。
- sendRedirect, foward 区别
浏览器地址栏路径sendRedirect发生变化,forward不发生变化。
sendRedirect( "/uu "); 表示相对于服务器根路径。如http://localhost:8080/Test 应用(则提交至http://localhost:8080/uu);
Forward 代码中的 "/uu " 则代表相对与WEB应用的路径。如http://localhost:8080/Test 应用(则提交至http://localhost:8080/Test/uu)
forward()方法在服务器端工作;它只能在服务器内工作。因为它是在服务器内工作,故速度快。
sendRedirect()方法在客户端工作;它可以在服务器内外使用。它可以将响应重定向到另一个资源,这个资源可以是servlet,jsp,或html文件。它接受相对和绝对的url.也因为它是接受url,所以,它可以再服务器内外工作。缺点:速度慢。
- 描述 Cookie 和 Session 的作用、区别和应用范围,
cookie机制采用的是在客户端保持状态的方案,而session机制采用的是在服务器端保持状态的方案。
由于在服务器端保持状态的方案在客户端也需要保存一个标识,所以session机制可能需要借助于cookie机制来达到保存标识的目的,但实际上还有其他选择。
Session用于保存每个用户的专用信息. 每个客户端用户访问时,服务器都为每个用户分配一个唯一的会话ID(Session ID) . 她的生存期是用户持续请求时间再加上一段时间(一般是20分钟左右).Session中的信息保存在Web服务器内容中,保存的数据量可大可小.当 Session超时或被关闭时将自动释放保存的数据信息.由于用户停止使用应用程序后它仍然在内存中保持一段时间,因此使用Session对象使保存用户数据的方法效率很低.对于小量的数据,使用Session对象保存还是一个不错的选择
Cookie 用于保存客户浏览器请求服务器页面的请求信息,程序员也可以用它存放非敏感性的用户信息,信息保存的时间可以根据需要设置.如果没有设置Cookie失效日期,它们仅保存到关闭浏览器程序为止.如果将Cookie对象的Expires属性设置为Minvalue,则表示Cookie永远不会过期.Cookie存储的数据量很受限制,大多数浏览器支持最大容量为4K,因此不要用来保存数据集及其他大量数据.由于并非所有的浏览器都支持Cookie,并且数据信息是以明文文本的形式保存在客户端的计算机中,因此最好不要保存敏感的,未加密的数据,否则会影响网站的安全性。
Session 工作原理。
session机制是一种服务器端的机制,服务器使用一种类似于散列表的结构(也可能就是使用散列表)来保存信息。
(1)当有Session启动时,服务器生成一个唯一值,称为Session ID(好像是通过取进程ID的方式取得的)。
(2)然后,服务器开辟一块内存,对应于该Session ID。
(3)服务器再将该Session ID写入浏览器的cookie。
(4)服务器内有一进程,监视所有Session的活动状况,如果有Session超时或是主动关闭,服务器就释放改内存块。
(5)当浏览器连入IIS时并请求的ASP内用到Session时,IIS就读浏览器Cookie中的Session ID。
(6)然后,服务检查该Session ID所对应的内存是否有效。
(7)如果有效,就读出内存中的值。
- 如果无效,就建立新的Session。
- 列举几个常用的 Linux 命令
ls命令
用来显示目标列表,在Linux中是使用率较高的命令。ls命令的输出信息可以进行彩色加亮显示,以分区不同类型的文件。 -a:显示所有档案及目录(ls内定将档案名或目录名称为“.”的视为影藏,不会列出); -A:显示除影藏文件“.”和“..”以外的所有文件列表;
cd命令
用来切换工作目录。 cd test001切换到当前目录下的test001目录。 cd 直接到当前用户根目录。 cd .. 切换到上一级目录。 cd - 返回进入此目录之前所在的目录;
pwd命令
以路径的方式显示用户当前工作目录。
比如输入pwd命令。[[email protected] ——]# pwd
输出 :/root 即在root根目录。
mkdir命令
用来创建目录。mkdir test,即在当前目录下创建test子目录。
rmdir命令用来删除空目录
rm -f命令删除文件
rm -rf /var/log/httpd/access
将会删除/var/log/httpd/access目录以及其下所有文件、文件夹
删除文件使用实例:
rm -f /var/log/httpd/access.log
将会强制删除/var/log/httpd/access.log这个文件
cp命令
用来将一个或多个源文件或者目录复制到指定的目的文件或目录。它可以将单个源文件复制成一个指定文件名的具体的文件或一个已经存在的目录下。cp命令还支持同时复制多个文件,当一次复制多个文件时,目标文件参数必须是一个已经存在的目录,否则将出现错误。
同一目录下,即是重命名,如cp test001.txt test002.txt相当于是对重命名为test002.txt。指定不同目录则是复制。
mv命令
用来对文件或目录重新命名,或者将文件从一个目录移到另一个目录中。source表示源文件或目录,target表示目标文件或目录。如果将一个文件移到一个已经存在的目标文件中,则目标文件的内容将被覆盖。
mv命令可以用来将源文件移至一个目标文件中,或将一组文件移至一个目标目录中。源文件被移至目标文件有两种不同的结果:
将文件ex3改名为new1
mv ex3 new1
将目录/usr/men中的所有文件移到当前目录中:
mv /usr/men/* .
cat 命令
cat 命令用于连接文件并打印到标准输出设备上。如cat test001.txt 即把test001.txt内容输出显示。
把 textfile1 的文档内容加上行号后输入 textfile2 这个文档里:
cat -n textfile1 > textfile2
把 textfile1 和 textfile2 的文档内容加上行号(空白行不加)之后将内容附加到 textfile3 文档里:
cat -b textfile1 textfile2 >> textfile3
Shutdown -h立即关机
shutdown -r 重启
reboot重启
vi 即打开vi编辑器。vi test001.txt即用vi编辑test001.txt文件。按Esc退出编辑模式。单击i可以回到编辑模式。
:wq:在命令模式下,执行存盘退出操作;
:w:在命令模式下,执行存盘操作;
:w!:在命令模式下,执行强制存盘操作;
:q:在命令模式下,执行退出vi操作;
:q!:在命令模式下,执行强制退出vi操作;
5.介绍一下 XMLHTTPREQUEST对象的常用方法和属性:
open(“method”,”URL”) ; 建立对服务器的调用,第一个参数是HTTP请求 方式可以为GET,POST或任何服务器所支持的您想调用的方式,第二个参数是请求页面的URL
send()方法,发送具体请求给服务器
abort()方法,停止当前请求
setRequestHeader()设置头信息(使用post才会用到,get并不需要调用该方法)
readyState属性请求的状态有5个可取值0=未初始化,1=正在加载2=以加载,3=交互中,4=完成
onreadystatechange 用于监听ajax的工作状态(readyState变化时会调用此方法)
responseText属性 服务器的响应,此属性返回一个字符串响应数据,文本内容
reponseXML 属性 服务器的响应,表示为XML
status 服务器的HTTP状态码,200对应ok 400对应not found
Spring/SpringBoot 框架部分
1.Spring 的核心理念是什么?
控制反转(IOC)和面向切面编程(AOP)
2.解释 Spring 支持的几种 bean 的作用域?
singleton:单例模式,在整个Spring IoC容器中,使用 singleton 定义的 bean 只有一个实例,当spring创建applicationContext容器的时候,spring会欲初始化所有的该作用域实例,加上lazy-init就可以避免预处理。
prototype:原型模式,每次通过容器的getbean方法获取 prototype 定义的 bean 时,都产生一个新的 bean 实例,创建后spring将不再对其管理。
只有在 Web 应用中使用Spring时,request、session、global-session 作用域才有效
request:对于每次 HTTP 请求,使用 request 定义的 bean 都将产生一个新实例,即每次 HTTP 请求将会产生不同的 bean 实例。
session:同一个 Session 共享一个 bean 实例。
global-session:同 session 作用域不同的是,所有的Session共享一个Bean实例。
3.什么是微服务?
微服务架构(MSA)的基础是将单个应用程序开发为一组小型独立服务,这些独立服务在自己的进程中运行,独立开发和部署。
这些服务使用轻量级 API 通过明确定义的接口进行通信。这些服务是围绕业务功能构建的,每项服务执行一项功能。由于它们是独立运行的,因此可以针对各项服务进行更新、部署和扩展,以满足对应用程序特定功能的需求。
程序中的微服务,就是将各个业务系统的共性再进行抽取,做成独立的服务。
4.如何理解 Spring Boot 配置加载顺序?
propertiese文件、YAML文件、系统环境变量、命令行参数。
- 数据持久层部分
1. MyBatis 中#{}和${}的区别是什么?
#{}占位符 和 ${}拼接符
(1)
1)#{} 为参数占位符 ?,即sql 预编译
2)${} 为字符串替换,即 sql 拼接
(2)
1)#{}:动态解析 -> 预编译 -> 执行
2)${}:动态解析 -> 编译 -> 执行
(3)
1)#{} 的变量替换是在DBMS 中
2)${} 的变量替换是在 DBMS 外
(4)
1)变量替换后,#{} 对应的变量自动加上单引号 ''
2)变量替换后,${} 对应的变量不会加上单引号 ''
(5)
1)#{} 能防止sql 注入
2)${} 不能防止sql 注入
2. Mybatis 是如何将 Sql 执行结果封装为目标对象并返回的?都有哪些映射?
第一种是使用<resultMap>标签,逐一定义列名和对象属性名之间的映射关系。
第二种是使用sql列的别名功能,将列别名书写为对象属性名,比如T_NAME AS NAME,对象属性名一般是name,小写,但是列名不区分大小写,Mybatis会忽略列名大小写,智能找到与之对应对象属性名,你甚至可以写成T_NAME AS NaMe,Mybatis一样可以正常工作。
有了列名与属性名的映射关系后,Mybatis通过反射创建对象,同时使用反射给对象的属性逐一赋值并返回,那些找不到映射关系的属性,是无法完成赋值的。
3. Mybatis 如何执行批量插入?
首先,创建一个简单的insert语句:
<insert id=”insertname”>
insert into names (name) values (#{value})
</insert>
然后在java代码中像下面这样执行批处理插入:
list<string> names = new arraylist();
names.add(“fred”);
names.add(“barney”);
names.add(“betty”);
names.add(“wilma”);
// 注意这里 executortype.batch
sqlsession sqlsession=sqlsessionfactory.opensession(executortype.batch);
try {
namemapper mapper = sqlsession.getmapper(namemapper.class);
for (string name : names) {
mapper.insertname(name);
}
sqlsession.commit();
}catch(Exception e){
e.printStackTrace();
sqlSession.rollback();
throw e;
}finally {
sqlsession.close();
}
- 数据部分
1.内连接、左连接、右连接区别?
left join (左连接):返回包括左表中的所有记录和右表中连接字段相等的记录。
right join (右连接):返回包括右表中的所有记录和左表中连接字段相等的记录。
inner join (等值连接或者叫内连接):只返回两个表中连接字段相等的行。
full join (全外连接):返回左右表中所有的记录和左右表中连接字段相等的记录。
2.数据库的事务及特性是什么?
事务是数据库操作最小单元,把多件事当一件事来处理,是一组不可在分割的操作集合。作为单个逻辑工作单元执行一系列操作,这些操作作为一个整体一起向系统提交,要么都执行,要么都不执行。
特性ACID(原子性、一致性、隔离性、持久性)
原子性:原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚,因此事务操作如果成功就必须要完全应用到数据库,如果操作失败则不能对数据库有一点影响。
一致性:一致性是指事务必须使数据库从一个一致性状态转换到另一个一致性状态,就是说事务执行前后都必须处在一致性状态。
隔离性:隔离性使当多个用户访问数据库时,比如操作同一张表,数据库开启的每一个事务,不能被其它事务干扰,多个并发事务之间相互隔离。
持久性:持久性是指一个事务一旦提交,对数据库中数据的改变是永久的,即使是数据库系统遇到故障也不会丢失提交的事务操作。
3.构造 SQL 语句查询员工表 emp 中员工编码 empno,姓名 ename,以及月收入(薪水+奖金),注意有的员工暂时没有奖金。(见附:职员表 emp)
select empno,ename,ifnull(salary,0)+ifnull(bonus,0) money from emp_嘚嘚;
附:职员表 emp
CREATE TABLE emps (empno NUMBER(4) PRIMARY KEY, ename
VARCHAR2(10), job VARCHAR2(9), mgr NUMBER(4), hiredate
DATE, sal NUMBER(7,2), comm NUMBER(7,2), deptno
NUMBER(2));