网易雷火笔试 网易雷火笔试题 0911

笔试时间:2024年09月11日 秋招

历史笔试传送门:2023秋招笔试合集

第一题

题目

游戏玩法相关的数值数据一股来说会披放在一个叫配置表的地方。配置表样表如下:1 today 2 is 3 good 4 day。约定:第一列为主键列(id列,唯一,从上到下保持升序)第二列为值列,所谓的差异比对就是比对的新旧两张表相同id行的值游戏的每一个版本更新,策划都会对配置表中的数据进行修改以通应游戏玩法的变化,为了避免乘划因人为失误导致配置表错误修改,需要对配置表每次变更内容都做审核,基于这个场景,请设计一个新旧配置表差异比对的程序,将左表(旧表)和右表(新表)进行差异比对,返回两张表的新增修改/删除行的信息。这个程序包含了4个入参,分别对应左表(旧日表)和右表(新表)的主键列和值列,第1个参数是左表的主健列表,第2个参数是左表的值列表,第3个参数是右表的主健列表,第4个参数是右表的值列表。出参是个双层的列表,内部包含了3个列表,第1个列表是新增行id列表,第2个列表是修改行id列表,第3个列表是删除行id列表,这3个列表均按id开序排例列。

样例输入

[1,2],["nowcoder","best"],[1,2],["nowcoder","great"]

样例输出

[[],[2],[]]

说明:在这个样例中,无数据新增,所以返回值第一个列表为空,id=2的数据行被修改了,所以返回值第二个列表是[2],无数据删除,所以返回值第三个列表为空。

参考题解

使用两个哈希表分别存储左表和右表的主键和值的对应关系,方便快速查找和比较。遍历新表的主键列,找出新增和修改的行。遍历旧表的主键列,找出删除的行。

C++:[此代码未进行大量数据的测试,仅供参考]

#include <iostream>
#include <vector>
#include <map>
#include <algorithm>

using namespace std;

vector<vector<long>> compareConfigs(vector<long> oldIds, vector<string> oldValues, vector<long> newIds, vector<string> newValues) {
    // 存储旧表和新表的数据
    map<long, string> oldTable;
    map<long, string> newTable;
    vector<long> addedRows;
    vector<long> modifiedRows;
    vector<long> deletedRows;

    for (int i = 0; i < oldIds.size(); i++) {
        oldTable[oldIds[i]] = oldValues[i];
    }

    for (int i = 0; i < newIds.size(); i++) {
        newTable[newIds[i]] = newValues[i];
    }

    for (auto id : newIds) {
        if (oldTable.find(id) == oldTable.end()) {
            addedRows.push_back(id);
        } else if (newTable[id] != oldTable[id]) {
            modifiedRows.push_back(id);
        }
    }

    for (auto id : oldIds) {
        if (newTable.find(id) == newTable.end()) {
            deletedRows.push_back(id);
        }
    }

    sort(addedRows.begin(), addedRows.end());
    sort(modifiedRows.begin(), modifiedRows.end());
    sort(deletedRows.begin(), deletedRows.end());

    vector<vector<long>> result = {addedRows, modifiedRows, deletedRows};
    return result;
}

Java:[此代码未进行大量数据的测试,仅供参考]

import java.util.*;

public static ArrayList<ArrayList<Long>> compareConfigs(ArrayList<Long> oldIds, ArrayList<String> oldValues,ArrayList<Long> newIds, ArrayList<String> newValues) {
 // 存储旧表和新表的数据
        Map<Long, String> oldTable = new HashMap<>();
        Map<Long, String> newTable = new HashMap<>();
        ArrayList<Long> addedRows = new ArrayList<>();
        ArrayList<Long> modifiedRows = new ArrayList<>();
        ArrayList<Long> deletedRows = new ArrayList<>();

        for (int i = 0; i < oldIds.size(); i++) {
            oldTable.put(oldIds.get(i), oldValues.get(i));
        }

        for (int i = 0; i < newIds.size(); i++) {
            newTable.put(newIds.get(i), newValues.get(i));
        }

        for (int id : newIds) {
            if (!oldTable.containsKey(id)) {
                addedRows.add(id);
            } else if (!newTable.get(id).equals(oldTable.get(id))) {
                modifiedRows.add(id);
            }
        }

        for (int id : oldIds) {
            if (!newTable.containsKey(id)) {
                deletedRows.add(id);
            }
        }

        Collections.sort(addedRows);
        Collections.sort(modifiedRows);
        Collections.sort(deletedRows);

        ArrayList<ArrayList<Integer>> result = new ArrayList<>();
        result.add(addedRows);
        result.add(modifiedRows);
        result.add(deletedRows);

        return result;
    }
}

Python:[此代码未进行大量数据的测试,仅供参考]

def compare_configs(old_ids, old_values, new_ids, new_values):
    # 存储旧表和新表的数据
    old_table = dict(zip(old_ids, old_values))
    new_table = dict(zip(new_ids, new_values))
    added_rows = []
    modified_rows = []
    deleted_rows = []

    for id in new_ids:
        if i

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

2024 BAT笔试合集 文章被收录于专栏

持续收录字节、腾讯、阿里、美团、美团、拼多多、华为等笔试题解,包含python、C++、Java多种语言版本,持续更新中。

全部评论

相关推荐

1)手撕:给定字符串,求不含重复字符的最长子串长度,并打印这个子串//哈希Set配合双指针private&nbsp;static&nbsp;String&nbsp;findLongestSubstring(String&nbsp;s)&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;n&nbsp;=&nbsp;s.length();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;left&nbsp;=&nbsp;0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;maxLength&nbsp;=&nbsp;0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;longestSubstring&nbsp;=&nbsp;&quot;&quot;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set&lt;Character&gt;&nbsp;charSet&nbsp;=&nbsp;new&nbsp;HashSet&lt;&gt;();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(int&nbsp;right&nbsp;=&nbsp;0&nbsp;;&nbsp;right&nbsp;&lt;&nbsp;n&nbsp;;&nbsp;right&nbsp;++){&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while(charSet.contains(s.charAt(right))){&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;charSet.remove(s.charAt(left));&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;left++;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;charSet.add(s.charAt(right));&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(maxLength&nbsp;&lt;&nbsp;right&nbsp;-&nbsp;left&nbsp;+&nbsp;1){&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;maxLength&nbsp;=&nbsp;right&nbsp;-&nbsp;left&nbsp;+&nbsp;1;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;longestSubstring&nbsp;=&nbsp;s.substring(left&nbsp;,&nbsp;right&nbsp;+&nbsp;1);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;longestSubstring;&nbsp;&nbsp;&nbsp;&nbsp;}2)如何设计一个秒杀系统?从以下角度考虑:1.高性能架构;采用分布式架构,消息队列来削峰填谷,服务的降级和熔断 2.高并发的处理能力:商品库存扣减的多线程安全问题,采用redisson分布式锁,缓存预热3.用户体验升级:websocket实现秒杀倒计时同步,消息队列实现秒杀结果实时反馈,针对ip地址,设备指纹和访问频率的限制实现防作弊系统4.数据一致性保障;数据库分库分表,本地消息表5.监控报警:监控系统,报警系统,日志系统,异常日志收集,分布式追踪系统6.安全防护、成本控制3)String&nbsp;StringBuffer&nbsp;StringBuilder区别String是不可变类,线程安全,每次修改字符串都会创建新的字符串,效率比较低StringBuffer是可变类,直接在原字符串上修改,使用了Synchronized实现同步,效率也比较低,适合多线程场景StringBuilder是可变类,线程不安全,效率比较高,适合单线程场景4)数据库字段char和varchar区别char:定长字符串,存储长度为1~255个字符,存储空间固定为255字节,不足用空格补,适合固定长度的字段,便于数据库读取和优化varchar:可变字符串,存储长度为1~65535个字符,存储空间为实际长度+长度字节5)索引失效的情况索引失效是指数据库在查询过程中无法有效利用已建立的索引,导致查询性能下降,甚至退化为全表扫描的情况。查询条件中使用了函数或表达式对索引列进行操作;使用了OR条件且未对所有分支列建立索查询条件中使用了NOT、&lt;&gt;、!=等否定操作符;对索引列进行了模糊查询(如LIKE&nbsp;'%abc%'),且通配符位于开头;查询条件中列的顺序与复合索引的列顺序不匹配;或者查询时数据类型不匹配导致索引无法使用。6)数据库的事务隔离级别读未提交:允许读取尚未提交的数据,可能导致脏读、幻读、不可重复读读已提交:允许读取已提交的数据,不能保证数据一致,可能导致幻读和不可重复读可重复读:允许读取已提交数据,可能导致幻读串行化:保证数据一致性,但是并发度和性能低7)Redis的常用数据类型,分别存储哪些东西?String:存储字符串,比如用户名、密码和验证码等哈希:哈希表,可以存储用户信息,商品信息等List:存储有序的元素,比如消息队列和日志记录Set:集合,可以做去重排序或求交集等Zset:带得分排序的集合,可以做用户或者流量等的排行榜8)Redis的锁机制基于SETNX命令,将锁名称作为键,客户端唯一标识(UUID)作为键值,使用完锁后DEL释放锁&nbsp;&nbsp;&nbsp;&nbsp;因不可冲入可能存在死锁和不及时释放锁的情况,可以释放锁时检查锁值是否为自己的UUID以及添加过期时间基于Lua脚本,使用原子SET命令和Lua脚本的事务性,但仍存在锁续期困难和业务超时锁释放风险基于Redisson的分布式锁,支持可冲入锁和自动续期,提供公平锁、联锁和红锁9)HTTP1.0&nbsp;2.0&nbsp;3.0&nbsp;区别HTTP1.0:默认为短连接,每次请求都需要建立TCP连接,并通过Connection:&nbsp;keep-alive头来实现持久连接,不支持管道&nbsp;&nbsp;&nbsp;&nbsp;化,主要使用If-Modified-Since/Expires来做为缓存判断的标准;HTTP2.0:采用二进制格式而非文本格式,解析更加高效,支持多路复用允许单个TCP交错发送多个请求和响应,引入HPA&nbsp;&nbsp;&nbsp;&nbsp;CK压缩算法,对请求和响应的头部信息进行压缩,消除冗余,允许客户端为请求设置优先级HTTP3.0:&nbsp;最新的HTTP协议,基于QUIC协议,QUIC使用udp传输数据,不存在队头阻塞问题,首次连接后具备0RTT优&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;势,减少延迟,允许网络切换时,将连接迁移到新的IP地址,默认采用TLS加密,保证数据传输的安全性10)&nbsp;TCP的三次握手和四次挥手,为什么需要?三次握手:客户端向服务器发送SYN表示请求同步,服务器向客户端发送SYN+ACK表示确认收到同步请求,可以确保客户&nbsp;&nbsp;&nbsp;&nbsp;端的发送能力正常,客户端向服务器发送ACK表示确认,可以确认服务器的发送和接收能力以及客户端的接收能力正常,&nbsp;&nbsp;&nbsp;连接建立,通过三次握手能够保证通信双方的接收发送能力正常四次挥手:客户端发送FIN+x序列号表示请求关闭连接,服务器发送ACK+x+1表示确认收到,客户端向服务器的通道关&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;闭,服务器发送FIN+y序列号表示请求关闭连接,客户端发送ACK+y+1表示收到,等待2MSL没有收到回复后关闭TCP连接,因为TCP是全双工的,双向链路分别需要发送和接收两次,所以是需要四次挥手。11)&nbsp;从输入网址,到最后访问页面的全过程首先输入URL,进行URL解析,准备发送http请求在请求之前,先本地查看浏览器缓存,如果缓存有该资源,直接返回,否则继续准备请求发送请求之前,进行DNS域名解析,按照本地缓存,本地HOST,路由器缓存,DNS服务器,DNS根服务器顺序,直到查&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;询到URL对应的IP地址三次握手建立TCP连接构建请求并发送,包括请求行,请求头,请求体,并把和该域名相关的cookie放入请求头,构建HTTP请求,如果是https&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;还要进行加密服务器处理请求,生成对应的响应并返回相应资源四次握手关闭TCP连接浏览器接收到响应后进行解析处理,如果是字节流可能是下载管理器进行下载,如果是html页面就是进行渲染生成页面。
查看11道真题和解析
点赞 评论 收藏
分享
评论
4
14
分享

创作者周榜

更多
牛客网
牛客企业服务