java面试篇 4.9(mybatis+微服务+线程安全+线程池)

news2025/5/19 3:11:38

目录

mybatis:

1、mybatis的执行流程

2、mybatis是否支持延迟加载?

当我们需要去开启全局的懒加载时:

3、mybatis的一级和二级缓存

微服务

1、springcloud五大组件有哪些

2、服务注册和发现是什么意思?springcloud如何实现服务注册发现的?

3、负载均衡时如何实现的?

ribbon的负载均衡策略有哪些?

​编辑

 4、什么是服务雪崩,怎么解决这个问题?

5、你们的微服务是怎么监控的?

6、微服务限流

7、分布式系统理论

 8、分布式事务的解决方案

线程安全

1、synchronized关键字的底层原理

2、synchronized底层原理进阶

3、你谈谈JMM(java的内存模型)

4、CAS你知道吗

线程池

1、线程池的核心参数和执行原理?​编辑​编辑

2、线程池中有哪些常见的阻塞队列?

3、如何确定核心线程数?

4、线程池的种类有哪些?(executors不建议用)

5、为什么不建议使用executors创建线程池?

6、线程池的使用场景?

1、countDownLatch 

​编辑

2、数据汇总

3、异步调用

7、如何控制某个方法允许并发访问线程的数量?

一些其他问题:

1.Springboot如何解决跨域问题?

方法一:使用@CrossOrigin注解

1. 作用于方法

2. 作用于类

方法二:配置WebMvcConfigurer实现跨域

说明

方法三:使用CorsFilter实现跨域

示例代码

方法四:使用CorsConfigurationSource实现跨域

示例代码

方法选择建议

2、mybatis的二级缓存的Serializable接口怎么实现?

实体类实现 Serializable 接口

3、线程的原子性指的是什么

原子性的关键点

常见的原子操作

如何保证原子性

原子性的重要性

总结


mybatis:

1、mybatis的执行流程

1、读取mybatis-config.xml文件确定连接的是什么数据库,扫描的是哪些Mapper文件。

2、创建一个sqlsessionFactory会话工厂,它可以创建多个sqlsession会话,包含了执行SQL语句的方法

3、执行器是真正操作数据库接口的,并且维护一些缓存

4、MapperedStatement对象会封装某些信息,比如Mapper映射文件的名称、映射文件的哪个方法、执行的SQL语句、数据库返回的结果

5、将java传来的参数类型转化为数据库支持的数据类型。执行完后要转为java类型。

2、mybatis是否支持延迟加载?

立即查询: 

延迟加载:

当我们不需要获取订单信息,系统不会执行查询订单信息的SQL语句。

当我们需要去开启全局的懒加载时:

<setting name="lazyLoadingEnabled" value ="true"/>

原理:创建一个代理对象

3、mybatis的一级和二级缓存

作用于同一个session的意思就是,通过同一个session执行的方法。

添加<cache/>标签。 

两个查询语句只会执行一个SQL语句(同一个Mapper文件的方法):

3的意思是第一个sqlsession结束才能将一级缓存转移到二级缓存。 

微服务

1、springcloud五大组件有哪些

配置中心写在springcloud.config文件中。

zuul被淘汰了。 

2、服务注册和发现是什么意思?springcloud如何实现服务注册发现的?

 ap是高可用模式,cp是强一致模式。

3、负载均衡时如何实现的?

 

ribbon的负载均衡策略有哪些?

 4、什么是服务雪崩,怎么解决这个问题?

一个服务的所有连接数是确定的,当服务A向服务D发送请求失败时,连接并不会被释放,A持续向D发送请求会占满A的最大连接数,故而A无法再提供服务,A发生了宕机,而这是一个链式的崩溃过程。

解决方法:

服务降级

服务熔断 

服务降级是针对接口,当服务的某个方法不可用时,我们对该接口的方法进行降级,它会直接返回错误而不占用连接,而仅仅是部分方法不可用不需要关闭整个服务,当请求失败率达到50%以上则触发熔断,整个服务会被关闭,进入熔断机制。熔断针对的是整个服务不可用。

5、你们的微服务是怎么监控的?

解决如下四个问题。

6、微服务限流

漏桶算法指的就是以固定速率漏出请求,超出桶容限的请求等待或抛弃。漏桶的请求数量更加平滑。

漏桶它的请求数是可以波动的,因为令牌数量可以累计,如果某一时间请求数很大会拿走大量的令牌。默认使用Redis存储令牌桶,所以需要在网关的配置文件中配置Redis连接。

7、分布式系统理论

要么是cp要么是ap

 8、分布式事务的解决方案

线程安全

1、synchronized关键字的底层原理

汇编执行流程:

2、synchronized底层原理进阶

对象的对象头中存有Markword,Markword会存有monitor的地址,从而关联对象锁和monitor。 

重量级锁:

轻量级锁的执行流程:

1、创建一个线程以后,线程里面会生成一个lock Record,里面的Object reference会指向对象锁,lock recode地址00存储锁地址然后与对象锁的marokword进行内容交换,那么对象锁的markword就会从无锁的状态转为轻量级锁(如果多个线程竞争一个对象锁,会升级为重量级锁),而tread-0中就会存储对象锁的原本内容,比如hashcode这些。

2、如果线程1执行中调用了线程2,则称之为锁重录,锁重录不是两个线程竞争对象锁,它仍然是一个线程,所以用轻量级锁即可。

3、发生锁重录后,线程Thread-0会再创建一个lock record,里面的lockrecord地址00会再与对象锁发生CAS连接,但是不发生交换,里面的内容为Null。

4、当线程逐渐执行完时,为lock record地址00为null的先执行完并被删除,CAS不会发生交换。而最后不为null的Lock Record会先与对象锁发生CAS交换,Markword部分再次变为无锁状态。然后LockRecord被删除,线程执行完。

偏向锁:

3、你谈谈JMM(java的内存模型)

4、CAS你知道吗

自旋的意思就是重新拉一份旧数据进行执行,保证线程的原子性。 

线程池

1、线程池的核心参数和执行原理?

具体实现:

2、线程池中有哪些常见的阻塞队列?

3、如何确定核心线程数?

开发时一般都是io密集型任务。

4、线程池的种类有哪些?(executors不建议用)

具体实现:会提供一个延迟执行的效果。

5、为什么不建议使用executors创建线程池?

6、线程池的使用场景?

1、countDownLatch 

具体实现:

真实案例:

1、设置好countDownLatch(总页数),每一个线程完成一个页面数据的导入,只有循环执行完总页数大小的线程数量才能导入完所有的数据。

2、每一页数据导入到es的任务是提交给线程池执行。

2、数据汇总

具体实现:

串行执行:

并行执行:

3、异步调用

搜索记录的保存。

@ASync注解

7、如何控制某个方法允许并发访问线程的数量?

控制一个方法内最多使用的线程数量。

一些其他问题:

1.Springboot如何解决跨域问题?

方法一:使用@CrossOrigin注解

@CrossOrigin注解是Spring框架提供的一个非常便捷的方式来解决跨域问题,它可以直接作用于Controller类或方法上。

1. 作用于方法

在具体的Controller方法上添加@CrossOrigin注解,仅对该方法生效。

@RestController
@RequestMapping("/api")
public class MyController {
    @GetMapping("/test")
    @CrossOrigin
    public String test() {
        return "Hello, CrossOrigin!";
    }
}

这样,只有/api/test接口允许跨域请求。

2. 作用于类

@CrossOrigin注解添加到Controller类上,该类中的所有方法都将允许跨域。

@RestController
@RequestMapping("/api")
@CrossOrigin
public class MyController {
    @GetMapping("/test1")
    public String test1() {
        return "Hello, CrossOrigin!";
    }

    @GetMapping("/test2")
    public String test2() {
        return "Hello, CrossOrigin!";
    }
}

这种方式适合整个Controller类中的所有接口都需要跨域的情况。

方法二:配置WebMvcConfigurer实现跨域

通过实现WebMvcConfigurer接口并重写addCorsMappings方法,可以全局配置跨域规则。

@Configuration
public class GlobalCorsConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        // 配置跨域规则
        registry.addMapping("/**") // 允许跨域的路径
                .allowedOrigins("*") // 允许跨域的来源,*表示所有
                .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") // 允许的请求方法
                .allowedHeaders("*") // 允许的请求头
                .allowCredentials(true) // 是否允许发送Cookie
                .maxAge(3600); // 预检请求的有效期
    }
}
说明
  • allowedOrigins:允许哪些来源进行跨域请求,*表示允许所有来源。

  • allowedMethods:允许哪些HTTP方法进行跨域请求,如GETPOST等。

  • allowedHeaders:允许哪些请求头。

  • allowCredentials:是否允许发送Cookie和HTTP认证信息。如果设置为true,则allowedOrigins不能为*,必须指定具体来源。

  • maxAge:预检请求的有效期,单位为秒。

方法三:使用CorsFilter实现跨域

通过自定义CorsFilter来实现跨域,这种方式更加灵活,可以对请求进行更细粒度的控制。

示例代码
@Component
public class MyCorsFilter implements Filter {
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;
        HttpServletRequest request = (HttpServletRequest) req;

        // 设置允许的来源
        response.setHeader("Access-Control-Allow-Origin", "*");
        // 设置允许的请求头
        response.setHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With, remember-me");
        // 设置允许的请求方法
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        // 设置是否允许发送Cookie
        response.setHeader("Access-Control-Allow-Credentials", "true");
        // 设置预检请求的有效期
        response.setHeader("Access-Control-Max-Age", "3600");

        // 如果是OPTIONS请求,直接返回
        if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
            response.setStatus(HttpServletResponse.SC_OK);
        } else {
            chain.doFilter(req, res);
        }
    }

    @Override
    public void init(FilterConfig filterConfig) {
    }

    @Override
    public void destroy() {
    }
}

方法四:使用CorsConfigurationSource实现跨域

通过实现CorsConfigurationSource接口,可以动态地为不同的请求路径配置不同的跨域规则。

示例代码
@Configuration
public class CorsConfig {
    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Arrays.asList("*")); // 允许的来源
        configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS")); // 允许的请求方法
        configuration.setAllowedHeaders(Arrays.asList("*")); // 允许的请求头
        configuration.setAllowCredentials(true); // 是否允许发送Cookie
        configuration.setMaxAge(3600L); // 预检请求的有效期

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration); // 配置路径
        return source;
    }
}

方法选择建议

  • 如果只需要为个别接口或Controller类解决跨域问题,可以使用@CrossOrigin注解。

  • 如果需要全局配置跨域规则,推荐使用WebMvcConfigurerCorsConfigurationSource

  • 如果需要更细粒度的控制,例如动态调整跨域规则,可以使用CorsFilterCorsConfigurationSource

根据实际需求选择合适的方法即可。

2、mybatis的二级缓存的Serializable接口怎么实现?

实体类实现 Serializable 接口

首先,定义一个实体类并实现 Serializable 接口。例如,定义一个 User 类:

import java.io.Serializable;

public class User implements Serializable {
    private static final long serialVersionUID = 1L;//看来最主要的就是这句话

    private Long id;
    private String name;
    private String email;

    // Getters and Setters
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", email='" + email + '\'' +
                '}';
    }
}

 二级缓存配置参数说明
eviction:指定缓存回收策略,可选值有:
FIFO(先进先出)
LRU(最近最少使用)
SOFT(软引用)
WEAK(弱引用)
flushInterval:缓存刷新间隔时间(毫秒),默认不刷新。
size:缓存的最大对象数。
readOnly:是否只读。如果设置为 true,则缓存的对象是只读的,不能被修改;如果设置为 false,则缓存的对象可以被修改。

3、线程的原子性指的是什么

线程的原子性(Atomicity)是指在多线程环境中,一个操作或一系列操作要么全部完成,要么全部不完成,不会出现部分完成的情况。换句话说,原子操作在执行过程中不会被其他线程中断。

原子性的关键点

  1. 不可分割性

    • 原子操作是不可分割的,不会在操作的中间被其他线程打断。

    • 例如,一个线程正在执行某个原子操作时,其他线程无法插入执行,必须等待该操作完成。

  2. 线程安全性

    • 原子操作通常用于解决多线程环境下的线程安全问题。

    • 如果多个线程同时访问和修改共享资源,原子操作可以确保操作的完整性,避免数据不一致。

常见的原子操作

  1. 单个变量的读写操作

    • 对于基本数据类型(如 intlongdouble 等),单个变量的读写操作通常是原子的。

    • 例如,x = 10 是一个原子操作。

  2. 复合操作

    • 一些复合操作(如 x++x += 10)在多线程环境下可能不是原子的。

    • 例如,x++ 实际上包括三个步骤:读取 x 的值、加 1、写回 x 的值。如果多个线程同时执行 x++,可能会导致数据竞争(Race Condition)。

如何保证原子性

  1. 使用同步机制

    • synchronized 关键字:在 Java 中,synchronized 可以确保多个线程不会同时进入同步代码块。

      java

      复制

      public class Counter {
          private int count = 0;
      
          public synchronized void increment() {
              count++;
          }
      
          public synchronized int getCount() {
              return count;
          }
      }
    • ReentrantLockReentrantLock 提供了比 synchronized 更灵活的锁机制。

      java

      复制

      import java.util.concurrent.locks.Lock;
      import java.util.concurrent.locks.ReentrantLock;
      
      public class Counter {
          private final Lock lock = new ReentrantLock();
          private int count = 0;
      
          public void increment() {
              lock.lock();
              try {
                  count++;
              } finally {
                  lock.unlock();
              }
          }
      
          public int getCount() {
              lock.lock();
              try {
                  return count;
              } finally {
                  lock.unlock();
              }
          }
      }
  2. 使用原子类

    • Java 提供了 java.util.concurrent.atomic 包,其中包含一系列原子类(如 AtomicIntegerAtomicLongAtomicReference 等)。

      java

      复制

      import java.util.concurrent.atomic.AtomicInteger;
      
      public class Counter {
          private final AtomicInteger count = new AtomicInteger(0);
      
          public void increment() {
              count.incrementAndGet();
          }
      
          public int getCount() {
              return count.get();
          }
      }
  3. 使用 volatile 关键字

    • volatile 修饰的变量可以保证可见性,但不能保证复合操作的原子性。

    • 例如,volatile 可以确保多个线程看到变量的最新值,但 x++ 仍然不是原子操作。

      java

      复制

      public class Counter {
          private volatile int count = 0;
      
          public void increment() {
              count++; // 不是原子操作
          }
      
          public int getCount() {
              return count;
          }
      }

原子性的重要性

  • 避免数据竞争:在多线程环境下,原子性可以避免多个线程同时修改共享资源导致的数据不一致问题。

  • 保证线程安全:通过原子操作,可以确保程序的正确性和稳定性。

总结

原子性是多线程编程中的一个重要概念,它确保操作的不可分割性和完整性。通过使用同步机制(如 synchronizedReentrantLock)、原子类(如 AtomicInteger)或 volatile 关键字,可以实现原子操作,从而保证线程安全。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2337694.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于电子等排体的3D分子生成模型 ShEPhERD - 评测

一、背景介绍 ShEPhERD 是一个由 MIT 开发的一个 3D 相互作用感知的 ligand-based的分子生成模型&#xff0c;以 arXiv 预印本的形式发表于 2024 年&#xff0c;被ICLR2025 会议接收。文章链接&#xff1a;https://openreview.net/pdf?idKSLkFYHlYg ShEPhERD 是一种基于去噪扩…

GR00T N1:面向通用类人机器人的开放基础模型

摘要 通用型机器人需要具备多功能的身体和智能的大脑。近年来&#xff0c;类人机器人的发展在构建人类世界中的通用自主性硬件平台方面展现出巨大潜力。一个经过大量多样化数据源训练的机器人基础模型&#xff0c;对于使机器人能够推理新情况、稳健处理现实世界的多变性以及快…

QT简单实例

QT简单实例 QT简单实例一&#xff1a;通过拖动创建1.创建工程2.拖动控件实现响应3.文件目录3.1 TestQDialog.pro3.2 main.cpp3.3 dialog.h3.4 dialog.cpp 二&#xff1a;通过动态创建1.创建工程2.文件目录2.1 TestQDialogSelf.pro2.2 main.cpp2.3 dialog.h2.4 dialog.cpp QT简单…

Linux:初学者的简单指令

文章目录 pwd&#xff08;Print working directory&#xff09;whoamilsmkdir ~~cd ~~touch ~~rm ~~ 充当后端服务,我们用xshell工具来进行操作 其中Linux文件是/目录/目录/目录或文件/来表示的&#xff08;其中目录可以看作是windows操作系统的文件夹&#xff0c;只是Linux中…

端侧大模型综述On-Device Language Models: A Comprehensive Review

此为机器翻译&#xff0c;仅做个人学习使用 设备端语言模型&#xff1a;全面回顾 DOI&#xff1a;10.48550/arXiv.2409.00088 1 摘要 大型语言模型 &#xff08;LLM&#xff09; 的出现彻底改变了自然语言处理应用程序&#xff0c;由于减少延迟、数据本地化和个性化用户体验…

python实现音视频下载器

一、环境准备 确保当前系统已安装了wxPython 、 yt-dlp 和FFmpeg。当前主要支持下载youtube音视频 1、安装wxPython pip install wxPython2、安装yt-dp pip install wxPython yt-dlp3、安装FFmpeg 在Windows 10上通过命令行安装FFmpeg&#xff0c;最简便的方式是使用包管理…

三、小白如何用Pygame制作一款跑酷类游戏(按键图片和距离的计算)

三、小白如何用Pygame制作一款跑酷类游戏&#xff08;实现移动距离的计算&#xff0c;以及按键指引的添加&#xff09; 文章目录 三、小白如何用Pygame制作一款跑酷类游戏&#xff08;实现移动距离的计算&#xff0c;以及按键指引的添加&#xff09;前言一、创建字体文件夹1.可…

H5:实现安卓和苹果点击下载App自动跳转到对应的应用市场

一、需求场景 手机扫描下载App&#xff0c;需要根据不同手机自动跳转到对应的应用市场&#xff08;商店&#xff09;里&#xff0c;苹果手机直接打开App Store里指定的app页面&#xff0c;安卓手机如果是海外用户则打开GooglePlay 商店里指定的app页面&#xff0c;国内直接下载…

【Linux】文件传输归档与压缩

目录 配置实验环境 文件传输方法--scp&#xff0c;rsync scp rsync 归档与压缩--tar&#xff0c;gz&#xff0c;bz2&#xff0c;xz&#xff0c;zip 归档---tar 压缩 zip gzip bzip2 xz 归档并压缩 gz bz2 xz 拓展du 配置实验环境 在多个linux系统进行系统传输…

3D人脸扫描技术如何让真人“进入“虚拟,虚拟数字人反向“激活“现实?

随着虚拟人技术的飞速发展&#xff0c;超写实数字人已经成为数字娱乐、广告营销和虚拟互动领域的核心趋势。无论是企业家、知名主持人还是明星&#xff0c;数字分身正在以高度还原的形象替代真人参与各类活动&#xff0c;甚至成为品牌代言、直播互动的新宠。 3D人脸扫描&#…

Git标签的认识

Git标签完全指南&#xff1a;从基础到企业级发布策略 前言 在软件发布领域&#xff0c;Git标签是版本管理的基石。根据2023年GitHub年度报告显示&#xff0c;85%的开源项目使用标签进行版本控制。然而&#xff0c;许多开发者仅停留在git tag的基础使用层面&#xff0c;未能充分…

【Rust基础】使用Rocket构建基于SSE的流式回复

背景 我们正在使用Rust开发基于RAG的知识库系统&#xff0c;其中对于模型的回复使用了常用的SSE&#xff0c;Web框架使用Rocket&#xff0c;Rocket提供了一个简单的方式支持SSE&#xff0c;但没有会话保持、会话恢复等功能&#xff0c;因此我们自己简单实现这两个功能。 使用R…

大前端基础学习

一、cs架构和bs架构 c&#xff1a;客户端&#xff0c; b&#xff1a;浏览器&#xff08;无需安装&#xff0c;无需更新&#xff0c;可跨平台&#xff09;√ s&#xff1a;server服务端&#xff0c;帮我们保 存信息&#xff0c;传递信息 二、 altshift向下键向下复制一行 …

Axios 的 POST 请求:QS 处理数据的奥秘与使用场景解析

在现代前端开发中&#xff0c;Axios 已经成为了进行 HTTP 请求的首选库之一&#xff0c;它的简洁易用和强大功能深受开发者喜爱。当使用 Axios 进行 POST 请求时&#xff0c;我们常常会遇到一个问题&#xff1a;是否需要使用 QS 库来处理请求数据&#xff1f;什么时候又可以不用…

Linux 防火墙( iptables )

目录 一、 Linux 防火墙基础 1. 防火墙基础概念 &#xff08;1&#xff09;防火墙的概述与作用 &#xff08;2&#xff09;防火墙的结构与匹配流程 &#xff08;3&#xff09;防火墙的类别与各个防火墙的区别 2. iptables 的表、链结构 &#xff08;1&#xff09;规则表 …

【redis进阶三】分布式系统之主从复制结构(1)

目录 一 为什么要有分布式系统&#xff1f; 二 分布式系统涉及到的非常关键的问题&#xff1a;单点问题 三 学习部署主从结构的redis (1)创建一个目录 (2)进入目录拷贝两份原有redis (3)使用vim修改几个选项 (4)启动两个从节点服务器 (5)建立复制&#xff0c;要想配…

EM储能网关ZWS智慧储能云应用(9) — 远程OTA升级

ZWS智慧储能云平台支持远程OTA固件升级&#xff0c;可以针对具体的储能设备进行升级&#xff0c;升级储能网关、EMS主控软件、PCS、BMS等。 简介 储能系统通常高度集成化&#xff0c;一体化设计&#xff0c;将EMS、BMS&#xff08;电池管理系统&#xff09;、PCS&#xff08…

ubuntu24.04LTS安装向日葵解决方案

去向日葵官方下载ubuntu使用的deb包 向日葵 输入如下命令安装&#xff0c;将具体版本修改成自己下载的版本 andrew in ~/下载 λ sudo dpkg -i SunloginClient_15.2.0.63064_amd64.deb 正在选中未选择的软件包 sunloginclient。 (正在读取数据库 ... 系统当前共安装有 290947…

达梦官方管理工具SQLark:自动识别外键约束、check约束与虚拟列,助力高效生成测试数据

在数据库管理和应用开发过程中&#xff0c;高质量的测试数据对于系统调试和POC测试至关重要。达梦官方推出的新一代管理工具 SQLark百灵连接&#xff0c;其数据生成功能&#xff0c;可以为应用开发者、DBA 以及测试人员带来极大便利&#xff0c;能够轻松应对各类复杂的测试场景…

不关“猫”如何改变外网IP?3种免重启切换IP方案

每次更换外网IP都要重启路由器&#xff1f;太麻烦了&#xff01;那么&#xff0c;不关猫怎么改变外网IP&#xff1f;无论是为了网络调试、爬虫需求&#xff0c;还是解决IP限制问题&#xff0c;频繁重启设备既耗时又影响效率。其实&#xff0c;更换外网IP并不一定要依赖“重启大…