好未来25校招Web前端开发工程师部分笔试题解析

发布于:2025-03-23 ⋅ 阅读:(42) ⋅ 点赞:(0)

单选题

1.假设你有一个包含N个元素的数组,你想要找到数组中最大的两个数。以下哪种方法的时间复杂度最低?( D )

A.对数组进行排序,然后返回最后两个元素

B.使用两次嵌套循环比较所有可能的元素对,找到最大的两个数

C.先遍历一次数组找到最大值,再遍历一次去除最大值后的数组找到第二大的值

D.遍历数组一次,同时追踪最大值和次大值

2.下列哪种数组的方法不会修改数组本身?(A)

A. slice

B. splice

C. sort

D. unshift

3.下列更适合使用Object而不是Map的场景的是(A)

A.将数据结构序列化为JSON

B.可能是除字符串和Symbol外的其他类型

C.频繁进行增删操作

D.需要进行复杂的遍历操作

解析

Object更适合用于简单的数据存储和JSON序列化,特别是当键是字符串且数据结构相对静态时。

Map更适合用于需要键的类型多样、频繁进行增删操作以及需要更灵活的遍历的场景。

4.给定一个整数数组nums和一个整数k,请编写一个函数来返回该数组中第k大的元素。你可以假设k总是有效的,并且1≤k≤数组的长度。( C )

A.对数组进行排序,然后返回排序后数组的第k个最大值

B.使用一个小顶堆(优先队列)来维护数组中的前k个最大元素

C.使用快速选择算法,它是快速排序的变种,在平均情况下能在O(n)时间内找到第k大的元素

D.遍历数组并使用计数排序的方法来统计每个数字出现的次数,然后根据这些统计结果找出第k大的元素

5.在建立TCP连接时,使用了三次握手协议。以下哪个步骤不是三次握手的一部分?(D)

A.客户端发送SYN包

B.服务端返回SYN-ACK包

C.客户端发送ACK包

D.客户端发送FIN包

解析

第一次握手:客户端发送一个带有SYN标志的数据包,请求建立连接(SYN包)。

第二次握手:服务器收到客户端的SYN包后,回应一个SYN-ACK包,表示同意建立连接并确认收到SYN包。

第三次握手:客户端收到服务器的SYN-ACK包后,再发送一个ACK包向服务器确认。至此,连接建立成功。

6.以下哪种技术允许浏览器从同一个域名请求多个资源,而无需为每个资源建立新的TCP连接?(C )

A. HTTP/1.0

B. HTTP/1.1持久连接(Persistent Connections)

C. HTTP/2多路复用(Multiplexing)

D. WebSockets

解析

HTTP/1.1 持久连接仅支持顺序处理多个请求(复用同一个 TCP 连接,但无法并发)。

HTTP/2多路复用通过二进制分帧实现真正并发(多个请求/响应可交错传输)。

多选题

1.以下哪些描述正确地反映了浏览器、网络和CDN的工作原理?(ABC)

A.CDN(内容分发网络)通过将内容缓存到多个地理位置的服务器上来加速内容交付。

B.浏览器在发送HTTP请求时,会首先检查本地缓存是否有对应的资源。

C.使用CDN可以减少服务器的负载并提高网站的可用性。

D.浏览器在解析HTML文档时,会阻塞渲染,直到所有外部JavaScript文件加载完成。

E.CDN只能用于静态内容的分发,动态内容无法通过CDN加速。

编程题

1.反转单向链表(leetcode206)

迭代法
    public ListNode reverseList(ListNode head) {
        ListNode prev = null;  // 指向前一个节点,初始为 null
        ListNode curr = head;  // 指向当前节点,初始为 head

        while (curr != null) {
            ListNode next = curr.next; // 保存下一个节点,因为稍后要修改 curr.next
            curr.next = prev;   // 将当前节点的 next 指针指向前一个节点,实现反转

            prev = curr;     // 将 prev 移动到当前节点
            curr = next;     // 将 curr 移动到下一个节点
        }

        return prev;  // 循环结束后,prev 指向的就是反转后的头节点
    }
递归法
public ListNode reverseList(ListNode head) {
        // 递归终止条件:链表为空或者只有一个节点
        if (head == null || head.next == null) {
            return head;
        }

        // 递归调用,反转 head.next 开始的链表
        ListNode newHead = reverseList(head.next);

        // 反转当前节点
        head.next.next = head;  // 将 head.next 的 next 指针指向 head
        head.next = null;     // 将 head 的 next 指针指向 null,防止循环链表

        return newHead;    // 返回反转后的头节点
    }

2.最小时差:(leetcode539)

给定一个24小时制(小时:分钟 "HH:MM”)的时间列表,找出列表中任意两个时间的最小时间差并以分钟数表示。

示例1

输入

[“23:59”,“00:00”]

输出

1

示例2

输入

[“00:00”,“23:59”, “00:00”]

输出

0

题解
public int findMinDifference(List<string> timePoints) {
        // 鸽巢原理优化:如果时间点的数量超过 1440 (一天的总分钟数),
        // 那么必定存在重复的时间点,最小时间差为 0
        if (timePoints.size() &gt; 1440) {
            return 0;
        }
        // 创建一个 HashSet 来存储已经出现的时间(以分钟为单位)。
        Set<integer> timeSet = new HashSet&lt;&gt;();
        // 创建一个 ArrayList 来存储转换后的时间(以分钟为单位)。
        List<integer> minutes = new ArrayList&lt;&gt;();
        // 遍历输入的字符串列表 (timePoints),将每个时间字符串转换为分钟
        for (String time : timePoints) {
            String[] parts = time.split(":");

            int hour = Integer.parseInt(parts[0]);

            int minute = Integer.parseInt(parts[1]);

            int totalMinutes = hour * 60 + minute;
            // 发现重复的时间点,直接返回 0
            if (timeSet.contains(totalMinutes)) {
                return 0;
            }
            // 将当前时间添加到 HashSet 中,标记为已出现
            timeSet.add(totalMinutes);
            // 将当前时间添加到 ArrayList 中,用于后续排序和计算
            minutes.add(totalMinutes);
        }
        // 对存储分钟的 ArrayList 进行升序排序
        Collections.sort(minutes);
        // 初始化最小时间差为最大整数值,以便后续比较和更新
        int minDiff = Integer.MAX_VALUE;
        
        for (int i = 1; i &lt; minutes.size(); i++) {
            // 遍历排序后的分钟列表,计算相邻时间点的时间差,
            // 并与当前最小时间差比较,更新 minDiff
            minDiff = Math.min(minDiff, minutes.get(i) - minutes.get(i - 1));
        }

        // 计算第一个时间和最后一个时间的差值 (考虑跨天的情况),1440 是一天的总分钟数
        // 这一步是为了解决 "00:00" 和 "23:59" 之间的时间差问题
        int headTailDiff = minutes.get(0) + 1440 - minutes.get(minutes.size() - 1);

        // 将首尾时间差与当前的最小时间差比较,更新 minDiff
        minDiff = Math.min(minDiff, headTailDiff);
        // 返回计算得到的最小时间差
        return minDiff;
        
    }