shopee虾皮 java后端 一面面经 整体感觉不难


面试总结:总体不难,算法题脑抽了只过了一半,面试官点出了问题说时间到了,反问一点点,感觉五五开,许愿一个二面
1.Java中的锁机制,什么是可重入锁
Java中的机制主要包括
-
synchronized关键字 -
Lock接口及其实现类(
如ReentrantLock) -
原子类(如
AtomicInteger) -
volatile关键字,仅保证可见性和有序性
可重入锁
可重入锁是指同一个线程在外层方法获取锁的时候,再进入该线程的内层方法会自动获取锁,不会因为之前已经获取过还没释放而阻塞。Java中ReentrantLock和synchronized都是可重入锁。
可重入锁的实现原理:
- 记录锁的持有线程
- 维护一个计数器
- 当计数器为0时,表示锁没有被任何线程持有
- 当持有锁的线程再次请求锁时,计数器+1
- 当线程退出同步代码块时,计数器-1
- 计数器为0时释放锁
可重入锁的优点:
- 避免死锁
- 提高了锁的灵活性
2.AQS (AbstractQueuedSynchronizer)
AQS是Java并发包中的核心基础组件,用于构建锁或者其他同步组件。
AQS使用一个int成员变量表示同步状态,通过内置的FIFO队列来完成资源获取线程的排队工作。
AQS的核心思想:
- 如果被请求的共享资源空闲,则将当前请求资源的线程设置为有效的工作线程,并且将共享资源设置为锁定状态。
- 如果被请求的共享资源被占用,那么就需要一套线程阻塞等待以及被唤醒时锁分配的机制。
AQS的主要方法:
acquire(int): 独占式获取同步状态release(int): 独占式释放同步状态acquireShared(int): 共享式获取同步状态releaseShared(int): 共享式释放同步状态
AQS的实现:
- 使用一个
volatile的int类型的成员变量来表示同步状态 - 使用一个FIFO队列来完成资源获取的排队工作
- 使用
CAS来原子性地修改同步状态值
AQS的应用:
- ReentrantLock
- Semaphore
- CountDownLatch
- ReentrantReadWriteLock
- ThreadPoolExecutor
3.Redis相关数据结构,为什么每种数据类型一般都有两种数据结构?
Redis的主要数据结构
- String: 简单动态字符串(SDS)
- List: 双向链表和压缩列表(ziplist)
- Hash: 哈希表和压缩列表
- Set: 哈希表和整数集合(intset)
- Sorted Set: 跳表(skiplist)和压缩列表
每种数据类型一般都有两种数据结构的原因
- 空间和时间的权衡
- 数据量小的时候使用更加紧凑的数据结构,节省内存
- 数据量大的时候转换为普通数据结构,提高操作效率
以Hash为例:
- 当field-value长度较短且个数较少时,使用压缩列表
- 当数据量增大时,转换为哈希表
这种设计能够在内存使用和性能之间取得很好的平衡。
4.JVM相关内存结构,GC
JVM内存结构
- 堆(Heap)
- 年轻代(Young Generation)
- Eden空间
- Survivor空间(From和To)
- 老年代(Old Generation)
- 年轻代(Young Generation)
- 方法区(Method Area)
- 永久代(JDK 8之前)/元空间(JDK 8及以后)
- 程序计数器(Program Counter Register)
- 虚拟机栈(VM Stack)
- 本地方法栈(Native Method Stack)
GC(垃圾回收)
垃圾回收算法:
- 标记-清除算法
- 复制算法
- 标记-整理算法
- 分代收集算法
垃圾收集器:
- Serial收集器
- ParNew收集器
- Parallel Scavenge收集器
- Serial Old收集器
- Parallel Old收集器
- CMS收集器
- G1收集器
GC触发时机:
- Minor GC:清理新生代。
- Major GC:清理老年代。
- Full GC:清理整个堆,包括新生代和老年代。
5.HashMap底层原理
HashMap的底层数据结构是数组+链表+红黑树(JDK 1.8及以后)。
主要属性:
- Node<K,V>[] table: 存储数据的数组
- int size: 实际存储的键值对数量
- int threshold: 扩容阈值
- float loadFactor: 负载因子
put操作流程:
- 对key的
hashCode()进行hash操作 - 计算index =
(n - 1) & hash - 如果没碰撞,直接放到bucket里
- 如果碰撞,以链表的形式存在buckets后
- 如果链表长度超过8,转换为红黑树
- 如果size超过threshold,进行扩容
get操作流程:
- 对key的
hashCode()进行hash操作 - 计算index =
(n - 1) & hash - 遍历该位置上的链表或红黑树
扩容机制:
- 当size超过
threshold时进行扩容 - 扩容时,容量变为原来的2倍
- 重新计算每个元素在数组中的位置(再散列)
6.MySQL索引类型,索引失效,覆盖索引,hash索引
MySQL索引类型
- B+树索引(默认)
- Hash索引
- Full-text全文索引
索引失效的情况
- 使用!=或<>操作符
- 使用函数或表达式
- 类型隐式转换
- 使用OR连接条件
- like以%开头
- 不满足最左前缀原则
覆盖索引
查询的数据列恰好是索引的一部分,可以直接从索引中获取数据,不需要回表查询。
Hash索引
- 基于哈希表实现,只有精确匹配才有效
- 不支持范围查询
- 不支持排序
- 不支持部分索引列匹配查找
Hash索引 vs B+树索引:
- Hash索引只支持等值查询,B+树索引支持范围查询
- Hash索引不支持排序,B+树索引天然支持排序
- Hash索引不支持最左前缀匹配,B+树索引支持
7.Spring IOC AOP原理,循环依赖解决
IOC(控制反转)
- 核心是BeanFactory和ApplicationContext
- 通过反射机制实例化bean并建立bean之间的依赖关系
- 管理bean的生命周期
AOP(面向切面编程)
- 核心是ProxyFactory
- 两种代理方式:JDK动态代理和CGLIB
- 通过织入切面来实现功能的统一维护
循环依赖解决
Spring通过三级缓存解决循环依赖
- 一级缓存,singletonObjects: 完全初始化好的bean
- 二级缓存,earlySingletonObjects: 实例化但未初始化的bean
- 三级缓存,singletonFactories: 存放BeanFactory的实例
解决流程:
- 创建bean实例
- 将创建的bean实例放入三级缓存
- 填充属性
- 如果发现循环依赖,尝试从三级缓存中获取
- 没有循环依赖,将bean放入一级缓存
构造函数的循环依赖无法解决,因为实例化和初始化是一体的。
8.MyBatis相关,#和$区别
MyBatis是一个优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射。
#{}和${}的区别:
- #{}是预编译处理,会将参数替换为?
- ${}是字符串替换,直接将参数值拼接到SQL中
使用场景:
- #{}用于SQL语句中的值
- ${}用于动态表名、列名等
安全性:
- #{}可以防止SQL注入
- ${}不能防止SQL注入
9.线程池相关,流程,拒绝策略,如何设计线程池最大线程数和核心线程数
线程池执行流程
- 如果运行的线程少于
corePoolSize,则创建新线程来处理请求 - 如果运行的线程等于或多于corePoolSize,则将请求加入队列
- 如果无法将请求加入队列,则创建新的线程来处理请求
- 如果创建新线程使当前运行的线程超出
maximumPoolSize,任务将被拒绝
拒绝策略
AbortPolicy: 丢弃任务并抛出RejectedExecutionException异常(默认)DiscardPolicy: 丢弃任务,但是不抛出异常DiscardOldestPolicy: 丢弃队列最前面的任务,然后重新尝试执行任务CallerRunsPolicy: 由调用线程处理该任务
如何设计线程池最大线程数和核心线程数
- CPU密集型任务: 线程数 = CPU核心数 + 1
- IO密集型任务: 线程数 = CPU核心数 * (1 + 平均等待时间/平均工作时间)
一般而言:
- 核心线程数 = CPU核心数
- 最大线程数 = CPU核心数 * 2
实际应用中,可以通过压测来确定最优的线程池参数。
10.HashMap和ConcurrentHashMap
HashMap:
- 非线程安全
- 允许null键和null值
- 初始容量16,负载因子0.75
- JDK 1.8后,链表长度超过8会转换为红黑树
ConcurrentHashMap:
- 线程安全
- 不允许null键和null值
- JDK 1.7使用分段锁(Segment)
- JDK 1.8使用CAS+Synchronized
ConcurrentHashMap的实现(JDK 1.8):
- 使用
volatile数组保存Node - 使用
CAS操作保证数组的原子性 - 使用
Synchronized锁定链表或红黑树的首节点
put操作:
- 如果bucket为空,使用CAS操作放入
- 如果bucket非空,使用Synchronized锁定首节点
- 执行链表或红黑树的插入操作
get操作:
- 不需要加锁,利用volatile的可见性保证
11.红黑树,二叉查找树,红黑树高度差
二叉查找树:
- 左子树所有节点的值均小于根节点的值
- 右子树所有节点的值均大于根节点的值
- 左右子树也分别为二叉查找树
- 时间复杂度: 平均O(logn),最坏O(n)
红黑树:
- 每个节点要么是红色,要么是黑色
- 根节点是黑色
- 每个叶子节点(NIL)是黑色
- 如果一个节点是红色的,则它的子节点必须是黑色的
- 从一个节点到该节点的子孙节点的所有路径上包含相同数目的黑节点
红黑树的高度:
- 最短路径: 全黑节点
- 最长路径: 红黑相间
- 最长路径的长度不会超过最短路径的2倍
红黑树 vs 平衡二叉树:
- 红黑树牺牲了部分平衡性以换取插入/删除操作时少量的旋转操作
- 红黑树的统计性能要好于平衡二叉树
12.MySQL索引
MySQL索引类型
- 普通索引
- 唯一索引
- 主键索引
- 联合/组合索引
- 全文索引
B+树索引的特点:
- 所有数据都存储在叶子节点
- 叶子节点形成一个单向链表
- 非叶子节点只存储键值信息
索引的优点:
- 加快数据检索速度
- 唯一索引可以保证数据的唯一性
- 加快表与表之间的连接
索引的缺点:
- 占用额外的存储空间
- 降低更新表的速度
13.如何判断链表有环,如何判断树是二叉查找树
判断链表是否有环
快慢指针法
- 定义两个指针,快指针每次移动两步,慢指针每次移动一步
- 如果存在环,两个指针最终会相遇
- 时间复杂度O(n),空间复杂度O(1)
哈希表法
- 遍历链表,将每个节点存入哈希表
- 如果当前节点已在哈希表中,说明存在环
- 时间复杂度O(n),空间复杂度O(n)
判断树是否为二叉搜索树:
中序遍历法
- 对二叉树进行中序遍历,结果应该是升序的
递归法
- 递归判断,利用二叉搜索树的性质,对于每个节点,它的左子节点值必须小于当前节点值,右子节点的值必须大于当前节点值,并且所有节点需要满足这个条件。
14.Redis分布式锁
Redis分布式锁的实现原理
- 加锁: 使用SETNX命令设置一个键值对,如果键不存在则设置成功并获得锁
- 解锁: 删除该键值对
- 超时: 设置键的过期时间,防止死锁
实现细节
- 使用Lua脚本保证加锁操作的原子性
- 使用唯一标识符(如UUID)作为值,防止误删其他客户端的锁
- 考虑Redis主从复制的延迟问题,使用Redlock算法
15.限流算法
- 计数器算法:基于时间窗口的请求数统计。
- 滑动窗口:将计数器细分成多个更小的时间窗口。
- 令牌桶算法:维持一个令牌桶,系统请求需拿到令牌。
- 漏桶算法:确保请求处理的稳定速率,通过漏水的速率控制请求速率。
更多惊喜
我还将定期分享:
-
最新互联网资讯:让你时刻掌握行业动态。
-
AI前沿新闻:紧跟技术潮流,不断提升自我。
-
技术分享与职业发展:助你在职业生涯中走得更远、更稳。
-
程序员生活趣事:让你在忙碌的工作之余找到共鸣与乐趣。
关注回复【1024】惊喜等你来拿!

敬请关注【程序员世杰】

相关文章:
shopee虾皮 java后端 一面面经 整体感觉不难
面试总结:总体不难,算法题脑抽了只过了一半,面试官点出了问题说时间到了,反问一点点,感觉五五开,许愿一个二面 1.Java中的锁机制,什么是可重入锁 Java中的机制主要包括 synchronized关键字 Loc…...
HydraRPC: RPC in the CXL Era——论文阅读
ATC 2024 Paper CXL论文阅读笔记整理 问题 远程过程调用(RPC)是分布式系统中的一项基本技术,它允许函数在远程服务器上通过本地调用执行来促进网络通信,隐藏底层通信过程的复杂性简化了客户端/服务器交互[15]。RPC已成为数据中心…...
pve笔记
配置显卡直通参考 https://blog.csdn.net/m0_59148723/article/details/130923893 https://foxi.buduanwang.vip/virtualization/pve/561.html/ https://www.cnblogs.com/MAENESA/p/18005241 https://www.wangsansan.com/archives/181/ pve配置显卡直通到虚拟机后,…...
typecho仿某度响应式主题Xaink
新闻类型博客主题,简洁好看,适合资讯类、快讯类、新闻类博客建站,响应式设计,支持明亮和黑暗模式 直接下载 zip 源码->解压后移动到 Typecho 主题目录->改名为xaink->启用。 演示图: 下载链接: t…...
springcloud RocketMQ 客户端是怎么走到消费业务逻辑的 - debug step by step
springcloud RocketMQ ,一个mq消息发送后,客户端是怎么一步步拿到消息去消费的?我们要从代码层面探究这个问题。 找的流程图,有待考究。 以下我们开始debug: 拉取数据的线程: PullMessageService.java 本…...
GPT-4o mini小型模型具备卓越的文本智能和多模态推理能力
GPT-4o mini 是首个应用OpenAI 指令层次结构方法的模型,这有助于增强模型抵抗越狱、提示注入和系统提示提取的能力。这使得模型的响应更加可靠,并有助于在大规模应用中更安全地使用。 GPT-4o mini 在学术基准测试中,无论是在文本智能还是多模…...
Milvus 向量数据库进阶系列丨部署形态选型
本系列文章介绍 在和社区小伙伴们交流的过程中,我们发现大家最关心的问题从来不是某个具体的功能如何使用,而是面对一个具体的实战场景时,如何选择合适的向量数据库解决方案或最优的功能组合。在 “Milvus 向量数据库进阶” 这个系列文章中&…...
【React】详解受控表单绑定
文章目录 一、受控组件的基本概念1. 什么是受控组件?2. 受控组件的优势3. 基本示例导入和初始化定义函数组件处理输入变化处理表单提交渲染表单导出组件 二、受控组件的进阶用法1. 多个输入框的处理使用多个状态变量使用一个对象管理状态 2. 处理选择框(…...
使用puma部署ruby on rails的记录
之前写过一篇《记录一下我的Ruby On Rails的systemd服务脚本》的记录,现在补上一个比较政治正确的Ruby On Rails的生产环境部署记录。使用Puma部署项目。 创建文件 /usr/lib/systemd/system/puma.service [Unit] DescriptionPuma HTTP Server DocumentationRuby O…...
如何在Linux上使用Ansible自动化部署
Ansible是一个开源的自动化工具,可以帮助开发人员和系统管理员对大规模的服务器进行自动化部署和管理。它使用SSH协议来在远程服务器上执行任务,并通过模块化的方式提供了丰富的功能,可以轻松地管理服务器配置、软件部署和应用程序运行。 在…...
scrapy爬取城市天气数据
scrapy爬取城市天气数据 一、创建scrapy项目二、修改settings,设置UA,开启管道三、编写爬虫文件四、编写items.py五、在weather.py中导入WeatherSpiderItem类六、管道中存入数据,保存至csv文件七、完整代码一、创建scrapy项目 先来看一下爬取的字段情况: 本次爬取城市天…...
一天搞定React(5)——ReactRouter(下)【已完结】
Hello!大家好,今天带来的是React前端JS库的学习,课程来自黑马的往期课程,具体连接地址我也没有找到,大家可以广搜巡查一下,但是总体来说,这套课程教学质量非常高,每个知识点都有一个…...
微信小程序之计算器
在日常生活中,计算器是人们广泛使用的工具,可以帮助我们快速且方便地计算金额、成本、利润等。下面将会讲解如何开发一个“计算器”微信小程序。 一、开发思路 1、界面和功能 “计算器”微信小程序的页面效果如图所示 在计算器中可以进行整数和小数的…...
【logstash】logstash使用多个子配置文件
这里有个误区在pipelines.yml中写conf.d/*,实测会有问题,不同的filter处理逻辑会复用。 现在有两个从kafka采集日志的配置文件:from_kafka1.conf,from_kafka2.conf 修改pipelines.yml配置文件 config/pipelines.yml- pipeline.i…...
暴风骑士S9电摩上市,定义青少年骑行安全新标准
暴风骑士,作为全球高端儿童电动车的开创品牌,以其卓越的技术实力和创新精神,不断推动行业发展。如今,暴风骑士再次突破自我,推出了全新力作——S9青少年电摩。这款全新上市的青少年专属电摩,以其领先的安全…...
spring security如何适配盐存在数据库中的密码
19.token认证过滤器代码实现_哔哩哔哩_bilibili19.token认证过滤器代码实现是SpringSecurity框架教程-Spring SecurityJWT实现项目级前端分离认证授权-挑战黑马&尚硅谷的第20集视频,该合集共计41集,视频收藏或关注UP主,及时了解更多相关视…...
Go语言编程 学习笔记整理 第2章 顺序编程 后半部分
1.流程控制 1.1 条件语句 if a < 5 { return 0 } else { return 1 } 注意:在有返回值的函数中,不允许将“最终的”return语句包含在if...else...结构中, 否则会编译失败!!! func example(x int) i…...
美团后端二面
美团后端二面 ……………………………… 两道场景 一道 数字转中文读法(1000-》一千) 0八股0自我介绍 反问 “您觉得我能过吗?” “这个需要横行对比之后才能有结果” ……………………………… 什么时候到岗 场景题 1 假设我有一个…...
学懂C语言(十六):对C语言作用域规则 局部变量、全局变量的认识
一、C 作用域规则 任何一种编程中,作用域是程序中定义的变量所存在的区域,超过该区域变量就不能被访问。C 语言中有三个地方可以声明变量: 局部变量:在函数或块内部全局变量:在所有函数外部形式参数:在函数…...
关于TS(typescript)的理论知识
关于TS(typescript)的理论知识 TypeScript 是一种由微软开发的开源编程语言,它是 JavaScript 的一个超集,添加了可选的静态类型和基于类的面向对象编程。TypeScript 最终会被编译成纯 JavaScript 代码,以便在任何支持 …...
转转集团旗下首家二手多品类循环仓店“超级转转”开业
6月9日,国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解,“超级…...
ffmpeg(四):滤镜命令
FFmpeg 的滤镜命令是用于音视频处理中的强大工具,可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下: ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜: ffmpeg…...
BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...
JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案
JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停 1. 安全点(Safepoint)阻塞 现象:JVM暂停但无GC日志,日志显示No GCs detected。原因:JVM等待所有线程进入安全点(如…...
【Android】Android 开发 ADB 常用指令
查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...
Rust 开发环境搭建
环境搭建 1、开发工具RustRover 或者vs code 2、Cygwin64 安装 https://cygwin.com/install.html 在工具终端执行: rustup toolchain install stable-x86_64-pc-windows-gnu rustup default stable-x86_64-pc-windows-gnu 2、Hello World fn main() { println…...
Leetcode33( 搜索旋转排序数组)
题目表述 整数数组 nums 按升序排列,数组中的值 互不相同 。 在传递给函数之前,nums 在预先未知的某个下标 k(0 < k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k1], …, nums[n-1], nums[0], nu…...
算法打卡第18天
从中序与后序遍历序列构造二叉树 (力扣106题) 给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。 示例 1: 输入:inorder [9,3,15,20,7…...
Redis上篇--知识点总结
Redis上篇–解析 本文大部分知识整理自网上,在正文结束后都会附上参考地址。如果想要深入或者详细学习可以通过文末链接跳转学习。 1. 基本介绍 Redis 是一个开源的、高性能的 内存键值数据库,Redis 的键值对中的 key 就是字符串对象,而 val…...
用 FFmpeg 实现 RTMP 推流直播
RTMP(Real-Time Messaging Protocol) 是直播行业中常用的传输协议。 一般来说,直播服务商会给你: ✅ 一个 RTMP 推流地址(你推视频上去) ✅ 一个 HLS 或 FLV 拉流地址(观众观看用)…...
