作者:沉默王二
让天下所有的面渣都能逆袭😄
TP-LINK 联洲也开奖了,并且有球友给出的年包让人完全无法拒绝,我也统计了一波放到了《Java 面试指南》中供大家参考。
985 本华五硕给到 50 万的年包,软件开发方向,并且学长说联洲这两年处于业务上升期,年终能给到 5 个月。
南京大学给到 22k,年终 4 个月,并且在逼签两方了,违约金 3000
硕士 985 结构方向只给了 17k,纯粹的劝退价
硕士 985 后天开发给到 27k,算是 SSP 了,一年算下来也逼近 50 万年包了。
我只能说,成都地区能开到 50 万这么高的年包真的很舒服了,可以活的很潇洒。要我说,能给这个数就只管冲,至于网上那些风评差的说法可以完全忽视,我就没见过哪个公司没有负面评论。
换句话说,公司愿意给你这么多钱,你去了就会发展的很好,毕竟公司要从你身上赚回来这么多钱才能顾住本,不然不就亏损了嘛。
那我也找了一份《TP-LINK 联洲同学 5的面经》放在了 Java 面试指南中,大家一起来学习一下。
TP-LINK联洲一面
日常用的编程语言
大一上先学习的 C 语言,大一下半学期开始学习 Java,中间还学过一些 Python 和 JavaScript,但整体的感受上来说还是最喜欢 Java。
因为它可以做的事情太多了,既可以用它来爬一些数据做测试,还可以用它来写 Web 后端服务,就连一些轮子也可以用它来造,比如说我之前写过一个 MYDB 的轮子,就是用的 Java。
项目的优化在哪
技术派项目做了蛮多的性能优化,比如说前端静态资源通过 Nginx 进行缓存、压缩、CDN 分发,后端返回结果通过 Spring Boot 压缩,接口请求数据时串行改并行,加本地缓存 Caffeine 以及分布式缓存 Redis,通过 Spring 的事件管理机制、RabbitMQ 进行异步通知,再比如说合理的库表设计(如索引、分页),代码中减少锁的范围,使用池化技术(Druid、HikariCP),以及在使用 MySQL 或者 Redis 的时候采用批处理等。
二哥的编程星球:技术派性能优化
Jwt具体怎么做认证怎么校验
首先,用户通过提交用户名和密码进行登录,服务器验证后会生成一个 JWT,包含用户的身份信息(如用户 ID、权限等),并使用一个密钥对 JWT 进行签名。服务器返回 JWT 给客户端,客户端在后续的请求中将该 JWT 放入 Authorization 头部。
在服务器收到带有 JWT 的请求后,首先会解码 JWT,并使用事先约定的密钥进行签名验证,确保 JWT 未被篡改。接着会检查 JWT 的过期时间、签发者等字段,确保其合法性和有效性。校验通过后,服务器从 JWT 中提取用户信息并进行权限判断,决定是否允许访问请求的资源。
二哥的编程星球:技术派 JWT 验证流程
扫码登录具体的实现
用户在 PC 网页端登录时,生成一个唯一的二维码,绑定请求端的身份信息,网页客户端和服务端保持链接,等待手机端扫描二维码获取授权 URL,微信端扫码登录成功后回调服务端接口(附带用户身份信息),并传回给应用服务器,完成登录。登录成功后,服务器生成一个 JWT 或 Session 并返回给 PC 端,用户完成登录。
二哥的编程星球:技术派扫码登录方案
如何解决缓存穿透
面渣逆袭中第 6 次出现。
缓存穿透是指查询不存在的数据,由于缓存没有命中(因为数据根本就不存在),请求每次都会穿过缓存去查询数据库。如果这种查询非常频繁,就会给数据库造成很大的压力。
三分恶面渣逆袭:缓存穿透
缓存穿透意味着缓存失去了减轻数据压力的意义。
它主要有两种解决办法:
①、
缓存空值/默认值
客户端请求某个 ID 的数据,首先检查缓存是否命中。如果缓存未命中,查询数据库。如果数据库查询结果为空,将该空结果(如 null 或 {})缓存起来,并设置一个合理的过期时间。当后续请求再访问相同 ID 时,缓存直接返回空结果,避免每次都打到数据库。
三分恶面渣逆袭:缓存空值/默认值
②、
布隆过滤器
通过布隆过滤器存储所有可能存在的合法数据的键,当请求到达时,先通过布隆过滤器判断该键是否存在:
如果布隆过滤器认为该键不存在,直接返回空,不会查询数据库。
如果布隆过滤器认为该键可能存在,则查询缓存和数据库。
三分恶面渣逆袭:布隆过滤器
布隆过滤器原理
面渣逆袭中第 1 次出现。
布隆过滤器(Bloom Filter)是一种空间效率极高的概率型数据结构,用于快速检查一个元素是否存在于一个集合中。
布隆过滤器由一个长度为 m 的位数组和 k 个哈希函数组成。
当一个元素被添加到过滤器中时,它会被 k 个哈希函数分别计算得到 k 个位置,然后将位数组中对应的位设置为 1。
当检查一个元素是否存在于过滤器中时,同样使用 k 个哈希函数计算位置,如果任一位置的位为 0,则该元素肯定不在过滤器中;如果所有位置的位都为 1,则该元素可能在过滤器中。
三分恶面渣逆袭:布隆过滤器
这种方式下5%的错误率可接受?
面渣逆袭中第 1 次出现。
布隆过滤器的优点是空间效率和查询时间都远远超过一般的算法,缺点是存在误判和删除困难。
勇哥:布隆过滤器
当布隆过滤器保存的元素越多,被置为 1 的 bit 位就会越多。假设元素 x 没有存储过,但其他元素的哈希函数映射到位数组的三个位刚好都为 1 且恰好覆盖了元素 x 映射的位置,那么对于布隆过滤器来讲,元素 x 这个值就是存在的,也就是说布隆过滤器存在一定的误判率。
布隆过滤器的误判率取决于以下几个因素:
位数组的大小(m):位数组的大小决定了可以存储的标志位数量。如果位数组过小,那么哈希碰撞的几率就会增加,从而导致更高的误判率。
哈希函数的数量(k):哈希函数的数量决定了每个元素在位数组中标记的位数。哈希函数越多,碰撞的概率也会相应变化。如果哈希函数太少,则过滤器很快会变得不精确;如果太多,误判率也会升高,效率下降。
存入的元素数量(n):存入的元素越多,哈希碰撞的几率越大,从而导致更高的误判率。
勇哥:布隆过滤器的误判
误判率公式如下:
虽然布隆过滤器会产生误判,但在很多场景下一定的误判率是可以接受的,这是因为布隆过滤器的主要优点是其高效的查询速度和低内存占用。相比其他精确的集合数据结构(如哈希表、树等),布隆过滤器可以在空间效率和查询速度上表现更优。
Jvm内存区域
面渣逆袭中第 14 次出现。
按照 Java 的虚拟机规范,JVM 的内存区域(JVM 的内存结构/JVM 运行时数据区)可以细分为
程序计数器
、
虚拟机栈
、
本地方法栈
、
堆
、
方法区
等。
三分恶面渣逆袭:Java虚拟机运行时数据区
其中
方法区
和
堆
是线程共享的,
虚拟机栈
、
本地方法栈
和
程序计数器
是线程私有的。
本地方法栈的运行场景
面渣逆袭中第 1 次出现。
当 Java 应用需要与操作系统底层或硬件交互时,通常会用到本地方法栈。
比如调用操作系统的特定功能,如内存管理、文件操作、系统时间、系统调用等。
举例:
System.currentTimeMillis()
就是调用本地方法来获取操作系统的当前时间。
二哥的Java 进阶之路:currentTimeMillis方法源码
再比如 JVM 自身的一些底层功能也需要通过本地方法来实现。像 Object 类中的
hashCode()
方法、
clone()
方法等。
二哥的Java 进阶之路:hashCode方法源码
Native方法解释一下
面渣逆袭中第 1 次出现。
Native 方法是在 Java 中通过 native 关键字声明的,用于调用非 Java 语言(如 C/C++)编写的代码。Java 可以通过 JNI(Java Native Interface)与底层系统、硬件设备、或高性能的本地库进行交互。
怎么保证多线程安全
面渣逆袭中第 3 次出现。
多线程安全是指在并发环境下,多个线程访问共享资源时,程序能够正确地执行,而不会出现数据不一致或竞争条件等问题。
为了保证线程安全,可以使用 synchronized 关键字或 ReentrantLock 来保证共享资源的互斥访问。
对于简单的变量操作,可以使用 Atomic 类来实现无锁线程安全。
可以使用线程安全容器,如 ConcurrentHashMap 或 CopyOnWriteArrayList。
对于每个线程独立的数据,可以使用 ThreadLocal 来为每个线程提供独立的变量副本。
对于简单的状态标志,可以使用 volatile 关键字确保多线程间的可见性。
Hashtable数据结构 底层
面渣逆袭中第 1 次出现。
与 HashMap 类似,Hashtable 的底层数据结构也是一个数组加上链表的方式,然后通过 synchronized 加锁来保证线程安全。
二哥的Java 进阶之路:Hashtable源码
Tcp三次握手