文章目录
一、数据结构与算法
1)、数据结构
-
List 有顺序可以重复
- ArrayList 数组
- LinkedList 链表
- Vector 数组 线程安全,队列
-
Set 没有顺序不可以重复
- HashSet 其实底层是用 HashMap 的key来存储的。
- LinkedHashSet 双向链表
- sortedSet 接口
- TreeSet 红黑树 平衡的排序二叉树
- HashSet 其实底层是用 HashMap 的key来存储的。
-
Map 键值对
- Hashtable 结构和 HashMap 一样 是同步的 在多线程环境下没有安全问题。效率低
- Properties
- HashMap 1.7之前数组+链表 1.8 数组+链表+红黑树
- LinkedHashMap 先进先出
- SortedMap
- TreeMap 红黑树
- Hashtable 结构和 HashMap 一样 是同步的 在多线程环境下没有安全问题。效率低
2)、算法
1. 排序
- 冒泡排序
- 选择排序
- 插入排序
- 希尔排序
- 快速排序
- 归并排序
- 基数排序
2. 查找
不需要排序:
- 顺序查找
需要先排序:
- 折半查找
- 插值查找
- 斐波那契查找
二、java基础+线程
java基础
== and equals()
概述:
== 比较的是引用是否相等,也就是比较的地址(HashCode) 常量 (八种数据类型) 只有一个引用地址,不管是再多的 123,“123” 这样的数据都只会存储一个地址,所以他们的引用是指向通一个地址,因此基本数据的常量和 String 的常量可以用 == 来直接比较。
- 八种数据类型是常量 boolean byte short char int float double long
- String str = “”; 这样定义的String 是常量
- Byte,Short,Integer,Long,Character 这5种整型的包装类的对象池范围在 -128-127 之间 超出这个范围的对象都会开辟自己的堆内存。
equals 如果自己所写的类中已经重写了equals方法,那么就按照用户自定义的方式来比较俩个对象是否相等,如果没有重写过equals方法,那么会调用父类(Object)中的equals方法进行比较,也就是比较地址值。
- String 重写过。
- 八种基本数据类型包装类重写过。
1)、创建和启用多线程
Thread/Runnable
1.多线程安全的类
2)、死锁
概述:
死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。
A:java 死锁产生的四个必要条件
1、互斥使用,即当资源被一个线程使用(占有)时,别的线程不能使用
2、不可抢占,资源请求者不能强制从资源占有者手中夺取资源,资源只能由资源占有者主动释放。
3、请求和保持,即当资源请求者在请求其他的资源的同时保持对原有资源的占有。
4、循环等待,即存在一个等待队列:P1占有P2的资源,P2占有P3的资源,P3占有P1的资源。这样就形成了一个等待环路。
B:产生原因
1、竞争资源引起进程死锁
2、可剥夺资源和不可剥夺资源
3、竞争不可剥夺资源
4、竞争临时资源
3)、避免(预防)和解决死锁
破坏掉死锁形成的条件就可以避免死锁,第一个条件建议保留,因为一个资源如果可以被多个线程同时使用的话会有可能造成数据的 脏读、幻读的一些不必要的问题
1.死锁预防
2.解决方法
三、Mysql优化
1)、存储结构优化
- 选择最合适的字段属性
- 尽量把字段设置为NOT NULL
- 外键
2)、查询优化
- 使用索引
- 使用连接(JOIN)来代替子查询(Sub-Queries)
- 使用联合(UNION)来代替手动创建的临时表
- 采用事务查询,(因为我们在查询中可能会有一些查询会失败)
- 锁定表
四、Jvm内存模型
考点背诵:
首先要说一下JVM内存空间分为五部分,分别是:方法区、堆、Java虚拟机栈、本地方法栈、程序计数器
方法区主要用来存放类信息、类的静态变量、常量、运行时常量池等,方法区的大小是可以动态扩展的,
堆主要存放的是数组、类的实例对象、字符串常量池等。
Java虚拟机栈是描述JAVA方法运行过程的内存模型,Java虚拟机栈会为每一个即将执行的方法创建一个叫做“栈帧”的区域,该区域用来存储该方法运行时需要的一些信息,包括:局部变量表、操作数栈、动态链接、方法返回地址等。比如我们方法执行过程中需要创建变量时,就会将局部变量插入到局部变量表中,局部变量的运算、传递等在操作数栈中进行,当方法执行结束后,这个方法对应的栈帧将出栈,并释放内存空间。栈中会发生的两种异常,StackOverFlowError和OutOfMemoryError,StackOverFlowError表示当前线程申请的栈超过了事先定好的栈的最大深度,但内存空间可能还有很多。 而OutOfMemoryError是指当线程申请栈时发现栈已经满了,而且内存也全都用光了。
本地方法栈结构上和Java虚拟机栈一样,只不过Java虚拟机栈是运行Java方法的区域,而本地方法栈是运行本地方法的内存模型。运行本地方法时也会创建栈帧,同样栈帧里也有局部变量表、操作数栈、动态链接和方法返回地址等,在本地方法执行结束后栈帧也会出栈并释放内存资源,也会发生OutOfMemoryError。
程序计数器,程序计数器是一个比较小的内存空间,用来记录当前线程正在执行的那一条字节码指令的地址。如果当前线程正在执行的是本地方法,那么此时程序计数器为空。程序计数器有两个作用
- 字节码解释器通过改变程序计数器来一次读取指令,从而实现代码的流程控制,比如我们常见的顺序、循环、选择、异常处理等。
- 在多线程的情况下,程序计数器用来记录当前线程执行的位置,当线程切换回来的时候仍然可以知道该线程上次执行到了哪里。而且程序计数器是唯一一个不会出现OutOfMeroryError的内存区域。
方法区和堆都是线程共享的,在JVM启动时创建,在JVM停止时销毁,而Java虚拟机栈、本地方法栈、程序计数器是线程私有的,随线程的创建而创建,随线程的结束而死亡。
原文链接
五、Redis相关
1)、数据类型及其作用
- List (LinkList) 列表数据显示、关注列表、粉丝列表、留言评价
- Z-set 有序集合(sorted set) 销量排名,积分排名等
- Hash Object (Map) (存储一个用户信息对象数据)
- String (java-String) 单个字符串或JSON字符串数据 二进制安全 可以把一个图片 文件的内容作为字符串来存储 微博数,粉丝数)
- Set Set是String类型的无序集合。集合成员是唯一的 对两个集合间的数据[计算]进行交集、集、差集运算
六、Linux常用命令
1)、See look and command
ls 显示文件或目录
-l 列出文件详细信息l(list)
-a 列出当前目录下所有文件及目录,包括隐藏的a(all)
mkdir 创建目录
-p 创建目录,若无父目录,则创建p(parent)
cd 切换目录
touch 创建空文件
echo 创建带有内容的文件。
cat 查看文件内容
cp 拷贝
mv 移动或重命名
rm 删除文件
-r 递归删除,可删除子目录及文件
-f 强制删除
find 在文件系统中搜索某文件
wc 统计文本中行数、字数、字符数
grep 在文本文件中查找某个字符串
rmdir 删除空目录
tree 树形结构显示目录,需要安装tree包
pwd 显示当前目录
ln 创建链接文件
more、less 分页显示文本文件内容
head、tail 显示文件头、尾内容
ctrl+alt+F1 命令行全屏模式
2)、Edit
vim三种模式:命令模式、插入模式、编辑模式。使用ESC或i或:来切换模式。
命令模式下:
:q 退出
:q! 强制退出
:wq 保存并退出
:set number 显示行号
:set nonumber 隐藏行号
/apache 在文档中查找apache 按n跳到下一个,shift+n上一个
yyp 复制光标所在行,并粘贴
h(左移一个字符←)、j(下一行↓)、k(上一行↑)、l(右移一个字符→)
3)、System
stat 显示指定文件的详细信息,比ls更详细
who 显示在线登陆用户
whoami 显示当前操作用户
hostname 显示主机名
uname 显示系统信息
top 动态显示当前耗费资源最多进程信息
ps 显示瞬间进程状态 ps -aux
du 查看目录大小 du -h /home带有单位显示目录信息
df 查看磁盘大小 df -h 带有单位显示磁盘信息
ifconfig 查看网络情况
ping 测试网络连通
netstat 显示网络状态信息
man 命令不会用了,找男人 如:man ls
clear 清屏
alias 对命令重命名 如:alias showmeit="ps -aux" ,另外解除使用unaliax showmeit
kill 杀死进程,可以先用ps 或 top命令查看进程的id,然后再用kill命令杀死进程。
4)、Compress zip
gzip:
bzip2:
tar: 打包压缩
-c 归档文件
-x 压缩文件
-z gzip压缩文件
-j bzip2压缩文件
-v 显示压缩或解压缩过程 v(view)
-f 使用档名
例:
tar -cvf /home/abc.tar /home/abc 只打包,不压缩
tar -zcvf /home/abc.tar.gz /home/abc 打包,并用gzip压缩
tar -jcvf /home/abc.tar.bz2 /home/abc 打包,并用bzip2压缩
当然,如果想解压缩,就直接替换上面的命令 tar -cvf / tar -zcvf / tar -jcvf 中的“c” 换成“x” 就可以了。
5)、Restart
shutdown
-r 关机重启
-h 关机不重启
now 立刻关机
halt 关机
reboot 重启
6)、Install and unload
dpkg (Debian Package)管理工具,软件包名以.deb后缀。这种方法适合系统不能联网的情况下。
比如安装tree命令的安装包,先将tree.deb传到Linux系统中。再使用如下命令安装。
sudo dpkg -i tree_1.5.3-1_i386.deb 安装软件
sudo dpkg -r tree 卸载软件
注:将tree.deb传到Linux系统中,有多种方式。VMwareTool,使用挂载方式;使用winSCP工具等;
APT(Advanced Packaging Tool)高级软件工具。这种方法适合系统能够连接互联网的情况。
依然以tree为例
sudo apt-get install tree 安装tree
sudo apt-get remove tree 卸载tree
sudo apt-get update 更新软件
sudo apt-get upgrade
将.rpm文件转为.deb文件
.rpm为RedHat使用的软件格式。在Ubuntu下不能直接使用,所以需要转换一下。
sudo alien abc.rpm
7)、Other command
/etc/passwd 存储用户账号
/etc/group 存储组账号
/etc/shadow 存储用户账号的密码
/etc/gshadow 存储用户组账号的密码
useradd 用户名
userdel 用户名
adduser 用户名
groupadd 组名
groupdel 组名
passwd root 给root设置密码
su root
su - root
/etc/profile 系统环境变量
bash_profile 用户环境变量
.bashrc 用户环境变量
su user 切换用户,加载配置文件.bashrc
su - user 切换用户,加载配置文件/etc/profile ,加载bash_profile
更改文件的用户及用户组
sudo chown [-R] owner[:group] {File|Directory}
例如:还以jdk-7u21-linux-i586.tar.gz为例。属于用户hadoop,组hadoop
要想切换此文件所属的用户及组。可以使用命令。
sudo chown root:root jdk-7u21-linux-i586.tar.gz
七、Spring
你觉得面试会问关于Spring 的什么内容。你觉得是下面的问题吗 >.<
- 什么是spring?
- 使用Spring框架的好处
是以下内容才对
7. 解释一下AOP模块
AOP(Aspect Oriented Programming,面向切面编程)是Spring另一个重要特征。AOP把一个业务流程分成几个部分,例如:日志记录、权限检查、业务处理等,然后把它们组装成完整的业务流程。每个部分被称为切面(Aspect)
是采用动态代理实现的,动态代理又可以分为jdk 动态代理,还有是cglib动态代理,jdk是可以代理接口和类的,cglib只能代理类。
13. 什么是Spring IOC 容器?
Spring IOC 负责创建对象,管理对象(通过依赖注入(DI),装配对象,配置对象,并且管理这些对象的整个生命周期。
14. IOC的优点是什么?
IOC 或 依赖注入把应用的代码量降到最低。它使应用容易测试,单元测试不再需要单例和JNDI查找机制。最小的代价和最小的侵入性使松散耦合得以实现。IOC容器支持加载服务时的饿汉式初始化和懒加载。
19. 有哪些不同类型的IOC(依赖注入)方式?
- 构造器依赖注入:构造器依赖注入通过容器触发一个类的构造器来实现的,该类有一系列参数,每个参数代表一个对其他类的依赖。
- Setter方法注入:Setter方法注入是容器通过调用无参构造器或无参static工厂 方法实例化bean之后,调用该bean的setter方法,即实现了基于setter的依赖注入。
18. 什么是Spring的依赖注入?
依赖注入,是IOC的一个方面,是个通常的概念,它有多种解释。这概念是说你不用创建对象,而只需要描述它如何被创建。你不在代码里直接组装你的组件和服务,但是要在配置文件里描述哪些组件需要哪些服务,之后一个容器(IOC容器)负责把他们组装起来。
21.什么是Spring beans?
Spring beans 是那些形成Spring应用的主干的java对象。它们被Spring IOC容器初始化,装配,和管理。这些beans通过容器中配置的元数据创建。比如,以XML文件中 的形式定义。
Spring 框架定义的beans都是单件beans。在bean tag中有个属性”singleton”,如果它被赋为TRUE,bean 就是单件,否则就是一个 prototype bean。默认是TRUE,所以所有在Spring框架中的beans 缺省都是单件。
26. Spring框架中的单例bean是线程安全的吗?
不,Spring框架中的单例bean不是线程安全的。
31. 什么是bean装配?
装配,或bean 装配是指在Spring 容器中把bean组装到一起,前提是容器需要知道bean的依赖关系,如何通过依赖注入来把它们装配到一起。
32. 什么是bean的自动装配?
Spring 容器能够自动装配相互合作的bean,这意味着容器不需要和配置,能通过Bean工厂自动处理bean之间的协作。
1. ioc 的执行流程
首先会根据 @component 注解来扫描这个类,然后就会去生成一个类的 beanDefinition ,这个beanDefinition bean 的描述文件 会记录这个类的一些特征,比如说是你这个对象的类型是什么,单例还是原型,是不是依赖一些其他的 bean 你的初始化方法,是不是懒加载的。基于这些类型然后去实例化一个对象。
容器中的每一个bean都会有一个对应的
BeanDefinition
实例,该实例负责保存bean对象的所有必要信息,包括bean对象的class类型、是否是抽象类、构造方法和参数、其它属性等等。当客户端向容器请求相应对象时,容器就会通过这些信息准备一个完整可用的bean实例返回给客户端。
八、Spring Mvc
九、MyBatis
2. Hibernate 和 MyBatis 的区别
相同点
都是对jdbc的封装,都是持久层的框架,都用于Dao层的开发。
不同点
映射关系
- MyBatis 是一个半自动映射的框架,配置Java对象与sql语句执行结果的对应关系,多表关联关系配置简单
- Hibernate 是一个全表映射的框架,配置Java对象与数据库表的对应关系,多表关联关系配置复杂
SQL优化和移植性
Hibernate 对SQL语句封装,提供了日志、缓存、级联(级联比 MyBatis 强大)等特性,此外还提供 HQL(Hibernate Query Language)操作数据库,数据库无关性支持好,但会多消耗性能。如果项目需要支持多种数据库,代码开发量少,但SQL语句优化困难。
MyBatis 需要手动编写 SQL,支持动态 SQL、处理列表、动态生成表名、支持存储过程。开发工作量相对大些。直接使用SQL语句操作数据库,不支持数据库无关性,但sql语句优化容易。
总结
MyBatis 是一个小巧、方便、高效、简单、直接、半自动化的持久层框架,
Hibernate 是一个强大、方便、高效、复杂、间接、全自动化的持久层框架。
3. 工作原理
MyBatis通过配置文件创建SqlsessionFactory,SqlsessionFactory根据配置文件,配置文件来源于两个方面:一个是xml,一个是Java中的注解,获取SQLSession。SQLSession包含了执行sql语句的所有方法,可以通过SQLSession直接运行映射的sql语句,完成对数据的增删改查和事物的提交工作,用完之后关闭SQLSession。
4. MyBatis编程步骤是什么样的?
1、 创建SqlSessionFactory
2、 通过SqlSessionFactory创建SqlSession
3、 通过SqlSession执行数据库操作
4、 调用session.commit()提交事务
5、 调用session.close()关闭会话
5. MyBatis的缓存
MyBatis的查询缓存分为一级缓存和二级缓存,一级缓存是SQLSession级别的缓存,二级缓存时mapper级别的缓存,二级缓存是多个SqlSession共享的。MyBatis通过缓存机制减轻数据压力,提高数据库性能。
一级缓存: 梗概
MyBatis的一级缓存是SQLSession级别的缓存,在操作数据库时需要构造SqlSession对象,在对象中有一个HashMap用于存储缓存数据,不同的SqlSession之间缓存数据区域(HashMap)是互相不影响的。
详解:一级缓存的作用域是SqlSession范围的,当在同一个SqlSession中执行两次相同的sql语句时,第一次执行完毕会将数据库中查询的数据写到缓存(内存)中,第二次查询时会从缓存中获取数据,不再去底层进行数据库查询,从而提高了查询效率。需要注意的是:如果SqlSession执行了DML操作(insert、update、delete),并执行commit()操作,MyBatis则会清空SqlSession中的一级缓存,这样做的目的是为了保证缓存数据中存储的是最新的信息,避免出现脏读现象。
总结: 当一个SqlSession结束后该SqlSession中的一级缓存也就不存在了,MyBatis默认开启一级缓存,不需要进行任何配置。
二级缓存: 梗概
二级缓存是mapper级别的缓存,使用二级缓存时,多个SqlSession使用同一个Mapper的sql语句去操作数据库,得到的数据会存在二级缓存区域,相比一级缓存SqlSession,二级缓存的范围更大,多SqlSession可以共用二级缓存,二级缓存是跨SqlSession的。
详解:二级缓存是多个SqlSession共享的,其作用域是mapper的同一个namespace,不同的SqlSession两次执行相同的namespace下的sql语句,且向sql中传递的参数也相同,即最终执行相同的sql语句,则第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次查询时会从缓存中获取数据,不再去底层数据库查询,从而提高查询效率。
总结: MyBatis默认没有开启二级缓存,需要在setting全局参数中配置开启二级缓存。
6、#{}和${}的区别是什么?
#{}是占位符,预编译处理;${}是拼接符,字符串替换,没有预编译处理。
MyBatis在处理#{}时,#{}传入参数是以字符串传入,会将SQL中的#{}替换为?号,调用PreparedStatement的set方法来赋值。
MyBatis在处理${}时,是原值传入,就是把{}时,是原值传入,就是把时,是原值传入,就是把{}替换成变量的值,相当于JDBC中的Statement编译
变量替换后,#{} 对应的变量自动加上单引号 ‘’;变量替换后,${} 对应的变量不会加上单引号 ‘’
#{} 可以有效的防止SQL注入,提高系统安全性;${} 不能防止SQL 注入
#{} 的变量替换是在DBMS 中;${} 的变量替换是在 DBMS 外
7、Xml映射文件中,除了常见的select|insert|update|delete标签之外,还有哪些标签?
还有很多其他的标签,、、、、,加上动态sql的9个标签,trim|where|set|foreach|if|choose|when|otherwise|bind等,其中为sql片段标签,通过标签引入sql片段,为不支持自增的主键生成策略标签。
8. 模糊查询like语句该怎么写
(1)’%${question}%’ 可能引起SQL注入,不推荐
(2)"%"#{question}"%" 注意:因为#{…}解析成sql语句时候,会在变量外侧自动加单引号’ ',所以这里 % 需要使用双引号" ",不能使用单引号 ’ ',不然会查不到任何结果。
(3)CONCAT(’%’,#{question},’%’) 使用CONCAT()函数,推荐
(4)使用bind标签
<select id="listUserLikeUsername" resultType="com.jourwon.pojo.User"> <bind name="pattern" value="'%' + username + '%'" /> select id,sex,age,username,password from person where username LIKE #{pattern} </select>
9、MyBatis是如何进行分页的?分页插件的原理是什么?
MyBatis使用RowBounds对象进行分页,它是针对ResultSet结果集执行的内存分页,而非物理分页,可以在sql内直接书写带有物理分页的参数来完成物理分页功能,也可以使用分页插件来完成物理分页。
分页插件的基本原理是使用MyBatis提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的sql,然后重写sql,根据dialect方言,添加对应的物理分页语句和物理分页参数。
举例:select * from student,拦截sql后重写为:select t.* from (select * from student)t limit 0,10
11、MyBatis动态sql是做什么的?都有哪些动态sql?能简述一下动态sql的执行原理不?
1)Mybatis动态sql可以让我们在Xml映射文件内,以标签的形式编写动态sql,完成逻辑判断和动态拼接sql的功能。
2)Mybatis提供了9种动态sql标签:trim|where|set|foreach|if|choose|when|otherwise|bind。
3)其执行原理为,使用OGNL从sql参数对象中计算表达式的值,根据表达式的值动态拼接sql,以此来完成动态sql的功能。
12. 在mapper中如何传递多个参数
- 顺序传参法
user_name = #{0}
- @Param注解传参法
selectUser(@Param("userName") String name)
- Map传参法
User selectUser(Map<String, Object> params);``````user_name = #{userName}
- Java Bean传参法 #{}里面的名称对应的是User类里面的成员属性。