JAVA八股文面经问题整理第8弹

文章目录

提问问题

  1. 笔试题:n皇后问题
  2. 笔试题:求一颗二叉搜索树中的众数
  3. TCP与UDP的概念,特点,区别和对应的使⽤场景?
  4. HTTP请求常⻅的状态码和字段
  5. 常⻅的请求⽅式?GET和POST请求的区别?
  6. 什么是虚拟内存?为什么需要虚拟内存?
  7. 什么是内存分段和分⻚?作⽤是什么?
  8. 说⼀说事物隔离级别?
  9. 什么时候需要创建索引
  10. 什么时候不需要创建索引?

问题1

利用回溯法解决,代码如下;具体思路看回溯法解n皇后

class Solution {
    List<List<String>> res = new ArrayList<>();//结果列表

    public List<List<String>> solveNQueens(int n) {
        char[][] chessboard = new char[n][n];
        for (char[] c : chessboard) {
            Arrays.fill(c, '.');
        }
        backTrack(n, 0, chessboard);
        return res;
    }


    public void backTrack(int n, int row, char[][] chessboard) {
        if (row == n) {//叶子节点
            res.add(Array2List(chessboard));
            return;
        }

        for (int col = 0;col < n; ++col) {
            if (isValid (row, col, n, chessboard)) {
                chessboard[row][col] = 'Q';
                backTrack(n, row+1, chessboard);
                chessboard[row][col] = '.';
            }
        }

    }


    public List Array2List(char[][] chessboard) {//处理结果
        List<String> list = new ArrayList<>();

        for (char[] c : chessboard) {
            list.add(String.copyValueOf(c));
        }
        return list;
    }


    public boolean isValid(int row, int col, int n, char[][] chessboard) {//检查是否合法
        // 检查列
        for (int i=0; i<row; ++i) { // 相当于剪枝
            if (chessboard[i][col] == 'Q') {
                return false;
            }
        }

        // 检查45度对角线
        for (int i=row-1, j=col-1; i>=0 && j>=0; i--, j--) {
            if (chessboard[i][j] == 'Q') {
                return false;
            }
        }

        // 检查135度对角线
        for (int i=row-1, j=col+1; i>=0 && j<=n-1; i--, j++) {
            if (chessboard[i][j] == 'Q') {
                return false;
            }
        }
        return true;
    }
}

问题2

二叉树的经典题目,代码如下;具体思路看二叉搜素树求众数

class Solution {
    ArrayList<Integer> resList;//结果集
    int maxCount;//最大出现频次
    int count;//当前节点频次
    TreeNode pre;//用来比较节点值是否相同
 
    public int[] findMode(TreeNode root) {
        resList = new ArrayList<>();
        maxCount = 0;
        count = 0;
        pre = null;//初始为空
        findMode1(root);
        int[] res = new int[resList.size()];
        for (int i = 0; i < resList.size(); i++) {
            res[i] = resList.get(i);
        }
        return res;
    }
 
    public void findMode1(TreeNode root) {
        if (root == null) {
            return;
        }
        findMode1(root.left);
 
        int rootValue = root.val;
       
        if (pre == null || rootValue != pre.val) { // 计数
            count = 1;
        } else {
            count++;
        }
 
        // 更新结果以及maxCount
        if (count > maxCount) {
            resList.clear();//清空失效的结果集
            resList.add(rootValue);//加入新的结果
            maxCount = count;
        } else if (count == maxCount) {
            resList.add(rootValue);
        }
        pre = root;
 
 
        findMode1(root.right);
    }
}

问题3

 TCP(传输控制协议)和UDP(用户数据报协议)是互联网协议套件(Internet Protocol Suite)中的两种主要传输层协议,它们定义了数据如何在网络中的不同设备之间进行传输

TCP特点:
- 面向连接:在数据传输前必须在通信双方建立连接。
- 可靠传输:通过序号和确认机制确保数据正确无误地按序到达。
- 流量控制:通过窗口机制防止发送方过快发送数据导致接收方来不及处理。
- 拥塞控制:能够检测网络拥塞并相应地调整数据发送速率。
- 全双工通信:支持数据同时双向传输。

UDP特点:
- 无连接:发送数据前不需要建立连接。
- 不可靠传输:不保证数据包的顺序、完整性或可靠到达。
- 无流量和拥塞控制:发送方不会根据网络状况调整数据发送速率。
- 轻量级:头部开销较小,开销仅有8字节,适合高速传输。
- 广播和多播支持:能够同时向多个接收者发送相同的数据。

TCP与UDP的区别:
连接性:
TCP是面向连接的,而UDP是无连接的。
可靠性:TCP提供可靠的数据传输服务,UDP不保证。
头部开销:TCP的头部开销较大,UDP较小。
顺序性:TCP保证数据按序传输,UDP不保证。
数据流量控制:TCP有流量控制和拥塞控制,UDP没有。
使用场景:TCP适合对数据传输质量要求较高的应用,如HTTP、FTP、SMTP等;UDP适合对实时性要求高但可以容忍一定丢包的应用,如VoIP、视频会议、在线游戏等。


问题4

 HTTP状态码是由三位数字组成,用来表示服务器响应请求的状态。

以下是一些常见的HTTP状态码及其含义:

  • `200 OK`:请求已成功,响应消息体中包含了请求的资源。
  • `201 Created`:请求已被实现,并且创建了新的资源。
  •  `204 No Content`:请求已成功,但响应消息体中不包含任何内容。
  •  `301 Moved Permanently`:请求的资源已被永久移动到新位置,响应中将包含新的URL。
  • `302 Found`:请求的资源临时移动到了其他URL,浏览器会跟踪这个临时位置。
  • `304 Not Modified`:资源未修改,可以使用缓存的版本。
  • `400 Bad Request`:服务器无法理解请求格式,客户端不应该尝试再次提交相同的请求。
  • `401 Unauthorized`:请求未经授权。通常需要用户认证。
  •  `403 Forbidden`:服务器理解请求客户端的请求,但是拒绝执行此请求。
  • `404 Not Found`:服务器找不到请求的资源。
  •  `500 Internal Server Error`:服务器遇到错误,无法完成请求。

HTTP响应中还包含一些重要的字段,这些字段通常位于HTTP响应头部(Status-Line之后):

  • Date:消息发送的日期和时间。
  • Server:处理请求的HTTP服务器软件及其版本。
  • Content-Type:响应体的媒体类型,例如text/htmlapplication/json等。
  • Content-Length:响应体的长度,以字节为单位。
  • Set-Cookie:由服务器设置客户端的cookie。
  • Location:用于重定向的URL。
  • Cache-Control:指示缓存指令,如max-age=300表示资源可以缓存300秒。
  • Expires:响应过期的日期和时间。
  • Last-Modified:资源最后修改的日期和时间。
  • ETag:资源的特定版本标识符,用于缓存验证。


问题5

 HTTP请求方法定义了客户端可以对服务器执行的操作。以下是一些常用的HTTP请求方法

  • GET:用于请求服务器发送指定资源。通常用于请求数据,如网页内容。
  • POST:用于向服务器提交数据进行处理,例如表单数据的提交。
  • PUT:用于上传资源到指定的URI。
  • DELETE:用于请求服务器删除指定的资源。
  • HEAD:类似于GET,但服务器在响应中只返回头部信息,不返回实体主体部分。
  • OPTIONS:用于获取目的资源所支持的通信选项。
  • PATCH:用于对资源进行部分更新。

GET和POST请求的区别主要包括以下几点:

1. 数据传输方式:GET请求将数据附加在URL之后,通过URL传递,数据可见且有长度限制;POST请求将数据放在HTTP请求的body中,数据不在URL中显示,没有长度限制

2. 安全性:POST比GET更安全,因为POST的数据不会显示在URL中,不易被保存和缓存。

3. 缓存:GET请求结果可以被浏览器缓存,而POST请求一般不会被缓存

4. 可重复性:GET请求可重复提交,而POST请求通常不建议这样做,因为可能导致同一资源被多次处理。

5. 应用场景:GET适用于获取数据,如网页浏览;POST适用于提交要被处理的数据,如表单提交、文件上传等。

6. 影响服务器状态:GET请求是幂等的,即多次执行相同的GET请求,资源状态不变;POST请求非幂等,执行多次可能会创建额外的资源或导致副作用。


问题6

虚拟内存是一种计算机系统内存管理技术,它允许操作系统使用硬盘空间作为临时的RAM(随机存取存储器)使用。在虚拟内存系统中,每个运行的程序都认为它拥有一大块连续的地址空间,即所谓的虚拟地址空间,而实际上这块空间可能被分割成多个物理内存碎片和硬盘上的交换文件。

虚拟内存的引入主要是为了解决以下问题

1. 物理内存限制:随着应用程序对内存需求的增加,物理内存(RAM)可能不足以满足所有程序的需求。虚拟内存通过使用硬盘空间来扩展可用内存,从而允许更多的程序同时运行。

2. 内存碎片:物理内存可能会因为频繁的内存分配和释放而产生大量的小碎片,这些碎片会降低内存的使用效率。虚拟内存抽象了物理内存的细节,使得操作系统可以更有效地管理内存。

3. 简化编程模型:虚拟内存为每个程序提供了一个连续的地址空间,这简化了程序设计和内存管理,因为程序员不需要担心实际物理内存的布局和限制。

4. 保护机制:虚拟内存可以实现内存隔离,确保一个程序的操作不会影响到其他程序的内存空间,从而提高系统的稳定性和安全性。

虚拟内存的关键技术包括分页(paging)和分段(segmentation)分页将虚拟地址空间和物理内存均划分为固定大小的块(页),而分段则根据逻辑结构划分数据块(段)。现代操作系统通常结合使用这两种技术来实现虚拟内存。

然而,虚拟内存也有其缺点,特别是当频繁访问硬盘上的虚拟内存时,会导致性能下降,这种现象称为“页面交换”(page swapping)或“页面抖动”(thrashing)。因此,虽然虚拟内存提供了灵活的内存管理和扩展能力,但它也依赖于足够快的硬盘和良好的内存管理策略来维持系统性能。


问题7

内存分段(Segmentation)和分页(Paging)是操作系统中用来管理虚拟内存的两种主要技术

内存分段按照程序的逻辑结构来划分内存,例如代码段、数据段、堆栈段等。每个段有自己的起始地址和长度,可以是不连续的物理内存块。分段的优点是可以更好地反映程序的逻辑结构,便于实现内存保护和共享。每个段可以独立地控制访问权限,而且可以支持动态链接和程序的模块化

分页则是将虚拟地址空间和物理内存均等划分为固定大小的块,这些块称为页(Page)和帧(Frame)。页和帧的大小是一样的,通常为几千字节。分页的优点在于它简化了内存的管理,因为内存的分配和回收只需要考虑页的大小,而不需要关心具体的物理内存布局。此外,分页减少了外部碎片,提高了内存的利用率

在实际的操作系统设计中,经常会将分段和分页结合起来使用,形成了段页式内存管理(Segmented Page)。这种方式既保留了分段的优点,又利用了分页的高效管理特性。在段页式内存管理中,首先按照程序的逻辑结构将虚拟地址空间分成若干逻辑段,然后再将每个逻辑段细分成固定大小的页。这样,操作系统可以通过段表来管理各个逻辑段的基址和界限,通过页表来管理各个页到物理帧的映射。这种方法既提供了灵活的内存管理,又保持了较高的性能。


问题8

当数据库上有多个事务同时执⾏的时候,就可能出现脏读(dirty read)、不可重复读(non-
repeatable read)、幻读(phantom read)
的问题,为了解决这些问题,就有了“隔离级别”的概
念。
SQL标准的事务隔离级别包括:读未提交(read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串⾏化(serializable )

  • 读未提交是指,⼀个事务还没提交时,它做的变更就能被别的事务看到。
  • 读提交是指,⼀个事务提交之后,它做的变更才会被其他事务看到。
  • 可重复读是指,⼀个事务执⾏过程中看到的数据,总是跟这个事务在启动时看到的数据是⼀致的。当然在可重复读隔离级别下,未提交变更对其他事务也是不可⻅的。
  • 串⾏化,顾名思义是对于同⼀⾏记录,“写”会加“写锁”,“读”会加“读锁”。当出现读写锁冲突的时候,后访问的事务必须等前⼀个事务执⾏完成,才能继续执⾏。


问题9

什么时候需要创建索引

  1. 表的主关键字:⾃动建⽴唯⼀索引
  2. 直接条件查询的字段:经常⽤于WHERE查询条件的字段,这样能够提⾼整个表的查询速度
  3. 查询中与其它表关联的字段:例如字段建⽴了外键关系
  4. 查询中排序的字段:排序的字段如果通过索引去访问将⼤⼤提⾼排序速度
  5. 唯⼀性约束列: 如果某列具有唯⼀性约束,那么为了确保数据的唯⼀性,可以在这些列上创建唯⼀索引。
  6. ⼤表中的关键列: 在⼤表中,如果查询的效率变得很低,可以考虑在关键列上创建索引。

问题10

什么时候不需要创建索引

  1. ⼩表: 对⼩表创建索引可能会带来额外的开销,因为在⼩数据集中扫描整个表可能⽐使⽤索引更快。
  2. 频繁的插⼊、更新和删除操作: 索引的维护成本会随着数据的插⼊、更新和删除操作⽽增加。如果表经常被修改,过多的索引可能会影响性能。
  3. 数据重复且分布平均的表字段:假如⼀个表有10万⾏记录,性别只有男和⼥两种值,且每个值的
  4. 分布概率⼤约为50%,那么对这种字段建索引⼀般不会提⾼数据库的查询速度。
  5. 很少被查询的列: 如果某列很少被⽤于查询条件,那么为它创建索引可能没有明显的性能提升。
  6. 查询结果总⾏数较少的表: 如果查询的结果集总⾏数很少,使⽤索引可能不会有太⼤的性能提升。

写在最后

PS:以上是网络上收集的一些常见的问题以及自己对答案搜索整理;一次整理基本上就是面试一次的题量,适合对自己的知识的查缺补漏

面试一般根据岗位要求或者简历上写的来进行扩展提问,也有些是直接问公司常用到的相关方面的技术问题,无论怎么准备都祝大家能拿到心怡的offer!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值