Java 岗大厂面试百日冲刺【Day42】,两年 java 开发面试题
本栏目 Java 开发岗高频面试题主要出自以下各技术栈:Java基础知识
、集合容器
、并发编程
、JVM
、Spring全家桶
、MyBatis等ORMapping框架
、MySQL数据库
、Redis缓存
、RabbitMQ消息队列
、Linux操作技巧
等。
面试题 1:如果用 mybatis 批量插入数据时需要返回主键,你是怎么做的?
===================================================================================================
需要在Mapper.xml
的中标签中配置useGeneratedKeys
和keyProperty
两个属性,就可以在批量插入时返回主键。
比如有个表 t_user,里面有 user_id,user_name,sex 这三个字段,其中user_id是自增主键
。
下面是批量插入的 Dao 层接口:
List<String> insertUsers(@Param("list") List<UserInfo> users);
xml 形式:
<insert id="insertUsers" useGeneratedKeys="true" keyProperty="user_id" resultType="String">
insert into t_user (user_name,sex)
values
<foreach collection="list" item="c" separator=",">
(#{c.user_name},#{c.sex})
</foreach>
</insert>
注解形式:
@Insert("<script>insert into t_user (user_name,sex) values " +
"<foreach collection='list' item='c' separator=','>(#{c.user_name},#{c.sex})</foreach></script>")
@Options(useGeneratedKeys = true, keyProperty = "user_id", resultType="String")
List<String> insertUsers(@Param("list") List<UserInfo> users);
注意:
@Param
里和foreach的collection
里都需要写成 list, 其实是源码中写死了key为list
,否则批量插入后会报错说找不到"user_id"字段,而无法返回主键。
这种方式的前提是该表主键有序自增
,它的原理其实就是拿到当前表中最大ID
,然后结合影响行数
来返回相应数据。但这就需要固定的 insert 场景,如果是 insert ignore 这种可能和实际影响行数不同的情况,就会出现不准确的情况。
![在这里插入图片描述](https://img-blog.csdnimg.cn/a1aa6ba623c745208802c927599f94a0.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAX-mZiOWTiOWTiA==
,size_18,color_FFFFFF,t_70,g_se,x_16#pic_center)
课间休息,来秀一下来自咱们群里同学搬砖工地附近的夜市。
作者:山一程雪一更
面试题 2:在微服务中你是如何实现不同服务间 session 共享的?
================================================================================================
在微服务中,一个完整的项目被拆分成多个不相同的独立的服务,各个服务独立部署在不同的服务器上,各自的 session 被从物理空间上隔离开了,但是经常,我们需要在不同微服务之间共享 session
。
常见的方案就是 Spring Session + Redis
来实现 session 共享。将所有微服务的 session 统一保存在 Redis 上,当各个微服务对 session 有相关的读写操作时,都去操作 Redis 上的 session 。这样就实现了session 共享
,Spring Session 基于 Spring 中的代理过滤器实现,使得 session 的同步操作对开发人员而言是透明的,非常简便。
同时,Spring Session已经集成了redis
,可以很方便的将 session 存到 redis 中从而实现单点登陆/登出的效果,但是从微服务的角度来说,为了降低系统间的耦合度,一般会单独建一个 Redis 服务来搞 session 共享。
1、pom 文件中引入以下包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
2、application.properties 配置好 redis
spring.redis.database = 0
spring.redis.host = 192.168.xx.xx
spring.redis.port = 6379
spring.redis.password = test
spring.redis.pool.max-active = 200
spring.redis.pool.max-wait = -1
spring.redis.pool.max-idle = 10
spring.redis.pool.min-idle = 0
spring.redis.pool.timeout = 1000
在需要共享 session 的服务的启动类上,加上注解即可
@EnableRedisHttpSession
@SpringBootApplication(exclude= {DataSourceAutoConfiguration.class})
public class PhoneApplication {
public static void main(String[] args) {
SpringApplication.run(PhoneApplication.class, args);
}
}
来了,CSDN 的中秋礼品已到位
作者:陈哈哈
面试题 3:你了解分库分表么?分库分表一般出现在哪些场景下?
============================================================================================
分库
:由单个数据库实例拆分成多个数据库实例,将数据分布到多个数据库实例中。
分表
:由单张表拆分成多张表,将数据划分到多张表内。
随着业务数据量和网站 QPS 日益增高,对数据库压力也越来越大,单机版数据库很快会到达存储和并发瓶颈,就需要做数据库性能方面的优化,分库分表采取的是分而治之的策略,分库目的是减轻单台 MySQL 实例存储压力及可扩展性,而分表是解决单张表数据过大以后查询的瓶颈问题,坦白说,这些问题也是所有关系型数据库的“硬伤”
。
常用策略包括:垂直分表
、水平分表
、垂直分库
、水平分库
。
一、朴实无华的 - 分表
1、垂直分表
垂直分表,或者叫竖着切表
,是不是感受到该策略是以字段为依据的!主要按照字段的活跃性、字段长度,将表中字段拆分到不同的表(主表和扩展表)中。
特点:
每个表的结构都不一样;
每个表的数据也不一样,
有一个关联字段,一般是主键或外键,用于关联
兄弟表
数据;所有兄弟表的并集是该表的全量数据;
场景:
有几个字段属于热点字段,更新频率很高
,要把这些字段单独切到一张表里,不然 innodb 行锁很恶心的,锁死你呀~~如用户表里的余额字段?不,我的余额就很稳定,一直是 0。。
评论