面试中常见问题汇集:

大家好,我是Java初学者,来CSDN主要也是为了学习知识。在个人博客中主要记录一些个人笔记、总结、学习心得等,如有不足之处请纠正,欢迎补充。——来自 菜鸟的蜕变

一、MySql与Oracle的区别

  1. 并发性
    MySQL:
    MySQL以表级锁为主,对资源锁定的粒度很大,如果一个session对一个表加锁时间过长,会让其他session无法更新此表中的数据。
    虽然InnoDB引擎的表可以用行级锁,但这个行级锁的机制依赖于表的索引,如果表没有索引或sql语句未使用索引,仍然会使用表级锁。
    Oracle:
    Oracle使用行级锁,对资源锁定的粒度要小很多,只是锁定sql需要的资源,并且加锁是在数据中心的数据行上,不依赖于索引。所以Oracle对并发性的支持要好很多。

  2. 事务的提交
    MySQL默认自动提交,而Oracle默认不自动提交–需用户手动提交,需要在写commit,指令或点击commit按钮。

  3. 事务隔离级别
    MySQL是read commited的隔离级别,而Oracle是repeatable read的隔离级别,二者都支持serializable串行化事务隔离级别,可以实现最高级别的读一致。
    每个session提交后其他session才能看到提交的更改。
    Oracle通过在undo表空间中构造多版本数据来实现读一致,每个session查询时,如对应数据块发生变化,Oracle会在undo表空间中为这个session构造它查询时的旧的数据块;
    MySQL没有雷士Oracle的构造多版本数据块的机制,只支持read commited的隔离级别。一个session读取数据时,其他session不能更改数据,但可以在表最后插入数据。session更新数据时要加上排它锁,其他session无法访问数据。

  4. 分页查询
    MySQL是直接在SQL语句中写 “select xxx from xxx where xxx limit x,y” ,有limit就可以实现分页;而Oracle则是需要用伪列ROWNUM和嵌套查询。

  5. 事务支持
    MySQL在innodb存储引擎的行级锁的情况下才可支持事务,而Oracle则完全支持事务。

  6. 持久性
    MySQL在数据库更新或重启,会丢失数据,而Oracle会把提交的SQL操作线写入在线联机日志文件中,保存到磁盘上 可随时恢复。

  7. 逻辑备份
    MySQL(逻辑)备份时要锁定数据才能保证备份的数据是一致的,影响业务正常的DML使用,而Oracle备份时不需锁定数据且备份的数据是一致的。

  8. 管理工具
    MySQL管理工具较少,在linux下的管理工具的安装有时还需装额外的包(phpmyadmin …),有些复杂;
    Oracle有多种成熟命令行、图形界面、web管理工具,还有其他第三方管理工具,管理方便且高效。

  9. 权限与安全
    MySQL的用户与主机有关,容易被仿冒主机及IP有可乘之机;
    Oracle则较为传统,中规中矩。

  10. 分区表与分区索引
    MySQL不太成熟稳定,Oracle则很成熟,可提高用户访问DB的体验。

  11. 性能诊断
    MySQL诊断调优方法较少,主要有慢查询日志;
    Oracle则有各种陈述的诊断调优工具,能实现多自动分析、诊断功能。如:awr、
    addm、sqltrace、tkproof等。

  12. 复制
    MySQL复制服务器配置简单,但主库出现问题时 从库有可能丢失一定数据,且需要手动切换从库到主库;
    Oracle既有推和拉式的传统数据复制,也有dataguard的双机或多级容灾机制,主库出现问题时 可自动切换备库到主库,但配置管理复杂。

  13. 其他
    MySQL是轻量级数据库-免费,没有服务恢复数据;
    Oracle重量型数据库-收费,Oracle公司对Oracle数据库有任何服务。

二、List与HashMap底层的实现

  1. List

List实现Collection接口,它的数据结构是有序可以重复的结合,该结合的体系有索引;它有三个实现类:ArrayList、LinkList、Vector三个实现类;
三个实现类的区别:
ArrayList:底层数据结构使数组结构,查询速度快,增删改慢,
LinkList:底层使用链表结构,增删速度快,查询稍慢;
Vector:底层是数组结构,线程同步ArrayList是线程不同步;
可变长度数组不断new数组:
ArrayList当初始化容量超过10时,会new一个50%de ,把原来的东西放入这150%中;
Vector:当容量超过10时,会new一个100%的浪费内存;

List接口对Collection进行了简单的扩充,它的具体实现类常用的有ArrayList和LinkedList。你可以将任何东西放到一个List容器中,并在需要时从中取出。ArrayList从其命名中可以看出它是一种类似数组的形式进行存储,因此它的随机访问速度极快,而LinkedList的内部实现是链表,它适合于在链表中间需要频繁进行插入和删除操作。在具体应用时可以根据需要自由选择。前面说的Iterator只能对容器进行向前遍历,而ListIterator则继承了Iterator的思想,并提供了对List进行双向遍历的方法。

  1. HashMap底层实现

HashMap实现了Map接口,Map接口对键值对进行映射。Map中不允许重复的键。Map接口有两个基本的实现,HashMap和TreeMap。TreeMap保存了对象的排列次序,而HashMap则不能。HashMap允许键和值为null。HashMap是非synchronized的,但collection框架提供方法能保证HashMap synchronized,这样多个线程同时访问HashMap时,能保证只有一个线程更改Map。
构造方法:
HashMap提供了四个构造方法,构造方法中,依靠第三个方法来执行的,但是前三个方法都没有进行数组的初始化操作,即使调用了构造方法此时存放HaspMap中数组元素的table表长度依旧为0 。在第四个构造方法中调用了inflateTable()方法完成了table的初始化操作,并将m中的元素添加到HashMap中。
HashMap的工作原理 :HashMap是基于散列法(又称哈希法hashing)的原理,使用put(key, value)存储对象到HashMap中,使用get(key)从HashMap中获取对象。
当我们给put()方法传递键和值时,我们先对键调用hashCode()方法,返回的hashCode用于找到bucket(桶)位置来储存Entry对象。”HashMap是在bucket中储存键对象和值对象,作为Map.Entry。并不是仅仅只在bucket中存储值

三、乐观锁与悲观锁

  1. 概念
    ·悲观锁(Pessimistic Lock):每次拿数据的时候都会担心会被别人修改(疑心重很悲观),所以每次在拿数据的时候都会上锁。确保自己使用的过程中不会被别人访问,自己使用完后再解锁。
    期间需要访问该数据的都会等待。(传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。Java中synchronized和ReentrantLock等独占锁就是悲观锁思想的实现。)

    ·乐观锁(Optimistic Lock):每次拿数据的时候都完全不担心会被别人修改(心态好很乐观),所以每次在拿数据的时候都不会上锁。但是在更新数据的时候去判断该期间是否被别人修改过(使用版本号、CAS算法实现等机制),期间该数据可以随便被其他人读取。(乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库提供的类似于write_condition机制,其实都是提供的乐观锁。在Java中java.util.concurrent.atomic包下面的原子变量类就是使用了乐观锁的一种实现方式CAS实现的。)

  2. 使用场景
    乐观锁适用于多读场景,即冲突很少发生的时候,这样可以省去锁的开销,加大系统的吞吐量;
    悲观锁适用于多写场景下,多写情况 一般会产生冲突,这就会导致上层应用汇不断进行retry,反而降低了性能。

  3. 乐观锁常见的两种实现方式

乐观锁一般会使用版本号机制或CAS算法实现。

版本号机制:
在数据表中加上一个数据版本号version字段,表示数据 被修改的次数,当数据被修改时,version值会加一。当线程A要更新数据值时,在读取数据的同时也会读取version值,在提交更新时,若刚才读取到的version值为当前数据库中的version值相等时才更新,否则重试更新操作,直到更新成功。
例:
假设数据库中帐户信息表中有一个 version 字段,当前值为 1 ;而当前帐户余额字段( balance )为 $100 。
操作员 A 此时将其读出( version=1 ),并从其帐户余额中扣除 $50( $100-$50 )。
在操作员 A 操作的过程中,操作员B 也读入此用户信息( version=1 ),并从其帐户余额中扣除 $20 ( $100-$20 )。
操作员 A 完成了修改工作,将数据版本号加一( version=2 ),连同帐户扣除后余额( balance=$50 ),提交至数据库更新,此时由于提交数据版本大于数据库记录当前版本,数据被更新,数据库记录 version 更新为 2 。
操作员 B 完成了操作,也将版本号加一( version=2 )试图向数据库提交数据( balance=$80 ),但此时比对数据库记录版本时发现,操作员 B 提交的数据版本号为 2 ,数据库记录当前版本也为 2 ,不满足 “ 提交版本必须大于记录当前版本才能执行更新 “ 的乐观锁策略,因此,操作员 B 的提交被驳回。
这样,就避免了操作员 B 用基于 version=1 的旧数据修改的结果覆盖操作员A 的操作结果的可能。

CAS算法(compare and swap——比较与交换)

有名的无所算法,无锁编程,即不使用锁的情况下实现多线程之间的变量同步,也就是在没有线程被阻塞的情况下实现变量的同步,所以也叫非阻塞同步(Non-blocking Synchronization)。涉及三个操作数:
需要读写的内存值 V
进行比较的值 A
拟写入的新值 B
当且仅当 V 的值等于 A时,CAS通过原子方式用新值B来更新V的值,否则不会执行任何操作(比较和替换是一个原子操作)。一般情况下是一个自旋操作,即不断的重试。

  1. 乐观锁的缺点
    ABA 问题(乐观锁常见问题
    如果一个变量V初次读取的时候是A值,并且在准备赋值的时候检查到它仍然是A值,那我们就能说明它的值没有被其他线程修改过了吗?很明显是不能的,因为在这段时间它的值可能被改为其他值,然后又改回A,那CAS操作就会误认为它从来没有被修改过。这个问题被称为CAS操作的 "ABA"问题。
    JDK 1.5 以后的 AtomicStampedReference 类就提供了此种能力,其中的 compareAndSet 方法就是首先检查当前引用是否等于预期引用,并且当前标志是否等于预期标志,如果全部相等,则以原子方式将该引用和该标志的值设置为给定的更新值。
    循环时间长开销大
    自旋CAS(也就是不成功就一直循环执行直到成功)如果长时间不成功,会给CPU带来非常大的执行开销。 如果JVM能支持处理器提供的pause指令那么效率会有一定的提升,pause指令有两个作用,第一它可以延迟流水线执行指令(de-pipeline),使CPU不会消耗过多的执行资源,延迟的时间取决于具体实现的版本,在一些处理器上延迟时间是零。第二它可以避免在退出循环的时候因内存顺序冲突(memory order violation)而引起CPU流水线被清空(CPU pipeline flush),从而提高CPU的执行效率。
    只能保证一个共享变量的原子操作
    CAS 只对单个共享变量有效,当操作涉及跨多个共享变量时 CAS 无效。但是从 JDK 1.5开始,提供了AtomicReference类来保证引用对象之间的原子性,你可以把多个变量放在一个对象里来进行 CAS 操作.所以我们可以使用锁或者利用AtomicReference类把多个共享变量合并成一个共享变量来操作。

  2. CAS与synchronized的使用情景
    简单的来说CAS适用于写比较少的情况下(多读场景,冲突一般较少),synchronized适用于写比较多的情况下(多写场景,冲突一般较多)
    对于资源竞争较少(线程冲突较轻)的情况,使用synchronized同步锁进行线程阻塞和唤醒切换以及用户态内核态间的切换操作额外浪费消耗cpu资源;而CAS基于硬件实现,不需要进入内核,不需要切换线程,操作自旋几率较少,因此可以获得更高的性能。
    对于资源竞争严重(线程冲突严重)的情况,CAS自旋的概率会比较大,从而浪费更多的CPU资源,效率低于synchronized。
    其它:Java并发编程这个领域中synchronized关键字一直都是元老级的角色,很久之前很多人都会称它为 “重量级锁” 。但是,在JavaSE 1.6之后进行了主要包括为了减少获得锁和释放锁带来的性能消耗而引入的 偏向锁 和 轻量级锁 以及其它各种优化之后变得在某些情况下并不是那么重了。synchronized的底层实现主要依靠 Lock-Free 的队列,基本思路是 自旋后阻塞,竞争切换后继续竞争锁,稍微牺牲了公平性,但获得了高吞吐量。在线程冲突较少的情况下,可以获得和CAS类似的性能;而线程冲突严重的情况下,性能远高于CAS。

四、synchronized与lock区别

在这里插入图片描述

  1. 实现层
    synchronized是Java关键字,JVM层面实现加锁和释放锁;Lock是一个接口,在代码层面实现加锁和释放锁。

  2. 用法
    sychronized用在代码块和方法上;lock只能写在代码里,不能直接修改方法。

  3. 释放锁
    sychronized在线程代码执行完或出现异常自动释放锁;Lock不自动释放,需要在finally{}代码块显示地中释放锁。

  4. 等待
    sychronized会导致线程拿不到锁一直等待;Lock可以设置尝试获取锁或获取锁失败一定超时。

  5. 通知
    sychronized无法得知是否获取锁成功;Lock可以通过tryLock获得锁是否成功。

  6. 功能复杂性
    sychronized加锁可重入、不可中断、非公平;
    Lock可重入、可判断、可公平和不公平、细分读写锁提高效率。

五、IO,NIO,BIO,AIO区别

简单来说就是input和output流,IO流主要是用来处理设备之间的数据传输,Java IO对于数据的操作都是通过流实现的,而java用于操作流的对象都在IO包中。
BIO:同步阻塞,服务器实现模式为一个连接一个线程, 适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中, ,JDK1.4以前的唯一选择,但程序直观简单易理解。
NIO:同步非阻塞,服务器实现模式为一个请求一个线程, 适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中,编程比较复杂,JDK1.4开始支持。
AIO:异步非阻塞,服务器实现模式为一个有效请求一个线程, 适用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用OS参与并发操作,编程比较复杂,JDK7开始支持。

六、jsp和servlet的过滤器和拦截器

Jsp:JSP(Java Server Pages)是Sun 公司指定的一种服务器端动态页面技术的组件规范,Jsp是以“.jsp”为后缀的文件,在该文件中主要是html 和少量的java 代码。jsp 文件在容器中会转换成Servlet中执行。
Servlet:Servlet (Server Applet)是Sun公司指定的一种用来扩展Web服务器功能的组件规范,属于服务器端程序,主要功能在于交互式地浏览和修改数据,生成动态Web内容。
jsp就是在html里面写java代码,servlet就是在java里面写html
过滤器和拦截器的区别:
①拦截器是基于java的反射机制的,而过滤器是基于函数回调。
②拦截器不依赖与servlet容器,过滤器依赖与servlet容器。
③拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。
④拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。
⑤在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。
⑥拦截器可以获取IOC容器中的各个bean,而过滤器就不行,这点很重要,在拦截器里注入一个service,可以调用业务逻辑。

七、Spring框架里如何实现事务

实现方式共有两种:声明式和编程式(事务操作的地方很少的时候)声明式事务管理方式。
基于AOP技术实现的声明式事务管理,实质就是:在方法执行前后进行拦截,然后在目标方法开始之前创建并加入事务,执行完目标方法后根据执行情况提交或回滚事务。
声明式事务管理又有两种方式:基于XML配置文件的方式;另一个是在业务方法上进行@Transactional注解,将事务规则应用到业务逻辑中。

八、如何实现动态sql

Mybatis动态sql可以在Xml映射文件内,以标签的形式编写动态sql
Mybatis提供了9种动态sql标签:
trim | where | set | foreach | if | choose | when | otherwise | bind。
执行原理是根据表达式的值 完成逻辑判断并动态拼接sql的功能。

九、Mybatis与JDBC底层工作原理

mybatis的工作原理:
MyBatis是支持普通SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索。
MyBatis使用简单的XML或注解用于配置和原始映射,将接口和Java的POJOs(Plain Ordinary Java Objects,普通的 Java对象)映射成数据库中的记录。
每个MyBatis应用程序主要都是使用SqlSessionFactory实例的,一个SqlSessionFactory实例可以通过SqlSessionFactoryBuilder获得。用xml文件构建SqlSessionFactory实例是非常简单的事情。
推荐在这个配置中使用类路径资源,但可以使用任何Reader实例,包括用文件路径或file://开头的url创建的实例。MyBatis有一个实用类----Resources,它有很多方法,可以方便地从类路径及其它位置加载资源。
JDBC原理
Java数据库连接技术的简称。
是一种用于执行SQL语句的JavaAPI,提供连接各种常用数据库的能力。
1>加载驱动——-2>获取连接对象—–3>创建命令—–4>执行sql语句,并且返回结果集——5>处理结果集—–6>关闭连接

十、SpringBoot2.x与1.x的一些区别?

1.配置变更
2.JDK版本升级:2.x至少需要JDK1.8的支持,2.x里面的许多方法应用了JDK8的许多高级新特性。
3.第三方库升级:响应式spring编程支持
2.x通过启动器和自动配置全面支持Spring的相应编程,响应式编程是完全异步和非阻塞的,它是基于时间驱动模型,而不是传统的线程模型。就连Spring Boot内部叶对一些功能点进行了很必要的响应式升级,最值得注意的是对内嵌式容器的支持。
4.HTTP/2支持
提供对HTTP/2的支持,如:Tomcat,undertow,jetty,这个得依赖具体选择得应用服务器和应用环境。
5.配置属性绑定
在2.x中,配置绑定功能有一些改造,在调整了1.x中许多不一致地方外,还提供了独立注解之外得API来装配配置属性,并且增加了属性得来源。
6.更多改进和加强
Gradle插件提供了一些重要得特性提升。
Kotlin 2.x开始提供了runApplication函数来运行Spring Boot应用
Actuator加强所有得HTTP执行端点现在都暴露在/actuator路径下,并对JSON结果集也做了改善
Data支持上面有说到对响应式

十一、SpringBoot常见的注解及其底层实现

@SpringBootApplication包含了@springBootConfiguration,(继承了@Configuration注解主要用于加载配置文件,二者的功能也一样,标志这个类是配置类,并会将当前类内申明的一个或多个以@Bean标志的方法的实例纳入到spring容器中,并且实列名就是方法名。);

@EnableAutoConfiguration可以帮助SpringBoot应用将所有符合条件的@Configuration配置都加载到当前SpringBoot创建并使用的IoC容器。借助于Spring框架原有的一个工具类:SpringFactoriesLoader的支持,@EnableAutoConfiguration可以智能的自动配置功效才得以大功告成;

@componentScan(@ComponentScan的功能其实就是自动扫描并加载符合条件的组件或bean定义,最终将这些bean定义加载到容器中。我们可以通过basePackages等属性指定@ComponentScan自动扫描的范围,如果不指定,则默认Spring框架实现从声明@ComponentScan所在类的package进行扫描,默认情况下是不指定的,所以SpringBoot的启动类最好放在root package下。);

@Controller——控制器,处理http请求。

@RestController—— 复合注解,从源码我们知道,@RestController注解相当于@ResponseBody+@Controller合在一起的作用,RestController使用的效果是将方法返回的对象直接在浏览器上展示成json格式;

@RequestBody通过HttpMessageConverter读取Request Body并反序列化为Object(泛指)对象;

@RequestMapping
@RequestMapping 是 Spring Web 应用程序中最常被用到的注解之一。这个注解会将 HTTP 请求映射到 MVC 和 REST 控制器的处理方法上;

@GetMapping用于将HTTP get请求映射到特定处理程序的方法注解
注解简写:@RequestMapping(value = “/say”,method = RequestMethod.GET)等价于:@GetMapping(value = “/say”)
GetMapping源码是@RequestMapping(method = RequestMethod.GET)的缩写;

@PostMapping用于将HTTP post请求映射到特定处理程序的方法注解
是@RequestMapping(method = RequestMethod.POST)的缩写

@PathVariable:获取url中的数据

//请求示例:
http://localhost:8080/User/getUser/123

@RequestParam:获取请求参数的值

十二、Spring中DI与IOC原理

控制反转IoC(Inversion of Control)即创建对象的控制权进行转移,以前创建对象的主动权和创建时机是由自己把控的,而现在这种权力转移到第三方,比如转移交给了IoC容器,它就是一个专门用来创建对象的工厂,你要什么对象,它就给你什么对象,有了IoC容器,依赖关系就变了,原先的依赖关系就没了,它们都依赖IoC容器了,通过IoC容器来建立它们之间的关系。
DI(Dependency Injection),即“依赖注入”:组件之间依赖关系由容器在运行期决定。

IOC:
DispatcherServlet在初始化init()的时候,会去创建ApplicationContext,在其构造实例化时加载配置文件,并解析文件封装成一个个BeanDefinition,然后将BeanDefinition一个个以key-value的形式缓存到一个集合Map中。之后在调用getBean()时,会根据全类名去刚刚缓存的集合里拿到对应的BeanDefinition,之后根据BeanDefinition创建真正的实例对象。之后spring进一步把创建好的实例对象封装成BeanWapper,在把BeanWapper保存到IOC容器中。
DI:
在调用 getBean ( )时,才会执行依赖注入,利用 反射以及注解对其进行依赖注入。

十三、JDK1.8的新特性

1.Lambda表达式:Lambda允许把函数作为一个方法的参数(函数作为参数传递到方法中)。
2.方法引用:方法引用提供了非常有用的语法,可以直接引用已有Java类或对象(实例)的方法或构造器。与lambda联合使用,方法引用可以使语言的构造更紧凑简洁,减少冗余代码。
3.默认方法:默认方法就是一个在接口里面有了一个实现的方法。
4.新工具:新的编译工具,如:Nashorn引擎 jjs、 类依赖分析器jdeps。
5.Stream API:新添加的Stream API(java.util.stream) 把真正的函数式编程风格引入到Java中。
6.Date Time API:加强对日期与时间的处理。
7.Optional类:Optional 类已经成为 Java 8 类库的一部分,用来解决空指针异常。
8.Nashorn,JavaScript引擎:JDK1.8提供了一个新的Nashorn javascript引擎,它允许我们在JVM上运行特定的javascript应用。

十四、JS引入以及常见事件

①外部引用

//用script标签,链接外部的js文件
<script src="main.js"></script>

②内部引用

//写在HTML文件内,用script标签包括
<head>
  <script>
    alert('Hello World!');
  </script>
</head>

③行内引用

//写在HTML元素内部
<input type="button" value="按钮" onclick="alert('Hello World')" />

常见事件:
点击事件(onclick)
页面加载事件(onload)
内容改变事件(onchange):事件内容发生变化时
聚焦事件(onfocus)
失去焦点事件(onblur)
窗口滚动事件(onscroll)
表单提交事件(onsubmit)
鼠标移动到某对象上方(Onmousemove)、鼠标离开某一对象 (onmouseout)、鼠标移动到某个区域(onmouseover)
鼠标按下事件(onmousedown)、鼠标松开事件(onmouseup)

十五、VUE的理解及其事件

Vue是一套构建用户界面的渐进式框架,也可以理解为是一个视图模板引擎,强调的是状态到界面的映射。开发人员将js代码分为了三个板块,数据(Model),逻辑控制(*),视图(View),数据板块只负责数据部分,视图板块负责更改样式,逻辑控制负责联系视图板块和数据板块,这样子有很大的好处,当需求发生变动时,只需要修改对应的板块就好

//常见事件
   <!-- 方法处理器 -->
 <button v-on:click="doThis"></button>
 <!-- 缩写 -->
<button @click="doThis"></button>

 <!-- 内联语句 -->
<button v-on:click="doThat('HelloWord', $event)"></button>
 <!-- stop停止冒泡 -->
 <button @click.stop="doThis"></button>

十六、sql语句本身的优化以及创建表的注意事项

Sql语句优化:
(1)a. ORDER BY + LIMIT组合的索引优化;
b. WHERE + ORDER BY + LIMIT组合的索引优化;
c. WHERE+ORDER BY多个栏位+LIMIT
(2)如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引
(3)like语句优化
(4)where子句使用 != 或 <> 操作符优化
(5)where子句中使用 IS NULL 或 IS NOT NULL 的优化
(6)where子句使用or的优化
(7)where子句使用IN 或 NOT IN的优化(between替换in、exist替换in、left join替换in)
(8)where子句中对字段进行表达式操作的优化
(9)任何地方都不要用 select * from table,用具体的字段列表替换"*",不要返回用不到的字段
(10)使用“临时表”暂存中间结果
(11)limit分页优化
(12)批量插入优化
(13)利用limit 1 、top 1 取得一行
(14)尽量不要使用 BY RAND()命令
(15)尽量用 union all 替换 union
(16)避免类型转换:where子句中出现column字段的类型和传入的参数类型不一致的时候发生的类型转换
(17)尽可能使用更小的字段
(18)Inner join 和 left join、right join、子查询
建表注意事项:
使用三大范式去设计表;
树形结构的数据,通常采用自连接的方式;
字典表设计结构参考,通常采用结构表来进行设计

十七、数据库的索引

索引用来快速地寻找那些具有特定值的记录,所有MySQL索引都 以B-树的形式保存。mysql中主要有FULLTEXT(全文索引),HASH,BTREE,RTREE四种
HASH:在in和“=”条件下可一次定位,效率高,但对于范围查询和排序及组合索引效率任然不高。
BTREE:按一定算法将值存入属性结构中(二叉树),查询时依次遍历;
RTREE:仅支持geometry数据类型
索引类型:
普通索引:加速查询,允许插入重复值和空置
唯一索引:加速查询,列值唯一
主键索引:加速查询,列值唯一,且表中只有一个
全文索引:在MyISAM引擎上使用只能在CHAR,VARCHAR,TEXT类型字段上使用全文索引,解决了模糊查询效率低的问题。
组合索引:用于组合搜索,其效率大于索引合并。

十八、数据库的事务与隔离级别

数据库事务的四大特性
原子性:要么全部成功,要么全部失败回滚;
一致性:使数据库从一个一致性状态变换到另一个一致性状态;
隔离性:两个用户操作同一张表时,互不干扰;
持久性:事务一旦被提交了,那么对数据库中的数据的改变就是永久性的。
在这里插入图片描述
脏读:一个事务处理过程中读取到另一个未提交的事务中的数据;
不可重复度:一个事务读取了另一个已提交的事务中的数据;
幻读:一个事务在前后两次查询同一个范围的时候,后一次查询看到了前一次查询没有看到的行。

十九、重定向与转发区别(框架里如何实现)

区别:
1.请求重定向和请求转发都是web开发中资源跳转的方式。
2.请求转发是服务器内部的跳转
地址栏发生变化
只有一个请求相应
可以通过request域跳转目标的请求
3.请求重定向是浏览器自动发起对跳转目标的请求
地址栏会发生变化
两次请求相应
无法通过request域传递对象
4.转发是服务器行为,重定向是客户端行为
如何在框架里实现:
在SpringMVC框架中,控制处理器中处理方法的return语句默认就是转发实现,只不过实现的是转发到视图;
在视图名称之前加上forward:完成转发
return “forward:/index/isLogin”;
在视图名称之前加上redirect: 完成重定向
return “redirect:/index/isRegister”;

二十、会话跟踪技术(cookie session…)

1.客户端会话技术cookie:cookie是将数据保存在浏览器客户端的;
Cookie:
cookie的数据存在浏览器
浏览器客户端第一次请求服务器时,服务器端创建cookie,绑定数据后通过响应发送cookie到浏览器客户端,浏览器收到cookie后存储在本地,下次请求时将cookie又带回服务器
浏览器对单个cookie的大小有限制,一般为4kb(不同浏览器存在差异),并对同一个域名下cookie的数量也有限制(一般20个以内)
2.服务端会话技术session:session是将数据保存在服务器的;
Session:
Session创建后服务器将Session ID 通过Cookie发送到客服端浏览器,而浏览器则将该Session ID 保存在会话Cookie中。当浏览器再次向服务器发送HTTP请求时,会将Session ID 信息一起发送给服务器。服务器根据该Session ID 在服务器内存找到对应的Session对象,即可取出共享数据
session不是一打开网站就会立刻建立,创建session需要满足以下两个条件中的任意一个条件:
(1)后台服务器端调用HttpSession session = request.getSession()进行创建
(2)用户第一次访问jsp页面就会创建session,因为jsp默认会调用session = pageContext.getSession();
session是依赖cookie的,JSessionId通过cookie传递到浏览器,并在浏览器通过cookie的形式存在
3.Session和Cookie的区别
(1) Session存储在服务器端,Cookie存储在浏览器端
(2)Session存储无大小限制,Cookie存储数据有大小限制
(3)Session相对Cookie更安全

二十一、所了解的网络知识(ISO七层模型…)

在这里插入图片描述
七大层:应用层、表示层、会话层、传输层、网络层、数据链路层、物理层
应用层:为网络用户或应用程序提供各种服务,如文件传输、电子邮件、网络管理和远程登录等(协议代表:HTTP、Telnet、FTP、SNMP、RTSP);
表示层:用于处理在多个通信系统之间交换信息的表示方式,包括数据格式的转换、数据加密与解密、数据压缩与恢复等(ASCII、ASN.1、JPEG、MPEG);
会话层:针对远程访问进行管理(比如断点续传),包括会话管理、传输同步以及数据交换管理等(NetBIOS、ASP);
传输层:传输层从会话层接收数据,形成报文(Message),并且在必要时将其分成若干个分组,然后交给网络层进行传输。为上一层进行通信的两个进程之间提供一个可靠的端到端服务,使传输层以上的各层不再关心信息传输的问题;(端到端:进行相互通信的两个节点不是直接通过传输介质连接起来,相互之间有很多交换设备,如路由器),TCP、UDP、SPX;
网络层:进行路由选择,以确保数据分组(Packet)从发送端到达接收端,并在子网发生阻塞时进行拥塞控制。网络层还要解决异构网络(比如网络协议不同)的互连问题,以实现数据分组在不同类型的网络中传输(IP、IPX、RIP、OSPF)。
数据链路层:在两个相邻节点间的线路上无差错地传送以帧为单位的数据,并要产生和识别帧边界。数据链路层还提供了差错控制与流量控制的方法,保证在物理线路上传送的数据无差错(SDLC、HDLC、PPP、STP、帧中继)。
物理层:透明地传送二进制比特流,但物理层并不关心比特流的实际意义和结构,只是负责接收和传送比特流。定义网络硬件的特性,包括使用什么样的传输介质以及与传输介质连接的接头等物理特性,所典型规范代表有(EIA/TIA RS-232、EIA/TIA RS-449、V.35、RJ-45)。

二十二、TCP与UDP的区别

1.连接方面区别
TCP是面向连接;
UDP是无连接的,即发送数据之前不需要建立连接;
2.安全方面的区别
TCP提供可靠的服务,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;
UDP尽最大努力交付,即不保证可靠交付;
3.传输效率的区别
TCP传输效率相对较低;
UDP传输效率高,适用于对高速传输和实时性有较高的通信或广播通信;
4.连接对象数量的区别
TCP连接只能是点到点,一对一的;
UDP支持一对一,一对多,多对一和多对多的交互通信

二十三、HTTP协议的理解

超文本传输协议,是一种用于分布式、协作式和超媒体信息系统的应用层协议。HTTP是万维网的数据通信的基础。
HTTP请求内容:请求行、请求头、空行、请求体组成
请求行:请求方式+url+协议版本

  1. 常见的请求方法有GET、POST、PUT、DELETE、HEAD;
  2. 客户端获取的资源路径(所谓的URL);
  3. 客户端使用的HTTP协议版本号
    请求头:客户端向服务器发送请求的补充说明
    请求体:一般携带的请求参数
    HTTP响应内容:响应行、响应头、空行、响应体组成

在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值