招商银行面经(技术1/2面)

该博客汇总了技术面试常见问题,涵盖根据价格排序分页、大数据分库分表、spring事务传播属性、springboot配置读取与热更新、防止短信验证码暴力破解,以及多线程数组累加等内容,为技术面试提供参考。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.根据价格升序排序并分页

select * 
from tbl_menu 
order by price asc 
limit pageSize offset pageNum

pageSize:指定每页显示的条数
pageNum:偏移量,确定结果从哪一行开始返回
asc:升序排序
desc:降序排序

2.大数据量的情况下分库分表怎么做

1.mycat:开源的分布式数据库中间件,它将应用程序与数据库分离,提供数据库分片、读写分离、负载均衡等功能。
         mycat原理是将一个逻辑数据库拆分成多个物理数据库,每个物理数据库负责一部分数据,从而实现
         水平扩展和提高数据库性能
特点和原理:
(1)分片和分库分表:mycat支持将大型数据库分片成多个小型数据库,每个小型数据库叫做一个分片。每个
                  分片可以进一步进行分库分表,实现数据的水平划分和管理
(2)读写分离:主库写,读库查询
(3)负载均衡:将请求分发到不同的数据库实例
(4)SQL解析和路由:解析SQL语句,根据SQL中的表名和条件,将查询路由到正确的分片
(5)缓存:支持缓存查询结果
(6)事务管理:提供分布式事务管理,支持跨多个分片的事务操作
(7)SQL优化
使用mycat存储上亿条用户数据,要求可以用手机号码查询用户,要怎么做:
(1)定义分片键:这个键要是与手机号码相关的字段,比如手机号码的前缀
(2)配置分片规则:在mycat配置文件中,定义分片规则,指定如何将查询请求路由到不同的分片上。
                使用分片键来计算路由规则
(3)部署分片数据库:将不同的分片部署在不同的数据库实例上。每个分片可以包含一部分用户数据,具体的
                  数据划分根据分片规则定义
(4)执行查询:当执行查询操作时,mycat会根据配置的路由规则将查询请求路由到相应的分片数据库上

2.sharding:一种数据库架构设计模式,用于处理大规模数据集的存储和管理。分片将数据分割成多个较小的
           子集,并将每个子集存储在独立的数据库实例中
原理:
(1)数据分割:将整个数据集分割成多个分片,每个分片包含一部分数据。分片可以按照不同的方式进行划分,
             如按照数据范围、哈希值、分片键等
(2)分布式存储:每个分片都存储在独立的数据库实例中,这些事例可以部署在不同的物理服务器上。
(3)路由:使用分片键来确定数据所在的分片
(4)负载均衡
(5)查询合并:当应用程序执行查询时,可能需要查询多个分片来获取完整的结果。它负责将来自不同分片的
             查询结果合并成最终结果

3.spring事务的传播属性

1.REQUIRED(默认):如果当前存在事务,则加入该事务;如果不存在事务,则创建一个新的任务
2.SUPPORTS:如果当前存在事务,则加入该事务;如果不存在事务,则以非事务的方式执行
3.MANDATORY:如果当前存在事务,则加入该事务;如果不存在事务,则抛出异常
4.REQUIRES_NEW:无论当前是否存在事务,都会创建一个新的事务。如果已经有事务存在,那么该事务会被挂起,
                并在方法执行结束后再恢复
5.NOT_SUPPORTED:以非事务方式执行方法,如果当前存在事务,则挂起该事务
6.NEVER:以非事务方式执行方法,如果当前存在事务,则抛出异常
7.NESTED:如果当前存在事务,则嵌套在该事务内执行;如果不存在事务,则创建一个新的嵌套事务。
          嵌套事务可以看作是原始事务内部的子事务,他有自己的保存点,并且可以独立提交和回滚。如果
          外部事务提交,但内部嵌套事务回滚,那么内部嵌套事务的回滚会回滚到外部事务的保存点
8.IGNORE:无论当前是否存在事务,都会以非事务的方式执行

4.REQUIRED_NEW在什么情况下会造成死锁

方法A和方法B都使用了REQUIRED_NEW做传播属性,A和B操作数据库中相同数据行或相关数据行,此时两个不同的
线程分别访问A和B,会造成死锁

5.springboot读取yml配置文件的过程

它借助了Spring的 PropertySource 抽象来实现配置文件的加载和解析

6.springboot项目怎么实现热更新

1.springboot devtools:spring官方提供的一个开发工具,支持热部署和自动重启,在项目中添加依赖即可,
                       当进行代码修改保存后,springboot devtools会自动检测到并重新加载应用程序,
                       实现了热更新效果

2.使用热部署工具:如 springLoaded JRebel 等,来实现热更新

3.使用springcloud Config:它允许将应用程序的配置放在一个外部配置服务器中,可以动态刷新配置,
                         而无需重启应用

4.使用热加载类库:如 JRebel DCEVM 等,可以在运行时替换java类,实现代码的热加载和热更新

5.使用Docker容器:构建一个docker镜像,将应用程序和配置文件打包在一起,并在需要时更新docker容器,
                 以实现热更新

7.技术方面怎么防止短信验证码被暴力破解

1.限制尝试次数:限制每个用户每天或每小时可以尝试的验证码验证次数

2.验证码有效期:设置验证码的有效期,确保验证码在一段事件后失效

3.短信验证码缓存:将已生成的短信验证码存储在缓存中,确保同一个验证码只能验证一次。
                缓存的生命周期应该与验证码的有效期一致

4.用户身份验证:在发送验证码之前,要求用户先进行身份验证,例如要求用户登录或者提供其他身份信息

5.图形验证码:使用图形验证码来替代或补充短信验证码,用户需要通过解答图形验证码来获取短信验证码

6.验证码加密:对验证码进行加密或哈希处理,以增加破解难度。在验证时,使用相同的加密方法来比较用户输入
            和存储的验证码

7.IP限制:向用户发送通知,告知他们有人尝试使用他们的手机号或账号来验证验证码

8.异常检测:实施监控和日志记录,以检测异常行为,如频繁的验证码验证尝试。如果异常情况发生,
           可以采取封禁IP地址或账户

9.安全库和服务:考虑使用专门的短信验证码服务提供商

8.有一个数组,数组元素20000,开启四个子线程分别累加数组的1/4,等四个子线程类加结束后,主线程再累加这四个子线程求出的和

public class GetSum {
    private static final int CAPACITY = 20000;
    private static final int THREADS_NUM = 4;//子线程数量
    private static final int SIZE = CAPACITY / THREADS_NUM;
    private static int[] arr = new int[CAPACITY];

    public static void main(String[] args) throws InterruptedException {
        //初始化数组
        for (int i = 0;i < CAPACITY;i++){
            arr[i] = i + 1;
        }
        Thread[] threads = new Thread[THREADS_NUM];
        int[] ans = new int[THREADS_NUM];
        //创建一个CountDownLatch 计数器初始化为子线程的数量
        CountDownLatch latch = new CountDownLatch(THREADS_NUM);

        //创建并启动四个子线程
        for (int i = 0;i < THREADS_NUM;i++){
            int temp = i;
            threads[i] = new Thread(() -> {
                int sum = 0;
                int start = temp * SIZE;
                int end = start + SIZE;
                for (int j = start;j < end;j++){
                    sum += arr[j];
                }
                ans[temp] = sum;
                //子线程完成后减少latch的计数
                latch.countDown();
            });
            threads[i].start();
        }
        //主线程等到所有子线程完成
        latch.await();//主线程会等待到CountDownLatch的计数器减为0
        int res = 0;
        for (int x : ans){
            res += x;
        }
        System.out.println("结果为: " + res);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cw旧巷

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值