发表时间:2022-03-25来源:网络
TCP/IP五层模型:物理,数据链路,网络,传输,应用
OSI 7层模型:物理,数据链路,网络,传输,会话,表示,应用
干嘛用的?
网络分层就是将网络节点所要完成的数据处理工作,分别交给不同的硬件和软件模块去完成
这些过程都使用了哪些协议
TCP 与服务器建立连接 IP 网络发送数据 OPSF 路由选择 ARP IP地址转换为MAC地址 HTTP 访问网页长连接:指的是通过三次握手建立起一次连接,可以在此连接内发送多次request请求,http1.0是短链接,http1.1协议默认是长连接,响应头加入Connection:keep-alive
网页之间的交互是通过Http协议传输数据的,而Http协议是无状态的协议,状态的协议是什么意思呢?一旦数据提交完后,浏览器和服务器的连接就会关闭,再次交互的时候需要重新建立新的连接。
服务器无法确认用户的信息,于是乎,w3c就提出了:给每个用户都发一个通行证,无论谁访问都需要携带通行证,这样服务器就可以从通行证上确认用户的信息了,这个通行证就是Cookie
1XX:指示信息--表示请求已接收,继续处理
2XX:成功-表示请求已成功接收,理解,接受
3XX:重定向-要完成请求必须进一步的操作
4XX:客户端错误-请求有语法错误或者请求无法实现
5XX:服务端错误--服务器未能实现合法的请求
分析:
第一次:客户端发送请求到服务端,这样服务器知道了客户端正常,自己接受正常,SYN=1,seq=x
第二次:服务器发送给客户端,这样客户端知道自己发送,接收正常,服务器接收正常,发送正常,ACK=1,ack=x+1,SYN=1,seq=y
第三次:就剩服务器还不知道客户端接收是否正常和自己发送是否正常了,这样客户端继续发送给服务端,服务端知道客户端发送,接收正常,自己也发送接收正常了。seq=x+1,ACK=1,ack=y+1
上面分析过程可以看出,握手两次达不到让双方都得出自己、对方的接收、发送能力都正常的结论的。

分析:
第一次:客户端请求断开FIN,seq=u
第二次:服务器确认客户端的断开请求ACK,ack=u+1,seq=v
第三次:服务器请求断开FIN,seq=w,ACK,ack=u+1
第四次:客户端确认服务器的断开ACK,ack=w+1,seq=u+1
在关闭连接时,当服务端收到FIN报文时,可能服务端还有些数据还没处理,并不会立即关闭socket,只能先回复一个ACK报文,告诉客户端,你的报文我收到了,只有等到我服务端所有的报文都发送完了才能发送FIN报文,因此不能一起发送,所有需要四次握手
答:虽然按道理,四个报文都发送完毕,我们可以直接进入CLOSE状态了,但是我们必须假象网络是不可靠的,有可以最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。在Client发送出最后的ACK回复,但该ACK可能丢失。Server如果没有收到ACK,将不断重复发送FIN片段。所以Client不能立即关闭,它必须确认Server接收到了该ACK。Client会在发送出ACK之后进入到TIME_WAIT状态。Client会设置一个计时器,等待2MSL的时间。如果在该时间内再次收到FIN,那么Client会重发ACK并再次等待2MSL。所谓的2MSL是两倍的MSL(Maximum Segment Lifetime)。MSL指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间。如果直到2MSL,Client都没有再次收到FIN,那么Client推断ACK已经被成功接收,则结束TCP连接。
UDP是不可靠连接,在传输数据之前不需要建立连接,主机在接收UDP报文之后,不需要给任何的确认
TCP是可靠连接,在传输数据之前需要建立连接,数据传送结束之后要释放连接
前提:为数据库连接建立一个缓冲池。
能够从连接池获取或创建可用的连接 使用完毕后,将连接返回给连接池 在系统关闭前,关闭所有的连接并释放占有的系统资源。 能够处理无效的连接,限制连接池中的连接总数不低于或不超过某个限定值。request,response,out,pagerContext,session,application,config,page,exception
application,session,request,page
servlet是java提供用于开发web服务器应用程序的一个组件,运行在服务端,由servlet容器管理,用来生成动态内容。一个servlet实例是实现了特殊接口servlet的java类,所有自定义的servlet均必须实现servlet接口。
Servlet是一个特殊的Java程序,能够依靠web服务器的支持向浏览器提供显示内容
JSP本质上是Servlet的一种简易形式,JSP会被服务器处理成一个类似于Servlet的Java程序,可以简化页面内容的生产。
JSP更侧重于视图,Servlet更侧重于控制逻辑
Servlet运行在Servlet容器中,其生命周期由容器来管理,Servlet的生命周期通过javax.servlet.Servlet接口中的init(),service和destroy()方法来表示。
Servlet的生命周期包含了下面4个阶段
监听器,过滤器,相关参数,会话超时时间,安全验证方式,错误页面
tomcat的主目录,conf/serve.xml文件下修改,把8080改为其他的
当容器启动时,会读取在webapps目录下所有的web应用的web.xml文件,然后对xml文件进行解析,并读取servlet注册信息。然后,将每个应用中注册的servlet都进行加载,并通过反射的方式实例化(有时候也是在第一次请求实例化)
在servlet注册时加上1如果为正数,则在一开始就实例化,如果不写或为负数,则第一次请求实例化。
Ajax是一种创建交互式网页应用的网页开发技术
Ajax的优势:
通常用ps查看进程pid,用kill命令终止进程
ps命令用于查看当前正在运行的进程
RDB的优点:节省磁盘空间,恢复数据快,虽然redis在fork时使用了写时拷贝技术,如果数据量大的话也是非常消耗性能的。
RDB的缺点:因为备份周期是在一定间隔时间做一次备份,如果redis意外down掉的话,会丢失最后一次快照后的所有修改
redis是单进程单线程的,redis利用队列技术将并发访问变为串行访问,消除了传统数据库串行控制的开销。
512M
为了达到最快的读写速度将数据都读到内存中,并通过异步的方式将数据写入磁盘,所以redis 具有快速和数据持久化的特征。如果不将数据放在内存中,磁盘I/O 速度为严重影响redis 的性能。在内存越来越便宜的今天, redis 将会越来越受欢迎。如果设置了最大使用的内存,则数据已有记录数达到内存限值后不能继续插入新值。
Redis可以使用主从同步,从从同步,第一次同步时,主节点做一次bgsave,并同时将后续修改操作记录到内存buffer,待完成后将rdb文件全量同步到复制节点,复制节点接受完成后将rdb镜像加载到内存,加载完成后,在通知主节点将期间修改的操作记录同步到复制节点进行重放就完成了同步过程。
一般是黑客故意去请求缓存中不存在的数据,导致所有的请求都落到数据库上,造成数据库短时间内承受大量的请求而崩掉。
解决方法
缓存同一时间大面积失效,所以,后面的请求都会落到数据库上,造成数据库短时间承受大量请求而崩掉。
解决
数据库和缓存双缓存,双写,如何解决一致性问题
如果你的系统不是严格要求缓存+数据必须强一致性的话,可以采用Cache-Aside Pattern 如果不得不做强一致性时,那么可以使用读请求和写请求串行化,串到一个内存队列里去 使用队列串行化的方式会导致系统的吞吐量会大幅度的降低主从复制的好处:
避免redis单点故障
构建读写分离架构,满足读多写少的应用场景
复制的过程原理
当从库和主库建立MS关系后,会向主数据库发送sync命令 主库接收到sync命令后,会开始在后台fork保存快照(RDB持久化过程bgsave)并将期间收到的写命令缓存起来。 当快照完成后,主Redis会将快照文件和所有缓存的写命令发送到从Redis。 当从Redis接收到后,会载入快照文件并且执行收到的缓存命令 主Redis每当接收到的写命令都会发送给从Redis,从而保证数据的一致性哨兵
哨兵的作用是对Redis系统运行情况进行监控,是一个独立的进程,他的功能有两个:
即使有了主从复制,每个数据库都需要保存整个集群中的所有数据,容易形成木桶效应,所有还需要集群。
key的有效使用CRC16算法计算出哈希值,再对哈希值对163284取余,得到插槽值。
在Redis集群中可以使用主从模式实现一个节点的高可用
在该结点宕机后,集群会将该结点的slave转变为master继续完成集群服务。
BLOB是一个二进制的对象,可以容纳可变数量的数据,TEXT是一个不区分大小写的BLOB。BLOB和TEXT类型的唯一区别在于对BLOB值进行排序和比较时区分大小写,对TEXT值不区分大小写
now()命令用于显示当前年份,月份,日期,小时,分钟,和秒
current_date()仅显示当前年份,月份和日期
char的长度是可变的,而varchar的长度是不可变的,当char值被存储时,它们被用空格填充到特定的长度,检索char值需删除尾随空格。
每当行被更改时,时间戳字段将获取当前时间戳
它会停止递增,任何进一步的插入都将产生错误, 因为密钥已被使用。
LAST_INSERT_ID 将返回由Auto_increment 分配的最后一个值,并且不需要指
定表名称。
数据库在通过连接两张或多张表来返回记录时,都会生成一张中间的临时表,然后再将这张临时表返回给用户。
在使用left join时,on和where条件的区别如下:
四个基本要素:原子性,一致性,隔离性,持久性
原子性:事务是一个原子操作单元,其对数据的修改,要么全部执行,要么全部不执行。 一致性:在事务开始和完成时,数据都必须保持一致状态,这意味着所有相关的数据规则都必须应用于事务的修改,以保持数据的完整性;事务结束时,所有的内部数据结构(如B树索引或双向链表)也都必须是正确的。 隔离性:数据库系统提供着一定的隔离机制,保证事务在不受外部并发操作影响的独立环境执行,这意味着事务处理过程的中间状态对外部是不可见的,反之亦然。 持久性:事务完成之后,它对数据的修改时永久性的,即使出现系统故障也能够保持。drop 直接删除表
truncate 删除表中的数据,在插入数据自增长id又从1开始 trun cate
delete 删除表中的数据,可以加where语句
数据本身之外,数据库还维护着一个满足特定查找算法的数据结构,这些数据结构以某种方式指向数据,以帮助MySQL高效获取数据,这种数据结构就是索引。
表级锁:每次操作都锁定在整张表,开销少,加锁快,不会出现死锁,锁定粒度大,发生锁冲突的概率最高,并发度最低
行级锁:每次操作锁定一行数据,开销大,加锁慢,会出现死锁,锁定粒度小,发生锁冲突的概率最低,并发度最高
页面锁:开销和加锁时间介于两者之间,会出现死锁,并发度一般
悲观锁:假定会发生并发冲突,屏蔽一切可能违反数据完整性的操作
乐观锁:假设不会发生并发冲突,只在提交操作时检查是否违反数据完整性
乐观锁更适合解决冲突概率极小的情况,而悲观锁则适合解决并发竞争激烈的情况,尽量使用行锁,缩小加锁粒度,以提高并发处理能力,即使加行锁的时间比表锁要长
相对于串行处理来说,并发事务处理能大大增加数据库资源的利用率,提高数据库系统的事务吞吐量,从而可以支持更多的用户
当两个或多个事务选择同一行,然后基于最初选定的值更新该行时,由于每个事务都不知道其他事务的存在,就会发生丢失更新问题——最后的更新覆盖了由其他事务所做的更新。
例如,两个程序员修改同一java文件,每个程序员独立地更改其副本,然后保存更改后的副本,这样就覆盖了原始文档,最后保存其更改副本的编辑人员覆盖前一个程序员的更改。
如果在一个程序员完成并提交事务之前,另一个程序员不能访问同一文件,则可避免此问题。
一个事务正在对一条记录做修改,在这个事务完成并提交前,这条记录的数据就处于不一致状态;这时,另一个事务也来读取同一条记录,如果不加控制,第二个事务读取了这些脏数据,并据此做进一步的处理,就会产生未提交的数据依赖关系,这种现象被形象的叫做脏读。
一句话:事务A读取到了事务B已修改但尚未提交的数据,还在这个数据基础上做了操作,此时,事务B进行回滚,A读取的数据无效,不符合一致性要求。
一个数据在读取某些数据后的某个时间,再次读取以前读过的数据,却发现其读取出的数据已经发生了变化,或某些记录已经被删除了,这种现象就叫做不可重复读。
一句话:事务A读取到了事务B已经提交的修改数据,不符合隔离性。
一个数据按相同的查询条件重新读取以前检索过的数据,却发现其他事务插入了满足其条件查询的新数据,这种现象就称为幻读。
一句话:事务A读取到了事务B提交的新增数据,不符合隔离性
多说一句;幻读和脏读有点类似,脏读是事务B里面修改了数据,幻读是事务B里面新增了数据。
更新丢失可以通过加锁来解决,“脏读”、“不可重复读”、“幻读”属于数据库一致性问题,由数据库提供一定的事务隔离机制来解决
数据库的隔离越严格,并发副作用越小,付出的代价也就越大,隔离的实质就是在一定程度上使事务串行化,这显然与并发是矛盾的。
未提交读(Read uncommitted)
已提交读(Read committed)
可重复读(Repeatable read)
可序列化(Serializable)
区别:char是一种固定长度的类型,varchar则是一种可变长度的类型
含义:最多存放50个字符,varchar(50)和varchar(200)存储hello所占空间一样,但后者在排序时会消耗更多的内存,因为order by col采用fixed_length计算col长度
int(10)10的含义:是指显示字符的长度,最大为255,仍占4字节存储,存储范围不变
有符号的整型范围是-2147483648~2147483647
无符号的整型范围是0~4294967295(2^32)
int(10)的意思是假设有一个变量名为id,它的能显示的宽度能显示10位。在使用id时,假如我给id输入10,那么mysql会默认给你存储0000000010。当你输入的数据不足10位时,会自动帮你补全位数。假如我设计的id字段是int(20),那么我在给id输入10时,mysql会自动补全18个0,补到20位为止。
是基于索引来完成行锁的
例如:select * from a_table where id = 1 for update;
for update 可以根据条件来完成行锁定,并且id是有索引键的列,如果id不是索引键,那么innodb将完成表锁
在分布式系统中是如何处理高并发的。 由于在高并发的环境下,来不及同步处理用户发送的请求,则会导致请求发生阻塞。比如说,大量的insert,update之类的请求同时到达数据库MYSQL,直接导致无数的行锁表锁,甚至会导致请求堆积很多。从而触发 too many connections 错误。使用消息队列可以解决【异步通信】
JMS的客户端之间可以通过JMS服务进行异步的消息传输
JMS的API是一个消息服务的规范,运行应用程序组件基于JavaEE平台创建,发送,接收和读取消息
是一个提供统一消息服务的应用层标准,是应用协议的一个开放标准
为面向消息的中间件设计,兼容JMS
基于此协议的客户端与消息中间件可传递消息,不受客户端/中间件不同产品,不同开放语言等限制。
通过lastinsertid()获取刚插入记录的自增主键值,在insert语句执行后,执行select LASTINSERTID()就可以回去自增主键
select LAST_INSERT_ID() INSERT INTO USER(username,birthday,sex,address) VALUES(#{username},#{birthday},#{sex},#{address})1)一级缓存: 基于PerpetualCache 的HashMap 本地缓存,其存储作用域为
Session,当Session flush 或close 之后,该Session 中的所有Cache 就
将清空, 默认打开一级缓存。
2)二级缓存与一级缓存其机制相同,默认也是采用PerpetualCache,HashMap
存储,不同在于其存储作用域为Mapper(Namespace),并且可自定义存储源,
如Ehcache。默认不打开二级缓存,要开启二级缓存,使用二级缓存属性类需要
实现Serializable 序列化接口(可用来保存对象的状态),可在它的映射文件中配置
;
3)对于缓存数据更新机制,当某一个作用域(一级缓存Session/二级缓存
Namespaces)的进行了C/U/D 操作后,默认该作用域下所有select 中的缓存将
被clear。
有联合查询和嵌套查询,
联合查询是几个表联合查询,只查询一次,通过resultMap里面配置association节点配置一对一的类就可以完成
嵌套查询是先查一个表,再根据这个表的结果的外键id,去再和另一个表里面的查询数据,也是通过association配置,但另一个表的查询是通过select属性配置。
有联合查询和嵌套查询。
联合查询是几个表联合查询,只查询一次,通过在
resultMap 里面的collection 节点配置一对多的类就可以完成;
嵌套查询是先查一个表,根据这个表里面的结果的外键id,去再另外一个表里面查询数据,也是通过
配置collection,但另外一个表的查询通过select 节点配置。
第一种是使用标签,逐一定义 数据库列名与对象属性 之间的映射关系
第二种是使用sql列别名功能,将列的别名书写为对象属性名
有了列名与属性名的映射关系后,Mybatis 通过反射创建对象,同时使用反射给
对象的属性逐一赋值并返回,那些找不到映射关系的属性, 是无法完成赋值的。
第一种:直接传参法:在java代码添加sql通配符
string wildcardname = "%smi%"; list names = mapper.selectlike(wildcardname); select * from foo where bar like #{value}第二种:在sql语句中拼接通配符,会引起sql注入
string wildcardname = "smi"; list names = mapper.selectlike(wildcardname); select * from foo where bar like "%"${value}"%"第三种:CONCAT()函数
MySQL的 CONCAT()函数用于将多个字符串连接成一个字符串,是最重要的mysql函数之一。
List selectBykeyWord(@Param("keyword") String keyword); SELECT * FROM t_role WHERE role_name LIKE CONCAT('%',#{keyword},'%') OR id LIKE CONCAT('%',#{keyword},'%') OR role_type LIKE CONCAT('%',#{keyword},'%')第四种:MyBatis的bind
List selectBykeyWord(@Param("keyword") String keyword); SELECT * FROM t_role WHERE role_name LIKE #{pattern} OR id LIKE #{pattern} OR role_type like #{pattern}mybatis是一个半ORM(对象关系映射)框架,内部封装了jdbc,开发只需要关注sql本身,不需要去处理驱动加载,创建连接,创建statement等繁琐的过程,我们只要编写原生的sql,可以控制sql执行性能,灵活度高
如果配置了namespace,那么当然可以重复,因为我们的Statement实际上就是namespace+id
Mybatis使用RowBounds对象进行分页,它是针对ResultSet结果集执行的内存分页,非物理分页,可以在sql内直接书写带有物理分页的参数来完成物理分页功能,也可以使用分页插件来完成物理分页。
分页插件的基本原理是使用Mybatis提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的sql,然后重写sql,根据dialect方言,添加对应的物理分页语句和物理分页参数。
举例:
select * from student拦截sql后重写为:
select t.* from (select * from student)t limit 0,10原理:
Mybatis仅可以编写针对ParameterHander、ResultSetHandler、StatementHander、Executor这4种接口的插件,Mybatis使用JDK的动态代理,为需要拦截的接口生成代理对象以实现接口方法拦截功能,每当执行这4种接口接口对象的方法时,就会进入拦截方法,具体就是InvocationHandler的invoke()方法,当然,只会拦截那些你指定需要拦截的方法。
实现Mybatis的Interceptor接口并复写intercept()方法,然后在给插件编写注解,指定要拦截哪一个接口的哪些方法即可,记住,别忘了在配置文件中配置你编写的插件。
Mybatis仅支持association关联对象和collection关联集合对象的延迟加载,association指的就是1对1,collection指的就是1对多查询,在mybatis配置文件中,可以配置是否启动延迟加载lazyLoadingEnabled=true|false
它的原理是,使用CGLIB创建目标对象的代理对象,当调动目标方法时,进入拦截器方法,比如调用a.getB.getName(),拦截器invoke()方法发现a.getB()是null值,那么就会单独发送事先保存好的查询关联B对象的sql,把B查询上来,然后调用a.setB(b),于是a的对象b属性就有值了,接着完成a.getB().getName()方法的调用。这就是延迟加载的基本原理。
当然了,不光是Mybatis,几乎所有的包括Hibernate,支持延迟加载的原理都是一样的。
作用范围:Executor的这些特点,都严格限制在S生命周期范围内。
注解装配在spring中时默认关闭的,所以需要在spring的核心配置文件中配置一下才能使用基于注解的装配模式。
常用的注解:
@Component :这将java 类标记为bean。它是任何Spring 管理组件的通
用构造型。spring 的组件扫描机制现在可以将其拾取并将其拉入应用程序环境
中。
@Controller :这将一个类标记为Spring Web MVC 控制器。标有它的
Bean 会自动导入到IoC 容器中。
@Service :此注解是组件注解的特化。它不
会对@Component 注解提供任何其他行为。您可以在服务层类中使用
@Service 而不是@Component,因为它以更好的方式指定了意图。
@Repository :这个注解是具有类似用途和功能的@Component 注解的特
化。它为DAO 提供了额外的好处。它将DAO 导入IoC 容器,并使未经检查
的异常有资格转换为Spring DataAccessException。
应用于bean属性的setter方法,此注解仅指示必须在配置时使用bean定义中的显式属性值或者使用自动装配填充受影响的bean属性。如果尚未填充受影响的bean属性,则容器将抛出BeanInitializationException
public class Employee { private String name; @Required public void setName(String name){ this.name=name; } public string getName(){ return name; } }@Autowired 可以更准确地控制应该在何处以及如何进行自动装配。此注解用于
在setter 方法,构造函数, 具有任意名称或多个参数的属性或方法上自动装配
bean。默认情况下,它是类型驱动的注入。
修饰语 【扩了伐i】
当您创建多个相同类型的bean 并希望仅使用属性装配其中一个bean 时,您可
以使用@ 注解和@Autowired 通过指定应该装配哪个确切的bean
来消除歧义。
例如,这里我们分别有两个类, Employee 和EmpAccount。在EmpAccount
中, 使用@ 指定了必须装配id 为emp1 的bean。
将特定的http请求映射到将处理相应请求的控制器中的特定类,方法。
构造函数注入
setter注入
接口注入
spring中,仅使用构造函数和setter注入
propagation: 用来设置事务的传播行为
事务的传播行为:一个方法运行在一个开启了事务的方法中时,当前方法是使用原来的事务还是开启一个新的事务 propagation.REQUIRED:默认值,使用原来的事务 propagation.REAUIRES_NEW: 将原来的事务挂起,开启一个新的事务isolation:用来设置事务的隔离级别
Isolation.REPEATABLE_READ: 可重复读,MySQL默认的隔离级别 Isolation.READ_COMMITTED: 读已提交,Oracle默认的隔离级别,开发时通常使用的隔离级别脏读:
Transaction01将某条记录的age值从20修改为30 Transaction02读取了Transaction01更新后的值30 Transaction01回滚,age值恢复到了20 Transaction02读取到的30就是一个无效的值当前事务读取到了其他事务更新还没有提交的数据
不可重复读
Transaction01读取了age的值为20 Transaction02将age值修改为30 Transaction01再次读取age的值为30,和第一次读取不一致幻读
Transaction01读取了STUDENT表中的一部分数据 Transaction02向STUDENT表中插入了新的行 Transaction01读取了STUDENT表时,多了一些行读未提交:READ UNCOMMITTED
允许Transaction01读取Transaction02未提交的修改读已提交:READ COMMITTED read committed
要求Transaction01只能读取Transaction02已提交的修改可重复读:REPEATABLE READ repeatable read
确保Transaction01可以多次从一个字段中读取到相同的值,即Transaction执行期间禁止其他事务对这个字段进行更新串行化:SERIALIZABLE serializable
确保Transaction01可以多次从一个表中读取到相同的行,在Transaction01执行期间禁止其他事务对这个表进行添加,更新删除操作,可以避免任何并发问题,但性能低下
在springmvc-xml中通过开启mvc:annotation-driven来实现注解处理器和适配器的开启
下一篇:JAVA面试(上)
皓盘云建最新版下载v9.0 安卓版
53.38MB |商务办公
ris云客移动销售系统最新版下载v1.1.25 安卓手机版
42.71M |商务办公
粤语翻译帮app下载v1.1.1 安卓版
60.01MB |生活服务
人生笔记app官方版下载v1.19.4 安卓版
125.88MB |系统工具
萝卜笔记app下载v1.1.6 安卓版
46.29MB |生活服务
贯联商户端app下载v6.1.8 安卓版
12.54MB |商务办公
jotmo笔记app下载v2.30.0 安卓版
50.06MB |系统工具
鑫钜出行共享汽车app下载v1.5.2
44.7M |生活服务
2022-03-26
2022-03-26
2022-03-26
2022-03-26
2022-03-26
2022-03-26
2022-03-26
2022-03-26
2022-02-15
2022-02-14