char与varchar的区别
最大长度
char最大长度255字符
varchar最大长度65535字节
定长
char定长,不足的部分
空间使用
char浪费空间,varchar更节省空间
查找效率
char查找效率很高,varchar查找效率偏低
尾部空格
char插入可省略,varchar插入不会省略,查找时省略
微服务架构设计原则
●单一职责原则指的是每一个微服务模块,只关心自己的业务规则。例如订单模块只关心订单的相关业务,不牵扯其他业务的逻辑。
●服务自治原则每一个微服务模块的开发,需要有自己的开发、测试、运维、部署这一条独立的栈,并且有自己的数据库等一切,完全把其当成一个单独的项目来做,不牵扯到其它无关业务。
●轻量级通信原则微服务的通信协议需要跨平台、跨语言的通信协议,因为微服务是不绑定技术栈的,不论使用Java、PHP还是.net去开发Web系统,它们之间的通信一定是去语言特色的。
●接口明确原则前面提到了微服务的“接口调整成本高”,那么怎么去避免它呢?我们一开始就应该规划好微服务的模块是一种什么样的模型,尽量去避免A接口的改动会导致B接口的改动这种情况。
ps:运维监控变得更难
SpringCloud五大组件
服务发现-Netflix Eureka(注册中心)
作用:实现服务治理(服务注册与发现)
简介:为了保证其高可用,单个服务通常会集群部署。由于网络原因或者自身的原因,服务并不能保证100%可用,如果单个服务出现问题,调用这个服务就会出现线程阻塞,此时若有大量的请求涌入,Servlet容器的线程资源会被消耗完毕,导致服务瘫痪。服务与服务之间的依赖性,故障会传播,会对整个微服务系统造成灾难性的严重后果,这就是服务故障的“雪崩”效应。
客服端负载均衡-Netflix Ribbon
作用:实现客户端的软件负载均衡算法
简介:Spring Cloud Ribbon是一个基于HTTP和TCP的客户端负载均衡工具,它基于Netflix Ribbon实现。通过Spring Cloud的封装,可以让我们轻松地将面向服务的REST模版请求自动转换成客户端负载均衡的服务调用。
断路器-Netflix Hystrix
作用:断路器,保护系统、控制故障范围
简介:为了保证其高可用,单个服务通常会集群部署。由于网络原因或者自身的原因,服务并不能保证100%可用,如果单个服务出现问题,调用这个服务就会出现线程阻塞,此时若有大量的请求涌入,Servlet容器的线程资源会被消耗完毕,导致服务瘫痪。服务与服务之间的依赖性,故障会传播,会对整个微服务系统造成灾难性的严重后果,这就是服务故障的“雪崩”效应。
服务网关-Netflix Zuul
作用:api网关,路由,负载均衡等多种作用
简介:类似nginx实现反向代理功能,增加了配合其他组件的特性。在微服务架构中,后端服务往往不直接开放给调用端,而是通过一个API网关根据请求的url,路由到相应的服务。当添加API网关后,在第三方调用端和服务提供方之间就创建了一面墙,这面墙直接与调用方通信进行权限控制,后将请求均衡分发给后台服务端。
分布式配置-Spring Cloud Config
作用:配置管理
简介:SpringCloud Config提供服务器端和客户端。服务器存储后端的默认实现使用git,因此它轻松支持标签版本的配置环境,以及可以访问用于管理内容的各种工具。这个还是静态的,得配合Spring Cloud Bus实现动态的配置更新。
Servlet
生命周期
init() 初始化阶段
Servlet容器加载Servlet,加载完成后,Servlet容器会创建一个Servlet实例并调用init()方法,init()方法只会调用一次
Servlet容器会在一下几种情况装载Servlet:
Servlet容器启动时自动装载某些servlet,实现这个需要在web.xml文件中添加1
在Servlet容器启动后,客户首次向Servlet发送请求
Servlet类文件被更新后,重新装载
service() 处理客服端请求阶段
每收到一个客户端请求,服务器就会产生一个新的线程去处理。
对于用户的Servlet请求,Servlet容器会创建一个特定于请求的ServletRequest和ServletResponse。
对于tomcat来说,它会将传递来的参数放入一个HashTable中,这是一个String–>String[]的键值映射
destroy() 终止阶段
当web应用被终止,或者Servlet容器终止运行,或者Servlet重新装载Servlet新实例时,Servlet容器会调用Servlet的destroy()方法
程序入口点
service()
工作原理
客服发送一个请求,servlet调用service()方法对请求进行响应,service方法会对请求的方法进行匹配,进入相应的逻辑层,完成请求的响应。
但是Servlet接口和GenericServlet接口中没有doGet(),doPost()等方法,HttpServlet中定义了这些,但是返回的都是Error信息,所以每次定义Servlet都要重写这些方法。
Sertvlet和GenericServlet是不特定于任何协议的,而HttpServlet是特定于Http协议的,所以HttpServlet中的service()方法中将ServletRequest,ServletResponse强转为HttpRequest和HttpResponse,最后调用自己的service方法去完成响应。
Java线程池
线程池的创建
可以通过ThreadPoolExecutor来创建一个线程池。
创建线程池需要的几个参数:
**corePoolSize(线程池的基本大小):**当提交一个任务到线程池时,线程池会创建一个线程来执行任务,即使其他空闲的基本线程能够执行新任务也会创建线程,等到需要执行的任务数大于线程池基本大小时就不再创建。如果调用了线程池的prestartAllCoreThreads方法,线程池会提前创建并启动所有基本线程。
**runnableTaskQueue(任务队列):**用于保存等待执行的任务的阻塞队列。 可以选择以下几个阻塞队列。
**ArrayBlockingQueue:**是一个基于数组结构的有界阻塞队列,此队列按 FIFO(先进先出)原则对元素进行排序。
**LinkedBlockingQueue:**一个基于链表结构的阻塞队列,此队列按FIFO (先进先出) 排序元素,吞吐量通常要高于ArrayBlockingQueue。
**SynchronousQueue:**一个不存储元素的阻塞队列。
**PriorityBlockingQueue:**一个具有优先级的无限阻塞队列。
**maximumPoolSize(线程池最大大小):**线程池允许创建的最大线程数。如果队列满了,并且已创建的线程数小于最大线程数,则线程池会再创建新的线程执行任务。
**RejectedExecutionHandler(饱和策略):**当队列和线程池都满了,说明线程池处于饱和状态,那么必须采取一种策略处理提交的新任务。这个策略默认情况下是AbortPolicy,表示无法处理新任务时抛出异常。
线程池类型
newCachedThreadPool
创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。示例代码如下:
线程池为无限大,当执行第二个任务时第一个任务已经完成,会复用执行第一个任务的线程,而不用每次新建线程。
newFixedThreadPool
创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。示例代码如下:
因为线程池大小为3,每个任务输出index后sleep 2秒,所以每两秒打印3个数字。定长线程池的大小最好根据系统资源进行设置。
如Runtime.getRuntime().availableProcessors()
newScheduleThreadExecutor
创建一个定长线程池,支持定时及周期性任务执行。延迟执行示例代码如下:
表示延迟3秒执行,定期执行示例代码如下:
表示延迟1秒后每3秒执行一次
newSingleThreadPool
创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。示例代码如下:
Java线程池获取线程名称
`Thread thread1 = new Thread(new MyThread());`
`thread1.setName("thread001");`
`thread1.start();`
//设置线程名称,
//MyThread 的 run 方法中可以取到线程名称
`Thread.currentThread().getName()`
MyBatis
映射器:#{}和${}的区别
-
#{}是占位符,预编译处理;${}是拼接符,字符串替换,没有预编译处理。
-
Mybatis在处理#{}时,#{}传入参数是以字符串传入,会将SQL中的#{}替换为?号,调用PreparedStatement的set方法来赋值。
-
Mybatis在处理时,是原值传入,就是把{}替换成变量的值,相当于JDBC中的Statement编译
-
变量替换后,#{} 对应的变量自动加上单引号 ‘’;变量替换后,${} 对应的变量不会加上单引号 ‘’
-
#{} 可以有效的防止SQL注入,提高系统安全性;${} 不能防止SQL 注入
-
#{} 的变量替换是在DBMS 中;${} 的变量替换是在 DBMS 外
动态SQL
Mybatis动态sql是做什么的?都有哪些动态sql?能简述一下动态sql的执行原理不?
Mybatis动态sql可以让我们在Xml映射文件内,以标签的形式编写动态sql,完成逻辑判断和动态拼接sql的功能,Mybatis提供了9种动态sql标签trim|where|set|foreach|if|choose|when|otherwise|bind。
其执行原理为,使用OGNL从sql参数对象中计算表达式的值,根据表达式的值动态拼接sql,以此来完成动态sql的功能。
分页
Mybatis使用RowBounds对象进行分页,它是针对ResultSet结果集执行的内存分页,而非物理分页,可以在sql内直接书写带有物理分页的参数来完成物理分页功能,也可以使用分页插件来完成物理分页。
分页插件的基本原理是使用Mybatis提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的sql,然后重写sql,根据dialect方言,添加对应的物理分页语句和物理分页参数。
举例:select * from student,拦截sql后重写为:select t.* from (select * from student) t limit 0, 10
XML的解析方式SAX与DOM的区别
SAX(Simple API for XML)
- 只能读,不能修改,只能顺序访问,适合解析大型XML,解析速度快
- 常应用于处理大量数据的XML,实现异构系统的数据访问,实现跨平台
- 从文档的开始通过每一节点移动,定位一个特定的节点
DOM(Document Object Model)
- 不仅能读,还能修改,而且能够实现随机访问,缺点是解析速度慢,适合解析小型文档
- 一般应用与小型的配置XML,方便操作
- 为载入到内存的文档节点建立类型描述,呈现可横向移动、潜在巨大的树型结构
- 在内存中生成节点树操作代价昂贵