java(框架) springboot-1 基础使用+mybaits使用

学习视频:b站黑马java教程

tomcat

spring-boot工程内嵌了tomcat服务器
在这里插入图片描述

  • 所有请求经过DispatcherServlet(实现servlet接口的类)(核心控制器/前端控制器)处理,再通过DispatcherServlet转发给各个controller

  • 最后通过DispatcherServlet给浏览器响应数据

  • 他会将浏览器的http请求鞋带的数据,比如header,body等封装到HttpServletRequest对象中,相当于nest的@Request() req;获取请求对象。

  • 然后通过HttpServletResponse设置相应数据,DispatcherServlet会根据响应数据,封装好http响应头,响应给浏览器。相当于nest的@Response() res;

  • BS架构 浏览器/服务器模式 用户只要有浏览器就行

  • CS架构 客户端/服务器,比如qq,网盘等

获取请求参数
query参数

原始方式,从HttpServletrequest中取出并且转换数据


    @RequestMapping("/hello") //相当于nest的@Get("/hello"),处理哪个请求
    public String hello(HttpServletRequest req){
        // 获取query参数
        String name = req.getParameter("name");
        String age = req.getParameter("age");
        return "your name is" + name + "; and you age is" + age;
    }

springboot方式

// 请求处理类
@RestController //注解,用来标记这个类是请求处理类,相当于nest的@Controller
public class HelloController {

    @RequestMapping("/hello") //相当于nest的@Get("/hello"),处理哪个请求
  @RequestMapping("/hello") //相当于nest的@Get("/hello"),处理哪个请求
    public String hello(@RequestParam(name="name", required=false) String userName, String age){
        return "your name is" + userName + "; and you age is" + age;
    }
}

简单参数直接作为方法参数写入即可,命名需要一样(不一样需要用@ReueqstParam(name=“name”)去重命名)。相当于nest的@Query() query快速获取参数。
对应Post请求,如果是x-www-form-urlencoded的方式,也是上述这种方式即可

小结

在这里插入图片描述

实体参数

如果简单参数太多,一个一个些不切实际,定义POJO接收即可。

package com.example.demo.pojo;

public class UserProps {
    private String name;
    private String age;
    public String getName(){
        return this.name;
    }

    public String getAge(){
        return this.age;
    }

}

定义一个实体对象,pojo类,

 @RequestMapping("/hello") //相当于nest的@Get("/hello"),处理哪个请求
    public String hello(UserProps user){
        return "your name is" + user.getName() + "; and you age is" + user.getAge();
    }

直接创建了一个实例,然后调用定义好的方法去获取。结果一样。
如果是复杂的,比如
在这里插入图片描述
用得较少。

数组集合参数

在这里插入图片描述
用得较少。

日期参数

在这里插入图片描述
用得较少,大多都是通过post封装json。

JSON参数

在这里插入图片描述


package com.example.demo.pojo;

public class AddressProps {
    public String province;
    public String city;

    public String get(String field){
        switch (field){
            case "city": {
                return this.city;
            }
            case "province":
            default: {
                return this.province;
            }
        }
    }

}
package com.example.demo.pojo;

public class UserJsonProps {
     public String name;
    public String age;
    public AddressProps address;

}



@RequestMapping("/json")
    public String json(@RequestBody UserJsonProps user){
        System.out.println(user.age);
        System.out.println(user.name);
        System.out.println(user.address.city + user.address.province);
        return "ok";
    };

使用@RequestBody标识,类似于nest的@Body() body;

Params 参数

在这里插入图片描述
@RequestMapping指定路径的时候就加上变量定义,然后通过@pathVariable去获取对应的变量。多个就写多个。

小结
  • query参数,可以通过HttpServletrequest得到req,然后通过req.getParamter获取值@也可以通过springboot封装好的,直接通过方法参数的形式获取,变量名称不一样的话需要使用@RequestParam去重命名。
  • 实体对象,但query很多的时候,可以封装pojo类来创建一个实例,然后通过实例获取值
  • 数据集合和日期通过query的比较少,一般通过json请求
  • json格式的数据,通过@RequestJson,封装pojo类获取
  • params格式的数据,通过@ReqeusetMapping指定url的时候就制定变量(跟nest类似),然后通过@PathVariable定义方法参数变量获取数据。
设置响应数据

在这里插入图片描述
@RestController注解的定义。

@Target({ElementType.TYPE}) //类型,TYPE表示作用在类或者接口
@Retention(RetentionPolicy.RUNTIME) //运行时间, runtime的时候运行
@Documented
@Controller
@ResponseBody
public @interface RestController {
    @AliasFor(
        annotation = Controller.class
    )
    String value() default "";
}

上述将HelloController标记为@RestController,@RestController是@Controller和@ResponseBody的集合,因为作用在类上,所以该类的所有方法的返回值都会作为响应传给客户端。

统一响应内容

类似于nest的拦截器,统一响应格式。

import {
  Injectable,
  NestInterceptor,
  ExecutionContext,
  CallHandler,
} from '@nestjs/common';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

interface Response<T> {
  data: T;
}

@Injectable()
export class TransformInterceptor<T>
  implements NestInterceptor<T, Response<T>>
{
  intercept(
    context: ExecutionContext,
    next: CallHandler,
  ): Observable<Response<T>> {
    return next.handle().pipe(
      map((data) => {
        const request = context.switchToHttp().getRequest();

        if (request.url.includes('weichat/userInfo')) {
          return data;
        }
        return {
          data,
          code: 0,
          extra: {},
          msg: 'success',
          success: true,
        };
      }),
    );
  }

java也需要定义一个统一返回数据的格式

在这里插入图片描述
定义一个Result类

package com.example.demo.pojo;

public class Result<T extends Object> {

    private Integer code;
    private String msg;
    private T data;

    public Result(Integer code, String msg, T data){
        this.code = code;
        this.msg = msg;
        this.data = data;
    }

    public Integer getCode(){
        return this.code;
    };
    public void setCode(Integer code){
        this.code = code;
    };

    public String getMsg(){
        return this.msg;
    };
    public void setMsg(String msg){
        this.msg = msg;
    };
    public T getData(){
        return this.data;
    };
    public void setData(T data){
        this.data = data;
    };


    // 重载
    public static <K extends Object>Result<K> success(K data){
        return new Result<K>(0, "success", data);
    }

    public static Result success(){
        return new Result<>(0, "success",  null);
    }

    public static Result error(String msg){
        return new Result(1, msg,  null);
    }

}

提供两个静态方法,success和error,然后修改

 @RequestMapping("/json")
    public Result json(@RequestBody UserJsonProps user){
        System.out.println(user.age);
        System.out.println(user.name);
        System.out.println(user.address.city + user.address.province);
        return Result.success(user);
    };

结果
在这里插入图片描述
这样就封装成功了。

分层解藕
三层架构

在这里插入图片描述
如nest的Controller 和 Service ,还有多一层dao,负责数据访问
在这里插入图片描述
controller层调用service层,service层调用dao层获取数据。
在这里插入图片描述
符合单一原则。

解耦

在这里插入图片描述
像上面三层设计,controller层要调用service层,所以new了一个实例,service层要调用dao层,也new了一个dao的实例,这就导致controller和service耦合,service和dao耦合。

原则:高内聚,低耦合

为了实现解耦,需要提供一个容器。将所有需要用到的对象放到容器中,然后其他层需要依赖的时候,再去取。类似于多一个中介,实现解耦。

在这里插入图片描述
现在的问题就是,我们不想要自己new一些对象,只想在class上面声明依赖,然后让程序帮我们创建对应的依赖对象传入进来。

这就涉及两个概念控制反转依赖注入

在这里插入图片描述
IOC:原本我们需要什么对象,就自己new一个,现在是直接交给容器去帮我们创建
DI: controller层需要依赖service对象,由容器我们注入,称之为依赖注入。

这就是 IoC 的实现思路。
  • 它有一个放对象的容器,程序初始化的时候会扫描 class 上声明的依赖关系,然后把这些 class 都给 new 一个实例放到容器里。

  • 创建对象的时候,还会把它们依赖的对象注入进去。这样不就完成了自动的对象创建和组装么?这种依赖注入的方式叫做 Dependency Injection,简称 DI。

  • 从主动创建依赖到被动等待依赖注入,这就是 Inverse of Control,反转控制。

java改造

需要被IOC接管的类,通过@Component注解装饰。
需要通过IOC依赖注入的属性,通过@Autowired注解装饰。如

@Component //将当前类交给IOC容器管理
public class EmpDao1 implements EmpDao {

    public List<String> listEmp(){
        return List.of("小米姑娘", "小红");
    }
}

@Component
public class EmpService1 implements EmpService {
    @Autowired
    EmpDao1 emp;
    public List<String> listEmp(){
        List<String> originData =  emp.listEmp();
        // 处理数据并且返回
        return originData;
    }
}

Dao层和Service等需要注入到其他类中的类,用@component声明,其次
Service中需要用到Emp对象,所以用@Autowired声明该属性。
最后看下controller层

// 请求处理类
@RestController //注解,用来标记这个类是请求处理类,相当于nest的@Controller
public class HelloController {
    @Autowired //标识该属性需要IOC提供bean对象,并且赋值给变量
    private EmpService empService;

    @RequestMapping("/hello") //相当于nest的@Get("/hello"),处理哪个请求
    public String hello(UserProps user){
        return "your name is" + user.getName() + "; and you age is" + user.getAge();
    }

    @RequestMapping("/json")
    public Result json(@RequestBody UserJsonProps user){
        System.out.println(user.age);
        System.out.println(user.name);
        System.out.println(user.address.city + user.address.province);
        return Result.success(user);
    };

    @RequestMapping("/ioc")
    public Result ioc(){
    return Result.success(empService.listEmp());
    }

}

要用到service对象,所以要用@Autowired注解装饰,IOC就会自动将实例分配进来。

IOC详解

在这里插入图片描述
将上述Service使用的@Component转为@Service,将Dao层换为@Repository,Controller不用换,因为@RestController已经包括@Controller。
其次Bean对象还有名字,默认是类名小写。

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Repository {
    @AliasFor(
        annotation = Component.class
    )
    String value() default "";
}


@Repository("daoA") //将当前类交给IOC容器管理
public class EmpDao1 implements EmpDao {

    public List<String> listEmp(){
        return List.of("小米姑娘", "小红");
    }
}

在这里插入图片描述
用注解声明的类不一定被扫描到,若扫描不到则会报错。’

DI详解

若依赖注入的时候,有多个相同的bean对象呢?
在这里插入图片描述

三种方法:

  • 通过在注解Service的时候,多注解一个@Primary,表示优先级高点。
  • 第二个就是在依赖注入时,多注解一个@Qualifiler(bean名字)
  • 第三个就是不用@autowired,而使用@Resource(bean名字),Autowried是通过类型注解的,而Resource是通过名字

在这里插入图片描述

nestjs ioc设计

需要通过IOC接管的类,通过@Injectable装饰器装饰。
需要通过IOC依赖注入的属性,通过@Inect装饰。
其次,nest还封装了module层等。

看一个简单的案例

Service

在这里插入图片描述

AppSerivce用@Injectable()装饰器装饰(java里面为注解),表示这个类,可以被注入,也可以注入别的类。那么nest在解析运行时就会new一个他的实例放入容器中。

然后这是个service层,需要用到数据库的数据,所以可以通过@InjectRepository(Project)等方式,注入两个仓库实例,使用的时候我们就不需要new一个实例,nest运行时直接帮我们创建好并且传入。

Controller

在这里插入图片描述
然后是Controller层,通过Controller装饰器装饰,表示该类只能注入其他对象,而不能被注入到其他对象。
其次还声明了他需要依赖的对象,以上两种方式都可以,一种是通过@Inject声明,一种直接在构造函数上声明。前者是构造器注入,后者是属性注入,两种都可以。

module

最后在model声明
在这里插入图片描述
@Module 声明模块
controllers是控制器,只能注入其他对象,
providers可以被注入,也可以注入其他对象,

当我们启动服务,nest就会自动解析我们在class上面声明的依赖,自动创建和组装对象。
所以上述projectController只声明了proejctSerivce的定义,就可以使用了。

此外,nest还加了模块机制,可以吧不同业务的controller和serivce放到不同模块。
不同模块也可以相互import,一旦相互omports后,他们模块exports的service即可使用。
比如上述的proejctService可以使用仓库实例,就是因为module imports了其模块,然后依赖的模块exports定义了这个类可以被其他模块使用。

总结
  • 后端系统有很多对象,这些对象之间关系错综复杂,如果手动创建并且组装依赖关系很麻烦,所以提供了IOC机制。
  • IOC机制是在calss标识哪些可以被注入,他的依赖是什么,然后从rookie开始扫描这些对象和依赖,自动创建和组装对象。
  • IOC解决了后端系统的对象依赖关系错综复杂的痛点问题。

Mybatis

在这里插入图片描述
类似于nest中的typeorm,mybatis也是一种orm框架,用来方便连接java和数据库

MyBatis使用步骤
在这里插入图片描述

操作步骤
  • 1 在pojo下面创建实体类,字段与数据库字段一致
    在这里插入图片描述

  • 2 创建mapper接口(跟之前创建dao层的类差不多)都是dao层的逻辑
    在这里插入图片描述
    这的mapper跟dao的含义是一样的,都是持久层的逻辑,然后定义对应的UserMappe接口r,用@Mapper注解装饰,然后定义listUser方法,使其查询全部用户信息返回。

  • 3 mybatis连接mysql
    在这里插入图片描述
    在springboot生成的配置文件下面,配置mysql服务器对应的地址等信息。

  • 4 使用
    在这里插入图片描述
    因为我们实现的UserMapper虽然是接口,但他用@Mapper注解,表示由IOC容器接管,所以会在运行时创建一个对象,这样我们就可以通过依赖注入的方式,直接得到UserMapper对应的实例,然后直接调用lisetUser方法,就可以获取到数据。
    在这里插入图片描述
    结果正常,这样就简单的用mybaits连接mysql了。

JDBC

在这里插入图片描述
一组操作数据库的API,具体实现由各个数据库厂商实现。

JDBC VS MyBaits
在这里插入图片描述
如上,右边是jdbc原始写法,左方是mybtits写法。

数据库连接池

在这里插入图片描述
相当于一个容器,负责管理分类数据库连接,可以重复使用,而不是每次要用的时候创建连接(创建连接释放连接是比较浪费资源的操作)。
客户端需要用的时候,从连接池获取链接,用完就归还给连接池。

在这里插入图片描述

上面的案例
在这里插入图片描述

Lombok

之前我们编写的User实体类太繁琐,lombok可以让我们通过注解的方式,高校的编写实体类。
在这里插入图片描述
简化之后


import lombok.Data;

@Data
public class User {
    private Integer id;
    private Integer age;
    private String phoneNum;
    private String name;

}
MyBaits基础操作
删除操作
package com.example.demo.mapper;

import com.example.demo.pojo.User;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;

import java.util.List;

@Mapper //在运行时,会自动生成改接口的实现类对象(动态代理对象),并且将该对象交给IOC容器管理。
public interface UserMapper {

    // 查询全部用户信息
    @Select("select * from users")
    public List<User> listUser();

    // 删除操作

    // #{变量} 是mybatis提供的占位符
    // delete会返回此次操作影响的数据条数,简单的说就是删除了多少条数据
    @Delete("delete from users where id = #{id}")
    public int delete(Integer id);

}

使用变量代替,这种称为预编译sql

在这里插入图片描述
首先是性能更高,因为sql是有缓存的,使用预编译sql,可以完美利用缓存。
其次是更安全。防止sql注入f
mybatis的参数占位符
在这里插入图片描述

新增
   // 新增
    @Insert("insert into users(name, age, phoneNum) values(#{name}, #{age}, #{phoneNum})")
    public void insert(User user);

变量是user里面的属性。
使用

@Test
	void insert(){
		User userTest = new User();
		userTest.setAge(18);
		userTest.setName("ceshi");
		userTest.setPhoneNum("1023123213");
		user.insert(userTest);
		System.out.println("插入成功");
		this.contextLoads();
	}

在这里插入图片描述
多个参数可以用实体类封装起来。

更新
 // 更新
    @Update("update users set name=#{name}, age=#{age}, phoneNum=#{phoneNum} where id=#{id}")
    public int update(User user);
查询
Select("select * from users where id=#{id}")
    public List<User> getById(Integer id);

在这里插入图片描述
mybatis有驼峰自动命名开关,一旦打开,会自动映射a_b到aB上。
直接在配置文件里面配置

mybatis.configuration.map-underscore-to-camel-case=true
条件查询

在这里插入图片描述
模糊查询因为是字符串,所以不能用#{},可以用${},但是性能低,不安全,使用java提供的concat函数拼接字符串
在这里插入图片描述

XML映射文件

之前用mybaits查数据库都是使用注解的方式。可以通过配置文件的方式来写sql
在这里插入图片描述
编写xml要注意规范

  • 文件名称一致,目录一致
    在这里插入图片描述
  • 2 id一致,resultType表示返回的单条数据类型

在这里插入图片描述在这里插入图片描述
最后,注释掉注解,使用xml,直接运行。
在这里插入图片描述
结果一样。

Mybaits 动态sql

在这里插入图片描述
有些字段传了就需要where,有些字段没值就不需要where

  <select id="listUser" resultType="com.example.demo.pojo.User">
        select * from users;
    </select>


    <select id="getByField" resultType="com.example.demo.pojo.User">
        select * from users
        <!-- 1 动态生成where 2 自动去除多余and 或者 or -->
        <where>

            <if test="name != null">
                name like concat('%', #{name}, '%')
            </if>
            <if test="age != null">
               and and age = #{age}
            </if>
            order by age desc;
        </where>

    </select>

如上,用where标签,自动生成where,并且会根据条件自动去除开头的and和or, 用if标签判断是否要加上该条件。

在这里插入图片描述

修改
 <update id="update">
        update users
        <!-- 跟where 一样, set标签自动加上set,去除末尾多余逗号-->
        <set>
            <if test="name != null">
                name = #{name},
            </if>
            <if test="age != null">
                age = #{age},
            </if>
            <if test="phoneNum != null">
                phoneNum = #{phoneNum}
            </if>
        </set>
        where id = #{id}

    </update>

也是用动态Sql
在这里插入图片描述

批量操作 foreach标签
<delete id="deleteByIds">
        delete from users where id in

        <!--
        collection 遍历的集合
        item 遍历出来的元素
        separator 分隔符
        open: 遍历钱拼接的sql片段
        close: 遍历结束后拼接的sql片段
        -->
        <foreach collection="ids" item="id" separator="," open="(" close=")">
            #{id}
        </foreach>
        <!-- 上面的标签会变成 (1,2,3) -->
    </delete>

在这里插入图片描述
foreach能转化像in (x,x,x)这些操作

include和sql标签

类似于组件复用,sql标签能将重复的sql语句拆出来,并且标记一个名字,使用的时候用include标签就可以引用到。
在这里插入图片描述
sql标签将重复的sql语句抽离,include标签引入抽离的sql标签。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

3D数字孪生运行不起来?该检查你的电脑配置了

运行3D数字孪生项目通常需要一定的计算资源和图形处理能力。以下是一些常见的电脑配置要求&#xff0c;可以作为参考&#xff1a;1处理器&#xff08;CPU&#xff09;&#xff1a;推荐使用多核心处理器&#xff0c;如Intel Core i7或更高级别的处理器。较高的时钟频率和较大的缓…

RocketMQ的事务消息是如何实现的?

RocketMQ的事务消息是通过 TransactionListener接口来实现的。 在发送事务消息时,首先向RocketMQ Broker 发送一条‘half消息’(半消息),半消息将被存储在broker端的事务消息日志中,但是这个消息还不能被消费者消费。 接下来,在半消息发送成功后,应用程序通过执行本地事务…

msvcr110.dll丢失的5种修复方法,快速修复msvcr110.dll缺失问题

MSVCR110.dll文件的丢失可能会引发一系列的问题与不便&#xff0c;严重影响到用户的计算机使用体验。首先&#xff0c;由于MSVCR110.dll是Microsoft Visual C Redistributable Package的一部分&#xff0c;它的缺失可能导致许多基于此运行库编译的应用程序无法正常启动或运行&a…

52. N 皇后 II

52. N 皇后 II 题目-困难难度1. 回溯 题目-困难难度 n 皇后问题 研究的是如何将 n 个皇后放置在 n n 的棋盘上&#xff0c;并且使皇后彼此之间不能相互攻击。 给你一个整数 n &#xff0c;返回 n 皇后问题 不同的解决方案的数量。 示例 1&#xff1a; 输入&#xff1a;n …

蓝桥杯集训·每日一题2024 (二分,双指针)

前言&#xff1a; 开学了&#xff0c;平时学习的压力也逐渐大起来了&#xff0c;不过还算可以接受&#xff0c;等到后面阶段考的时候就不一样了&#xff0c;我目前为了转专业退选了很多课&#xff0c;这些课我都需要花时间来刷绩点&#xff0c;不然保研就没有竞争力了。我自己会…

人工蜂群算法

人工蜂群算法 人工蜂群算法&#xff08;Artificial Bee Colony Optimization,ABC&#xff09;是一种基于蜜蜂觅食行为的优化算法&#xff0c;由土耳其学者Karaboga于2005年提出&#xff0c;算法模拟蜜蜂的采蜜行为对优化问题进行求解。 算法原理 ABC算法的核心思想是将优化问…

STM32基础--构建自己的固件库

CMSIS 标准及库层次关系 因为基于 Cortex 系列芯片采用的内核都是相同的&#xff0c;区别主要为核外的片上外设的差异&#xff0c;这些差异却导致软件在同内核&#xff0c;不同外设的芯片上移植困难。为了解决不同的芯片厂商生产的 Cortex 微控制器软件的兼容性问题&#xff0…

API可视化编排,提高API可复用率

在数字化时代&#xff0c;API&#xff08;应用程序编程接口&#xff09;已成为不同软件应用之间沟通的桥梁。然而&#xff0c;如何高效管理、编排和复用这些API&#xff0c;成为了企业和开发者面临的重要挑战。随着技术的不断进步&#xff0c;RestCloud API可视化编排应运而生&…

PCIE的TLP包的封包解包原理

前言&#xff1a;开始pcie项目之前需要知道&#xff0c;本次项目我们是使用现有的框架RIFFA框架去完成设计的&#xff0c;因此比起具体代码的含义&#xff0c;更注重框架的使用。在开始项目之前需要了解PCIE的组建包过程。 一、TLP包的基本格式&#xff1a; 1.1整体包结构概述…

01-DevOps代码上线-git入门及gitlab远程仓库

一、准备学习环境 10.0.0.71-gitlab 2c2g-20GB 10.0.0.72-jenkins 2c2g-20GB 10.0.0.73-sonarqube 1c1g-20GB 10.0.0.74-nexus 1c1g-20GB 10.0.0.75-dm 1c1g-20GB &#xff08;模拟写代码服务器&#xff09; 在centos系统中&…

2024 批量下载公众号文章内容/阅读数/在看数/点赞数/留言数/粉丝数导出pdf文章备份(带留言):公众号记忆承载近1500篇历史文章在线查看,找文章方便了

关于公众号文章批量下载&#xff0c;我之前写过很多文章&#xff1a; 视频更新版&#xff1a;批量下载公众号文章内容/话题/图片/封面/音频/视频&#xff0c;导出html&#xff0c;pdf&#xff0c;excel包含阅读数/点赞数/留言数 2021陶博士2006/caoz的梦呓/刘备我祖/六神读金…

微服务架构 | 多级缓存

INDEX 通用设计概述2 优势3 最佳实践 通用设计概述 通用设计思路如下图 内容分发网络&#xff08;CDN&#xff09; 可以理解为一些服务器的副本&#xff0c;这些副本服务器可以广泛的部署在服务器提供服务的区域内&#xff0c;并存有服务器中的一些数据。 用户访问原始服务器…

HNU-算法设计与分析-甘晴void学习感悟

前言 算法设计与分析&#xff0c;仅就课程而言&#xff0c;似乎是数据结构与算法分析的延续 教材使用&#xff1a; 课程 关于课程&#xff0c;橙学长讲的非常清晰&#xff0c;我深以为然。 HNUCS-大三课程概览-CSDN博客文章浏览阅读1.3k次&#xff0c;点赞5次&#xff0c;收…

JVM-垃圾收集底层算法实现

三色标记 背景描述 在并发标记的过程中&#xff0c;因为标记期间应用线程还在继续跑&#xff0c;对象间的引用可能发生变化&#xff0c;多标和漏标的情况就有可能发生。 如何解决上面的问题&#xff1f; 引入“三色标记” 意思就是&#xff0c;把Gcroots可达性分析遍历对象过程…

【北京迅为】《iTOP-3588开发板网络环境配置手册》第4章 开发板直连电脑配置方法(无线上网)

RK3588是一款低功耗、高性能的处理器&#xff0c;适用于基于arm的PC和Edge计算设备、个人移动互联网设备等数字多媒体应用&#xff0c;RK3588支持8K视频编解码&#xff0c;内置GPU可以完全兼容OpenGLES 1.1、2.0和3.2。RK3588引入了新一代完全基于硬件的最大4800万像素ISP&…

qtvs2022工程cmakelist.txt添加QCharts模块

find_package(QT NAMES Qt5 COMPONENTS Core Gui Widgets OpenGL Concurrent Charts Sql Network REQUIRED) find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui Widgets OpenGL Charts Concurrent Sql Network REQUIRED)这里find_package只是设置搜索路径&#xff0c;为…

使用ffmpeg提取视频中的音频并保存为单声道wav

1 原始视频信息 通过ffmpeg -i命令查看视频基本信息 $ ffmpeg -i C0439.MP4 ffmpeg version 6.1-essentials_build-www.gyan.dev Copyright (c) 2000-2023 the FFmpeg developersbuilt with gcc 12.2.0 (Rev10, Built by MSYS2 project)configuration: --enable-gpl --enable…

设计模式学习笔记 - 设计原则 - 10.实战:针对非业务的通用框架开发,如何做需求分析和设计及如何实现一个支持各种统计规则的性能计数器

前言 接下来我们在结合一个支持各种统计规则的性能计数项目&#xff0c;学习针对一个非业务的通用框架开发&#xff0c;如何来做需求分析、设计和实现&#xff0c;同时学习如何灵活应用各种设计原则。 项目背景 设计开发一个小的框架&#xff0c;能够获取接口调用的各种统计信…

Mysql中的MVCC

”真正学会&#xff0c;如你般自由~“ MVCC机制简介 MVCC(Multi-Version-Concurrency-Control)多版本并发控制&#xff0c;MVCC 是一种并发控制的方法&#xff0c;一般在数据库管理系统中&#xff0c;实现对数据库的并发访问&#xff1b;在编程中实现事务内存。 取自 MVCC存在被…

基于Python3的数据结构与算法 - 12 数据结构(列表和栈)

目录 一、引入 二、分类 三、列表 1. C语言中数组的存储方式 2. Python中列表的存储方式 四、栈 1. 栈的应用 -- 括号匹配问题 一、引入 定义&#xff1a;数据结构是指相互之间存在着一种或多种关系的数据元素的集合和该集合中数据元素之间的关系组成。简单来说&#x…