1.设计模式之七大原则和介绍

news2024/9/29 23:37:59

0.为什么我要学习设计模式呢?
我发现mysql的jdbc有factory有工厂模式(编程思想,不指定语言都可以用)
mq有一个QueueBuilder().setArg().xxx().build建造者模式,单例模式貌似也遇到过,前端也遇到了好几个设计模式的问题,比如prototype深拷贝和浅拷贝 所以我决定系统的学习一下设计模式…

1.java面试题

  1. 原型设计模式问题
    1.使用UML类图画出原型模式核心角色
    2. 原型设计模式的深拷贝和浅拷贝是什么,并写深拷贝2种方式的源码 clone方法实现和序列化实现
    3.spring空间哪里使用原型模式,对源码进行分析 beans.xml

    4.new ClasPathXmlApplicationContext(“beans.xml”);
    Object bean =application.getBean(“id01”)
    getBean(String name){ return doGetBean(name,null,null,false)}
    doGetBean(…){
    else if(mbd.isPrototype){
    //创建bean,面试官希望实际使用过设计模式看过源代码
    }
    }

  2. 设计模式的七大原则
    1.单一职责原则
    2.接口隔离原则
    3.依赖倒转(倒置)原则
    4.里氏替换原则
    5.开闭原则ocp 工厂模式有使用
    6.迪米特法则
    7.合成复用原则
    类图来说明设计原则

  3. 金融借贷平台 有审核-发布-抢单模式.随着操作不同改变得到状态.使用状态模式进行设计,并完成代码
    我们通常使用if else 判断状态对应的修改状态,添加一种功能导致代码更加臃肿.没有管理好状态就会有严重bug

  4. 解释器设计模式是什么? 画他的uml类图.spring框架哪里用到它,源码分析
    SepelExpressionParser类

  5. 单例设计模式 有几种实现方式8种
    1.饿汉式 2种
    2.懒汉式 3种
    3.双重检查
    4.静态内部类
    5.枚举

2.设计模式 design pattern

  1. 是解决软件设计中普遍存在(反复出现)的问题的解决方案,由1990 erich Gamma等人从建筑领域引入到计算机领域的
  2. 高楼大厦(扩展性稳定性,复用性 维护性 可读性)和小破屋 在之前的基础上加一个功能后简单可以维护
  3. 使用的地方: 面向对象->功能模块(设计模式+算法)->框架[用多种设计模式]->框架[服务器集群]
  4. 是站在项目结构合理性的角度,而不是实现功能角度,实现功能可能压根不用设计模式(我自己就深有体会,代码虽然写的方式有千百万种,只是我们写的代码量级没有达到某个层次,没有站在可维护性,可读性的角度看)

3.设计模式的目的

1.代码重用性(相同功能代码不用重复编写)
2.可读性(规范性,方便其他程序员阅读)
3.可拓展性(增加新功能非常方便 可维护性)
4.可靠性(加新功能对原来功能没有影响)
5.高内聚 低耦合(联系少,不相互影响,不多个调用别的功能,看到一堆代码我感觉脑袋快要炸掉了,如果一大堆代码有看的套路,就不再烧脑)

4.单一职责原则(一个类只实现一个功能,不同职责可能导致错误) 一个类只有一个职责(不是里面有一个方法) 如UserDao就是这个
//singreponsibility, 交通工具的例子

//不符合单一职责的代码,run方法明显是可以拆分成天空跑,地上跑,水里跑的.
class Vihicle{ //输入为飞机就错误了
       void run(String vehicle){
	sout(vehicle+"在公路上跑");
       }
 }
//改进1 拆分为多个Vihicle 符合单一职责原则,但是改动比较大,需要修改客户端
class RoadVihicle{ //输入为大车
       void run(String vehicle){
	sout(vehicle+"在公路上跑");
       }
 }
class AirVihicle{ //输入为飞机
       void run(String vehicle){
	sout(vehicle+"在天上上跑");
       }
 }
//改进2 ,直接在增加相同功能的方法,不用多个类,方法级别也可遵守单一职责
   //方法数量足够少,才可以违反单一职责
    class Vihicle{ //输入为飞机
       void run(String vehicle){
		sout(vehicle+"在公路上跑");
       }
    void runAir(String vehicle){
		sout(vehicle+"在天空上跑");
       }
  void runWater(String vehicle){
		 sout(vehicle+"在水上跑");
       }
 }

5.接口隔离原则 interface segregation principle(最小接口原则) 一个类多个类被实现,但是使用这个通过实现类间接使用这个接口的时候,有很多方法是没有使用到了,导致代码冗余
//类依赖大的接口,需要拆分为多个小的接口,类依赖与需要的接口(产生隔离不会相互影响)

   //需要把他改成最小接口 不浪费
public class singleResponsiblity {
    public static void main(String[] args) {
        A a = new A();
        a.depend1(new B());
        a.depend2(new B());
        a.depend3(new B());
        C c = new C();
        c.depend1(new D());
        c.depend4(new D());
        c.depend5(new D());


    }
}
interface Interface1{
    void fun1();
    void fun2();
    void fun3();
    void fun4();
    void fun5();
}
class A {
   void depend1(Interface1 i){
       i.fun1();
   }
    void depend2(Interface1 i){
        i.fun2();
    }
    void depend3(Interface1 i){
        i.fun3();
    }

}
class B implements Interface1{


    @Override
    public void fun1() {
        System.out.println("A实现了fun1");
    }

    @Override
    public void fun2() {
        System.out.println("A实现了fun2");
    }

    @Override
    public void fun3() {
        System.out.println("A实现了fun3");
    }

    @Override
    public void fun4() {
        System.out.println("A实现了fun4");
    }

    @Override
    public void fun5() {
        System.out.println("A实现了fun5");
    }
}
class C{
    void depend1(Interface1 i){
        i.fun1();
    }
    void depend4(Interface1 i){
        i.fun4();
    }
    void depend5(Interface1 i){
        i.fun5();
    }

}
class D implements Interface1{ //因为是实现所以必须要实现全部方法,用idea的语法提示也不方便 .出他有什么明确的方法

    @Override
    public void fun1() {
        System.out.println("D实现了fun1");
    }

    @Override
    public void fun2() {
        System.out.println("D实现了fun2");
    }

    @Override
    public void fun3() {
        System.out.println("D实现了fun3");
    }

    @Override
    public void fun4() {
        System.out.println("D实现了fun4");
    }

    @Override
    public void fun5() {
        System.out.println("D实现了fun5");
    }
}

//改进!!!

   public class singleResponsiblity {
    public static void main(String[] args) {
        A a = new A();
        a.depend1(new B());
        a.depend2(new B());
        a.depend3(new B());

        C c = new C();
        c.depend1(new D());
        c.depend4(new D());
        c.depend5(new D());





    }
}
interface Interface1{
    void fun1();

}
interface Interface2{
    void fun2();
    void fun3();

}
interface Interface3{
    void fun4();
    void fun5();
}
class B implements Interface1,Interface2{ //代码可读性更好了
    @Override
    public void fun1() {
        System.out.println("B实现了fun1");
    }

    @Override
    public void fun2() {
        System.out.println("B实现了fun2");
    }

    @Override
    public void fun3() {
        System.out.println("B实现了fun3");
    }
}
class D implements Interface1,Interface3{

    @Override
    public void fun1() {
        System.out.println("D实现了fun1");
    }

    @Override
    public void fun4() {
        System.out.println("D实现了fun4");
    }

    @Override
    public void fun5() {
        System.out.println("D实现了fun5");
    }
}
class A {
    void depend1(Interface1 i){
        i.fun1();
    }
    void depend2(Interface2 i){
        i.fun2();
    }
    void depend3(Interface2 i){
        i.fun3();
    }

}

class C{
    void depend1(Interface1 i){
        i.fun1();
    }
    void depend4(Interface3 i){
        i.fun4();
    }
    void depend5(Interface3 i){
        i.fun5();
    }

}

6.依赖倒转原则 dependence inversion principle

1.高层模块不依赖低层模块
2.抽象不依赖于细节,细节依赖抽象
3.中心思想是 面向接口编程(在设计上非常有用)
4.抽象的相对稳定,倒转指的是 我不直接写普通类了,而是先写接口后写类

代码: //接收消息的代码 ,

//改进,调用的代码不用改变只需要增加一个接口,然后类实现他

//依赖传递!!!的三种方式(类必须有接口,类型是接口赋值,我们程序就有个缓存层)
1.通过接口传递实现依赖 //把依赖的作为参数传给实现的方法,可以在依赖的方法上加功能

 public class Inversion2 {
    public static void main(String[] args) {
        //这里不用改代码
        Person2 person = new Person2();
        person.send(new Email2());
//        person.open(new WeiXin2());

    }
}

interface ReveiveMessage2{
    void receive();
}
//接收到消息后转发给其他人
interface ReveiveAndSend{ //为了把依赖(也是接口的思想)
    void send(ReveiveMessage2 depend);

}

class Email2 implements ReveiveMessage2{ //多个实现
   //public default private protected
    @Override
    public void receive() {
        System.out.println("接收邮箱消息");
    }
}

//class WeiXin2 implements ReveiveMessage2{//多个实现
//    @Override
//    public void receive() {
//        System.out.println("接收微信信息");
//    }
//}


class Person2 implements ReveiveAndSend{


    @Override
    public void send(ReveiveMessage2 depend) { //使用
        depend.receive();
        System.out.println("接收的信息转发出去");
    }
   
}
  1. (开发使用)1的改进 ,//使用依赖的类(实现接口,构造方法调用依赖初始化,实现的方法不用参数专门来实现功能)和依赖
public class Inversion3 {
    public static void main(String[] args) {

        Person3 person = new Person3(new Email3());
        person.send();
//        person.open(new WeiXin2());

    }
}

interface ReveiveMessage3{
    void receive();
}

//接收到消息后转发给其他人
interface ReveiveAndSend3{ //为了把依赖(也是接口的思想)
    void send();

}

class Email3 implements ReveiveMessage3{ //多个实现
   //public default private protected
    @Override
    public void receive() {
        System.out.println("接收邮箱消息");
    }
}

//class WeiXin2 implements ReveiveMessage2{//多个实现
//    @Override
//    public void receive() {
//        System.out.println("接收微信信息");
//    }
//}


class Person3 implements ReveiveAndSend3{
    ReveiveMessage3 re;
    Person3(ReveiveMessage3 re){
        this.re=re;
    }
    @Override
    public void send() { //使用
        re.receive();
        System.out.println("接收的信息转发出去");
    }


}
   3. (开发使用)和2差不多,通过set方法给接口赋值(可能没有使用set导致空指针)
       public class Inversion4 {
    public static void main(String[] args) {

        Person4 person = new Person4();
        person.setRe(new Email4());
        person.send();
//        person.open(new WeiXin2());

    }
}

interface ReveiveMessage4{
    void receive();
}

//接收到消息后转发给其他人
interface ReveiveAndSend4{ //为了把依赖(也是接口的思想)
    void send();

}

class Email4 implements ReveiveMessage4{ //多个实现
   //public default private protected
    @Override
    public void receive() {
        System.out.println("接收邮箱消息");
    }
}

//class WeiXin2 implements ReveiveMessage2{//多个实现
//    @Override
//    public void receive() {
//        System.out.println("接收微信信息");
//    }
//}


class Person4 implements ReveiveAndSend4{
    ReveiveMessage4 re;
    @Override
    public void send() { //使用
        re.receive();
        System.out.println("接收的信息转发出去");
    }

    public void setRe(ReveiveMessage4 re) {
        this.re = re;
    }
}

7.里氏替换原则(解决子类重写父类方法,导致子类方法调用错误(无意识的,我以为调用了继承的父类的方法),造成的巨大影响,破坏继承体系)

  1. 介绍 :是Liskov 麻省理工大学的女士1988年提出的
  2. 子类不要重写父类的方法(所有用基类的地方必须透明的使用其子类对象[子类重写所有父类的方法,相当于父类没有使用])
    耦合性(关联,修改了另外一个影响另外一个)
  3. 适当情况下,共同继承一个基类,然后使用
    1继承类图 generalization
    聚合 如4聚合UML类图
    组合(把A类成为B的私有成员,然后创建B的方法调用A) composite 如2组合UML类图

请添加图片描述请添加图片描述
请添加图片描述

-------改进前-----

public class LiskReplace {
    public static void main(String[] args) {
        B b = new B();
        System.out.println(b.add(1, 2));
    }

}


class A{ //如果我们还看到父类这个方法,就会和子类混淆实现的具体步骤
    //两数相加
    public int add(int a,int b){
        return a+b;
    }


}
class B extends A{
    //两数相加,我无意识的增加了这个方法导致父类方法被覆盖
    public int add(int a,int b){

        return a+b-1;
    }
    public int sub(int a,int b){
        return a-b;
    }
}

-----改进后-----

public class LiskReplace {
    public static void main(String[] args) {
        A a = new A();
        System.out.println(a.add(1, 2));
    }

}
class Base{ //建立一个基类共同继承,其实这里是为了设计,说明A和B和同一类功能的类型,可读性提高


}

class A extends Base{ //因为AB是单独的所以不会混淆方法覆盖
    //两数相加
    public int add(int a,int b){
        return a+b;
    }


}
class B  extends Base{  //  去掉继承 extends A,变成聚合 组合 依赖的方式,
    public int add(int a,int b){

        return a+b-1;
    }
    public int sub(int a,int b){
        return a-b;
    }
}

8.开闭原则 Open Closed Principle(ocp) (前面的原则都是为了这个原则,是基础和最重要的原则)

  1. 类,模块,函数 扩展开放(开发者) 修改关闭(使用这个类函数的使用者) 抽象构建框架,实现拓展细节
  2. 通过扩展实现变化(增加代码),不是通过修改代码实现变化(已有的代码修改,可能会出bug) //依赖倒置的那个案例也是满足ocp原则
  3. 改进方法,增加一个抽象类或接口,使用方调用这个抽象类

----改进前的代码—

   public class Ocp {
    public static void main(String[] args) {
        ShapeEditor shapeEditor = new ShapeEditor(new Circle());
        ShapeEditor tri = new ShapeEditor(new Triangle());
         new ShapeEditor(new RectAngle());  //(3)使用者修改代码,本来就要修改
    }
}

class ShapeEditor{
    ShapeEditor(Shape shape){
        if (shape.type==1){
            Circle circle = new Circle();
            circle.draw();
        }else if(shape.type==2){
            Triangle triangle = new Triangle();
            triangle.draw();
        }else if(shape.type==3){ //(2)增加一个判断,修改类,增加了不需要的判断, 这里不应该去修改 ,要满足扩展开放,修改关闭
            RectAngle rectAngle = new RectAngle();
            rectAngle.draw();

        }
    }

}
class Shape{
    int type;
    Shape(){

    }
    Shape(int type){
        this.type=type;
    }

}
class Circle extends Shape{
    Circle(){
        super.type=1;
    }
    void draw(){
        System.out.println("绘制圆形");
    }
}
class Triangle extends Shape{

    Triangle(){
        super.type=2;
    }
    void draw(){
        System.out.println("绘制三角形");
    }

}
//如果我增加一个长方形,需要增加的代码如(1)(2)(3)
class RectAngle extends Shape{ //(1) 最基础的是增加这个类和修改type为3

    RectAngle(){
        super.type=3;
    }
    void draw(){
        System.out.println("绘制长角形");
    }


}

----改进后的代码,暴力节省判断的代码,只需要改变超类为抽象类()—

  public class Ocp {
    public static void main(String[] args) {
        ShapeEditor shapeEditor = new ShapeEditor(new Circle());
        ShapeEditor tri = new ShapeEditor(new Triangle());
         new ShapeEditor(new RectAngle());  //(3)使用者修改代码,本来就要修改
    }
}

class ShapeEditor{
    ShapeEditor(Shape shape){
            shape.draw();  //(1)为什么会导致这样的结果呢?,因为抽象类和接口一样会调用他实现的对应的类
    }

}

abstract class Shape{
     int type;
    abstract void draw();  //(2)


}

class Circle extends Shape{
    Circle(){
        super.type=1;
    }
    void draw(){
        System.out.println("绘制圆形");
    }
}

class Triangle extends Shape {

    Triangle(){
        super.type=2;
    }
    void draw(){
        System.out.println("绘制三角形");
    }

}


class RectAngle extends Shape{

    RectAngle(){
        super.type=3;
    }
    void draw(){
        System.out.println("绘制长角形");
    }


}

//使用场景,他是为了使用者调用的时候,不改变原来的代码,只做增加类,不在类方法里面修改
//多用抽象和继承配合一起使用

9.迪米特法则demeter (最少知道原则),一个类对外只提供public方法不泄漏任何信息,

1.类方法内(局部变量)是非直接朋友,外面或者是返回值和方法传入的参数就是直接朋友
2.可以降低类和类的耦合度,类不可能完全没有耦合
3.改进的方案 把其他类有违反迪米特法则的代码,写到我们要使用的类的方法

public class demeter {

    public static void main(String[] args) {
        Manager manager = new Manager();
    }
}
class Manager{
    Manager(){
        Employee employee=new Employee();  //违反迪米特法则
        employee.work();

    }

}
class Employee{
    void work(){
        System.out.println("开始工作");

    }

}

//使用迪米特法则改进

public class demeter {

    public static void main(String[] args) {
        Manager manager = new Manager();
        manager.start(new Employee());

    }
}

class Manager{
    Employee employee=new Employee();//没有违反,依赖的组合关系
    Manager(){
        employee.work();
//        Employee employee=new Employee(); //违反
//        employee.work();

    }
    void start(Employee employee){//没有违反
        employee.work();
//        Employee employee=new Employee(); //违反
//        employee.work();
    }

}

class Employee{
    void work(){
        System.out.println("开始工作");

    }

}

10.合成复用原则 尽量使用合成/聚合(通过B的set方法设置A依赖)的方式,而不使用继承
如图5合成复用法则解决方案
请添加图片描述

11.设计原则核心思想

  1. 找出可能变化的地方,不要和不需要变化的地方混合在一起

  2. 针对接口编程,而不是针对实现(不是 implements关键字,是方法实现的具体过程)编程

  3. 松耦合
    Dependency 依赖 (另外一个类 调用方法传入参数)
    Association 关联(会使用到)
    Generalization泛化(继承)
    Realization(实现)
    Aggregation聚合(使用set方法设置另外一个类)<(耦合度) Composite组合直接在构造方法初始化另外一个类

    Note 对UML注释
    //工具Eclipse UML插件 AmasterUML.jar导入
    //idea自带 file->setting–>tools—>diagrams—>java class diagrams—>钩上fields constructor和methods—>apply—>要画的文件夹右键
    diagrams---->show diagram—> java class diagrams 自动生成完工…

12.UML类图(最重要的是类图,用例图次要)用于程序员之间交流
如图 6.类图的分类

请添加图片描述

  1. 在eclipse .java拖拽直接变成类图,在同一文件夹下写类图逻辑会比较清晰
  2. 依赖关系(如果没有这个类会编译不通过) (总之就是用到,不管是直接或者间接)(形容比较广泛的关系)
    1.类中使用到对方
    2.类的成员属性
    3.方法的返回值
    4.方法接收的参数类型
    5.方法内使用到
    //最下面一条线是依赖关系请添加图片描述
  3. 泛化关系 依赖的特例 就是继承关系
    请添加图片描述
  1. 实现关系 依赖的特例 类—>实现–>接口
    请添加图片描述
  1. 关联关系 依赖的特例 一对一,一对多关系
    如 一个Person对应一个IDCard类 Person-1—1>IDCard 1----n>List集合 Map
    public class Person{ private IDCard card;}

  2. 聚合关系aggregation(重要) 关联关系的特例 整体和部分可以分开 鼠标和键盘可以从电脑分离
    图 7.聚合关系

    一群人聚在一起->乌合之众请添加图片描述

  1. 组合关系composition 整体和部分不可分割(只要Computer创建 mouse和monitor在成员new出来了)
    图 8组合关系
    你的器官是组合,(各有优点)
    请添加图片描述
  1. 组合和聚合一起使用 .级联删除IDCard也是组合关系
    图9聚合关系
    请添加图片描述

13.UML统一建模语言 idea安装PlantUML插件

@startuml

title 类图
scale 1.5
/'组合关系(composition)'/
class Human {
    - Head mHead;
    - Heart mHeart;
    ..
    - CreditCard mCard;
    --
    + void travel(Vehicle vehicle);
}

Human *-up- Head : 组合 >
Human *-up- Heart : 组合 >

/'聚合关系(aggregation)'/
Human o-left- CreditCard : owns >

/'依赖关系(dependency)'/
Human .down.> Vehicle : dependent

/'关联关系(association'/
Human -down-> Company : associate

/'继承关系(extention)'/
interface IProgram {
    + void program();
}
class Programmer {
    + void program();
}
Programmer -left-|> Human : extend
Programmer .up.|> IProgram : implement
@enduml

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

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

相关文章

TC8:SOMEIP_ETS_004-005

SOMEIP_ETS_004: Burst_Test 目的 检查DUT是否可以在短时间内处理突发请求并返回所有请求的响应 测试步骤 Tester:新建有效SOME/IP消息Tester:使用method echoUINT8发送突发SOME/IP Request消息DUT:返回每个请求消息的响应消息期望结果 3、DUT:返回每个请求消息的响应消息…

学redis这一篇就够了

目录 1.下载安装启动 1.1 临时启动服务 2.2 默认服务安装 2.常用五大基本数据类型 2.1 key操作 2.2 字符串&#xff08;String&#xff09; 2.3 列表&#xff08;List&#xff09; 2.4 Set&#xff08;集合&#xff09; 2.5 Hash&#xff08;哈希&#xff09; 2.6 Zs…

分离表示学习:通用图像融合框架

IFSepR: A General Framework for Image Fusion Based on Separate Representation Learning &#xff08;IFSepR&#xff1a;一种基于分离表示学习的通用图像融合框架&#xff09; 提出了一种基于分离表示学习的图像融合框架IFSepR。我们认为&#xff0c;基于先验知识的共模…

Fast Segment Anything Model(FastSAM)

Fast Segment Anything Model&#xff08;FastSAM&#xff09; Fast Segment Anything Model&#xff08;FastSAM&#xff09;是一个仅使用SAM作者发布的SA-1B数据集的2%进行训练的CNN Segment Anything模型。FastSAM在50倍的运行速度下实现了与SAM方法相当的性能。 SAM代码&a…

pubg 依赖安装

一、安装python 1、进入官网 https://www.python.org/ 2、勾选Add python.exe to PTHA 3、自定义下载 测试和文档不需要勾选&#xff0c;然后next 4、自定义安装路径 点击install安装 安装成功&#xff0c;点击close。 5、测试 windr键&#xff0c;输入cmd 输入python回…

基于SSM的餐厅点餐系统设计与实现(Java+MySQL)

目 录 第一章 绪论 1 1.1系统研究背景和意义 1 1.2研究现状 1 1.3论文结构 2 第二章 相关技术说明 3 2.1 JSP(Java Server Page)简介 3 2.2 Spring框架简介 4 2.3 Spring MVC框架简介 5 2.4 MyBatis 框架简介 5 2.4 MySql数据库简介 5 2.6 Tomcat简介 6 2.7 jQuery简介 7 2.8系…

计算机毕业论文内容参考|基于大数据的信息物理融合系统的分析与设计方法

文章目录 导文摘要前言绪论课题背景国内外现状与趋势:课题内容:相关技术与方法介绍:系统架构设计:数据采集与处理:数据存储与管理:数据分析与挖掘:系统优化与调试:应用场景:挑战与机遇:研究方向:系统分析:系统设计:系统实现:系统测试:总结与展望:

SpringBoot原理(1)--@SpringBootApplication注解使用和原理/SpringBoot的自动配置原理详解

文章目录 前言主启动类的配置SpringBootConfiguration注解验证启动类是否被注入到spring容器中 ComponentScan 注解ComponentScan 注解解析与路径扫描 EnableAutoConfiguration注解 问题解答1.AutoConfigurationPackage和ComponentScan的作用是否冲突起因回答 2.为什么能实现自…

WIN10上必不可少的5款优质软件

噔噔噔噔&#xff0c;作为一个黑科技软件爱好者&#xff0c;电脑里肯定是不会缺少这方面的东西&#xff0c;今天的5款优质软件闪亮登场了。 颜色拾取器——ColorPix ​ ColorPix是一个颜色拾取器工具&#xff0c;可以让你快速地获取屏幕上任意位置的颜色值&#xff0c;如RGB、…

ivshmem-plain设备原理分析

文章目录 前言基本原理共享内存协议规范 具体实现设备模型数据结构设备初始化 测试验证方案流程Libvirt配置Qemu配置测试步骤 前言 ivshmem-plain设备是Qemu提供的一种特殊设备&#xff0c;通过这个设备&#xff0c;可以实现虚机内存和主机上其它进程共存共享&#xff0c;应用…

618美妆个护28个榜单:欧莱雅稳住冠军?珀莱雅大爆发第二?

存量时代的购物造节大竞争&#xff0c;作为消费复苏后的首场大促&#xff0c;今年的618堪称史上最“卷”&#xff0c;也承载着消费振兴、经济复苏等希望。 不过&#xff0c;今年所有平台都未公布具体GMV&#xff0c;某种程度说明大促造节的时代俨然已成过去式了。 5月18日&am…

怎么去除视频里的背景音乐?其实非常简单!

如何去除视频背景音乐&#xff1f;在视频处理中&#xff0c;有时我们需要从视频中提取声音并进行处理&#xff0c;而不仅仅是简单地去除整个背景音乐。我们可能需要有选择性地去除人声或背景音乐。这个处理过程对于选用合适的工具至关重要。在本文中&#xff0c;我将分享两种可…

【⑦MySQL】· 一文了解四大子查询

前言 ✨欢迎来到小K的MySQL专栏&#xff0c;本节将为大家带来MySQL标量/单行子查询、列子/表子查询的讲解✨ 目录 前言一、子查询概念二、标量/单行子查询、列子/表子查询三、总结 一、子查询概念 子查询指一个查询语句嵌套在另一个查询语句内部的查询&#xff0c;这个特性从My…

抖音林客生活服务商机构

抖音林客生活服务商机构是在抖音平台上提供各种生活服务的机构或组织。这些机构通常会提供家政服务、保洁服务、美容美发服务等&#xff0c;也有一些提供餐饮、旅游、电商等服务。用户可以通过抖音搜索、浏览和下单&#xff0c;享受到优质的服务体验。 这些服务商机构在抖音…

数值组件滚动趋势图联动需求拆解

技术栈&#xff1a;使用vue3的composition API tsx 进行开发 一、需求描述 直接看UI图吧。 简单描述一下&#xff1a; 数值卡片&#xff1a; 上方部分是一个数值卡片列表&#xff0c;每个卡片维护不同的集中状态&#xff0c;选中态&#xff0c;hover态。 细节&#xff1…

【测试学习】Junit5的简单使用

目录 &#x1f31f;需要知道&#xff1a; &#x1f31f;Junit学习 &#x1f308;1、常用的注解 &#x1f308;2、测试用例的执行顺序 &#x1f308;3、参数化 &#x1f308;4、断言 &#x1f308;5、测试套件 &#x1f31f;需要知道&#xff1a; 问题1&#xff1a;Selen…

ATA-4315高压功率放大器在铁路钢轨损伤检测中的应用

随着高速铁路的建设和不断发展&#xff0c;确保铁路线路的安全和稳定运行变得越来越重要。钢轨作为铁路的重要组成部分&#xff0c;其损坏可能导致严重的事故和交通堵塞。因此&#xff0c;对钢轨损伤进行及时、准确的检测至关重要。高压功率放大器作为一种精密的测试仪器&#…

SQL 优化(一):慎用 SQL 函数

假如有下面这样一张用户表 CREATE TABLE t_user (user_id int(11) NOT NULL AUTO_INCREMENT,username varchar(50) DEFAULT NULL,sex tinyint(1) DEFAULT NULL,mobile varchar(45) DEFAULT NULL,create_time datetime DEFAULT CURRENT_TIMESTAMP,PRIMARY KEY (user_id),KEY id…

Linux系统下查看网卡配置和网络流量监控指令:ifconfig、ethtool

文章目录 1 查看/设置网卡&#xff08;ifconfig&#xff09;2 查看网卡配置、属性&#xff08;ip、ethtool&#xff09;3 查看网络接口配置情况&#xff1a;4 查看网络接口属性信息5 测试网路通信&#xff08;ping&#xff09; 6 查看具体网卡配置文件 1 查看/设置网卡&#xf…

Unity | HDRP高清渲染管线学习笔记:Lightmapping(光照烘焙)与Lightmap(光照贴图)

目录 相关概念 1.渐进式光照贴图烘焙 1.1 渐进式光照贴图烘焙对模型的要求 1.2 渐进式光照贴图烘焙对硬件的要求 1.3 渐进式光照贴图烘焙支持的Unity渲染管线 1.4 进行渐进式光照贴图烘焙结果 1.5 渐进式光照贴图烘焙的CPU版本和GPU版本 1.6 Lighting窗口Lightmapping …