上海 JAVA开发工程师 薪资15-20K
职位描述
1、计算机或相关专业本科以上学历,3年以上相关工作经验,有电商行业经验,有架构经验者优先;
2、有良好的Java基础,对设计模式、领域模型、数据结构有较深入的理解,有JVM调优经验者优先;
3、对主流Java技术栈有比较深入的理解,熟悉Spring MVC/iBatis/Dubbo/Spring Boot/Spring Cloud等框架和技术原理;
4、熟练使用主流的中间件,并掌握其原理,如Redis、ElasticSearch、MQ、ZooKeeper等;
5、熟悉Mysql、ORACLE等数据库,熟悉数据库设计,熟悉SQL语句编写与优化;
6、熟悉Linux/Windows环境的搭建与项目的部署,以及故障排查和诊断;
7、具有很强的学习能力,分析复杂问题和解决复杂问题的能力,有强烈的责任心和使命感,良好的沟通表达能力和团队协作能力。
视频面试 时长20分钟
问了好多啊 答案我找的不一定对哈 欢迎纠正补充 🥲
1.扣库存是先扣的缓存么
方法一
并发不高、业务不复杂时可以直接用一条update语句更新数据库库存
方法二
并发高还使用数据库的话会造成大量请求阻塞,导致请求超时系统雪崩,校验库存后可以将创建订单扣库存的操作放到mq中,虽然有一定延迟性,但可以减轻数据库压力
方法三
并发高或一条update语句不能满足时可以将库存放入缓存中,用redis+lua脚本的方式扣库存
2.缓存扣减怎么保证原子性
Redis使用单个Lua解释器去运行所有脚本,并且Redis也保证脚本会以原子性(atomic)的方式执行:当某个脚本正在运行的时候,不会有其他脚本或 Redis 命令被执行。这和使用 MULTI / EXEC 包围的事务类似
3.如果扣的缓存怎么保证缓存和数据库数据一致
设置过期时间
定时刷新缓存
使用分布式锁保证同一时间只有一个线程去更新数据库
4.分布式锁使用场景
① 防止重复操作:在某些场景下,比如订单处理、任务调度等,需要确保同一操作只能被执行一次。使用分布式锁可以防止多个节点同时执行同一操作,避免重复操作的问题。
② 并发控制:当多个节点同时对共享资源进行读写操作时,可能会出现数据不一致或冲突的情况。通过使用分布式锁,可以保证在同一时间只有一个节点对资源进行操作,从而实现并发控制,保证数据的一致性和正确性。
③ 缓存同步:在使用缓存的场景下,如果缓存失效时多个节点同时去更新缓存,可能会导致缓存击穿或雪崩的问题。使用分布式锁可以确保只有一个节点去更新缓存,其他节点等待获取锁后再进行操作,避免了对缓存的同时大量请求,减轻了数据库或其他后端资源的压力。
④ 限流:在高并发场景下,为了保护系统的稳定性,需要对请求进行限流。使用分布式锁可以实现简单的限流策略,例如每秒只允许一定数量的请求通过,其他请求需要等待获取锁后再进行处理。
5.springboot自动装配原理
SpringBoot项目中有个注解@SpringBootApplication,这个注解是对三个注解进行了封装:
@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan
其中@EnableAutoConfiguration是实现自动化配置的核心注解。
该注解通过@Import注解导入AutoConfigurationImportSelector类,这个类实现了一个导入器接口ImportSelector。
在该接口中存在一个方法selectImports,该方法的返回值是一个数组,数组中存储的就是要被导入到spring容器中的类的全类名。
在AutoConfigurationImportSelector类中重写了这个方法,该方法内部就是读取了项目的classpath路径下META-INF/spring.factories文件中的所配置的类的全类名。
在这些配置类中所定义的Bean会根据条件注解所指定的条件来决定是否需要将其导入到Spring容器中
6.post get 区别是什么
① 传参方式
GET:参数数据会附加在URL的末尾以键值对的形式出现,请求的数据会被暴露在URL中,可见性较高。
POST:通过请求体传递数据,数据不会暴露在URL中,而是作为请求体的一部分发送给服务器。
② 请求长度限制
GET:由于数据附加在URL上,URL的长度限制了GET请求能够传递的数据量。不同的浏览器和服务器对URL长度的支持有所不同,一般来说,URL长度限制在几千个字符左右。
POST:由于数据在请求体中,没有像GET请求那样的长度限制。POST请求可以传输更大量的数据。
② 数据安全
GET:由于数据附加在URL上,GET请求的数据会被浏览器缓存和历史记录保存,且容易被拦截、修改或泄漏。因此,不适合用于传输敏感数据。
POST:由于数据在请求体中,POST请求的数据不会被缓存和保存在浏览器的历史记录中,相对来说更安全。
7.平常接口怎么选择哪种请求类型
GET:一般用于搜索下载和筛选之类的操作(淘宝,支付宝的搜索查询都是get提交),目的是资源的获取,读取数据
POST:一般用于修改和写入数据
8.mysql什么情况容易出现索引失效
!=条件、like以%开头、or中有字段没有索引、条件中有索引列运算、条件字段需要类型转换、复合索引未用左列字段等等
9.mysql慢查询优化以及根据什么看是否用到索引
用Explain去排查是否用到索引
key表示用到的索引
key_len表示索引长度
rows表示预计要检查的行数,涉及行数越少越好
10.mysql大小表啥的没太懂记不清了
11.一个接口请求很慢怎么排查
检查日志确定慢的具体位置
检查网络,带宽、DNS解析慢等问题
检查是否有慢sql
检查代码逻辑,是否存在死循环之类的
检查是否机器达到性能瓶颈,IO、CPU等问题
等等
12.apollo怎么动态刷新配置
可以使用@ApolloConfigChangeListener监听器 具体需要了解下源码
13.有用过什么配置中心么
springCloud config、nacos、apollo
14.nacos和apollo区别
| 对比项目/配置中心 | nacos | apollo |
|---|---|---|
| 项目背景 | 阿里巴巴开源项目 | 携程开源项目 |
| 功能特性 | 服务注册发现、配置管理等 | 专注于配置管理 |
| 开源时间 | 2016.5 | 2018.6 |
| 配置实时推送 | 支持(HTTP长轮询1s内) | 支持(HTTP长轮询1s内) |
| 版本管理 | 自动管理 | 自动管理 |
| 配置回滚 | 支持 | 支持 |
| 权限管理 | 支持 | 待支持 |
| 多集群多环境 | 支持 | 支持 |
| 监听查询 | 支持 | 支持 |
| 多语言 | Go,C++,Python,Java,net,OpenAPI | Python,Java,Nodejs,OpenAPI |
| 分布式高可用最小集群数量 | Config2+Admin3+Portal*2+Mysql=8 | Nacos*3+mysql=4 |
| 配置格式校验 | 支持 | 支持 |
| 通信协议 | HTTP | HTTP |
| 数据一致性 | 数据库模拟消息队列,Apollo定时读消息 | HTTP异步通知 |
| 单机读(tps) | 9000 | 15000 |
| 单机写(tps) | 1100 | 1800 |
15.springcloud常用组件以及各个组件作用
zuul 网关组件,用于实现反向代理,将外部请求转发给对应的微服务,并提供路由、过滤、负载均衡等功能
hytrix 容错管理组件,用于处理服务之间的故障和延迟,实现服务的熔断、降级、限流等功能
ribbon 客户端负载均衡组件,用于在服务消费方进行负载均衡策略的选择和切换
eureka 服务注册与发现组件,用于实现服务治理
feign 声明式的 HTTP 客户端,用于简化服务之间的 HTTP 调用,通过注解方式定义接口并实现远程调用。
16.redis 数据类型
String(字符串)
List(列表)
Set(集合)
Hash(散列)
Sorted Set/Zset(有序集合)
17.redis zset使用场景
有序队列
ZSet主要适用于需要排序(排行榜)的场景,如:
粉丝列表(按关注时间排序);
学生成绩排名;
文章帖子排名;
各类榜单(如微博总热榜、分类热榜);
18.redis 常用命令
字符串(String):
设置键值对:`SET key value`
获取值:`GET key`
删除键值对:`DEL key`
修改值:`SET key new_value`
列表(List):
在列表左侧插入元素:`LPUSH key element`
在列表右侧插入元素:`RPUSH key element`
获取列表范围内的元素:`LRANGE key start stop`
删除指定元素:`LREM key count element`
哈希(Hash):
设置哈希字段的值:`HSET key field value`
获取哈希字段的值:`HGET key field`
获取所有哈希字段及值:`HGETALL key`
删除哈希字段:`HDEL key field`
集合(Set):
添加元素到集合:`SADD key member`
获取集合中的所有成员:`SMEMBERS key`
从集合中移除元素:`SREM key member`
判断元素是否在集合中:`SISMEMBER key member`
有序集合(Sorted Set):
添加带有分数的元素到有序集合:`ZADD key score member`
获取有序集合中指定范围的元素:`ZRANGE key start stop`
获取有序集合中成员的分数:`ZSCORE key member`
移除有序集合中的元素:`ZREM key member`
19.linux查询日志命令
tail -100f test.log
grep "测试" test.log | grep "测试2"