TCP/IP五层模型:物理,数据链路,网络,传输,应用OSI7层模型:物理,数据链路,网络,传输,会话,表示,应用
干嘛用的?网络分层就是将网络节点所要完成的数据处理工作,分别交给不同的硬件和软件模块去完成
这些过程都使用了哪些协议
网页之间的交互是通过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报文,因此不能一起发送,所有需要四次握手
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命令用于查看当前正在运行的进程
ps-ef|grepjava//表示查看所有进程里cmd是java的进程信息ps-aux|grepjava//-aux显示所有状态kill-9[pid]//kill命令用于终止进程-9表示强迫进程立即停止Redisredis的好处Redis使用场景Redis持久化机制RDB的优点:节省磁盘空间,恢复数据快,虽然redis在fork时使用了写时拷贝技术,如果数据量大的话也是非常消耗性能的。
redis是单进程单线程的,redis利用队列技术将并发访问变为串行访问,消除了传统数据库串行控制的开销。
512M
为了达到最快的读写速度将数据都读到内存中,并通过异步的方式将数据写入磁盘,所以redis具有快速和数据持久化的特征。如果不将数据放在内存中,磁盘I/O速度为严重影响redis的性能。在内存越来越便宜的今天,redis将会越来越受欢迎。如果设置了最大使用的内存,则数据已有记录数达到内存限值后不能继续插入新值。
Redis可以使用主从同步,从从同步,第一次同步时,主节点做一次bgsave,并同时将后续修改操作记录到内存buffer,待完成后将rdb文件全量同步到复制节点,复制节点接受完成后将rdb镜像加载到内存,加载完成后,在通知主节点将期间修改的操作记录同步到复制节点进行重放就完成了同步过程。
数据库和缓存双缓存,双写,如何解决一致性问题
主从复制的好处:避免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分配的最后一个值,并且不需要指定表名称。
数据库在通过连接两张或多张表来返回记录时,都会生成一张中间的临时表,然后再将这张临时表返回给用户。在使用leftjoin时,on和where条件的区别如下:
四个基本要素:原子性,一致性,隔离性,持久性
drop直接删除表truncate删除表中的数据,在插入数据自增长id又从1开始truncatedelete删除表中的数据,可以加where语句
数据本身之外,数据库还维护着一个满足特定查找算法的数据结构,这些数据结构以某种方式指向数据,以帮助MySQL高效获取数据,这种数据结构就是索引。
相对于串行处理来说,并发事务处理能大大增加数据库资源的利用率,提高数据库系统的事务吞吐量,从而可以支持更多的用户
当两个或多个事务选择同一行,然后基于最初选定的值更新该行时,由于每个事务都不知道其他事务的存在,就会发生丢失更新问题——最后的更新覆盖了由其他事务所做的更新。例如,两个程序员修改同一java文件,每个程序员独立地更改其副本,然后保存更改后的副本,这样就覆盖了原始文档,最后保存其更改副本的编辑人员覆盖前一个程序员的更改。如果在一个程序员完成并提交事务之前,另一个程序员不能访问同一文件,则可避免此问题。
一个事务正在对一条记录做修改,在这个事务完成并提交前,这条记录的数据就处于不一致状态;这时,另一个事务也来读取同一条记录,如果不加控制,第二个事务读取了这些脏数据,并据此做进一步的处理,就会产生未提交的数据依赖关系,这种现象被形象的叫做脏读。一句话:事务A读取到了事务B已修改但尚未提交的数据,还在这个数据基础上做了操作,此时,事务B进行回滚,A读取的数据无效,不符合一致性要求。
一个数据按相同的查询条件重新读取以前检索过的数据,却发现其他事务插入了满足其条件查询的新数据,这种现象就称为幻读。一句话:事务A读取到了事务B提交的新增数据,不符合隔离性多说一句;幻读和脏读有点类似,脏读是事务B里面修改了数据,幻读是事务B里面新增了数据。更新丢失可以通过加锁来解决,“脏读”、“不可重复读”、“幻读”属于数据库一致性问题,由数据库提供一定的事务隔离机制来解决
数据库的隔离越严格,并发副作用越小,付出的代价也就越大,隔离的实质就是在一定程度上使事务串行化,这显然与并发是矛盾的。未提交读(Readuncommitted)已提交读(Readcommitted)可重复读(Repeatableread)可序列化(Serializable)
区别:char是一种固定长度的类型,varchar则是一种可变长度的类型含义:最多存放50个字符,varchar(50)和varchar(200)存储hello所占空间一样,但后者在排序时会消耗更多的内存,因为orderbycol采用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*froma_tablewhereid=1forupdate;
forupdate可以根据条件来完成行锁定,并且id是有索引键的列,如果id不是索引键,那么innodb将完成表锁
在分布式系统中是如何处理高并发的。由于在高并发的环境下,来不及同步处理用户发送的请求,则会导致请求发生阻塞。比如说,大量的insert,update之类的请求同时到达数据库MYSQL,直接导致无数的行锁表锁,甚至会导致请求堆积很多。从而触发toomanyconnections错误。使用消息队列可以解决【异步通信】
JMS的客户端之间可以通过JMS服务进行异步的消息传输JMS的API是一个消息服务的规范,运行应用程序组件基于JavaEE平台创建,发送,接收和读取消息
是一个提供统一消息服务的应用层标准,是应用协议的一个开放标准为面向消息的中间件设计,兼容JMS
基于此协议的客户端与消息中间件可传递消息,不受客户端/中间件不同产品,不同开放语言等限制。
有联合查询和嵌套查询,联合查询是几个表联合查询,只查询一次,通过resultMap里面配置association节点配置一对一的类就可以完成嵌套查询是先查一个表,再根据这个表的结果的外键id,去再和另一个表里面的查询数据,也是通过association配置,但另一个表的查询是通过select属性配置。
有联合查询和嵌套查询。联合查询是几个表联合查询,只查询一次,通过在resultMap里面的collection节点配置一对多的类就可以完成;嵌套查询是先查一个表,根据这个表里面的结果的外键id,去再另外一个表里面查询数据,也是通过配置collection,但另外一个表的查询通过select节点配置。
第一种是使用标签,逐一定义数据库列名与对象属性之间的映射关系第二种是使用sql列别名功能,将列的别名书写为对象属性名有了列名与属性名的映射关系后,Mybatis通过反射创建对象,同时使用反射给对象的属性逐一赋值并返回,那些找不到映射关系的属性,是无法完成赋值的。
第一种:直接传参法:在java代码添加sql通配符
stringwildcardname="%smi%";list
stringwildcardname="smi";list
MySQL的CONCAT()函数用于将多个字符串连接成一个字符串,是最重要的mysql函数之一。
List
如果配置了namespace,那么当然可以重复,因为我们的Statement实际上就是namespace+id
Mybatis使用RowBounds对象进行分页,它是针对ResultSet结果集执行的内存分页,非物理分页,可以在sql内直接书写带有物理分页的参数来完成物理分页功能,也可以使用分页插件来完成物理分页。分页插件的基本原理是使用Mybatis提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的sql,然后重写sql,根据dialect方言,添加对应的物理分页语句和物理分页参数。
举例:
select*fromstudent拦截sql后重写为:
selectt.*from(select*fromstudent)tlimit0,10简述Mybatis的插件运行原理原理: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的这些特点,都严格限制在SqlSession生命周期范围内。
注解装配在spring中时默认关闭的,所以需要在spring的核心配置文件中配置一下才能使用基于注解的装配模式。
@Controller:这将一个类标记为SpringWebMVC控制器。标有它的Bean会自动导入到IoC容器中。
@Service:此注解是组件注解的特化。它不会对@Component注解提供任何其他行为。您可以在服务层类中使用@Service而不是@Component,因为它以更好的方式指定了意图。
@Repository:这个注解是具有类似用途和功能的@Component注解的特化。它为DAO提供了额外的好处。它将DAO导入IoC容器,并使未经检查的异常有资格转换为SpringDataAccessException。
应用于bean属性的setter方法,此注解仅指示必须在配置时使用bean定义中的显式属性值或者使用自动装配填充受影响的bean属性。如果尚未填充受影响的bean属性,则容器将抛出BeanInitializationException
publicclassEmployee{privateStringname;@RequiredpublicvoidsetName(Stringname){this.name=name;}publicstringgetName(){returnname;}}@Autowired注解有什么用?@Autowired可以更准确地控制应该在何处以及如何进行自动装配。此注解用于在setter方法,构造函数,具有任意名称或多个参数的属性或方法上自动装配bean。默认情况下,它是类型驱动的注入。
publicclassEmployee{privateStringname;@AutowiredpublicvoidsetName(Stringname){this.name=name;}publicstringgetName(){returnname;}}qualifier修饰语【扩了伐i】
当您创建多个相同类型的bean并希望仅使用属性装配其中一个bean时,您可以使用@Qualifier注解和@Autowired通过指定应该装配哪个确切的bean来消除歧义。例如,这里我们分别有两个类,Employee和EmpAccount。在EmpAccount中,使用@Qualifier指定了必须装配id为emp1的bean。
构造函数注入setter注入接口注入spring中,仅使用构造函数和setter注入
当前事务读取到了其他事务更新还没有提交的数据
在springmvc-xml中通过开启mvc:annotation-driven来实现注解处理器和适配器的开启