• java秋招面试一


    springboot依赖注入的方式

    Bean的注入通常使用@Autowired注解,该注解用于bean的field、setter方法以及构造方法上,显式地声明依赖。
    在最新的文档中注入方式有两大类:

    基于构造函数的依赖注入(推荐使用)
    基于setter的依赖注入

    springboot事务传播机制

    在这里插入图片描述

    springboot的优缺点

    优点:快速创建独立运行的Spring应用以及与主流框架集成
    1.1. 使用嵌入式的Servlet容器,应用最终可以打成Jar包的形式独立运行。
    1.2. 版本仲裁中心和不同的场景启动器为Spring Boot应用开发管理这不同的框架和版本依赖。
    1.3. 约定大于配置,Spring Boot为开发者导入项目所使用的框架设置好了默认配置。
    1.4. Java Config代替了原有难以管理的SpringXML配置。
    1.5. 提供了准生产环境的运行时的应用监控。
    1.6. 与云计算的天然集成,Spring Cloud相关框架技术。
    缺点:Spring Boot的最大优点就是为开发者屏蔽了底层框架的复杂性。这样恰好是其缺点。Spring Boot降低了入门门槛,但是其封装使后期学习曲线陡峭。所以如果需要熟练的掌握该框架,必须了解其底层原理。依赖太多。

    springboot自动装配原理

    SpringBoot启动的时候会通过@EnableAutoConfiguration注解找到META- INF/spring.factories配置文件中的所有自动配置类,并对其进行加载,而这些自动配置类都是以AutoConf iguration结尾来命名的,它实际上就是一个JavaConfig形式的Spring容器配置类,它能通过以Properties结尾命名的类中取得在全局配置文件中配置的属性如: server .port,而XxxxProperties类是通 过@Confi gurationProperties注解与全局配置文件中对应的属性进行绑定的。

    springboot如何配置redis

    1.导入依赖

    <dependency>
    	<groupId>org.springframework.boot</groupId>
    	<artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    
    • 1
    • 2
    • 3
    • 4

    2.配置连接
    编写yml

      redis:
        #数据库索引
        database: 0
        host: 127.0.0.1
        port: 6379
        password:
        jedis:
          pool:
            #最大连接数
            max-active: 8
            #最大阻塞等待时间(负数表示没限制)
            max-wait: -1
            #最大空闲
            max-idle: 8
            #最小空闲
            min-idle: 0
            #连接超时时间
        timeout: 10000
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    3.编写配置类

    import org.springframework.cache.annotation.CachingConfigurerSupport;
    import org.springframework.cache.annotation.EnableCaching;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.redis.connection.RedisConnectionFactory;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
    import org.springframework.data.redis.serializer.RedisSerializer;
    import org.springframework.data.redis.serializer.StringRedisSerializer;
    
    @Configuration
    @EnableCaching
    public class RedisConfig extends CachingConfigurerSupport {
        @Bean(name = "redisTemplate")
        public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){
    
            RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
            //参照StringRedisTemplate内部实现指定序列化器
            redisTemplate.setConnectionFactory(redisConnectionFactory);
            redisTemplate.setKeySerializer(keySerializer());
            redisTemplate.setHashKeySerializer(keySerializer());
            redisTemplate.setValueSerializer(valueSerializer());
            redisTemplate.setHashValueSerializer(valueSerializer());
            return redisTemplate;
        }
    
        private RedisSerializer<String> keySerializer(){
            return new StringRedisSerializer();
        }
    
        //使用Jackson序列化器
        private RedisSerializer<Object> valueSerializer(){
            return new GenericJackson2JsonRedisSerializer();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    java线程的启动

    1.继承Thread
    2.通过runnable接口
    3.通过Callable和Future创建线程
    4.使用异步框架 CompletableFuture
    5.线程池

    thread.start()和run()有什么区别

    start()
    用 start方法来启动线程,是真正实现了多线程, 通过调用Thread类的start()方法来启动一个线程,这时此线程处于就绪(可运行)状态,并没有运行,一旦得到cpu时间片,就开始执行run()方法。但要注意的是,此时无需等待run()方法执行完毕,即可继续执行下面的代码。所以run()方法并没有实现多线程。

    run()
    run()方法只是类的一个普通方法而已,如果直接调用Run方法,程序中依然只有主线程这一个线程,其程序执行路径还是只有一条,还是要顺序执行,还是要等待run方法体执行完毕后才可继续执行下面的代码。

    区别
    1、线程中的start()方法和run()方法的主要区别在于,当程序调用start()方法,将会创建一个新线程去执行run()方法中的代码。但是如果直接调用run()方法的话,会直接在当前线程中执行run()中的代码,注意,这里不会创建新线程。这样run()就像一个普通方法一样。

    2、另外当一个线程启动之后,不能重复调用start(),否则会报IllegalStateException异常。但是可以重复调用run()方法。

    总结起来就是run()就是一个普通的方法,而start()会创建一个新线程去执行run()的代码。

    说一说java常用集合

    Collection 接口的接口 对象的集合(单列集合)
    ├——-List 接口:元素按进入先后有序保存,可重复
    │—————-├ LinkedList 接口实现类,双向链表, 插入删除, 没有同步, 线程不安全
    │—————-├ ArrayList 接口实现类,数组,随机访问,异步, 线程不安全
    │—————-└ Vector 接口实现类 数组,线程同步, 线程安全(类方法有很多sychronized进行修饰)
    │ ———————-└ Stack 是Vector类的实现类
    └——-Set 接口: 仅接收一次,不可重复,并做内部排序
    ├—————-└HashSet 使用hash表(数组)存储元素
    │————————└ LinkedHashSet 链表维护元素的插入次序,内部通过LinkedHashMap来实现
    └ —————-TreeSet 底层实现为二叉树,元素排好序

    Map 接口 键值对的集合 (双列集合)
    ├———Hashtable 接口实现类, 同步, 线程安全,数组+列表
    ├———HashMap 接口实现类 ,没有同步, 线程不安全,可以null为key(聊了聊hashmap底层
    │—————–├ LinkedHashMap 双向链表和哈希表实现
    │—————–└ WeakHashMap
    └ ——–TreeMap 红黑树对所有的key进行排序、

    说一说有哪些线程安全的集合类

    Vector

    Vector 是 jdk1.0 的古老集合类,该类对大部分方法都加上了 synchronized 关键字,用来保证线程安全。

    CopyOnWriteArrayList

    CopyOnWrite 容器即写时复制的容器。往一个容器添加元素的时候,不直接往当前容器Object添加。

    而是先将当前容器 Object[] 进行复制,复制一个新的容器 Object[] newElement 并往其中里添加元素,添加完元素之后,再将原容器的引用指向新的容器 setArray(new Element) 。

    这样做的好处是可以对 CopyOnWrite 容器进行并发的读,而不需要加锁,因为当前容器不会添加任何元素。所以CopyOnWrite 容器也是一种读写分离的思想,读和写不同的容器。

    ConcurrentHashMap

    ConcurrentHashMap

    mysql索引的优缺点

    一、索引的优点
    1)创建索引可以大幅提高系统性能,帮助用户提高查询的速度;
    2)通过索引的唯一性,可以保证数据库表中的每一行数据的唯一性;
    3)可以加速表与表之间的链接;
    4)降低查询中分组和排序的时间。

    二、索引的缺点
    1)索引的存储需要占用磁盘空间;
    2)当数据的量非常巨大时,索引的创建和维护所耗费的时间也是相当大的;

    mysql的优化

    添加链接描述

    mybatis #{}和${}的区别

    #相当于对数据 加上 双引号,$相当于直接显示数据。

    1、#对传入的参数视为字符串,也就是它会预编译,select * from user where name = #{name},比如我传一个csdn,那么传过来就是 select * from user where name = ‘csdn’;

    2、$ 将不会将传入的值进行预编译,select * from user where name=${name},比如我传一个csdn,那么传过来就是 select * from user where name=csdn;

    3、#的优势就在于它能很大程度的防止sql注入,而$ 则不行。比如:用户进行一个登录操作,后台sql验证式样的:select * from user where username=#{name} and password = #{pwd},如果前台传来的用户名是“wang”,密码是 “1 or 1=1”,用#的方式就不会出现sql注入,而如果换成$方式,sql语句就变成了 select * from user where username=wang and password = 1 or 1=1。这样的话就形成了sql注入。

    4、MyBatis排序时使用order by 动态参数时需要注意,用$而不是#

    模糊查询中的%和_的区别

    %的作用,代表任意长度(长度可以为0)的字符串例如a%b表示以a开头,以b结尾的任意长度的字符串
    _(下横线)的作用:代表任意单个字符

  • 相关阅读:
    react组件通信
    @JsonDeserialize集合解析实例
    TensorFlow实现股票预测(RNN,网络过拟合优化)
    数据结构之常见排序算法
    基础不牢地动山摇:JS逆向攻防对抗核心的博弈点在于对JS最基础部分的深刻理解和灵活应用——干货语法大全
    java计算机毕业设计三门峡市旅游景点一站式服务规划系统演示录像源码+数据库+系统+lw文档+mybatis+运行部署
    CNN实现与训练--------------以cifar10数据集为例进行演示(基于Tensorflow)
    【win10 VS2019 opencv4.6 配置参考】
    【目标测距】雷达投影测距
    基于单片机停车场环境监测系统仿真设计
  • 原文地址:https://blog.csdn.net/qq_45681074/article/details/127410219