当前位置: 首页 > news >正文

面经Java

怎么用MyBatis在几s内内插入百万条数据?

使用MyBatis的ExecutorType.Batch执行器,手动控制事务与提交频率,利用批量SQL插入+合理分批(每次1000条防止内存溢出)。

代码大概就是在对象中注入一个SqlSessionFactory,然后在相应的方法中调用sqlSessionFactory.openSession(ExecutorType.BATCH, false)传入执行器,然后调用getMapper方法传入Mapper的class对象获取相应的Mapper,然后固定batchSize = 1000,for循环遍历要插入的数据,if判断每1000条提交一次(i % batchSize == n),最后执行到for循环外部处理一下最后一批的提交。

// 假设我们有一个简单的实体类 User(id, name, age)@Autowired
private SqlSessionFactory sqlSessionFactory;public void batchInsertUsers(List<User> userList) {// 1. 使用 BATCH ExecutorTypetry (SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH, false)) {UserMapper mapper = session.getMapper(UserMapper.class);int batchSize = 1000; // 每次提交 1000 条for (int i = 0; i < userList.size(); i++) {mapper.insertUser(userList.get(i));// 每 1000 条提交一次if (i > 0 && i % batchSize == 0) {session.flushStatements(); // 刷新批处理语句session.commit();          // 提交事务session.clearCache();      // 清理一级缓存,防止 OOM}}// 处理最后一批未提交的session.flushStatements();session.commit();session.clearCache();}
}

数据库层的优化方面:

innodb_buffer_pool_size设置的尽量大提高缓存能力,控制事务提交时日志刷盘的时机为innodb_flush_log_at_trx_commit = 2,每次提交直接系统调用write()到文件系统缓存,然后由操作系统决定何时刷盘fsync(),平衡性能和安全

controller service mapper层,mapper层不用mybatis,怎么设计不会修改太多service的代码

换成原生JDBC的话,同时想要Service层几乎不动,可以把Mapper层之上加一层Repository抽象,Service层依赖Repository而不是Mapper

高并发上传图片如何设计

保证高并发,数据可靠性

前端上传的时候【分块上传】,并发上传多块。

计算文件MD5,避免重复上传【秒传】

【断点续传】仅上传缺失分片,Range字段

服务端只负责【签名授权】,【客户端直接上传到OSS】,图片流不用经过Java服务

上传之后触发回调接口,告诉后端上传的【元信息】MySQL落库

图片元信息存在数据库中,结构是图片【唯一ID】、上传者、图片类型、存储路径【URL】、上传时间、状态

压缩、裁剪、缩略图的任务发送到消息中间件做【异步处理】

大量图片上传导致OOM怎么办

客户端直传图片到OSS,不经过Java服务

如果图片流确实要经过Java的话确实容易造成OOM,代码层面首先要杜绝调getBytes()方法,而是使用流式方式处理,比如ossClient.putObject(bucketName, objectName, in)就是自动流式处理。

SpringBoot中通过配置方式或者代码方式限制图片的大小

或者Spring也可以把上传的文件临时保存到磁盘而不是内存 

项目中Redis挂了怎么办?

Redis挂了也要保证服务可用性,可以降级用本地缓存兜底,或者直接请求数据库,保证核心功能可用

微服务项目也可以触发限流或熔断,限流触发后通知上游服务429错误码不要立即重试,而是走兜底逻辑或者退避一段时间重试,熔断触发后也可以走兜底逻辑,避免故障扩散。

也可以将写失败的操作放到消息中间件里防止数据丢失

从架构方面来看,如果是哨兵模式,主节点挂了还有从节点顶上,集群模式会自动进行故障转移选出新的主节点

图结构数据如果用关系型数据库的二维表存储,怎么设计表的结构?

一张节点表,一张边表,节点表的一条数据代表一个节点,边表的一条记录代表两个节点的关系,包括起始节点ID、终点节点ID、边类型、边权重

平时用什么 JDK 版本做开发

JDK1.8,这是企业中最稳定,兼容性最好的版本,满足绝大部份需求,各种中间件兼容性也比较好,新版本虽然有一些语法糖,但是现有核心系统仍然以1.8为主,迁移成本比较大

JDK 17 的 Optional 类是干嘛的?

是一个容器类,用于存放一个可能为null的值,也可以说它是一个可以为空的盒子,里面要么有一个对象(非空),要么什么都没有(空盒子)。

主要是为了避免NullPointerException

Stream 流的原理

是一种基于pipeline流水线的模型,每个中间操作都会生成一个新的Stream流对象,底层是通过一连串的AbstractPipeline节点实现的,中间操作是惰性执行的,只有遇到终结操作,比如for each才触发执行,每个元素从数据源取出后,会顺序通过每个节点操作

Spring事务失效的场景

1. 方法不是public:AOP无法代理不是public的方法

2. 同类方法内调用:一个方法调用同类内另一个事务方法的时候,事务失效,因为代理对象在外部调用时才能生效,直接调用自身方法会绕过代理

Spring的事务传播行为有哪些?

REQUIRED:默认行为。如果当前存在事务,则加入;否则新建一个事务。

REQUIRES_NEW:总是新建一个事务,如果当前存在事务,则挂起当前事务。

SUPPORTS:如果当前存在事务,就加入,否则以普通方法执行

有一台 1GB 内存的机器和一个 1TB 大小的文件,文件的内容由空格、换行符、无序的数字组成,如何找到这个文件中最大的数字和最小的数字?

不能一次性读到内存,要用流式扫描处理,一边读一边计算,在遍历的过程中过滤非数字元素,并且维护最小值和最大值

让你来设计一个用户登录的流程,从安全和性能的角度考虑,你会怎么设计?

首先是功能需求:用户名/密码登录、邮箱/手机号登录、支持 MFA(TOTP/短信/Push)、记住我、登出、刷新 token、密码重置、设备管理。

然后是流程:

  1. 客户端(HTTPS)调用 POST /auth/login 提交 {identifier, password, deviceInfo}。identifier 可为 username/email/phone。

  2. API Gateway 做安全检测(IP地址);通过则请求到 Auth Service。

  3. 查 DB 取用户实体,看看用户是否被禁用

  4. 使用安全哈希函数(Argon2 / bcrypt / PBKDF2-with-HMAC-SHA256)对比密码;

  5. 若密码错误:在Redis中增加失败计数(Redis 原子 INCR),达到阈值触发 CAPTCHA / 临时锁定 / notify;

  6. 客户端收到 token 存储在cookies

  7. 后续请求携带 Access Token(Header Authorization: Bearer … 或 Cookie)。验证通过即访问资源。

安全方面主要是密码加密存储和对比,强制 HTTPS 请求,利用图片验证码防止脚本攻击,设置用户黑明单,在网管层做安全检测IP地址

Token可以用JWT

Token的原理?

客户端提交用户名 + 密码,后台验证之后返回一个字符串,如果是JWT的话就是用密钥加密过的用户基本信息,避免频繁查询DB。

返回给客户端(前端 / App),客户端保存在Cookies或者LocalStorage

客户端每次请求时在 HTTP Header(通常是 Authorization: Bearer <token>)中携带;

服务端验证 Token 的合法性(签名、是否过期);

验证通过 → 放行请求;否则返回 401(未授权)。

怎么实现二维码登录?

服务端生成一个 随机的、唯一的登录标识 loginKey(UUID 或加密随机数)

根据这个随机的loginKey生成一个二维码,前端展示

loginKey 存储在服务端缓存(Redis)并设置过期时间(比如 2 分钟)

手机端扫码后获取 loginKey

手机端执行登录状态验证(用户已登录微信/账号)

手机端调用服务端接口确认登录:将 loginKey 标记为已确认,并关联当前用户 ID

PC 端定期轮询服务端接口查询 loginKey 是否已被确认

如果确认 → 生成 Access Token 或 Session,完成登录

如果二维码过期 → 提示用户刷新二维码

怎么设计一个分布式缓存系统

分布式缓存 = 分片 + 副本 + 缓存策略 + 一致性 + 高可用 + 可扩展设计

首先明确需求,缓存系统需要支持高速读写,支持key value存储,支持过期策略,支持高并发访问,支持高可用,数据一致性和故障恢复

缓存节点一定是集群部署的,可以是Redis集群

首先是数据分片,可以用一致性哈希减少节点扩展或者减少时的迁移成本,也可以Redis Cluster使用哈希槽数量16384来映射节点

每个缓存节点都要有主从副本,读写分离,主节点挂了可以启动从节点,保证高可用,从节点要保证和主节点的数据一致性(通过同步复制)。

还要设计淘汰策略和过期策略

Cache Aside模式保证缓存和数据库的一致性

现在用户登录功能,响应很慢,一直转圈圈,如何排查问题?

如果是后端的问题,看一下线上的日志有没有报错,也可以看一下慢查询日志,然后用EXPLATIN查看SQL的执行计划,看看是不是有filesort,缓存失效等问题。

缓存方面可以检查一下Redis是否命中?是不是由于大量请求打到DB导致的

服务器方面可以用top -Hp命令看一下CPU和内存占用率是否异常,然后用jstack生成堆栈信息文件,在这个文件用搜索CPU占用率高的线程的执行信息,最终定位到代码看看是不是有死循环,Redis和DB连接问题,或者死锁的问题

红黑树和b+树区别?

红黑树是高度自平衡的二叉搜索树,树高O(logn),b+树是多路平衡的搜索树树高比较低

红黑树每个节点都存储key value,b+树只有叶子结点有可能存储k-v,非叶子结点都存的是索引,节点具有天然有序性,方便范围查询

红黑树是二叉查找,每次访问节点都会触发IO,B+树由于比较矮,并且一个节点对应一个磁盘页,IO次数也比较少

红黑树的插入和删除操作是通过调整颜色和旋转保持平衡,B+树是通过分裂和合并节点维持多路平衡

MySQL索引应该怎么加

CREATE TABLE user (
    id INT PRIMARY KEY,             -- 主键索引
    username VARCHAR(50) NOT NULL UNIQUE,  -- 唯一索引
    email VARCHAR(100),
    age INT,
    INDEX idx_age (age),            -- 普通索引
    INDEX idx_email_age (email, age) -- 复合索引
);

CREATE INDEX idx_username ON user(username);

http://www.dtcms.com/a/484119.html

相关文章:

  • 网站建设什么服务器好什么网站可以做单词书
  • 定制东莞网站制作公司查域名ip地址查询
  • 基于pycharm和anaconda的yolo简单部署测试
  • 沧州南皮手机网站建设网站后台模板论坛
  • 2014年10月自考《信息组织》试题
  • 网站哪家好百度网盘人工申诉电话
  • 【下载安装】mysql
  • 厚街镇仿做网站广州出名的网站
  • Go 语言条件语句详解
  • 中国建设部官方网站绿色建筑竞价排名深度解析
  • 把自己的网站卖给别人后对方做违法山西省建设厅官方网站
  • Bert:从“读不懂上下文”的AI,到真正理解语言
  • 成立网站要什么手续负责网站建设
  • 常州免费企业网站建设百度搜索风云榜小说
  • 产品网站建设公司官方网站内容可做证据吗
  • 2019年4月自考《信息组织》试题
  • 网站制作钱网站下拉菜单代码
  • 做公司 网站怎么在网站上做外链
  • [嵌入式系统-108]:定昌电子DC-A588电路板介绍,一款基于瑞芯微RK3588芯片的高性能嵌入式AI边缘计算工控主机
  • 哈尔滨做网站设计东莞网站建设平台
  • 焊接经验积累
  • 做网站4000-262-263怎么制作公司宣传图片
  • 无锡市住房和城乡建设部网站怎么建立一个博客网站
  • 高质量数据集、多模态数据处理与数据标注之间的关系
  • 怎样自己做电影网站wordpress小米商城模板
  • 深圳市住房和建设局网站公示google关键词查询工具
  • 湖北山河建设集团网站如何让百度抓取网站
  • ROS2-创建对象时,加载动态参数的方法
  • 之江汇学校网站建设大型做网站的公司有哪些
  • 网站建设公司营业执照wordpress旅游类网站