常考
计算机网络
分层
分层类型:
七层:应、表、会、传输层、网络层、数据链路层、物理层
五层:
四层:应、传、网、网络接口层
各层作用:
应用层
-
功能:为用户提供网络服务
-
该层的协议:HTTP、FTP、SMTP、DNS
-
数据的形式:报文
传输层
-
功能:为两个主机中进程之间的通信提供数据传输服务
-
协议:tcp udp
-
设备:网关
-
数据形式:报文段
网络层
-
功能:选择合适的网间路由和交换节点,根据ip地址寻找mac地址
流量控制和拥塞控制的区别是:流量控制只是端端之间,只需要管理两个端之间的流量传输即可,也就是局部的。但是拥塞控制是全局的,是整个网络所做的事情,需要所有的路由器主机一起努力完成的事情。在传输层,既有流量控制也有拥塞控制。
HTTP和TCP的区别
-
应用层,传输层
-
http协议是基于tcp协议
-
http专注于要传输的信息,是信息的载体;tcp关注传输的可靠性
Java
Java容器
常用容器
-
Collection
List、Set、Queue(LinkedList, PriorityQueue)
-
Map(HashMap, HashTable, ConcurrentHashMap)
HashMap
-
底层结构:一个entry数组+链表/红黑树,数组里面存放的是链表的头节点,每一个节点里面包含四个字段:hash值、key、value、Node<K, V> next。
-
往HashMap中添加数据时:先根据hash值通过哈希算法找到对应的数组下标,若对应数组下标处没有数据,则将该节点直接存入数组下标处;如果对应下标处有节点,则遍历该链表,用key的equals方法判断是否存在相同key的节点,如果发现存在相同key的节点,则将key相同的节点的value值改为要插入的value值;如果没有key相同的节点,那么就将要插入的数据插到链表的尾部。
-
取数据时:首先通过key求出hash值,再通过hash值找到数组下标,找到相应的链表,如果没有就返回null;如果找到了,就遍历链表,对链表的每个节点用equals方法判断是否存在对应key的节点,如果存在则返回该节点的value,如果不存在则返回null。
遍历集合的三种方式
for、foreach、iterator
JUC
Java锁
-
公平锁、非公平锁
-
可重入锁
-
自旋锁:尝试获取的线程不会立即阻塞,而是采用循环的方式不断区尝试获取锁,这样的好处是减少线程上下文切换带来的消耗,缺点是循环会消耗CPU
-
读写锁
Synchronized和Lock(ReentrantLock)的区别
-
二者都是可重入锁:(同)
可重入锁的意思是,自己可以再次获取自己内部的锁。当一个线程获得了某个对象的锁,在锁释放之前,该线程可以再次获取该对象的锁,这样可以避免死锁。同一线程每次获取锁,锁的计数器+1。
-
底层实现上:synchronized依赖于JVM,是java关键字;而ReentrantLock依赖于API
-
是否手动释放:synchronized不需要手动释放锁,在执行完相应代码后会自动让线程释放对锁的占用;ReentrantLock则需要手动释放锁,一般通过lock()和unlock()结合try/finally语句块来完成,一般unlock是在finally中完成。
-
是否可中断:synchronized是不可中断类型的锁,正在等待的线程会一直等待下去,直到锁释放;ReentrantLock则可以中断,可以通过tryLock设置超时时间或者通过lock.lockInterruptibly()来实现这个机制,也就是说,正在等待的线程可以选择放弃等待,改为处理其他事情。
-
是否公平锁:synchronized为非公平锁,而ReentrantLock则可以指定公平锁还是非公平锁,默认是非公平;公平锁就是先等待的线程先获得锁。
-
锁是否可绑定条件Condition:synchronized不可绑定,只能通过wait()/notify()/notifyAll()方法要么随机唤醒一个线程,要么唤醒全部线程;而ReentrantLock可以通过结合Condition实现”选择性通知“,线程对象可以注册在指定的Conditon中,而Condition实例的signalAll()方法只会唤醒注册在该Condition实例中的所有等待线程。
i++线程安全问题
不安全,涉及到jmm
设计模式
工厂模式
解耦:将对象的创建和使用分离
可复用:对于创建过程比较复杂且在很多地方都使用到的对象,使用工厂模式可以提高对象创建代码的可复用性
便于管理:由于复杂对象通过工厂进行统一管理,所以只需要修改工厂内部的对象创建过程即可维护对象,从而达到降低成本的额目的
类型
简单工厂模式
工厂方法模式
抽象工厂模式
实现
以简单为例,造汽车,首先创建一个汽车接口,里面定义方法名;然后定义不同的类实现这个接口,并重写里面的方法,如aodi, bmw;接下来,创建汽车工厂,里面实现汽车的创建方法,根据传入的参数名来确定调用的是哪一种汽车的构造方法,并返回相应的对象。
package factory.simple; import factory.model.Computer; import factory.model.HuaweiComputer; import factory.model.XiaomiComputer; public class ComputerFactory { public Computer create(String type){ if (type == null || type.length() == 0){ return null; } if ("Huawei".equalsIgnoreCase(type)) { return new HuaweiComputer(); } else if ("Xiaomi".equalsIgnoreCase(type)) { return new XiaomiComputer(); } return null; } }
数据库
redolog、undolog、binlog
redolog是InnoDB层面的,binlog是MySQL层面
redolog:mysql中数组是以页为单位,查一条数据时,会从硬盘把一整页数据加载进内存,后续的查询也是先去内存查,没查到再去硬盘,减少io;对于更新也是如此,如果发现内存中有需要更新的数据(如果没有则同上),那么就直接在内存中更新,然后将进行的修改操作写入redolog中。具体什么时候将redolog
binlog用于主从复制
undolog用于回滚,保证原子性
框架
Spring
IOC
(是什么,what)控制反转,将原本在程序中手动创建对象的控制权,交由Spring框架来管理。
(有什么用,why)将对象之间的相互依赖关系交给IOC容器来管理,并由IOC容器完成对象的注入,这样可以很大程度上简化应用的开发,把应用从复杂的依赖关系中解放出来。
(怎么实现,how)IOC容器就像是一个工厂,当我们需要创建一个对象的时候,只需要配置好配置文件/注解即可,完全不需要考虑对象是如何被创建出来的。
bean的作用域(@Scope())
-
singleton:单例模式,在IOC容器中只会存在一个bean实例,默认是创建容器时就自动创建该bean对象,也可以通过设置lazy-init="true",设置为懒加载。
-
prototype:原型模式,懒加载,每次请求都会创建一个对象,不仅仅是http请求,还有将其注入到另一个bean中,或者直接调用getBean()方法都会创建一个新的实例。
-
request:每一次http请求都会产生一个新的bean,该bean只在当前http request内有效,请求结束后,该bean的生命周期结束。只适用于web程序。
-
session:在当前http session内有效,同一个会话的多个请求可以服用scope为session的bean实例。
-
globalSession
单例bean的线程安全
https://www.jianshu.com/p/ed20bd1b11c2
Spring中单例Bean的线程安全问题采坑_软件开发随心记的博客-CSDN博客_spring 单例bean 线程安全问题
线程安全与否取决于是否有共享的资源竞争关系存在,即bean是有状态的还是无状态的,有状态指的是有数据存储功能,比如存储用户信息等全局变量,无状态就是无数据存储功能。
解决方法:1.尽量避免在bean中定义全局的成员变量(不太现实)
2. 使用threadlocal,将可变的成员变量保存在其内
@Component和@Bean的区别
-
作用对象不同,Component是作用于类,bean是作用于方法
bean的生命周期
Spring事务
Spring常用注解
-
将类声明为bean(注入ioc容器)
-
@Component:通用的注解
-
Service
-
Controller
-
Repository
-
-
注入bean的注解
-
Autowired
-
Inject
-
Resource
-
Autowired和Resource的区别:
(105条消息) @Autowired和@Resource注解的区别和联系(十分详细,不看后悔)莫小兮丶的博客-CSDN博客autowired和resource注解的区别
-
当接口只有一个实现类的时候,两个注解的效果相同
-
Autowired是Spring的注解,Resource是java的注解
-
Autowired默认是byType,当有多个实现时,则通过byName;Resource默认是byName,如果没有匹配则通过byType
-
Autowired默认注入的对象需要在容器中存在,也可加上required=false
-
-
-
配置类
-
Configuration;声明当前类为配置类
-
@ComponentScan :扫描设置的扫描路径,并自动将符合条件的组件注入到ioc容器中
-
-
bean的属性:Scope
spring和springboot的区别
springboot是spring的扩展,使得开发、测试和部署更加方便
-
简化依赖:比如
-
简化配置:
-
简化部署