腾讯、阿里面试总结

腾讯、阿里面试总结

Java基础

1.String,StringBuilder,StringBuffer对比

  • String:字符串常量,字符串长度不可变。Java 中 String 是不可变的。
  • StringBuffer:字符串变量(Synchronized,即线程安全)。如果要频繁对字符串内容进行修改,出于效率考虑最好使用 StringBuffer,
  • StringBuilder:字符串变量(非线程安全)。在内部,StringBuilder 对象被当作是一个包含字符序列的变长数组。

2.new 字符串,String Pool的介绍

在这里插入图片描述

jvm主要分栈区,堆区,方法区。

  • String在创建对象时,会将字符串变成一个常量,如果是第一次创建会将这个常量存储到方法区。如果方法区中已经存在,则直接将常量的地址交给String对象。
  • 当使用直接方法创建String对象是
    String str = “string”;虚拟机会直接将常量的地址交给变量str
  • 而使用new的方法创建时,我们知道new出来的对象会存放在堆中,所以
    String s = new String(“string”);
    s存的是在堆中的引用,堆中的引用存储的是方法区String常量的地址。
  • String Pool:对于java程序中的字符直接量(即采用字面值方式赋值,型如:String s1 = “aaaa”;),JVM会使用一个字串池StringPool来保存它们。当第一次使用某个字符串直接量时,JVM会将它放入字符串池中进行缓存。

3. 重写重载对比

  • 重载(Overload):编译时的多态性。指在一个类中定义多个同名的方法,但要求每个方法具有不同的参数的类型或参数的个数。应用:多用于构造方法的重载
  • 重写(覆写,Override):运行时的多态性:当子类继承父类后,如果想要修改,可以用方法的重写;应用:子类需要修改继承自父类的方法时应用

4. Object的equals和hashCode对比

  • equals()方法是用来判断其他的对象是否和该对象相等,先通过hashcode来比较,如果hashcode相等,那么就用equals方法来比较两个对象是否相等。
  • 1.hashCode是为了提高在散列结构存储中查找的效率。2.equals重写的时候hashCode也跟着重写;3.两对象equals如果相等那么hashCode也一定相等,反之不一定。

5.抽象类和接口对比

在这里插入图片描述

6. 匿名内部类和lambda表达式实现方式对比

  • 1.匿名内部类可以为任意接口创建实例。Lambda表达式只能为函数式接口创建实例。
  • 2.匿名内部类实现的抽象方法体允许调用接口中的默认方法,但Lambda表达式的代码块不允许调用接口中的默认方法。直接访问的局部变量,以及外部类的成员变量(包括实力变量和类变量);

容器

1.ArrayList与Vector对比,初始化、扩容、线程安全

  • 默认初始化容量:10;Vector线程安全,而ArrayList线程不安全。Vector将方法synchronized了所以是线程安全的。
  • 扩容:ArrayList以1.5倍的方式在扩容(oldCapacity >> 1 结果为二分之一的oldCapacity)。
  • 新数组长度为原数组长度+扩容容量增量、否则新数组长度为原数组长度的2倍。与minCapacity进行比较、较大者为最终的新长度。

2. LinkedList与ArrayLIst对比

  • ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。
  • 对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。
  • 对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。

4.HashMap的存储结构、扩容、rehash、并发时存在的问题,与HashTable对比

  • 存储结构:从结构实现来讲,HashMap是数组+链表+红黑树(JDK1.8增加了红黑树部分)实现的
    红黑树是一种特化的AVL树(平衡二叉树),进行插入和删除操作时通过特定操作保持二叉查找树的平衡,从而获得较高的查找性能。从根到叶子的最长的可能路径不多于最短的可能路径的两倍长。
  • 扩容:扩容后的HashMap容量是之前容量的两倍
  • Rehash:当hash表中的负载因子达到负载极限的时候,hash表会自动成倍的增加容量(桶的数量),并将原有的对象;重新的分配并加入新的桶内,这称为rehash。
  • 并发:两个线程同时put。当调用Get由于带有环形链表,所以程序将会进入死循环!
    (1) HashMap:它根据键的hashCode值存储数据,大多数情况下可以直接定位到它的值,因而具有很快的访问速度,HashMap非线程安全,即任一时刻可以有多个线程同时写HashMap,可能会导致数据的不一致。
    (2) Hashtable:Hashtable是遗留类,很多映射的常用功能与HashMap类似,不同的是它承自Dictionary类,键值都不可为null,并且是线程安全的,任一时间只有一个线程能写Hashtable。

4. ConcurrentHashMap的存储结构,size()操作实现细节;与HashMap、HashTable对比

ConcurrentHashMap的数据结构是由一个Segment数组和多个HashEntry组成,主要实现原理是实现了锁分离的思路解决了多线程的安全问题。

  • 1、第一种方案他会使用不加锁的模式去尝试多次计算的size,最多三次,比较前后两次计算的结果。
  • 2、第二种方案是如果第一种方案不符合,他就会给每个Segment加上锁,然后计算ConcurrentHashMap的size返回.

5. LinkedHashMap特性,实现方式

LinkedhashMap在HashMap 基础上,用一个双向的链表维持的插入时候的顺序

6. ConcurrentSkipListMap存储结构,搜索效率

Skip list让已排序的数据分布在多层链表中,通过“空间来换取时间”的一个算法,在每个节点中增加了向前的指针,在插入、删除、查找时可以忽略一些不可能涉及到的结点,从而提高了效率。多条链构成,是关键字升序排列的数据结构;如果关键字 key在 级别level=i中出现,则,level<=i的链表中都会包含该关键字key;

7.Copy实现方式,应用场景,不足

占空间

并发

1.多线程实现方式、线程状态

  • 状态:新建、就绪、执行、阻塞、死亡
  • 执行中又包含:就绪、执行、睡眠、等待、离开、阻塞、唤醒
    Runnable是在JDK1.0的时候提出的多线程的实现接口,而Callable是在JDK1.5之后提出的;java.lang.Runnable 接口之中只提供了一个run()方法,并且没有返回值;java.util.concurrent.Callable接口提供有call(),可以有返回值;

2. 用户线程、守护线程对比

  • Daemon的作用是为其他线程的运行提供便利服务,比如垃圾回收线程就是一个很称职的守护者。
  • User和Daemon两者几乎没有区别,唯一的不同之处就在于虚拟机的离开:如果 User Thread已经全部退出运行了,只剩下Daemon Thread存在了,虚拟机也就退出。

3. 线程间通信、同步方式

  • (1)使用全局变量:主要由于多个线程可能更改全局变量,因此全局变量最好声明为volatile
  • (2)使用消息实现通信:每一个线程都可以拥有自己的消息队列(UI线程默认自带消息队列和消息循环,工作线程需要手动实现消息循环),因此可以采用消息进行线程间通信sendMessage,postMessage。
  • (3)使用事件CEvent类实现线程间通信:Event对象有两种状态:有信号和无信号,线程可以监视处于有信号状态的事件,以便在适当的时候执行对事件的操作。
    同步方式:
  • ① 临界区:临界区对应着一个CcriticalSection对象,当线程需要访问保护数据时,调用EnterCriticalSection函数;当对保护数据的操作完成之后,调用LeaveCriticalSection函数释放对临界区对象的拥有权,以使另一个线程可以夺取临界区对象并访问受保护的数据。
  • ② 互斥量:互斥与临界区很相似,但是使用时相对复杂一些(互斥量为内核对象),还可以在不同的进程间实现同步,从而实现资源的安全共享。由于互斥量是内核对象,因此其可以进行进程间通信
  • ③ 信号量:信号量的用法和互斥的用法很相似,不同的是它可以同一时刻允许多个线程访问同一个资源.
  • ④ 事件:事件分为手动置位事件和自动置位事件.一个布尔值表示是手动置位事件还是自动置位事件,另一个布尔值用来表示事件有无触发。由SetEvent()来触发,由ResetEvent()来设成未触发。

4. Java内存模型、操作、特性

Java内存模型简称JMM。JMM定义了Java 虚拟机(JVM)在计算机内存(RAM)中的工作方式。JMM是隶属于JVM的。JMM决定一个线程对共享变量的写入何时对另一个线程可见。从抽象的角度来看,JMM定义了线程和主内存之间的抽象关系:

  • 线程之间的共享变量存储在主内存(main memory)中,每个线程都有一个私有的本地内存(local memory),本地内存中存储了该线程以读/写共享变量的副本。Java内存模型有三个特性:原子性、可见性、有序性。这个三个特性主要体现在多线程环境下对变量的操作。

5. Java四种锁的实现细节,升级顺序

  • 无锁:无锁就是没有对任何资源进行锁定,所有线程都能访问并修改资源。
  • 偏向锁:在没有其他线程参与竞争时,锁就一直偏向被当前线程持有,当前线程就可以一直占用资源或者执行代码。
  • 自旋锁:一旦有另外一个线程参与锁竞争,偏向锁就会升级为自旋锁。竞争的两个线程都在各自的线程栈帧中生成一个Lock Record空间,用CAS操作将Mark Word设置为指向自己这个线程的LR(Lock Record)指针,设置成功者获得
  • 重量级锁:长时间的自旋操作是很消耗CPU资源的,为了避免这种盲目的消耗,JVM会在有线程超过10次自旋,或者自旋次数超过CPU核数的一半(JDK1.6以后加入了自适应自旋-Adaptive Self Spinning,由JVM自己控制自旋次数)时,会升级到重量级锁。

6. ReentrantLock 对比 synchronized

  • 相似点:这两种同步方式有很多相似之处,它们都是加锁方式同步,而且都是阻塞式的同步。
  • 功能区别:这两种方式最大区别就是对于Synchronized来说。而ReentrantLock需要lock()和unlock()方法配合try/finally语句块来完成,而ReenTrantLock需要手工声明来加锁和释放锁,为了避免忘记手工释放锁造成死锁,所以最好在finally中声明释放锁。

7. volatile对比synchronized

  • volatile本质是在告诉jvm当前变量在寄存器(工作内存)中的值是不确定的,需要从主存中读取; synchronized则是锁定当前变量,只有当前线程可以访问该变量,其他线程被阻塞住。
  • volatile仅能使用在变量级别;synchronized则可以使用在变量、方法、和类级别
  • volatile仅能实现变量的修改可见性,不能保证原子性;而synchronized则可以保证变量的修改可见性和原子性
  • volatile不会造成线程的阻塞;synchronized可能会造成线程的阻塞。
  • volatile标记的变量不会被编译器优化;synchronized标记的变量可以被编译器优化

8. 并发工具类的应用场景(CountDownLatch、CyclicBarrier、Semaphore)

  • CountDownLatch 是能使一组线程等另一组线程都跑完了再继续跑;
  • CyclicBarrier 能够使一组线程在一个时间点上达到同步,可以是一起开始执行全部任务或者一部分任务。同时,它是可以循环使用的;
  • Semaphore 是只允许一定数量的线程同时执行一段任务

10. 线程池的实现原理、重要参数解释

先判断线程池中核心线程池所有的线程是否都在执行任务。如果不是,则新创建一个线程执行刚提交的任务,否则,则进入第2步;判断当前阻塞队列是否已满,如果未满,则将提交的任务放置在阻塞队列中;否则,则进入第3步;判断线程池中所有的线程是否都在执行任务,如果没有,则创建一个新的线程来执行任务,否则,则交给饱和策略进行处理。
下面对参数进行说明:

  • corePoolSize:表示核心线程池的大小。
  • maximumPoolSize:表示线程池能创建线程的最大个数。
  • keepAliveTime:空闲线程存活时间。
  • unit:时间单位。为keepAliveTime指定时间单位。
  • workQueue:阻塞队列。
  • threadFactory:创建线程的工程类。
  • handler:饱和策略。
  • AbortPolicy: 直接拒绝所提交的任务,并抛出RejectedExecutionException异常;
  • CallerRunsPolicy:只用调用者所在的线程来执行任务;
  • DiscardPolicy:不处理直接丢弃掉任务;
  • DiscardOldestPolicy:丢弃掉阻塞队列中存放时间最久的任务,执行当前任务

虚拟机

1. 运行时数据区域、各个区域内容以及对比

在这里插入图片描述

栈上分配和TLAB对比

在这里插入图片描述

2、运行时常量池、字符串常量池对比

  • 字符串常量池 在每个VM中只有一份,存放的是字符串常量的引用值 。
  • 运行时常量池 是在类加载完成之后,将每个class常量池中的符号引用值转存到运行时常量池中,也就是说,每个class都有一个运行时常量池。

3. 对象的创建过程、内存布局、访问方式

  • 1)对象创建过程
    类加载:遇到 new 指令时,获取对应的符号引用,并检查该符号引用代表的类是否已被初始化。如果没有就进行类加载。分配内存:从堆中找到一块空间划分给对象。分配时,为了避免并发问题,JVM 会通过 CAS + TLAB 来保证线程安全。TLAB 本地线程分配缓冲:每个线程都会在堆中预先分配一小块内存,这块空间叫做 TLAB。设置零值。设置对象头信息:执行 init 方法。
  • 2)内存布局
    对象头:对象运行时数据,如哈希码、GC 分代年龄、锁状态标志、线程持有的锁、偏向线程 ID、偏向时间戳等。
    类型指针:指向方法区里的类元数据。用来确定该对象是哪个类的。
    实例数据:程序中定义的各字段。包括从父类继承的。
  • 3)访问方法
    JVM 规范中只规定了栈上的 reference 类型是指向对象的引用,并没有规定 JVM 该如何根据这个引用进行定位、访问堆中的对象。
    Hotspot 中 reference 是直接存储了对象的地址。而获取对象类型信息,就根据对象头的类型指针来访问获取。

4. 垃圾收集时可回收的判断、收集算法、垃圾收集器的应用场景及不足

  • 要有两种方式:引用计数法和可达性分析
  • 算法:(1)引用计数法(Reference Counting):给对象中添加一个引用计数器,每当有一个地方引用它时,计数器就加1;当引用失效时,计数器就减1;当计数器为0时对象就是不再被使用的。
    (2)标记-清除算法(Mark-Sweep)
    标记-清除算法采用从根集合(GC Roots)进行扫描,对存活的对象进行标记,标记完毕后,再扫描整个空间中未被标记的对象,进行回收。
    (3)复制算法(Copying):复制算法的提出是为了克服句柄的开销和解决内存碎片的问题。它开始时把堆分成一个对象面和多个空闲面, 程序从对象面为对象分配空间,当对象满了,基copying算法的垃圾收集就从根集合(GC Roots)中扫描活动对象,并将每个活动对象复制到空闲面(使得活动对象所占的内存之间没有空闲洞),这样空闲面变成了对象面,原来的对象面变成了空闲面,程序会在新的对象面中分配内存。
    (4)标记-整理算法(Mark-compact):标记-整理算法采用标记-清除算法一样的方式进行对象的标记,但在清除时不同,在回收不存活的对象占用的空间后,会将所有的存活对象往左端空闲空间移动,并更新对应的指针。

5. 内存分配策略、Minor GC与Full GC的时机

  • A.对象优先在Eden分配
    大多数情况下,对象在新生代Eden区中分配。当Eden区没有足够的空间时,虚拟机将发起一次Minor GC。
  • B.大对象直接进入老年代:所谓的大对象是指,需要大量连续内存空间的Java对象,最典型的大对象就是那种很长的字符串以及数组。
  • C.长期存活的对象进入老年代:既然虚拟机采用了分代收集的思想来管理内存,那么内存回收是就必须能识别哪些对象应放在新生代,哪些对象应放在老年代中。
  • D.动态对象年龄判断
  • E.空间分配担保:在发生MInor GC 之前,虚拟机会首先检查老年代最大可用的连续空间是否大于新生代所有对象的总和,如过这个条件成立,那么Minor GC 可以确保是安全的。
    新生代GC(Minor GC):只发生在新生代的垃圾收集动作,Minor GC非常频繁,一般回收速度也比较快。
    老年代GC(Major GC/Full GC):只发生在老年代的GC,Full GC的速度一般会比Minor GC慢10倍以上。

7. 类加载机制、双亲委派模型的好处与不足

虚拟机只有在两个类的类名相同且加载该类的加载器均相同的情况下才判定这是一个类。
双亲委派机制能保证多加载器加载某个类时,最终都是由一个加载器加载,确保最终加载结果相同。

  • 双亲委派模型的好处:在于Java类随着它的类加载器一起具备了一种带有优先级的层次关系。

8. 如何在Java程序运行时不停机动态加载一个函数进来

通过Java的类加载机制(ClassLoader)来动态加载某个class文件到内存当中的

9. 静态/动态分派、单/多分派的对比

根据对象的类型而对方法进行的选择,就是分派(Dispatch)。根据分派发生的时期,可以将分派分为两种,即分派分静态分派和动态分派。静态分派(Static Dispatch) 发生在编译时期,分派根据静态类型信息发生。方法重载(Overload)就是静态分派。(所谓的:编译时多态)。动态分派(Dynamic Dispatch) 发生在运行时期,动态分派动态地置换掉某个方法。(所谓的:运行时多态)。根据分派基于多少种不同的方法的接收者与方法的参数,可以将分派划分为单分派和多分派两种。一言以蔽之,JAVA语言支持静态的多分派和动态的单分派。
数据库

6.MySQL存储的数据结构,使用这样数据结构的原因,和其他数据结构的对比

目前大部分数据库系统及文件系统都采用B-Tree或其变种B+Tree作为索引结构。B+树在提高了磁盘IO性能的同时只要遍历叶子节点就可以实现整棵树的遍历,减少了树的高度,效率更高。

  • 为什么不用AVL(平衡二叉树)?
    数据库索引是存储在磁盘上,磁盘IO操作比较耗时,为了提高查询效率就需要减少磁盘IO的次数。
  • 为什么不用红黑树?
    红黑树是一种自平衡的二叉查找树,当插入或删除节点的时候,红黑树的规则可能被打破。

    7.MySQL语句的从客户端到服务端的执行流程

在这里插入图片描述

8.MySQL索引分类、索引的常见优化方式、

索引分类:
1.normal:普通索引
2.unique:唯一索引,不允许重复
3.spatial:空间索引
4. full text:全文搜索的引擎,全文索引时将存储在数据库中的整本书或整篇文章中的任意内容信息查找出来的技术
索引优化:
复合索引:创建复合索引时应该将最常用作限制条件的列放在最左边,依次递减。索引不会包含有NULL值的列:
使用短索引:对串列进行索引,如果可能应该指定一个前缀长度。排序的索引问题。
mysql查询只使用一个索引尽量不要包含多个列的排序,如果需要最好给这些列创建复合索引。

9.MySQL的存储引擎对比、主从复制和读写分离的实现方式

MyISAM基于ISAM存储引擎,MyISAM拥有较高的插入、查询速度,但不支持事务。InnoDB是事务型数据库的首选引擎,支持事务安全表(ACID),支持行锁定和外键。MEMORY存储引擎将表中的数据存储到内存中,为查询和引用其他表数据提供快速访问。Archive
在这里插入图片描述

主从复制(也称 AB 复制)允许将来自一个MySQL数据库服务器(主服务器)的数据复制到一个或多个MySQL数据库服务器(从服务器)。
读写分离:简单来说,读写分离就是只在主服务器上写,只在从服务器上读。基本原理是让主数据库处理事务性查询,而从服务器处理select查询。

计算机网络

1. OSI七层和TCP/IP五层协议

在这里插入图片描述

2. 传输层UDP和TCP对比

在这里插入图片描述

TCP协议和UDP协议特性区别总结:

  1. (1)TCP协议在传送数据段的时候要给段标号;UDP协议不
  2. (2)TCP协议可靠;UDP协议不可靠
  3. (3)TCP协议是面向连接;UDP协议采用无连接
  4. (4)TCP协议负载较高,采用虚电路;UDP采用无连接
  5. (5)TCP协议的发送方要确认接收方是否收到数据段(3次握手协议)
  6. (6)TCP协议采用窗口技术和流控制

当数据传输的性能<数据传输的完整性、可控制性和可靠性时,TCP协议是当然的选择。当强调传输性能而不是传输的完整性时,如:音频和多媒体应用,UDP是最好的选择。

3.TCP三次握手原因

  • TCP的连接因为是全双工的,也就是Client和Server两端,发送消息两个方向的连接都要建立成功。
  • 如果要保证双向连接都成功的话,三次通信是最少的次数了。大于三次的话,后面的次数通信就没有必要了,是在浪费资源.

4. TCP四次挥手原因(TIME_WAIT状态存在的原因)

  • 在关闭连接时,当收到对方的FIN报文通知时,它仅仅表示对方没有数据发送给你了;
  • 但未必你所有的数据都全部发送给对方了,所以你可以未必会马上会关闭SOCKET,也即你可能还需要发送一些数据给对方之后,
  • 再发送FIN报文给对方来表示你同意可以关闭连接了,所以它这里的ACK报文和FIN报文多数情况下都是分开发送的。

5. TCP(UDP)如何保证可靠传输

① 校验和:将这些整数加起来,且前面的进位不能丢弃,补在后面,最后取反即得到校验和
② 确认应答、序列号:TCP传输时将每个字节的数据都进行了编号,即序列号。
确认应答:TCP传输过程中,每次接收方收到数据后,都会对传输方进行确认应答。
③ 超时重传:超时重传可以理解为发送方在发送完数据后等待一段时间,时间到达没有接收到ACK报文,那么对刚才的数据进行重新发送,once again。
④ 连接管理:三次握手
⑤ 流量控制:接收端接收到数据后,对其进行处理。TCP根据接收端对数据的处理能力,决定发送端的发送速度,这个机制则为流量控制机制。
⑥ 拥塞控制:发送端在发送大量数据的时候,可能会引发一些问题,比如网络可能在刚开始的时候就很拥堵,引入了拥塞窗口的概念,在发送数据之前,首先将拥塞窗口与接收端反馈的窗口大小比对,取较小的值作为实际发送的窗口。

6. TCP拥塞控制的流程

拥塞控制的算法有:慢开始、拥塞避免、快重传、快恢复四种。

  • (1)慢开始算法的核心是从小到大逐渐增大发送窗口,也就是说,从小到大逐渐增大拥塞窗口的数值。当拥塞窗口的值小于慢开始门限时,使用慢开始算法,一旦拥塞窗口的值大于慢开始门限的值,就改用拥塞避免算法;
  • (2)拥塞避免算法的思路是让拥塞窗口缓慢地增大,收到每一轮的确认后,将拥塞窗口的值加1,而不是加倍,这样拥塞窗口的值按照线性规律缓慢增长。
  • (3)快重传算法首先要求接收方每收到一个失序的报文段后就立即发出重复确认(重复发送对前面有序部分的确认),如果发送方连续收到三个重复确认,就应该立即重传对方未收到的报文段。
  • (4)快恢复算法:1、当发送方连续收到三个重复确认时,就把慢开始门限减半,这是为了预防网络发生拥塞。

7. TCP滑动窗口和流量控制的关系

在确认应答策略中,对每一个发送的数据段,都要给一个ACK确认应答。使用滑动窗口,就可以一次发送多条数据,从而就提高了性能

8. 传输层和链路层的差错检测的区别

  • 数据链路层负责建立和管理节点间的链路。主要功能是通过各种控制协议,将有差错的物理信道变为无差错的、能可靠传输数据针的数据链路。
  • 传输层是通信子网和资源子网的接口和桥梁。主要任务是:向用户提供可靠的端到端的差错和流量控制,保证报文的正确传输。
  • 另外传输层的环境比数据链路层的环境要复杂得多。并且传输的数据是报文、信息帧

9. ARP解析地址流程(网络层协议)

  • 源主机先在自己的ARP缓冲区中寻找映射,如果有(直接填充于以太网帧中),
  • 如果没有,通过路由广播请求,这时一些联网的主机就会收到这个请求,并将这个请求传回网络层,对比IP地址,检验是否可以接受,
  • 如果不行,则直接丢失这个信息,如果可以那么回复ARP请求,并且将源主机的MAC地址加入到目的ARP缓冲区中,形成映射,
    • 源主机接受到请求后,将目的的MAC地址加入到ARP缓冲区,也形成映射,并将mac地址传输至连接层

10. HTTP请求页面的交互流程

在这里插入图片描述

11. HTTP的若干请求方式介绍对比

在这里插入图片描述

12. Cookie和session对比

  1. cookie数据存放在客户的浏览器上,session数据放在服务器上。
  2. cookie不是很安全,别人可以分析存放在本地的cookie并进行cookie欺骗,考虑到安全应当使用session。
  3. session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能,考虑到减轻服务器性能方面,应当使用cookie。
  4. 单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。
  5. 可以考虑将登陆信息等重要信息存放为session,其他信息如果需要保留,可以放在cookie中。

13. HTTPS的加密解密流程

在这里插入图片描述

14. IO模型 阻塞/非阻塞/IO复用/信号驱动IO/异步IO

在这里插入图片描述

15. select/poll/epoll对比

在这里插入图片描述

poll是Linux目前大规模网络并发程序开发的首选模型。在绝大多数情况下性能远超select和poll。目前流行的高性能web服务器正式依赖于epoll提供的高效网络套接字轮询服务。

16. epoll底层实现方式(https://www.cnblogs.com/Joy-Hu/p/10762239.html)

当进程调用epoll监控多个socket时,会在底层创建一个eventpoll对象,这个对象中包含一个重要的队列:就绪队列;进程调用epoll函数后,epoll会把这个进程加入eventpoll对象的等待队列中;然后把eventpoll对象加入到所有socket的等待队列中,并让CPU阻塞住,当某一个socket有数据返回时,CPU中断程序会把这个socket加入到eventpoll对象的就绪队列中,并把eventpoll中等待的进程唤醒。进程被唤醒后直接从就绪队列中获取socket读取数据数据读取完成后,epoll又会把进程加入到eventpoll的等待队列中,然后让CPU阻塞住。
epoll针对select优化的点:
除了第一次外,epoll不需操作所有socket对象的等待队列,只需要操作eventpoll的等待队列即可

17.自动重传(ARQ)协议

停止且等待ARQ:每发完一个分组就停止发送,等待对方确认(回复ACK)。如果过了一段时间,还是没有收到 ACK 确认,重新发送,直到收到确认后再发下一个分组。
连续ARQ:发送方维持一个发送窗口,凡位于发送窗口内的分组可以连续发送出去,而不需要等待对方确认。接收方一般采用累计确认,对按序到达的最后一个分组发送确认,表明到这个分组为止的所有分组都已经正确收到了。

18.ARP协议:将“IP地址”解析成为“物理地址”

一台计算机的IP地址可变(但必须唯一),MAC地址不可变。同一局域网中的一台主机要和另一台主机进行通信,需要通过 MAC 地址进行定位,然后才能进行数据包的发送。

  • 源主机先在自己的ARP缓冲区中寻找映射,如果有(直接将硬件地址写入以太网MAC帧中完成传输),如果没有,通过路由广播请求,这时一些联网的主机就会收到这个请求,并将这个请求传回网络层,对比IP地址,检验是否可以接受,如果不行,则直接丢失这个信息,如果可以那么回复ARP请求,并且将源主机的MAC地址加入到目的ARP缓冲区中,形成映射,源主机接受到请求后,将目的的MAC地址加入到ARP缓冲区,也形成映射,并将mac地址传输至连接层。
    逆地址解析协议RAPR:将“物理地址”解析为“IP地址”

19.打开一个网页的过程

DNS解析——TCP连接——发送HTTP请求——服务器处理请求并返回HTTP报文——浏览器解析渲染页面——连接结束

20.HTTPS和HTTP的区别

  • HTTPS协议的本质就是HTTP + SSL(or TLS)。在HTTP报文进入TCP报文之前,先使用SSL对HTTP报文进行加密。从网络的层级结构看它位于HTTP协议与TCP协议之间。
  • HTTP协议80/8080, HTTPS协议443

21.Web优化

1)合理使用缓存,将资源放在浏览器端
2)优化DNS,对内容进行压缩,减少响应内容大小,缩短连接时间
3)优化浏览器解析渲染

22.长连接和短连接

HTTP/1.0短连接:客户端和服务器每进行一次HTTP操作,就建立一次连接,任务结束就中断连接
HTTP/1.1起长连接:客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭(设置一个保持时间),客户端再次访问这个服务器时,会继续使用这一条已经建立的连接——在响应头中增加Connection:keep-alive。
HTTP协议的长连接和短连接,实质上是TCP协议的长连接和短连接。

23.HTTP如何保存用户状态?

HTTP 是一种无状态(stateless)协议,Session 机制的存在就是为了解决这个问题,Session 的主要作用就是通过服务端记录用户的状态。通过在 Cookie 中附加一个 Session ID ,服务端就可以标识并且跟踪这个用户了。

24.校验码

(1)奇偶校验(2)海明码(3)循环冗余校验码CRC

25.链路层的差错控制和传输层的可靠传输的区别

  • 数据链路层负责建立和管理节点间的链路。主要功能是在被传送的1、0数据串中加插特定的监督码元,建立某种校验关系。当校验关系在传输过程中产生错误,可以通过各种控制协议,使得接收方发现并及时纠错或要求重发,将有差错的物理信道变为无差错的、能可靠传输数据帧的数据链路。
  • 传输层的纠错级别就不停留在是0还是1错误,它负责保证整个数据报文的完整性和正确性。可靠性通过序号和确认来实现,完整性通过校验和实现。主要任务是:向用户提供可靠的端到端的差错和流量控制,保证报文的正确传输。

26.差错控制协议

传输差错:接收端接收到的数据与发送方发出的数据不一致

  • 1、前向纠错FEC。实时性好,单工通信采用。
  • 2、自动重发请求(ARQ)。强调检错能力,不要求有纠错能力,双向通道采用。
  • 3、混合纠错HEC。

操作系统

1、进程和线程以及它们的区别。

一个进程可以有多个线程,多个线程也可以并发执行。

  • 1、进程是资源分配的最小单位,线程是程序执行的最小单位(资源调度的最小单位)
  • 2、进程有自己的独立地址空间,每启动一个进程,系统就会为它分配地址空间,建立数据表来维护代码段、堆栈段和数据段,这种操作非常昂贵。线程是共享进程中的数据的。
  • 3、线程之间的通信更方便,同一进程下的线程共享变量等数据,而进程之间的通信需要以通信的方式(IPC)进行。不过如何处理好同步与互斥是编写多线程程序的难点。
  • 4、多进程程序更健壮,多线程程序只要有一个线程死掉,整个进程也死掉了,而一个进程死掉并不会对另外一个进程造成影响,因为进程有自己独立的地址空间。

4、什么是虚拟内存?

虚拟内存是计算机系统内存管理的一种技术。它使得应用程序认为它拥有连续可用的内存(一个连续完整的地址空间),而实际上,它通常是被分隔成多个物理内存碎片,还有部分暂时存储在外部磁盘存储器上,在需要时进行数据交换。

分页与分段的区别?

  1. 段是信息的逻辑单位,它是根据用户的需要划分的,因此段对用户是可见的;页是信息的物理单位,是为了管理主存的方便而划分的,对用户是透明的;
  2. 段的大小不固定,有它所完成的功能决定;页大大小固定,由系统决定;
  3. 段向用户提供二维地址空间;页向用户提供的是一维地址空间;
  4. 段是信息的逻辑单位,便于存储保护和信息的共享,页的保护和共享受到限制

1.进程的状态
在这里插入图片描述

多进程的组织:PCB+状态+队列,交替的三个部分:队列操作+调度+切换
2.上下文切换
从当前执行任务切换到另一个任务执行的过程,在切换之前会保存当前任务的状态,然后加载下一个任务的状态,切换到下一个任务继续执行。上下文是指某一时间点 CPU 寄存器和程序计数器的内容
3.进程上下文切换与线程上下文切换的区别
线程的切换虚拟空间内存是相同的(因为都是属于自己的进程),但是,进程切换的虚拟空间内存则是不同的。
4.进程通信
进程间通信(IPC):进程之间交换数据必须通过内核,在内核中开辟一块缓冲区,进程1把数据从用户空间拷到内核缓冲区,进程2再从内核缓冲区把数据读走,内核提供的这种机制称为进程间通信。
在这里插入图片描述

5.进程的调度算法

为了确定首先执行哪个进程以及最后执行哪个进程以实现最大 CPU 利用率。

  • (1)先到先服务(FCFS)调度算法 : 从就绪队列中选择一个最先进入该队列的进程为之分配资源,使它立即执行并一直执行到完成或发生某事件而被阻塞放弃占用 CPU 时再重新调度。
  • (2)短作业优先(SJF)的调度算法 : 从就绪队列中选出一个估计运行时间最短的进程。
  • (3)时间片轮转调度算法 : 给每个进程分配一个时间片。
    多级反馈队列调度算法 :多个就绪队列,每个队列的优先级递减,且各队列时间片大小也不同,每个队列都采用FCFS策略排列。
  • (4)优先级调度 :为每个流程分配优先级,首先执行具有最高优先级的进程。

6.死锁条件

多个进程访问共享资源,而且一个进程所需要的资源不止一个。若干进程竞争有限资源,出现无限期循环等待的局面。 产生死锁的必要条件:

  1. 互斥条件。即某个资源在一段时间内只能由一个进程占有,不能同时被两个或两个以上的进程占有。
  2. 不可抢占条件。进程所获得的资源在未使用完毕之前,资源申请者不能强行地从资源占有者手中夺取资源,而只能由该资源的占有者进程自行释放。
  3. 占有且申请条件。进程至少已经占有一个资源,但又申请新的资源。
  4. 循环等待条件。存在一个进程等待序列{P1,P2,…,Pn},其中P1等待P2所占有的某一资源,P2等待P3所占有的某一源,…,而Pn等待P1所占有的某一资源。

7.解决死锁的方法

一般地,解决死锁的方法分为死锁的预防,避免,检测与恢复三种。

  • (1)死锁的预防:要求进程申请资源时遵循某种协议,从而打破产生死锁的四个必要条件中的一个或几个,保证系统不会进入死锁状态。
    〈1〉打破互斥条件。即允许进程同时访问某些资源。
    〈2〉打破不可抢占条件。即允许进程强行从占有者那里夺取某些资源。
    〈3〉打破占有且申请条件。可以实行资源预先分配策略。即进程在运行前一次性地向系统申请它所需要的全部资源。
    〈4〉打破循环等待条件,实行资源有序分配策略,即把资源事先分类编号,按号分配。
  • (2)死锁的避免 :允许进程动态地申请资源,但系统在进行资源分配之前,应先计算此次资源分配的安全性。若此次分配不会导致系统进入不安全状态,则将资源分配给进程;否则,令进程等待。
  • (3)死锁的检测与恢复 :系统为进程分配资源时,不采取任何限制性措施,但是提供了检测和解脱死锁的手段。

8.操作系统内存管理机制

负责内存的分配与回收(malloc,free),地址转换

  • (1)连续分配管理
    块式管理:将内存分为几个固定大小的块,每个块中只包含一个进程,但是如果程序运行只需要很小的空间的话,就会有很大一部分被浪费了。
  • (2)非连续分配管理方式

页式管理 :把主存分为大小相等且固定的一页一页的形式,通过页表对应逻辑地址和物理地址。
段式管理 :把主存分为一段段的,每一段的空间又要比一页的空间小很多,每个段定义了一组逻辑信息,例如,有主程序段 MAIN、子程序段 X、数据段 D 及栈段 S 等,通过段表对应逻辑地址和物理地址。
段页式管理:把主存先分成若干段,每个段又分成若干页。

9.快表

相当于高速缓存,根据虚拟地址中的页号查快表,如果该页在快表中,可以直接从快表中读取相应的物理地址,否则才会访问内存中的页表。

10.多级页表

多级页表其实就是对页表进行分页管理,即内存中只常驻一级页表,一级页表的每个PTE指向一个二级页表的基地址,以此类推,最后一级页表存储物理块号和块内偏移量,二级以后的页表可以不存在,也可以不在主存。

11.页面置换算法
当发生缺页中断时,如果当前内存中并没有空闲的页面,操作系统就必须在内存选择一个页面将其移出内存,以便为即将调入的页面让出空间。

  • OPT 最佳置换算法:所选择的被淘汰页面将是以后永不使用的,或者是在最长时间内不再被访问的页面。
  • FIFO先进先出页面置换算法 : 总是淘汰最先进入内存的页面
  • LRU 最近最久未使用页面置换算法:LRU算法赋予每个页面一个访问字段,用来记录一个页面自上次被访问以来所经历的时间 T。
  • LFU最少使用页面置换算法 : 该置换算法选择在之前时期使用最少的页面作为淘汰页。
    在这里插入图片描述
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值