面试总结001

Collection

是集合中的顶级接口;

Set集合和LIst集合构成;

Set集合:唯一、无序

HashSet按照Hash算法存储集合中的元素,当向HashSet中添加元素时,根据HashCode()方法生成对象的HashCode值,然后根据HashCode的值来决定元素的位置。

哈希算法:将任意长度的二进制映射到固定长度的二进制。

HashCode()相同:比较地址;
==相同:比较地址;

==的作用:
基本数据类型(byte,short,char,int,long,float,double,boolean):比较的就是值是否相同;
引用数据类型:比较的是地址值是否相同(堆内存地址);
equals的作用:
底层源码:
public boolean equals(Object obj) {
//this - s1
//obj - s2
return (this == obj);
}
说明equals方法底层还是进行地址值得比较,但是string,Integer,Data这些包装类自己重写了Equals()方法;

List:有序、不唯一

ArrayList:线程不安全的
1.实现是基于动态数组实现的数据结构。(内存空间紧密排列)
LinkedList:
1.实现是基于链表的数据结构;

区别:

1.对于随机访问的get(),set()方法,arrayList的速度大于LinkedList,因为ArrayList是紧密顺序的,可以根据索引下标查找。
2.对于新增、删除操作,LinkedList快,因为ArrayList需要移动数据补空。
Map集合:K-V
Key值是Collection集合,key值不能重复。
实现类:HashMap、HashTable、TreeMap、LinkedHashMap

HashMap:

根据键的HashCode存储数据,根据键值能快速查找数据,最多一条记录的键为Null,允许多条记录的值为null,非线程同步。
TreeTable:能把保存的的记录根据键排序,默认是升序。
HashTable:k-v都不允许为空,支持线程同步。

遍历Map集合:
一般方法:entrySet()的返回值Map集合实体
//返回实体
Map.Entry<String, Integer> entrys = Map.entrySet();

//遍历entry
Forch(Map.Entry<String, Integer> entry ; entrys){
Entry.getKey();
Entry.getValue();
}
JDK1.8 lamada表达式
map.forEach((K,V)->{“item”+k ,“value”+v}

Cookie与session

会话:是指客户端与服务器之间连续发生请求和响应的过程。

cookie是客户端技术,将数据保存到客户端浏览器内存中,默认关闭浏览器cookie就会被销毁,不过可将cookie保存到磁盘中。
// 获得Cookie:
Cookie[] request.getCookies();
// 向浏览器回写Cookie:
response.addCookie(Cookie cookie);
cookie的存储大小一般不超过4K,所以cookie一般用来存储小量数据。
cookie和session结合使用
由于cookie存储用户信息不安全,所以一般cookie会存储session_id,在请求服务器时,会带上session_id传入服务器,服务器会在session库中查找是否存在该session_id,并获取用户信息;

session是服务端技术,将数据保存到服务端内存中。
httpSession:私有的数据.登录用户的信息.

  • 生命周期:
    • 服务器端第一次调用getSession()方法时候.才会创建一个session对象.
    • session销毁三种情况:
      • session过期:默认过期时间30分钟.
      • 非正常关闭服务器:(正常关闭服务器 序列化到硬盘)
      • 调用session.invalidate();

日志:

级别:由高到低,日志级别越高记录的信息越少;
OFF最高级别,用于关闭所有日志记录。
ERROR:指出虽然发生错误事件,但仍然不影响系统的继续运行。
Warn:警告。
INFO:生产环境中输出程序中的重要信息。
DEBUG:针对调试应用程序提供帮助,在控制台打印给程序员看。

使用:
private static Logger logger = Logger.getLogger(Test.class);
// 记录debug级别的信息
logger.debug(“This is debug message.”);
// 记录info级别的信息
logger.info(“This is info message.”);
// 记录error级别的信息
logger.error(“This is error message.”);
.

代码中如何正确使用日志?

1、ERROR级别:一般在系统出错时,记录错误信息;
2、INFO级别:自己想看什么信息;
3、DEBUG级别:打印信息到控制台,一般打印一些SQL语句,传入的参数;

Spirng boot项目实现日志的统一管理:

核心思想:aop面向切面编程;

具体实现:
1.自定义注解
2.构建切面类
3.在类和方法上加入@注解使用
对于多环境日志控制使用spring profiles 切换环境

事物的特性:

原子性:强调事务的不可分割.
一致性:强调的是事务的执行的前后,数据的完整性要保持一致.
隔离性:一个事务的执行不应该受到其他事务的干扰.
持久性:事务一旦结束(提交/回滚)数据就持久保持到了数据库.

事物的隔离级别:

二、事务的并发问题
  1、脏读:事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据
  2、不可重复读:事务 A 多次读取同一数据,事务 B 在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果 不一致。
  3、幻读:系统管理员A将数据库中所有学生的成绩从具体分数改为ABCDE等级,但是系统管理员B就在这个时候插入了一条具体分数的记录,当系统管理员A改结束后发现还有一条记录没有改过来,就好像发生了幻觉一样,这就叫幻读。
  小结:不可重复读的和幻读很容易混淆,不可重复读侧重于修改,幻读侧重于新增或删除。解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表

Linux常用命令:

1.Cd 进入文件夹 参数实例:…/bin/tomcat-8080/date
2.Ls 查看当前文件夹中所有目录下 参数实例:ls –a 查看所有的包括隐藏文件;
3.Mkdir 创建目录 参数实例:mkdir app
4.Rmdir 删除目录 参数实例:Rmdir app
5. cat 显示文件内容 参数实例:cat yum.conf
tail 显示文件后几行内容 参数实例:tail –f notes.log
当我们需要持续显示文件后几行内容时,列如打印运行时日志时使用此命令
-f 循环执行此命令。

  1. vim 编辑文件内容
    参数实例:打开文件:vim file
    退出:esc :q
    修改文件:输入i进入插入模式
    保存并退出:esc:wq

不保存退出:esc:q!

3种进入插入模式:
i:在当前的光标所在处插入
o:在当前光标所在的行的下一行插入
a:在光标所在的下一个字符插入

快捷键:
dd – 快速删除一行
R – 替换
7. tar打包文件
Gzip压缩文件
常用参数:
-c:创建一个新tar文件
-v:显示运行过程的信息
-f:指定文件名
-z:调用gzip压缩命令进行压缩
-t:查看压缩文件的内容
-x:解开tar文件
参考:
打包:
tar –cvf xxx.tar ./*
打包并且压缩:
tar –zcvf xxx.tar.gz ./*

解压
tar –xvf xxx.tar
tar -xvf xxx.tar.gz -C /usr/aaa

  1. 查看日志的常用方法:

1.Tail -f log.out 实时监控10行日志;

2.cat -n test.log |grep “debug” 得到关键日志的行号

应用场景二:根据日期查询日志
grep 查询符合条件的字符串;
//先查询该时间点是否存在
grep ‘2014-12-17 16:17:20’ test.log
sed -n ‘/2014-12-17 16:17:20/,/2014-12-17 16:17:36/p’ test.log

指定端口号查看进程情况:netstat -tunlp|grep 22
查看某个进程:ps –ef | grep 进程名称
ps –aux | grep 进程名称

参考资料:https://www.cnblogs.com/savorboard/p/distributed-system-transaction-consistency.html

分布式事务:

CAP原则:分布式系统的CAP理论:理论首先把分布式系统中的三个特性进行了如下归纳:
  ● 一致性(C):在分布式系统中的所有数据备份,在同一时刻是否同样的值。(等同于所有节点访问同一份最新的数据副本)
● 可用性(A):在集群中一部分节点故障后,集群整体是否还能响应客户端的读写请求。(对数据更新具备高可用性)
● 分区容错性(P):以实际效果而言,分区相当于对通信的时限要求。系统如果不能在时限内达成数据一致性,就意味着发生了分区的情况,必须就当前操作在C和A之间做出选择。

三、取舍策略
CAP三个特性只能满足其中两个,那么取舍的策略就共有三种:

CA without P:如果不要求P(不允许分区),则C(强一致性)和A(可用性)是可以保证的。但放弃P的同时也就意味着放弃了系统的扩展性,也就是分布式节点受限,没办法部署子节点,这是违背分布式系统设计的初衷的。

CP without A:如果不要求A(可用),相当于每个请求都需要在服务器之间保持强一致,而P(分区)会导致同步时间无限延长(也就是等待数据同步完才能正常访问服务),一旦发生网络故障或者消息丢失等情况,就要牺牲用户的体验,等待所有数据全部一致了之后再让用户访问系统。设计成CP的系统其实不少,最典型的就是分布式数据库,如Redis、HBase等。对于这些分布式数据库来说,数据的一致性是最基本的要求,因为如果连这个标准都达不到,那么直接采用关系型数据库就好,没必要再浪费资源来部署分布式数据库。

AP wihtout C:要高可用并允许分区,则需放弃一致性。一旦分区发生,节点之间可能会失去联系,为了高可用,每个节点只能用本地数据提供服务,而这样会导致全局数据的不一致性。典型的应用就如某米的抢购手机场景,可能前几秒你浏览商品的时候页面提示是有库存的,当你选择完商品准备下单的时候,系统提示你下单失败,商品已售完。这其实就是先在 A(可用性)方面保证系统可以正常的服务,然后在数据的一致性方面做了些牺牲,虽然多少会影响一些用户体验,但也不至于造成用户购物流程的严重阻塞。

RestFul风格总结

RestFul是什么:URL定位资源,用HTTP动词(GET,POST,DELETE,DETC)描述操作。

主要作用:Rest主要用来定义接口名称,根据HTTP动词来描述操作。

实例:
URL路径 请求类型
1.新增类型接口:test/user post
2.删除类型接口:test/user delete
3.修改类型接口:test/user put
4.查找类型接口:test/user get

用请求类型区分调用的接口

Http超文本传输协议:
http请求报文:请求行、请求头、空行、请求体(请求数据);

http响应报文:状态行、响应头、空行、响应体;

SQL语句的调优

1.索引不是越多越好,一个表索引最多不超过6个,因为索引会影响update和insert操作。
2.Like语句的优化

4.避免类型转换;
5.子查询的性能又比外连接性能慢,尽量用外连接来替换子查询;

Nginx

常用操作:反向代理,静态资源访问;
主要是修改配置文件;

从原理上来说,代理服务器都是处理来自客户端的请求,并发送到目的服务器上;

正向代理:客户端与代理形成一个LAN,可以保护客户端的ip地址;
方向代理:代理与服务端形成一个LAN,可以保护服务端的ip地址;
Gitlib工具使用:
1.git与svn的区别:
核心:克隆一个跟中心版本库一模一样的本地版本库;
第一步:创建分支(相当于创建了本地版本)
第二步:update、commit、delete操作的都是本地仓库
第三部:推送到远程仓库;

面向对象的三大特性:封装、继承、多态;

JWT:json web token

分为三部分:头:记录token类型(“JWT”)和算法名称(“SHA256”)
载体
签名

线程与进程

进程和线程都是一个时间段的描述,是CPU工作时间段的描述。

下面细说背景:
CPU+RAM+各种资源(比如显卡,光驱,键盘,GPS, 等等外设)构成我们的电脑,但是电脑的运行,实际就是CPU和相关寄存器以及RAM之间的事情。

一个最最基础的事实:CPU太快,太快,太快了,寄存器仅仅能够追的上他的脚步,RAM和别的挂在各总线上的设备完全是望其项背。那当多个任务要执行的时候怎么办呢?轮流着来?或者谁优先级高谁来?不管怎么样的策略,一句话就是在CPU看来就是轮流着来。

一个必须知道的事实:执行一段程序代码,实现一个功能的过程介绍 ,当得到CPU的时候,相关的资源必须也已经就位,就是显卡啊,GPS啊什么的必须就位,然后CPU开始执行。这里除了CPU以外所有的就构成了这个程序的执行环境,也就是我们所定义的程序上下文。当这个程序执行完了,或者分配给他的CPU执行时间用完了,那它就要被切换出去,等待下一次CPU的临幸。在被切换出去的最后一步工作就是保存程序上下文,因为这个是下次他被CPU临幸的运行环境,必须保存

相当于CPU是皇上,其他的资源相当于妃子,妃子都准备好了,等着皇上;

串联起来的事实:前面讲过在CPU看来所有的任务都是一个一个的轮流执行的,具体的轮流方法就是:先加载程序A的上下文,然后开始执行A,保存程序A的上下文,调入下一个要执行的程序B的程序上下文,然后开始执行B,保存程序B的上下文。。。。

========= 重要的东西出现了========
进程和线程就是这样的背景出来的,两个名词不过是对应的CPU时间段的描述,名词就是这样的功能。

进程就是切换上下文切换的程序执行时间总和
= CPU加载上下文 + CPU执行 + CPU保存上下文

线程是什么呢?
进程的颗粒度太大,每次都要有上下的调入,保存,调出。如果我们把进程比喻为一个运行在电脑上的软件,那么一个软件的执行不可能是一条逻辑执行的,必定有多个分支和多个程序段,就好比要实现程序A,实际分成 a,b,c等多个块组合而成。那么这里具体的执行就可能变成:
程序A得到CPU =》CPU加载上下文,开始执行程序A的a小段,然后执行A的b小段,然后再执行A的c小段,最后CPU保存A的上下文。
这里a,b,c的执行是共享了A的上下文,CPU在执行的时候没有进行上下文切换的。这里的a,b,c就是线程,也就是说线程是共享了进程的上下文环境,的更为细小的CPU时间段。

到此全文结束,再一个总结:

进程和线程都是一个时间段的描述,是CPU工作时间段的描述,不过是颗粒大小不同

进程是父亲,父亲拥有很多资源(上下文),线程是儿子,享受了父亲的资源,而且在此期间并没有换父亲;

进程是大的时间段,线程是小的时间段;

线程安全

当代码所在进程有个多线程同时运行,而这多个线程同时运行这个方法,必须a线程访问完后b线程才能访问,这个叫线程安全;(加锁机制)

多线程

常用的线程池:

1.newCacheThreadPool
2.newFixedThreadPool
3.newSingleThreadExecutor
4.newScheduleThreadPool

Shiro的使用

1.重写reaml方法实现认证、授权;
继承AuthorizingRealm 类重写doGetAuthorizationInfo与doGetAuthenticationInfo认证和授权方法;

认证:拿到session_id去sessionMangment里面查找是否存在;
授权:根据用户信息查询角色表获取权限;
2.观察者模式
3.装饰者模式
4.工厂模式
5.职责链模式:

工厂模式主要是为创建对象提供了接口

应用场景:在编码时不能预见需要创建哪种类的实例;
具体例子:相当于自动贩卖机,可以从中拿得各种不同的饮料;
工程模式分为三种:静态工厂模式,工厂方法模式,抽象工厂模式;

6.代理模式:静态代理,动态代理;

springboot自动配置的原理

1.启动根据@SpringBootApplication注解

2.@EnableAutoConfiguration和@ComponentScan开启自动配置

3.@Import注解中的 AutoConfigurationImportSelector类中的方法selectImports()会去扫描默认的类路径;
META-INF/spring.factories

4.读取对应maven中已经导入的jar,获取配置文件类,类文件属性都会有@xxxxProperties注解,从该注解获取属性信息;

常用数据结构

一:线性表
实现线性表的方式一般有两种,一种是使用数组存储线性表的元素,即用一组连续的存储单元依次存储线性表的数据元素。另一种是使用链表存储线性表的元素,即用一组任意的存储单元存储线性表的数据元素(存储单元可以是连续的,也可以是不连续的)。
1.数组:大小固定的数据结构;该结构数据之间连接紧密,是线性表,可以根据下标进行查找定位,查询快,但是在中间删除或新增需要移动补空花销较大,当数组大小超过时,可以通过new一个新数组替换当前数组;
底层实现数组的新增和删除:通过arrayList进行新增删除再转换回来;
2.链表
链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列节点组成,这些节点不必在内存中相连。每个节点由数据部分Data和链部分Next,Next指向下一个节点,这样当添加或者删除时,只需要改变相关节点的Next的指向,效率很高。

二、队列与栈
栈和队列也是比较常见的数据结构,它们是比较特殊的线性表,因为对于栈来说,访问、插入和删除元素只能在栈顶进行,对于队列来说,元素只能从队列尾插入,从队列头访问和删除。
三、树与二叉树
树可以随意节点
二叉树

四、图
分布式项目

SpringMVC核心处理流程:

1、DispatcherServlet前端控制器接收发过来的请求,交给HandlerMapping处理器映射器
2、HandlerMapping处理器映射器,根据请求路径找到相应的HandlerAdapter处理器适配器(处理器适配器就是那些拦截器或Controller)
3、HandlerAdapter处理器适配器,处理一些功能请求,返回一个ModelAndView对象(包括模型数据、逻辑视图名)
4、ViewResolver视图解析器,先根据ModelAndView中设置的View解析具体视图
5、然后再将Model模型中的数据渲染到View上
这些过程都是以DispatcherServlet为中轴线进行的。

分布式事物:tx-lcn补偿机制

1.简介:协调本地事物从而达到数据一致性;
3个概念:
创建事物组:事务发起方调用TxManager创建事务组对象,然后拿到事务标示GroupId的过程;
添加事务组:参与方(模块代码)在执行完业务方法以后,向TxManager发送通知消息;
关闭事务组:发起方执行完代码后,将执行状态结果通知txManager;
使用方法:
Springboot使用tx-lcn 在运行主类上加上@EnableTransactionManagerServer

1.导入依赖
2.在yml中加入tx-manager的地址;

使用:被调用的服务

事物发起方:

RabbitMQ

1.发送消息需要指定routing key 和消息内容
2.交换器会根据自身的二维表(组成:去哪个队列和routing key)查看是否符合匹配规则;
3.符合则消息存入改队列;

场景:解耦合,异步处理,流量削峰,秒杀;

Myql引擎

四.mysql引擎
mysql有4种引擎5.1版本以前默认的是myisam,5.1版本以后默认的是innodb
1.Innodb引擎概述
Innodb引擎提供了对数据库ACID事务的支持,并且实现了SQL标准的四种隔离级别。该引擎还提供了行级锁和外键约束,它的设计目标是处理大容量数据库系统,它本身其实就是基于MySQL后台的完整数据库系统,MySQL运行时Innodb会在内存中建立缓冲池,用于缓存数据和索引。而且它没有保存表的行数,当SELECT COUNT(*) FROM TABLE时需要扫描全表。当需要使用数据库事务时,该引擎当然是首选。由于锁的粒度更小,写操作不会锁定全表,所以在并发较高时,使用Innodb引擎会提升效率。但是使用行级锁也不是绝对的,如果在执行一个SQL语句时MySQL不能确定要扫描的范围,InnoDB表同样会锁全表

总结:提供事物支持,提供4种隔离级别,锁级别到行,运行时会建立缓存,但是不保存表的行数,当SELECT COUNT(*) FROM TABLE时需要扫描全表。当不能确定扫描范围时默认会锁全表;

2.myisam引擎
MyISAM是MySQL默认的引擎,但是它没有提供对数据库事务的支持,也不支持行级锁和外键,因此当INSERT(插入)或UPDATE(更新)数据时即写操作需要锁定整个表,效率便会低一些。不过和Innodb不同,MyISAM中存储了表的行数,于是SELECT COUNT() FROM TABLE时只需要直接读取已经保存好的值而不需要进行全表扫描。如果表的读操作远远多于写操作且不需要数据库事务的支持,那么MyISAM也是很好的选择。
总结:不支持事物,不支持行锁和外键,只支持表锁,会存储行数,因此SELECT COUNT(
) FROM TABLE不走全表扫描;

区别
1、MyISAM是非事务安全的,而InnoDB是事务安全的
2、MyISAM锁的粒度是表级的,而InnoDB支持行级锁
3、MyISAM支持全文类型索引,而InnoDB不支持全文索引
4、MyISAM相对简单,效率上要优于InnoDB,小型应用可以考虑使用MyISAM
5、MyISAM表保存成文件形式,跨平台使用更加方便
应用场景
1、MyISAM管理非事务表,提供高速存储和检索以及全文搜索能力,如果再应用中执行大量select操作,应该选择MyISAM
2、InnoDB用于事务处理,具有ACID事务支持等特性,如果在应用中执行大量insert和update操作,应该选择InnoDB

MySQl索引:

1.普通索引:没有限制;
2.唯一索引:UNIQUE 唯一,允许为空;
3.主键索引:是特殊的唯一索引,不允许为空;
4.全文索引:
5.组合索引:组合用

总结:索引会加快查询速度,但是会降低新增、修改、删除速度
分布式工程目录结构
Dubbo+zookeeper目录结构说明(最简单版本):

dddyun父工程:用于公共jar版本管理
dddyun-commons工具类工程:用于子工程之间公共工具的管理
dddyun-test真正写代码的工程(子工程都为聚合工程):
dddyun-api:存放实体类和接口工程
dddyun-serviceImpl:实现接口工程,dubbo中称为服务提供者
dddyun-control:控制层,调用服务层,dubbo中成为服务消费者
dddyun-dao:数据访问层,与数据库打交道

JVM虚拟机

JVM就是Java的运行环境;

1: 虚拟机并不神秘,在操作系统的角度看来,它只是一个普通进程。
2: 这个叫做虚拟机的进程比较特殊,它能够加载我们编写的class文件。如果把JVM比作一个人,那么class文件就是我们吃的食物。
3: 加载class文件的是一个叫做类加载器的子系统。就好比我们的嘴巴,把食物吃到肚子里。
4: 虚拟机中的执行引擎用来执行class文件中的字节码指令。就好比我们的肠胃,对吃进去的食物进行消化。
5: 虚拟机在执行过程中,要分配内存创建对象。当这些对象过时无用了,必须要自动清理这些无用的对象。清理对象回收内存的任务由垃圾收集器负责。就好比人吃进去的食物,在消化之后,必须把废物排出体外,腾出空间可以在下次饿的时候吃饭并消化食物。
后面将分析类加载子系统,内存分配,垃圾收集子系统的原理

线程的5种状态:

1.新建状态
2.就绪状态:调用了start()状态,等待获取CPU控制权;
3.运行状态;
4.阻塞状态
5.死亡状态;

http请求中get与post的区别

1.get与post简单来说:
2.Get可以在url上查看,post放在request body中;
3.Get请求长度有限制,Post没有;
4.Post比get安全;
复杂来说:http请求底层是tcp/ip通信协议;get与post都是http请求,所以get与post底层也是tcp/ip,底层来说get与post能做一样的事情,只不过是http的规定让get与post产生了差别;

重点:对于get方式,浏览器会把请求头和请求数据一起发送过去,服务器响应;
Post方式,浏览器会先发送请求头过去,响应100 continue,浏览器再发送请求数据;
所以get只产生一个tcp数据包,而post会产生两个;

RPC

Servlet生命周期

1.加载和实例化
2.初始化
3.请求处理
4.服务终止

谈谈你对MVC的理解:

MVC的处理过程:首先控制器接受用户的请求,调用相应的模型来进行业务处理,并返回数据给控制器。控制器调用相应的视图来显示处理的结果。

TCP与UDP的区别

Tcp:传输控制协议,用于计算机传输层协议;
Udp:用户数据报协议,用于计算机传输层协议;

区别:TCP是面向连接的,UDP是无连接的,即发送数据之前不需要建立连接;
TCP提供可靠的服务,无差错,不丢失,不重复;UDP不保证可靠性;
TCP面向字节流,UDP面向报文;
TCP首部开销20字节,UDP只有8个字节;

Java语言中默认定义了8个原始数据类型
大致可以分为4类:
整型:包含byte、short、int、long
浮点型:float、double
布尔型:boolean
字符:char

泛型的作用:

1.类型的参数,把类型向参数一样传递;

为什么要使用分布式?

1.单体项目执行效率有限;
2.模块的内聚性更高,更多的关注自身业务;
JVM垃圾回收机制:
1.引用计数器算法:使用计数+1,弃用时-1,为0时回收;
2.可达性算法;代码块结束了,按道理应该回收内存空间,但是外部还有对其的使用,不回收;

docker基本概念

分布式锁

redis锁
数据库乐观锁
Zookeeper锁

重载与重写的区别

重载(Overload):同一个类中多个方法具有相同的名字,但这些方法具有不同的参数列表,即参数的数量和参数的类型不能完全相同;
重写(Override):是子父类之间的,对父类函数进行重新定义,返回类型、方法名、参数个数和类型都必须相同;

抽象类与接口的区别

抽象类是对根源的抽象,而接口是对动作的抽象;对于抽象类;
比如,男人,女人这两个类,可以抽象出一个更高级的类人,而对于接口,我们可以拿叉子吃饭可以拿筷子吃饭,所以可以抽象出吃饭接口;
总结:1.抽象是abstract关键词,接口是interface关键词;
3.抽象类中可以写抽象方法和普通方法,如何继承抽象类那么必须实现抽象方法普通方法可以不用实现,实现某个接口必须实现所有方法;
4.抽象类是用来继承的,接口是用来实现的;
5.抽象类主要是用来抽象类别,接口主要是用来抽象方法功能;

多线程的实现方法:

1.继承thread类创建线程
2.实现Runnable接口创建线程
3.通过ExecutorServer创建4种线程池:
newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行

实例:还是重新Runnable的run()方法;

修饰符
Private私有 Protected保护 Public公有

查询学生表中有相同姓名的学生:
Select name from 学生表 group by name having count(*)>1
mysql与sql server的分页
Mysql: limit 0,10 从0号位置开始,向后展示10条;
Sql server:offset A rows ,将前A条记录舍去,fetch next B rows only ,向后在读取B条数据。

创建索引的语句:
create index index_name on table_name (column_list) ;

跨域请求
@CrossOrigin
Spring mvc版本4.2以上可以使用该注解;
@crossOrigin可以设置两个参数:
origins : 允许可访问的域列表
maxAge:准备响应前的缓存持续的最大时间(以秒为单位)。

方法二:1.实现Filter 接口重写doFilter()方法;
2.在web.xml配置引入实现的SimpleCORSFilter;

分布式总结
1.分布式目录结构:

dddyun父工程:用于公共jar版本管理
dddyun-commons工具类工程:用于子工程之间公共工具的管理
dddyun-test真正写代码的工程(子工程都为聚合工程):
dddyun-api:存放实体类和接口工程
dddyun-serviceImpl:实现接口工程,dubbo中称为服务提供者
dddyun-control:控制层,调用服务层,dubbo中成为服务消费者
dddyun-dao:数据访问层,与数据库打交道
2.Dubbo
Dubbo的核心概念(3点):
1.远程通信:实现不同服务器代码相互通信
2.集群容错:具有容错机制和软负载均衡;
3.自动发现:服务自动注册与发现,不需要写死服务提供方地址,注册中心基于接口名查询服务提供方的ip地址;

Dubbo+zookeeper整合与使用:
1.修改zookeeper的配置文件中的日志位置;
2.启动zookeeper,zkService.sh start
3.Dubbo配置消费者:

避免和 server 工程端口冲突

server.port=8081

Dubbo 服务消费者配置

spring.dubbo.application.name=consumer
spring.dubbo.registry.address=zookeeper://127.0.0.1:2181
spring.dubbo.scan=org.spring.springboot.controller

使用:
@Reference(version = “1.0.0”)
CityDubboService cityDubboService;

4.配置服务者:

Dubbo 服务提供者配置

spring.dubbo.application.name 应用名称
spring.dubbo.registry.address 注册中心地址
spring.dubbo.protocol.name 协议名称
spring.dubbo.protocol.port 协议端口
spring.dubbo.scan dubbo 服务类包目录

spring.dubbo.application.name=provider
spring.dubbo.registry.address=zookeeper://127.0.0.1:2181
spring.dubbo.protocol.name=dubbo
spring.dubbo.protocol.port=20880
spring.dubbo.scan=org.spring.springboot.dubbo

使用在实现类加入
// 注册为 Dubbo 服务
@Service(version = “1.0.0”)
public class CityDubboServiceImpl implements CityDubboService {

public City findCityByName(String cityName) {
    return new City(1L,2L,"温岭","是我的故乡");
}

}

3.Redis

常用数据类型:stirng,(list,set,Zset)单key多values,hash是k-v的k-v;
1.String: get set
Set myredis test
Get myredis
2.List:lpush(从前开始存) rpush(从后开始存)
Lrange 0 -1 讲元素全部取出;
3.set sadd set1 2,3,4
Smembers set1 随机取出所有元素;
4.Zset
5.Hash Hset user username jack
Hget user userName

持久化机制:

RDB快照机制(dump.rdb),AOF记录写操作(appendonly.aof);

配置主从复制读写分离命令:slaveof 主机地址:主机端口
Info replication 查看本机信息是主机还是从机;

Redis复制原理:

1.从机连接主机,发送同步sync同步命令;
2.主机收到命令生成快照,并记录此后的所有写操作;
3.快照生成完成,主机发送给每一个从机;
4.从机丢弃之前快照,载入新快照;
5.快照载入完成,主机开始发送后来的写命令;
6.从机执行后来的写命令;

配置哨兵模式:sentinel.marster:主机ip:主机端口

Sentinel.nodes:从机ip:从机端口,++++
使用redis:
1.自定义redisTemplate(因为序列号后是乱码保存在redis里,所以使用Jackson2JsonRedisSerializer转换一下)
2.将自定义redisTemplate注入到cacheManager里面
3.使用
@Autowirte
RedisTemplate redisTemplate;
redisTemplate.opsForList() 操作列表
redisTemplate.opsForValue().set(“k”,”123”,60)操作字符串
redisTemplate.opsForValue().get(“k”)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值