网易日常实习一面面经

1. 自我介绍

2. 两道代码题:

  • 第一道题:写一道链表排序题要求空间复杂度O(1) :已ac
    插入排序算法 时间复杂度 O(N^2),空间复杂度O(1)
class ListNode{
    int val;
    ListNode next;
    public ListNode(int x) {
        this.val = x;
    }
}
public class LinkedListInsertionSort {
    // 插入排序
    public ListNode insertionSort(ListNode head) {
        if(head == null || head.next == null)
            return head;

        ListNode dummy = new ListNode(0);
        ListNode cur = head;
        // 4 2 1 3
        while(cur != null){
            // 每次从链表的哨兵结点向后寻找插入位置
            ListNode prev = dummy;
            // 在已排序的链表中找到合适的位置插入节点
            while(prev.next != null && prev.next.val < cur.val){
                prev = prev.next;
            }
            // 保存当前链表当中的下一个节点,因为这个节点要进行插入了
            ListNode nextTemp = cur.next;
            // 将 cur 节点插入到 pre 后面
            cur.next = prev.next;
            prev.next = cur;
            // 继续处理下一个节点
            cur = nextTemp;
        }
        return dummy.next;
    }

    public static void main(String[] args) {
        LinkedListInsertionSort sorter = new LinkedListInsertionSort();

        // 创建测试链表 4 -> 2 -> 1 -> 3
        ListNode head = new ListNode(4);
        head.next = new ListNode(2);
        head.next.next = new ListNode(1);
        head.next.next.next = new ListNode(3);

        // 排序
        ListNode sorted = sorter.insertionSort(head);

        // 输出排序后的链表
        while(sorted != null){
            System.out.print(sorted.val + " ");
            sorted = sorted.next;
        }
    }
}

归并排序 时间复杂度O(nlogn) , 空间复杂度O(nlogn) 。当然这道题不可以使用这个算法。

  • 第二道题:写出可以StackOverFlow的代码
public class StackOverFlow {
    public static void main(String[] args) {
        dfs();
    }

    private static void dfs() {
        dfs();
    }
}

3. 讲一讲自己项目当中那部分是比较有成就感的。

那我就讲一下第一个项目:基于微服务架构的社区社交平台:
我认为在笔记服务当中:首先我先测试的仅使用了 Mysql 数据库存储和读取数据的接口设计,并用Jmeter 压测单机单节点,发现在本地运行笔记发布删除的吞吐量仅有 10000+/ s ,响应耗时也较高,此时我选择引用 Redis分布式缓存来对数据库查询修改接口之前加上一段缓存,此时吞吐量提升了近1倍,后面我又在Redis之前添加Caffeine 的本地缓存,吞吐量又有较高的提升。但是此时产生了二级缓存结构与Mysql数据库数据不一致的问题。因此我采取在读取记录的读策略时发现缓存当中不存在的情况下先查询数据库在添加到缓存当中。在更新、删除记录时,使用 RocketMQ 广播服务,实现集群环境下,对本地缓存中缓存的删除,达到数据一致性。并且在点赞接口支持高并发写:使用 Redis Bloom 布隆过滤器,高性能判断用户是否点赞,通过 Redis ZSET + MQ 异步落库,消费者中使用 RateLimiter 令牌桶实现流量削峰,避免了缓存雪崩,缓存穿透,缓存击穿等问题;
在用户关系服务当中:通过 Redis 缓存 + 发送顺序消息 MQ 异步存库,实现接口的高并发写与操作的顺序性,使用 Lua 脚本,避免频繁操作 Redis 造成的性能瓶颈,且保证多次操作的原子性;消费者使用联合唯一索引保证关系记录的幂等性;

4. 加入说有个用户进行了点赞,怎么统计某个笔记和内容的点赞数量

首先使用 Redis Bloom 布隆过滤器,高性能判断用户是否点赞:然后发送MQ消息,将点赞落数据落库:最后调用计数服务通过聚合操作将数据落入数据库。

5.怎样处理中间件的消息积压问题?

发生了消息积压,这时候就得想办法赶紧把积压的消息消费完,就得考虑提高消费能力,一般有两种办法:
消息积压处理

  • 消费者扩容: 如果当前 Topic 的 Message Queue 的数量大于消费者数量,就可以对消费者进行扩容,增加消费者,来提高消费能力,尽快把积压的消息消费玩。
  • 消息迁移 Queue 扩容: 如果当前 Topic 的 Message Queue 的数量小于或者等于消费者数量,这种情况,再扩容消费者就没什么用,就得考虑扩容 Message Queue。可以新建一个临时的 Topic,临时的 Topic 多设置一些 Message Queue,然后先用一些消费者把消费的数据丢到临时的 Topic,因为不用业务处理,只是转发一下消息,还是很快的。接下来用扩容的消费者去消费新的 Topic 里的数据,消费完了之后,恢复原状。
    消息迁移扩容消费

6. Java基础

6.1

	String a = "abc";
    String b = new String("abc");
    String c = new String("abc");
    String d = "abc";
    System.out.println(a == b);
    System.out.println(b == c);
    System.out.println(c == d);
    System.out.println(d == a);

这几个用==判断是否相同,首先在字符串常量池当中创建字符串 "abc" 所以 a, d都是指向的字符串常量池的地址,b,c都是在堆上new出来的结果,由于a = "abc"先执行,所以都在堆中的对象指向字符串常量池中的地址,但是他们这两个对象地址又不相同,所以a = d, a != b, b != c, a != c。

6.2 假如当前有一个对象,要重写euqals方法,在重写euqals方法的时候要注意什么?

在重写 equals 方法时,一定要重写 hashCode 方法。equals 和 hashCode 之间有一个重要的契约:

  • 如果两个对象通过 equals 比较结果相等,则它们的 hashCode 也必须相等。
  • 如果两个对象通过 equals 比较结果不相等,它们的 hashCode 不一定要不同,但建议尽量不同,以提高性能。

例如String类当中重写了euqals方法,他会首先判断两个对象是否是同一个对象,即==来判断,通过 这个判断的原理就是计算两个对象的hashcode是否相同。如果相同直接返回true,不同再回判断是否类型相同长度相同,里面的元素相同等等。

如何遍历一个Map,我想要拿到他们所有的key所有的value

在 Java 中,遍历 Map 可以通过多种方式来实现。你可以选择遍历 Map 的所有键 (key),值 (value),或者键值对 (key-value pair)。
以下是几种常见的遍历 Map 的方式,适用于任何实现了 Map 接口的类(如 HashMap、TreeMap 等)。

1. 使用 for-each 和 entrySet()(推荐方式)

entrySet() 方法返回 Map 中所有键值对的集合 (Set<Map.Entry<K, V>>),你可以通过这种方式高效地遍历 Map 的所有键值对。

Map<String, String> map = new HashMap<>();
map.put("a", "apple");
map.put("b", "banana");
map.put("c", "cherry");

// 遍历 key-value 对
for (Map.Entry<String, String> entry : map.entrySet()) {
    String key = entry.getKey();
    String value = entry.getValue();
    System.out.println("Key: " + key + ", Value: " + value);
}

2. 使用 for-each 和 keySet()

keySet() 方法返回 Map 中所有的键(Set),你可以通过这种方式获取所有键,并使用 get() 方法获取对应的值。

Map<String, String> map = new HashMap<>();
map.put("a", "apple");
map.put("b", "banana");
map.put("c", "cherry");

// 遍历所有键,然后获取值
for (String key : map.keySet()) {
    String value = map.get(key);
    System.out.println("Key: " + key + ", Value: " + value);
}

3. 使用 for-each 和 values()(仅遍历值)

如果你只对值感兴趣,而不关心具体的键,可以使用 values() 方法,它返回一个 Collection,包含 Map 中的所有值。

Map<String, String> map = new HashMap<>();
map.put("a", "apple");
map.put("b", "banana");
map.put("c", "cherry");

// 仅遍历值
for (String value : map.values()) {
    System.out.println("Value: " + value);
}

4. 使用 Iterator 遍历 entrySet()

如果你需要在遍历过程中进行删除操作或者有特殊的遍历需求,可以使用 Iterator。

Map<String, String> map = new HashMap<>();
map.put("a", "apple");
map.put("b", "banana");
map.put("c", "cherry");

// 使用 Iterator 遍历 key-value 对
Iterator<Map.Entry<String, String>> iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
    Map.Entry<String, String> entry = iterator.next();
    String key = entry.getKey();
    String value = entry.getValue();
    System.out.println("Key: " + key + ", Value: " + value);
}

5. Java 8 Stream API(现代方式)

如果你使用的是 Java 8 或更高版本,Stream API 可以为你提供更简洁的代码风格。

Map<String, String> map = new HashMap<>();
map.put("a", "apple");
map.put("b", "banana");
map.put("c", "cherry");

// 使用 Java 8 Stream API 遍历
map.forEach((key, value) -> System.out.println("Key: " + key + ", Value: " + value));

7. JUC

7.1 假设有一个发音引擎:部署在本地最多只支持32路并发,假设有第33个请求进入翻译引擎,请问怎样实现这个业务?

可以通过阻塞队列或者是信号量来实现这个需求:
信号量实现就32个信号,没有了就阻塞

8. Linux

8.1 讲一下tail命令

tail 命令用于查看文件的末尾内容,默认情况下显示文件的最后 10 行。
语法

tail [OPTION]... [FILE]...

常用选项

选项说明
-n N显示文件的最后 N 行
-f监听文件内容变化,实时输出新增内容(常用于日志文件)
-c N显示文件的最后 N 字节
-q静默模式,不输出文件名
-v始终输出文件名
使用示例

1. 查看文件最后 10 行

tail file.txt

2. 查看文件最后 20 行

tail -n 20 file.txt

3. 实时监听日志文件

tail -f /var/log/syslog

4. 监听多个文件

tail -f file1.log file2.log

5. 显示文件的最后 50 个字节

tail -c 50 file.txt

结合其他命令使用
6. 结合 grep 过滤日志

tail -f /var/log/syslog | grep "error"

退出 tail -f

在 tail -f 运行时,可以使用 Ctrl + C 退出监听模式。
总结: tail 是一个非常实用的命令,特别适用于日志文件的查看和实时监控。

8.2 如果当前有个文件他的权限是644,那么这个644代表什么?

在 Linux 中,文件权限是通过三组数字(通常是三位或四位)来表示的,每个数字代表一组用户的权限设置。数字 644 具体表示以下含义:
解释:

  • 数字 6: 表示文件所有者(Owner)的权限。
  • 数字 4: 表示文件所属组(Group)的权限。
  • 数字 4: 表示其他用户(Others)的权限。

权限映射:
每个数字实际上是由三个二进制位组成,分别代表读(r)、写(w)和执行(x)权限:
r (读权限) = 4
w (写权限) = 2
x (执行权限) = 1
- (没有权限) = 0

权限详情:

6: 文件所有者的权限是 rw-(读 + 写,无法执行),对应二进制是 110,即 4 + 2 + 0 = 6。
4: 文件所属组的权限是 r–(只读),对应二进制是 100,即 4 + 0 + 0 = 4。
4: 其他用户的权限是 r–(只读),对应二进制是 100,即 4 + 0 + 0 = 4。

综合起来:

文件所有者: 有读和写权限(rw-)
文件所属组: 只有读权限(r–)
其他用户: 只有读权限(r–)

总结:

数字 644 代表文件权限为:

  • 所有者(Owner):读和写权限(rw-)
  • 所属组(Group):只读权限(r–)
  • 其他用户(Others):只读权限(r–)

9. git

9.1 讲一下git的pull

在 Git 中,git pull 是一个常用的命令,用于从远程仓库获取最新的更改并将它们合并到当前本地分支。简单来说,git pullgit fetchgit merge 两个操作的组合。
语法

git pull [<remote>] [<branch>]
  • <remote>:指定远程仓库的名称,默认为 origin,即默认的远程仓库。
  • <branch>:指定要拉取的远程分支,默认为当前分支。

工作流程

  1. git fetch:从远程仓库拉取最新的代码(但是不会合并到本地分支)。
  2. git merge:将从远程仓库拉取下来的更改与当前本地分支进行合并。

所以,执行 git pull 相当于先执行 git fetch,然后执行 git merge
示例

1. 拉取默认远程仓库 origin 的当前分支更新

git pull

这会从远程仓库 origin 获取当前分支的最新更新,并与本地分支进行合并。
2. 拉取指定远程仓库 origin 的指定分支(例如 main)

git pull origin main

这会从远程仓库 originmain 分支拉取更新,并合并到当前本地分支。
3. 拉取更新后不进行合并(仅获取更改)

如果你想只获取远程更新,但不合并到本地分支,可以使用:

git fetch

这会从远程仓库拉取所有的更改,但不会自动合并。你可以查看更改并决定如何处理它们。
4. 使用 git pull --rebase

默认情况下,git pull 会执行一个 merge 操作,可能会产生合并提交(merge commit)。如果你想避免生成额外的合并提交,而是将本地提交“放在”远程分支的最新提交之后,可以使用 --rebase 选项。

git pull --rebase

这会让你的本地更改基于远程分支的最新更改进行重放(rebase)。
注意事项

  • 合并冲突: 如果本地更改和远程更改冲突,Git 会提示你进行冲突解决。在解决冲突后,你需要手动提交合并结果。
  • 历史记录: 如果你使用 --rebase 选项,历史记录会变得更为线性,没有合并提交。

总结

git pull 是用来从远程仓库获取并合并代码到本地的命令。
它是 git fetchgit merge 的组合,可以自动合并更新。
使用 git pull --rebase 可以避免产生额外的合并提交,使得历史记录更加整洁。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/967536.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

DeepSeek LLM 论文解读:相信长期主义开源理念可扩展大语言模型(DeepSeek 吹响通用人工智能的号角)

论文链接&#xff1a;DeepSeek LLM: Scaling Open-Source Language Models with Longtermism&#xff08;相信长期主义开源理念可扩展大语言模型&#xff09; 目录 摘要一、数据处理&#xff08;一&#xff09;数据清洗与丰富&#xff08;二&#xff09;分词器与词汇设置 二、模…

02DevOps基础环境准备

准备两台Linux的操作系统&#xff0c;最简单的方式就是在本机上使用虚拟机搭建两个操作系统&#xff08;实际生产环境是两台服务器&#xff0c;虚拟机的方式用于学习使用&#xff09; 我搭建的两台服务器的ip分别是192.168.1.10、192.168.1.11 192.168.1.10服务器用于安装doc…

基于 SpringBoot 和 Vue 的智能腰带健康监测数据可视化平台开发(文末联系,整套资料提供)

基于 SpringBoot 和 Vue 的智能腰带健康监测数据可视化平台开发 一、系统介绍 随着人们生活水平的提高和健康意识的增强&#xff0c;智能健康监测设备越来越受到关注。智能腰带作为一种新型的健康监测设备&#xff0c;能够实时采集用户的腰部健康数据&#xff0c;如姿势、运动…

表单与交互:HTML表单标签全面解析

目录 前言 一.HTML表单的基本结构 基本结构 示例 二.常用表单控件 文本输入框 选择控件 文件上传 按钮 综合案例 三.标签的作用 四.注意事项 前言 HTML&#xff08;超文本标记语言&#xff09;是构建网页的基础&#xff0c;其中表单&#xff08;<form>&…

vue3中使用print-js组件实现打印操作

第一步&#xff1a;安装依赖 yarn add print-js 第二步&#xff1a;创建打印组件&#xff1a;PrintHtmlComp.vue <template><div id"printArea_123456789"><!-- 默认插槽&#xff0c;传入打印内容 --><slot></slot></div>…

【计算机网络】TCP/IP 网络模型有哪几层?

目录 应用层 传输层 网络层 网络接口层 总结 为什么要有 TCP/IP 网络模型&#xff1f; 对于同一台设备上的进程间通信&#xff0c;有很多种方式&#xff0c;比如有管道、消息队列、共享内存、信号等方式&#xff0c;而对于不同设备上的进程间通信&#xff0c;就需要网络通…

网络工程师 (29)CSMA/CD协议

前言 CSMA/CD协议&#xff0c;即载波监听多路访问/碰撞检测&#xff08;Carrier Sense Multiple Access with Collision Detection&#xff09;协议&#xff0c;是一种在计算机网络中&#xff0c;特别是在以太网环境下&#xff0c;用于管理多个设备共享同一物理传输介质的重要…

基于Python的人工智能驱动基因组变异算法:设计与应用(下)

3.3.2 数据清洗与预处理 在基因组变异分析中,原始数据往往包含各种噪声和不完整信息,数据清洗与预处理是确保分析结果准确性和可靠性的关键步骤。通过 Python 的相关库和工具,可以有效地去除噪声、填补缺失值、标准化数据等,为后续的分析提供高质量的数据基础。 在基因组…

AI大语言模型

一、AIGC和生成式AI的概念 1-1、AIGC Al Generated Content&#xff1a;AI生成内容 1-2、生成式AI&#xff1a;generative ai AIGC是生成式 AI 技术在内容创作领域的具体应用成果。 目前有许多知名的生成式 AI&#xff1a; 文本生成领域 OpenAI GPT 系列百度文心一言阿里通…

在postman中设置环境变量和全局变量以及五大常用响应体断言

一、什么是环境变量和全局变量 环境变量&#xff08;Environment Variables&#xff09;和全局变量&#xff08;Global Variables&#xff09;是 Postman 中用于存储和管理数据的两种变量类型&#xff0c;它们可以提高 API 测试的灵活性和可维护性。 1、 环境变量&#xff08…

Redis数据库(二):Redis 常用的五种数据结构

Redis 能够做到高性能的原因主要有两个&#xff0c;一是它本身是内存型数据库&#xff0c;二是采用了多种适用于不同场景的底层数据结构。 Redis 常用的数据结构支持字符串、列表、哈希表、集合和有序集合。实现这些数据结构的底层数据结构有 6 种&#xff0c;分别是简单动态字…

C++STL(六)——list模拟

目录 本次所需实现的三个类一、结点类的模拟实现构造函数 二、迭代器类的模拟实现为什么有迭代器类迭代器类的模板参数说明构造函数运算符的重载- -运算符的重载和!运算符的重载*运算符的重载->运算符的重载引入模板第二个和第三个参数 三、list的模拟实现3.1 默认成员函数构…

国产编辑器EverEdit - 替换功能详解

1 替换 1.1 应用场景 替换文本是在文档编辑过程中不可回避的操作&#xff0c;是将指定的关键词替换为新的文本&#xff0c;比如&#xff1a;写代码时修改变量名等。 1.2 使用方法 1.2.1 基本替换 使用主菜单查找 -> 替换&#xff0c;或使用快捷键Ctrl H&#xff0c;会打…

LIMO:上海交大的工作 “少即是多” LLM 推理

25年2月来自上海交大、SII 和 GAIR 的论文“LIMO: Less is More for Reasoning”。 一个挑战是在大语言模型&#xff08;LLM&#xff09;中的复杂推理。虽然传统观点认为复杂的推理任务需要大量的训练数据&#xff08;通常超过 100,000 个示例&#xff09;&#xff0c;但本文展…

防御保护作业二

拓扑图 需求 需求一&#xff1a; 需求二&#xff1a; 需求三&#xff1a; 需求四&#xff1a; 需求五&#xff1a; 需求六&#xff1a; 需求七&#xff1a; 需求分析 1.按照要求进行设备IP地址的配置 2.在FW上开启DHCP功能&#xff0c;并配置不同的全局地址池&#xff0c;为…

蓝桥与力扣刷题(226 翻转二叉树)

题目&#xff1a;给你一棵二叉树的根节点 root &#xff0c;翻转这棵二叉树&#xff0c;并返回其根节点。 示例 1&#xff1a; 输入&#xff1a;root [4,2,7,1,3,6,9] 输出&#xff1a;[4,7,2,9,6,3,1]示例 2&#xff1a; 输入&#xff1a;root [2,1,3] 输出&#xff1a;[2,…

大型语言模型(LLM)中的自适应推理预算管理:基于约束策略优化的解决方案

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

[EAI-033] SFT 记忆,RL 泛化,LLM和VLM的消融研究

Paper Card 论文标题&#xff1a;SFT Memorizes, RL Generalizes: A Comparative Study of Foundation Model Post-training 论文作者&#xff1a;Tianzhe Chu, Yuexiang Zhai, Jihan Yang, Shengbang Tong, Saining Xie, Dale Schuurmans, Quoc V. Le, Sergey Levine, Yi Ma 论…

大数据-259 离线数仓 - Griffin架构 修改配置 pom.xml sparkProperties 编译启动

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; Java篇开始了&#xff01; 目前开始更新 MyBatis&#xff0c;一起深入浅出&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff0…

【时时三省】(C语言基础)基础习题1

山不在高&#xff0c;有仙则名。水不在深&#xff0c;有龙则灵。 ----CSDN 时时三省 1.什么是程序&#xff1f;什么是程序设计 程序是为实现特定目标或解决特定问题&#xff0c;用计算机能理解和执行的语言编写的一系列指令的集合。 程序设计是问题分析&#xff0c;设计算法…