目录

JAVA

JAVA基础

Java中的final关键字

1Java中的栈与堆

2 Java中的多线程的生命周期

3 编写多线程程序有几种实现方式

如何检测死锁?

59、怎么预防死锁? 

为什么要使用线程池?直接new个线程不是很舒服?

线程池的核心属性有哪些?

说下线程池的运作流程。 

线程池有哪些拒绝策略 

71、ArrayList 和 LinkedList 的区别。

ArrayList 和 Vector 的区别。 

JVM虚拟机

1 JDK,JRE,JVM的关系

2 Java程序执行的过程

3 JVM整个类加载过程 

4 JVM的运行时数据区(重点)

4、Java虚拟机中有哪些类加载器?

5.怎么判定对象已经“死去”?

6.介绍下四种引用(强引用、软引用、弱引用、虚引用)?

7、什么时候运行垃圾回收?

8. 垃圾收集有哪些算法,各自的特点?

 Java中常用的设计模式

Spring

计算机网络

一:OSI,TCP/IP,五层协议的体系结构,以及各层协议

二:TCP 和UDP的特点和区别:

TCP 的主要特点

UDP 的主要特点

三:HTTP 与 HTTPS 区别

四 TCP 协议如何保证可靠传输

五:TCP 三次握手和四次挥手(面试常客)

六: 在浏览器中输入url地址 ->> 显示主页的过程(面试常客) 

数据库

1 MySql底层采用什么数据结构来存储数据?

2 分页所用的关键字

 2 增删改查操作:

3 SQL实现数据表的复制

4 什么是事务

5 数据库事务的四大特性

6 数据库的三级模式

7 什么是存储过程

8 简单介绍一下触发器

9 什么是E-R图

10 什么是外连接、内连接?

11 什么是索引?有什么用?

12 三大范式

13 数据库性能调优

14 项目中如何提升索引速度

操作系统

1、 什么是操作系统?操作系统由什么组成?

2、 进程与线程的关系

3、 线程和进程的区别

4、进程间的通信的几种方式

5、线程间的通信机制 (线程同步的方式)线程同步与互斥关系

6、 并发与并行

7、什么是轮询?

8、什么是死锁?四个必要条件:

9、 解决死锁的基本方法

10、分页存储和分段存储有什么区别?

Linux

数据结构

快速排序

冒泡排序

二分查找

二叉树的遍历

什么是红黑树


JAVA

JAVA基础

Java 基础高频面试题(2021年最新版)_程序员囧辉-CSDN博客_java高频面试题

50-63进程和线程

Java中的final关键字

修饰类:该类不能再派生出新的子类,不能作为父类被继承。因此,一个类不能同时被声明为abstract 和 final。

修饰方法:该方法不能被子类重写。

修饰变量:该变量必须在声明时给定初值,而在以后只能读取,不可修改。 如果变量是对象,则指的是引用不可修改,但是对象的属性还是可以修改的。
 

1Java中的栈与堆

Java面试--堆和栈的概念和区别_姜皓的博客-CSDN博客_java 堆和栈的区别

栈内存:栈内存首先是一片内存区域,存储的都是局部变量,凡是定义在方法中的都是局部变量(方法外的是全局变量),for循环内部定义的也是局部变量,是先加载函数才能进行局部变量的定义,所以方法先进栈,然后再定义变量,变量有自己的作用域,一旦离开作用域,变量就会被释放。栈内存的更新速度很快,因为局部变量的生命周期都很短。

堆内存:存储的是数组和对象(其实数组就是对象),凡是new建立的都是在堆中,堆中存放的都是实体(对象),实体用于封装数据,而且是封装多个(实体的多个属性),如果一个数据消失,这个实体也没有消失,还可以用,所以堆是不会随时释放的,但是栈不一样,栈里存放的都是单个变量,变量被释放了,那就没有了。堆里的实体虽然不会被释放,但是会被当成垃圾,Java有垃圾回收机制不定时的收取。

 所以堆与栈的区别很明显:

            1.栈内存存储的是局部变量而堆内存存储的是实体;

            2.栈内存的更新速度要快于堆内存,因为局部变量的生命周期很短;

            3.栈内存存放的变量生命周期一旦结束就会被释放,而堆内存存放的实体会被垃圾回收机制不定时的回收。

2 Java中的多线程的生命周期

50-63进程和线程的面试题

Java 多线程编程 | 菜鸟教程

  • 新建状态:

    使用 new 关键字和 Thread 类或其子类建立一个线程对象后,该线程对象就处于新建状态。它保持这个状态直到程序 start() 这个线程。

  • 就绪状态:

    当线程对象调用了start()方法之后,该线程就进入就绪状态。就绪状态的线程处于就绪队列中,要等待JVM里线程调度器的调度。

  • 运行状态:

    如果就绪状态的线程获取 CPU 资源,就可以执行 run(),此时线程便处于运行状态。处于运行状态的线程最为复杂,它可以变为阻塞状态、就绪状态和死亡状态。

  • 阻塞状态:

    如果一个线程失去所占用资源之后,该线程就从运行状态进入阻塞状态。在睡眠时间已到或获得设备资源后可以重新进入就绪状态。可以分为三种:

    • 等待阻塞:运行状态中的线程执行 wait() 方法,使线程进入到等待阻塞状态。

    • 同步阻塞:线程在获取 synchronized 同步锁失败(因为同步锁被其他线程占用)。

    • 其他阻塞:通过调用线程的 sleep() 或 join() 发出了 I/O 请求时,线程就会进入到阻塞状态。当sleep() 状态超时,join() 等待线程终止或超时,或者 I/O 处理完毕,线程重新转入就绪状态。

  • 死亡状态:

    一个运行状态的线程完成任务或者其他终止条件发生时,该线程就切换到终止状态。

3 编写多线程程序有几种实现方式

通常来说,可以认为有三种方式:1)继承 Thread 类;2)实现 Runnable 接口;3)实现 Callable 接口。

如何检测死锁?

死锁的四个必要条件:

1)互斥条件:进程对所分配到的资源进行排他性控制,即在一段时间内某资源仅为一个进程所占有。此时若有其他进程请求该资源,则请求进程只能等待。

2)请求和保持条件:进程已经获得了至少一个资源,但又对其他资源发出请求,而该资源已被其他进程占有,此时该进程的请求被阻塞,但又对自己获得的资源保持不放。

3)不可剥夺条件:进程已获得的资源在未使用完毕之前,不可被其他进程强行剥夺,只能由自己释放。

4)环路等待条件:存在一种进程资源的循环等待链,链中每一个进程已获得的资源同时被 链中下一个进程所请求。即存在一个处于等待状态的进程集合{Pl, P2, …, pn},其中 Pi 等待的资源被 P(i+1) 占有(i=0, 1, …, n-1),Pn 等待的资源被 P0占 有,如下图所示。
 

59、怎么预防死锁? 

 预防死锁的方式就是打破四个必要条件中的任意一个即可。

1)打破互斥条件:在系统里取消互斥。若资源不被一个进程独占使用,那么死锁是肯定不会发生的。但一般来说在所列的四个条件中,“互斥”条件是无法破坏的。因此,在死锁预防里主要是破坏其他几个必要条件,而不去涉及破坏“互斥”条件。。

2)打破请求和保持条件:1)采用资源预先分配策略,即进程运行前申请全部资源,满足则运行,不然就等待。 2)每个进程提出新的资源申请前,必须先释放它先前所占有的资源。

3)打破不可剥夺条件:当进程占有某些资源后又进一步申请其他资源而无法满足,则该进程必须释放它原来占有的资源。

4)打破环路等待条件:实现资源有序分配策略,将系统的所有资源统一编号,所有进程只能采用按序号递增的形式申请资源。
 

Java线程池详解 

为什么要使用线程池?直接new个线程不是很舒服?

Java线程池详解_分享传递价值-CSDN博客_java线程池

如果我们在方法中直接new一个线程来处理,当这个方法被调用频繁时就会创建很多线程,不仅会消耗系统资源,还会降低系统的稳定性,一不小心把系统搞崩了,就可以直接去财务那结帐了。

如果我们合理的使用线程池,则可以避免把系统搞崩的窘境。总得来说,使用线程池可以带来以下几个好处:

降低资源消耗。通过重复利用已创建的线程,降低线程创建和销毁造成的消耗。
提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行。
增加线程的可管理型。线程是稀缺资源,使用线程池可以进行统一分配,调优和监控。
 

线程池的核心属性有哪些?

threadFactory(线程工厂):用于创建工作线程的工厂。

corePoolSize(核心线程数):当线程池运行的线程少于 corePoolSize 时,将创建一个新线程来处理请求,即使其他工作线程处于空闲状态。

workQueue(队列):用于保留任务并移交给工作线程的阻塞队列。

maximumPoolSize(最大线程数):线程池允许开启的最大线程数。

handler(拒绝策略):往线程池添加任务时,将在下面两种情况触发拒绝策略:1)线程池运行状态不是 RUNNING;2)线程池已经达到最大线程数,并且阻塞队列已满时。

keepAliveTime(保持存活时间):如果线程池当前线程数超过 corePoolSize,则多余的线程空闲时间超过 keepAliveTime 时会被终止。
 

说下线程池的运作流程。 

线程池有哪些拒绝策略 

AbortPolicy:中止策略。默认的拒绝策略,直接抛出 RejectedExecutionException。调用者可以捕获这个异常,然后根据需求编写自己的处理代码。

DiscardPolicy:抛弃策略。什么都不做,直接抛弃被拒绝的任务。

DiscardOldestPolicy:抛弃最老策略。抛弃阻塞队列中最老的任务,相当于就是队列中下一个将要被执行的任务,然后重新提交被拒绝的任务。如果阻塞队列是一个优先队列,那么“抛弃最旧的”策略将导致抛弃优先级最高的任务,因此最好不要将该策略和优先级队列放在一起使用。

CallerRunsPolicy:调用者运行策略。在调用者线程中执行该任务。该策略实现了一种调节机制,该策略既不会抛弃任务,也不会抛出异常,而是将任务回退到调用者(调用线程池执行任务的主线程),由于执行任务需要一定时间,因此主线程至少在一段时间内不能提交任务,从而使得线程池有时间来处理完正在执行的任务。

71、ArrayList 和 LinkedList 的区别。

ArrayList 底层基于动态数组实现,LinkedList 底层基于链表实现。

对于按 index 索引数据(get/set方法):ArrayList 通过 index 直接定位到数组对应位置的节点,而 LinkedList需要从头结点或尾节点开始遍历,直到寻找到目标节点,因此在效率上 ArrayList 优于 LinkedList。

对于在中间随机插入和删除:ArrayList 需要移动目标节点后面的节点(使用System.arraycopy 方法移动节点),而 LinkedList 只需修改目标节点前后节点的 next 或 prev 属性即可,因此在效率上 LinkedList 优于 ArrayList。

对于顺序插入和删除:由于 ArrayList 不需要移动节点,因此在效率上比 LinkedList 更好。这也是为什么在实际使用中 ArrayList 更多,因为大部分情况下我们的使用都是顺序插入

ArrayList 和 Vector 的区别。 

 Vector 和 ArrayList 几乎一致,唯一的区别是 Vector 在方法上使用了 synchronized 来保证线程安全,因此在性能上 ArrayList 具有更好的表现。

有类似关系的还有:StringBuilder 和 StringBuffer、HashMap 和 Hashtable。

72、java各种集合类区别

java各种集合类区别_小白新人-CSDN博客_java集合类

JVM虚拟机

Java虚拟机面试题精选(一)_程序员囧辉-CSDN博客_java虚拟机面试题及答案

1 JDK,JRE,JVM的关系

深入Java JVM内存模型(多图解)_我不是哈哈镜的博客-CSDN博客_java jvm模型

 简单来说是包含关系,JDK包含了JRE,JRE又包含了JVM。

JDK是Java Development Kit,它是功能齐全的Java SDK。它拥有JRE所拥有的一切,还有编译器(javac)和工具(如javadoc和jdb)。它能够创建和编译程序。

JRE 是 Java运行时环境。它是运行已编译 Java 程序所需的所有内容的集合,包括 Java虚拟机(JVM),Java类库,java命令和其他的一些基础构件。但是,它不能用于创建新程序。

JVM是java字节码执行的引擎,还能优化java字节码,使之转化成效率更高的机器指令。

类加载器运行时数据区执行引擎构成。

类加载器,在 JVM 启动时或者类运行时将需要的 class 加载到 JVM 中

执行引擎,执行引擎的任务是负责执行 class 文件中包含的字节码指令,相当于实际机器上的 CPU

内存区,将内存划分成若干个区以模拟实际机器上的存储、记录和调度功能模块,如实际机器上的各种功能的寄存器或者 PC 指针的记录器等

本地方法调用,调用 C 或 C++ 实现的本地方法的代码返回结果

2 Java程序执行的过程

JVM是java字节码执行的引擎,还能优化java字节码,使之转化成效率更高的机器指令。

 

3 JVM整个类加载过程 

1. 装载

装载过程负责找到二进制字节码并加载至JVM中,JVM通过类名、类所在的包名通过ClassLoader来完成类的加载,同样也采用以上三个元素来标识一个被加载了的类:类名+包名+ClassLoader实例ID。

2 校验解析:对二进制字节码的格式进行校验、初始化装载类中的静态变量以及解析类中调用的接口、类。

3.初始化:初始化过程即为执行类中的静态初始化代码、构造器代码以及静态属性的初始化,

4 使用:处理class类,运行java程序

5 卸载

4 JVM的运行时数据区(重点)

程序计数器(Program Counter Register)

一块较小的内存空间,可以看作当前线程所执行的字节码的行号指示器。如果线程正在执行的是一个Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的是Native方法,这个计数器值则为空。

Java虚拟机栈(Java Virtual Machine Stacks)
与程序计数器一样,Java虚拟机栈也是线程私有的,它的生命周期与线程相同。虚拟机栈描述的是Java方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法从调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。

本地方法栈(Native Method Stack)
本地方法栈与虚拟机栈所发挥的作用是非常相似的,它们之间的区别不过是虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则为虚拟机使用到的Native方法服务。

Java堆(Java Heap)
Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。

方法区(Method Area)
与Java堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。方法区是JVM规范中定义的一个概念,具体放在哪里,不同的实现可以放在不同的地方。

运行时常量池(Runtime Constant Pool)
运行时常量池是方法区的一部分。Class文件中除了有类的版本、字段、方法、接口等描述信息外,还有一项信息是常量池,用于存放编译期生成的各种字面量和符号引用,这部分内容将在类加载后进入方法区的运行时常量池中存放。
 

4、Java虚拟机中有哪些类加载器?

启动类加载器(Bootstrap ClassLoader):

这个类加载器负责将存放在<JAVA_HOME>\lib目录中的,或者被-Xbootclasspath参数所指定的路径中的,并且是虚拟机识别的(仅按照文件名识别,如rt.jar,名字不符合的类库即使放在lib目录中也不会被加载)类库加载到虚拟机内存中。

扩展类加载器(Extension ClassLoader)

这个加载器由sun.misc.Launcher$ExtClassLoader实现,它负责加载<JAVA_HOME>\lib\ext目录中的,或者被java.ext.dirs系统变量所指定的路径中的所有类库,开发者可以直接使用扩展类加载器。

应用程序类加载器(Application ClassLoader):

这个类加载器由sun.misc.Launcher$AppClassLoader实现。由于这个类加载器是ClassLoader中的getSystemClassLoader()方法的返回值,所以一般也称它为系统类加载器。它负责加载用户类路径(ClassPath)上所指定的类库,开发者可以直接使用这个类加载器,如果应用程序中没有自定义过自己的类加载器,一般情况下这个就是程序中默认的类加载器。

5.怎么判定对象已经“死去”?

常见的判定方法有两种:引用计数法和可达性分析算法,HotSpot中采用的是可达性分析算法。

引用计数法
给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1;当引用失效时,计数器值就减1;任何时刻计数器为0的对象就是不可能再被使用的。

客观地说,引用计数算法的实现简单,判定效率也很高,在大部分情况下它都是一个不错的算法,但是主流的Java虚拟机里面没有选用引用计数算法来管理内存,其中最主要的原因是它很难解决对象之间相互循环引用的问题。

可达性分析算法
这个算法的基本思路就是通过一系列的称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链相连(用图论的话来说,就是从GC Roots到这个对象不可达)时,则证明此对象是不可用的。如下图所示,对象object 5、object 6、object 7虽然互相有关联,但是它们到GC Roots是不可达的,所以它们将会被判定为是可回收的对象。

6.介绍下四种引用(强引用、软引用、弱引用、虚引用)?

强引用:在程序代码之中普遍存在的,类似“Object obj=new Object()”这类的引用,只要强引用还存在,垃圾收集器永远不会回收掉被引用的对象。

软引用:用来描述一些还有用但并非必需的对象,使用SoftReference类来实现软引用,在系统将要发生内存溢出异常之前,将会把这些对象列进回收范围之中进行第二次回收。

弱引用:用来描述非必需对象的,使用WeakReference类来实现弱引用,被弱引用关联的对象只能生存到下一次垃圾收集发生之前。

虚引用:是最弱的一种引用关系,使用PhantomReference类来实现虚引用,一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用来取得一个对象实例。为一个对象设置虚引用关联的唯一目的就是能在这个对象被收集器回收时收到一个系统通知。

7、什么时候运行垃圾回收?

  • 堆可用内存不足
  • CPU空闲

8. 垃圾收集有哪些算法,各自的特点?

标记 - 清除算法
首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象。它的主要不足有两个:一个是效率问题,标记和清除两个过程的效率都不高;另一个是空间问题,标记清除之后会产生大量不连续的内存碎片,空间碎片太多可能会导致以后在程序运行过程中需要分配较大对象时,无法找到足够的连续内存而不得不提前触发另一次垃圾收集动作。

标记 - 整理算法
标记过程仍然与“标记-清除”算法一样,但后续步骤不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存。

 复制算法
为了解决效率问题,一种称为“复制”(Copying)的收集算法出现了,它将可用内存按容量划分为大小相等的两块,每次只使用其中的一块。当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后再把已使用过的内存空间一次清理掉。这样使得每次都是对整个半区进行内存回收,内存分配时也就不用考虑内存碎片等复杂情况,只要移动堆顶指针,按顺序分配内存即可,实现简单,运行高效。只是这种算法的代价是将内存缩小为了原来的一半,未免太高了一点。

 Java中常用的设计模式

Java中常用的设计模式_Superme-CSDN博客_java设计模式

Spring

1 Spring bean 的生命周期

计算机网络

转载自:常用应届生Java开发笔试面试题(更新中)_每个人为不同的理由带着面具说谎,动机也只有一种名字那 叫做欲望-CSDN博客_java应届生面试题  

一:OSI,TCP/IP,五层协议的体系结构,以及各层协议

 

OSI:应用层,表示层,会话层,传输层,网络层,数据链路层,物理层。

五层协议:应用层,传输层,网络层,数据链路层,物理层。

TCP/IP体系结构:应用层,传输层,网际层,网络接口层。

各层作用讲解:

1. 物理层:实现相邻计算机节点之间原始比特流的透明传送,尽可能屏蔽掉具体传输介质和物理设备的差异。 

2. 数据链路层:负责建立和管理节点间的数据链路。该层的主要功能是:通过各种控制协议,将有差错的物理信道变为无差错的、能可靠传输数据帧的数据链路。

3. 网络层:负责为分组交换网上的不同主机提供通信服务,通过路由选择算法,为报文或者分组通过通信子网选择最合适的路径。

4. 传输层: 的主要任务就是负责向两台主机进程之间的通信提供通用的数据传输服务,保证报文的正确传输。

传输层主要使用以下两种协议

  1. 传输控制协议 TCP(Transmisson Control Protocol)--提供面向连接的,可靠的数据传输服务。
  2. 用户数据协议 UDP(User Datagram Protocol)--提供无连接的,尽最大努力的数据传输服务(不保证数据传输的可靠性)。

5. 会话层:为不同机器上的节点之间建立和管理会话,将不同实体之间的表示层链接称为会话。

6. 表示层: 对用层的数据进行表示和加密,格式化数据,以便为应用程序提供通用接口。

7. 应用层: 直接对应用程序提供服务,通过应用进程间的交互来完成特定网络应用,包含各种应用层协议:如域名系统DNS,支持万维网应用的 HTTP协议,支持电子邮件的 SMTP协议等等。我们把应用层交互的数据单元称为报文。

域名系统

域名系统(Domain Name System缩写 DNS,Domain Name被译为域名)是因特网的一项核心服务,它作为可以将域名和IP地址相互映射的一个分布式数据库,能够使人更方便的访问互联网,而不用去记住能够被机器直接读取的IP数串。(百度百科)例如:一个公司的 Web 网站可看作是它在网上的门户,而域名就相当于其门牌地址,通常域名都使用该公司的名称或简称。例如上面提到的微软公司的域名,类似的还有:IBM 公司的域名是 www.ibm、Oracle 公司的域名是 www.oracle、Cisco公司的域名是 www.cisco 等。

HTTP协议

超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议。所有的 WWW(万维网) 文件都必须遵守这个标准。设计 HTTP 最初的目的是为了提供一种发布和接收 HTML 页面的方法。(百度百科)

二:TCP 和UDP的特点和区别:

TCP 的主要特点

  1. TCP 是面向连接的。(就好像打电话一样,通话前需要先拨号建立连接,通话结束后要挂机释放连接)
  2. 每一条TCP连接只能是一对一的;
  3. TCP 提供可靠交付的服务,在传送数据之前必须先建立连接,数据传送结束后要释放连接,因此它是可靠的。(通过TCP连接传送的数据,无差错、不丢失、不重复、并且按序到达);
  4. TCP 提供全双工通信,TCP 允许通信双方的应用进程在任何时候都能发送数据。(TCP 连接的两端都有发送缓存和接收缓存,用来临时存放双方通信的数据);
  5. TCP首部开销是20个字节,比UDP的8个字节要多。
  6. TCP 一般用于文件传输、发送和接收邮件、远程登录等场景。

UDP 的主要特点

  1. UDP 是无连接的,面向报文的;
  2. UDP 支持一对一、一对多、多对一和多对多的交互通信;
  3. UDP 在传送数据之前不需要先建立连接,因此不保证可靠交付;
  4. UDP 没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低;
  5. UDP 的首部开销小,只有8个字节,比TCP的20个字节的首部要短。
  6. UDP一般用于语音,视频等。

UDP 是无连接的,面向报文的,在传送数据之前不需要先建立连接,可以1对多通信,远地主机在收到 UDP 报文后,不需要给出任何确认。虽然 UDP 不提供可靠交付,但在某些情况下 UDP 确是一种最有效的工作方式(一般用于即时通信),比如: QQ 语音、 QQ 视频 、直播等等,UDP 的首部开销小,只有8个字节,比TCP的20个字节的首部要短。。

TCP 提供面向连接的服务,只能1对1通信。在传送数据之前必须先建立连接,数据传送结束后要释放连接,因此它是可靠的(TCP的可靠体现在TCP在传递数据之前,会有三次握手来建立连接,而且在数据传递时,有确认、重传、拥塞控制机制,在数据传完后,还会断开连接用来节约系统资源),但是难以避免增加了许多开销,如确认,流量控制,计时器以及连接管理等。TCP首部开销是20个字节,比UDP的8个字节要多。TCP 一般用于文件传输、发送和接收邮件、远程登录等场景。

三:HTTP 与 HTTPS 区别

  • 安全性:HTTP 明文传输,数据都是未加密的,安全性较差,HTTPS(SSL+HTTP) 数据传输过程是加密的,安全性较好。
  • 费用:使用 HTTPS 协议需要到 CA 申请证书,一般免费证书较少,因而需要一定费用。
  • 响应速度:HTTP 页面响应速度比 HTTPS 快,主要是因为 HTTP 使用 TCP 三次握手建立连接,客户端和服务器需要交换 3 个包,而 HTTPS除了 TCP 的三个包,还要加上 ssl 握手需要的 9 个包,所以一共是 12 个包。
  • 连接方式:http 和 https 使用的是完全不同的连接方式,用的端口也不一样,前者是 80,后者是 443。
  • 服务器资源:HTTPS 其实就是建构在 SSL/TLS 之上的 HTTP 协议,所以,要比较 HTTPS 比 HTTP 要更耗费服务器资源。

四 TCP 协议如何保证可靠传输

  1. 应用数据被分割成 TCP 认为最适合发送的数据块。
  2. TCP 给发送的每一个包进行编号,接收方对数据包进行排序,把有序数据传送给应用层。
  3. 校验和: TCP 将保持它首部和数据的检验和。这是一个端到端的检验和,目的是检测数据在传输过程中的任何变化。如果收到段的检验和有差错,TCP 将丢弃这个报文段和不确认收到此报文段。
  4. TCP 的接收端会丢弃重复的数据。
  5. 流量控制: TCP 连接的每一方都有固定大小的缓冲空间,TCP的接收端只允许发送端发送接收端缓冲区能接纳的数据。当接收方来不及处理发送方的数据,能提示发送方降低发送的速率,防止包丢失。TCP 使用的流量控制协议是可变大小的滑动窗口协议。 (TCP 利用滑动窗口实现流量控制)
  6. 拥塞控制: 当网络拥塞时,减少数据的发送。
  7. 自动重传ARQ协议 也是为了实现可靠传输的,它通过使用确认和超时这两个机制,在不可靠服务的基础上实现可靠的信息传输。如果发送方在发送后一段时间之内没有收到确认帧,它通常会重新发送。ARQ可能包括停止等待ARQ协议连续ARQ协议

停止并等待ARQ协议(stop-and-wait)

  • 停止等待协议是为了实现可靠传输的,它的基本原理就是每发完一个分组就停止发送,等待对方确认。在收到确认后再发下一个分组;
  • 在停止等待协议中,若接收方收到重复分组,就丢弃该分组,但同时还要发送确认;

连续ARQ协议(Continuous ARQ)包含:回退N重传和选择重传

为了克服停止并等待ARQ协议长时间等待ACK的缺点。这个协议会连续发送一组数据包,然后再等待这些数据包的ACK.分为:

回退N重传(Go-Back-N)

  • 接收点丢弃从第一个没有收到的数据包开始的所有数据包。
  • 发送点收到NACK后,从NACK中指明的数据包开始重新发送。

选择重传(Selective Repeat)

  • 发送点连续发送数据包但对每个数据包都设有个一个计时器。
  • 当在一定时间内没有收到某个数据包的ACK时,发送点只重新发送那个没有ACK的数据

五:TCP 三次握手和四次挥手(面试常客)

三次握手的目的是建立可靠的通信信道,其目的就是双方确认自己与对方的发送与接收是正常的。

  • 客户端–发送带有 SYN 标志的数据包给服务器         ---服务器端收到数据包,确认了对方发送正常
  • 服务端–发送带有 SYN/ACK 标志的数据包给客户端   ---客户端确认了:自己发送、接收正常,对方发送、接收正常;服务器确认了:自己接收正常,对方发送正常
  • 客户端–发送带有带有 ACK 标志的数据包给服务器端。 ---最后一次服务器端收到ACK包确认了:自己发送、接收正常,对方发送接收正常

为什么要传回 SYN

接收端传回发送端所发送的 SYN 是为了告诉发送端,我接收到的信息确实就是你所发送的信号了。

 四次挥手:

  • 客户端-发送一个 FIN,用来关闭客户端到服务器的数据传送
  • 服务器-收到这个 FIN,它发回一 个 ACK,确认序号为收到的序号加1 。这个时候客户端关闭。
  • 服务器-关闭与客户端的连接,发送一个FIN给客户端
  • 客户端-发回 ACK 报文确认,并将确认序号设置为收到序号加1,这个时候服务器端关闭。

六: 在浏览器中输入url地址 ->> 显示主页的过程(面试常客) 

1浏览器查找域名(www.google)的IP地址。

2浏览器与服务器进行3次握手,向web服务器发送一个http请求。

3服务器处理请求。

4服务器 返回一个html的相应。

5浏览器开始显示HTML。

数据库

1 MySql底层采用什么数据结构来存储数据?

B-数,平衡树

2 分页所用的关键字

MySQL:

Limit
MySQL中使用 LIMIT
select * from students limit 0, 10   从第0条开始查,一共查询10条记录。

 2 增删改查操作:

创建数据表Create,删除数据表Drop

CREATE TABLE IF NOT EXISTS `runoob_tbl`(
   `runoob_id` INT UNSIGNED AUTO_INCREMENT,
   `runoob_title` VARCHAR(100) NOT NULL,
   `runoob_author` VARCHAR(40) NOT NULL,
   `submission_date` DATE,
   PRIMARY KEY ( `runoob_id` )
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
DROP TABLE table_name ;

插入数据 :

INSERT INTO table_name (column1,column2,column3,...)
VALUES (value1,value2,value3,...);

INSERT INTO Websites (name, url, alexa, country) VALUES ('百度','https://www.baidu/','4','CN');

删除:

DELETE FROM table_name
WHERE some_column=some_value;

DELETE FROM Websites WHERE name='Facebook' AND country='USA';

修改:

UPDATE table_name
SET column1=value1,column2=value2,...
WHERE some_column=some_value;

UPDATE Websites SET alexa='5000', country='USA' WHERE name='菜鸟教程';

查询:

SELECT column_name,column_name
FROM table_name
WHERE column_name operator value;

SELECT * FROM Websites WHERE country='CN';

3 SQL实现数据表的复制

Selcet xx into table2 from table1
select into from 和 insert into select都是用来复制表.
两者的主要区别为: 
select into from 要求目标表不存在,因为在插入时会自动创建
insert into select from 要求目标表存在
两者的语法:
SELECT vale1, value2 into Table2 from Table1
Insert into Table2(field1,field2,...) select value1,value2,... from Table1

4 什么是事务

事务是数据库中并发控制的基本单位,它是一个操作序列,一个事务中的操作序列要么全都执行,要不都不执行。

5 数据库事务的四大特性

ACID
-原子性(Atomicity):事务作为一个整体被执行,包含在其中的对数据库的操作要么全部被执行,要么都不执行
-一致性(Consistency):事务应确保数据库的状态从一个一致状态转变为另一个一致状态。
-隔离性(Isolation):多个事务并发执行时,一个事务的执行不应影响其他事务的执行
-持久性(Durability):已被提交的事务对数据库的修改应该永久保存在数据库中

6 数据库的三级模式

数据库标准结构是三级模式结构,它包括外模式、概念模式、内模式。
-外模式,又称用户模式,对应于用户级。它是某个或某几个用户所看到的数据库的数据视图,含模式中允许特定用户使用的那部分数据。
-概念模式,它是由数据库设计者综合所有用户的数据,按照统一的观点构造的全局逻辑结构,是对数据库中全部数据的逻辑结构和特征的总体描述。
-内模式又称存储模式,对应于物理级。它是数据库中全体数据的内部表示或底层描述,描述了数据在存储介质上的存储方式和物理结构,对应着实际存储在外存储介质上的数据库。

7 什么是存储过程

存储过程类似于是一个方法,它是由一些SQL语句组成的代码块,
这些SQL语句代码像一个方法一样实现一些功能(对单表或多表的增删改查),然后再给这个代码块取一个名字,在用到这个功能的时候调用他就行了。

8 简单介绍一下触发器

触发器是由 INSERT、UPDATE 和 DELETE 等事件来触发某种特定操作。
满足触发器的触发条件时,数据库系统就会执行触发器中定义的程序语句。这样做可以保证某些操作之间的一致性。
例如,在执行完一句插入语句时,触发查询所有,保证信息的完整性。

9 什么是E-R图

 ER图中包含了实体(即数据对象)、关系和属性3种基本成分;
 通常用矩形框代表实体,用连接相关实体的菱形框表示关系,用椭圆形或圆角矩形表示实体(或关系)的属性,并用直线把实体(或关系)与其属性连接起来。
 三种联系:
 	- 1:1 例如,一个部门有一个经理,而每个经理只在一个部门任职,则部门与经理的联系是一对一的
 	- 1:N 例如,某校教师与课程之间存在一对多的联系“教”,即每位教师可以教多门课程,但是每门课程只能由一位教师来教。
 	- M:N 例如,学生与课程间的联系(“学”)是多对多的,即一个学生可以学多门课程,而每门课程可以有多个学生来学。

10 什么是外连接、内连接?

内连接:根据连接条件只保留两个表中有对应数据的记录;
外连接:当一个表中记录在另一个表中没有对应记录时,会生成一条与 NULL 值对应的记录

11 什么是索引?有什么用?

索引相当于目录,可以更加方便的用于查询。

12 三大范式

第一范式
第一范式(1NF)要求数据库表的每一列都是不可分割的基本数据项,同一列中不能有多个值。
若某一列有多个值,可以将该列单独拆分成一个实体,新实体和原实体间是一对多的关系。
在任何一个关系数据库中,第一范式(1NF)是对关系模式的基本要求,不满足第一范式(1NF)的数据库就不是关系数据库。
第二范式
满足第二范式(2NF)必须先满足第一范式(1NF)
第二范式要求数据库的每个实例或行必须可以被唯一的区分,即表中要有一列属性可以将实体完全区分,这个属性就是主键,即每一个属性完全依赖于主键,
第三范式
满足第三范式(3NF)必须先满足第二范式。
第三范式要求:实体中的属性不能是其他实体中的非主属性。因为这样会出现冗余。即:属性不依赖于其他非主属性。
如果一个实体中出现其他实体的非主属性,可以将这两个实体用外键关联,而不是将另一张表的非主属性直接写在当前表中。

13 数据库性能调优

数据库结构优化:

为什么要优化
系统的吞吐量瓶颈往往出现在数据库的访问速度上
随着应用程序的运行,数据库的中的数据会越来越多,处理时间会相应变慢
数据是存放在磁盘上的,读写速度无法和内存相比
优化原则:减少系统瓶颈,减少资源占用,增加系统的反应速度。

数据库结构优化
需要考虑数据冗余、查询和更新的速度、字段的数据类型是否合理等多方面的内容。

将字段很多的表分解成多个表

对于字段较多的表,如果有些字段的使用频率很低,可以将这些字段分离出来形成新表。

因为当一个表的数据量很大时,会由于使用频率低的字段的存在而变慢。

增加中间表

对于需要经常联合查询的表,可以建立中间表以提高查询效率。

通过建立中间表,将需要通过联合查询的数据插入到中间表中,然后将原来的联合查询改为对中间表的查询。

增加冗余字段

设计数据表时应尽量遵循范式理论的规约,尽可能的减少冗余字段,让数据库设计看起来精致、优雅。但是,合理的加入冗余字段可以提高查询速度。

表的规范化程度越高,表和表之间的关系越多,需要连接查询的情况也就越多,性能也就越差。

注意:

冗余字段的值在一个表中修改了,就要想办法在其他表中更新,否则就会导致数据不一致的问题。

14 项目中如何提升索引速度

操作系统

1、 什么是操作系统?操作系统由什么组成?

操作系统是用户和计算机之间的界面。一方面操作系统管理着所有计算机系统资源,另一方面操作系统为用户提供了一个抽象概念上的计算机。在操作系统的帮助下,用户使用计算机时,避免了对计算机系统硬件的直接操作。

操作系统的主要组成部分:进程和线程的管理,存储管理,设备管理,文件管理。

2、 进程与线程的关系

进程:是程序的一次执行,是系统进行资源分配和调度的基本单位
线程:是操作系统能够进行运算调度的最小单位,它是进程中的一个实体。
两者关系:进程是指程序执行时的一个实例,线程是进程的一个实体;
    线程必定也只数据一个进程,而进程可以拥有多个线程而且至少拥有一个线程。

3、 线程和进程的区别

进程是是程序的一次执行,是系统进行资源分配的基本单位
    - 拥有独立的堆栈空间和数据段,系统开销大
    - 由于进程之间是独立的特点 使得进程的安全性比较高 有独立的地址空间 一个进程崩溃 不影响其他进程
    - 进程的通信机制相对复杂 譬如管道、信号、消息队列、套接字等
线程是是操作系统能够进行运算调度的最小单位,它是进程中的一个实体。
    - 线程所占的资源比较少,比进程开销小,一个进程中的所有线程共享该进程所拥有的全部资源,
    - 一个线程可以创建和撤销另一个线程,同一个进程中的多个线程之间可以并发执行,当进程退出后,该进程中所产生的线程都会被强制退出并清除。
    - 线程通信相对方便

4、进程间的通信的几种方式

-管道(pipe):是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。

-信号(signal):信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生;

-消息队列:消息队列是消息的链接表,它克服了上两种通信方式中信号量有限的缺点,具有写权限得进程可以按照一定得规则向消息队列中添加新信息;对消息队列有读权限得进程则可以从消息队列中读取信息;

-共享内存:可以说这是最有用的进程间通信方式。它使得多个进程可以访问同一块内存空间,不同进程可以及时看到对方进程中对共享内存中数据得更新。这种方式需要依靠某种同步操作,如互斥锁和信号量等;

-信号量:信号量是一个计数器,可以用来控制多个进程对共享资源的访问。

-套接字:这是一种更为一般得进程间通信机制,它可用于网络中不同机器之间的进程间通信,应用非常广泛。
 

5、线程间的通信机制 (线程同步的方式)线程同步与互斥关系

线程同步表示各个线程协同步调,按预定的先后次序进行运行。目的是为了线程安全,线程安全是指多线程访问同一代码,不会产生不确定的结果(即不会存在二义性。

线程互斥是对于共享的进程系统资源,在各单个线程访问时的排他性。当有若干个线程都要使用某一共享资源时,任何时刻最多只允许一个线程去使用,其他要使用该资源的线程必须等待,直到占用资源者释放该资源。线程互斥可以看成是一种特殊的线程同步。

1. 锁机制:互斥锁、读写锁
 互斥锁采用互斥对象机制,只有拥有互斥对象的线程才有访问公共资源的权限,因为互斥对象只有一个,所以可以保证公共资源不会同时被多个线程访问。
 读写锁允许多个线程同时读共享数据,而对写操作是互斥的。

2 信号量机制 :信号量是一个计数器,它允许同一时刻多个线程访问同一资源,但是需要控制同一时刻访问此资源的最大线程数量

3 事件对象(信号)通过通知操作的方式来保持多线程同步,还可以方便的实现多线程优先级的比较操作

6、 并发与并行

-并发:是指同一个时间段内多个任务同时都在执行,并且都没有执行结束。并发任务强调在一个时间段内同时执行,而一个时间段由多个单位时间累积而成,所以说并发的多个任务在单位时间内不一定同时在执行 。
-并行:是说在单位时间内多个任务同时在执行 。 

7、什么是轮询?

轮询是一种CPU决策如何提供周边设备服务的方式
轮询法的概念是由CPU定时发出询问,依序询问每一个周边设备是否需要其服务,有即给予服务,服务结束后再问下一个周边,接着不断周而复始。

8、什么是死锁?四个必要条件:

死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。

四个必要条件:
(1)互斥条件:系统存在着临界资源,资源不能被共享,只能由一个进程使用。
(2)请求与保持条件:进程已获得了一些资源,但因请求其他资源被阻塞时,对已获得的资源保持不放。
(3)不可抢占条件:有些系统资源是不可抢占的,当某个进程已获得这种资源后,系统不能强行收回,只能由进程使用完时自己释放。
(4)循环等待条件:若干进程之间行为一种头尾相接的循环等待资源关系。

9、 解决死锁的基本方法

主要是破坏死锁的4个条件

(1)预防死锁:
- 资源一次性分配:(即破坏请求和保持条件)
- 可剥夺资源:即当某进程新的资源未满足时,释放已占有的资源(破坏不可剥夺条件)
- 资源有序分配法:系统给每类资源赋予一个编号,每一个进程按编号递增的顺序请求资源,释放则相反(破坏循环等待条件)

(2)避免死锁:
最具有代表性的避免死锁算法是银行家算法

(3)解除死锁:
当发现有进程死锁后,便应立即把它从死锁状态中解脱出来,常用的方法有:
- 剥夺资源:从其他进程剥夺足够数量的资源给死锁进程,以解除死锁状态
- 撤销进程:可以直接撤销死锁进程或撤销代价最小的进程,直至有足够的资源可用,死锁状态消除为止;所谓代价是指优先级、运行代价、进程的重要性和价值等。

10、分页存储和分段存储有什么区别?

1)定义
分页:
用户程序的地址空间被划分成若干固定大小的区域,称为“页”,相应地,内存空间分成若干个物理块,页和块的大小相等。可将用户程序的任一页放在内存的任一块中,实现了离散分配。
分段:将用户程序地址空间分成若干个大小不等的段,每段可以定义一组相对完整的逻辑信息。存储分配时,以段为单位,段与段在内存中可以不相邻接。

(2)分页和分段的主要区别

-页是内容的物理单位,分页式为了实现非连续分配,以便解决内存碎片问题,或者说分页是由于系统管理的需要。段是信息的逻辑单位,它含有一组意义相对完整的信息,分段的目的是为了更好地实现共享,满足用户的需要。
-页的大小固定,由系统确定,将逻辑地址划分为页号和页内地址是由机器硬件实现的。而段的长度却不固定,决定于用户所编写的程序,通常由编译程序在对源程序进行编译时根据信息的性质来划分。
-分页的作业地址空间是一维的。分段的地址空间是二维的。
(3)Windows内存管理方式:段存储,页存储,段页存储。
分页存储管理基本思想:
用户程序的逻辑地址空间被划分成若干固定大小的区域,称为“页”或者“页面”,相应地,内存物理空间也分成相对应的若干个物理块,页和块的大小相等。可将用户程序的任一页放在内存的任一块中,实现了离散分配。

分段存储管理基本思想:
将用户程序地址空间分成若干个大小不等的段,每段可以定义一组相对完整的逻辑信息。存储分配时,以段为单位,段与段在内存中可以不相邻接,也实现了离散分配。

段页式存储管理基本思想:
分页系统能有效地提高内存的利用率,而分段系统能反映程序的逻辑结构,便于段的共享与保护,将分页与分段两种存储方式结合起来,就形成了段页式存储管理方式。在段页式存储管理系统中,作业的地址空间首先被分成若干个逻辑分段,每段都有自己的段号,然后再将每段分成若干个大小相等的页。对于主存空间也分成大小相等的页,主存的分配以页为单位。

Linux

  • Linux基础入门(详细版) Linux基础入门(详细版)_能-CSDN博客_linux基础
  • 菜鸟教程 Linux 教程 | 菜鸟教程
  • b站linux 教程 超详细Linux核心基础入门篇(程序员必备的Liunx核心技术)_哔哩哔哩_bilibili

数据结构

快速排序







冒泡排序

假设有一些数字: 10, 20 ,90 , 5, 18, 33, 46, 66
冒泡排序的规则:依次拿取每个数字进行比较,小的放前面,大的放后面(看需求)。

第一次: 10 , 20					拿前两个数字进行比较 小的放前面。
第二次: 10 , 20 , 90				拿 90 依次与 10 ,20 比较,大就放后面。
第三次: 5, 10 , 20 , 90         5 比 10小 所以放最前。
第四次: 5, 10 , 18 , 20 , 90
...
最终结果: 5 , 10 , 18 , 20, 33 ,46 ,66 ,90
//冒泡排序	外层循环 N-1 内层循环 N-1-i
for(int i=0; i<arr.length-1;i++){
	for(int j=0; j<arr.length-1-i;j++){
		if(arr[j] > arr[j+1]){
			int t=arg[j];
			arr[j]=arr[j+1];
			arr[j+1]=t;
		}
	}
}

二分查找

二分查找又称折半查找,它是一种效率较高的查找方法。
【二分查找要求】:1.必须采用顺序存储结构 2.必须按关键字大小有序排列。

public static int commonBinarySearch(int[] arr,int key){
		int low = 0;
		int high = arr.length - 1;
		int middle = 0;			//定义middle
		
		if(key < arr[low] || key > arr[high] || low > high){
			return -1;				
		}
		
		while(low <= high){
			middle = (low + high) / 2;
			if(arr[middle] > key){
				//比关键字大则关键字在左区域
				high = middle - 1;
			}else if(arr[middle] < key){
				//比关键字小则关键字在右区域
				low = middle + 1;
			}else{
				return middle;
			}
		}
		return -1;		//最后仍然没有找到,则返回-1
	}
int index = Arrays.binarySearch(arr, i);

二叉树的遍历

什么是红黑树

更多推荐

面试题(更新中)+JAVA+计网+数据库+操作系统+Linux+数据结构