淘天Java一面,难度适中!(上篇)
1.公司介绍
淘天集团是阿里巴巴集团全资拥有的业务集团,全球领先的科技商业公司。 淘天集团以淘宝 APP 为主要服务载体,构建国内国际供给、线上线下场景、远场近场履约相结合的商业矩阵,汇聚数十万全球和中国品牌、上千万中小商家及内容创作者,满足 9 亿中国消费者多元化、个性化、品质化的生活需求。
淘天集团拥有淘宝、天猫、1688、闲鱼等商业品牌,并通过天猫国际、淘宝直播、天猫超市、淘宝买菜、阿里妈妈等业务,提供进口、直播、超市、买菜、数字营销等服务。按 GMV 计算,淘宝是中国最大的数字零售平台;由天猫首创的双 11 全球狂欢季,已经成为全球最大的购物节之一。 未来三年,淘天集团将全力实施用户为先、生态繁荣、科技驱动三大战略,在继续服务最大规模消费者和商家的同时,逐步升级为一个一站式的消费及生活平台。
也就是说,“淘天”就是“淘宝”+“天猫”的结合。
2.面试背景
面试岗位:Java 开发工程师
面试时间:2023.10.28
3.面试问题
- 为什么要用 Redis?有预估 QPS 的提升幅度吗?
- Redis 内存不够用怎么办?
- 是否定义、设计过业务模型?
- 百万级用户规模服务上线的话需要做什么?
- JVM 怎么创建一个对象?
- 有哪些场景会触发类的加载?
- 双亲委派机制,如果不按这种会有什么问题?
- 线程状态,一个线程包含哪些信息?
- 线程池执行任务的过程?
- 线程同步有哪些策略和类,有没有实测过关键字的性能?
- SpringBoot 搭建的 Web 服务处理过程?
- 有没有看过开源框架的源码,举一个例子讲讲?
4.答案解析
问题1:为什么要用 Redis?有预估 QPS 的提升幅度吗?
答案解析思路:为什么用 Redis?回答 Redis 的优势即可。 QPS(Queries Per Second,每秒钟查询次数)的问题可以使用 Redis 性能测试报告中的数据即可。
Redis 优势有以下几个:
- 基于内存:Redis 是一种基于内存的数据存储系统,所有的数据都存储在内存中。相比传统的磁盘存储系统,内存访问速度更快,这使得 Redis 能够在毫秒级别快速地读取和写入数据。
- 单线程模型:Redis 使用单线程模型来处理客户端请求。这可能听起来似乎效率不高,但实际上,这种设计有助于避免多线程的竞争条件和锁开销。Redis 通过非阻塞的方式处理多个客户端请求,每个请求的执行时间很短,因此在单线程下,Redis 能够处理大量的并发请求。
- 高效数据结构:Redis 提供了多种高效的数据结构,如哈希表、有序集合等。这些数据结构的实现都经过了优化,使得 Redis 在处理这些数据结构的操作时非常高效。
- 非阻塞 I/O:Redis 使用了非阻塞 I/O 模型,这意味着当进行磁盘读写或者网络通信时, Redis 不会等待数据的返回,而是继续处理其他请求。这样可以充分利用 CPU 的时间,提高整体的吞吐量。
Redis 官方性能测试报告地址:https://redis.io/docs/management/optimization/benchmarks/
答案加分项:除了官方的性能测试数据之后,还可以使用 Redis 自带的性能测试工具 redis-benchmark l来对当前环境下的 Redis 做性能测试和预测,但也需要注意,网络带宽和网络延迟可能是 Redis 操作最大的性能瓶颈。
问题2:Redis 内存不够用怎么办?
答案解析思路:Redis 内存不够用时,会触发 Redis 内存淘汰策略。
早期版本的 Redis 有以下 6 种淘汰机制(也叫做内存淘汰策略):
- noeviction:不淘汰任何数据,当内存不足时,新增操作会报错,Redis 默认内存淘汰策略;
- allkeys-lru:淘汰整个键值中最久未使用的键值;
- allkeys-random:随机淘汰任意键值;
- volatile-lru:淘汰所有设置了过期时间的键值中最久未使用的键值;
- volatile-random:随机淘汰设置了过期时间的任意键值;
- volatile-ttl:优先淘汰更早过期的键值。
在 Redis 4.0 版本中又新增了 2 种淘汰机制:
- volatile-lfu:淘汰所有设置了过期时间的键值中,最少使用的键值;
- allkeys-lfu:淘汰整个键值中最少使用的键值。
其中 allkeys-xxx 表示从所有的键值中淘汰数据,而 volatile-xxx 表示从设置了过期键的键值中淘汰数据。
所以,现在 Redis 的版本中有 8 种内存淘汰策略。
答案扩展:当然你还可以通过设置 Redis 的最大运行内存来尽量避免这个问题,它的设置步骤
- 打开 Redis 的配置文件:在 Redis 的安装目录下找到 redis.conf 文件,使用文本编辑器打开该文件。
- 找到并修改 maxmemory 参数:在配置文件中,搜索并找到名为"maxmemory"的参数,该参数控制 Redis 的最大内存限制。默认情况下,该参数被注释掉,即 Redis 不会限制内存使用。
- 设置 maxmemory 的值:取消注释 "maxmemory" 参数,并将其值设置为期望的运行内存大小。值可以使用单位 K、M、G 来表示,如"1G"表示 1GB 内存。确保设置的内存大小合理,不要超过可用物理内存的限制。
- 配置内存淘汰策略:在 Redis 超过设置的最大内存限制时,需要根据配置的策略来决定如何清理数据。找到并修改"maxmemory-policy"参数,可以选择使用的内存逐出策略,如 volatile-lru、allkeys-lru、volatile-random 等。
- 保存配置文件:保存对 redis.conf 文件的修改。
- 重启 Redis 服务:重新启动 Redis 服务,使新的配置生效。
问题3:是否定义、设计过业务模型?
答案解析思路:这个问题看似“高大上”,但其实非常简单。所谓的业务模型就是将需求转换成程序之后,设计的数据库和数据表,所以在开发中你一定定义过或设计过业务模型。
在软件开发过程中,业务模型是一种抽象表示,用于描述系统中涉及的业务实体、其属性和关系,以及业务流程。
定义和设计业务模型的过程涉及以下几个方面:
- 理解业务需求:首先,需要与业务团队密切合作,深入了解业务需求。这包括了解业务流程、业务规则以及业务参与者之间的关系。
- 分析业务实体:根据业务需求,将业务实体抽象成模型中的类或对象。这些实体可能包括产品、用户、订单等,每个实体都有相应的属性和行为。
- 建立关系和依赖:在业务模型中,不同实体之间可能存在关系和依赖,如一对一、一对多、多对多等关系。需要根据业务需求,确定和定义这些关系。
- 设计业务逻辑:根据业务需求,确定业务模型中的行为和业务逻辑。这些逻辑可以通过方法、规则或者流程来表示,以实现业务的各种操作和处理。
- 持久化与数据模型:将业务模型映射到数据模型,用于在持久化介质(如数据库)中存储和检索数据。这涉及选择合适的数据结构和数据库设计,以及确保业务模型与数据模型的一致性。
在设计数据库的整个过程中,要遵循数据库的“三范式”。
数据库的三范式是指关系型数据库设计中的三个规范化级别,用于优化数据存储和查询的效率,提高数据的一致性和可维护性。
这三个范式分别是:
- 第一范式(1NF):第一范式要求关系表中的每个属性(列)都是原子的,不可再分的。每个属性都应该包含单一的值,不允许存在重复的属性或属性中包含多个值。这样可以避免数据冗余和数据的不一致性。
- 第二范式(2NF):第二范式在满足第一范式的基础上,进一步要求表中的非主键属性完全依赖于主键属性。也就是说,表中不存在非主键属性对部分主键属性进行冗余的情况。通过将数据分解为更小的表和使用关联关系,可以减少数据冗余,并确保数据的一致性。
- 第三范式(3NF):第三范式在满足第二范式的基础上,进一步要求表中的非主键属性之间互不依赖。也就是说,表中的每个非主键属性只依赖于主键或其他非主键属性,不会存在传递依赖的情况。通过进一步的数据分解和建立外键关系,可以消除冗余数据和数据的多次更新。
遵循三范式的设计原则能够提高数据库的数据结构和查询效率,并减少数据冗余和依赖问题,从而提高数据库的性能和可维护性。但需要注意,在实际设计中需要根据具体的业务需求和查询需求进行灵活的取舍和权衡,不一定要求严格遵守三范式。
问题4:百万级用户规模服务上线的话需要做什么?
答案解析思路:百万级用户规模在上线的时候,主要考虑的是高可用和容错的处理。因为你的业务更新不能影响用户的正常使用,并且要做好上线前测试、以及灰度发布、备份及回滚等准备工作。
百万级用户规模需要考虑的主要内容有以下几方面:
- 架构设计与扩展性规划:确保服务具备良好的扩展性和可伸缩性,以应对大量用户的访问请求。这涉及到合理的系统架构设计、使用水平扩展和垂直扩展等技术手段。
- 性能测试和优化:进行全面的性能测试,模拟高并发、大数据量等场景,发现和解决系统瓶颈和性能问题。通过优化数据库查询、缓存使用、代码逻辑等方面,提高系统的响应速度和稳定性。
- 高可用和容错处理:确保服务在面对故障或意外情况时也能保持高可用性,不影响用户体验,所以尽量选择用户使用频率最低的时间段来更新,比如凌晨 3 点到 5 点之间。采用负载均衡、故障转移、备份恢复等机制,对关键系统组件进行容错处理。
- 安全性保障:加强系统的安全性,保护用户数据和隐私。进行安全性评估和漏洞扫描,采用合适的身份认证、访问控制、数据加密等技术手段,预防和防范潜在的安全威胁。
- 监控和日志记录:建立全面的系统监控和日志记录机制,及时发现和解决系统故障和异常。监控系统的性能指标、错误日志、访问日志等,保持对系统运行状态的实时了解,为及时处理问题提供依据。
- 客户支持和用户反馈:建立用户支持渠道,及时处理用户反馈和问题。通过建立客户服务团队、在线帮助文档、用户反馈收集等方式,积极跟进用户需求和问题,不断优化产品和服务。
问题5:JVM 怎么创建一个对象?
答案解析思路:JVM 创建对象的过程,其实就是 JVM 类加载的过程。
JVM 类加载可以分为以下几个阶段:
- 加载
- 链接
- 验证
- 准备
- 解析
- 初始化
具体内容如下。
① 加载
加载(Loading)阶段是整个“类加载”(Class Loading)过程中的一个阶段,它和类加载 Class Loading 是不同的,一个是加载 Loading 另一个是类加载 Class Loading,所以不要把二者搞混了。
在加载 Loading 阶段,Java 虚拟机需要完成以下 3 件事:
- 通过一个类的全限定名来获取定义此类的二进制字节流;
- 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构;
- 在内存中生成一个代表这个类的 java.lang.Class 对象,作为方法区这个类的各种数据的访问入口。
② 验证
验证是连接阶段的第一步,这一阶段的目的是确保 Class 文件的字节 流中包含的信息符合《Java虚拟机规范》的全部约束要求,保证这些信 息被当作代码运行后不会危害虚拟机自身的安全。
验证选项:
- 文件格式验证
- 字节码验证
- 符号引用验证...
③ 准备
准备阶段是正式为类中定义的变量(即静态变量,被static修饰的变量)分配内存并设置类变量初始值的阶段。
比如此时有这样一行代码:
public static int value = 123;
它是初始化 value 的 int 值为 0,而非 123。
④ 解析
解析阶段是 Java 虚拟机将常量池内的符号引用替换为直接引用的过程,也就是初始化常量的过程。
⑤ 初始化
初始化阶段,Java 虚拟机真正开始执行类中编写的 Java 程序代码,将主导权移交给应用程序。初始化阶段就是执行类构造器方法的过程。
答案扩展:你除了可以按照书本的方式去解释类加载的过程(加载 -> 验证 -> 准备 -> 解析 -> 初始化),你还可以选择使用比较通俗的方式来回答此问题,比如以下这样:
JVM 创建一个对象的流程主要有以下这些步骤:
- 类加载:首先,JVM 会通过类加载器加载对象所属的类。类加载器将字节码文件加载到内存中,并解析生成类的结构信息。
- 内存分配:在 JVM 的堆内存中分配对象的空间。堆是 Java 运行时数据区域之一,用于存储对象实例。
- 初始化属性:为对象的属性分配内存,并进行初始值赋值。这包括对象的成员变量、实例变量以及与对象相关的其他信息。
- 执行构造方法:调用对象的构造方法进行对象的初始化。构造方法在对象创建过程中被调用,用于完成对象的初始化工作,可以设置初始状态、初始化成员变量等。
- 返回引用:创建对象后,JVM 将返回一个指向该对象的引用。通过这个引用,可以在程序中操作和访问该对象。
但需要注意的是,JVM 在内存分配和对象创建过程中可能会做一些优化,如对象的重叠分配、内存预分配等技术手段,以提高对象创建的效率和性能。
问题6:有哪些场景会触发类的加载?
答案解析:在 Java 中,会触发类的加载的主要场景包括以下几种:
- 创建类的实例:当通过关键字
new
创建一个类的实例时,JVM 需要加载该类以创建对应的对象。 - 访问类的静态变量或静态方法:当访问一个类的静态变量或调用静态方法时,JVM 需要加载该类以获取对应的静态成员。
- 调用类的静态成员所在的类被加载:当访问一个类的静态成员,而该类的静态成员所在的类还没有被加载时,JVM 需要先加载该静态成员所在的类。
- 使用反射机制:当使用反射机制进行类的动态加载和操作时,JVM 会在运行时加载相应的类。
- 类型转换:当进行类型转换时(如将一个父类对象强制转换为子类对象),JVM 需要加载目标类型所对应的类。
需要注意的是,类的加载是按需进行的,即在运行时根据实际需要来加载。JVM 会采用懒加载的策略,尽可能避免不必要的类加载和资源消耗。
小结
文章内容篇幅以及作者精力的原因,所以咱们把淘天的面试题分为上、下两篇来完成,希望各位老铁多多体谅和包涵。个人能力有限,如有回答不正确或不完整之处,欢迎大家评论区留言指正和补充。
本文已收录到我的面试小站 www.javacn.site,其中包含的内容有:Redis、JVM、并发、并发、MySQL、Spring、Spring MVC、Spring Boot、Spring Cloud、MyBatis、设计模式、消息队列等模块。
淘天Java一面,难度适中!(上篇)的更多相关文章
- 淘宝JAVA中间件Diamond详解(2)-原理介绍
淘宝JAVA中间件Diamond详解(二)---原理介绍 大家好,通过第一篇的快速使用,大家已经对diamond有了一个基本的了解.本次为大家带来的是diamond核心原理的介绍,主要包括server ...
- Java基础语法(上篇)
Java基础语法(上篇) 知识概要: (1)关键字的表示与规范 (2)标示符 (3)注释 (4 ...
- 淘宝JAVA中间件Diamond详解之简介&快速使用 管理持久配置的系统
http://my.oschina.net/u/435621/blog/270483?p=1 淘宝JAVA中间件Diamond详解(一)---简介&快速使用 大家好,今天开始为大家带来我们通用 ...
- 淘宝JAVA中间件Diamond
以下是转载自网上资料,但是根据步骤可以搭建出diamond配置中心服务器. 项目中需要用到diamond的理由是, 项目中使用了很多定时任务和异步任务.而且这些定时任务和异步任务都是分布式的安排在多个 ...
- 淘宝JAVA中间件Diamond详解(一)---简介&快速使用
大家好,今天开始为大家带来我们通用产品团队的产品 —— diamond的专题,本次为大家介绍diamond的概况和快速使用. 一.概况 diamond是淘宝内部使用的一个管理持久配置的系统,它的特点是 ...
- java中难度大一点的面试题
1.请大概描述一下Vector和ArrayList的区别,Hashtable和HashMap的区别.(5) (1)Vector和ArrayList的异同 实现原理,功能相同,可以互用 主要区别: Ve ...
- Java面向对象 线程技术--上篇
Java面向对象 线程 知识概要: (1)线程与进程 (2)自定义线程的语法结构 (3)多线程概念理解 (4)多线程状态图 (5)多线程--卖票 (6)同 ...
- 淘宝JAVA中间件Diamond详解(二)---原理介绍
转:http://blog.csdn.net/anhuidelinger/article/details/70314744 大家好,通过第一篇的快速使用,大家已经对diamond有了一个基本的了解.本 ...
- Java中间件:淘宝网系统高性能利器(转)
淘宝网是亚太最大的网络零售商圈,其知名度毋庸置疑,吸引着越来越多的消费者从街头移步这里,成为其忠实粉丝.如此多的用户和交易量,也意味着海量的信息处理,其背后的IT架构的稳定性.可靠性也显得尤为重要.那 ...
- Java中间件:淘宝网系统高性能利器
[TechTarget中国原创]淘宝网是亚太最大的网络零售商圈,其知名度毋庸置疑,吸引着越来越多的消费者从街头移步这里,成为其忠实粉丝.如此多的用户和交易量,也意味着海量的信息处理,其背后的IT架构的 ...
随机推荐
- PostgreSQL 10 文档: SQL 语法
SQL 命令 这部分包含PostgreSQL支持的SQL命令的参考信息.每条命令的标准符合和兼容的信息可以在相关的参考页中找到. 目录 ABORT - 中止当前事务 ALTER AGGREGATE ...
- mysql系列03---事务
一.事务简介 事务是一组操作的集合,它是一个不可分割的工作单位,事务会把所有的操作作为一个整体一起向系统提交或撤销 操作请求,即这些操作要么同时成功,要么同时失败. 二.事物的四大特性 一个事务具有A ...
- enumerate()使用方法
enumerate()(单词意思是枚举的意思)是python中的内置函数, enumerate(X,[start=0]) 函数中的参数X可以是一个迭代器(iterator)或者是一个序列, start ...
- DHorse v1.3.0 发布,基于k8s的发布平台
综述 DHorse是一个简单易用.以应用为中心的云原生DevOps系统,具有持续集成.持续部署.微服务治理等功能,无需安装依赖Docker.Maven.Node等环境即可发布Java.Vue.Reac ...
- 创建本地yum仓库
创建本地yum仓库 1,将镜像挂载到/mnt 如果失败打开虚拟机把设备状态的两个选项打勾 2,切换到客户端的指定目录 3,创建文件夹bak存放网络yum创库配置文件 4,将网络源移动到bak减少干扰 ...
- 从ABNF读懂HTTP协议格式
定义 HTTP(Hyper Text Transfer Protocol)超文本传输协议 HTML( Hyper Text Markup Language)超文本标记语言 URI(Uniform Re ...
- redux的三个概念与三大核心
1.什么是redux?一个组件里可能会有很多的状态,比如控制某个内容显示的flag,从后端获取的展示数据,那么这些状态可以在自己的单个页面进行管理,也可以选择别的管理方式,redux就是是一种状态管理 ...
- 3.0 Python 迭代器与生成器
当我们需要处理一个大量的数据集合时,一次性将其全部读入内存并处理可能会导致内存溢出.此时,我们可以采用迭代器Iterator和生成器Generator的方法,逐个地处理数据,从而避免内存溢出的问题. ...
- Java 日志系列:JUL 使用和原理分析
目录 一. 简介 二.使用 三.日志级别 四.Logger 继承关系 五.配置文件 六.原理解析 一. 简介 JUL 全称 Java util Logging 是 java 原生的日志框架,使用时不需 ...
- 春秋云镜像-CVE-2022-0788
准备: 攻击机:win10. 靶机:春秋云镜像-CVE-2022-0788. 写这个的时候在网上想查找下该漏洞的利用方式,没有找到相关的资料,因此记录下自己通过这个靶场的poc与exp. curl ' ...