字符串

1
2
3
4
5
6
7
String a = "a" + "b"  + "c";
String b = "abc";
String c = "ab";
String d = c + "c";

System.out.println(a == b);
System.out.println(a == d);

输出

1
2
true
false

CMS 能不能 初始标记 并发标记 重新标记 并发清理 去掉重新标记

1 浮动垃圾 如图,GC 线程便利对象树(实际是图),遍历过了A ,然后遍历过了B,遍历到了C,但是还没有遍历完C的儿子D,这时候如果 A.B=null; 那么B就变成了浮动垃圾,本次GC 过程B不会被清除。只能下次清除。

2 GC 三色标记算法过程中,白色的节点指向 黑色的节点 怎么办?

  直接把黑色变成灰色,这是浮动垃圾吗?不是,因为黑色节点变成了灰色,GC线程每次暂停后开始都会重灰色线程开始,也就是说黑色变成灰色以后,会重新便利这个灰色和下面的非黑色节点。

3 三色算法为什么要重新标记,便利灰色节点的子节点过程中,如果已经被遍历的子节点(已经被遍历过的子节点可能是黑色或者灰色)被指向了一个白色节点A.B=E ,然后这个B位置变成了白色的E,黑色的E变成了浮动垃圾。

如果直接删除B不会被删除,但是E会被删除,我们希望的E不会删除,B 被删除,B浮动垃圾下次GC在删除没问题,E 肯定不能删除,所有需要重新标记一边(这时候只能暂停业务线程(STW),不然又会出现类似的情况),重新标记只遍历黑色节点,看看下面是否有白色节点,有就标记成黑色。因为GC 这个过程实际有标记成黑色的一般比较少,所以比并发标记的对象少很多,速度要快一些,但是也标记了2次。

4 G1 怎么处理三色标记算法

  在上面图 A.B=E 的过程中,G1 把这个数据记录下来,编发标记完了不是去遍历所有黑色,而是去遍历 记录的 那份数据,这时候记录的数据 里面有个白色的E,只要通过分区集合找到 有关联的分区中如果有父黑色的节点指向

这个白色的E,有就标记成黑色,如果没有就保持白色(保持白色,是这个过程中业务线程把 A.E= null )

双亲委派

然而, DriverManager 是位于rt.jar包中的,类加载器是启动类加载器,com.mysql.jdbc.Driver肯定不在 <JAVA_HOME>/lib,那就无法加载MySQL的Driver,我们可以用应用程序类加载器来加载。所以java开发者的设计是,添加一个线程上下文类加载器(Thread Context ClassLoader),在启动类加载器中获取应用程序类加载器。 Thread.setContextClassLoaser() 设置线程上下文类加载器,如果创建线程的时候没有设置,会从父类继承一个,默认应用程序类加载器。

线程上下文类加载器是让父类加载器请求子类加载器完成类的加载,打破了双亲委派机制。

具体过程,在 DriverManager 的静态代码块对 Driver进行加载:

作者:Huffman
链接:https://juejin.cn/post/7003977368842960933
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

Select a from test where b > 123 order by c 怎样建索索引, a b , b a 建索引一样么

image-20220715001615003

牛客字节面经(07-15)

1. TCP首部字段有那些

img

  • 源端口、目标端口:计算机上的进程要和其他进程通信是要通过计算机端口的,而一个计算机端口某个时刻只能被一个进程占用,所以通过指定源端口和目标端口,就可以知道是哪两个进程需要通信。源端口、目标端口是用16位表示的,可推算计算机的端口个数为2^16个。
  • 序列号:表示本报文段所发送数据的第一个字节的编号。在TCP连接中所传送的字节流的每一个字节都会按顺序编号。由于序列号由32位表示,所以每2^32个字节,就会出现序列号回绕,再次从 0 开始。那如何区分两个相同序列号的不同TCP报文段就是一个问题了,后面会有答案,暂时可以不管。
  • 确认号:表示接收方期望收到发送方下一个报文段的第一个字节数据的编号。也就是告诉发送发:我希望你(指发送方)下次发送的数据的第一个字节数据的编号是这个确认号。也就是告诉发送方:我希望你(指发送方)下次发送给我的TCP报文段的序列号字段的值是这个确认号。
  • TCP首部长度:由于TCP首部包含一个长度可变的选项部分,所以需要这么一个值来指定这个TCP报文段到底有多长。或者可以这么理解:就是表示TCP报文段中数据部分在整个TCP报文段中的位置。该字段的单位是32位字,即:4个字节。
    • URG:表示本报文段中发送的数据是否包含紧急数据。URG=1,表示有紧急数据。后面的紧急指针字段只有当URG=1时才有效。
    • ACK:表示是否前面的确认号字段是否有效。ACK=1,表示有效。只有当ACK=1时,前面的确认号字段才有效。TCP规定,连接建立后,ACK必须为1。
    • PSH:告诉对方收到该报文段后是否应该立即把数据推送给上层。如果为1,则表示对方应当立即把数据提交给上层,而不是缓存起来。
    • RST:只有当RST=1时才有用。如果你收到一个RST=1的报文,说明你与主机的连接出现了严重错误(如主机崩溃),必须释放连接,然后再重新建立连接。或者说明你上次发送给主机的数据有问题,主机拒绝响应。
    • SYN:在建立连接时使用,用来同步序号。当SYN=1,ACK=0时,表示这是一个请求建立连接的报文段;当SYN=1,ACK=1时,表示对方同意建立连接。SYN=1,说明这是一个请求建立连接或同意建立连接的报文。只有在前两次握手中SYN才置为1。
    • FIN:标记数据是否发送完毕。如果FIN=1,就相当于告诉对方:“我的数据已经发送完毕,你可以释放连接了”
  • 窗口大小:表示现在运行对方发送的数据量。也就是告诉对方,从本报文段的确认号开始允许对方发送的数据量。
  • 校验和:提供额外的可靠性。具体如何校验,参考其他资料。
  • 紧急指针:标记紧急数据在数据字段中的位置。

2.TCP 可靠的机制

  • 检验和
  • 应答序列号
  • 超时重传
  • 流量控制
  • 拥塞控制
    • 慢启动
    • 拥塞避免
    • 快重传
    • 快恢复

3.PCB中有哪些信息

  • 程序ID(PID、进程句柄):它是唯一的,一个进程都必须对应一个PID。PID一般是整形数字
  • 特征信息:一般分系统进程、用户进程、或者内核进程等
  • 进程状态:运行、就绪、阻塞,表示进程现的运行情况
  • 优先级:表示获得CPU控制权的优先级大小
  • 通信信息:进程之间的通信关系的反映,由于操作系统会提供通信信道
  • 现场保护区:保护阻塞的进程用
  • 资源需求、分配控制信息
  • 进程实体信息,指明程序路径和名称,进程数据在物理内存还是在交换分区(分页)中
  • 其他信息:工作单位,工作区,文件信息等

作用

  • 进程控制块:进程控制块的作用是使一个在多道程序环境下不能独立运行的程序(包含数据),成为一个能独立运行的基本单位,一个能与其它进程并发执行的进程。
  • 程序段:是进程中能被进程调度程序在CPU上执行的程序代码段。
  • 数据段:一个进程的数据段,可以是进程对应的程序加工处理的原始数据,也可以是程序执行后产生的中间或最终数据

4. 进程间通信的方式,信号量有哪些,信号有哪些

  • 信号
  • 信号量
  • 管道
  • 有名管道
  • 无名管道
  • 消息队列
  • 共享内存
  • 套接字

牛客字节面经(07-14)

1.网络分层结构及协议

preview

2.http和https区别

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

3.https的传输过程

我们都知道 HTTPS 能够加密信息,以免敏感信息被第三方获取,所以很多银行网站或电子邮箱等等安全级别较高的服务都会采用 HTTPS 协议。

img

1、客户端发起 HTTPS 请求

这个没什么好说的,就是用户在浏览器里输入一个 https 网址,然后连接到 server 的 443 端口。

2、服务端的配置

采用 HTTPS 协议的服务器必须要有一套数字证书,可以自己制作,也可以向组织申请,区别就是自己颁发的证书需要客户端验证通过,才可以继续访问,而使用受信任的公司申请的证书则不会弹出提示页面(startssl 就是个不错的选择,有 1 年的免费服务)。

这套证书其实就是一对公钥和私钥,如果对公钥和私钥不太理解,可以想象成一把钥匙和一个锁头,只是全世界只有你一个人有这把钥匙,你可以把锁头给别人,别人可以用这个锁把重要的东西锁起来,然后发给你,因为只有你一个人有这把钥匙,所以只有你才能看到被这把锁锁起来的东西。

3、传送证书

这个证书其实就是公钥,只是包含了很多信息,如证书的颁发机构,过期时间等等。

4、客户端解析证书

这部分工作是有客户端的TLS来完成的,首先会验证公钥是否有效,比如颁发机构,过期时间等等,如果发现异常,则会弹出一个警告框,提示证书存在问题。

如果证书没有问题,那么就生成一个随机值,然后用证书对该随机值进行加密,就好像上面说的,把随机值用锁头锁起来,这样除非有钥匙,不然看不到被锁住的内容。

5、传送加密信息

这部分传送的是用证书加密后的随机值,目的就是让服务端得到这个随机值,以后客户端和服务端的通信就可以通过这个随机值来进行加密解密了。

6、服务端解密信息

服务端用私钥解密后,得到了客户端传过来的随机值(私钥),然后把内容通过该值进行对称加密,所谓对称加密就是,将信息和私钥通过某种算法混合在一起,这样除非知道私钥,不然无法获取内容,而正好客户端和服务端都知道这个私钥,所以只要加密算法够彪悍,私钥够复杂,数据就够安全。

7、传输加密后的信息

这部分信息是服务段用私钥加密后的信息,可以在客户端被还原。

8、客户端解密信息

客户端用之前生成的私钥解密服务段传过来的信息,于是获取了解密后的内容,整个过程第三方即使监听到了数据,也束手无策。

4.状态码

状态码 状态码英文名称 中文描述
100 Continue 继续。客户端应继续其请求
101 Switching Protocols 切换协议。服务器根据客户端的请求切换协议。只能切换到更高级的协议,例如,切换到HTTP的新版本协议
200 OK 请求成功。一般用于GET与POST请求
201 Created 已创建。成功请求并创建了新的资源
202 Accepted 已接受。已经接受请求,但未处理完成
203 Non-Authoritative Information 非授权信息。请求成功。但返回的meta信息不在原始的服务器,而是一个副本
204 No Content 无内容。服务器成功处理,但未返回内容。在未更新网页的情况下,可确保浏览器继续显示当前文档
205 Reset Content 重置内容。服务器处理成功,用户终端(例如:浏览器)应重置文档视图。可通过此返回码清除浏览器的表单域
206 Partial Content 部分内容。服务器成功处理了部分GET请求
300 Multiple Choices 多种选择。请求的资源可包括多个位置,相应可返回一个资源特征与地址的列表用于用户终端(例如:浏览器)选择
301 Moved Permanently 永久移动。请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替
302 Found 临时移动。与301类似。但资源只是临时被移动。客户端应继续使用原有URI
303 See Other 查看其它地址。与301类似。使用GET和POST请求查看
304 Not Modified 未修改。所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。客户端通常会缓存访问过的资源,通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源
305 Use Proxy 使用代理。所请求的资源必须通过代理访问
306 Unused 已经被废弃的HTTP状态码
307 Temporary Redirect 临时重定向。与302类似。使用GET请求重定向
400 Bad Request 客户端请求的语法错误,服务器无法理解
401 Unauthorized 请求要求用户的身份认证
402 Payment Required 保留,将来使用
403 Forbidden 服务器理解请求客户端的请求,但是拒绝执行此请求
404 Not Found 服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站设计人员可设置”您所请求的资源无法找到”的个性页面
405 Method Not Allowed 客户端请求中的方法被禁止
406 Not Acceptable 服务器无法根据客户端请求的内容特性完成请求
407 Proxy Authentication Required 请求要求代理的身份认证,与401类似,但请求者应当使用代理进行授权
408 Request Time-out 服务器等待客户端发送的请求时间过长,超时
409 Conflict 服务器完成客户端的 PUT 请求时可能返回此代码,服务器处理请求时发生了冲突
410 Gone 客户端请求的资源已经不存在。410不同于404,如果资源以前有现在被永久删除了可使用410代码,网站设计人员可通过301代码指定资源的新位置
411 Length Required 服务器无法处理客户端发送的不带Content-Length的请求信息
412 Precondition Failed 客户端请求信息的先决条件错误
413 Request Entity Too Large 由于请求的实体过大,服务器无法处理,因此拒绝请求。为防止客户端的连续请求,服务器可能会关闭连接。如果只是服务器暂时无法处理,则会包含一个Retry-After的响应信息
414 Request-URI Too Large 请求的URI过长(URI通常为网址),服务器无法处理
415 Unsupported Media Type 服务器无法处理请求附带的媒体格式
416 Requested range not satisfiable 客户端请求的范围无效
417 Expectation Failed 服务器无法满足Expect的请求头信息
500 Internal Server Error 服务器内部错误,无法完成请求
501 Not Implemented 服务器不支持请求的功能,无法完成请求
502 Bad Gateway 作为网关或者代理工作的服务器尝试执行请求时,从远程服务器接收到了一个无效的响应
503 Service Unavailable 由于超载或系统维护,服务器暂时的无法处理客户端的请求。延时的长度可包含在服务器的Retry-After头信息中
504 Gateway Time-out 充当网关或代理的服务器,未及时从远端服务器获取请求
505 HTTP Version not supported 服务器不支持请求的HTTP协议的版本,无法完成处理

5.一个url地址输入后的整个过程

img

6.进程线程协程

1.进程和线程的区别

进程——资源分配的最小单位,

线程——程序执行的最小单位。

协程是一种用户态的轻量级线程,协程的调度完全由用户控制。协程拥有自己的寄存器上下文和栈。协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈,直接操作栈则基本没有内核切换的开销,可以不加锁的访问全局变量,所以上下文的切换非常快。

协程与线程主要区别是它将不再被内核调度,而是交给了程序自己而线程是将自己交给内核调度。

1.实际意义的区别

(1)一个程序至少有一个进程,一个进程至少有一个线程。线程(Thread)是进程的一个实体,是CPU调度和分派的基本单位;

(2)进程拥有独立的内存单元,而多个线程共享内存。从而线程效率更高;

(3)进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮;

(4)进程切换时,耗费资源较大,效率要差一些;

(5)进程是系统资源分配的基本单位,线程是调度的基本单位。

2.比较进程线程的优点

(1)易于调度。

(2)提高并发性。通过线程可方便有效地实现并发性。进程可创建多个线程来执行同一程序的不同部分。

(3)开销少。创建线程比创建进程要快,所需开销很少。

(4)利于充分发挥多处理器的功能。

3.相比进程线程的缺点

(1)线程之间的同步和加锁控制比较麻烦

(2)一个线程的崩溃影响到整个程序的稳定性

(3)线程多了之后,线程本身的调度也是一个麻烦事儿,需要消耗较多的CPU

4.通讯的区别

(1)每个进程有自己的地址空间。两个进程中的地址即使值相同,实际指向的位置也不同。进程间通信一般通过操作系统的公共区进行。

同一进程中的线程因属同一地址空间,可直接通信。

(2)只有进程间需要通信,同一进程的线程share地址空间,没有通信的必要,但要做好同步/互斥mutex,保护共享的全局变量。线程拥有自己的栈。同步/互斥是原语primitives. 而进程间通信无论是信号,管道pipe还是共享内存都是由操作系统保证的,是系统调用.

(3)线程间通信:由于多线程共享地址空间和数据空间,所以多个线程间的通信是一个线程的数据可以直接提供给其他线程使用,而不必通过操作系统(也就是内核的调度)。进程间的通信则不同,它的数据空间的独立性决定了它的通信相对比较复杂,需要通过操作系统。以前进程间的通信只能是单机版的,现在操作系统都继承了基于套接字(socket)的进程间的通信机制。这样进程间的通信就不局限于单台计算机了,实现了网络通信。

5.切换和调度

线程上下文切换比进程上下文切换要快得多,在多线程程序下,进程不是一个可执行的实体

2.协程

协程是用户模式下的轻量级线程,最准确的名字应该叫用户空间线程(User Space Thread)

操作系统内核对协程一无所知,协程的调度完全有应用程序来控制,操作系统不管这部分的调度;

一个线程可以包含一个或多个协程,协程拥有自己的寄存器上下文和栈,协程调度切换时,将寄存器上下文和栈保存起来,在切换回来时恢复先前保运的寄存上下文和栈。

协程的优势如下:

  • 节省内存,每个线程需要分配一段栈内存,以及内核里的一些资源
  • 节省分配线程的开销(创建和销毁线程要各做一次 syscall)
  • 节省大量线程切换带来的开销
  • 与 NIO 配合实现非阻塞的编程,提高系统的吞吐

7.mysql一个select语句的执行过程

  1. 客户端(通常是你的服务)发出更新语句” update t set b = 200 where id = 2 “ 并向MySQL服务端建立连接;
  2. MySQL连接器负责和客户端建立连接,获取权限,维持和管理连接;
  3. MySQL拿到一个查询请求后,会先到查询缓存看看(MySQL8.x已经废弃了查询缓存),看之前是否已经执行过,如果执行过,执行语句及结果会以key-value形式存储到内存中,如果命中缓存会返回结果。如果没命中缓存,就开始真正执行语句。分析器会先做词法分析,识别出关键字update,表名等等;之后还会做语法分析,判断输入的语句是否符合MySQL语法;
  4. 经过分析器,MySQL已经知道语句是要做什么。优化器接着会选择使用哪个索引(如果多个表,会选择表的连接顺序);
  5. MySQL服务端最后一个阶段是执行器会调用引擎的接口去执行语句;
  6. 事务开始(任何一个操作都是事务),写undo log ,记录记录上一个版本数据,并更新记录的回滚指针和事务ID;
  7. 执行器先调用引擎取id=2这一行。id是主键,引擎直接用树搜索找到这一行;
    1. 如果id=2这一行所在的数据页本来就在内存 中,就直接返回给执行器更新;
    2. 如果记录不在内存,接下来会判断索引是否是唯一索引;
      1. 如果不是唯一索引,InnoDB会将更新操作缓存在change buffer中;
      2. 如果是唯一索引,就只能将数据页从磁盘读入到内存,返回给执行;
  8. 执行器拿到引擎给的行数据,把这个值加上1,比如原来是N,现在就是N+1,得到新的一行数据,再调用引擎接口写入这行新数据;
  9. 引擎将这行数据更新到内存中,同时将这个更新操作记录到redo log 里面;
  10. 执行器生成这个操作的binlogbinlog ;
  11. 执行器调用引擎的提交事务接口;
  12. 事务的两阶段提交:commit的prepare阶段:引擎把刚刚写入的redo log刷盘;
  13. 事务的两阶段提交:commit的commit阶段:引擎binlog刷盘。

8.redo log和 bing log区别

redo log binlog
文件大小 redo log 的大小是固定的。 binlog 可通过配置参数 max_binlog_size 设置每个binlog文件的大小。
实现方式 redo log InnoDB 引擎层实现的,并不是所有引擎都有。 binlog Server 层实现的,所有引擎都可以使用 binlog 日志
记录方式 redo log 采用循环写的方式记录,当写到结尾时,会回到开头循环写日志。 binlog通过追加的方式记录,当文件大小大于给定值后,后续的日志会记录到新的文件上
适用场景 redo log 适用于崩溃恢复(crash-safe) binlog 适用于主从复制和数据恢复

binlog redo log 的区别可知: binlog 日志只用于归档,只依靠 binlog 是没有 crash-safe能力的。但只有 redo log 也不行,因为 redo log InnoDB
特有的,且日志上的记录落盘后会被覆盖掉。因此需要 binlog redo log
二者同时记录,才能保证当数据库发生宕机重启时,数据不会丢失。

9.InnoDB和myISARM的区别

  • 一、InnoDB支持事务,MyISAM不支持,这一点是非常之重要。事务是一种高级的处理方式,如在一些列增删改中只要哪个出错还可以回滚还原,而MyISAM就不可以了。
  • 二、MyISAM适合查询以及插入为主的应用,InnoDB适合频繁修改以及涉及到安全性较高的应用
  • 三、InnoDB支持外键,MyISAM不支持
  • 四、MySQL 在 5.1 之前版本默认存储引擎是 MyISAM,5.1 之后版本默认存储引擎是 InnoDB
  • 五、InnoDB不支持FULLTEXT类型的索引
  • 六、InnoDB中不保存表的行数,如select count() from table时,InnoDB需要扫描一遍整个表来计算有多少行,但是MyISAM只要简单的读出保存好的行数即可。注意的是,当count()语句包含where条件时MyISAM也需要扫描整个表
  • 七、对于自增长的字段,InnoDB中必须包含只有该字段的索引,但是在MyISAM表中可以和其他字段一起建立联合索引
  • 八、清空整个表时,InnoDB是一行一行的删除,效率非常慢。MyISAM则会重建表
  • 九、InnoDB支持行锁(某些情况下还是锁整表,如 update table set a=1 where user like ‘%lee%’