最终复习1

面向对象

1. 面向对象有什么特征,请分别解释。

  1. 封装

    定义:隐藏对象的属性和实现细节,对外仅仅提供公共访问的方式。

    好处:变化隔离、提高重用性、安全性

  2. 继承

    定义:子类继承父类的行为和特征,使得子类对象具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为

    好处:

    1. 提高了代码的复用性。

    2. 让类与类之间产生了关系,提供了另一个特征多态的前提。

    缺点:增加耦合

  3. 多态

    定义:父类引用或者接口的引用指向自己子类的对象。

    好处:提高了程序的扩展性。

  4. 抽象

    抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面。

    抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用部分细节。抽象包括两个方面,一是过程抽象,二是数据抽象。

2.重载(overload)和重写(override)的区别?

  1. 两者都是实现多态的方式,区别在于重载实现的是编译时的多态性,重写实现的是运行时的多态性

  2. 重载发生在一个类中,同名的方法如果有不同的参数列表则视为重载(参数类型不同,参数个数不同,或者二者都不同)

  3. 重写:

    1. 继承关系中

    2. 方法名必须一样

    3. 参数列表必须高度保持一致

    4. 子类重写的方法的访问修饰符和返回值类型可以小于或者等于父类的那个方法

    5. 重写有一个特殊的场景——子类重写之后的方法的修饰符、返回类型、方法名、参数列表和父类高度保持一致——重构

3. 接口和抽象类的区别是什么?

  1. 抽象类是abstract关键字,接口是interface关键字

  2. 抽象类中允许有构造方法,而接口不允许

  3. 抽象类可以包含所有方法,而接口中只能包含抽象方法、静态方法、默认方法

  4. 一个子类最多只能继承一个抽象类,而一个实现类可以同时实现多个接口

  5. 抽象类中可以包含初始化块,而接口中不可以( 初始化块就是{ } )

4.同步和异步有何异同,在什么情况下分别使用他们?举例说明。

如果数据将在线程间共享。例如正在写的数据以后可能被另一个线程读到,或者正在读的数据可能已经被另一个线程写过了,那么这些数据就是共享数据,必须进行同步存取。当应用程序在对象上调用了一个需要花费很长时间来执行的方法,并且不希望让程序等待方法的返回时,就应该使用异步编程,在很多情况下采用异步途径往往更有效率。

5.分别解释什么是JVM、JRE和JDK

JVM(Java Virtual Machine):是Java虚拟机是一个可以执行Java字节码的虚拟机进程,Java源文件被编译成能被Java虚拟机执行的字节码文件,用于保证Java的跨平台的特性

虚拟机工作原理:源程序——java编译器——字节码——类装载器——字节码检验器——解释器——操作系统平台。

JRE(Java Runtime Environment):是Java运行时环境,包括JVM+java的核心类库

JDK(Java Development Kit):是Java开发工具包,针对开发者使用,包括JRE+开发工具,可以让开发者开发、编译、执行Java应用程序

6.Java的访问修饰符有哪些,并解释各自的作用域

public:修饰的属性和方法,其他所有类都能访问

protected:修饰的属性和方法,只能在一个包中或不同包中的子类访问

缺省:修饰的属性和方法,只能在同一个包中访问

private:修饰的属性和方法,只有本类能访问

List

1.请你列出你常用的集合框架中的类与接口(Java集合框架的基础接口有哪些?)

 

 

2.ArrayList、LinkedList 、Vector的区别

1.数据结构:

ArrayList:本质是数组,元素物理地址是连续的

LinkedList 本质是链表,元素物理地址是不连续的

2.增删改查元素:

查元素:

ArrayList元素物理地址是连续的,所以可以通过下标获得元素,速度很快

LinkedList 元素物理地址是不连续的,查询元素需要遍历链表,速度很慢

增元素:

ArrayList可能会扩容,导致元素复制与内存的浪费,不适合大量频繁的添加元素

LinkedList 是链式结构,添加元素只需要消耗一个内存节点即可,不会对其他元素产生影响

所以:ArrayList适合频繁的取元素,LinkedList 适合频繁的添加删除元素

Vector本质也是数组,与ArrayList一样,是线程安全的。

ArrayList扩容机制1.5倍,Vector扩容机制2倍

3.Collection与Collections的区别?

  1. Collection 是一个集合接口。它提供了对集合进行基本操作的接口方法

  2. Collections是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索、排序、线程安全等操作

4.List集合的遍历

List集合的遍历有三种方法,分别为增强for循环,利用Iterator、传统的for循环

//增强for循环
​
    @Test
    public void test2() {
        List l1 = new ArrayList();
        l1.add(123);
        l1.add("AA");
        l1.add(new String("狼来了"));
        //增强for循环
        for(Object l:l1) {
            System.out.print(l+"\t");
        }
    }
 //利用Iterator
​
    List l1 = new ArrayList();
        l1.add(123);
        l1.add("AA");
        l1.add(new String("狼来了"));
        //Iterator迭代
        Iterator iter = l1.iterator();
        while(iter.hasNext()) {
            System.out.println(iter.next());
        }
​
​
    //传统for循环
​
    @Test
    public void test3() {
        List l1 = new ArrayList();
        l1.add(123);
        l1.add("AA");
        l1.add(new String("狼来了"));
        //一般for循环
        for(int i= 0;i<l1.size();i++) {
            System.out.print(l1.get(i)+"\t");
        }
    }
​

HashMap

1.HashMap和Hashtable有什么区别:

  1. HashMap线程非安全,HashTable线程安全,内部的方法基本都经过synchronized修饰。

  2. HashMap的效率略高于HashTable

  3. HashMap允许将null作为一个key或者value,而HashTable不允许

  4. HashMap的默认初始扩容大小为16,之后每次扩容容量为原来的2倍。HashTable的默认初始大小为11,之后每次扩容容量变为原来的2n+1

  5. JDK8.x以后HashMap在解决哈希冲突时有了较大变化,当链表大于阈值(默认为8)时将链表转换为红黑树,HashTable没有这样的机制。

  6. Hashtable 和 HashMap 采用的 hash/rehash 算法都大概一样,所以性能不会有很大的差异。

  7. HashMap 把 Hashtable 的 contains 方法去掉了,改成 containsValue 和 containsKey。因为 contains 方法容易让人引起误解。

2.HashMap的内部数据结构

数组 + 链表+红黑树

3.HashMap的数据插入原理

  1. 判断数组是否为空,为空进行初始化;

  2. 不为空,计算 k 的 hash 值,通过(n - 1) & hash计算应当存放在数组中的下标 index;

  3. 查看 table[index] 是否存在数据,没有数据就构造一个Node节点存放在 table[index] 中;

  4. 存在数据,说明发生了hash冲突(存在二个节点key的hash值一样), 继续判断key是否相等,相等,用新的value替换原数据(onlyIfAbsent为false);

  5. 如果不相等,判断当前节点类型是不是树型节点,如果是树型节点,创造树型节点插入红黑树中;(如果当前节点是树型节点证明当前已经是红黑树了)

  6. 如果不是树型节点,创建普通Node加入链表中;判断链表长度是否大于 8并且数组长度大于64, 大于的话链表转换为红黑树;

  7. 插入完成之后判断当前节点数是否大于阈值,如果大于开始扩容为原数组的二倍。

4.为什么链表转红黑树的阈值是8?

我们平时在进行方案设计时,必须考虑两个很重要的因素是:时间和空间。对于HashMap也是同样的道理,简单来说,阈值为8是在时间和空间上权衡的结果。红黑树节点大小约为链表的2倍,在节点太少时,红黑树的查找性能优势并不明显,付出2倍空间的代价并不值得。

理想环境下,使用随机的hash码,节点分布在hash桶中的频率遵循松泊分布,在负载因子为0.75的情况下,单个hash槽内元素个数为8的概率小于百万分之一,将7作为一个分水岭,等于7时不做转换,大于等于8才转红黑树,小于等于6才转为链表。链表中元素个数为8时的概率已经非常小,再多的就更少了,之所以链表转红黑树的阈值是8,是因为Java的源码贡献者再进行大量的实验时发现,hash碰撞发生8次的概率已经降到了0.00000006几乎为不可能事件如果真的发生了8次碰撞,那么这个时候说明由于元素本身和hash函数的原因,此次操作的hash碰撞的可能性就非常大了,后续可能会继续发生hash碰撞。所以这个时候,就应该将链表转为红黑树了,也就是为什么链表转红黑树的阈值是8

5.阈值为6时红黑树转为链表

如果也将阈值设置为8,那么当hash碰撞在8时。会发生链表和红黑树相互激荡转换,白白浪费资源。

6.负载因子0.75

负载因子是0.75的时候,空间利用率比较高,避免了较多的hash冲突,提升空间效率,如果过大,桶中键值对碰撞的利率就会越大,增加搜索时间,性能下降。如果设置过小,空间利用率不高,放不了几个键值对就要进行扩容,浪费空间。

7.初始容量为16

因为HashMap的初始容量必须是2的N次方,初始容量之所以为16,是因为16是一个折中值,过小的话放不了几个元素就要进行扩容,过大的话就会造成空间的浪费。

8.HashMap为什么要引入红黑树?

红黑树相比二叉平衡树,在检索时其实效率差不多,都是通过平衡来二分查找。但对于插入删除等操作效率提高很多,红黑树不像平衡二叉树一样追求绝对的平衡,允许局部很少的不完全平衡,对效率影响不大,省去了很多没有必要的调平衡操作。红黑树的每个节点要么是红色要么是黑色,根节点是黑色,每个叶子节点都是黑色的空节点,每个红色节点的两个子节点都是黑色的,从任意节点到其每个叶子的所有路径都包含相同的黑色节点。红黑树牺牲了一些查找性能,但其本身并不是完全平衡的二叉树,因此插入删除操作效率略高于平衡二叉树,所以HashMap要引入红黑树。

SpringBoot

优势

1.简约配置:与springmvc或其他框架相比,SpringBoot配置很简单 application.yaml
           使得开发人员更加专注于业务,而不是环境配置
    
2.一键启动:项目直接在主函数main中启动,有内置的tomcat服务器
3.依赖封装:springboot-starter,springboot-web-starter 封装了Spring、SpringMVC的基础依赖
4.第三方组件插拔性好:如 mybatis,rabbitmq,redis,druid,mysql...集成到SpringBoot里,非常轻便

SpringBoot注解

@Controller
    用于标注是控制层组件,需要返回页面时请用@Controller而不是@RestController;
    
@Service
    一般用于修饰service层的组件
        
@Repository
     使用@Repository注解可以确保DAO或者repositories提供异常转译,这个注解修饰的DAO或者repositories类会被ComponetScan发现并配置,同时也不需要为它们提供XML配置项。
        
@Component
     泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注;
​
@Configuration
     指出该类是 Bean 配置的信息源,相当于XML中的,一般加在主类上;
        
@Bean
     相当于XML中的,放在方法的上面,而不是类,意思是产生一个bean,并交给spring管理。
       
@ResponseBody
      表示该方法的返回结果直接写入HTTP response body中,一般在异步获取数据时使用,在使用@RequestMapping后,返回值通常解析为跳转路径,
      加上@responsebody后返回结果不会被解析为跳转路径,而是直接写入HTTP response body中;比如异步获取json数据,加上@responsebody后,会直接返回json数据;

JDBC

Java DataBase Connectivity(Java数据库连接)

1.JDBC的编程步骤

  1. 加载数据库驱动类

  2. Java 连接数据库

  3. 执行SQL语句

  4. 获得结果

  5. 处理结果(封装成Java对象)

  6. 关闭数据库连接

2.IOC:Inversion Of Controller 控制反转

组件的生命周期不再由上一层组件控制,而是交由第三方容器控制,这样实现了面向接口编程,降低组件耦合性,安全性提高

3.DI:Dependency Injection 依赖注入

controller - service - mapper

对象实例化的时候,需要依赖于其他组件,该其他组件是在第三方容器实例化的

4.注入的方式

setter注入,构造器注入

5.bean的生命周期

<bean scope = "singleton | prototype | request | session">
​
 (1)scope = "singleton" 单例模式
    在spring容器实例化的时候,内部的bean对也随之 实例化instance与初始化initial,
    在spring容器关闭的时候,bean也随之消亡
    == bean对象 生命周期 完全由spring容器控制
    
 (2)scope = "prototype" 原型模式
    在spring容器实例化的时候,在外部客户端getBean("id")的时候,会实例化与初始化
    在spring容器关闭的时候,bean没有消亡
    == bean对象 生命周期 不完全由spring容器控制
    

6.AOP:Aspect Oritinted Programming 面向切面编程

1.什么样的业务使用面向切面编程?

一些服务性业务,如日志记录,事务管理,性能检测,访问权限等,不能直接通过硬编码交织在核心业务中,此时采用切面编程

2.面向切面编程有什么好处?

1.组件之间的耦合性降低:商品增删改查,日志添加
2.代码的冗余性降低

3.切面编程的技术实现:代理模式【反射】

(1)JDK动态代理:目标对象 有接口
    ---通过Java反射机制和动态生成class的技术,实现生成代理对象
    
(2)CGLib动态代理:目标对象 没有接口【反射】
    ---在生成字节码过程中,目标对象生成子类对象,并覆盖其中的方法,实现字节码增强,把该子类对象 称之为代理对象

MySQL

1.优化查询的方法

①使用索引

使用索引时,应尽量避免全表扫描,首先应考虑在 where 及 order by ,group by 涉及的列上建立索引。

②优化SQL语句

分析查询语句:通过对查询语句的分析,可以了解查询语句执行情况,找出查询语句执行的瓶颈,从而优化查询语句。

任何地方都不要使用select * from t ,用具体的字段列表代替“*”,不要返回用不到的任何字段。

不在索引列做运算或者使用函数。

查询尽可能使用 limit 减少返回的行数,减少数据传输时间和带宽浪费。

③优化数据库对象

1.优化表的数据类型

  使用 procedure analyse()函数对表进行分析,该函数可以对表中列的数据类型提出优化建议。表数据类型第一个原则是:使用能正确地表示和存储数据的最短类型。这样可以减少对磁盘空间、内存、CPU缓存的使用。

  使用方法:select * from 表名 procedure analyse();

2.对表进行拆分

  通过拆分表可以提高表的访问效率。

④硬件优化

1.CPU优化

  选择多核和主频高的CPU。

2.内存的优化

  使用更大的内存。将尽量多的内存分配给MySQL做缓存。

3.磁盘I/O的优化

⑤MySQL自身的优化

  对MySQL自身的优化主要是对其配置文件my.cnf中的各项参数进行优化调整。如指定MySQL查询缓冲区的大小,指定MySQL允许的最大连接进程数等

⑥应用优化

1.使用数据库连接池

2.使用查询缓存

  它的作用是存储 select 查询的文本及其相应结果。如果随后收到一个相同的查询,服务器会从查询缓存中直接得到查询结果。查询缓存适用的对象是更新不频繁的表,当表中数据更改后,查询缓存中的相关条目就会被清空。

2.索引(Index)

比如我们要在字典中找某一字,如何才能快速找到呢?那就是通过字典的目录。

对数据库来说,索引的作用就是给‘数据’加目录。创建所以的目的就是为了提高查询速度

索引是对数据库表中一列或多列的值进行排序的一种结构,使用索引可快速访问数据库表中的特定信息。

①索引算法

  1. btree(平衡树)索引 log2N

  2. hash(哈希)索引 1

②优缺点

  1. 好处

    加快了查询速度(select )

    创建唯一性索引,保证数据库表中每一行数据的唯一性;

    加速表和表之间的连接

    在使用分组和排序子句进行数据检索时,可以显著减少查询中分组和排序的时间。

  2. 坏处:

    降低了增,删,改的速度(update/delete/insert),降低了数据的维护速度。

    增大了表的文件大小,占物理空间(索引文件甚至可能比数据文件还大)

③索引类型

  1. 普通索引(index):仅仅是加快了查询速度,数据可以重复

  2. 唯一索引(unique):行上的值不能重复,要求所有记录都唯一

  3. 主键索引(primary key):不能重复,也就是在唯一索引的基础上相应的列必须为主键

  4. 全文索引(fulltext):仅可用于 MyISAM 表,针对较大的数据,生成全文索引很耗时好空间,语法和普通索引一样

  5. 组合索引:为了更多的提高mysql效率可建立组合索引,遵循”最左前缀“原则。

3.底层数据结构(B+树)

①什么是B+树

B+树是一种树数据结构,通常用于数据库和操作系统的文件系统中。B+ 树的特点是能够保持数据稳定有序,其插入与修改拥有较稳定的对数时间复杂度。B+树元素自底向上插入,这与二叉树恰好相反

②B+ 树优势

 

  1. 有k个子树的中间节点包含有k个元素(B树中是k-1个元素),每个元素不保存数据,只用来索引,所有数据都保存在叶子节点。

  2. 所有的叶子结点中包含了全部元素的信息,及指向含这些元素记录的指针,且叶子结点本身依关键字的大小自小而大顺序链接。

  3. 所有的中间节点元素都同时存在于子节点,在子节点元素中是最大(或最小)元素。

③B+树特点

  1. B+树的层级更少:相较于B树B+每个非叶子节点存储的关键字数更多,树的层级更少所以查询数据更快;

  2. B+树查询速度更稳定:B+所有关键字数据地址都存在叶子节点上,所以每次查找的次数都相同所以查询速度要比B树更稳定;

  3. B+树天然具备排序功能:B+树所有的叶子节点数据构成了一个有序链表,在查询大小区间的数据时候更方便,数据紧密性很高,缓存的命中率也会比B树高。

  4. B+树全节点遍历更快:B+树遍历整棵树只需要遍历所有的叶子节点即可,,而不需要像B树一样需要对每一层进行遍历,这有利于数据库做全表扫描。

④B树和B+树的区别

  1. 关键字的数量不同:B+树中分支结点有m个关键字,其叶子结点也有m个,其关键字只是起到了一个索引的作用,但是B树虽然也有m个子结点,但是其只拥有m-1个关键字。

  2. 存储的位置不同:B+树中的数据都存储在叶子结点上,也就是其所有叶子结点的数据组合起来就是完整的数据,但是B树的数据存储在每一个结点中,并不仅仅存储在叶子结点上。

  3. 分支结点的构造不同:B+树的分支结点仅仅存储着关键字信息和儿子的指针(这里的指针指的是磁盘块的偏移量),也就是说内部结点仅仅包含着索引信息。

  4. 查询不同:B树在找到具体的数值以后,则结束,而B+树则需要通过索引找到叶子结点中的数据才结束,也就是说B+树的搜索过程中走了一条从根结点到叶子结点的路径。

☆4.事务

①事务的定义:

就是指一个任务中有一组sql语句组成,这些sql语句要么全部执行成功,要么全部不执行

注意:

  1. 在数据库中,执行业务的基本单位是事务,不是以某一条SQL

  2. 数据库在默认情况下,事务都是打开的,也就是说它是一直处在事务中的,一个事务的结束,代表着下一个事务的开启

  3. 执行commit或者rollback指令时,会结束当前事务

②作用:

用来保证数据的平稳性和可预测性

③事务的四大属性(ACID):

  1. atomic,原子性,事务是业务逻辑单元中不可再分割的,一个任务中的多个sql语句,要么同时成功,要么不执行

  2. consistency,一致性,事务一旦结束,内存中的数据和数据库中的数据是保持一致的 或者:几个并行执行的事务,其执行结果必须与按某一顺序串行执行的结果相一致 或者:事务的一致性指的是在一个事务执行之前和执行之后数据库都必须处于一致性状态 这种特性称为事务的一致性。假如数据库的状态满足所有的完整性约束,就说该数据库是一致的

  3. isolation,隔离性,事务之间互不干扰,一个事务的结束意味着下一个事务的开启

  4. duration,持久性,事务一旦提交,则数据持久化到数据库中,永久保存

④事务的隔离级别

1.Read uncommitted(读未提交)

如果一个事务已经开始写数据,则另外一个事务不允许同时进行写操作,但允许其他事务读此行数据,该隔离级别可以通过“排他写锁”,但是不排斥读线程实现。这样就避免了更新丢失,却可能出现脏读,也就是说事务B读取到了事务A未提交的数据

解决了更新丢失,但还是可能会出现脏读

2.Read committed(读提交)

如果是一个读事务(线程),则允许其他事务读写,如果是写事务将会禁止其他事务访问该行数据,该隔离级别避免了脏读,但是可能出现不可重复读。事务A事先读取了数据,事务B紧接着更新了数据,并提交了事务,而事务A再次读取该数据时,数据已经发生了改变。

解决了更新丢失和脏读问题

3.Repeatable read(可重复读取)

可重复读取是指在一个事务内,多次读同一个数据,在这个事务还没结束时,其他事务不能访问该数据(包括了读写),这样就可以在同一个事务内两次读到的数据是一样的,因此称为是可重复读隔离级别,读取数据的事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务(包括了读写),这样避免了不可重复读和脏读,但是有时可能会出现幻读。(读取数据的事务)可以通过“共享读镜”和“排他写锁”实现。

解决了更新丢失、脏读、不可重复读、但是还会出现幻读

4.Serializable(可序化)

提供严格的事务隔离,它要求事务序列化执行,事务只能一个接着一个地执行,但不能并发执行,如果仅仅通过“行级锁”是无法实现序列化的,必须通过其他机制保证新插入的数据不会被执行查询操作的事务访问到。序列化是最高的事务隔离级别,同时代价也是最高的,性能很低,一般很少使用,在该级别下,事务顺序执行,不仅可以避免脏读、不可重复读,还避免了幻读

解决了更新丢失、脏读、不可重复读、幻读(虚读)

以上四种隔离级别最高的是Serializable级别,最低的是Read uncommitted级别,当然级别越高,执行效率就越低,像Serializeble这样的级别,就是以锁表的方式(类似于Java多线程中的锁)使得其他线程只能在锁外等待,所以平时选用何种隔离级别应该根据实际情况来,在MYSQL数据库中默认的隔离级别是Repeatable read(可重复读)。

5.DDL:数据定义语言

Data Defination Language:适用范围:对数据库中的某些对象(例如,database,table)进行管理,如create、alter、drop、TRUNCATE、show等

建表- 约束

建表

①创建表 create

create table 表名(
    列名  数据类型,
 列名  数据类型,
 列名  数据类型,
 ...
 ...
)

②修改表 alter

-- (1)将学生表中添加新的一列,籍贯 stu_hometown varchar(50)
alter table student add stu_hometown varchar(50)
​
-- (2)修改籍贯 stu_hometown 列名,改为 student_hometown
alter table student change stu_hometown student_hometown varchar(50)
​
-- (3)修改籍贯 stu_hometown 列数据类型,改为 varchar(25)
alter table student modify column stu_hometown varchar(25)
​
-- (4)删除籍贯 列
alter table student drop student_hometown
​
-- (5)将表名修改为mystudent
alter table student to mystudent

③删除表

drop table 表名;
​
-- 删除10部门
 delete from dept where deptno = 10
    -- 删除失败,原因在于在emp表中有在10部门的员工,所以不能删除
​
 delete from dept where deptno = 50
    -- 删除成功,原因在于在其他表中没有在50部门的员工,所以可以删除
​
--删除时的级联操作
--删除部门数据时候,对关联表emp 员工表 有什么影响?
​
emp 表中有外键 dept(deptno)
示例: 在emp表中有在10部门的员工,现在要删除10部门
​
(1) NO ACTION :不允许删除,也不报错,不提示
(2) RESTRICT : 不允许删除,会报错,提示在其他表中找到该记录
(3) SET NULL :允许删除,把emp中的员工所在部门编号设置为null 【前提:emp(deptno)允许为null】
(4) CASACDE : 级联删除,删除了10部门,在10部门的员工记录也删除了

约束

作用:为了保证数据的完整性与正确性,表中数据必须有约束

主键约束 primary key

用于唯一识别一条记录的字段(该主键可以是一个列,也可以是多个列- 联合主键) 
特征:
(1)唯一性
(2)非空性
identifier 身份识别

唯一性约束 unique

列的值 是唯一的

非空约束 not null

列的值 不为null

外键约束

b表中的某列 数据 来源于 a 表中的 某一列

6.DML:数据操纵语言

Data Manipulation Language:适用范围:对数据库中的数据进行一些简单操作,如insert,delete,update,select等

① insert语句

插入数据

insert into 表名 (列,列,列...) values(值,值,值...);
    --当插入的数据时与表格列一一对应的话,则列可以省略
​
insert into 表名 values(值,值,值...);

②update语句

主要是用来更新表中的数据

update 表名 set 列名=新值,列名=新值  where 条件;

③delete语句

delete from 表名 where 条件;

DDL和DML区别

1.DML操作是可以手动控制事务的开启、提交和回滚的。

2.DDL操作是隐性提交的,不能rollback!

7.Restful

drop、delete、truncate

1.drop:drop table xxx; 删除表,属于DDL操作

2.truncate: truncate table xxx;清空表,属于DDL操作,后面不能跟where,执行后,自增id从1开始

按页删除

3.delete:delete from xxx where ...,删除表记录,属于DML操作,后面可以跟where,执行后,自增id与上一次连续

按行删除

8.数据库的三大范式是什么?

第一范式:原子性,表中每个字段都不能再分

第二范式:满足第一范式并且表中的非主键字段都依赖于主键字段

第三范式:满足第一范式和第二范式并且表中的非主键字段不传递依赖于主键字段

9.MySQL数据库有哪些引擎?区别是什么?

10.说一说数据连接池的工作机制是什么?

11.Mysql中有哪几种锁?说一说数据库的乐观锁和悲观锁。

12.为什么要使用视图?什么是视图?

排序

1.冒泡排序Bubble Sort

冒泡排序属于一种典型的交换排序。交换排序顾名思义就是通过元素的两两比较,判断是否符合要求,如过不符合就交换位置来达到排序的目的。冒泡排序名字的由来就是因为在交换过程中,类似水冒泡,小(大)的元素经过不断的交换由水底慢慢的浮到水的顶端。

    public static void BubbleSort(String[] args) {
        int[] array = {15, 36, 98, 52, 32, 20, 15, 65, 88, 77};
        System.out.println("待排数组:");
       for (int i = 0;i<array.length;i++){
           System.out.print( array[i] + " " );
       }
        System.out.println();
        quick(array);
        System.out.println("排序后数组:");
        for (int i = 0;i<array.length;i++) {
            System.out.print( array[i]+ " ");
        }
​
    }

2.快速排序

它的基本思想是:选择一个基准数,通过一趟排序将要排序的数据分割成独立的两部分;其中一部分的所有数据都比另外一部分的所有数据都要小。然后,再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

快速排序流程: (1) 从数列中挑出一个基准值。 (2) 将所有比基准值小的摆放在基准前面,所有比基准值大的摆在基准的后面(相同的数可以到任一边);在这个分区退出之后,该基准就处于数列的中间位置。 (3) 递归地把"基准值前面的子数列"和"基准值后面的子数列"进行排序。

Redis

1. 什么是Redis?简述它的优缺点

Redis本质上是一个Key-Value类型的高性能内存数据库 。Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。 Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。 Redis支持数据的备份,即master-slave模式的数据备份。

2. Redis 优势

1、速度快,Redis能读的速度是110000次/s,写的速度是81000次/s,因为数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1)

2、支持丰富数据类型,支持string,list,set,Zset,hash等

3、支持事务,操作都是原子性,所谓的原子性就是对数据的更改要么全部执行,要么全部不执行

4、丰富的特性:可用于缓存,消息,按key设置过期时间,过期后将会自动删除

3.Redis支持的数据类型?

Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zsetsorted set:有序集合)。

String字符串:

格式: set key value

string类型是二进制安全的。意思是redis的string可以包含任何数据。比如jpg图片或者序列化的对象 。

string类型是Redis最基本的数据类型,一个键最大能存储512MB。

Hash(哈希)

格式: hmset name key1 value1 key2 value2

Redis hash 是一个键值(key=>value)对集合。

Redis hash是一个string类型的field和value的映射表,hash特别适合用于存储对象。

List(列表)

Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)

格式: lpush name value

在 key 对应 list 的头部添加字符串元素

格式: rpush name value

在 key 对应 list 的尾部添加字符串元素

格式: lrem name index

key 对应 list 中删除 count 个和 value 相同的元素

格式: llen name

返回 key 对应 list 的长度

Set(集合)

格式: sadd name value

Redis的Set是string类型的无序集合。

集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。

zset(sorted set:有序集合)

格式: zadd name score value

Redis zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。

不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。

zset的成员是唯一的,但分数(score)却可以重复。

4.Redis最适合的场景?

会话缓存(Session Cache)

最常用的一种使用Redis的情景是会话缓存(session cache)。用Redis缓存会话比其他存储(如Memcached)的优势在于:Redis提供持久化。当维护一个不是严格要求一致性的缓存时,如果用户的购物车信息全部丢失,大部分人都会不高兴的,现在,他们还会这样吗? 幸运的是,随着 Redis 这些年的改进,很容易找到怎么恰当的使用Redis来缓存会话的文档。甚至广为人知的商业平台Magento也提供Redis的插件。

全页缓存(FPC)

除基本的会话token之外,Redis还提供很简便的FPC平台。回到一致性问题,即使重启了Redis实例,因为有磁盘的持久化,用户也不会看到页面加载速度的下降,这是一个极大改进,类似PHP本地FPC。 再次以Magento为例,Magento提供一个插件来使用Redis作为全页缓存后端。 此外,对WordPress的用户来说,Pantheon有一个非常好的插件 wp-redis,这个插件能帮助你以最快速度加载你曾浏览过的页面。

队列

Reids在内存存储引擎领域的一大优点是提供 list 和 set 操作,这使得Redis能作为一个很好的消息队列平台来使用。Redis作为队列使用的操作,就类似于本地程序语言(如Python)对 list 的 push/pop 操作。 如果你快速的在Google中搜索“Redis queues”,你马上就能找到大量的开源项目,这些项目的目的就是利用Redis创建非常好的后端工具,以满足各种队列需求。例如,Celery有一个后台就是使用Redis作为broker,你可以从这里去查看。

排行榜/计数器

Redis在内存中对数字进行递增或递减的操(Set)和有序集合(Sorted Set)也使得我们在执行这些操作的时候变的非常简单,Redis只是正好提供了这两种数据结构。所以,我们要从排序集合中获取到排名最靠前的10个用户–我们称之为“userscores”。

发布/订阅

最后(但肯定不是最不重要的)是Redis的发布/订阅功能。发布/订阅的使用场景确实非常多。我已看见人们在社交网络连接中使用,还可作为基于发布/订阅的脚本触发器,甚至用Redis的发布/订阅功能来建立聊天系统!

 

设计模式

1.单例模式

(1)饿汉式:多线程安全,创建对象时进行初始化

public class Singleton {
    //2. 初始化一个变量,该变量就是该类的唯一实例[对象]
    private static Singleton instance = new Singleton();
    
    //1. 私有化构造  
    private Singleton(){  
        System.out.println("私有化构造");
    }
    
    //3. 提供一个公开的、静态的、方法来返回这个类的唯一属性
    public static Singleton getInstance(){
        return instance;
    }
}

(2)懒汉式:多线程不安全,需要时进行初始化

public class Singleton {
    private static Singleton instance ;
​
    private Singleton(){
        
    }
​
    public static Singleton getInstance(){
​
        if (instance == null){
            instance = new Singleton();
        }
        return instance;
    }
}

(3)枚举(多线程、安全)

public class Bank{
    private Bank(){}
    public static enum BankEnum{
        BANK;//类加载 public static final BankEnum BANK = new BankEnum(); 
        private Bank bank = null;
        private BnakEnum(){
            bank = new Bank();//为什么
        }
        public Bank getInstance(){
            return bank;
        }
    }
​
    public static void main(String[] args){
        Bank bank = BankEnum.BANK.getInstance();
    }
}

2.简单工厂模式

一个工厂决定了创建某种产品的实例,它完成了对象的创建和对象的使用分离

优点:简单粗暴,通过一个含参的工厂方法,就可以创建一个实例对象

缺点:

  1. 当增加工厂的产品的时候,会导致工厂负担过大,代码繁多

  2. 增加新产品,违背开闭原则,只能修改工厂来实现

public class ProductFactory {
    public static final int QQ = 1;
    public static final int WX = 2;
​
    //根据传入的参数来返回某个具体的产品
    //多态的应用 - 面向接口的编程
    //3.方法的返回值类型写成接口,方法的执行结果可以是这个接口的任意一个实现类
    public static Sender getInstance(int type){
        Sender sender = null;
        switch (type){
            case 1:
                sender = new QQSender();
                break;
            case 2:
                sender = new WXSender();
                break;
            default:
                System.out.println("参数不合法!");
                break;
        }
        return sender;
    }
}

3.代理模式

(1)JDK动态代理:目标对象 有接口 ---通过Java反射机制和动态生成class的技术,实现生成代理对象 (2)CGLib动态代理:目标对象 没有接口【反射】 ---在生成字节码过程中,目标对象生成子类对象,并覆盖其中的方法,实现字节码增强,把该子类对象 称之为代理对象

SpringCloud

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值