个人面试小总结之一
基础
值传递和引用传递的区别
值传递:指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,那么我们的实际参数不会改变
引用传递:指在调用函数时将实际参数的地址直接传递到函数中,那么函数中对参数进行修改的时候,也会影响到我们的实际参数。
修饰符的作用与访问类型
private:只能本类
默认:同包下
proptect:同包下+继承了本类的其他类可以
public:全局
final修饰符
- final 变量必须被显示初始化,只能赋值一次;
- final修饰基本类型变量的时候,该变量不能被重新赋值;
- final修饰引用类型变量的时候,该变量不能重新指向其他对象;
- final修饰的方法为最终的方法,该方法不能被重写;
- final修饰的类为超类,不能被继承;
说说static
static本身是静态的意思。
被static关键字修饰的方法或者变量不需要依赖于对象来进行访问,只要类被加载了,就可以通过类名去进行访问。
可以用于类上、方法上、代码块等
静态方法:不用依赖于对象就可以之间进行访问,是没有this关键字,因为不依赖对象且在静态方法中不能访问非静态成员与非静态成员方法 ,但是我们可以在非静态的方法中访问静态资源
静态变量:静态变量被所有的对象所共享,在内存中只有一个,非静态变量是在创建对象的时候被初始化,静态变量被所有的对象所共享
静态代码块:在类初次被加载的时候,会按照static块的顺序来执行每个static块,并且只会执行一次。
多线程的应用场景
-
servlet多线程
-
FTP下载,多线程操作文件
-
数据库用到多线程
框架
SpringBoot或者SpringMVC常用注解
SpringMVC:
@Controller、@Service、@Reqository 标记的类就是一个SpringMVC Controller对象,并检查该方法是否用了@RequestMapping注解。 @RequestMapping才是真正处理请求的处理器
@RequestMapping:是一个用来处理请求地址映射的注解,可用于类或方法上 其中RequestMapping注解有6个属性
- value:指定请求的实际地址
- method:指定请求的method类型,GET、POST(新增)、PUT(修改)、delete(删除)
- consumes
- params:指定request中必须包含特定的参数,才能使用该方法
- headers:指定request中必须包含某些指定的header值。
@Resource与@AutoWired :bean注入的时候使用
Autowired:注解是按照类型(ByType)装配
Resource:是按照ByName装配
@PathVariable:取出uri模板中的变量作为参数
@RequestParam:将请求参数区数据映射到功能处理方法的参数上
@SessionAttributes:将值放到session作用域中,写在Class上
@ResponseBody:用于将Controller的方法返回的对象,转换格式后写入Response对象的body数据区。
@Component:通用注解,
SpringBoot
@SpringBootApplication:核心注解,用在主类,表名是Boot应用
- @Configuration
- @EnableAutoConfiguration
- @ComponentScan三个注解的组合
@EnableAutoConfiguration:开启启动配置,根据当前类路径下的包或者类来配置Spring Bean
@Configuration:用于定义的配置类,指出该类是bean配置的信息源,相当于xml配置文件
也可以@ImportResource
注解加载xml配置文件
@ComponentScan:让boot扫描到Configuration类并把它加入到上下文
@ConfigurationProperties:将自定义的properties文件映射到实体bean中,比如config.properties文件
@Repository、Service
@RestController:是@Controller和ResponseBody的合集 (表示是控制器bean,并且是将函数的返回值直接填入Http的响应体中。
@ResponseBody:将结果直接写入Http的响应体中
@Component:泛指组件
@bean:相当于XML中的
@AutoWired:byType方式。把配置好的Bean拿来用,完成属性、方法的组装,它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。
@Qualifier:当有多个同一类型的bean时,可以用@qualifier(”name“)来指定具体的
@requestMapping:负责URL到Controller中的具体函数的映射,可用于类或方法上
@Transactional:可以声明事务,可以添加在类上或者方法上
@Profiles:提供了一种隔离应用程序配置的方法
SpringBoot中properties和yml的区别
Spring的IOC与AOP
Spring中AOP的应用场景与注入方式
场景:
- 记录日志
- 权限控制
- 缓存优化(第一次调用查询数据库,将查询结果放入内存对象, 第二次调用, 直接从内存对象返回,不需要查询数据库)
- 事务管理(调用方法前开启事务, 调用方法后提交关闭事务)
注入方式:
基于xml配置开发
自定义实现AOP
注解方式
SpringBoot中Bean注入的方式
- @ComponentScan+@组件标注注解
- @Configuration+@Bean
- @Import 快速给容器中导入组件 id默认是全类名
集合
list和set(cotnection)区别
list可以插入多个null元素,set只允许插入一个null元素
list容器是有序的,set是无序的
list可以允许重复的对象,set不允许重复的对象
list方法常用的实现类有ArrayList、LinkedList 和 Vector。
Set方法中最流行的几个实现类是 HashSet、LinkedHashSet 以及 TreeSet
HashMap和HashTable
HaspMap与HashTable都实现了Map接口
不同点:
第一:线程安全性不同,HashMap线程不安全,HashTable中的方法都是Synchronized修饰的。
第二:key、value是否运行null。 HashMap的key与Value都可以是null,但是key只允许一个null; Hashtable的key与value都不能为null
第三:迭代器不同
第四:hash的计算方式,HashMap计算了hash值;Hashtable使用了key的hashCode方法
第五点: HashMap把Hashtable的contains方法去掉了,改成containsValue和containsKey,因为contains方法容易让人引起误解。
JVM
JVM的运行时分区空间
方法区:存储了每个类的信息(包括类的名称、方法信息、字段信息)、静态变量、常量以及编译器编译后的代码等,类加载器将 .class 文件加载到运行时数据区时就是先丢到这一块上面。
堆:和方法区同属性线程共享区域,主要放了一下存储数据,如:对象实例、数组等 JVM只有一个堆
栈:内存模型,存放的是一个个栈帧,每一个栈帧对应一个被调用的方法
本地方法栈:可以看到它的start()方法带有一个native关键字修饰,而且不存在方法体,这种用native修饰的方法就是本地方法。本地方法栈则是为执行本地方法(Native Method)服务的
JVM的GC方法?
引用计数法:每个对象在创建的时候,就给这个对象绑定一个计数器。每当有一个引用指向该对象时,计数器加一;每当有一个指向它的引用被删除时,计数器减一。这样,当没有引用指向该对象时,该对象死亡,计数器为0,这时就应该对这个对象进行垃圾回收操作。
优点:简单、代价分散
缺点:不全面(容易漏掉循环引用的对象) 占用额外内存空间
标记-清除法:每个对象存储一个标记位,记录对象的状态(活着或是死亡)。分为两个阶段,一个是标记阶段,这个阶段内,为每个对象更新标记位,检查对象是否死亡;第二个阶段是清除阶段,该阶段对死亡的对象进行清除,执行 GC
操作。
优点:
相比于引用计数法,标记—清除算法中每个活着的对象的引用只需要找到一个即可,找到一个就可以判断它为活的。
缺点:判断对象是否死亡,消耗了很多时间
每个对象都要去标识检查,复杂度高
标记-整理法:在标记阶段,该算法也将所有对象标记为存活和死亡两种状态;不同的是,在第二个阶段,该算法并没有直接对死亡的对象进行清理,而是将所有存活的对象整理一下,放到另一处空间,然后把剩下的所有对象全部清除。
优点:不会像标记-清除法那样 产生大量的碎片空间
缺点:如果存活对象多,整理阶段就会执行较多复制操作,导致算法效率低。
可达性分析:通过一种GC ROOT的对象(虚拟机栈(栈帧中的本地变量表)中引用的对象、方法区中类静态属性引用的对象、方法区中常量引用的对象、本地方法栈中JNI(即一般说的Native方法)引用的对象)来判断,如果有一条链能够到达GC ROOT就说明,对象还在被引用,不能到达GC ROOT就说明对象已经不再被引用,可以回收
JDK1.8的什么。。
MyByatis
${ } 和#
#是预编译处理、是占位符
eg:select id,name,age from student where id =#{id},当前端把id值1,传入到后台的时候,就相当于 select id,name,age from student where id ='1'.
$字符串替换、是拼接符。
eg:select id,name,age from student where id =${id},当前端把id值1,传入到后台的时候,就相当于 select id,name,age from student where id = 1.
{}的变量替换是发生在DBMS中的,变量替换后,#{}对应的变量自动加上单引号
${}的变量替换是在DBMS之外,替换后,对应的变量不会加上单引号。
#可以很大程度上防止sql注入
Mybatis如何一次性插入一万条数据
循环插入
foreach插入
使用ExecutorType 分批插入 (批处理)
//我们使用的是springboot,sqlSessionTemplate是可以自己注入的
@Autowired
private SqlSessionTemplate sqlSessionTemplate;
public void insertExcelData(List<User> list) {
//如果自动提交设置为true,将无法控制提交的条数,改为最后统一提交,可能导致内存溢出
SqlSession session = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH, false);
//不自动提交
try {
UserDao userDao = session.getMapper(UserDao.class);
for (int i = 0; i < list.size(); i++) {
userDao.insert(list.get(i));
if (i % 400 == 0 || i == list.size() - 1) {
//手动每400条提交一次,提交后无法回滚
session.commit();
//清理缓存,防止溢出
session.clearCache();
}
}
} catch (Exception e) {
//没有提交的数据可以回滚
session.rollback();
} finally {
session.close();
}
}
userDao.insert(User user);
<insert id="insert" parameterType="com.echo.UserPo">
insert into USER
(id
<if test="age != null">
,age
</if>
<if test="name != null">
,name
</if>
<if test="email != null">
,email
</if>
)
values (
sys_guid()
<if test="age != null">
,#{age}
</if>
<if test="name != null">
,#{name}
</if>
<if test="email != null">
,#{email}
</if>)
</insert>
MyBati中select from where || group by || oderBy 的执行顺序
我们平常写的语句:
1. SELECT
2. DISTINCT <select_list>
3. FROM <left_table>
4. <join_type> JOIN <right_table>
5. ON <join_condition>
6. WHERE <where_condition>
7. GROUP BY <group_by_list>
8. HAVING <having_condition>
9. ORDER BY <order_by_condition>
10.LIMIT <limit_number>
但是Mybatis的执行条件是
FROM
<表名> # 笛卡尔积
ON
<筛选条件> # 对笛卡尔积的虚表进行筛选
JOIN <join, left join, right join...>
<join表> # 指定join,用于添加数据到on之后的虚表中,例如left join会将左表的剩余数据添加到虚表中
WHERE
<where条件> # 对上述虚表进行筛选
GROUP BY
<分组条件> # 分组
<SUM()等聚合函数> # 用于having子句进行判断,在书写上这类聚合函数是写在having判断里面的
HAVING
<分组筛选> # 对分组后的结果进行聚合筛选
SELECT
<返回数据列表> # 返回的单列必须在group by子句中,聚合函数除外
DISTINCT
# 数据除重
ORDER BY
<排序条件> # 排序
LIMIT
<行数限制>
数据库
开启事务的命令
begin? start transaction
事务
ACID原则
脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据
不可重复读:前后多次读取,数据内容不一致
幻读:前后多次读取,数据总量不一致
隔离级别