面试题 新版 旧版 网络 1 2 socket 位于传输层之上,应用层之下 Nignx位于第四层 - ip转发, 第七层,http 请求解析
1 2 3 4 5 物理层(建立物理连接,传输二进制流)。那么首先摆在面前的第一个问题就是主机A与主机B之间得有一条物理链路(有线、无线)进行数据传输,否则通信无从谈起;所以物理层的作用便是在主机之间搭建一条物理链路传输二进制流(即0 与1 ,与协议无关)。 数据链路层(局域网,主机间通信)。物理链路联通以后主机之间就具备了数据传输的基础能力,但是物理链路上是无协议的,传输的是二进制流;二进制流意味着没有起始标识符,接收的主机不知道什么时候开始解析数据,也不知道什么时候终止数据的接收;于是在数据链路层上对发送的数据进行了封装:分装成帧(frame);这样主机在接收二进制流时就知道什么时候开始,什么时候结束;。 网络层(网络路由,主机间通信)。当物理层和数据链路层准备就绪以后,另外的问题出现了:计算机网络中存在大量的主机,那么主机A如何找到主机B呢?即网络路由寻址能力;在网络层最出名的协议莫过于IP协议(Internet Protocol)。在特定的网络下,每台主机都分配了一个唯一IP地址,配合路由器的IP路由寻址,主机A就能通过IP协议找到主机B了;也就意味着主机A与主机B之间具备了数据传输能力。 传输层(进程间通信)。主机之间具备传输功能之后,那么更近一步把数据发送到指定端口即可完成一次不同主机间的进程通信了;记住传输层并不是数据传输的地方,而是控制数据如何传输的地方:面向连接还是无连接,传输的拥塞控制等。 应用层(发送&接收数据)。主机B上的进程b只要监听特定的端口号,那么就能够收到主机A上的进程a发送过来的数据了。
MySQL sql语句如何通过分数排名查询第三到第十名信息
1 2 3 4 5 6 SELECT id, name , scoreFROM ( SELECT id, name , score, RANK() OVER (ORDER BY score DESC ) AS rank FROM students ) as temp WHERE rank BETWEEN 3 AND 10 ;
Redis Redis的持久化方式 1 2 3 4 5 6 Redis有两种持久化方式:RDB和AOF。1. RDB持久化方式: RDB是Redis的默认持久化方式,它会定期将内存中的数据快照保存到磁盘上,以保证数据的持久化。RDB的优点是数据量小,可以快速恢复数据,但缺点是可能会丢失最近的一些数据。2. AOF持久化方式: AOF是Redis的另一种持久化方式,它会将所有的写操作记录下来,以文本方式保存在磁盘上。AOF的优点是可以保证数据的完整性和可靠性,但缺点是数据量大,恢复速度相对较慢。
String 创建一个String – new String(),第一步都是看字符串常量池中有无字符串,没有就现在字符串常量池中创建,
然后,new String(),一定会在堆中创建对象实例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 下面代码创建了几个对象String str = new String ("Cat" ); 答案:一个或者两个 原因:先判断字符串常量池里面有没有Cat字符串对象,如果有,就不会在常量池里面创建Cat对象,但是会在堆内存里面创建一个Cat对象,并将对象地址返回给str变量,这种情况创建一个对象; 如果常量字符串没有,就会现在常量池里面创建Cat字符串,然后再在堆内存里面创建Cat字符串对象,这种情况会创建两个对象 String hello = "hello" ; String hel = "hel" ; String lo = "lo" ; System.out.println(hello == "hel" + "lo" ); System.out.println(hello == "hel" + lo); 前三句在String Pool里分别产生“hello”、“hel”、“lo”三个常量字符串对象。 “hel”+”lo” 这是两个字符串拼接成一个”hello”字符串对象,拼接后会在String pool看有没有hello字符串对象,如果有,则返回已有对象的地址,没有的话,就在String pool创建一个hello字符串对象 “hel”+lo 这相当于修改lo字符串对象,由于字符串是不可变的数据类型,所以会在字符串堆内存里面创建一个新的字符串对象
StringBuilder
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 String s = new StringBuilder ("abc" ).toString(); s.intern();String s1 = "abc" ; System.out.println(s1 == s); String s = new StringBuilder ("abc" ).append("ss" ).toString(); s.intern();String s1 = "abcss" ; System.out.println(s1 == s);
1)静态常量池: 是指程序(.class)文件在加载时候会将程序中保存的字符串、普通的常量、类和方法等信息,全部进行分配。
2) 运行时常量池: 是指当一个和程序(.class)加载之后,有一些字符串内容是通过String对象的形式保存后在实现字符串连接处理,由于String对象的内容可以改变,所以此称为运行时常量池。
举个栗子:静态常量池
1 2 3 4 String strA = "HelloWorld" ;String strB = "Hello" +"World" ; System.out.println(strA==strB);
举个栗子:运行时常量池
1 2 3 4 String strA = "HelloWorld" ;String strB = "World" ;String strC = "Hello" +strB;
//使用+进行字符串连接,动态拼凑时,由于strB是变量其内容运行时可能改变,所以其无法从常量池获取字符串引用 System.out.println(strA==strC);//判断结果:false
总结 1 2 3 对于字符串,首先分析他是 静态常量池(字符常量池) 还是运行常量池(对象) 静态之间,编译器即可确定,为字符常量池的地址, 有对象参与,则使用StringBuilder的append 进行处理,只在堆中创建最终对象
RabbitMQ (1条消息) RabbitMQ(总结最全面的面试题!!!)_rabbitmq面试题_小杰要吃蛋的博客-CSDN博客
场景题 Hash一致性算法是如何解决数据倾斜问题的 (1条消息) 面试官:Hash一致性算法是如何解决数据倾斜问题的_hashtag 如何防止cachecloud数据倾斜_Java架构师联盟的博客-CSDN博客
单点登录 基于直接访问模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 Me: 如何实现不通过跳转的页面的方式,进行单点登录 AI:please wait... 要实现不通过跳转的页面的方式进行单点登录,可以采用以下步骤:1. 在用户登录时,将用户的认证信息(如用户名和密码)保存在后端的session中。2. 在需要进行单点登录的应用中,通过后端的接口获取用户的认证信息。3. 将用户的认证信息保存在前端的cookie中,设置过期时间。4. 在其他需要进行单点登录的应用中,通过前端的cookie获取用户的认证信息,然后向后端发送请求进行认证。5. 如果认证成功,则在后端生成一个token,并将token保存在cookie中,设置过期时间。6. 在其他需要进行单点登录的应用中,通过前端的cookie获取token,然后向后端发送请求进行验证。7. 如果验证通过,则认为用户已经登录,可以直接进入应用。 需要注意的是,在保存用户的认证信息和token时,应该采用加密算法对其进行加密,以保证安全性。同时,应该设置合理的过期时间,避免信息泄露和安全问题。
基于页面跳转方式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 Me: 如何实现跨域单点登录 AI:please wait... 跨域单点登录(Cross -domain Single Sign-On ,简称SSO)是指在不同的域名下进行用户认证,用户只需要在一个域名下登录后,就可以在其他域名下自动登录,无需再次输入用户名和密码。 实现跨域单点登录的方式有很多,下面列举几种常用的方式: 1. 基于Cookie的跨域单点登录 使用这种方式,用户在第一次登录时,登录信息会保存在Cookie中。当用户跳转到其他子域名下的页面时,可以通过读取Cookie来判断用户是否已经登录。如果已经登录,则可以直接跳转到目标页面,否则需要跳转到登录页面进行认证。 2. 基于Token 的跨域单点登录 使用这种方式,用户在登录时会生成一个Token ,该Token 会保存在服务器端。当用户跳转到其他子域名下的页面时,需要将该Token 传递给目标页面。目标页面再将Token 发送给认证服务器进行验证,验证通过后用户就可以被认为已经登录了。 3. 基于OAuth2.0的跨域单点登录 OAuth2.0是一种授权框架,可以用于实现跨域单点登录。使用这种方式,用户在登录时会被重定向到认证服务器,用户需要输入用户名和密码进行认证。认证通过后,服务器会生成一个Access Token ,该Token 会被传递回到客户端。当用户跳转到其他子域名下的页面时,需要将该Token 发送给目标页面。目标页面再将Token 发送给认证服务器进行验证,验证通过后用户就可以被认为已经登录了。 无论使用哪种方式,都需要注意安全性问题,比如防止CSRF攻击、XSS攻击等等。同时,还需要在不同的域名下进行配置,以确保各子域名之间的通信能够正常进行。
备注:cookie类型
1 2 3 4 5 6 7 1. 会话Cookie(Session Cookie):保存在用户浏览器中,仅在当前会话有效,浏览器关闭后失效。2. 持久化Cookie(Persistent Cookie):保存在用户浏览器中,可以设置失效时间,即使浏览器关闭后也可以保留。3. 安全Cookie(Secure Cookie):只能通过HTTPS连接传输,可以提高Cookie的安全性。4. HttpOnly Cookie:只能通过HTTP/HTTPS协议访问,不能通过JavaScript等客户端脚本访问,可以有效防止XSS攻击。
LRU算法 — 最近最久未使用算法 LinkedHashMap
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 import java.util.LinkedHashMap;import java.util.Map;public class LRUCache <K, V> extends LinkedHashMap <K, V> { private int cacheSize; public LRUCache (int cacheSize) { super (16 , (float ) 0.75 , true ); this .cacheSize = cacheSize; } protected boolean removeEldestEntry (Map.Entry<K, V> eldest) { return size() > cacheSize; } }import org.slf4j.Logger;import org.slf4j.LoggerFactory;public class LRUCacheTest { private static final Logger log = LoggerFactory.getLogger(LRUCacheTest.class); private static LRUCache<String, Integer> cache = new LRUCache <>(10 ); public static void main (String[] args) { for (int i = 0 ; i < 10 ; i++) { cache.put("k" + i, i); } log.info("all cache :'{}'" ,cache); cache.get("k3" ); log.info("get k3 :'{}'" , cache); cache.get("k4" ); log.info("get k4 :'{}'" , cache); cache.get("k4" ); log.info("get k4 :'{}'" , cache); cache.put("k" + 10 , 10 ); log.info("After running the LRU algorithm cache :'{}'" , cache); } }
LFU算法 LFU(Least Frequently Used ,最近最少使用算法)也是一种常见的缓存算法。
顾名思义,LFU算法的思想是:如果一个数据在最近一段时间很少被访问到,那么可以认为在将来它被访问的可能性也很小。因此,当空间满时,最小频率访问的数据最先被淘汰 。
LFU 算法的描述:
设计一种缓存结构,该结构在构造时确定大小,假设大小为 K,并有两个功能:
set(key,value):将记录(key,value)插入该结构。当缓存满时,将访问频率最低的数据置换掉。
get(key):返回key对应的value值。
算法实现策略:考虑到 LFU 会淘汰访问频率最小的数据,我们需要一种合适的方法按大小顺序维护数据访问的频率。LFU 算法本质上可以看做是一个 top K 问题(K = 1),即选出频率最小的元素,因此我们很容易想到可以用二项堆来选择频率最小的元素,这样的实现比较高效。最终实现策略为小顶堆+哈希表。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 一面Java集合类 JUC ConcurrentHashmap 初始化 put过程 冲突 size实现Java并发编程(voliatle synchronize reentrantlock aqs cas ABA)JVM组成,栈溢出的几种情况 类加载机制(过程final static,双亲委派,破坏) GC 收集器(列举,特点) Redis数据类型,底层数据结构,SDS 跳跃表红黑树 分布式事务解决方案 nacos ap cp 源码读过哪些,Dubbo底层原理知道吗,Netty 序列化框架有哪些 性能指标 聊项目 二面 先笔试,三题,简单难度,过了几天后电话面试。 介绍项目 大学的时候做过什么项目 自研框架团队分工,价值,设计 团队划分,产品组做了啥,你负责了啥,说了jmeter压测,监控选型 项目价值 反射的原理 学习方式,线上沙龙,书籍 大数据转前端,前端转后端,心态变化和学习方式的变化 职业规划 秒杀场景设计: 预减库存 ,层层拦截,请求去重,幂等,数据预热,预减库存,MQ操作减库存 频繁GC问题怎么解决 项目中的遇到的最难的问题 一直问我最大数据量的场景 说说什么上线中的深刻经验 项目管理经验 最喜欢的leader,为什么 问常用Linux系统常用命令 堆栈信息导出命令,堆转储什么的怎么导出jstack -l <pid>jmap -dump:live,format=b,file=heap-dump.bin <pid> 然后面试官说先这样,匆匆挂了,看时间到晚上10 点了 补充二面: 说上次没问完,仍然是二面。 分库分表,中间件java线程状态 死锁线程排查,和状态,top -Hp 死锁现象 线程的创建方式、参数 single线程池 和 size=1 线程池的区别 mysql中的幻读 不可重复读 mysql索引实现 mysql分页查询 limit 分布式事务 redis memcache 区别 分布式缓存 redis分布式锁几种实现 分布式缓存问题,击穿 穿透 雪崩 如何带团队 如何带应届生 菜鸟二面: 自我介绍 项目背景 业务背景 业务价值、技术价值 菜鸟三面: 交叉面。 没有自我介绍。。 直接问了简历上的项目细节 讨论了项目如何处理缓存 问有没有擅长的东西 最后问了几个简单的java并发问题 看过什么源码? 想问的?问了面试官的职位方向(业务架构师) 菜鸟四面: 自我介绍,三个项目, 公司基本背景:解决方案提供商 部门结构,职责划分,java开发人员 项目的业务背景,商业模式,2 B 供应链业务 项目解决方案的具体部分,从开发到上线 核心技术(技术含量)有哪些 ?个人负责的工作? 技术栈有哪些? 技术设计亮点?技术价值? 业务设计亮点?研发效率?业务设计抽象? 工作中自己推动的、创新的、有哪些? 平常看的书?开源的代码? 职业思考和规划? 想问的:大佬最近在忙啥?菜鸟跟cbu的关系? 一面: 先做自我介绍 说说现在做的项目,业务场景,技术实现 现在住哪,换工作原因 为什么来杭州 直接问简历上只是提了一下的物联网平台。 动态代理几种实现方式? mybatis 两种分页方式? mybatis 事务的运行过程? mysql 事务原理? mysql 如何实现acid? 问什么比较擅长? 问我想问些什么吗? 我问了部门业务有哪些。 然后问了他我的面试过程有哪些严重的缺陷? 他说知识体系结构有问题,mysql即使达不到DBA的程度,熟知原理是必须的。 最后就是等通知。 挂了,全程大概10 分钟左右。12 月中旬,周六上午面的。去了一趟杭州,顺便跟一个大佬同学面基,下雨天还去了趟西湖。 以为要问并发、缓存、分布式。结果在数据库上翻车了。回头复盘一下。总的来说这一趟面试还是很值的。(绝对不是因为蹭了大佬一顿饭,杭州大虾很不错,哈哈哈。)2 . 莱斯网信 一面: 业务场景,项目介绍,工作内容 spring gateway原理 。webflux 解决过一个bug nacos 源码看过吗 raft算法。只是编译过,说了 ap cp skywalking 原理 agent gRPC 为什么使用spring cloud alibaba 技术栈jsr269注解处理器,使用场景,为什么要用 ELK用来做什么 ,日志收集 聊聊java锁,synchronize volatial aqs是什么 rokectmq原理,为什么用mq 分布式事务 xa saga tcc mq mysql acid 实现,隔离性 mvcc过程,undo log redo logoracle和mysql实现区别 redis 数据结构,跳跃表 二叉树 复杂度的区别 hive hbase 数据倾斜 能否接受另一套架构栈开发 为什么换工作 二面: 为什么用spring security 工作中收获最大的事情 做过什么项目 为什么换工作 平常的爱好和兴趣 在原公司的工作内容 自己的未来发展方向 能否接受CRUD 了解中科28 所吗。然后介绍了他们的部门业务 谈薪资 挂,应该跟学历有关。 每次都是多个部门的面试官一起面的,每次都是4 ~5 个人面一个。 一面的时候有个大佬面试官应该是玩开源社区的,还吐槽了nacos源码。正好我这一年用的技术栈他都熟悉,所以聊的还不错。不过大佬问的挺深,像mvcc的具体实现过程和redis跳跃表这种问题当时没回答上来,还是要多读书多总结啊。3 . 中科曙光南京研究院 一面 sqoop 支持的数据压缩类型? sqoop 抽取多少数据用多少时间,有哪些调优方式? mysql 执行一百条sql后,怎么找出慢sql,如何优化? mysql 批量插入一亿条测试数据,需要的时间,有哪些方法? mysql 手写行转列。 mysql 索引类型 使用场景 kylin 构建过程、构建时间和查询时间。剪枝优化。 hive udf 写过吗 spring 里的设计模式 举例子,简单工厂 抽象工厂的区别? spring boot 多数据源怎么做? spring boot 打包到别的容器怎么做? spring boot 项目依赖冲突怎么解决? spring 读取外部自定义配置文件怎么做? 你简历上写熟悉java那就说说jvm jvm中一个对象从年轻代到老年代的过程和条件,几种,几次 gc算法cms和g1区别特点
面经 一、 腾讯云智二面_牛客网 (nowcoder.com)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 面试官上来先问你这个实习是只实习暑假还是一直下去,我说当然一直下下去,能转正最好 自我介绍 挑一个项目说说 我的项目是利用C++11 实现的简易RPC网络通信框架,实现了服务的发布、注册、远程过程调用等功能,在这个项目中我使用zookeeper的watch机制和znode节点实现服务的的分布式部署,利用protobuf进行数据的序列化和反序列化,利用muduo进行高性能网络发送,利用生产者消费者模型编写异步日志模块 面试官反问:你为什么选择使用zookeeper作为服务注册中心 在分布式环境中,我们需要用到一个服务注册中心,来将我们发布的服务注册到上面取,来保证客户端在这个注册中心找到我们对应的节点,同时服务注册中心还要能够监听我们注册服务结点的变化,如何节点出现故障了我们就需要动态删除节点,同时也需要通知客户端节点节点发生了变化,需要做哪些处理,而Zookeeper正好实现了这么一个机制,它通过心跳机制来检测rpc节点是否还存在,每个一段事件zookeeper服务端就像rpc节点发送心跳包来判断rpc节点是否存在,如果不存在就删除节点,同时通过watch机制告诉客户端节点出现了变化,需要做出相应的变化。 面试官:你用没有考虑使用其它中间件做服务注册中心 我说:zookeeper刚好满足我的服务注册中心的要求,所以我就选了它 面试官:有了解过其它的吗? 额,没有 面试官:做项目要横向对比,分析所有组件的优缺点,选出最合适的,不能说只看一两个 面试官:你的项目使用protobuf进行数据序列化和反序列化,为什么 利用protobuf主要是为了进行数据的序列化和反序列化,也可以用json ,xml ,但是它们没有protobuf高效,protobuf是以二进制形式存储的,json 是以key value 形式存储的,xml 存储需要二外的文本,所以在同等条件下哦,protobuf的数据大小较小,传输效率较高,而且protobuf支持rpc方法的描述,更加有利于我们实现rpc服务 面试官:了解protobuf的底层实现吗 额,只了解过它的基本使用场景,没有了解底层具体实现(感觉要寄了) 面试官:也就是你这个项目都是使用了其它库,没有深入理解过,这个项目那个部分你深入了解过 muduo库部分,我在做这个项目的时候需要一个高性能网络传输框架,我就使用了muduo库,之后我看了muduo库的源码,进行了相应的了解 面试官:了解过源码,那么具体说说muduo的实现 使用“One Loop per thread”的设计模式,可以很好的处理网络IO和数据发送,不会导致我的框架在网络IO部分出现问题 One Loop per thread:一个线程里面还有一个EventLoop,一个Reactor模型包含4 个部分,Event事件,Recator反应堆,事件分发器,事件处理器;在muduo库设计中,我们主线程的EventLoop只负责新用户的连接,每次找到连接的用户之后就会把他交给子线程进行处理,而每个子线程里面也维护者一个EventLoop,它负责监听已连接用户的读写事件,如果一个文件描述符上发生了对应文件描述符感兴趣的事件,就调用对应的事件处理器EventHandler进行处理 面试官:为什么使用muduo库 muduo库刚好满足我的需求,而且它的效率也很高,所有我是用了它 面试官:其它很多库也可能使用了这个设计,甚至比它设计好,为什么使用了它 (有点无语了,因为只会使用它啊)muduo基于C++11 进行实现,很好的支持了现代C++语法,使用bind进行回调时间的绑定,更有利于现代C++的使用,同时它的设计也非常棒,基于one Loop per thread,效率非常好,同时他对于C++新手非常友好,代码通俗易懂,而且一般的网络库线程之间都是通过加锁来实现线程间通信的,而muduo网络库采取无锁的方式,利用threadlocal来判断当前Chanel是否有该EventLoop执行,更加提升了效率,对于学习C++高性能服务器开发非常有帮助 面试官:你是如何学习muduo库的,仅仅只是看了它的代码? 没有的,我在学习muduo库的时候不仅看过它的源代码,我还对muduo库进行改进,实现了muduo库的TcpServer部分,去除这部分对于boost库的依赖,同时进行归纳总结(埋坑了) 面试官:你是怎么进行归纳总结的,使用什么工具 (啊这,我当时就随口一说而已)我一般在本地使用typora进行归纳总结,然后自己一个人进行复习 面试官:项目部分差不多了,接下来问点算法的吧,如果求一个数的n次方 我说直接n个数相乘,然后考虑n为负数能特殊情况,判断特殊情况即可 面试官:还有其它想法吗,可以考虑优化一下吗? 我说:应该只能这样了吧,其它方法没有了解过,可以给点提示吗? 面试官:你试试递归,看看递归如何? 递归的话效率有点低吧,因为他需要大量重复值得计算,所以相比于递归可能上面迭代的效率更高(寄了) 面试官:为什么会有这种感觉吗,有没有学过归并排序 有的,它采取分支思想,局部有序之后在进行合并,艹,到这终于有点思路了 X^n=X^(n/2 )**X^(n/2 )=X^(n/4 )*X^(n/4 ) X^(n/4 ) X^(n/4 ) 之后一直进行递归就可以找出答案了 面试官:没错的,就是这种方法,那么你在学校学过计算机组成原理吧,那么如何求一个浮点数得最大最小值 (直接寄,组成原理上课我都没有去过,压根不知道讲了什么)我说组成原理学过的时间有点久了,有点想不起来了 面试官:没关系,你可以在纸上画画,推导推导 我的内心mmp啊,直接不会啊,我说好,然后假装推导了几分钟之后就告诉面试官抱歉面试官,我下去在好好想想吧,是在是忘记了,太尴尬了 面试官:那行吧,问你一个简单得,如何求一个链表是否有环 (终于遇到一个会的了,后面才知道原来也有坑),快慢指针,快指针一次走两步,慢指针一次走1 步,判断快慢指针是否会相遇,如果相遇就有环,如果没有相遇就没有环 面试官:还有其它方法吗? 利用unordered_map记录走过的节点,如果一个节点重复走过那么就是有环,如果没有重复节点就没有环 面试官:那么你怎么保证快慢指针一定可以遇到 我说这个问题就类比操场上跑圈,那跑得快得人到最后可以套那个跑的慢的一圈,两者就相遇了(面试官听到这😀了) 面试官:我们考虑问题要理性,而不能感性,要严谨得证明,那么假设快指针一次走5 步,慢指针一次走2 步,可以相遇吗 艹,这才想起来,可能快指针可能刚好超过慢指针,以前都没有考虑过,面试官然我再想想 想了一会还是没有思路啊,以前都没有注意过,寄了 面试官:时间差不多了,我们聊点其它得,chatgpt了解过吗 我说了解过 面试官:那你了解过它的底层吗 那肯定没有啊,我本科没有学过相关课程,所以没有了解过,抱歉了 面试官:看来只是简单注册了账号玩了玩啊 啊对对对() 面试官:看你对数据库索引,事务,索引优化有理解,讲一讲索引吧 索引是一种特殊的数据结构,通过建立索引可以加快数据搜索速度,它就像书的目录一样,MySQL默认使用innodb作为存储引擎,它的底层索引结果是B+树,查询效率是非常高的,但是不一定创建索引就是非常好的,索引的创建本身是非常消耗资源的,在数据量比较大的时候创建索引需要花费大量时间,而且索引本身是非常占用内存空间的;在后期新增数据的时候可能需要进行数据的移动,后期维护也是需要大量时间的;当数据量比较小的时候没有必要建立索引,MySQL底层在判断索引和整表查询时间差不多的时候是不会使用索引的;有时候建立索引过多或者建立不当可能起到相反的作用 面试官:应该如何建立索引 前缀索引优化:利用字符串前几个字符建立索引,而不是整个字符串建立索引 联合索引优化 自增主键作为索引 防止索引失效 面试官:优化索引,你如何做的,实际应用中1. 启动慢查询日志,记录操作时间过长的SQL 语句,2. 利用explain 分析执行时间过长的SQL 语句3. 看看该语句是否加索引,没有加索引就加上索引,若有索引看看索引是否起作用4. 看看索引是否添加正确,查询是否用到索引,有没有用到回表,是否用到外排序,如果有外排序是否可以考虑建立联合索引,在sql 语句中是否存在函数、强制类型转换等,然后具体问题进行具体分析 面试官:你在网络学习上花了多少时间 上学期一直在跟着学校课程学习,这学期也在积极自学 面试官:我也不问你了,你自己说说你网络学到了什么 学习了TCP/IP协议栈,学习了HTTP,TCP,UDP,IP,ICMP(埋坑了)等协议,了解网络通信基本流程,能够进行高并发网络编程 面试官:TCP三次握手四次挥手,及状态转换 这个就不写了 面试官:整整的网络环境可能不是这样的,抓包抓过吗 抓过,上学期实验课使用Wireshark抓包,Linux平台没有试过(辛亏给自己没有埋坑啊) 面试官:Linux平台没有抓过包就算了,有时候网络环境很差,需要进行探测,icmp了解吗 ICMP协议称为互联网报文控制协议,主要用来检测对端网络环境是否良好,通过发生ICMP报文判断是否有ICMP回应 面试官:那么icmp报文是怎么传输会我的发送端得,应用层面上有ip协议,这个是怎么做到的 直接寄,没有了解过, 面试官:(可能觉得没有希望了),直接问我我和其它同学相比有什么优势 瞎扯ing…. 面试官:高数、概率论成绩怎么样,切比雪夫不等式了解过吗 高数,概率论当时成绩还可以,但是现在基本都忘光了,切比雪夫不等式我记得是概率论的,现在有点忘记了,抱歉啊 今典反问: 我有什么需要改进的吗 基础可以,但是学习东西不能只看重表面,编程是一个与时俱进,日新月异的,要注重持续学习 自我反思:为什么我的面试和别人的不一样啊,我看别人面经的东西我都没有考到,背了那么长时间面经好像没有用到,有点郁郁,感觉有点想kpi面,上次我答得很垃圾,过了两天给我发二面了,当时以为裂开了,兄弟门判断一下这个是不是kpi面
二、