面试遇见的问题总结

说一说你对volatile关键字的理解

标准回答

volatile用于保证内存的可见性,可以将其看做是轻量级的锁,它具有如下的内存语义:

  • 写内存语义:当写一个volatile变量时,JMM会把该线程本地内存中的共享变量的值刷新到主内存中。
  • 读内存语义:当读一个volatile变量时,JMM会把该线程本地内存置为无效,使其从主内存中读取共享变量。

其中,JMM是指Java内存模型,而本地内存只是JMM的一个抽象概念,它涵盖了缓存、写缓冲区、寄存器以及其他的硬件和编译器优化。在本文中,大家可以将其简单理解为缓存。

volatile只能保证单个变量读写的原子性,而锁则可以保证对整个临界区的代码执行具有原子性。所以,在功能上锁比volatile更强大,在可伸缩性和性能上volatile更优优势。

加分回答

volatile的底层是采用内存屏障来实现的,就是在编译器生成字节码时,会在指令序列中插入内存屏障来禁止特定类型的处理器重排序。内存屏障就是一段与平台相关的代码,Java中的内存屏障代码都在Unsafe类中定义,共包含三个方法:LoadFence()、storeFence()、fullFence()。

请你说一说epoll原理

通过epoll_create生成一个存储结构称之为epoll对象, 主要包含两个属性, 其一是用来保存当前待检测文件描述符的红黑树, 其二是检测到状态发生变化的文件描述符的双向链表.

通过epoll_ctrl函数可以向epoll对象中插入, 修改, 删除待检测的文件描述符.

通过epoll_wt可以让系统自动监控文件描述符的状态, 将需要发生IO操作的文件描述符整合到一起, 通过返回的文件描述符数组做进一步事件处理.

具体的操作原理有两种方式: 水平触发 与 边沿触发

其中水平触发为缺省的工作模式, 分为阻塞与非阻塞两种工作方式, 当检测到文件描述符状态发生改变时, 系统会直接发送一个通知, 即使没有做任何IO操作, 系统还是会继续通知.

边沿触发是另一种高效的工作模式, 只要非阻塞的工作方式, 当检测到文件描述符状态发生改变时, 系统会假定已经知道文件描述符发生改变, 并且不会继续发送更多的通知, 除非人为操作了IO操作使该文件描述符的状态发生改变, 否则系统仅通知一次, 避免了水平工作模式下的多次重复通知而浪费系统资源, 性能更加优异, 但只能采用非阻塞的工作方式.

介绍一下SQL中的聚合函数

常用的聚合函数有COUNT()、AVG()、SUM()、MAX()、MIN()。

  1. COUNT()函数:统计数据表中包含的记录行的总数,或者根据查询结果返回列中包含的数据行数。
    • COUNT(*)计算表中总的行数,不管某列是否有数值或者为空值。
    • COUNT(字段名)计算指定列下总的行数,计算时将忽略空值的行。
  2. AVG()函数:通过计算返回的行数和每一行数据的和,求得指定列数据的平均值。
  3. SUM()函数:是一个求总和的函数,返回指定列值的总和。
  4. MAX()函数:返回指定列中的最大值,不仅适用于查找数值类型,也可应用于字符类型。
  5. MIN()函数:返回查询列中的最小值,不仅适用于查找数值类型,也可应用于字符类型。

此外,聚合函数可以与GROUP BY关键字一起使用,对每个分组进行计算。

UDP协议的特点有哪些?

1、 无连接性: UDP是一种无连接的协议,发送端在发送数据之前不需要与接收端建立连接。

2、 面向数据报:UDP将应用层交给它的数据进行分割,并在每个数据上加上源端口号和目标端口号的首部信息

3、 不可靠性:UDP协议不提供可靠交付机制,它不保证数据报的可靠性、顺序性、不重复性。

4、高效性: UDP没有建立连接和维护状态的开销,使用UDP具有较小的数据报头部,以及较低的通信延迟。

5、支持一对一、一对多、多对多的通信。

6、无阻塞控制: UDP协议没有内置的拥塞控制机制,因此发送端会一直以恒定的速率发送数据

创建线程有哪几种方式?

继承Thread类创建线程:

- 定义Thread类的子类,并重写该类的run方法,该run方法的方法体就代表了线程要完成的任务。因此把run()方法成为执行体
- 创建Thread子类的实例也就是创建了线程对象
- 调用线程对象的start()方法来启动线程

通过Runnable接口创建线程类:

- 定义runnable接口的实现类,并重写该接口的run()方法,该run()方法的方法体同样是该线程的线程执行体
- 创建Runnable实现类的实例,并依此实例作为Thread的target来创建Thread对象,该Thread对象才是真正的线程对象
- 调用线程对象的start()方法来启动该线程

通过Callable和Future创建对象:

- 创建Callable接口的实现类,并实现call()方法,该call()方法将作为线程的执行体,并且有返回值
- 创建Callable实现类的实例,使用FutureTask类来包装Callable对象,该FutrueTask对象封装了该Callable对象的call()方法的返回值
- 使用FutureTask对象作为Thread对象的target创建并启动新线程
- 调用FutureTask对象的get()方法来获得子线程执行结束后的返回值

DNS(域名系统)是什么?

DNS(Domain Name System)是一种用于将域名转换为与之关联的IP地址的系统。它是互联网中的一项基础设施,使得用户可以使用容易记忆的域名(例如www.baidu.com)来访问网站,而不需要记住复杂的IP地址(202.108.22.5)。DNS系统由一组分布在全球各地的DNS服务器组成,它们相互协作,将域名解析为相应的IP地址。当用户在浏览器中输入域名时,浏览器会向本地DNS服务器发送请求,本地DNS服务器会向根DNS服务器查询域名的IP地址,并将结果返回给浏览器,浏览器再使用该IP地址连接到相应的网站。

说一说虚拟地址空间有哪些部分 ?

用户空间、内核空间、栈空间、堆空间、代码段、BSS段、DATA段

标准回答

32位系统中,虚拟地址空间为 0 ~ 4G,将最高的 1G 字节(从虚拟地址 0xC0000000 到 0xFFFFFFFF),供内核使用,称为内核空间,将较低的 3G 字节(从虚拟地址 0x00000000 到 0xBFFFFFFF),供各个进程使用,称为用户空间,虚拟地址空间分布如下图:
在这里插入图片描述

  1. 内核空间

    存放内核的代码和数据,所有进程的内核代码段都映射到同样的物理内存,并在内存中持续存在,是操作系统的一部分。内核空间为内核保留,不允许应用程序读写该区域的内容或直接调用内核代码定义的函数。

  2. 用户空间

    用户空间给各个进程使用,也称为使用者空间。用户空间中的代码运行在较低的特权级别上,只能看到允许它们使用的部分系统资源,并且不能使用某些特定的系统功能,也不能直接访问内核空间和硬件设备,以及其他一些具体的使用限制。用户空间又大致细分为下列一些空间:

    • 栈空间
    • 共享区
    • 堆空间
    • BSS 段(未初始化数据段)
    • DATA 段(已初始化数据段)
    • TEXT 段(代码段)
    • 保留区
    延伸阅读

    用户空间:

    1. 栈空间

      栈又称堆栈,由编译器自动分配释放,行为类似数据结构中的栈(先进后出)。存储局部变量、函数参数值。栈从高地址向低地址增长,是一块连续的空间。

    2. 共享区

      内存映射以及共享库(动态库)所在的内存。

    3. 堆空间

      堆用于存放进程运行时动态分配的内存段,可动态扩张或缩减。堆从低地址向高地址增长。通过 new() 或者 malloc() 函数可以在堆区开辟空间。

    4. BSS 段(未初始化数据段)

      BSS(Block Started by Symbol)段中通常存放程序中以下符号:

      • 未初始化的全局变量和静态局部变量
      • 初始值为 0 的全局变量和静态局部变量(依赖于编译器实现)
    5. DATA 段(已初始化数据段)

      数据段通常用于存放程序中已初始化且初值不为 0 的全局变量和静态局部变量。

    6. TEXT 段(代码段)

      代码段也称正文段或文本段,通常用于存放程序执行代码(即CPU执行的机器指令)。

    7. 保留区

      位于虚拟地址空间的最低部分,未赋予物理地址。任何对它的引用都是非法的,用于捕捉使用空指针和小整型值指针引用内存的异常情况。

什么是MVC?

MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范。

用一种业务逻辑、数据、界面显示分离的方法,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。MVC被独特的发展起来用于映射传统的输入、处理和输出功能在一个逻辑的图形化用户界面的结构中。

谈谈InnoDB引擎中的锁

在InnoDB存储引擎中,锁是实现并发控制和事务隔离的重要机制之一。InnoDB引擎提供了多种锁类型,包括共享锁、排他锁和意向锁等。

  1. 共享锁(Shared Lock):允许多个事务同时读取同一行数据,但是不允许对该行数据进行修改。当一个事务持有共享锁时,其他事务可以获取共享锁,但是不能获取排他锁。多个事务可以同时持有共享锁,不会互相阻塞。
  2. 排他锁(Exclusive Lock):只允许一个事务独占一行数据,其他事务不能获取共享锁或排他锁,直到该事务释放排他锁。当一个事务持有排他锁时,其他事务无法获取任何类型的锁,必须等待该事务释放锁。
  3. 意向锁(Intention Lock):用于协调共享锁和排他锁之间的竞争。当一个事务获取共享锁或排他锁时,必须先获取对应的意向锁。意向锁是一种轻量级锁,不会阻塞其他事务的读取操作,只会阻塞其他事务的修改操作。

InnoDB引擎中还有其他类型的锁,例如行锁、表锁和间隙锁等,它们也都有各自的特点和应用场景。在实际开发中,需要根据具体的需求选择合适的锁类型,以保证并发控制和事务隔离的正确性和性能。

说一说 Linux 如何管理内存

标准回答

Linux 操作系统是采用段页式内存管理方式:

页式存储管理能有效地提高内存利用率(解决内存碎片),而分段存储管理能反映程序的逻辑结构并有利于段的共享。将这两种存储管理方法结合起来,就形成了段页式存储管理方式。

段页式存储管理方式即先将用户程序分成若干个段,再把每个段分成若干个页,并为每一个段赋予一个段名。在段页式系统中,为了实现从逻辑地址到物理地址的转换,系统中需要同时配置段表和页表,利用段表和页表进行从用户地址空间到物理内存空间的映射。

系统为每一个进程建立一张段表,每个分段有一张页表。段表表项中至少包括段号、页表长度和页表始址,页表表项中至少包括页号和块号。在进行地址转换时,首先通过段表查到页表始址,然后通过页表找到页帧号,最终形成物理地址。

在这里插入图片描述

OSI七层模型

7.应用层

6.表示层

5.会话层

4.传输层

3.网络层

2.数据链路层

1.物理层

UDP协议的首部结构?

UDP首部有8个字节,由4个字段构成,每个字段都是两个字节
1.源端口号: 可有可无,需要对方回信时选用,不需要时全部置0。
2.目的端口号:必须有,在终点交付报文的时候需要用到。
3.长度:UDP的数据报的长度(包括首部和数据)其最小值为8字节(只有首部)。
4.传输层

3.网络层

2.数据链路层

1.物理层

UDP协议的首部结构?

UDP首部有8个字节,由4个字段构成,每个字段都是两个字节
1.源端口号: 可有可无,需要对方回信时选用,不需要时全部置0。
2.目的端口号:必须有,在终点交付报文的时候需要用到。
3.长度:UDP的数据报的长度(包括首部和数据)其最小值为8字节(只有首部)。
4.校验和:检测UDP数据报在传输中是否有错,有错则丢弃。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值