Java SE
面向对象三大特性?
封装是指的是类的内部信息进行隐藏,一般是指对类内部的属性进行私有化,外部无法直接访问或影响内部的属性,只能通过特定的方法对封装的内容进行访问,提高了代码的安全性
继承是指子类继承父类,子类可以获得父类的全部属性和方法,且可以拥有一些父类所没有的方法和属性,提高了代码的复用性和逻辑性。
多态指的是类与类的关系,多态必备三要素:继承、重写、父类引用子类对象,对于方法来说,非静态方法遵循编译看左边,运行看右边,静态方法遵循编译看左边运行看右边,对于属性来说是编译看左边,运行看左边
有哪几种数据类型?
java的基本数据类型有8种,分别是:byte(位)、short(短整数)、int(整数)、long(长整数)、float(单精度)、double(双精度)、char(字符)和boolean(布尔值)
各类型所占字节和取值范围大小?
byte 1字节 、 short 2字节 、int 4字节 、long 8字节 、float 4字节精确到7位有效数字 、 double 8字节 、char 2字节 、[boolean] 1位、引用类型 4字节 1个字节表示8位
byte 1 8 -128 +127
short 2 16 -2(15) ~ +2(15)-1
int 4 32 -2(31) ~ +2(31)-1j
long 8 64 -2(63) ~ +2(63)-1
==和equals()的区别?
==:如果是基本数据类型,⽐较是值,如果是引⽤类型,⽐较的是引⽤地址 equals:具体看各个类重写equals⽅法之后的⽐较逻辑,⽐如String类,虽然是引⽤类型,但是 String类中重写了equals⽅法,⽅法内部⽐较的是字符串中的各个字符是否全部相等。
重写和重载的区别?
重载(Overload): 在⼀个类中,同名的⽅法如果有不同的参数列表(⽐如参数类型不同、参数个数 不同)则视为重载。 重写(Override): 从字⾯上看,重写就是 重新写⼀遍的意思。其实就是在⼦类中把⽗类本身有的⽅ 法重新写⼀遍。⼦类继承了⽗类的⽅法,但有时⼦类并不想原封不动的继承⽗类中的某个⽅法,所 以在⽅法名,参数列表,返回类型都相同(⼦类中⽅法的返回值可以是⽗类中⽅法返回值的⼦类)的 情况下, 对⽅法体进⾏修改,这就是重写。但要注意⼦类⽅法的访问修饰权限不能⼩于⽗类的。
子类最多可以继承多少个父类?
单继承只能有一个
最多可以实现几个接口?
可以实现多个接口
抽象类和接口的区别?
1、抽象类和接口都不能直接实例化。如果要实例化,抽象类变量必须指向实现所有抽象方法的子类对象,接口变量必须指向实现所有接口方法的类对象。
2、抽象类要被子类继承,接口要被类实现。
3、接口只能做方法申明,抽象类中可以做方法申明,也可以做方法实现。
4、接口里定义的变量只能是公共的静态的常量,抽象类中的变量是普通变量。
5、抽象类里的抽象方法必须全部被子类所实现,如果子类不能全部实现父类抽象方法,那么该子类只能是抽象类。同样,实现接口的时候,如不能全部实现接口方法,那么该类也只能为抽象类。
6、抽象方法只能申明,不能实现。
7、抽象类里可以没有抽象方法
8、如果—个类里有抽象方法,那么这个类只能是抽象类
9、抽象方法要被实现,所以不能是静态的,也不能是私有的。
10、接口可以继承接口,并且可多继承接口,但类只能单—继承。
11.接口可以通过匿名内部类实例化。接口是对动作的抽象,抽象类是对根源的抽象。抽象类表示的是,这个对象是什么。而接口表示的是,这个对象能做什么。
使用final修饰类,属性,方法有什么作用?
1.final 修饰类时,这个类不能被继承了
2.final 修饰方法,此方法就不能被重写。 eg:object类中的getClas 方法
3.final 修饰变量,这个时候的变量就是一个常量。
3.1 final 可以修饰属性
3.2 final 可以修饰局部变量,尤其是使用final修饰形参时,表明此形参是一个常量,当我们调用此方法时,给给常量形参赋一个实参,一旦赋值以后,就只能在方法体内使用此形参,但不能进行重新赋值
4.static final 用来修饰属性 :全局变量
try里面写了return,是否还会执行finally里面的代码?
try中有return,finally一定会执行。
try catch finally 执行代码的顺序?
1、不管有没有出现异常,finally块中的代码都会执行;
2、当try和catch中有return时,finally仍然会执行;
3、finally是在return后面的表达式运算后执行的。
有哪些数据结构?
1、List;2、Vector;3、ArrayList;4、LinkedList;5、Set;6、HashSet;7、LinkedHashSet;8、SortedSet;9、Map;10、HashMap。
ArrayList如何遍历数据
for-each遍历
把链表变为数组相关的内容进行遍历
使用迭代器
HashMap怎么遍历数据
- 迭代器
- ForEach 遍历
- lambda 表达式遍历
- StreamsApi 遍历
arrayList和linkedlist的区别?
1、数据结构不同
ArrayList是Array(动态数组)的数据结构,LinkedList是Link(链表)的数据结构。
2、效率不同
当随机访问List(get和set操作)时,ArrayList比LinkedList的效率更高,因为LinkedList是线性的数据存储方式,所以需要移动指针从前往后依次查找。
当对数据进行增加和删除的操作(add和remove操作)时,LinkedList比ArrayList的效率更高,因为ArrayList是数组,所以在其中进行增删操作时,会对操作点之后所有数据的下标索引造成影响,需要进行数据的移
arrayList是否可以插入重复数据,如何实现数据去重?
可以插入重复数据
第一种:通过LinkedHashSet来解决,LinkedHashSet是有序不可重复的,可以把ArrayList传入LinkedHashSet中
第二种:使用Java8的新特性stream的distinct()方法来实现
第三种:使用contains()方法去重
第四种: 利用HashSet(无序唯一)的特性
map是否可以插入重复数据?
map本身不可以,key不可以重复,但value可以重复
什么是反射?
在 Java 中的反射机制是指 在运行状态中,对于任意一个类都能够知道这个类所有的属性和方法;并且对于任意一个对象,都能够调用它的任意一个方法;这种动态获取信息以及动态调用对象方法的功能成为 Java 语言的反射机制
多线程实现的方式有哪几种?
使用实现多线程有四种方式:①继承Thread类;②实现Runnable接口;③使用Callable和FutureTask实现有返回值的多线程;④使用ExecutorService和Executors工具类实现线程池(如果需要线程的返回值,需要在线程中实现Callable和Future接口)
Runnable 与 Callable的区别:
(1)Callable规定的方法是call(),Runnable规定的方法是run().
(2)Callable的任务执行后可返回值,而Runnable的任务是不能返回值的
(3)call方法可以抛出异常,run方法不可以
(4)运行Callable任务可以拿到一个Future对象,Future 表示异步计算的结果。(PS: 特别注意,executorService.submit(Runnable task) 也会返回future, 但是没有future的效果 )
线程的三大特性?
1、 原子性
原子性指的就是一个操作是不可中断,即使有多个线程执行,一个操作开始也不会受其他线程影响,即可以理解为线程的最小执行单元,不可被分割。当然这个最小执行单元可以只是一个操作也可以是一段代码。在线程中实现原子性的操作可以为 synchronized修饰或通过lock( ReenTrantLock)实现
2、可见性
可见性指的就是当某个线程修改了其内存**享变量的值时,其他线程能立刻感知到其值的变化,这既是可见性,对于串行线程来说,这个可见性现象是不存在的。
3、有序性
有序性即是程序按一定规则进行顺序的执行,期间会进行编译器优化重排、指令重排、内存重排等,执行规则遵循as-if-serial语义规则和happens-before 原则,其中
使用过哪些设计模式?
IOC和DI设计模式。
工厂设计模式:Spring使用工厂模式通过BeanFactory和ApplicationContext创建bean对象。
单例设计模式:Spring中的Bean对象默认都是单例的。
代理设计模式:AOP是基于动态代理实现的。
适配器模式:SpringAOP的增强/通知(Advice)以及SpringMVC中的Controller都用到了适配器模式
设计模式六大原则:
1、单一原则(Single Responsibility Principle):一个类或者一个方法只负责一项职责,尽量做到类的只有一个行为原因引起变化;
a、业务对象(BO business object)、业务逻辑(BL business logic)拆分;
2、里氏替换原则(LSP liskov substitution principle):子类可以扩展父类的功能,但不能改变原有父类的功能;(本质其实就是c++的多态)
(目的:增强程序的健壮性)实际项目中,每个子类对应不同的业务含义,使父类作为参数,传递不同的子类完成不同的业务逻辑。
3、依赖倒置原则(dependence inversion principle):面向接口编程;(通过接口作为参数实现应用场景)
抽象就是接口或者抽象类,细节就是实现类
含义:
上层模块不应该依赖下层模块,两者应依赖其抽象;
抽象不应该依赖细节,细节应该依赖抽象;
通俗点就是说变量或者传参数,尽量使用抽象类,或者接口;
【接口负责定义public属性和方法,并且申明与其他对象依赖关系,抽象类负责公共构造部分的实现,实现类准确的实现业务逻辑】
4、接口隔离原则(interface segregation principle):建立单一接口;(扩展为类也是一种接口,一切皆接口)
定义:
a.客户端不应该依赖它不需要的接口;
b.类之间依赖关系应该建立在最小的接口上;
简单理解:复杂的接口,根据业务拆分成多个简单接口;(对于有些业务的拆分多看看适配器的应用)
【接口的设计粒度越小,系统越灵活,但是灵活的同时结构复杂性提高,开发难度也会变大,维护性降低】
5、迪米特原则(law of demeter LOD):最少知道原则,尽量降低类与类之间的耦合;
一个对象应该对其他对象有最少的了解
6、开闭原则(open closed principle):用抽象构建架构,用实现扩展原则;
什么是栈,堆?它们有什么区别?
堆和栈都java内存,堆是用来存储java中对象和数组,在创建一个数组或者对象时,堆内存会留一段空间存放它,栈使用来执行程序的。
1.功能不一样
栈内存用来存储局部变量和方法调用;堆内存用来存储java中的对象。
2.空间大小不一样
栈的内存要小于堆的内存。
Java EE
get 和 post 请求的区别?
1.get请求一般是去取获取数据(其实也可以提交,但常见的是获取数据);
post请求一般是去提交数据。
2.get因为参数会放在url中,所以隐私性,安全性较差,请求的数据长度是有限制的,
不同的浏览器和服务器不同,一般限制在 2~8K 之间,更加常见的是 1k 以内;
post请求是没有的长度限制,请求数据是放在body中;
3.get请求刷新服务器或者回退没有影响,post请求回退时会重新提交数据请求。
4.get请求可以被缓存,post请求不会被缓存。
5.get请求会被保存在浏览器历史记录当中,post不会。get请求可以被收藏为书签,因为参数就是url中,但post不能。它的参数不在url中。
6.get请求只能进行url编码(appliacation-x-www-form-urlencoded),post请求支持多种(multipart/form-data等)。
cookie和seesion的区别?
1.co oki es:是针对每个网站的信息,每个网站只能对应一个,其他网站无法访问,这个文件保存在客户端,每次您拨打相应网站,浏览器都会查找该网站的 cookies,如果有,则会将该文件发送出去。cookies文件的内容大致上包括了诸如用户名、密码、设置等信息。
2.se ss ion:是针对每个用户的,只有客户端才能访问,程序为该客户添加一个 session。session中主要保存用户的登录信息、操作信息等等。此 session将在用户访问结束后自动消失(如果也是超时)。
3.存储数据的大小不同,一个 cookie存储的数据不超过3 K; session存储在服务器上可以任意存储数据,但是,当 session存储数据太多时,服务器可选择进行清理。
转发和重定向的区别?
1、请求次数不同;2、重定向时地址栏会发生变化,而转发时地址栏不会发生变化;3、重定向两次请求不共享数据,转发一次请求共享数据。
jsp的作用域有哪些或有哪些内置对象?
JSP的四大作用域:pageContext、request、session、application。
JSP的九大内置对象:page、config、request、response、session、application、out、pageContext 、exception
jsp和servlet的区别?
从技术角度,JSP是包含静态和动态数据的文本文档。静态数据以基于文本的格式表示(例如:XML、HTML),而JSP元素表示动态数据。
Servlet是一个Java类了,它按照请求-响应模式扩展了承载应用程序的服务器功能。
Servlet通常用于扩展由Web服务器托管的应用程序。尽管如此,它们也可以响应各种类型的请求。专门针对此类应用程序,Java Servlet技术指定了HTTP特定的servlet类。
springmvc有哪些常用的注解?
@RequestMapping:用来设置方法的请求地址。它呢可以用在类上也可以用在方法上,用在类上的话,则访问所有的请求方法时都需要加上该地址作为父路径。
@GetMapping:也是用来设置方法的请求地址的,但是只支持get请求。一般在进行查询操作的时候会用到这个注解。
@PostMapping:也是用来设置方法的请求地址的,但是只支持post请求。一般在进行新增操作或者传递的参数比较多的情况下会用到这个注解。
@DeleteMapping:也是用来设置方法的请求地址的,但是只支持delete请求。一般在进行删除操作的时候会用到这个注解。
@PutMapping:也是用来设置方法的请求地址的,但是只支持delete请求。一般在进行修改操作的时候会用到这个注解。
@ResponseBody:用于将服务器端返回java对象转为JSON数据。
@RequestBody: 用于将客户端传递过来的JSON数据转换为java对象。
@RestController: 它是一个组合注解,组合了@Controller和@ResponseBody这两个注解。如果说某个Controller所有的方法都需要返回JSON格式的数据,直接在Controller类上加上这个注解,这样就不用我们在每个方法上再单独添加@ResponseBody注解了。
@PathVariable:用来获取路径参数
@RequestParam:用来设置请求参数和请求方法里的参数的映射,一般用于请求参数名和请求方法中参数名不一致的情况。
springmvc如何去处理客户端发起的请求?
1、 首先用户发送请求——>DispatcherServlet,前端控制器收到请求后自己不进行处理,而是委托给其他的解析器进行处理,作为统一访问点,进行全局的流程控制;
2、 DispatcherServlet——>HandlerMapping,HandlerMapping将会把请求映射为HandlerExecutionChain对象(包含一个Handler处理器(页面控制器)对象、多个HandlerInterceptor拦截器)对象,通过这种策略模式,很容易添加新的映射策略;
3、 DispatcherServlet——>HandlerAdapter,HandlerAdapter将会把处理器包装为适配器,从而支持多种类型的处理器,即适配器设计模式的应用,从而很容易支持很多类型的处理器;
4、 HandlerAdapter——>处理器功能处理方法的调用,HandlerAdapter将会根据适配的结果调用真正的处理器的功能处理方法,完成功能处理;并返回一个ModelAndView对象(包含模型数据、逻辑视图名);
5、 ModelAndView的逻辑视图名——> ViewResolver,ViewResolver将把逻辑视图名解析为具体的View,通过这种策略模式,很容易更换其他视图技术;
6、 View——>渲染,View会根据传进来的Model模型数据进行渲染,此处的Model实际是一个Map数据结构,因此很容易支持其他视图技术;
7、返回控制权给DispatcherServlet,由DispatcherServlet返回响应给用户,到此一个流程结束。
spring ioc 和 aop分别是什么?
IOC是spring的两大核心概念之一,IOC是一种控制反转的思想,他给我们提供了一个bean容器,这个容器会帮我们自动去创建对象,不需要我们手动创建,IOC的具体实现是通过DI(依赖注入),我们可以通过写Java注解代码或者是XML配置方式,把我们想要注入对象所依赖的一些其他的bean,自动的注入进去,他是通过byName或byType类型的方式来帮助我们注入。正是因为有了依赖注入,使得IOC有这非常强大的好处:解耦。
在日常工作中,我们可能会遇到许多重复性的代码,比如事务、日志,我们需要在很多类里面同时把这些代码写进去,这样的话是非常麻烦的,比如事务,我们需要在所有的service层里开启事务、提交、回滚。
Spring AOP可以给我们提供面向切面编程,将这些共有的代码抽象出来,切入到我们想要切入的类中,极大的方便了我们代码的书写,减少了我们的冗余代码。AOP的实现是通过动态代理实现的,如果我们要代理的对象有接口,那么我们就是用Java原生的动态代理,如果没有实现任何接口,会采用Cglib的技术进行动态代理类的创建。
spring有哪些常用注解?
@Component : 这将 java 类标记为 bean。它是任何 Spring 管理组件的通用 构造型。spring 的组件扫描机制现在可以将其拾取并将其拉入应用程序环境中。 @Controller : 这将一个类标记为 Spring Web MVC 控制器。标有它的Bean 会自动导入到 IoC 容器中。@Service :此注解是组件注解的特化。它不会对 @Component 注解提供任何其他行为。您可以在服务层类中使用
@Service 而不是 @Component, 因为它以更好的方式指定了意图。 @Repository : 这个注解是具有类似用途和功能的 @Component 注解的特 化。它为 DAO 提供了额外的好处。它将 DAO 导入 IoC 容器, 并使未经检查的 异常有资格转换为 Spring
@@Qualifier 当您创建多个相同类型的 bean 并希望仅使用属性装配其中一个 bean 时,您可以 使用@Qualifier 注解和 @Autowired 通过指定应该装配哪个确切的 bean 来消 除歧义。
spring有哪些事务?事务的实现方式?
spring框架提供了两种事务实现方式:编程式事务、声明式事务
编程式事务:在代码中进行事务控制。优点:精度高。缺点:代码耦合度高
声明式事务:通过@Transactional注解实现事务控制
什么是mybatis?
MyBatis 是一个可以自定义SQL、存储过程和高级映射的持久层框架。MyBatis 摒除了大部分的JDBC代码、手工设置参数和结果集重获。MyBatis 只使用简单的XML 和注解来配置和映射基本数据类型、Map 接口和POJO 到数据库记录。相对Hibernate和Apache OJB等“一站式”ORM解决方案而言,Mybatis 是一种“半自动化”的ORM实现。
#{}和${}的区别是什么?
#{}是预编译处理,$ {}是字符串替换。
使用 #{} 可以有效的防止SQL注入,提高系统安全性
mysql基本语法?
一.增Insert
基本语法 insert into 表名(列1,列2,列3,列4,…) values(值,值,值)
例子 insert into student(name,sex,age) values(‘张三’,18,’男’)
二.删delete
基本语法 delete from 表名 where 列=值
例子 delete from student where id=1
DELETE from 表名 一行行删除整张表
基本语法 update 表名 set 列=值,列=值,…. where…
列子 update student set name = ‘张三’ where id=1
三.改update
基本语法 update 表名 set 列=值,列=值,…. where…
列子 update student set name = ‘张三’ where id=1
四.查select
1.基本的select查询语句
select * from student(查询student表中所有列)
mysql如何进行模糊查询?
“%” 百分号通配符: 表示任何字符出现任意次数 (可以是0次)。
“_” 下划线通配符:表示只能匹配单个字符,不能多也不能少,就是一个字符。当然,也可以like “陈”,数量不限。
like操作符:LIKE作用是指示mysql后面的搜索模式是利用通配符而不是直接相等匹配进行比较;但如果like后面没出现通配符,则在SQL执行优化时将 like 默认为 “=”执行
mysql如何分页查询?
select * from table order by id limit m, n;
很简单,该语句的意思就是查询m+n条记录,去掉前m条,返回后n条。无疑该查询能够实现分页,但m越大,查询性能就越低,因为MySQL需要扫描全部m+n条记录。
mysql如何排序查询?
SELECT 查询列表FROM 表【WHERE 筛选条件】ORDER BY 排序列表 【ASC | DESC】
ASC:代表的是升序;DESC:代表的是降序。如果不写默认是升序。
ORDER BY子句一般放在查询语句的最后面,limit子句除外。
group by 是什么意思?
group_by的意思是根据by对数据按照哪个字段进行分组,或者是哪几个字段进行分组。“Group By”从字面意义上理解就是根据“By”指定的规则对数据进行分组,所谓的分组就是将一个“数据集”划分成若干个“小区域”,然后针对若干个“小区域”进行数据处理。
语法结构如下所示:select 字段 from 表名 where 条件 group by 字段
或者
select 字段 from 表名 group by 字段 having 过滤条件
注意:对于过滤条件,可以先用where,再用group by或者是先用group by,再用having
mysql有哪几种事务?
原子性,事务中包含的各操作要么都做,要么都不做;
一致性,事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态;
隔离性,一个事务的执行不能对其它事务形成干扰。即一个事务内部的操作及使用的数据对其它并发事务是隔离的,并发执行的各个事务之间不能互相干扰;
持久性,一个事务一旦提交,它对数据库中的数据的改变就应该是永久性的。接下来的其它操作或故障不应该对其执行结果有任何影响。
MySQL 中有哪几种锁?
基于锁的属性分类:共享锁(读锁)、排他锁(写锁)。
基于锁的粒度分类:行级锁((innodb )、表级锁( innodb、myisam)、页级锁( innodb引擎)、记录锁、间隙锁、临键锁。
基于锁的状态分类:意向共享锁、意向排它锁(一般不用)。
mysql设计表要注意哪些?
库名、表名、字段名必须使用小写字母,“_”分割。
库名、表名、字段名必须不超过12个字符。
库名、表名、字段名见名知意,建议使用名词而不是动词。
建议使用InnoDB存储引擎。
存储精确浮点数必须使用DECIMAL替代FLOAT和DOUBLE。
建议使用UNSIGNED存储非负数值。
建议使用INT UNSIGNED存储IPV4。
整形定义中不添加长度,比如使用INT,而不是INT(4)。
使用短数据类型,比如取值范围为0-80时,使用TINYINT UNSIGNED。
不建议使用ENUM类型,使用TINYINT来代替。
尽可能不使用TEXT、BLOB类型。
VARCHAR(N),N表示的是字符数不是字节数,比如VARCHAR(255),可以最大可存储255个汉字,需要根据实际的宽度来选择N。
VARCHAR(N),N尽可能小,因为MySQL一个表中所有的VARCHAR字段最大长度是65535个字节,进行排序和创建临时表一类的内存操作时,会使用N的长度申请内存。
表字符集选择UTF8。
使用VARBINARY存储变长字符串。
存储年使用YEAR类型。
存储日期使用DATE类型。
存储时间(精确到秒)建议使用TIMESTAMP类型,因为TIMESTAMP使用4字节,DATETIME使用8个字节。
建议字段定义为NOT NULL。
将过大字段拆分到其他表中。
禁止在数据库中使用VARBINARY、BLOB存储图片、文件等。
表结构变更需要通知DBA审核。
mysql的索引是什么?
在mysql中,索引是一种特殊的数据库结构,由数据表中的一列或多列组合而成,可以用来快速查询数据表中有某一特定值的记录。通过索引,查询数据时不用读完记录的所有信息,而只是查询索引列即可。
如何优化mysql?
-
在读表的时候,尽可能的避免全表扫描,合理的根据业务需求,在where及order by涉及的列上建立索引。
-
应尽量避免在where字句中使用!=或 <> 操作符,否则将引擎会放弃索引而走全表扫描。
-
尽量避免where字句中对字段进行null值判断,否则也会导致引擎放弃索引而走全表扫描。可以用0代替判断,前提是保证字段不能为null。
-
尽量避免在where字句中用or拼接,否则也会走全表扫描。可以通过union all 拼接代替。
-
尽量不适用Like做搜索查询,诺要提高效率,可以采用全文检索。
-
尽量不适用In或 Not in查询,否则会导致全表扫描。对于连续的数字,可以用between代替 in。比如:select id from t where num between 1 and 3
-
如果在where字句中使用参数,也会导致全表扫描。因为SQL只有在运行时才会解析局部变量,但优化程序不能将访问计划的选择推迟到运行时;它必须在编译时进行选择。然 而,如果在编译时建立访问计划,变量的值还是未知的,因而无法作为索引选择的输入项。比如:select id from t where num=@num
可以改为强制查询使用索引:select id from t with(index(索引名)) where num=@num -
尽量避免在 where子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。比如:select id from t where num/2=100
-
应尽量避免在where子句中对字段进行函数操作。
-
不要在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引。
-
并不是所有索引对查询都有效,SQL是根据表中数据来进行查询优化的,当索引列有大量数据重复时,SQL查询可能不会去利用索引,如一表中有字段 sex,male、female几乎各一半,那么即使在sex上建了索引也对查询效率起不了作用。
-
索引并不是越多越好,索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率,因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。一个表的索引数最好不要超过6个,若太多则应考虑一些不常使用到的列上建的索引是否有 必要。
-
应尽可能的避免更新 clustered(聚集)索引数据列,因为 clustered索引数据列的顺序就是表记录的物理存储顺序,一旦该列值改变将导致整个表记录的顺序的调整,会耗费相当大的资源。若应用系统需要频繁更新 clustered索引数据列,那么需要考虑是否应将该索引建为 clustered索引。一个表只能有一个聚集索引,比如表中的时间列。
-
尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连接时会 逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。
-
尽可能的使用 varchar/nvarchar 代替 char/nchar ,因为首先变长字段存储空间小,可以节省存储空间,其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些。
-
尽量不要select查询*全部信息,只读取所需要的字段。
-
避免频繁创建和删除临时表,以减少系统表资源的消耗。
-
在新建临时表时,如果一次性插入数据量很大,那么可以使用 select into 代替 create table,避免造成大量 log ,以提高速度;如果数据量不大,为了缓和系统表的资源,应先create table,然后insert。
-
尽量避免大事务操作,提高系统并发能力。
-
尽量避免向客户端返回大数据量,若数据量过大,应该考虑相应需求是否合理。
分布式
什么是springboot?
Springboot是Spring开源组织下的子项目,是Spring组件一站式解决方案,主要是简化了使用Spring的难度,简省了繁重的配置,提供了各种启动器,开发者能快速上手。
springboot有哪些常用注解?
启动注解 @SpringBootApplication
@SpringBootConfiguration 注解,继承@Configuration注解,主要用于加载配置文件
@EnableAutoConfiguration 注解,开启自动配置功能
@ComponentScan 注解,主要用于组件扫描和自动装配
redis有几种持久化方式?如何进行持久化?
RDB,就是把内存数据以快照的形式保存到磁盘上。和AOF相比,它记录的是某一时刻的数据,,并不是操作。
AOF(append only file) 持久化,采用日志的形式来记录每个写操作,追加到AOF文件的末尾。Redis默认情况是不开启AOF的。重启时再重新执行AOF文件中的命令来恢复数据。它主要解决数据持久化的实时性问题。
redis的缓存击穿,穿透,雪崩是什么?
所谓的redis缓存雪崩指的是:redis中大量key集中过期或者redis服务器宕机,从而导致大量请求从数据库获取数据,导致数据库服务器访问压力过大。
所谓的redis缓存击穿指的是:热点key的过期,从而导致大量访问热点key的请求访问数据库,从而导致数据库压力过大。
所谓的redis缓存穿透指的是:redis当中没有数据,数据库当中也没有数据,请求每次都是访问数据库,而数据库有没有数据返回
先存到mysql还是先存到redis?
一种是对数据时效性要求高的,会先写入redis,这样读取的时候就能读取到最新的数据,然后再把数据同步到mysql中。
一种是先写入mysql,然后再写入redis。这样实现方便,每次只要redis不存在,就从mysql获取数据即可,缺点也明显,有一定的数据延迟。数据一致性要求不高的场合可以使用这种方式。
如何保证redis和mysql数据一致性?
可以采用延时双删策略
在写库前后都进行redis.del(key)操作,并且设定合理的超时时间。
伪代码如下:
public void write( String key, Object data ){ redis.delKey( key ); db.updateData( data ); Thread.sleep( 500 ); redis.delKey( key );}
1、先删除缓存
2、再写数据库
3、休眠xxx毫秒(根据具体的业务时间来定)
4、再次删除缓存
问题:这个500毫秒怎么确定的,具体该休眠多久时间呢?
1、需要评估自己的项目的读数据业务逻辑的耗时。
2、这么做的目的,就是确保读请求结束,写请求可以删除读请求造成的缓存脏数据。
3、当然这种策略还要考虑redis和数据库主从同步的耗时。
4、最后的的写数据的休眠时间:则在读数据业务逻辑的耗时基础上,加几百ms即可。
比如:休眠1秒。
设置缓存过期时间时关键点
1、从理论上来说,给缓存设置过期时间,是保证最终一致性的解决方案
2、所有的写操作以数据库为准,只要到达缓存过期时间,缓存删除
3、如果后面还有读请求的话,就会从数据库中读取新值然后回填缓存
什么是反向代理?
通常的代理服务器仅用于代理从内部网络到互联网外部网络的连接请求。而客户端必须指定一个代理服务器,并将直接发送到Web服务器的HTTP请求发送到代理服务器。不支持从外部网络到内部网络的连接请求,因为内部网络对外部网络不可见。代理服务器可以代理外部网络上的主机并访问内部网络时,这项代理服务便称为反向代理服务。
什么是正向代理?
正向代理:是一个位于客户端和原始服务器(origin server)之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。客户端才能使用正向代理。
如何实现nginx的负载均衡?
负载均衡器:将用户请求根据对应的负载均衡算法分发到应用集群中的一台服务器进行处理
修改nginx.conf配置文件;
微服务有哪些组件?
服务注册中心:注册系统中所有服务的地方。
服务注册:服务提供方将自己调用地址注册到服务注册中心,让服务调用方能够方便地找到自己。
·服务发现:服务调用方从服务注册中心找到自己需要调用服务的地址。
·负载均衡:服务提供方一般以多实例的形式提供服务,使用负载均衡能够让服务调用方连接到合适的服务节点。
·服务容错:通过断路器(也称熔断器)等一系列的服务保护机制,保证服务调用者在调用异常服务时快速地返回结果,避免大量的同步等待。
·服务网关:也称为API网关,是服务调用的唯一入口,可以在这个组件中实现用户鉴权、动态路由、灰度发布、负载限流等功能。
分布式配置中心:将本地化的配置信息(properties、yml、yaml等)注册到配置中心,实现程序包在开发、测试、生产环境的无差别性,方便程序包的迁移。
liunx 基本命令有哪些?
s 显示文件或目录
-l 列出文件详细信息l(list)
-a 列出当前目录下所有文件及目录,包括隐藏的a(all)
mkdir 创建目录
-p 创建目录,若无父目录,则创建p(parent)
cd 切换目录
touch 创建空文件
echo 创建带有内容的文件。
cat 查看文件内容
cp 拷贝
mv 移动或重命名
rm 删除文件
-r 递归删除,可删除子目录及文件
-f 强制删除
find 在文件系统中搜索某文件
wc 统计文本中行数、字数、字符数
grep 在文本文件中查找某个字符串
rmdir 删除空目录
tree 树形结构显示目录,需要安装tree包
pwd 显示当前目录
ln 创建链接文件
more、less 分页显示文本文件内容
head、tail 显示文件头、尾内容
ctrl+alt+F1 命令行全屏模式