零散面试问题补充

1.机器学习算法:k-means算法

k-means算法是一种聚类算法,依据数据间的距离进行划分;

算法步骤:
1. 从n个数据中随机选择 k 个对象作为初始聚类中心;
2. 根据每个聚类对象的均值(中心对象),计算每个数据点与这些中心对象的距离;并根据最小距离准则,重新对数据进行划分;
3. 重新计算每个有变化的聚类簇的均值,选择与均值距离最小的数据作为中心对象;

4. 循环步骤2和3,直到每个聚类簇不再发生变化为止。

需要用户事先指定类簇个数;聚类结果对初始类簇中心的选取较为敏感;容易陷入局部最优;只能发现球型类簇;

2.python :GIL

对Python虚拟机的访问由全局解释器锁GIL进行控制,保证同一时刻只有一个线程在运行。

1. 设置GIL
2. 切换到一个线程去运行
3. 运行:
    a. 指定数量的字节码指令,或者

    b. 线程主动让出控制(可以调用time.sleep(0))
4. 把线程设置为睡眠状态
5. 解锁GIL
6. 再次重复以上所有步骤

3.网络:进程间通信

管道
  1. 它是半双工的(即数据只能在一个方向上流动),具有固定的读端和写端。

  2. 它只能用于具有亲缘关系的进程之间的通信(也是父子进程或者兄弟进程之间)。

  3. 它可以看成是一种特殊的文件,对于它的读写也可以使用普通的read、write 等函数。但是它不是普通的文件,并不属于其他任何文件系统,并且只存在于内存中。

命名管道
  1. FIFO可以在无关的进程之间交换数据,与无名管道不同。

  2. FIFO有路径名与之相关联,它以一种特殊设备文件形式存在于文件系统中。

消息队列
  1. 消息队列是面向记录的,其中的消息具有特定的格式以及特定的优先级。

  2. 消息队列独立于发送与接收进程。进程终止时,消息队列及其内容并不会被删除。

  3. 消息队列可以实现消息的随机查询,消息不一定要以先进先出的次序读取,也可以按消息的类型读取。

信号量
  1. 信号量用于进程间同步,若要在进程间传递数据需要结合共享内存。

  2. 信号量基于操作系统的 PV 操作,程序对信号量的操作都是原子操作。

  3. 每次对信号量的 PV 操作不仅限于对信号量值加 1 或减 1,而且可以加减任意正整数。

  4. 支持信号量组。

共享内存
  1. 共享内存是最快的一种 IPC,因为进程是直接对内存进行存取。

  2. 因为多个进程可以同时操作,所以需要进行同步。

  3. 信号量+共享内存通常结合在一起使用,信号量用来同步对共享内存的访问。

4.网络:为什么tcp的连接需要3次握手,断开需要4次

连接:为了应对网络中存在延迟的重复数据。client的请求延迟了但未丢失,server接收到以后会认为是新的连接,发出确认。此时若没有第三次确认,会造成服务器空等。

断开:tcp是全双工的网络协议,允许通信双方同时进行数据的收发和连接的单向关闭。避免client数据发送完毕,server还有数据未发送完毕的情况。每一个方向上连接的关闭分别需要一次FIN和ACK

5.Linux命令 : 如何判断一个端口是否存在/可联通

telnet命令;wget命令;ssh命令

6.Linux命令:删除目录及子目录下的某种类型的文件

find . -name "*.txt" -type f -print -exec rm -rf {} \;  

7.中断的分类

同步中断(由cpu控制单元产生):异常(故障,自陷,终止)

异步中断(其他硬件设备产生):中断(可屏蔽,非屏蔽)

8.数据库

查询总分前5名的学生(同一个表的情况)

SELECT id,(math+english) as sum from mysql_test ORDER BY sum DESC LIMIT 2

单科前5(同一个表的情况)

SELECT name from mysql_test order by math DESC LIMIT 2

如果属性分布在多个表

SELECT id_name.id,id_name.`name`,(grade.math+grade.english) as sumer from 
id_name LEFT JOIN grade ON id_name.id = grade.id
ORDER BY sumer DESC LIMIT 2

9.数据库:用户权限管理

grant 权限 on 数据库对象 to user,可以作用于服务器,数据库,表,列,函数

revoke回收权限

10.数据库:

sum : 按列求和

count:计算返回的行的个数;

            count(*):统计表中所有的记录数(包括null值)

            count(列名):该字段在表中出现的次数(不包含null值)

 

11.java:内存泄漏

内存泄露是指无用对象(不再使用的对象)持续占有内存或无用对象的内存得不到及时释放,从而造成的内存空间的浪费称为内存泄露。内存泄露有时不严重且不易察觉,这样开发者就不知道存在内存泄露,但有时也会很严重,会提示你Out of memory。
长生命周期的对象持有短生命周期对象的引用就很可能发生内存泄露

  https://blog.csdn.net/zhousenshan/article/details/52864277

12.数据库

脏读脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。就是读到了一个已经过期的数据。
不可重复读是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。(即不能读到相同的数据内容)
幻读例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,

13.Java

hashmap hashtable concurrenthashmap的区别

https://www.cnblogs.com/zx-bob-123/archive/2017/12/26/8118074.html

14.Java

反射机制

https://www.cnblogs.com/whgk/p/6122036.html

15.Java

泛型

https://blog.csdn.net/weixin_35582406/article/details/78013727

16.Java

类加载器

https://www.cnblogs.com/fingerboy/p/5456371.html

17.Java:数据库连接泄漏

代码中未正确的关闭connection,每次执行后遗留了未关闭的连接,这些连接无法再被使用,造成了连接的泄漏。数据库连接资源是有限的,高频出现泄漏会导致数据库的崩溃。

18.Linux: 两台linux之间传文件

可以使用scp指令 -P 指定端口

19.HTTP 报文段

请求报文:请求行(方法,url,版本号)

                  请求头部:连接参数

                  空白行

                  请求体

响应报文:响应行(版本,状态,描述)

                  响应头部:连接参数

                  空白行

                  响应数据

20.求n以内的最大质数,倒着求,遍历查看每个数是否为质数

https://blog.csdn.net/wwzheng16/article/details/80979134

21.操作系统:多进程多线程在操作系统层面的差别与联系

https://blog.csdn.net/luoweifu/article/details/46595285

进程是程序的动态执行过程,是操作系统进行资源分配和调度的单位。依赖PCB进行管理。

线程是处理器调度的基本单位。一个进程可以有多个线程并共享其内存空间,切换更快。

22.网络:tcp如何保证可靠性

a.确认与重传:tcp的包有序号标记,建立滑动窗口,在规定时间内未收到ACK会进行重传。

b.提供数据校验

c.数据合理分片和排序

d.流量控制和拥塞控制

23.网络:tcp的流量控制和拥塞控制

流量控制:采用大小可变的滑动窗口进行流量控制,让发送方发送速度不过快。接收端会回传自己的窗口大小

拥塞控制:防止过多的数据进入网络,发送方会维护一个拥塞窗口,发送方窗口等于拥塞窗口和流量控制窗口的最小值,有四种算法:慢开始,拥塞避免(加法增),快速重传(收到3个重复的ack),快回复(乘法减小,加法增)。

24.数据结构:堆排序

不稳定。复杂度在nlogn。非终节点的值不大于(不小于)左右孩子的值。

堆的调整:取出堆顶后,用最后一个元素代替堆顶,再进行比较。

堆的新建:完全二叉树,从n/2(最后一个非叶节点)开始调整至根(反复筛选)

25.数据库:CHAR和VCHAR的区别

都是用于存储字符串的

char:的长度不可变,效率高但占用空间大,适用于长度短,固定长度,频繁改变的

vchar:长度可变,除开数据外还需要记录长度,按字节存储

nvchar:按字符存储

26.Jvm : stop the world

虚拟机在进行gc中过程时,会暂停掉其余线程。以免运行导致原来标记产生的状态变化

方法是设置安全点或安全区域。运行到安全点就会停下来等待gc过程(例如循环的结尾,方法调用返回和进入,产生异常的位置)。但是无法处理线程sleep或阻塞的情况。当线程进入安全区域,如sleep或者阻塞时,会标志自己已经进入了安全区域,当进行GC的时候,就不用去管它了,当他要离开安全区域是,会先看看JVM已经完成了GC没有,如果没有就等到GC完成之后再离开安全区域。

stw是必然发生的。(查看gcroots引用关系的时候)

27.Jvm : gc roots可以是哪些

a.虚拟机栈(栈桢中的本地变量表)中的引用的对象 
b.方法区中的类静态属性引用的对象 
c.方法区中的常量引用的对象 
d.本地方法栈中JNI的引用的对象

28.Jvm: OOM发生在哪,如何查找,如何调优

栈中可能发生(虚拟机扩展栈时无足够空间)。堆中可能发生。方法区可能发生。在报错信息中可以得到初步的定位。

visial VM jmap(查看堆)jstack(栈)

29.Jvm: 为什么要使用双亲委派

防止内存中出现同样的字节码,为了保证 JDK 核心类库都是由 bootstrap 加载器加载,保证了安全性。

30.操作系统:死锁的原因及如何打破

 互斥条件:一个资源每次只能被一个进程使用。
 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。
 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

可以预防死锁:

资源一次性分配:(破坏请求和保持条件)

可剥夺资源:即当某进程新的资源未满足时,释放已占有的资源(破坏不可剥夺条件)

资源有序分配法:系统给每类资源赋予一个编号,每一个进程按编号递增的顺序请求资源,释放则相反(破坏环路等待条件)

避免死锁:银行家算法

检查死锁与解除:根据资源编号和进程编号发现死锁,然后剥夺资源或撤销进程。

31.数据结构:快排优化

如果数组为有序数组,时间复杂度退化到O(n^2)

如果数组中存在大量重复元素,时间复杂度也会退化到O(n^2)

解决方法:选用中位数(最左,中间,最右)可以优化较为有序的情况,3路快排可以优化存在大量复杂元素的情况(划分为小于,等于,大于)。在划分的过程中,扫描时将遇到的左子序列中与基准元素排序码等值的元素放到序列的最左边,将遇到的右子序列中与基准元素排序码等值的元素放到序列的最右边。然后我们只要将所有排序码与基准元素等值的元素与扫描指针指向的元素开始依次交换,就可以得到三路划分的结果了

https://blog.csdn.net/jlqCloud/article/details/46939703

32.算法:换零钱算法(动态规划)

d(0) = 0; d(i) = min{d(i-vj)+1} i-vj>=0;

33.Java多线程:AQS

AQS是同步框架,进行两方面的工作,资源的管理(volatile int state)和资源申请者的管理(FIFO 线程等待队列)。可以用于构建锁或同步器。

state可以通过getState() setState() compareAndSetState()进行访问。

资源有两种定义:独占资源和共享资源

AQS对资源申请者的管理已经在顶层实现好了,自定义同步器时仅仅需要重写几种特定的方法,不需要关心队列的实现细节

自定义同步器要么是独占方法,要么是共享方式,他们也只需实现tryAcquire-tryRelease、tryAcquireShared-tryReleaseShared中的一种即可。但AQS也支持自定义同步器同时实现独占和共享两种方式。

https://blog.csdn.net/yizhenn/article/details/52384592

34.java多线程:线程池的排队策略和拒绝策略

当创建线程和销毁线程带来的开销已经超过了线程运行的开销,可以考虑采用线程池。

线程池的组成部分:

线程池管理器(ThreadPool):用于创建并管理线程池,包括 创建线程池,销毁线程池,添加新任务;
工作线程(PoolWorker):线程池中线程,在没有任务时处于等待状态,可以循环的执行任务;
任务接口(Task):每个任务必须实现的接口,以供工作线程调度任务的执行,它主要规定了任务的入口,任务执行完后的收尾工作,任务的执行状态等; 任务队列(taskQueue):用于存放没有处理的任务。提供一种缓冲机制。

线程池类型:

newSingleThreadExecutor

单个线程的线程池,即线程池中每次只有一个线程工作,单线程串行执行任务

newFixedThreadExecutor(n)

固定数量的线程池,没提交一个任务就是一个线程,直到达到线程池的最大数量,然后后面进入等待队列直到前面的任务完成才继续执行

newCacheThreadExecutor(推荐使用)

可缓存线程池,当线程池大小超过了处理任务所需的线程,那么就会回收部分空闲(一般是60秒无执行)的线程,当有任务来时,又智能的添加新线程来执行。

newScheduleThreadExecutor

大小无限制的线程池,支持定时和周期性的执行线程

排队策略

  1. 直接提交。直接提交策略表示线程池不对任务进行缓存。新进任务直接提交给线程池,当线程池中没有空闲线程时,创建一个新的线程处理此任务。这种策略需要线程池具有无限增长的可能性。实现为:SynchronousQueue
  2. 有界队列。当线程池中线程达到corePoolSize时,新进任务被放在队列里排队等待处理。有界队列(如ArrayBlockingQueue)有助于防止资源耗尽,但是可能较难调整和控制。队列大小和最大池大小可能需要相互折衷:使用大型队列和小型池可以最大限度地降低 CPU 使用率、操作系统资源和上下文切换开销,但是可能导致人工降低吞吐量。如果任务频繁阻塞(例如,如果它们是 I/O 边界),则系统可能为超过您许可的更多线程安排时间。使用小型队列通常要求较大的池大小,CPU 使用率较高,但是可能遇到不可接受的调度开销,这样也会降低吞吐量。
  3. 无界队列。使用无界队列(例如,不具有预定义容量的 LinkedBlockingQueue)将导致在所有 corePoolSize 线程都忙时新任务在队列中等待。这样,创建的线程就不会超过 corePoolSize。(因此,maximumPoolSize 的值也就无效了。)当每个任务完全独立于其他任务,即任务执行互不影响时,适合于使用无界队列;例如,在 Web 页服务器中。这种排队可用于处理瞬态突发请求,当命令以超过队列所能处理的平均数连续到达时,此策略允许无界线程具有增长的可能性。

拒绝策略

1、直接丢弃(DiscardPolicy)

2、丢弃队列中最老的任务(DiscardOldestPolicy)。

3、抛异常(AbortPolicy)

4、将任务分给调用线程来执行(CallerRunsPolicy)。只要线程池未关闭,该策略直接在调用者线程中运行当前被丢弃的任务。显然这样不会真的丢弃任务,但是,调用者线程性能可能急剧下降。

35.JUC

JUC:java.util.concurrent

CopyOnWriteArrayList:相当于线程安全的ArrayList,它实现了List接口,他是线程安全的。

CopyOnWriteArraySet:相当于线程安全的HashSet,内部使用 CopyOnWriteArrayList 。

ConcurrentSkipListSet:一个基于 ConcurrentSkipListMap 的可缩放并发 NavigableSet 实现,内部排序是有序的。

ConcurrentHashMap:支持获取的完全并发和更新的所期望可调整并发的哈希表。

ConcurrentSkipListMap:可缩放的并发 ConcurrentNavigableMap 实现,内部排序是有序的Map,该类为线程安全的。

ArrayBlockingQueue:一个由数组支持的有界阻塞队列。此队列按 FIFO(先进先出)原则对元素进行排序;

LinkedBlockingQueue:一个基于已链接节点的、范围任意的 blocking queue。此队列按 FIFO(先进先出)排序元素;

LinkedBlockingDeque:一个基于已链接节点的、任选范围的阻塞双端队列;

ConcurrentLinkedQueue:一个基于链接节点的无界线程安全队列。此队列按照 FIFO(先进先出)原则对元素进行排序;

ConcurrentLinkedDeque:是双向链表实现的无界队列,该队列同时支持FIFO和FILO两种操作方式。

36.网络 :

http2.0与http1.0的区别

1.采用二进制格式传输数据,而非http1.1文本格式

2.压缩消息头

3.多路复用:http2 多个请求可同时在一个连接上并行执行

4.Server Push,服务器端能够更快的把资源推送到客户端。

5.采用了https

http1.0与http1.1的区别

https://www.cnblogs.com/gofighting/p/5421890.html

支持了长连接,增加了host字段

37.数据库:SQL优化

a.尽量避免全表扫描,在where 或者 order by 的列上面使用索引

b.避免隐形的类型转化,null查询(设置特殊值),!= ,or(用union来进行连接),in,like,在where字段进行函数操作

   会导致放弃索引

c.避免无意义的操作

d.建立索引的优化

e.避免频繁的创建和删除临时表

https://blog.csdn.net/jie_liang/article/details/77340905

38.数据库:数据库优化

选取最适用的字段属性(表结构)

合理使用外键(表结构)

合理建立索引(表结构)

SQL的优化

减少数据访问(减少磁盘访问)

返回更少数据(减少网络传输或磁盘访问)

减少交互次数(减少网络传输)

减少服务器CPU开销(减少CPU及内存开销)

利用更多资源(增加资源)

系统配置和硬件的优化

39.数据库:导致索引失效的情况

a.隐形的类型转化

b.对索引进行了运算

c.使用了内部函数

d.进行了!=  ,in , like查询,null值查询

e.出现了 or

40.Java : arraylist的扩容方式与时机

如果是无参构造的,初始数组的大小是0,如果数组(elementData)的长度小于最小需要的容量(minCapacity)就扩容,第一次分配10.扩容按1.5的倍数+1.容量+容量>>1 = 1.5容量

每次扩容都是通过Arrays.copyOf(elementData, newCapacity) 这样的方式实现的

所以预先知道需要的空间很大时应该手动设置一个大小避免多次扩容带来的消耗

41.计算机网络:NIO,BIO,AIO

都是IO的方式

BIO:需要先在服务端启动一个ServerSocket,然后在客户端启动Socket来对服务端进行通信,默认情况下服务端需要对每个请求建立一堆线程等待请求,而客户端发送请求后,先咨询服务端是否有线程相应,如果没有则会一直等待或者遭到拒绝请求,如果有的话,客户端会线程会等待请求结束后才继续执行

NIO:NIO则是使用单线程或者只使用少量的多线程,每个连接共用一个线程。当socket有流可读或可写入socket时,操作系统会相应的通知引用程序进行处理,应用再将流读取到缓冲区或写入操作系统。  也就是说,这个时候,已经不是一个连接就要对应一个处理线程了,而是有效的请求,对应一个线程,当连接没有数据时,是没有工作线程来处理的

AIO:read/write方法都是异步的,完成后会主动调用回调函数

  • Java BIO : 同步并阻塞,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善。

  • Java NIO : 同步非阻塞,服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。

  • Java AIO(NIO.2) : 异步非阻塞,服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理,

42.JVM:自定义加载器如何实现

https://www.cnblogs.com/szlbm/p/5504631.html

why:需求无法满足。部署在同一个服务器上的两个Web应用程序所使用的Java类库可以实现相互隔离。部署在同一个服务器上的两个Web应用程序所使用的Java类库可以相互共享。

过程:如果不想打破双亲模式,只需要重写findClass()方法即可。此方法根据参数指定类的名字,返回对象的Class对象

           如果需要打破双亲模式,需要重写整个classLoad方法,

43.数据库:事务有什么用

https://www.cnblogs.com/sharpest/p/6122352.html

事务提供了一种机制,可用来将一系列数据库更改归入一个逻辑操作。更改数据库后,所做的更改可以作为一个单元进行提交或取消。事务可确保遵循原子性、一致性、隔离性和持续性(ACID)这几种属性,以使数据能够正确地提交到数据库中。

44.联合索引的匹配原则

https://www.jianshu.com/p/b7911e0394b0

最左前缀匹配:

如果有一个2列的索引(col1,col2),则已经对(col1)、(col1,col2)上建立了索引;
如果有一个3列索引(col1,col2,col3),则已经对(col1)、(col1,col2)、(col1,col2,col3)上建立了索引;

45.web请求的过程

https://www.cnblogs.com/engeng/articles/5959335.html

域名解析 - tcp的3次握手 - 建立连接后发起http请求 - 服务器响应http请求,发回html代码 - 浏览器解析html代码并请求资源 - 返回给用户

46.Ddos攻击

https://www.cnblogs.com/xuan52rock/p/4377393.html

分布式拒绝服务攻击

DDoS究竟如何攻击?目前最流行也是最好用的攻击方法就是使用SYN-Flood进行攻击,SYN-Flood也就是SYN洪水攻击。SYN-Flood不会完成TCP三次握手的第三步,也就是不发送确认连接的信息给服务器。这样,服务器无法完成第三次握手,但服务器不会立即放弃,服务器会不停的重试并等待一定的时间后放弃这个未完成的连接,这段时间叫做SYN timeout,这段时间大约30秒-2分钟左右。若是一个用户在连接时出现问题导致服务器的一个线程等待1分钟并不是什么大不了的问题,但是若有人用特殊的软件大量模拟这种情况,那后果就可想而知了。一个服务器若是处理这些大量的半连接信息而消耗大量的系统资源和网络带宽,这样服务器就不会再有空余去处理普通用户的正常请求(因为客户的正常请求比率很小)。这样这个服务器就无法工作了,这种攻击就叫做:SYN-Flood攻击。

限制同时打开的SYN半连接数目。

缩短SYN半连接的time out 时间。

正确设置防火墙,禁止对主机的非开放服务的访问,限制特定IP地址的访问,启用防火墙的防DDoS的属性,严格限制对外开放的服务器的向外访问,运行端口映射程序祸端口扫描程序,要认真检查特权端口和非特权端口。

47.数据库:Mysql事务的实现原理

https://blog.csdn.net/ai_xiangjuan/article/details/78568337

  1. 为了实现MVCC,innodb对每一行都加上两个隐含的列,其中一列存储行被更新的时间,另外一列存储行被删除的时间。但是innodb存储的并不是绝对的时间,而是与时间对应的数据库系统的版本号。(保存这两个额外系统版本号使大多数读操作可以不加锁)

  2. 每当一个事务开始的时候,innodb都会给这个事务分配一个递增的版本号。所以版本号也可以被认为是事务号。

  3. 对于每一个查询语句,innodb都会把这个查询语句的版本号同查询遇到的行的版本号进行对比,然后结合不同的事务等级来决定是否返回该行。

48.Java:new对象的过程

https://www.cnblogs.com/CZDblog/p/5589379.html

首先检查new指令的参数能否在常量池中定位到一个类的符号引用,然后检查其是否已加载,解析和初始化;

然后为新生对象在堆上分配内存并初始化为0,生成对象头信息;

执行init方法进行初始化;

49:大数据量问题:一亿个数找出top 100(top K)问题

https://blog.csdn.net/zyq522376829/article/details/47686867

思路:

a.排序(由于数据量大基本不可行)

b.建立大小为k的堆,然后后续的数依次进行比较,最后堆中的就是所求的。时间复杂度在o(n*k*logk)

c.分治法:分成若干份,查找每份中最大的k个,然后再合并之后查找前k个,可以用快排优化(找到下标为k)

d.hash法,如果在这些数中有很多相同的数,先通过hash计算将相同的分在一个文件中,再采用之前几种办法进行查找

50.算法:寻找结点的共同双亲(参考剑指offer)

https://blog.csdn.net/wtyvhreal/article/details/45565383

首先考虑是否为二叉搜索树,然后考虑是否有指向父节点的指针;

如果都没有,则需要分别找到到这两个节点的路径并抽象为链表,然后还是回归到找链表的公共节点的问题。

51.算法:一个数组 找出所有和为n的种类数目

https://blog.csdn.net/yan456jie/article/details/51027770

可以采用递归来进行(取当前数,不取当前数)

也可以首先将数组进行排序,采用两个下标,然后遍历一次即可找到所有组合

52.网络:http请求头有哪些

https://blog.csdn.net/u010256388/article/details/68491509

属性名:属性值

accept:客户端能接受什么类型的响应类型,一个或多个MIME类型

referer:请求来源的url

cookie,语言,日期,编码信息,用户信息,cache-control

53.数据结构:红黑树的时间复杂度特性

插入,查找,删除 logn 遍历 n 

逻辑上很近的节点(父子)物理上可能很远,无法利用局部性

54.数据结构:B+树的时间复杂度特性

http://www.cnblogs.com/aspirant/p/9214485.html

插入,查找,删除 logn

数据库索引采用B+树的主要原因是B树在提高了磁盘IO性能的同时并没有解决元素遍历的效率低下的问题。正是为了解决这个问题,B+树应运而生。B+树只要遍历叶子节点就可以实现整棵树的遍历。而且在数据库中基于范围的查询是非常频繁的,而B树不支持这样的操作(或者说效率太低)。

55.数据库:Mysql的隔离级别

https://www.cnblogs.com/huanongying/p/7021555.html

首先要解释脏读,不可重复读,幻读

事务隔离级别脏读不可重复读幻读
读未提交(read-uncommitted)
不可重复读(read-committed)MMUC
可重复读(repeatable-read)MMUC
串行化(serializable)

56.算法:两个字符串的最长子字符串(连续)

https://blog.csdn.net/na_beginning/article/details/64921406

动态规划的思想是用d[i][j]来存si和sj的最长子串,并在计算过程中不断更新max和start值

57.算法:如何判断一个数是平方数

a.遍历到n/2,因子不会大于这个值;且有序所以可以进行二分查找;

b.平方的公式可以化为等差为2,初始值为1的序列;

58.算法:打印一个目录下,所有的文件名

https://www.cnblogs.com/woshuaile/p/8434243.html

在遇见目录时进行递归即可;

59.操作系统:物理内存和虚拟内存,虚拟内存如何映射

MMU直接进行管理,如果发现要用的页还没加载进内存就产生缺页中断,然后调度进内存;虚拟内存容量实际是硬盘容量加上内存容量,划分时保证页大小相同;

60.操作系统:写一段死锁的代码

https://blog.csdn.net/qq_35064774/article/details/51793656

在同步代码块中,占有资源的线程再去申请对方占有的资源

61.算法:链表排序

https://blog.csdn.net/qq_35644234/article/details/53222603

a.使用只交换数据域的冒泡排序(快排是不太适合链表排序的)

b.首先将数据取出来排序,然后重新生成链表或更改值

c.可以利用堆的结构进行排序

62.Java:jdk1.8中,对hashMap的优化

https://blog.csdn.net/USTC_Zn/article/details/78173217

1.8增加了红黑树部分,在链表长度大于8时转化为红黑树结构,将时间复杂度降到o(logn)

63.Java:jdk1.8中对concurrentHashMap的优化

https://blog.csdn.net/xzllss/article/details/80681581

数据结构也变为了数组+链表+红黑树,分段锁改为了CAS+同步,锁定的粒度减小(Node节点)

https://www.cnblogs.com/javalyy/p/8882172.html

64.操作系统:大端和小端

大端:将尾端存在高地址

小端:将尾端存在低地址

65.Java:volatile关键字的原理

https://www.cnblogs.com/dolphin0520/p/3920373.html

a.保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。

使用valitale会强制将修改的值立即写入主存,导致其他线程的缓存失效,在其他线程需要读取时就需要从新从主存进行读取。

b.禁止进行指令重排序

当程序执行到volatile变量的读操作或者写操作时,在其前面的操作的更改肯定全部已经进行,且结果已经对后面的操作可见;在其后面的操作肯定还没有进行;

在进行指令优化时,不能将在对volatile变量访问的语句放在其后面执行,也不能把volatile变量后面的语句放到其前面执行。

lock前缀指令:相当于一个内存屏障(也成内存栅栏)

它确保指令重排序时不会把其后面的指令排到内存屏障之前的位置,也不会把前面的指令排到内存屏障的后面;即在执行到内存屏障这句指令时,在它前面的操作已经全部完成;它会强制将对缓存的修改操作立即写入主存;如果是写操作,它会导致其他CPU中对应的缓存行无效。

66.设计模式:适配器模式

作为两个不兼容的接口之间的桥梁;

例如:美国电器110V,中国是220V,需要适配器转接;

JAVA JDK 1.1 提供了 Enumeration 接口,而在 1.2 中提供了 Iterator 接口,想要使用 1.2 的 JDK,则要将以前系统的 Enumeration 接口转化为 Iterator 接口,这时就需要适配器模式

76.网络:TCP头部信息

https://blog.csdn.net/qq_34501940/article/details/51073691

16位源端口号;16位目的端口号

32位序号;32位确认号;SYN,FIN等信号(各1位);校验和;紧急指针;选项;

77.网络:get和post请求区别

和服务器的不同交互方式

https://blog.csdn.net/czpxiaoze/article/details/78388081

1.提交形式不同:GET提交,请求的数据会附在URL之后(就是把数据放置在HTTP议头中),POST提交:把提交的数据放置在是HTTP包的包体中。因此,GET提交的数据会在地址栏中显示出来,而POST提交,地址栏不会改变。

2.传输数据的大小: HTTP协议并没有对传输的数据大小进行限制,HTTP协议规范也没有对URL长度进行限制。对于get请求特定浏览器和服务器对URL长度有限制;而对POST请求理论上数据不受限。但实际各个WEB服务器会规定对post提交数据大小进行限制get传送的数据量较小,不能大于2KB。post传送的数据量较大,一般被默认为不受限制。post基本没有限制,传不同的文件只不过要修改form里面的那个type参数

3.安全性不同:POST的安全性要比GET的安全性高。

4.get 和 post只是一种传递数据的方式,get也可以把数据传到服务器,他们的本质都是发送请求和接收结果。只是组织格式和数据量上面有差别

5. 对于get方式,服务器端用Request.QueryString获取变量的值,对于post方式,服务器端用Request.Form获取提交的数据。

6.

对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);

而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。所以get请求会更快。

78.数据库:mysql存储过程

https://www.cnblogs.com/mark-chan/p/5384139.html

相当于一个函数,会进行预编译;故而效率更快,占用网络流量更小,安全性高,可移植性和灵活性更好。并且可以多次调用

和事务的区别:事务中可以有存储过程 存储过程中也可以有事务

https://blog.csdn.net/lyb957919360/article/details/7770523

79.JVM的调优参数?

https://blog.csdn.net/manzhizhen/article/details/52606726

https://www.cnblogs.com/panxuejun/p/6058022.html

目的:

GC的时间足够的小

GC的次数足够的少

发生Full GC的周期足够的长

可以调优的地方:堆的最大值最小值;年轻代和老年代的比例;合适的垃圾回收器;堆栈的设置;

80.网络:

对称加密:DES

非对称加密:RSA

81.算法:找到二叉树中最长的一条路径。

https://www.cnblogs.com/wangzaizhen/p/5179729.html

思路应该是利用递归,此时的路径长度应该等于左子树的高度+右子树的高度+2;然后设置全部变量来记录出现过的最大值;返回值应该是子树的最高高度。

82.设计模式:装饰器模式和代理模式有什么区别

装饰器模式:原有的不能满足现有的需求,对原有的进行增强。

代理模式:给一个对象提供一个代理对象,并有代理对象来控制对原有对象的引用,提供了一个访问层

装饰模式应该为所装饰的对象增强功能;代理模式对代理的对象施加控制,并不提供对象本身的增强功能

代理模式注重的是隔离限制,关注于控制对对象的访问,让外部不能访问你实际的调用对象,比如权限控制。代理和真实对象之间的的关系通常在编译时就已经确定了。
装饰模式注重的是功能的拓展,关注于在一个对象上动态的添加方法,在同一个方法下实现更多的功能。装饰者能够在运行时递归地被构造。 

83.Java:序列化和反序列化

把对象转换为字节序列的过程称为对象的序列化。方便存储和传输
把字节序列恢复为对象的过程称为对象的反序列化

https://www.cnblogs.com/xdp-gacl/p/3777987.html

只有实现了Serializable和Externalizable接口的类的对象才能被序列化。Externalizable接口继承自 Serializable接口,实现Externalizable接口的类完全由自身来控制序列化的行为(可以限定哪些属性可以序列化),而仅实现Serializable接口的类可以 采用默认的序列化方式 。
  对象序列化包括如下步骤:
  1) 创建一个对象输出流,它可以包装一个其他类型的目标输出流,如文件输出流;
  2) 通过对象输出流的writeObject()方法写对象。

  对象反序列化的步骤如下:
  1) 创建一个对象输入流,它可以包装一个其他类型的源输入流,如文件输入流;
  2) 通过对象输入流的readObject()方法读取对象。

84.JVM:如何编写自定义的类加载器

https://blog.csdn.net/gg_18826075157/article/details/72847039

https://www.cnblogs.com/straybirds/p/8456136.html

继承classloader类,重写查找类的方法findclass。

85.Mysql:两种数据引擎的区别

https://blog.csdn.net/only_musm/article/details/78784109

功  能MYISAMMemoryInnoDBArchive
存储限制256TBRAM64TBNone
支持事物NoNoYesNo
支持全文索引YesNoNoNo
支持数索引YesYesYesNo
支持哈希索引NoYesNoNo
支持数据缓存NoN/AYesNo
支持外键NoNoYesNo

如果要提供提交、回滚、崩溃恢复能力的事物安全(ACID兼容)能力,并要求实现并发控制,InnoDB是一个好的选择

如果数据表主要用来插入和查询记录,则MyISAM引擎能提供较高的处理效率

如果只是临时存放数据,数据量不大,并且不需要较高的数据安全性,可以选择将数据保存在内存中的Memory引擎,MySQL中使用该引擎作为临时表,存放查询的中间结果

86.什么时候需要重写equals

当一个类有自己的相等定义时(非地址),重写equals方法时也需要重写hashcode方法。 

一般来说,如果你要把一个类的对象放入容器中,那么通常要为其重写equals()方法,让他们比较内容值而不是地址值。特别地,如果要把你的类的对象放入散列中,那么还要重写hashCode()方法;要放到有序容器中,还要重写compareTo()方法。 

https://blog.csdn.net/championhengyi/article/details/53490549

87.设计模式:模块模式

有一些通用的方法。由顶层模块封装调用逻辑,具体方法实现放在子类中。一般设置为final

88.jdbc查询一条语句及关闭的流程

https://www.cnblogs.com/wuziyue/p/4827295.html

a.加载驱动 class.forname

b.获取连接

c.创建一个statement对象

d.执行sql语句

e.处理返回的结果集

f.关闭资源 结果->对象->连接

89.非静态方法中是否可以有静态变量

调用是可以的,静态方法是属于类的,同理,在方法中(静态和非静态)是不可以定义静态变量的

90.数据库范式

https://blog.csdn.net/dove_knowledge/article/details/71434960

1NF:实体中的某个属性不能有多个值或重复的属性

2NF:每一个非主属性完全函数依赖于R的某个候选键

3NF:不存在非主属性对主属性的传递依赖

BCNF:不存在主属性对主属性的传递依赖和部分依赖

91.后端的大量图片怎么存储和传输

https://segmentfault.com/q/1010000008150690/a-1020000008150961

文件像普通文件一样放在磁盘上,数据库中记录文件在文件系统中的路径。静态文件服务器

92.tcp怎么保证传输的顺序

https://blog.csdn.net/wyq_tc25/article/details/51504642

主要是通过序列号机制

93.ping命令用到的协议

https://blog.csdn.net/csdnhsy/article/details/77945715?locationNum=1&fps=1

ICMP(网络层协议)

94.用什么算法从大量的IP中找出频率最高的IP的

https://blog.csdn.net/luyaran/article/details/54136227

先用hash分成小块文件,一般是取模,先统计小模块中重复次数最多的,再求出总的最多。

95.你有很多关键词, 但是内存能存下这么多关键词. 现在发表一条评论, 要求判断有没有包含关键词

a.用trie树存下关键词,然后根据文本进行查找。

96.指令重排序

https://www.cnblogs.com/xinde123/p/7602583.html

指令重排序是指CPU采用了允许将多条指令不按程序规定的顺序分开发送给各相应电路单元处理。并不是任意重排,需要保证指令依赖情况。

在虚拟机层面,为了尽可能减少内存操作速度远慢于CPU运行速度所带来的CPU空置的影响,虚拟机会按照自己的一些规则(这规则后面再叙述)将程序编写顺序打乱——即写在后面的代码在时间顺序上可能会先执行,而写在前面的代码会后执行——以尽可能充分地利用CPU。拿上面的例子来说:假如不是a=1的操作,而是a=new byte[1024*1024](分配1M空间)`,那么它会运行地很慢,此时CPU是等待其执行结束呢,还是先执行下面那句flag=true呢?显然,先执行flag=true可以提前使用CPU,加快整体效率,当然这样的前提是不会产生错误(什么样的错误后面再说)。虽然这里有两种情况:后面的代码先于前面的代码开始执行;前面的代码先开始执行,但当效率较慢的时候,后面的代码开始执行并先于前面的代码执行结束。不管谁先开始,总之后面的代码在一些情况下存在先结束的可能。 
在硬件层面,CPU会将接收到的一批指令按照其规则重排序,同样是基于CPU速度比缓存速度快的原因,和上一点的目的类似,只是硬件处理的话,每次只能在接收到的有限指令范围内重排序,而虚拟机可以在更大层面、更多指令范围内重排序。

97.CAS乐观锁
http://www.importnew.com/20472.html

乐观锁( Optimistic Locking)其实是一种思想。相对悲观锁而言,乐观锁假设认为数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果发现冲突了,则让返回用户错误的信息,让用户决定如何去做。上面提到的乐观锁的概念中其实已经阐述了他的具体实现细节:主要就是两个步骤:冲突检测和数据更新。其实现方式有一种比较典型的就是Compare and Swap(CAS)。

CAS:当多个线程尝试使用CAS同时更新同一个变量时,只有其中一个线程能更新变量的值,而其它线程都失败,失败的线程并不会被挂起,而是被告知这次竞争中失败,并可以再次尝试。

CAS 操作包含三个操作数 —— 内存位置(V)、预期原值(A)和新值(B)。如果内存位置的值与预期原值相匹配,那么处理器会自动将该位置值更新为新值。否则,处理器不做任何操作。无论哪种情况,它都会在 CAS 指令之前返回该位置的值。(在 CAS 的一些特殊情况下将仅返回 CAS 是否成功,而不提取当前值。)CAS 有效地说明了“我认为位置 V 应该包含值 A;如果包含该值,则将 B 放到这个位置;否则,不要更改该位置,只告诉我这个位置现在的值即可。”这其实和乐观锁的冲突检查+数据更新的原理是一样的

98.海量个人购买纪录,含不同商品购买数量,统计计算销售量前1000的商品 

a.建立一个大小为1000的堆,里面要记录商品及数目。当个数不足够时向堆中添加,个数够时和堆顶进行比较。

b.也可采用hash将商品名相同的分在同一个文件,然后统计数量并输出<=1000,再合并起来求出前1000。

99. MySQL的主从复制

https://www.cnblogs.com/kylinlin/p/5258719.html

主从复制用于:使得数据可以从一个数据库服务器复制到其他服务器上。在复制的时候,一个服务器充当主服务器,其余的服务器作为从服务器。方式有基于SQL语句的复制,基于行的负责,基于事务的复制。

优点:

  1. 通过增加从服务器来提高数据库的性能,在主服务器上执行写入和更新,在从服务器上向外提供读功能,可以动态地调整从服务器的数量,从而调整整个数据库的性能。
  2. 提高数据安全-因为数据已复制到从服务器,从服务器可以终止复制进程,所以,可以在从服务器上备份而不破坏主服务器相应数据
  3. 在主服务器上生成实时数据,而在从服务器上分析这些数据,从而提高主服务器的性能

主从复制的时延:感觉普通应用的时延还是可以接受的。

https://blog.csdn.net/petpig0312/article/details/78908308

100.协程是什么

https://blog.csdn.net/zdy0_2004/article/details/51323583

协程:单线程下的并发,由用户程序自己控制调度。一个线程可以拥有多个协程。核心点在于调度那块由他来负责解决,遇到阻塞操作,立刻yield掉,并且记录当前栈上的数据。之后将cpu交给其他的协程进行运行。就算没有用到其他线程,假如一个操作需要连续性地完成,那么也是需要借助锁的概念

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值