面试问题
1.项目问题
1.讲讲Redis实现购物车的设计思路
https://blog.csdn.net/lonely_bin/article/details/103164418
https://www.cnblogs.com/fengli9998/p/6417117.html
https://blog.csdn.net/qq_40742223/article/details/106999570
前端–后台–数据库
前端表单接收用户名密码,post提交到后台controler,接收用户名密码,controler层调用service根据用户名密码查询用户,查到返回true,否则返回false,在dao层根据用户名密码查询表
问到了接口安全问题,说下jwt的token的用法
https://www.cnblogs.com/aaron911/p/11300062.html
https://blog.csdn.net/weixin_40826349/article/details/89204143
在库存管理中设定库存、订货量、在途和警戒线水平这么4个基本参数,其中警戒线水平可以独立设置(如商品库存低于5个时该商品在货品清单和库存清单中就用红色标记),也可以用订货量达到库存量的某一比例dao设置警戒,如对于网络订单的那种,可以设置当一笔订单超过库存的1/2时即达到警戒水平,需要对该笔订单进行额外审核,判断是否是恶意订单。使用Timer,定时检查库存。并发消息
1.签名
根据用户名或者用户id,结合用户的ip或者设备号,生成一个token。在请求后台,后台获取http的head中的token,校验是否合法(和数据库或者Redis中记录的是否一致,在登录或者初始化的时候,存入数据库/redis)
2.加密
客户端和服务器都保存一个秘钥,每次传输都加密,服务端根据秘钥解密。
客户端:
1、设置一个key(和服务器端相同)
2、根据上述key对请求进行某种加密(加密必须是可逆的,以便服务器端解密)
3、发送请求给服务器
服务器端:
1、设置一个key
2、根据上述的key对请求进行解密(校验成功就是「信任」的客户端发来的数据,否则拒绝响应)
3、处理业务逻辑并产生结果
4、将结果反馈给客户端
比如spring security-oauth,jwt
你们数据模型设计用的什么工具
Powerdesign
使用,设计表结构
1>功能太强大,隐藏较深,上手有一定难度,使用起来比较复杂。
2>仅限Windows平台使用
1>永远免费使用
2>Windows,Mac,Linux三个平台均可以使用
基础知识
集合框架
2.mybatis中"#{}“和”${}"的区别
1、#相当于对数据
加上 双引号,$相当于直接显示数据。
2、#{} :
根据参数的类型进行处理,比如传入String类型,则会为参数加上双引号。#{} 传参在进行SQL预编译时,会把参数部分用一个占位符 ? 代替,这样可以防止 SQL注入。
3、${} :
将参数取出不做任何处理,直接放入语句中,就是简单的字符串替换,并且该参数会参加SQL的预编译,需要手动过滤参数防止 SQL注入。
4、因此 mybatis 中优先使用 #{};当需要动态传入 表名或列名时,再考虑使用 ${} , 比 较 特
殊 , 他 的 应
用 场 景 是 需
要 动 态 传 入
表 名 或 列 名
时 使 用 , M y B a t i s 排 序 时
使 用 o r d e r b y 动
态 参 数 时 需
要 注 意 , 用 {} 比较特殊, 他的应用场景是 需要动态传入
表名或列名时使用,MyBatis排序时使用order by 动态参数时需要注意,用 比较特殊,他的应用场景是需要动态传入表名或列名时使用,MyBatis排序时使用orderby动态参数时需要注意,用而不是#
try – 用于监听。将要被监听的代码(可能抛出异常的代码)放在try语句块之内,当try语句块内发生异常时,异常就被抛出。
• catch – 用于捕获异常。catch用来捕获try语句块中发生的异常。
• finally – finally语句块总是会被执行。它主要用于回收在try块里打开的物力资源(如数据库连接、网络连接和磁盘文件)。只有finally块,执行完成之后,才会回来执行try或者catch块中的return或者throw语句,如果finally中使用了return或者throw等终止方法的语句,则就不会跳回执行,直接停止。
• throw – 用于抛出异常。
• throws – 用在方法签名中,用于声明该方法可能抛出的异常
1、接口类似于类,但接口的成员自都没有执行方式,它只是方法、属性、事件和索引的组合而已,并且也只能包含这四种成员;类除了这四种成员之外还可以有别的成员(如字段)。
2、不能实例化一个接口,接口只包括成员的签名;而类可以实例化(abstract类除外)。
3、接口没有构造函数,类有构造函数。
4、接口不能进行运算符的重载,类可以进行运算符重载。
5、接口的成员没有任何修饰符,其成员总是公共的,而类的成员则可以有修饰符(如:虚拟或者静态)。
6、派生于接口的类必须实现接口中所有成员的执行方式,而从类派生则不然
1)按照数据的流向:
输入流、输出流
(2)按照流数据的格式:
字符流、字节流
(3)按照流数据的包装过程:
节点流(低级流)、处理流(高级流)
最基本的几种进行简单介绍:
InputStream/Reader: 所有的输入流的基类,前者是字节输入流,后者是字符输入流。
OutputStream/Writer: 所有输出流的基类,前者是字节输出流,后者是字符输出流。
https://www.cnblogs.com/dolphin0520/p/3778589.html
== 比较的是变量(栈)内存中存放的对象的(堆)内存地址,用来判断两个对象的地址是否相同,即是否是指相同一个对象。比较的是真正意义上的指针操作。equals用来比较的是两个对象的内容是否相等,由于所有的类都是继承自java.lang.Object类的,所以适用于所有对象,如果没有对该方法进行覆盖的话,调用的仍然是Object类中的方法,而Object中的equals方法返回的却是==的判断。String s=“abcd"是一种非常特殊的形式,和new 有本质的区别。它是java中唯一不需要new 就可以产生对象的途径。以String s=“abcd”;形式赋值在java中叫直接量,它是在常量池中而不是象new一样放在压缩堆中。 这种形式的字符串,在JVM内部发生字符串拘留,即当声明这样的一个字符串后,JVM会在常量池中先查找有有没有一个值为"abcd"的对象,如果有,就会把它赋给当前引用.即原来那个引用和现在这个引用指点向了同一对象, 如果没有,则在常量池中新创建一个"abcd”,下一次如果有String s1
= “abcd”;又会将s1指向"abcd"这个对象,即以这形式声明的字符串,只要值相等,任何多个引用都指向同一对象.
而String s = new String(“abcd”);和其它任何对象一样.每调用一次就产生一个对象,只要它们调用。
也可以这么理解: String str = “hello”; 先在内存中找是不是有"hello"这个对象,如果有,就让str指向那个"hello".
如果内存里没有"hello",就创建一个新的对象保存"hello".
String str=new String (“hello”) 就是不管内存里是不是已经有"hello"这个对象,都新建一个对象保存"hello"。
get和post的全部别
Get是不安全的,因为在传输过程,数据被放在请求的URL中;Post的所有操作对用户来说都是不可见的。
Get传送的数据量较小,这主要是因为受URL长度限制;Post传送的数据量较大,一般被默认为不受限制。
Get限制Form表单的数据集的值必须为ASCII字符;而Post支持整个ISO10646字符集。
Get执行效率却比Post方法好。Get是form提交的默认方法。
进程和线程之间的区别
列举常用的设计模式,写出单例模式
23个设计模式(至少写出前五种):
根据目的设计模式可以分bai为创造模式,结构模式和行为模式,创建模式用于处理对象的创建。结构模式用于处理类或对象的组合。
行为模式用于描述类或对象如何交互以及如何分配职责,创建模式用于处理对象的创建。主要包括以下五种设计模式:
工厂方法模式()
抽象工厂模式(AbstractFactoryPattern)
建造者模式(BuilderPattern)
原型模式(PrototypePattern)
单例模式(SingletonPattern)
结构模式用于处理类或对象的组合,包括以下七个设计模式:
适配器模式(AdapterPattern)
桥接模式(BridgePattern)
组合模式(CompositePattern)
装饰者模式(DecoratorPattern)
外观模式(FacadePattern)
享元模式(FlyweightPattern)
行为模式描述类或对象如何交互以及它们如何分配职责。它由以下11种设计模式组成:
责任链模式(Chain的ResponsibilityPattern)
命令模式(CommandPattern)
解释器模式(InterpreterPattern)
迭代器模式(IteratorPattern)
中介者模式(MediatorPattern)
备忘录模式(MementoPattern)
观察者模式(ObserverPattern)
状态模式(StatePattern)
策略模式(StrategyPattern)
模板方法模式(TemplateMethodPattern)
访问者模式(VisitorPattern)
public class Singleton {
private
final static Singleton INSTANCE = new Singleton();
private
Singleton(){}
public
static Singleton getInstance(){
return INSTANCE;
}
}
步骤:
1、父类静态变量和静态代码块(先声明的先执行);
2、子类静态变量和静态代码块(先声明的先执行);
3、父类的变量和代码块(先声明的先执行);
4、父类的构造函数;
5、子类的变量和代码块(先声明的先执行);
6、子类的构造函数。
1、用来修饰一个引用
如果引用为基本数据类型,则该引用为常量,该值无法修改;
如果引用为引用数据类型,比如对象、数组,则该对象、数组本身可以修改,但指向该对象或数组的地址的引用不能修改。
如果引用时类的成员变量,则必须当场赋值,否则编译会报错
2.用来修饰一个方法
当使用final修饰方法时,这个方法将成为最终方法,无法被子类重写。但是,该方法仍然可以被继承
3.用来修饰类
当用final修改类时,该类成为最终类,无法被继承。简称为“断子绝孙类
volatile的作用之一就是保证变量的可见性,它能让数据直接同步到主存中去,让缓存中的数据失效。
当一个变量被volatile关键词修饰时,对于共享资源的读操作会直接在主存中执行,当然也会缓存到工作内存,当其他线程对共享资源进行修改,会导致当前线程在工作内存中的共享资源失效,所以必须从主存中再次获取,对于共享资源的写操作当然是要先修改工作内存,修改结束后再刷新到主内存。因此volatile关键字无法保证原子性,只能保证可见性
volatile关键词直接禁止JVM对volatile关键字修饰的指令进行重新排序。但对于前后无依赖关系的指令则可以随意排序。
https://www.cnblogs.com/twoheads/p/10137263.html
JSP九大内置对象分为四类:
输入输出对象:out对象、response对象、request对象
通信控制对象:pageContext对象、session对象、application对象
Servlet对象:page对象、config对象
错误处理对象:exception对象
简介:
out对象:用于向客户端、浏览器输出数据。
request对象:封装了来自客户端、浏览器的各种信息。
response对象:封装了服务器的响应信息。
exception对象:封装了jsp程序执行过程中发生的异常和错误信息。
config对象:封装了应用程序的配置信息。
page对象:指向了当前jsp程序本身。
session对象:用来保存会话信息。也就是说,可以实现在同一用户的不同请求之间共享数
application对象:代表了当前应用程序的上下文。可以在不同的用户之间共享信息。
pageContext对象:提供了对jsp页面所有对象以及命名空间的访问。
jsp四大作用域:
page范围:只在一个页面保留数据 (javax.servlet.jsp.PageContext(抽象类))
request范围:只在一个请求中保存数据 (javax.servlet.httpServletRequest)
Session范围:在一次会话中保存数据,仅供单个用户使 用(javax.servlet.http.HttpSession)
Application范围:在整个服务器中保存数据,全部用户共享(javax.servlet.ServletContext)
forward是服务器内部重定向,程序收到请求后重新定向到另一个程序,客户属机并不知道;redirect则是服务器收到请求后发送一个状态头给客户,客户将再请求一次,这里多了两次网络通信的来往。当然forward也有缺点,就是forward的页面的路径如果是相对路径就会有些问题了。
forward 会将 request state , bean 等等信息带往下一个 jsp
redirect 是送到 client 端后再一次 request , 所以资料不被保留.
一.ArrayList与linkList区别
增加:ArrayList的性能要比LinkedList的性能高 数据越大差距越明显
插入:与删除相同
删除:删除靠后面的数据时ArrayList的性能要比LinkedList的性能高,但是删除靠前的数据时LinkedList不变,ArrayList性能变 差,数据越靠前ArrayList性能越差
修改:ArrayList比LinkedList快
二,hashMap的底层原理:
1.
HashMap: 存储时,如果key相同,后面的会把前面的替换 并返回被替换的值,如果没有替换则返回null
Hash表本身也叫Entry数组,Entry是一个单项链表也是Hash桶
加载因子: 是一个float类型的参数,扩容界限等于加载因子乘与当前容量,加载因子确定什么时候扩容。加载因子越大空间利用率越高性能越低,反之!
2.
hashMap: put方法
hashMap一般使用string作为key值,因为string已经重写了hashcode 和equals方法,所以,当key值相等时,新的值会重新覆盖旧的值
hashMap如果使用对象作为key值,在对象类中必须重写hashcode和equals方法,才能达到当key值相等时,新的值会重新覆盖旧的值,如果不重写,两个值都会产生
3.hash涉及知识:
hash算法:不同输入尽可能有不同的输出也成散列算法,好的算法发生hash碰撞会减少
hash碰撞:不同的输入有相同的输出 发生碰撞越小效率越高
重写equals方法
框架部分
简单介绍Spring是什么?
1、Spring的核心是一个轻量级(Lightweight)的容器(Container)。
2、Spring是实现IoC(Inversion of Control)容器和非入侵性(No intrusive)的框架。
3、Spring提供AOP(Aspect-oriented
programming)概念的实现方式。
4、Spring提供对持久层(Persistence)、事物(Transcation)的支持。
5、Spring供MVC Web框架的实现,并对一些常用的企业服务API(Application Interface)提供一致的模型封装。
6、Spring提供了对现存的各种框架(Structs、JSF、Hibernate、Ibatis、Webwork等)相整合的方案
https://blog.csdn.net/qq32933432/article/details/89918264
Spring提供了许多内置事务管理器实现,常用的有以下几种:
DataSourceTransactionManager(JDBC局部事务)bai,
HibernateTransactionManager(Hibernate事务),
和JtaTransactionManager(JTA全局事务)。
Spring提供了两种事务管理方式:
编程式事务管理和声明式事务管理。
不推荐使用编程式事务管理,推荐使用声明式管理。
Spring Boot是Spring旗下众多的子项目之一,其理念是约定优于配置,它通过实现了自动配置(大多数用户平时习惯设置的配置作为默认配置)的功能来为用户快速构建出标准化的应用。Spring Boot的特点可以概述为如下几点:
内置了嵌入式的Tomcat、Jetty等Servlet容器,应用可以不用打包成War格式,而是可以直接以Jar格式运行。
提供了多个可选择的”starter”以简化Maven的依赖管理(也支持Gradle),让您可以按需加载需要的功能模块。
尽可能地进行自动配置,减少了用户需要动手写的各种冗余配置项,Spring Boot提倡无XML配置文件的理念,使用Spring Boot生成的应用完全不会生成任何配置代码与XML配置文件。
提供了一整套的对应用状态的监控与管理的功能模块(通过引入spring-boot-starter-actuator),包括应用的线程信息、内存信息、应用是否处于健康状态等,为了满足更多的资源监控需求,Spring Cloud中的很多模块还对其进行了扩展。
mybatis通过JDK的动态代理方式,在启动加载配置文件时,根据配置mapper的xml去生成Dao的实现。
session.getMapper()使用了代理,当调用一次此方法,都会产生一个代理class的instance,看看这个代理class的实现.
这里是用到了JDK的代理Proxy。 newMapperProxy()可以取得实现interfaces 的class的代理类的实例。
当执行interfaces中的方法的时候,会自动执行invoke()方法,其中public
Object invoke(Object proxy, Method method, Object[] args)中 method参数就代表你要执行的方法.
MapperMethod类会使用method方法的methodName 和declaringInterface去取 sqlMapxml 取得对应的sql,也就是拿declaringInterface的类全名加上 sql-id…
https://blog.csdn.net/qq_35433716/article/details/86375506
不同在于:
1、存储方式:
memecache 把数据全部存在内存之中,断电后会挂掉,数据不能超过内存大小
redis有部份存在硬盘上,这样能保证数据的持久性,支持数据的持久化(笔者注:有快照和AOF日志两种持久化方式,在实际应用的时候,要特别注意配置文件快照参数,要不就很有可能服务器频繁满载做dump)。
2、数据支持类型:
redis在数据支持上要比memecache多的多。
3、使用底层模型不同:
新版本的redis直接自己构建了VM 机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求。
4、运行环境不同:
redis目前官方只支持LINUX 上去行,从而省去了对于其它系统的支持,这样的话可以更好的把精力用于本系统
环境上的优化,虽然后来微软有一个小组为其写了补丁。但是没有放到主干上
总结:有持久化需求或者对数据结构和处理有高级要求的应用,选择redis,其他简单的key/value存储,选择memcache。
5.性能上:
性能上都很出色,具体到细节,由于Redis只使用单核,而Memcached可以使用多核,所以平均每一个核上Redis在存储小数据时比
Memcached性能更高。而在100k以上的数据中,Memcached性能要高于Redis,虽然Redis最近也在存储大数据的性能上进行优化,但是比起 Memcached,还是稍有逊色。
6.内存空间和数据量大小:
MemCached可以修改最大内存,采用LRU算法。Redis增加了VM的特性,突破了物理内存的限制。
7.操作便利上:
MemCached数据结构单一,仅用来缓存数据,而Redis支持更加丰富的数据类型,也可以在服务器端直接对数据进行丰富的操作,这样可以减少网络IO次数和数据体积。
8.可靠性上:
MemCached不支持数据持久化,断电或重启后数据消失,但其稳定性是有保证的。Redis支持数据持久化和数据恢复,允许单点故障,但是同时也会付出性能的代价。
9.应用场景:
Memcached:动态系统中减轻数据库负载,提升性能;做缓存,适合多读少写,大数据量的情况(如人人网大量查询用户信息、好友信息、文章信息等)。
Redis:适用于对读写效率要求都很高,数据处理业务复杂和对安全性要求较高的系统(如新浪微博的计数和微博发布部分系统,对数据安全性、读写要求都很高)。
需要慎重考虑的部分
优缺点对比
1.Memcached单个key-value大小有限,一个value最大只支持1MB,而Redis最大支持512MB
2.Memcached只是个内存缓存,对可靠性无要求;而Redis更倾向于内存数据库,因此对对可靠性方面要求比较高
3.从本质上讲,Memcached只是一个单一key-value内存Cache;而Redis则是一个数据结构内存数据库,支持五种数据类型,因此Redis除单纯缓存作用外,还可以处理一些简单的逻辑运算,Redis不仅可以缓存,而且还可以作为数据库用
4.新版本(3.0)的Redis是指集群分布式,也就是说集群本身均衡客户端请求,各个节点可以交流,可拓展行、可维护性更强大
https://blog.csdn.net/weixin_40910372/article/details/89466955
全局异常
局部异常
https://segmentfault.com/a/1190000013200212
https://blog.csdn.net/qq_41723615/article/details/89088901
3.数据库
1.truncate和 delete只删除数据不删除表的结构(定义)
drop语句将删除表的结构被依赖的约束(constrain),触发器(trigger),索引(index); 依赖于该表的存储过程/函数将保留,但是变为invalid状态。
2.delete语句是dml,这个操作会放到rollback segement中,事务提交之后才生效;如果有相应的trigger,执行的时候将被触发
truncate,drop是ddl, 操作立即生效,原数据不放到rollback segment中,不能回滚. 操作不触发trigger。
3.delete语句不影响表所占用的extent, 高水线(high
watermark)保持原位置不动
显然drop语句将表所占用的空间全部释放
truncate 语句缺省情况下见空间释放到 minextents个 extent,除非使用reuse storage; truncate会将高水线复位(回到最开始)。
4.速度,一般来说: drop> truncate > delete。
5.安全性:小心使用drop 和truncate,尤其没有备份的时候.否则哭都来不及。
6.使用上,想删除部分数据行用delete,注意带上where子句. 回滚段要足够大. 想删除表,当然用drop
想保留表而将所有数据删除. 如果和事务无关,用truncate即可. 如果和事务有关,或者想触发trigger,还是用delete
如果是整理表内部的碎片,可以用truncate跟上reuse stroage,再重新导入/插入数据。
没有查询条件,或者查询条件没有建立索引
在查询条件上没有使用引导列
查询的数量是大表的大部分,应该是30%以上。
索引本身失效
查询条件使用函数在索引列上,或者 对索引列进行运算,
运算包括(+,-,*,/,! 等) 错误的例子:select * from test
where id-1=9; 正确的例子:select * from test
where id=10;
对小表查询
提示不使用索引
统计数据不真实
CBO计算走索引花费过大的情况。其实也包含了上面的情况,这里指的是表占有的block要比索引小。
10)隐式转换导致索引失效.这一点应当引起重视.也是开发中经常会犯的错误. 由于表的字段tu_mdn定义为varchar2(20),但在查询时把该字段作为number类型以where条件传给Oracle,这样会导致索引失效. 错误的例子:select * from test where tu_mdn=13333333333; 正确的例子:select * from test where tu_mdn=‘13333333333’;
13,like “%_” 百分号在前.
4,表没分析.
15,单独引用复合索引里非第一位置的索引列.
16,字符型字段为数字时在where条件里不添加引号.
17,对索引列进行运算.需要建立函数索引.
18,not in ,not exist.
19,当变量采用的是times变量,而表的字段采用的是date变量时.或相反情况。
20,B-tree索引 is null不会走,is not null会走,位图索引 is null,is not null
都会走
21,联合索引 is not null
只要在建立的索引列(不分先后)都会走, in null时
必须要和建立索引第一列一起使用,当建立索引第一位置条件是is null 时,其他建立索引的列可以是is null(但必须在所有列 都满足is null的时候),或者=一个值; 当建立索引的第一位置是=一个值时,其他索引列可以是任何情况(包括is null =一个值),以上两种情况索引都会走。其他情况不会走。
https://blog.csdn.net/zhushuai1221/article/details/51740846
索引类型
Mysql目前主要有以下几种索引类型:FULLTEXT,HASH,BTREE,RTREE。
即为全文索引,目前只有MyISAM引擎支持。其可以在CREATE TABLE ,ALTER TABLE ,CREATE INDEX 使用,不过目前只有 CHAR、VARCHAR ,TEXT 列上可以创建全文索引。
全文索引并不是和MyISAM一起诞生的,它的出现是为了解决WHERE name LIKE “%word%"这类针对文本的模糊查询效率较低的问题。
由于HASH的唯一(几乎100%的唯一)及类似键值对的形式,很适合作为索引。
HASH索引可以一次定位,不需要像树形索引那样逐层查找,因此具有极高的效率。但是,这种高效是有条件的,即只在“=”和“in”条件下高效,对于范围查询、排序及组合索引仍然效率不高。
BTREE索引就是一种将索引值按一定的算法,存入一个树形的数据结构中(二叉树),每次查询都是从树的入口root开始,依次遍历node,获取leaf。这是MySQL里默认和最常用的索引类型。
RTREE在MySQL很少使用,仅支持geometry数据类型,支持该类型的存储引擎只有MyISAM、BDb、InnoDb、NDb、Archive几种。
相对于BTREE,RTREE的优势在于范围查找。
索引种类
普通索引:仅加速查询
唯一索引:加速查询 + 列值唯一(可以有null)
主键索引:加速查询 + 列值唯一(不可以有null)+ 表中只有一个
组合索引:多列值组成一个索引,专门用于组合搜索,其效率大于索引合并
全文索引:对文本的内容进行分词,进行搜索
11.3面试问题
1.项目问题
1.讲讲Redis实现购物车的设计思路
https://blog.csdn.net/lonely_bin/article/details/103164418
https://www.cnblogs.com/fengli9998/p/6417117.html
3.订单的定时提醒支付功能是怎么实现的
https://blog.csdn.net/qq_40742223/article/details/106999570
基础知识
集合框架
2.mybatis中"#{}“和”${}"的区别
1、#相当于对数据
加上 双引号,$相当于直接显示数据。
2、#{} :
根据参数的类型进行处理,比如传入String类型,则会为参数加上双引号。#{} 传参在进行SQL预编译时,会把参数部分用一个占位符 ? 代替,这样可以防止 SQL注入。
3、${} :
将参数取出不做任何处理,直接放入语句中,就是简单的字符串替换,并且该参数会参加SQL的预编译,需要手动过滤参数防止 SQL注入。
4、因此 mybatis 中优先使用 #{};当需要动态传入 表名或列名时,再考虑使用 ${} , 比 较 特
殊 , 他 的 应
用 场 景 是 需
要 动 态 传 入
表 名 或 列 名
时 使 用 , M y B a t i s 排 序 时
使 用 o r d e r b y 动
态 参 数 时 需
要 注 意 , 用 {} 比较特殊, 他的应用场景是 需要动态传入
表名或列名时使用,MyBatis排序时使用order by 动态参数时需要注意,用 比较特殊,他的应用场景是需要动态传入表名或列名时使用,MyBatis排序时使用orderby动态参数时需要注意,用而不是#
try – 用于监听。将要被监听的代码(可能抛出异常的代码)放在try语句块之内,当try语句块内发生异常时,异常就被抛出。
• catch – 用于捕获异常。catch用来捕获try语句块中发生的异常。
• finally – finally语句块总是会被执行。它主要用于回收在try块里打开的物力资源(如数据库连接、网络连接和磁盘文件)。只有finally块,执行完成之后,才会回来执行try或者catch块中的return或者throw语句,如果finally中使用了return或者throw等终止方法的语句,则就不会跳回执行,直接停止。
• throw – 用于抛出异常。
• throws – 用在方法签名中,用于声明该方法可能抛出的异常
1、Spring的核心是一个轻量级(Lightweight)的容器(Container)。
2、Spring是实现IoC(Inversion of Control)容器和非入侵性(No intrusive)的框架。
3、Spring提供AOP(Aspect-oriented
programming)概念的实现方式。
4、Spring提供对持久层(Persistence)、事物(Transcation)的支持。
5、Spring供MVC Web框架的实现,并对一些常用的企业服务API(Application Interface)提供一致的模型封装。
6、Spring提供了对现存的各种框架(Structs、JSF、Hibernate、Ibatis、Webwork等)相整合的方案
Spring提供了许多内置事务管理器实现,常用的有以下几种:
DataSourceTransactionManager(JDBC局部事务)bai,
HibernateTransactionManager(Hibernate事务),
和JtaTransactionManager(JTA全局事务)。
Spring提供了两种事务管理方式:
编程式事务管理和声明式事务管理。
不推荐使用编程式事务管理,推荐使用声明式管理。
Spring Boot是Spring旗下众多的子项目之一,其理念是约定优于配置,它通过实现了自动配置(大多数用户平时习惯设置的配置作为默认配置)的功能来为用户快速构建出标准化的应用。Spring Boot的特点可以概述为如下几点:
内置了嵌入式的Tomcat、Jetty等Servlet容器,应用可以不用打包成War格式,而是可以直接以Jar格式运行。
提供了多个可选择的”starter”以简化Maven的依赖管理(也支持Gradle),让您可以按需加载需要的功能模块。
尽可能地进行自动配置,减少了用户需要动手写的各种冗余配置项,Spring Boot提倡无XML配置文件的理念,使用Spring Boot生成的应用完全不会生成任何配置代码与XML配置文件。
提供了一整套的对应用状态的监控与管理的功能模块(通过引入spring-boot-starter-actuator),包括应用的线程信息、内存信息、应用是否处于健康状态等,为了满足更多的资源监控需求,Spring Cloud中的很多模块还对其进行了扩展。
一.ArrayList与linkList区别
增加:ArrayList的性能要比LinkedList的性能高 数据越大差距越明显
插入:与删除相同
删除:删除靠后面的数据时ArrayList的性能要比LinkedList的性能高,但是删除靠前的数据时LinkedList不变,ArrayList性能变 差,数据越靠前ArrayList性能越差
修改:ArrayList比LinkedList快
二,hashMap的底层原理:
1.
HashMap: 存储时,如果key相同,后面的会把前面的替换 并返回被替换的值,如果没有替换则返回null
Hash表本身也叫Entry数组,Entry是一个单项链表也是Hash桶
加载因子: 是一个float类型的参数,扩容界限等于加载因子乘与当前容量,加载因子确定什么时候扩容。加载因子越大空间利用率越高性能越低,反之!
2.
hashMap: put方法
hashMap一般使用string作为key值,因为string已经重写了hashcode 和equals方法,所以,当key值相等时,新的值会重新覆盖旧的值
hashMap如果使用对象作为key值,在对象类中必须重写hashcode和equals方法,才能达到当key值相等时,新的值会重新覆盖旧的值,如果不重写,两个值都会产生
3.hash涉及知识:
hash算法:不同输入尽可能有不同的输出也成散列算法,好的算法发生hash碰撞会减少
hash碰撞:不同的输入有相同的输出 发生碰撞越小效率越高
mybatis通过JDK的动态代理方式,在启动加载配置文件时,根据配置mapper的xml去生成Dao的实现。
session.getMapper()使用了代理,当调用一次此方法,都会产生一个代理class的instance,看看这个代理class的实现.
这里是用到了JDK的代理Proxy。 newMapperProxy()可以取得实现interfaces 的class的代理类的实例。
当执行interfaces中的方法的时候,会自动执行invoke()方法,其中public
Object invoke(Object proxy, Method method, Object[] args)中 method参数就代表你要执行的方法.
MapperMethod类会使用method方法的methodName 和declaringInterface去取 sqlMapxml 取得对应的sql,也就是拿declaringInterface的类全名加上 sql-id…
https://blog.csdn.net/qq_35433716/article/details/86375506
Redis和Memcache区别,优缺点对比
两个对象怎么比较
重写equals方法
全局异常
局部异常
https://segmentfault.com/a/1190000013200212
Shiro和 springcecury 都是用来做权限控制的自己实现的话需要用户表,角色表,权限表,两张中间表。
2.冒泡排序算法
//第一个 for 循环是程序需要执行要走多少趟
for(int i=0;i //第二个 for 循环是每趟需要比较多少次 for(int j=0;j //此处是从大到小排列 if(arr[j] //定义一个临时变量 temp int temp=arr[j]; arr[j]=arr[j+1]; arr[j+1]=temp; } } } 3.集合总结 List、Set、Map 是这个集合体系中最主要的三个接口。 其中 List 和 Set 继承自 Set 不允许元素重复。HashSet 和 TreeSet 是两个主要的实现类。 List 有序且允许元素重复。ArrayList、LinkedList 和 Vector 是三个主要的实现类。 Map 也属于集合系统,但和 Collection 接口不同。Map 是 key 对 key 不能重复,但是 value 可以重复。HashMap、TreeMap 和 SortedSet 和 4.简单介绍 spring 1、Spring 的核心是一个轻量级(Lightweight)的容器(Container)。 2、Spring 是实现 IoC(Inversion 3、Spring 提供 AOP(Aspect-oriented programming)概念的实现方式。 4、Spring 提供对持久层(Persistence)、事物(Transcation)的支持。 5、Spring 供 MVC Web框架的实现,并对一些常用的企业服务 API(Application 6、Spring 提供了对现存的各种框架(Structs、JSF、Hibernate、Ibatis、Webwork等)相整合的方案 Spring Spring Spring Spring Spring Spring https://blog.csdn.net/a745233700/article/details/80959716 5.事务的几种实现方式 (1)编程式事务管理对基于 POJO 的应用来说是唯一选择。我们需要在代码中调用 beginTransaction()、commit()、rollback()等事务管理相关的方法,这就是编程式事务管理。 (2)基于 TransactionProxyFactoryBean 的声明式事务管理 (3)基于 @Transactional 的声明式事务管理 (4)基于 Aspectj AOP 配置事务 6.spring boot 自动装配 Spring Boot 是 Spring 旗下众多的子项目之一,其理念是约定优于配置,它通过实现了自动配置(大多数用户平时习惯设置的配置作为默认配置)的功能来为用户快速构建出标准化的应用。Spring Boot 的特点可以概述为如下几点: 内置了嵌入式的 Tomcat、Jetty 等 Servlet 容器,应用可以不用打包成 War 格式,而是可以直接以 Jar 格式运行。 提供了多个可选择的”starter”以简化 Maven 的依赖管理(也支持 Gradle),让您可以按需加载需要的功能模块。 尽可能地进行自动配置,减少了用户需要动手写的各种冗余配置项,Spring Boot 提倡无 XML 配置文件的理念,使用 Spring Boot 生成的应用完全不会生成任何配置代码与 XML 配置文件。 提 供 了 一 整 套 的 对 应 用 状 态 的 监 控 与 管 理 的 功 7.UNION 和 UNION ALL 的区别 都是将两个结果集合并为一个,但这两者从使用和效率上来说都有所不同。 1、对重复结果的处理:UNION 在进行表链接后会筛选掉重复的记录,Union All 不会去除重复记录。 2、对排序的处理:Union 将会按照字段的顺序进行排序;UNION ALL 只是简单的将两个结果合并后就返回。 所以:从效率上说,UNION ALL 要比 UNION 快很多,所以,如果可以确认合并的两个结果集中不包含重复数据且不需要排序时的话,那么就使用 UNION ALL。 8.Git怎么创建切换合并分支 1、首先列出所有分支 git branch -a 2、创建一个不存在的分支 dev git branch dev 3、切换到新创建的 dev 分支 git checkout dev 4、添加 add 到分支上 git add . 5、执行 commit 到缓存中 git commit -m “备注信息” 6、提交到 git 仓库 git push origin dev 二、切换、合并分支 1、首先列出所有分支 git branch -a 2、创建一个不存在的分支 dev git branch dev 3、切换到新创建的 dev 分支 git checkout dev 4、在 dev 分支 add 一个 test.txt 文件 touch test.txt ##此处是添加一个文件、如已有提交文件请忽略、往下走 git add test.txt 5、执行 commit 到缓存中 git commit -m “备注信息-添加 test.txt 文件” 6、切换到待合并分支、我这里为 master git checkout master 7、将 dev 合并到 master 分支 9.前端框架 vue 中,举例 3 个生命周期钩子函数,并加以解释。 beforeCreate:创建前 1、当前 vue 实例化的时候会做一个初始化的操作,在这个生命周期函数里面 我们可以做初始化的 loading 2、在当前函数里面是访问不到 data 中的属性,但是可以通过 vue 的实例对象 进行访问 created:创建后 1、当 beforeCreate 执行完毕以后,会执行 created. 在当前函数中我们可以访 问到 data 中的属性 2、当前生命周期函数执行的时候会将 data 中所以的属性和 methods 身上所以 的方法添加到 vue 的实例身上,同时 会将 data 中所有的属性添加一个 getter/setter 方法 3、如果需要进行前后端上数据交互(ajax 请求的时候) 需要在当前生命周期中 使用 beforeMount:挂载前 (渲染) render 函数初次被调用---->数据和模板没有进行相结合,同时还没有渲染到 html页面上 可以在此做渲染前 data 中数据最后的修改 mounted:挂载后 1、数据和模板进行相结合,渲染成真实的 DOM 结构 2、在当前生命周期函数里面我们可以访问到真实的 DOM 结构, 3、在 vue 中我们可以通过$refs来访问到真实的 DOM 结构 4、ref类似与 id 一样 值必须是唯一的 访问的时候我们可以通过 属性 beforeDestroy:销毁前 销毁之前还可以访问到 DOM 结构 以及相关的数据(data) 在这个生命周期函数中我们可以将绑定的事件进行移除 destroyed:销毁后 在这个生命周期函数中会将数据和模板之间的关系断开(不是你的做的) 在这个生命周期函数中我们还是可以访问到 data中的属性 但是访问不到真实的 DOM 结构了 beforeUpdate:更新前 只要 data 中的属性发生了改变,那么这个生命周期就会执行,render 函数再 次会执行 在这个生命周期函数中我们可以对数据进行最后的修改,同时也可以访问到最 新的 DOM 结构和数据 updated:更新后 在当前生命周期函数中我们可以访问到最新的 DOM 结构(数据更新后最新的 DOM 结构)和数据 10.前端框架 vue 中,举例四种指令,并说明用法。 v-text 主要用来更新 textContent,可以等同于 JS 的 text属性。 双大括号的方式会将数据解释为纯文本,而非 HTML。为了输出真正的 HTML,可以用 v-html指令。它等同于 JS 的 innerHtml 属性。 v-pre 主要用来跳过这个元素和它的子元素编译过程。可以用来显示原始的 Mustache 标签。 跳过大量没有指令的节点加快编译。 这个指令是用来保持在元素上直到关联实例结束时进行编译。 v-once 关联的实例,只会渲染一次。之后的重新渲染,实例极其所有的子节点将被视为静态内容跳过,这可以用于优化更新性能。 11.MySql 中主键、外键、索引的区别。 主键是关系表中记录的唯一标识。主键的选取非常重要:主键不要带有业务含义,而应该使用BIGINT 自增或者 GUID 类型。主键也不应该允许 NULL。可以使用多个列作为联合主键,但联合主键并不常用。 关系数据库通过外键可以实现一对多、多对多和一对一的关系。外键既可以通过数据库来约束,也可以不设置约束,仅依靠应用程序的逻辑来保证。 通过对数据库表创建索引,可以提高查询速度。通过创建唯一索引,可以保证某一列的值具有唯一性。数据库索引对于用户和应用程序来说都是透明的。 12.MySql 中 1、delete 和 truncate 仅仅删除表数据,drop 连表数据和表结构一起删除。 2、delete 是 DML 语句,操作完以后如果没有不想提交事务还可以回滚,truncate 和 drop是DDL 语句,操作完马上生效,不能回滚。 3、执行的速度上,drop>truncate>delete。 13.数据库大表优化 当 MySQL 单表记录数过大时,数据库的 CRUD 性能会明显下降,一些常见的优化措施如下:限定数据的范围:务必禁止不带任何限制数据范围条件的查询语句。比如:我们当用户在查询订单历史的时候,我们可以控制在一个月的范围内。; 读/写分离:经典的数据库拆分方案,主库负责写,从库负责读; 缓存:使用 MySQL 的缓存,另外对重量级、更新少的数据可以考虑使用应用级别的缓存;垂直分区: 根据数据库里面数据表的相关性进行拆分。例如,用户表中既有用户的登录信息又有用户的基本信息,可以将用户表拆分成两个单独的表,甚至放到单独的库做分库。 简单来说垂直拆分是指数据表列的拆分,把一张列比较多的表拆分为多张表。如下图所示,这样来说大家应该就更容易理解了。 垂直拆分的优点:可以使得行数据变小,在查询时减少读取的 Block 数,减少 I/O 次数。此外,垂直分区可以简化表的结构,易于维护。 垂直拆分的缺点:主键会出现冗余,需要管理冗余列,并会引起 Join 操作,可以通过在应用层进行 Join 来解决。此外,垂直分区会让事务变得更加复杂; 保持数据表结构不变,通过某种策略存储数据分片。这样每一片数据分散到不同的表或者库中,达到了分布式的目的。水平拆分可以支撑非常大的数据量。 水平拆分是指数据表行的拆分,表的行数超过 200 万行时,就会变慢,这时可以把一张的表的数据拆成多张表来存放。举个例子:我们可以将用户信息表拆分成多个用户信息表,这样就可以避免单一表数据量过大对性能造成影响。 水平拆分可以支持非常大的数据量。需要注意的一点是:分表仅仅是解决了单一表数据过大的问题,但由于表的数据还是在同一台机器上,其实对于提升 MySQL 并发能力没有什么意义,所以 水平拆分最好分库 。 水平拆分能够 支持非常大的数据量存储,应用端改造也少,但 分片事务难以解决 ,跨界点Join 性能较差,逻辑复杂。尽量不要对数据进行分片,因为拆分会带来逻辑、部署、运维的各种复杂度 ,一般的数据表在优化得当的情况下支撑千万以下的数据量是没有太大问题的。如果实在要分片,尽量选择客户端分片架构,这样可以减少一次和中间件的网络 I/O。 下面补充一下数据库分片的两种常见方案: 客户端代理:分片逻辑在应用端,封装在 jar 包中,通过修改或者封装 JDBC 层来实现。当当网的 Sharding-JDBC 、阿里的 TDDL 是两种比较常用的实现。 中间件代理:在应用和数据中间加了一个代理层。分片逻辑统一维护在中间件服务中。我们现在谈的 Mycat、360 的 Atlas、网易的 DDB 等等都是这种架构的实现。 14.请简述 java的内存回收机制。 内存回收机制就是对象没有引用就会回收 其实 Java垃圾回收主要做的是两件事:1)内存回收 2)碎片整理垃圾回收算法 1)串行回收(只用一个 CPU)和并行回收(多个 CPU 才有用):串行回收是不管系统有多少个 CPU,始终只用一个 CPU 来执行垃圾回收操作,而并行回收就是把整个回收工作拆分成多个部分,每个部分由一个 CPU 负责,从而让多个 CPU 并行回收。并行回收的执行效率很高,但复杂度增加,另外也有一些副作用,如内存随便增加。 2)并发执行和应用程序停止 :应用程序停止(Stop-the-world)顾名思义,其垃圾回收方式在执行垃圾回收的同时会导致应用程序的暂停。并发执行的垃圾回收虽然不会导致应用程序的暂停,但由于并发执行垃圾需要解决和应用程序的执行冲突(应用程序可能在垃圾回收的过程修改对象),因此并发执行垃圾回收的系统开销比 Stop-the-world 高,而且执行时需要更多的堆内存。 3)压缩和不压缩和复制 : ①支持压缩的垃圾回收器(标记-压缩 = 标记清除+压缩)会把所有的可达对象搬迁到一起,然后将之前占用的内存全部回收,减少了内存碎片。 ②不压缩的垃圾回收器(标记-清除)要遍历两次,第一次先从跟开始访问所有可达对象,并将他们标记为可达状态,第二次便利整个内存区域,对未标记可达状态的对象进行回收处理。这种回收方式不压缩,不需要额外内存,但要两次遍历,会产生碎片 ③复制式的垃圾回收器:将堆内存分成两个相同空间,从根(类似于前面的有向图起始顶点) 开始访问每一个关联的可达对象,将空间 A 的全部可达对象复制到空间 B,然后一次性回收空间 A。对于该算法而言,因为只需访问所有的可达对象,将所有的可达对象复制走之后就直接回收整个空间,完全不用理会不可达对象,所以遍历空间的成本较小,但需要巨大的复制成本和较多的内存。 15.分库分表,主从复制,读写分离在 spring 层面上怎么做的。 分布式读写分离和分库分表采用 sharding-jdbc 实现。 sharding-jdbc是当当网推出的一款读写分离实现插件,其他的还有 mycat,或者纯粹的 Aop 代码控制实现。 16.什么情况下设置了索引但无法引用。 1.如果条内件中有 or,即使其中容有条件带索引也不会使用 2.对于多列索引,不是使用的第一部分,则不会使用索引 3.like查询是以%开头 4.如果列类型是字符串,那一定要在条件中将数据使用引号引用起来,否则不使用索引 5.如果 mysql 估计使用全表扫描要比使用索引快,则不使用索引 17.如何进行数据库的优化,简单说几个方法。 首先要根据需求写出结构良好的 SQL,然后根据 SQL在表中建立有效的索引。但是如果索引太多,不但会影响写入的效率,对查询也有一定的影响。 合理的数据库是设计 系统配置的优化 例如:MySQL 数据库 my.cnf 更快的 IO、更多的内存。一般来说内存越大,对于数据库的操作越好。但是 CPU 多就不一定了,因为他并不会用到太多的 CPU 数量,有很多的查询都是单 CPU。另外使用高的 IO(SSD、RAID),但是 IO 并不能减少数据库锁的机制。所以说如果查询缓慢是因为数据库内部的一些锁引起的,那么硬件优化就没有什么意义 1、选取最适用的字段属性 2、使用连接(JOIN)来代替子查询(Sub-Queries) 3、使用联合(UNION)来代替手动创建的临时表 4、事务 5、锁定表 7、使用索引 8、优化的查询语句 18.简述微服务中是如何实现负载均衡的 通过 1.服务提供者只需要启动多个服务实例并注册到一个注册中心或是多个相关联的服务注册中心。 的接口调用。 这样,我们就可以将服务提供者的高可用以及服务消费者的负载均衡调用一起实现了。其中,我们使用了个非常有用的对象 RestTemplate.该对象会使用 Ribbon的自动化配置,同时通过配置@LoadBalanced还能够开启客户端负载均衡。 19.微服务中如何尽可能的避免请求现场阻塞导致的资源浪费? 利用线程隔离和熔断 Hystrix 是由 Netflix 发布,旨在应对复杂分布式系统中的延时和故障容错 线程隔离的优点: 请求线程与依赖代码的执行线程可以完全隔离第三方代码; 当一个依赖线程由失败变成可用时,线程池将清理后并立即恢复可用; 线程池可设置大小以控制并发量,线程池饱和后可以拒绝服务,防止依赖问题扩散 熔断器机制 : 当请求失败比率(失败/总数)达到一定阈值后,熔断器开启,并休眠一段时间,这段休眠期过后熔断器将处与半开状态(half-open),在此状态下将试探性的放过一部分流量(Hystrix只支持 single 20.请简述控制反转的优点。 在最开 dao始写程序,DAO 是我们自己 new 出来 du的,这 zhi 时候的编程完全控制在 dao自己手里 用了专 spring 之后,初始化过属程控制在容器手里了,我们自己不再去 new 它了,反转到容器那里去了。 原来我们的程序我们控制的是具体的实现,写程序直接写实现,现在我们控制的是它的接口它的抽象,原来我们依赖的是它的实现,现在我们依赖的是它的抽象。从具体的实现反转到抽象的概念上 21.在表数据的导入导出中,如何优化批量操作大量数据。 在插入数据库之前作判断太花时间,没必要。所以最后将数据的处理交给了数据库来做。 建一个临时表 CUST_OBJECT_TEMP,先把所有的数据都用 jdbc batch 22.搜索引擎的全量更新和增量更新。 全量更新 全量更新,就是把数据库中的全部数据都导入 solr 缓存库中,一般会删除 solr 缓存库现有的数据。全量的话,可以采用直接全部覆盖(使用“新”数据覆盖“旧”数据);或者走更新逻辑(覆盖前判断下,如果新旧不一致,就更新) 增量更新 增量的基础是全量,就是你要使用某种方式先把全量数据拷贝过来,然后再采用增量方式同步更新。增量的话,就是指抓取某个时刻(更新时间)或者检查点(checkpoint)以后的数 据来同步,不是无规律的全量同步。这里引入一个关键性的前提:副本一端要记录或者知道(通过查询更新日志或者订阅更新)哪些更新了。 23.如何解决用户访问时 token 过期的不良用户体验? 把 token存入数据库,不设置存活时间或者,存入 reids 给 token设置持久化 24.如何实现定时推送功能。 采用定时服务(time server)@timerout实现什么时候调用什么方法实现什么功能 25.RabbitMQ消息中间件的使用场景。 抢购活动,削峰填谷,防止系统崩塌。 延迟信息处理,比如十分钟之后给下单未付款的用户发送邮件提醒 解耦系统,对于新增的功能可以单独写模块扩展,比如用户确认评价之后,新增了给用户返积分的功能,这个时候不用在业务代码里添加新增积分的功能,只需要把新增积分的接口订阅确认评价的消息队列即可,后面再添加任何功能只需要订阅对应的消息队列即可。 26.如何进行数据建模,数据库建模?
Collection 接口。
value 的映射集合,其中 key 列就是一个集合。
Hashtable 是三个主要的实现类。
SortedMap 接口对元素按指定规则排序,SortedMap 是对
key 列进行排序。
of Control)容器和非入侵性(No intrusive)的框架。
Interface)提供一致的模型封装。
Core:核心类库,提供 IOC服务;
Context:提供框架式的 Bean访问方式,以及企业级功能(JNDI、定时任务等);Spring AOP:AOP服务;
DAO:对 JDBC的抽象,简化了数据访问异常的处理;
ORM:对现有的 ORM框架的支持;
Web:提供了基本的面向Web的综合特性,例如多方文件上传;
MVC:提供面向Web应用的 Model-View-Controller实现
能 模 块 ( 通 过 引 入spring-boot-starter-actuator),包括应用的线程信息、内存信息、应用是否处于健康状态等,为了满足更多的资源监控需求,Spring Cloud 中的很多模块还对其进行了扩展。git
merge dev
8、提交到 git 仓库
git push origin master
this.$refs.
drop\delete\truncate的区别
SpringCloudRibbon 的封装,我们在微服务架构中使用客户端负载均衡调用非常简单,只需要如下两步:
RestTemplate 来实现面向服务
request),如果这部分流量调用成功后,再次将熔断器闭合,否则熔断器继续保持开启并进入下一轮休眠周期
insert 插入或者分数据段插入,这个过程不做任何的数据校验。再搞个存储过程来处理两个表的数据就行了。数据库中有个批量操作,一次插入 5 万条,分多次插入
和产品经理共同协商调研,产品经理会把调研结果给到开发组,然后我们用 powerdesigner画出 er 图