1. 阐述Spring Boot整合Spring Data Redis整合步骤。

创建项目,修改pom文件,配置全局配置文件,创建启动类

  1. @Configuration注解的作用是什么?

表示将当前文件作为配置类

  1. @Bean注解的作用是什么?

用于注入方法中的配置信息

    1. Spring Boot整合Spring Data Redis-提取Redis的链接参数 
       
    1. @ConfigurationProperties注解的作用是什么?
     @ConfigurationProperties:会将前缀相同的内容创建一个实体
    1. @ConfigurationProperties注解中的prefix属性的作用是什么?
     指定前缀内容
    1. Spring Boot整合Spring Data Redis-存取Java对象 
       
    1. 创建Users实体对象,包含id、name、age、address属性。
     public class Users implements Serializable{
     private Integer id;
     private String name;
     private Integer age;
     private String address;
    }
    1. 创建测试代码,在测试方法中重新设置序列化器,更换为jdk序列化器,
    2. 并将Users对象缓存到Redis中。
    3. 创建测试代码,获取缓存的Users对象。
     /**
     * 完成对Redis的整合的一些配置
     * 
     * @author chy
     *
     */
    @Configuration
    public class RedisConfig {
     /**
     * 1.创建JedisPoolConfig 对象。在该对象中完成一些链接池配置
     * @ConfigurationProperties:会将前缀相同的内容创建一个实体。
     */
     @Bean
     @ConfigurationProperties(prefix="spring.redis.pool")
     public JedisPoolConfig jedisPoolConfig(){
     JedisPoolConfig config = new JedisPoolConfig();
     //最大空闲数
     //config.setMaxIdle(10);
     //最小空闲数
     //config.setMinIdle(5);
     //最大链接数
     //config.setMaxTotal(20);
     System.out.println("默认值:"+config.getMaxIdle());
     System.out.println("默认值:"+config.getMinIdle());
     System.out.println("默认值:"+config.getMaxTotal());
     return config;
     }
     /**
     * 2.创建JedisConnectionFactory:配置redis链接信息
     */
     @Bean
     @ConfigurationProperties(prefix="spring.redis")
     public JedisConnectionFactory jedisConnectionFactory(JedisPoolConfig config){
     System.out.println("配置完毕:"+config.getMaxIdle());
     System.out.println("配置完毕:"+config.getMinIdle());
     System.out.println("配置完毕:"+config.getMaxTotal());
     JedisConnectionFactory factory = new JedisConnectionFactory();
     //关联链接池的配置对象
     factory.setPoolConfig(config);
     //配置链接Redis的信息
     //主机地址
     //factory.setHostName("192.168.179.131");
     //端口
     //factory.setPort(6379);
     return factory;
     }
     /**
     * 3.创建RedisTemplate:用于执行Redis操作的方法
     */
     @Bean
     public RedisTemplate<String,Object> redisTemplate(JedisConnectionFactory factory){
     RedisTemplate<String, Object> template = new RedisTemplate<>();
     //关联
     template.setConnectionFactory(factory);
     //为key设置序列化器
     template.setKeySerializer(new StringRedisSerializer());
     //为value设置序列化器
     template.setValueSerializer(new StringRedisSerializer());
     return template;
     }
    }
    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringBootTest(classes=App.class)
    public class TestRedis {
     @Autowired
     private RedisTemplate<String, Object> redisTemplate;
     /**
     * 插入一个字符串
     */
     @Test
     public void TestSet() {
     this.redisTemplate.opsForValue().set("name", "乔鲁诺乔斯达");
     }
     /**
     * 从redis中取值
     */
     @Test
     public void TestGet() {
     String name = (String) this.redisTemplate.opsForValue().get("name");
     System.out.println(name);
     }
    /**
     * 设置Users对象
     *注意通过: JdkSerializationRedisSerializer序列化器所占内存较大
     */
     @Test
     public void TestObjectSet() {
     Users users = new Users();
     users.setId(1);
     users.setName("乔鲁诺乔巴纳");
     users.setAge(16);
     users.setAddress("意大利罗马");
     this.redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
     this.redisTemplate.opsForValue().set("Users", users);
     }
     /**
     * 获取Users对象
     *注意通过: JdkSerializationRedisSerializer序列化器所占内存较大
     */
     @Test
     public void TestObjectGet() {
     this.redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
     Users users = (Users) this.redisTemplate.opsForValue().get("Users");
     System.out.println(users);
     }
     /**
     * 设置Users对象,通过Json序列化器
     *占用内存较小
     */
     @Test
     public void TestObjectSetJson() {
     Users users = new Users();
     users.setId(1);
     users.setName("乔鲁诺乔巴纳");
     users.setAge(16);
     users.setAddress("意大利罗马");
     this.redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(Users.class));
     this.redisTemplate.opsForValue().set("Users_Json", users);
     }
     /**
     * 获取Users对象,通过Json序列化器
     *占用内存较小
     */
     @Test
     public void TestObjectGetJson() {
     this.redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(Users.class));
     Users users = (Users) this.redisTemplate.opsForValue().get("Users_Json");
     System.out.println(users);
     }
    }
    1. Spring Boot定时任务-@Scheduled的使用 
       
    1. Scheduled是什么?
     //不属于控制层、服务层、数据访问层。所以使用@Component
    @Component
    public class ScheduledDemo {
     /**
     * 每两秒打印一次时间
     * cron="0/2 * * * * *"
     * 
     * 每分钟的第二秒打印一次时间
     * cron="2 * * * * *"
     */
     @Scheduled(cron="0/2 * * * * ?")
     public void doScheduled() {
     System.out.println("定时器:"+new Date());
     }
    }
    1. @Scheduled注解的作用是什么?

    开启定时任务

    1. @Scheduled的cron属性的作用是什么?

    指定定时器规则

    1. 什么是cron表达式?

    Cron 表达式是一个字符串,分为6 或7 个域,每一个域代表一个含义

    Cron 有如下两种语法格式:

    (1) Seconds Minutes Hours Day Month Week Year

    (2) Seconds Minutes Hours Day Month Week(推荐使用)

    1. @EnableScheduling注解的作用是什么?

    在开启启动类时,需要额外加@EnableScheduling注解

    1. Spring Boot定时任务-cron表达式
    1. Cron表达式的语法格式有几种?
    2. Cron表达式的结构是什么样的?
    3. Cron表达式各字段的含义是什么?
    4. 在Cron表达式中(*)、(?)、(-)、(,)、(/)、(#)分别表示什么含义?
    5. 在Cron表达式中L、W、LW、C分别表示什么含义?

    Spring Boot定时任务-Quartz介绍

    1. 什么是Quartz?

    Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用。Quartz可以用来创建简单或为运行十个,百个,甚至是好几万个Jobs这样复杂的程序。Jobs可以做成标准的Java组件或 EJBs。Quartz的最新版本为Quartz 2.3.0。

    1. Quartz的使用思路是什么?

    创建定时任务,启动定时任务

    1. Spring Boot定时任务-SpringBoot整合Quartz
    1. 阐述Spring Boot整合Quartz整合步骤。

    1.创建项目,导入依赖

    2.修改全局配置文件

    3.创建启动类

    1. @EnableScheduling注解的作用是什么?

    开启定时器

    1. Spring Boot定时任务-Job类对象注入
    1. 阐述Job类注入时生异常的原因。

    在quartz中定时任务的创建时通过AdaptableJobFactory类中的createJobInstance方法创建,使用的是反射,没有使用spring,所以无法注入对象。

    1. 如何解决该异常?

    复写createJobInstance方法,将创建的定时任务加入到spring容器中。

    1. AutowireCapableBeanFactory对象的作用是什么?

    可以将一个对象添加到SpringIOC 容器中,并且完成该对象注入

    1. 单体架构
    1. 什么是单体架构?

    单体架构也称之为单体系统或者是单体应用。就是一种把系统中所有的功能、模块耦合在一个应用中的架构方式。

    1. 单体架构有哪些特点?

    打包成一个独立的单元 jar包或者 war包 ;会以进程的方式运行

    1. 单体架构的优缺点是什么?

    优点:项目易于管理、部署简单。

    缺点:测试成本高、可伸缩性差、可靠性差、迭代困难、跨语言程度差、团队协作难

    1. 微服务架构
    1. 什么是微服务?

    微服务就是一个轻量级的治理方案。

    1. 常见的架构风格有哪些?

    MVC、RPC、SOA、微服务架构

    1. 微服务架构有哪些特点?




    springboot ThreadPoolTaskScheduler会阻塞_定时任务


    1. 微服务架构的优缺点是什么?

    优点: 模块之间耦合度低,可拓展性强

    缺点: 项目变多,启动费时,不易管理

    1. 常见软件架构方式的区别
    1. 什么是MVC架构?

    MVC(Model-View-Controller) : MVC架构就是一个单体架构。

    1. 什么是RPC架构?

    RPC(Remote Procedure Call) :远程过调用。通过网络从计算机序上请求服务,而不需要了解底层网络技术的协议的架构方式。

    1. 什么是SOA架构?

    SOA(Service oriented Architecture): 面向服务架构

    1. AKF拆分原则
    1. 设计微服务的原则是什么?’’

    AKF拆分原则

    前后端分离原则

    无状态服务

    Restful通信风格

    1. 什么是AKF拆分原则?

    业界对于可扩展的系统架构设计有一个朴素的理念,就是: 通过加机器就可以解决容量和可用性问题。(如果一台不行那就两台)。 这一理念在“云计算”概念疯狂流行的今天,得到了广泛的认可!对于一个规模迅速增长的系统而言,容量和性能问题当然是首当其冲的。但是随着时间的向前,系统规模的增长,除了面对性能与容量的问题外,还需要面对功能与模块数量上的增长带来的系统复杂性问题以及业务的变化带来的提供差异化服务问题。而许多系统,在架构设计时并未充分考虑到这些问题,导致系统的重构成为常态,从而影响业务交付能力,还浪费人力财力!对此,《可扩展的艺术》一书提出了一个更加系统的可扩展模型—— AKF可扩展立方 (Scalability Cube)。这个立方体中沿着三个坐标轴设置分别为:X、Y、Z。

    1. AKF拆分原则中的Y轴表示什么?

    Y轴(功能 ) —— 关注应用中功能划分, 基于不同的业务拆分

    1. AKF拆分原则中的X轴表示什么?

    X轴(水平扩展) —— 关注水平扩展,也就是”加机器解决问题”

    1. AKF拆分原则中的Z轴表示什么?

    Z轴(数据分区) —— 关注服务和数据的优先级划分,如按地域划分

    1. 前后端分离原则
    2. 什么是前后端分离原则?

    前后端分离原则,简单来讲就是前端和后端的代码分离,我们推荐的模式是最好采用物理分离的方式部署,进一步促使更彻底的分离。如果继续直接使用服务端模板技术,如:jsp,把java、js、html、css 都堆到一个页面里,稍微复杂一点的页面就无法维护了。

    1. 无状态服务
    1. 什么是无状态服务?

    对于无状态服务,首先说一下什么是状态:如果一个数据需要被多个服务共享,才能完成一笔交易,那么这个数据被称为状态。进而依赖这个“状态”数据的服务被称为有状态服务,反之称为无状态服务。 那么这个无状态服务原则并不是说在微服务架构里就不允许存在状态,表达的真实意思是要把有状态的业务服务改变为无状态的计算类服务,那么状态数据也就相应的迁移到对应的“有状态数据服务”中。

    场景说明:例如我们以前在本地内存中建立的数据缓存、Session缓存,到现在的微服务架构中就应该把这些数据迁移到分布式缓存中存储,让业务服务变成一个无状态的计算节点。迁移后,就可以做到按需动态伸缩,微服务应用在运行时动态增删节点,就不再需要考虑缓存数据如何同步的问题。

    1. RestFul通信风格
    1. 什么是RestFul通信风格?

    作为一个原则来讲本来应该是个“无状态通信原则”,在这里我们直接推荐一个实践优选的Restful 通信风格 ,因为他有很多好处:

    无状态协议HTTP,具备先天优势,扩展能力很强。例如需要安全加密,有现成的成熟方案HTTPS即可。

    JSON 报文序列化,轻量简单,人与机器均可读,学习成本低,搜索引擎友好。

    语言无关,各大热门语言都提供成熟的Restful API框架,相对其他的一些RPC框架生态更完善。