网站首页 > 精选教程 正文
1.数据类型有哪些
整数类型
byte (字节) 1字节 8位 -127 -- 128
short (短整型) 2字节 16位
int (整型) 4字节 32位
long (长整型) 8字节 64位
小数类型
float (单精度) 4字节 32位
double (双精度) 8字节 64 位
字符类型
char (字符型) 2字节 16 位
布尔类型
boolean (布尔型) 1位 true/false
2.String 常用方法
.equals // 字符串比较
.length // 字符串长度
.replace // 字符串替换
.indexOf // 返回指定字符的索引
.substring // 截取 字符串
.toLowerCase // 将字符串转成小写字母
.toUpperCase // 将字符串转成大写字母
3.Spring、SpringBuffer、StringBuilder 区别
String、StringBuffer、StringBuilder 都是操作字符串的类;
String 声明的是不可变对象,每次操作都会生成新的 String 对象,指针指向新的 String 对象;底层有 final 修饰;
StringBuffer。StringBuilder 可以在原有对象的基础上进行操作,可以改变字符串内容
StringBuilder 是线程不安全的,StringBuffer 是线程安全的,StringBuilfer 性能上高于 StringBuffer;单线程建议 StringBuilfer,多线程就是 StringBuffer;
4.== 和 equals 区别
== 使用来判断两个变量之间的值是否相等,变量可分为基本数据类型 和 引用数据类型;如果是基本数据类型就是 值比较,如果是引用数据类型就是 地址比较;
equals 用来比较两个对象长得是否一样,判断两个对象的某些特征是否一样;字符串基本使用 equals;
Integer 10 = Integer 10 /true --- 自动拆箱
Integer 1000 = Integer 1000 /false -- 不自动拆箱
5.设计模式有那些
单例模式
(懒汉模式、饿汉模式)
代理模式
动态代理
JDK 实现、CGLIB 实现
接口就使用 JDK,没有就用 CGLIB,也可以强制使用 CGLIB
静态代理
工厂模式
Spring IOC 就是使用了 工厂模式
适配器模式
类的适配器模式
对象的适配器模式
接口的适配器模式
装饰者模式
6.抽象类 和 接口 区别
- 抽象类可以有构造方法,接口不能有
- 类可以实现多个接口,只能继承一个抽象类
- 接口方法默认使用 public 修饰,抽象类中方法可以任意访问修饰符
- 一个类 可以被多重实现,抽象类只能被单继承
都可以被继承
都可以被实例化
都可以包含方法声明
7.抽象类必须要有抽象方法吗?
不需要;抽象类不一定非要有抽象方法,写一个普通方法也可以运行;
8.抽象类能使用 final 修饰吗?
不能;
定义抽象类就是为了让其他类继承的,如果 final 修饰就不能被继承,相互矛盾,所以 final 不能修饰抽象类,编辑器会直接提示错误;
9.抽象类 和 普通类 区别
普通类 不能包含 抽象方法,抽象类可以包含抽象方法;
抽象类不能被直接实例化,普通类可以直接实例化;
10.& 和 && 区别
& 和 && 都可以用作逻辑与运算符,表示 与(and),当运算符两边的表达式的结果都为 true 时,整个运算结果才为 true,否则只要有一方为 false,则结果为 false
&& 具有短路功能,即如果第一个表达式为 false,则不计算第二个表达式。&会运算
比如:
if ( x == 1 && ++y > 0 ) y 不变
if ( x == 1 & ++y > 0 ) y 增加
11.两个对象 hashCode 相同,则equals 也一定为 true 吗?
不对,两个对象的 hashcode 相同,equals 不一定 true
String str1 = "通话";
String str2 = "重地";
System.out.println(String.format("str1:%d | str2:%d", str1.hashCode(),str2.hashCode()));
System.out.println(str1.equals(str2));
// str1:1179395 | str2:1179395
// false
/*
解读代码:很显然 通话 和 重地 的hashcode 相同,然而 equals 则为false ,因为在散列表中,
hashcode 相等即两个键值对的哈希值相等,然而哈希值想等,并不一定能得出键值对相等;
*/
12.常见异常
空指针异常 --- NullPointerException
数据类型转换异常 --- ClassCastException
算数异常 --- ArithmeticException
下标越界异常 --- IndexOutOfBoundsException
IO流异常 --- IOException
运行时异常 --- RuntimeException
不支持的操作异常 --- UnsupportedOperationException
13.throw 和 throws 区别
throw :是指抛出的一个具体的异常类型;一定在方法里,是异常类型,主动;
throws :用来声明一个方法可能抛出的所有异常信息,throws 是将异常声明但是不处理,而是将异常往上传,谁调用就交给谁处理;在方法头,抛出异常对象,被动;
14.final 在 java 中有什么作用
final 修饰的类叫最终类,该类不能被继承
final 修饰的方法不能被重写
final 修饰的变量叫常量,常量必须初始化,初始化之后值不能被修改
15.final、finally、finalize 区别
final:可以修饰类,方法,变量,修饰类表示该类不能被继承,修饰方法表示该方法不能被重写,修饰变量表示该变量是一个常量,不能被重新赋值;
finally:一般用在 try-catch 代码块中,在处理异常的时候,通常我们将一定要执行的代码方法放在 finally 代码块中,表示不管是否又出现异常,改代码块都会执行,一般用来存放一些关闭资源的代码;
finalize:是一个方法,属于 Object 类的一个方法,而 Object 类是所有类的父类,该方法一般由垃圾回收器来调用,当我们调用 System 的 gc() 方法的时候,由垃圾处理器调用 finalize() ,回收垃圾;
16.重载 和 重写 区别
重写:子类集成父类的所有方法【方法名,参数,返回值相同,但是方法体进行重写】
重载:就是同一个类中,同名方法,参数不同,参数个数不同,顺序不同
17.session 和 cookie 区别
cookie 数据存放在客户端的浏览器上,session 数据存放在服务器上;
单个 cookie 保存的数据不能超过 4k
session 放访问增多,会占用服务器的性能
cookie 不是很安全,可以分析存放的 cookie 进行 cookie 欺骗
登录信息等重要信息存放在 session
18.cookie 被禁用了怎么办?
cookie 被禁用了,就重写 url,在请求的最后加上 session_id,一般被禁用了就给用户弹出友情提示框;
19.如何解决跨域
Nginx 反向代理
从浏览器的同源策略的限制角度考虑。即浏览器的访问前端页面和后端接口的IP 主机相同,Post 接口相同,这样的前端页面的请求就不会出现跨域问题
ajax 中 jsonp.js 里面解决
SSM
通过服务器设置接口响应头 Header 允许接口被跨域请求,那么服务器即允许接口被跨域访问,不同源的前端页面也可以调用该接口
Spring 中 注解 @CrossOrign
自定义拦截器,对每个请求 response header,spring 自带的 cors 标签进行 xml 配置。web.xml 中通过 fifter 设置
20.http 中 get 和 post 区别
- Get 请求提交数据会在地址栏显示出来 ,Post 请求不会在地址栏显示;
- 传输数据的大小,Get请求由于浏览器对地址栏长度的限制导致传输数据有限;Post 不限
- 安全性,Post 的安全性要比 Get 安全性高,因为数据地址呈现相关
21.Servlet 生命周期
加载 class ----- 实例化 ---- 初始化 init ---- 响应请求 service ---- 关闭/销毁 destroy
Servlet 启动时,开始加载 servlet 生命周期开始,Servlet 被服务器实例化后,容器运行其 init 方法。请求到达时运行其 service 方法,service 方法自动派遣运行与请求对应的doxxxx方法(doGet,doPost)等,当服务器决定将实例销毁的时候(服务器关闭)调用其 destroy 方法;
22.重定向 和 转发 区别
转发:
1.地址栏不会变化
2.可以共享信息,只有一次请求
3.不支持跨域访问
4.如果内容在 WEB-INF 中可以通过转发来访问
重定向:
1.地址栏会发生变化
2.不可以共享信息,只有二次请求
3.可以跨域访问
4.如果内容存在 WEB-INF 中不可以访问到
23.说一下 反射
通俗的讲 就是能够通过运行时的类名获取类的全部信息;
反射是在运行状态中对于任意一个类,能够知道这个类的所有属性和方法;对于任意一个对象都能够调用它的任意一个方法和属性,这种动态获取的信息以及动态调用对象的方法就是java语言的反射机制,灵活性避免写死;
24.线程创建
1.继承 Thread ---重写 run 方法
2.实现 Runnable 接口
3.实现 Callable 接口
4.使用线程池,Executor 框架 或者 newThreadPoolExecutor
5.Spring底层实现多线程(底层是线程池)
6.定时器 Timer (底层封装一个 TimerThread 对象)
继承扩展性不强,Java 只支持单继承,如果一个类继承了 Thread 就不能继承其他类了,但是可以多实现,所以实现 Runnabled 接口好一些,Thread 也是实现了 Runnable 接口的;
25.线程池的创建
很多种方式
1.通过 Executiontors 工厂方式创建;线程工具类
2.通过 new ThreadPool
26.线程池优点
- 限定线程个数,不会导致由于线程过多导致系统运行缓慢或崩溃
- 线程池不需要每次都去创建或销毁,节约了资源
- 因为不需要每次都去创建,响应时间更快
27.线程的状态
创建【在生成线程对象,并没有调用该对象的start方法,这时线程处于创建状态】
就绪【当调用了线程对象的start方法之后,该线程就进入了就绪状态】
运行【线程调度程序将处于就绪状态的线程设置为当前线程,此时线程进入了运行状态,开始运行run函数当中的代码】
阻塞【线程正在运行的时候被暂停,同时视为了等待某个事件之后再继续执行。sleep。wait。都可以导致线程阻塞】
死亡【如果一个线程的 run 方法执行结束或者调用 stop 方法,该线程就会死亡。对于已经死亡的线程,无法在使用 start 方法令其进入就绪】
28.线程中 run() 和 start() 区别
start 方法是用来启动一个线程,真正实现了多线程运行;
start 方法用于启动线程;run 方法用于执行线程的运行时代码;
start 方法只能调用一次;run 可以重复调用
毎个线程都是通过某个特定 Thread 对象所对应的方法 run 方法来完成其操作的。方法 run 称为线程体,通过调用 Thread 类的 start 方法来启动一个线程;
调用 run 就是普通的方法调用,系统不会给我们开启一个线程来执行 run 方法的线程任务;
29.线程安全问题
多个线程同时去访问一个资源
加锁(乐观 悲观 ThreadLock)
使用自动锁(Synchronized),使用手动锁(Lock),使用安全类(util.concurrent)下的类;
Synchronized 关键字可以标记在一个方法或者代码块中,当一个线程调用该对象的 Synchronized 方法或者 Synchronized 代码时,这个线程便获得了该对象的锁,其他线程暂时无法访问这个方法,只有等待这个方法执行完毕或者代码块执行完毕,当前线程才会释放锁,其他线程才能执行这个方法或代码块;
30.线程和进程 区别
- 进程是一个程序,一个java程序运行起来就会占用一个进程,一个进程里包含多个线程;
- 进程是资源分配的最小单位,线程是程序执行的最小单位;
- 进程有自己的独立空间,毎启动一个进程,系统就会为它分配地址空间;
- 多进程程序更健壮,多线程程序只要有一个线程死掉,整个进程也死掉了。而一个进程死掉并不会对另一个进程造成影响,因为进程有自己独立的地址空间;
31.Synchronized 和 Lock 区别
Synchronized 和 Lock 都是属于 悲观锁;
Synchronized 可以给类,方法,代码块加锁;Lock只能给代码块加锁;
Synchronized 不需要手动释放锁,发生异常会自动释放锁,不会造成死锁;
Lock 需要自己加锁和释放锁,如果不释放就会造成死锁;
性能上面讲的话 Lock 效率高一些
32.Synchronized 和 volatile 区别
volatile 是变量修饰符; synchronized 是修饰类、方法、代码段;
volatile 仅能实现变量的修改可见性,不能保证原子性;而 synchronized 则可以保证变量修改的可见性和原子性;
volatile 不会造成线程的阻塞;synchronized 可能会造成线程阻塞;
33.sleep() 和 wait() 区别
sleep 是Thread 类的方法,会使线程暂停执行一段时间,把执行机会让给其他线程,时间一到就复苏;
wait 是 Object 类的方法,是当前拥有该对象锁的进程等待,直到其他线程调用 notify 方法
sleep 不释放锁,wait 释放锁
sleep 时间到自动恢复;wait 必须调用 notify / notify all 唤醒
wait 不用捕获异常, sleep 必须捕获异常
sleep 必须放在同步控制方法或者同步语句块中,wait 可以放在任意地方
34.notify() 和 notify all() 区别
notify 随意唤醒一个线程(具体哪个线程由虚拟机控制)
notify all 会唤醒所有的线程
35.怎么防止 死锁
- 互斥使用,即当资源被一个线程占用时,别的线程不能使用
- 不可抢占,资源请求者不能强制从资源占有者手中夺取资源,资源只能由资源占有者主动释放
- 请求和保持,即当资源请求者在请求其他资源的同时保持对资源的占有
- 循环等待
36.JVM 组成
运行时数据区【方法区、堆、程序计数器、虚拟机栈、本地方法栈】
执行引擎【即时编译器、垃圾收集】
类加载器子系统
本地方法库
线程共享区【方法区、Java堆】
线程独占去【虚拟机栈、本地方法栈、程序计数器(CPU寄存器)】
37.JVM 优化
使用较少的内存占用来获得较高的吞吐量或者较低的延迟
调优可以依赖参考系统运行日志、堆栈错误信息、GC日志、线程快照什么的
年轻代大小的选择
1.响应时间优先的应用
尽可能设大,直到接近系统的最低响应的时间限制;(这种情况下年轻代收集发生的频率也是最小的,同时减少到达老年代的对象)
2.吞吐量优先的应用
尽可能设大,可能到达Gbit的程度,因为对响应时间没有要求,垃圾收集可以并行进行,一般适合8CPU以上的应用;
老年代大小的选择
吞吐量优先的应用
一般吞吐量优先的应用都有一个很大的年轻代和一个较小的老年代;
原因:这样可以尽可能回收掉大部分短期对象,减少中期的对象,而老年代存放长期存活对象;
较小堆引起的碎片问题
38.JVM、JRE、JDK 区别
JVM 就是虚拟机,就相当于计算机里面安装一个虚拟机,就能实现跨平台了,不用再去毎个系统都做一套相对应的软件;
JRE 相当于一个数据库,输入的源代码,通过数据库转换成字节码。运行时也会在 JRE 中读取需要的数据;
JDK 开发者用的开发工具,里面包含了 JRE,作用就是可以 编译和运行代码;
39.堆栈 区别
功能方面:堆 使用来存放对象的,栈使用来执行程序的
共享方面:堆 是线程共享的,栈是线程私有的
从软件设计方面:堆 代理处理逻辑,栈代表了数据
40.JDBC 存储过程
加载驱动
获取连接
设置参数
执行
释放连接
41.引用类型有那些
软引用:有用但不是必须的对象,会发生内存溢出之前被回收
强引用:发生GC的时候不会被回收
弱引用:有用但不是必须的对象,在下次GC的时候被回收
虚引用:在GC时返回一个通知
42.JDK 1.8 特性
- Lambda 表达式【排序.sort() 一句话搞定】
- Optional 类 【用来解决空指针异常】
- 增强时间和日期的处理 【LocalData、LocalTime】
- 方法引用 【提供很多有用的语法,代码结构更紧凑简洁,减少冗余代码】
- 引入 【 :: 另一种调用方式】
43.类加载机制/流程
- 加载字节码
- 验证字节码(是否有效,检验是不是字节码文件等)
- 准备(准备空间)
- 解析(替换直接引用,加载到内存中地址)
- 初始化(对变量赋值)
44.List 和 Set 区别
List 是有序,可以重复
Set 是无序,不可以重复
ArrayList (底层基于数组,查询和修改的效率高)
LinkedList(底层基于双向链表,删除和插入的效率高)
HashSet(保证不重复 hashCode)
TreeSet(内存按排序规则进行排序)
45.HashMap 原理
JDK 1.7 hashMap 底层是基于 数组 + 链表的方式实现的,是以键值对的形式存储,查询会遍历所有的链表,查询效率低,会出现hash 碰撞,0.75 加载因子使用来判断数组是否需要扩容;
JDK 1.8 的时候hashMap 底层是基于 数组+链表+红黑树 的方式实现,引入红黑树就是为了防止hash冲突,引起链表长度过长,查询效率低的问题;
当链表长度超过 8 的时候,链表转为红黑树;
当红黑树的节点小于 6 的时候,重新转为链表;
1.7 采用表头插入链表;1.8 采用的是尾部插入链表
HashMap 的主干就是一个 Entry 数组;Entry 是 HashMap 的基本组成单位,每一个 Entry 包含一个 kay-value 键值对。简单来说 hashMap 由数组 + 链表 组成的,数组是 hashMap 的主体,链表也是为了解决哈希冲突而存在的,如果定位到的数组位置不包含链表,当前 entry 的 next 指向 null,那么对于查找添加等操作就很快,只需一次寻址即可;如果定位到数组包含链表,对于添加操作 首先遍历链表,然后通过 key 对象的 equals 方法逐一对比查找;
我们通过 put/get 方法存储和获取对象。当我们键值对传递给 put 方法时,它调用键对象的 hashCode 方法来计算 hashCode,然后找到 bucket 位置来存储对象;
当获取对象时,通过键对象的 equals 方法找到正确的键值对,返回值对象;
hashMap 使用链表来解决碰撞问题,当发生碰撞了,对象将会存储在链表的下一个节点中。hashMap 在每个节点中存储键值对对象;
46.HashMap 中 put / get
put
- 先判断 当前数组中的节点是不是为空,为空则需要初始化;
- 如果不为空就根据 key 计算的hash 值,定位到具体的节点中,在判断是否为空,为空表明没有hash 冲突,直接在当前位置创建新节点就可以
- 如果不为空 出现 hash 冲突,则判断 table 首个元素是否和 key 一样,如果相同就直接覆盖
- 还会判断 是否是 红黑树,如果是就在红黑树里面插入键值对
- 如果不是红黑树,就判断链表长度是否大于 8 ,大于 8 就把链表转为红黑树,否则进行链表插入操作,如果 key 存在直接覆盖 value
- 插入成功后判断存在的键值对是否超出了最大容量,如果超出就扩容,默认的初始容量是 16 ,加载因子 0.75 【16 * 0.75 = 12】大于12就扩容
get
首先获取定位的节点,一般第一个节点就是值,没必要循环,如果不止一个节点就需要循环遍历,判断是否是红黑树,如果是则调用树的查询,不然就按照链表的方式遍历匹配返回值;
47.hashMap 和 HashTable 区别
HashMap去掉了 HashTable 的contains方法,加上了containsValue() 和 containsKey()方法;
HashTable 同步的(线程安全),HashMap 是非同步的(线程不安全),HashMap 在效率上高于 HashTable
HashMap 允许空键值,HashTable 不允许
48.如何解决哈希冲突
开放定址法
发生冲突,就继续寻找下一个没有占用的存储地址;
链地址法
hashMap 就是 数组+链表。使用链表存放 hash 值,相等且内容不等,存放在同一个链表里面;
49.ArrayList 和 LinkedList 区别
数据结构不同
ArrayList 是 Array(动态数组)的数据结构;LinkedList 是 Link(链表)的数据结构;
效率不同
当随机访问List(get和set操作)时,ArrayList 比 LinkedList 效率高,因为 LinkedList 是线性的数据存储方式,需要移动指针从前往后依次查找;
当对数据集进行增删操作(add和remove)时,LinkedList 比 ArrayList 效率高,因为 ArrayList 是数组,所以进行增删时,会对操作之后所有数据的下标索引造成影响,需要进行数据移动,如果改变长度就要重新创建新的数组,然后把以前的拷贝到新数组里面,如果数据量大,很消耗性能;
自由性不同
主要控件开销不同
ArrayList 列表需要预留一定空间,LinkedList 存储信息及节点指针信息
50.Array 和 ArrayList 区别
Array 可以容纳基本类型和对象,而 ArrayList 只能容纳对象;
Array 可以指定大小的,而 ArrayList 大小是固定的
Array 没有提供 ArrayList 那么多功能,比如 :addAll、removeAll、iterator等
51.MySQL 优化
sql 优化
合理使用索引
选择合适字段
表结构
分库分表
垂直分表:一个字段很多的表,拆分成多个表,解决宽度问题,不常用的单独放一个表,关联密切的放一个表等;
水平分表:把原来一个表拆分成多个表,毎个表的结构都是一样的,解决单表数据量大的问题;
读写分离/主从同步
主从同步:数据库最终会把数据持久化到磁盘,如果集群必须确保毎个数据库服务器的数据是一致的。能改变数据的操作都往主数据库去写,而其他的数据库从主数据库上同步数据;
读写分离:使用负载均衡来实现写的操作都往主数据库去,而读的操作往从服务器去;
Redis中央缓存
在持久层(dao)数据库(db)之间添加一个缓存层,如果用户访问的数据已经缓存起来,在用户访问时直接从缓存中获取,不用访问数据库,而缓存是在操作内存级,访问速度快,可减少数据库服务器压力,减少访问时间;
52.说一下索引
索引一般加在查询条件的关键字上,如果有多个查询条件,还可以添加组合索引/复合索引,用空间换时间。索引原理就是二叉树,减少查询
索引有:普通索引、唯一索引、全文索引、复合索引
创建索引【 ALTER TABLE 表名 ADD UNIQUE INDEX(字段) 】
查询索引【 show index from 表名 】
删除索引【 ALTER TABLE 表名 DROP INDEX 索引名 】
53.索引会在什么情况下失效
- 条件中有 or ,说不定前一个条件字段带索引,但是后面一个条件字段没有带;
- like 查询 是 % 开头的;(后面加 % 可以)
- 如果类型是字符串,一定要在条件中将数据使用引号引起来,否则索引失效;
- 全表扫描比使用索引快,则不使用索引
- 不要在 sql 里面运算 != < > ,会导致索引失效,造成全表扫描
- 避免 where 句中进行 null 判断,会造成全表扫描,不要给数据库留 null,使用 NOTNULL 填充
- 少用 *
54.MySQL 中 内连接、右连接、左连接
内连接:inner join
左连接:left join
右连接:right join
内连接就是把匹配的关联数据显示出来;
左连接是左边的表全部显示出来,右边的表显示出符合条件的数据;
右连接是右边的表全部显示出来,左边的变显示出符合条件的数据;
55.事务的特性
原子性【一组操作紧密相连,不能分开【要么都做要么都不做】】
一致性【数据的一致性,总量是不变的】
隔离性【相互之间不会有影响,一个事务的执行不会被其他事务干扰】
持久性【保存到磁盘上,一个事务一旦提交,它对数据库中的改变就应该是永久性的;】
56.事务的传播机制
Required:【存在的事务会支持该事务,不存在的则开启新事务】
Required_New:【表示每次都创建新的逻辑事务】
Supports:【支持当前事务,如果没有事务则已非事务方式执行】
Not_Support:【以非事务的方式执行,如果当前存在事务就暂停事务,已非事务方式执行】
Mandatory:【支持当前事务,如果没有事务则抛出异常】
Never:【已非事务方式运行,如果有事务则抛出异常】
Nested:【嵌套事务支持,如果当前存在事务,则嵌套在事务内部执行,如果不存在事务就会新建事务,内部事务不影响外部事务,外部事务回滚则会导致内部事务回滚】
57.MySQL的隔离级别
读取未提交内容(Read Uncommotted)
所有事务都可以看到其他未提交的执行结果(读取未提交又称脏读)
读取提交内容(Read Committed)
大多数数据库默认的隔离级别,一个事务只能看见已经提交事务所做的改变(支持不可重复读)
可重读(Repeatable Read)
MySQL默认隔离级别,确保同一个事务的多个实例在并发读取数据时,看到的同样的数据行(出现幻读)
可串行化(Serializable)
最高隔离级别,通过强制事务排序,使之不可能相互冲突,解决幻读,可以说是在毎个读的数据行上共享锁,可能导致大量的超时现象和锁竞争(完全服从ACID)
58.脏读幻读不可重复读
脏读:
就是说一个事务正在访问数据,并且对数据进行修改,修改还没提交到数据库中,另一个事务又读取,并使用了原来数据
当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时。另一个事务也访问这个数据,然后使用了这个数据。因为这个数据是还没有提交的数据,那么另一个事务读到数据是脏数据,依据数据所操作可能是不正确的;
幻读:
当一个事务执行插入,先查询数据,数据里没有,接下来准备添加,结果出错,再查显示有这条数据了,因为在第一个事务查询完,第二个事务添加了,这就是幻读
当事务不是独立执行的时候发生的一种现象;例如第一个事务对一个表中的数据进行修改,这种修改涉及到表中的全部数据行。同时第二个事务也修改了这个表中的数据,这种修改是向表中插入一行新数据。那么就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就像发生了幻觉;
不可重复读:
一个事务多次读取同一条数据,当第一个事务访问完第一次要访问第二次时,第二个事务进来并修改了数据,导致第一个事务两次读取的数据不一致
在一个事务内,多次读同一个数据。在这个事务还没有结束时,另一个事务也访问该同一个数据。那么在第一个事务中的两次读数据之间,由于第二个事务的修改,导致第一个事务两次读取到的数据可能不一致。这样就发生一个事务内两次读到的数据是不一样的,称为不可重复读;
59.MYISAM 和 INNODB 区别
事务安全:MYISAM 不支持事务,INNODB 支持
查询和添加速度:MYISAM 速度快【不支持事务就不用考虑同步锁,查找添加更快】
锁机制:MYISAM 表锁,INNODB 行锁(事务)
支持全文检索:MYISAM 支持,INNODB 不支持
外键:MYISAM 不支持,INNODB 支持
60.数据库 三范式
第一范式:每一列只存一个值;(不能一列又是id 又是name)
第二范式:每一行必须唯一;
第三范式:a表不能出现 b表的其他字段,只能出现 b表的外键
61.Spring 理解
Spring 是一个轻量级的 IOC和AOP 容器框架,是为了 java 应用程序提供的基础性服务的一套开源 JavaEE 开发框架
IOC
IOC 把 Bean 交给 Spring ,创建初始化,销毁,我们都不用管,交给 Spring 管理;
DI 把控 Bean 和 Bean 之间的关系的,Bean 交给 Spring ,那 Spring 也要管理对象的依赖关系;
IOC 底层就是通过 xml 解析 + 工厂设计模式 + 反射,IOC 思想基于 IOC 容器完成,IOC 容器底层就是对象工厂;
Spring 提供 IOC 容器的两种实现方式,都可以加载配置文件创建对象,一种是 BeanFactory,一种是 ApplicationContext
一般用 ApplicationContext ,是 BeanFactory 的子接口,提供更多的功能,加载配置文件的时候会把配置文件里面的对象直接创建了;
BeanFactory IOC 容器基本实现,是 Spring 内部使用,加载配置文件的时候不会创建对象,是获取使用时才会去创建,是懒加载;定义是什么类型不一定返回这个类型,一个类实现这个接口,里面有个 getObject 方法,这个就是返回 Bean 的方法,返回类型是 Object,所有的类都包含这个接口,BeanFactory 定义了 IOC 容器的最基本形式,并提供可 IOC 容器因循环的最基本的接口,也就是 Spring IOC 所遵循的最底层和最基本的编辑规范;
IOC 的注入方式分为【构造器注入】【setter方法注入】【注解注入】
构造器注入:构造器依赖注入通过容器触发一个类的构造器来实现,该类有一系列参数,毎个参数代表一个对其它类的依赖;
setter方法注入:是容器通过调用无参构造器或无参 static 工厂方法实例 Bean 之后,调用 Bean 的 setter 方法,即实现了基于 setter 的依赖注入
AOP
AOP 面向切面编程,也可以说是 OOP 面向对象编程;通过 xml 配置或者注解的方式实现,前置通知,后置通知,异常通知,最终通知等;在需要的地方加入逻辑,抽取出来封装成为一个可复用的模块,这个模块就成为了切面,可解耦(避免重复代码),还提升维护效率,还有事务开启关闭,公共代码抽取,日志等等;
可以通过 JDK 动态代理,基于接口的方式实现;
可以通过 CGLB 代理,基于子类的方式实现;
62.Spring 常用注解
@Controller 【控制层】
@Service 【业务层】
@Repository 【dao层】
@Component 【不明确的角色】
@Aspect 【声明一个切面 AOP】
@Bean 【 声明一个bean】
63.Spring Bean 生命周期
实例化 Bean
属性注入
初始化
执行
关闭/销毁
64.Spring 支持的事务管理
编程式事务管理
通过编程的方式管理事务,带来了极大的灵活性,但是维护难
声明式事务管理
可以将业务代码和事务管理分离,需要用注解和xml配置来管理事务。一般选用声明式事务管理,对代码影响小,无入侵
65.Spring 框架中用到了那些设计模式
工厂模式:Spring使用工厂模式 BeanFactory,ApplicationContext 创建 Bean 对象
代理模式:Spring AOP 功能的实现
单例模式:Spring 中的 Bean 默认都是单例的
模板方法模式:解决重复代码问题,比如:RestTemplate、JmsTemplate、JpaTemplate
适配器模式:Spring AOP 的增强或通知(Advice)使用到了,SpringMVC 也用了了 Controller
66.描述 SpringBoot
SpringBoot 简化了 Spring 框架中大量且繁琐的配置文件
SpringBoot 就是基于 Spring 更深封装的一个框架,Spring 组件一站式解决方案,简化 Spring 的初始搭建,开发过程等!消除了设置 Spring 应用程序所需要的 XML 配置,编码更简单、配置更简单、部署更简单、监控更简单。还内置了 Tomcat ,就是找错不是很明显;
67.SpringBoot 优点
独立运行,简化配置,自动配置,无代码生成 xml 配置,应用监控,上手容易;
68.SpringBoot 常用注解
@SpringBootApplication 自动配置 在主类上
@Repository 标注数据访问组件
@Service 标注业务层
@RestController 标注控制层组件
@ResponseBody 直接返回 json 数据
@Component 泛指组件,不好归类的时候
@Bean 产生一个bean,交给spring管理
69.SpringBoot 自动配置原理
启动类上加 @SpringBootApplication 注解,里面继承了 @EnableAutoConfiguration 的一个注解,@EnableAutoConfiguration 里面导入了一个配置类,这个配置类里面加载了一个 spring.factories 的配置文件,这个 spring.factories 中 SpringBoot 的 autoconfigure 包下,这个 autoconfigure 包里 META-INF 文件下有一个 spring.factories 配置文件,这个配置文件里面有一百多个 autoconfigure 的自动装配类,这些 autoconfigure 的类在满足一定条件下,(当然这些自动配置类并不是在spring容器一启动的时候就全部加载,比如当某bean不存在,当bean是单例等等就会生效),它会被spring容器加载,配置好一些bean,这样我们在使用 springboot 的自动装配的功能就需要 导包,写yml,注入这个bean,就可以开始用了,减少我们用户自己创建bean 的过程,也可默认配置直接注入,不用导包配置yml。
70.SpringBoot 核心文件
SpringBoot 的核心配置文件 : application 和 bootstrap
application 配置文件就是用于 SpringBoot 项目自动化配置
bootstrap 使用 SpringCloud Config 配置中心时,需要 bootstrap 配置文件中添加链接到配置中心的配置属性来加载外部配置中心的配置信息;
71.SpringBoot配置文件有那些格式
.properties app.user.name = javastack
.yml app: user: name: javastack
yml格式不支持@PropertySource注解导入配置
72.SpringBoot 配置加载顺序
- properties 文件
- yml 文件
- 系统环境变量
- 命令行参数
73.SpringCloud 常用组件
- eureka :注册中心【实现服务治理,注册于发现服务】
- ribbon/feign:负载均衡 【服务调用使用,算法:随机,轮询】
- hystrix:断路器 【避免微服务集群雪崩,保护系统,控制故障范围】
- zuul:服务网关 【路由。api网关。负载均衡等多种作用,类似 Nginx反向代理】
- Config:配置管理
74.SpringCloud 优点
- 服务拆分粒度更细,有利于资源重复利用,有利于提高开发效率
- 可以更精准的制定优化服务方案,提高系统的可维护性
- 微服务架构采用去中心化思想,服务之间采用 Restful 等轻量级通讯
- 适于互联网时代,产品迭代周期更短
75.面向对象的特征
封装:就是把客观事物封装成抽象的类,并且类可以把自己的数据只让可信的类或者对象操作,对不可信的尽心信息隐藏
继承:就是可以使用现有类的所有功能,并无需要重新编写原来的类的情况下进行功能扩展
多态:允许子类类型的指针赋值给父类类型的指标
76.什么是 ORM
对象关系映射模式(Object Relational Mapping),简称 ORM,可以控制 SQL,解决面向对象与关系数据库存在的相互不匹配现象。可以简单的采用硬编码方式(jdbc 操作 sql 方式),为每一种可能的数据使用 ORM 框架 【MyBatis、Hibernate】
77.微服务 和 分布式 区别
微服务就是在分布式的基础上对其的本身做更细腻的拆分,毎个都有自己的服务器进行部署,微服务一定是分布式,分布式不一定是微服务;
分布式就是多个服务器对其对应的服务进行部署
78.MyBatis 中 # 和 $ 区别
#{} 是预编译处理; ${} 是字符串替换
MyBatis 在处理 # 时,会将 SQL 中的 # 替换为 ? 号,调用 PreparedStatement 的 set 方法来赋值;
MyBatis 在处理 $ 时,就是把 $ 替换成变量的值
使用 # 可以有效防止 SQL 注入,提高系统安全性
79.MyBatis 和 MyBatis-plus 区别
MyBatis 是全自动的;
MyBatis-plus 是半自动的;
80.说一下 MVC
MVC 就是一种设计典范,可以将业务逻辑聚集到一个部件里面,再改进相关的时候,不需要重写别的业务逻辑;
M:模型 Model (JavaBean)
V:视图 View (Html、Jsp、Freemaker)
C:控制器 Controller (Servlet)
① 当控制器收到来自用户的请求
② 控制器调用 JavaBean 完成业务
③ 完成业务后通过控制器跳转 JSP 页面的方式给用户反馈信息
④ JSP 给用户做出反应
81.SpringMVC 执行流程
- 用户向服务器发送请求,请求被Spring前端控制机 Servlet DispatcherServlet 捕获
- DispathcherServlet 对请求URL解析,调用HandlerMapping获取Handler配置的所有相关对象
- DispathcherServlet根据获取的Handler,选择合适的HandlerAdapter
- 获取 Request 中的模型数据,填充 Handler 入参,开始执行 Handler
- Handler 执行完成后,向 DispathcherServlet 返回一个 ModelAndView 对象
- 根据返回的 ModerAndView 选择合适的 ViewReolver,结合 Model 和 View 渲染视图
- 渲染结果返回客户端
82.Shiro 核心类
- Subject 【当前用户】
- SecuritManager 【Shiro 的权限管理器】
- Realm 【去拿到登录等的值,拿到数据获取数据】
83.Shiro 四大基石
- Authentcation 身份验证:登录
- Authorization 授权:权限判断
- Cryptography 密码:加密
- Session Management 会话关联:session
84.Git 常用命令
git add 【添加到缓存区】
git commit 【提交】
git merge 【分支合并】
git branch 【查看所有本地分支】
git branch -r 【查看所有远程分支】
git branch [xxxx] 【创建分支】
git branch -d [xxx] 【删除分支】
85. Git 和 SVN 区别
Git 支持分布式
86.如何远程连接 Linux
Putty + Xshell
Winscp + xftp
87.Linux 优点
开源免费
安全稳定
网络支持 / 支持多用户
很低的内存就可以运行
88.Linux 常用命令
pwd:获取当前路径
cd:跳转目录
cd../..:返回上两级目录
ls:查看目录中的文件
ifconfig:查看IP
su -u:切换管理员
89.说一下 Redis
Redis 是以键值对的形式存储值 【key - value】的非关系型数据库 NoSQL;先存在内存中,会根据一定策略持久化到磁盘,即使断电也不会丢失数据;
提高了性能,减少数据库的访问,对其经常读的数据可以减少访问数据库的次数,相比而言,支持集群和分布式,所有操作都是原子性的;
经常使用需要查询的,很少修改的数据,放到 redis ,减少下次访问时间,减轻数据库压力;
90.怎么保证 缓存 和数据库的数据一致性
合理的设置缓存的过期时间
新增、更改、删除 数据库操作的同时 更新 redis,可以使用事务机制来保证数据的一致性;
91.Redis 和 Memche 区别
- Redis 和 Memche 都是将数据存放在内存中,都是内存数据库,不过 Memche 还可以用于缓存其他东西。比如图片、视频等
- Redis 不仅仅支持简单的 key-value 类型的数据,同时还提供 list、set、hash 等数据结构的存储;
- 虚拟内存---Redis 当物理内存用完时,可以将一些很久没有用到的 value 交换到磁盘
92.Redis 优点
- 支持多种数据结构
- 支持持久化操作
- 支持事务,redis 所有操作都是原子性的
- 读写性能优异,redis 能读的速度是 110000次/s ,写的速度是 81000次/s
- 支持主从复制,主机会自动将数据同步到从机,可以进行读写分离
93.Redis 常见数据结构
List(列表)、Set(集合)、String(字符串)、ZSet(有序集合)、Hash(字典)
94.Redis 淘汰策略
- 从已设置过期时间的数据集中挑选 最近最少使用 的数据淘汰;
- 从已设置过期时间的数据集中挑选 将要过期 的数据淘汰;
- 从已设置过期时间的数据集中挑选 任意数据 的数据淘汰;(随机)
- 从所有数据集中挑选 最近最少使用 的数据淘汰;
- 从所有数据集中挑选 任意数据 的数据淘汰;(随机)
- 不删除策略 ,达到最大内存限制时,直接返回错误信息
95.Redis 集群
主从模式
当主服务器宕机后,需要手到把一台从服务器切换到主服务器,就需要人工干预,费时费力,还会造成一段时间内服务不可用,不推荐,优先使用哨兵模式;
主从模式只解决了高并发问题,但是主从切换是不够及时的,需要运维人员手动切换。通过第三方(keeplive)进行切换,降低系统的可用性,存在数据丢失问题,并没有很好地去解决孤战迁移;
哨兵模式
哨兵通过发送命令,等待 redis 服务器响应,从而监控运行的多个 redis 实例;
当哨兵检查到 master 宕机,会自动将 slave 切换成 master。然后通过发布订阅模式通知其他的从服务器,修改配置文件,让它们切换主机。一个哨兵进程对 redis 服务器进行监控可能会出现问题,我们可以使用多个哨兵进行监控,各个哨兵之间还会监控,这就是多哨兵模式;
同时监控所有的主从节点,定时 ping 链接,一旦请求超时,就认为该节点故障,从剩下的节点中选举一个新的作为主节点;
96.缓存击穿、缓存雪崩、缓存穿透
缓存击穿:【key 并发非常高,正好 key 过期,所有都访问到了数据库】
解决:别让它过期就好了 .... 这种情况本身就很极端,或者搞上锁;
缓存雪崩:【很多 key 大批量到期,并发撞进数据库,和击穿很像,击穿是一个,这是一推】
解决:分散过期时间,永不过期,随机过期,等等
解决:再缓存失效后,通过加锁或者队列来控制数据库写缓存的线程数量
解决:不同的 key,设置不同的过期时间,让缓存失效的时间尽量均匀;
缓存击穿:【缓存和数据库中都没有的数据,用户一直反复访问,就是不存在的数据反复访问】
解决:可以在缓存搞一个空字符串,来一个缓存没有,进入数据库。第二次进来再来就直接把空字符串传回去;
97.Redis 如何防止数据丢失
- 做主从
- 持久化,RDB 数据快照 和 AOF 日志文件
RDB 数据快照
压缩写入,内存小,加载 RDB 文件速度快,但是某一时刻的快照,有可能数据不全,生成写入占用 CPU 和 内存资源;
AOF 日志文件
可以配置,一秒写入等;可以把数据丢失控制在一秒内,数据更加完整;
98.ElasticSearch 优点
- ES 是分布式的,不需要其他组件,分发是实时的;
- ES 完全支持 Apache Lucene 的接近实时的搜索;
- 处理多用户(multitenancy)不需要特殊配置,而 Solr 则需要更多的高级设置;
- ES 采用 Gateway 的概念,使备份更简单;
97.ElasticSearch 为什么 快
传统的数据库采用的 B+ 树索引,ES 中所有字段默认都建了倒序排序;
98.jQuery 选择器有那些
id 选择器
类 选择器
元素 选择器
Class 选择器
标签 选择器
99.获取列元素用 jQuery 那种方式
- 通过某个事件获取 用 live() 方法
- 通过 post 从后台返回值添加到 <table> 中,只用 ajaxComolete() 方法
100.说一下 Ajax
异步的 javascrip 和 xml
通过 Ajax 与服务器进行数据交换,Ajax 可以使页面实现局部更新;
HttpRequest 对象,使用这个对象可以异步想服务器发送请求,获取响应,完成局部刷新;
猜你喜欢
- 2024-11-17 java面试题及答案2022,java2022最新面试题及答案
- 2024-11-17 舔狗都内卷了!这10万+Java面试题总结+答案链接你还不来看吗
- 2024-11-17 50道Java面试题(java高级面试题及答案)
- 2024-11-17 5 个刁钻的 String 面试题!你都遇到过哪些?
- 2024-11-17 Java 最常见面试题全解析:反射、Java Web
- 2024-11-17 好程序员Java培训分享20个Java程序员基础题
- 2024-11-17 干货来了!| 125 条常见的 java 面试笔试题大汇总 |(50/125)| 日更
- 2024-11-17 这是我见过最有用的java面试题,强烈推荐(含答案)
- 2024-11-17 Java最全面试题之Spring篇(java面试题 spring)
- 2024-11-17 Java常见面试题:String(java常见的面试题目)
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- nginx反向代理 (57)
- nginx日志 (56)
- nginx限制ip访问 (62)
- mac安装nginx (55)
- java和mysql (59)
- java中final (62)
- win10安装java (72)
- java启动参数 (64)
- java链表反转 (64)
- 字符串反转java (72)
- java逻辑运算符 (59)
- java 请求url (65)
- java信号量 (57)
- java定义枚举 (59)
- java字符串压缩 (56)
- java中的反射 (59)
- java 三维数组 (55)
- java插入排序 (68)
- java线程的状态 (62)
- java异步调用 (55)
- java中的异常处理 (62)
- java锁机制 (54)
- java静态内部类 (55)
- java怎么添加图片 (60)
- java 权限框架 (55)
本文暂时没有评论,来添加一个吧(●'◡'●)