【设计模式学习】单例模式和工厂模式

 ꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱
ʕ̯•͡˔•̯᷅ʔ大家好,我是xiaoxie.希望你看完之后,有不足之处请多多谅解,让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客
本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN 如需转载还请通知˶⍤⃝˶​
个人主页:xiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客

系列专栏:xiaoxie的JAVAEE学习系列专栏——CSDN博客●'ᴗ'σσணღ
我的目标:"团团等我💪( ◡̀_◡́ ҂)" 

( ⸝⸝⸝›ᴥ‹⸝⸝⸝ )欢迎各位→点赞👍 + 收藏⭐️ + 留言📝​+关注(互三必回)! 

目录

 一.设计模式

1.什么是设计模式

2.设计模式的重要性

 二.单例模式

1.什么是单例模式

2.饿汉模式实现单例模式

1.Java代码

2.代码解释

3.是否为线程安全

3.懒汉模式实现单例模式

1.Java代码实现

2.代码解释

3.是否为线程安全

4.饿汉模式和懒汉模式的区别以及各自的优缺点和应用场景

1.饿汉模式和懒汉模式的区别

2.饿汉模式和懒汉模式的优缺点

3. 饿汉模式和懒汉模式的应用场景

三.工厂模式

1.什么是工厂模式

1.工厂模式的分类

2.工厂模式的应用场景

3.工厂模式的优点

4.工厂模式的缺点

5.总结

2.Java代码实现

1.简单工厂模式

2.工厂方法模式 

3.抽象工厂模式 


 

 一.设计模式

1.什么是设计模式

设计模式是在软件设计中反复出现的问题和解决方案的经验总结。它是对软件设计中常见问题的通用解决方案,可以帮助设计人员更高效地解决问题,并提高软件设计的质量和可维护性。设计模式提供了一种在特定情况下的解决方案,它们可以被反复使用,并且是经过验证的最佳实践。设计模式可以帮助开发人员更好地理解软件设计中的问题,并为他们提供一种标准的方法来解决这些问题。通俗易懂的一点来说:就是提高你的下限

设计模式就像是建筑行业的预制构件或者烹饪领域的配方,它为程序员在面对特定设计挑战时提供了一个经过验证、成熟且可复用的方案蓝图(都是大佬们写的绝对牛逼好用)。例如,在软件开发中,如果你需要创建多个相似对象,但又希望避免大量重复代码,你可以参考“工厂模式”来设计一个统一的创建接口;当你想要改变对象的行为,而又不修改对象本身时,可以运用“策略模式”动态地替换对象的算法。

所以,掌握和灵活运用设计模式,不仅能够提升编程效率,使得代码结构更加清晰合理,增强代码的可读性和可维护性,还能帮助团队成员之间通过共享的设计语言进行更有效的沟通与协作,从而提升整个项目的开发质量和效率。

2.设计模式的重要性

  1. 代码复用性

    • 设计模式为常见问题提供了标准化的解决方法,这些方法已经在实践中得到广泛验证,能够确保代码结构的稳定性。通过应用设计模式,开发人员可以创建模块化、可重用的组件,避免重复发明轮子,从而提高了代码的复用性。
  2. 代码可读性和可维护性

    • 使用设计模式能够使代码结构更加清晰,遵循一定的命名约定和组织原则,使得其他开发者更容易理解代码的工作机制,进而降低了维护成本。良好的设计模式应用还能减少由于代码复杂度引起的潜在错误。
  3. 系统灵活性与扩展性

    • 设计模式强调“开闭原则”,即对扩展开放,对修改关闭。这意味着设计模式鼓励构建低耦合、高内聚的系统,这样在不改动现有代码的基础上就能轻松添加新功能或适应变化的需求。
  4. 团队协作与沟通

    • 在团队开发环境中,设计模式充当了一种通用的设计语言,让开发人员能够快速准确地传达复杂的设计思想和实现策略,提高了团队成员间的沟通效率和协作水平。
  5. 软件质量提升

    • 应用设计模式通常意味着遵循最佳实践,这有助于提高软件的稳定性和健壮性,从而间接提升了软件产品的整体质量。
  6. 重构和优化

    • 设计模式提供了解决特定问题的标准途径,当需要对现有代码进行重构以改善性能或简化结构时,设计模式可作为指导方针,帮助开发人员安全高效地进行改造工作。

综上所述,设计模式不仅是提升个人编程技艺的有效工具,更是推动整个软件开发行业进步的关键要素之一。通过学习和掌握设计模式,开发人员能够构建出更加灵活、可维护、可靠且高效的软件系统。最重要的就是一句话,校招什么的常考,日常开发也用的很多

 二.单例模式

1.什么是单例模式

单例模式是一种常用的软件设计模式,它确保一个类只有一个实例(也就是在这个进程中,该类只能new出来一个对象),并提供一个全局访问点。这种模式在需要全局共享一个对象的场景中非常有用,例如:

  1. 资源管理

    • 数据库连接池:在整个应用程序运行期间,数据库连接通常是有限的宝贵资源,单例模式可以用来创建一个全局的数据库连接池,确保所有的数据库操作都共享这些连接,而不是频繁地创建和销毁连接。
    • 缓存服务:如Redis或Memcached客户端,通常作为单例实现,以便各个模块都可以共享同一份缓存连接,同时方便进行集中管理和配置。
  2. 日志服务

    • 日志系统通常会采用单例模式,确保整个应用程序只生成一个日志输出器实例,以统一格式和策略处理日志记录。
  3. 工具类

    • RestTemplateHttpClient等HTTP客户端工具类,在Spring框架中常常被设计成单例,避免每次请求都创建新的客户端实例,提高性能并便于集中配置。
    • 在前端开发中,某些全局配置或工具类也需要保证全局唯一,例如事件总线、通用函数库等。
  4. 配置管理

    • 应用程序配置读取类,可能需要在整个系统中共享一套配置,单例模式可以确保配置只加载一次并被全局复用。
  5. 多线程环境下的协调与控制

    • 单例模式可以用于充当线程间共享的协调者角色,比如线程池管理器、任务调度器等。
  6. 应用程序入口

    • 很多应用框架中的主入口类或者服务容器,为了保证整个应用生命周期内只有一个实例存在,会采用单例模式设计。
  7. 其他服务类

    • 文件系统访问类、消息队列客户端、图形用户界面组件工厂等场合,也可能用到单例模式来确保系统内只存在一个共享实例。

总之,任何需要在整个程序范围内保持唯一实例并且允许全局访问的对象,都是单例模式的适用场景 .

2.饿汉模式实现单例模式

1.Java代码

class Singleton {private static Singleton instance = new Singleton();public static Singleton getInstance() {return instance;}private Singleton() {}
}

2.代码解释

1private static Singleton instance = new Singleton(); 这里设为静态的,就意味着instance  为类属性,只有一个,并且和整个类的生命周期相同,在类被创建的同时被创建,被销毁时同时被销毁,初始化这个类自然也就只创建一次.并且因为只要这个类被创建,就实例化了一个对象,所以也被称为饿汉模式(饿了就先吃(提前实例化)”的特点).

2.public static Singleton getInstance() 获取单例对象的方法,它对外提供了一个全局访问点,任何时候调用此方法都将得到同一个Singleton实例. 

3. private Singleton() 可以看到该构造方法是被private所修饰的,也就意味着,其他类不能调用Singleton 类的构造方法,外部就不能通过new关键字实例化该类的对象,保证了单例的特性。当然如果你使用反射的话还是可以访问该方法的,

3.是否为线程安全

因为该类在被JVM创建后,由于instan是静态的也就是类属性,所以,会和该类同时被JVM创建,所以并不存在同步的问题,类加载的过程是由JVM保证线程安全的以在多线程环境下,即使多个线程同时首次访问Singleton getInstance() 方法,也只会有一个线程触发Singleton类的加载,因此它们都会得到相同的Singleton类的实例

3.懒汉模式实现单例模式

1.Java代码实现

class SingletonLazy {private static volatile SingletonLazy instance = null;public static SingletonLazy getInstance() {if(instance == null) {synchronized (SingletonLazy.class) {if(instance == null) {instance = new SingletonLazy();}}}return instance;}private SingletonLazy() {}
}

2.代码解释

1. private static volatile SingletonLazy instance = null;和饿汉模式不一样的是,一开始先不实例化对象,等到调用的getInstance()时候在实例化对象,这样就提高了效率,因为在实际开发中,实例化的对象中可能会包含很多数据,如果我们像饿汉模式一样一创建类就马上实例化对象,后续不一定一开始就需要使用这个对象,就浪费系统资源了,同时为了避免内存可见性问题,和指令重排序问题这里使用关键字 volatile 修饰该属性,避免出现线程安全问题.

2. public static SingletonLazy getInstance() 我们可以看到该方法块里的实例SingletonLazy 对象使用了双重检测以及加 synchronized 锁的方法,实例化对象,并且保证只实例化一次,以及避免线程安全问题,这里博主在通过画图来解释一下这里的双重检测以及加 synchronized 锁的方法,如何保证只实例化一次,以及避免线程安全问题.(因为懒汉模式是单例模式的最为常用的模式,这里需要重点掌握)

 总结来说就是:

  1. 第一次检查:在getInstance()方法的开始,首先检查instance是否已经被实例化。如果已经实例化,则直接返回该实例,这样可以避免不必要的同步操作,提高性能。

  2. 同步块:如果instance未被实例化,代码进入同步块。这里的同步操作是关键,它确保了在多线程环境下,只有一个线程能够执行同步块内的代码。

  3. 第二次检查:在同步块内部,进行第二次检查以确认instance是否仍然为null。这是必要的,因为可能在第一个线程检查instancenull并进入同步块的同时,其他线程也检查到instancenull。如果没有第二次检查,当第一个线程创建了实例并释放锁之后,其他线程可能会再次进入同步块并错误地创建新的实例。

  4. 实例化:如果第二次检查确认instance仍然为null,那么在同步块中创建单例对象,并将其实例赋值给instance

  5. 释放锁:完成实例化后,当前线程退出同步块,并释放锁,允许其他线程访getInstance()方法。

 3.private SingletonLazy()  和饿汉模式一样可以看到该构造方法是被private所修饰的,也就意味着,其他类不能调用Singleton 类的构造方法,外部就不能通过new关键字实例化该类的对象,保证了单例的特性。当然如果你使用反射的话还是可以访问该方法的.

3.是否为线程安全

由于懒汉模式为了延迟实例化对象,所以在创建类的时候没有一开始就实例化对象而是在调用getInstance()方法后再实例化对象,虽然节约了系统资源,但这样也就意味着在多线程的环境下,会发生线程安全问题,在上文博主解释了使用双重检测和synchronized上锁的机制保证了线程安全问题的一方面,为什么这里要说一方面呢,因为这里还有一个隐藏的线程安全问题即指令重排序问题,这个时候Instance就需要被关键字 volatile 所修饰,使得确保变量的读写操作对所有线程都是可见的,并且防止指令重排.这里博主再通用画图的形式讲解一下指令重排序问题

1.先解释一下什么是指令重排序

在编译器优化和处理器执行过程中,为了提高性能,可能会对指令序列进行重排序。这种重排序在单线程环境下通常不会引起问题,因为每个线程看到的指令执行顺序是一致的。但在多线程环境下,如果重排序导致内存操作的顺序发生变化,就可能出现数据不一致的问题。

使用小明去菜市场买菜来模拟一下cpu执行指令的过程.由于cpu执行指令是一条一条的执行的所以

可以发现这样买的效率就十分低效,所以呢大佬们就设计的编译器或者JVM就十分智能,可以根据实际情况生成指令的排序顺序,就会和原本写的代码的指令排序顺序有所差别,就像上图的例子,妈妈给了小明一个购物清单(代码),小明(编译器或者是JVM)就根据实际情况即( 鱼-> 猪肉 - > 卷心菜 - > 虾 -> 牛肉)对购物清单(代码)的顺序做出了修改,这样就大大提高了代码的执行效率,这种重排序在单线程环境下通常不会引起问题,因为每个线程看到的指令执行顺序是一致的。但在多线程环境下,如果重排序导致内存操作的顺序发生变化,就可能出现数据不一致的问题。

以上就是指令重排序的解释,现在再解释一下饿汉模式出现指令重排序问题的解释:

总结来说就是:

1.线程1获取到锁,判断 instance 为空的,就执行 instance = new SingletonLazy(); 这个操作,

2.这行代码被执行时,它实际上包含了三个步骤:

  1. 分配对象所需的内存空间。
  2. 调用构造函数初始化对象。
  3. instance引用指向分配的内存地址

3. 由于编译器或CPU可能对这三个步骤进行重排序:

      1.分配对象所需的内存空间。

      2.将instance引用指向分配的内存地址。

      3.调用构造函数初始化对象

4.先执行了将 instance引用指向分配的内存地址,但由于构造函数还未执行完毕,此时的 instance指向的是未初始化完成的对象.

5.此时线程2执行,读取到 instance为非空由于双重检测的缘故,就直接返回instance 

6.这里线程2返回的instance 对象并没有被初始化,这个时候就产生了BUG

7.所以我们就要一开始使用关键字 volatile 修饰 instance 能确保对instance的写操作(即实例化SingletonLazy对象)对所有线程立即可见,并且不会发生指令重排序,从而保证当其他线程读取到instance非空时,对应的SingletonLazy实例已经完全初始化完成.

8.上述说的场景虽然发生的概率很小,但是为了严谨性我们还是需要加入关键字 volatile 和 双重检测以及锁一起配合确保防止出现线程安全问题.

4.饿汉模式和懒汉模式的区别以及各自的优缺点和应用场景

1.饿汉模式和懒汉模式的区别

1.饿汉模式:饿汉模式在类加载时就完成了单例对象的初始化,也就是说,当类被载入到JVM时,单例就已经创建好了通常通过静态初始化块或直接在静态变量定义时初始化单例对象

2.懒汉模式是在第一次调用getInstance()方法时才进行实例化,即所谓的“懒加载”。需要处理线程安全问题,常见的做法有双重检查锁定。

2.饿汉模式和懒汉模式的优缺点

1.饿汉模式优点

  • 简单易懂,实现简单。
  • 线程安全,因为类加载过程由JVM保证是线程安全的。
  • 由于实例一开始就创建好了,所以在多线程环境下无须担心线程安全问题。

 2.饿汉模式缺点

  • 单例对象在程序启动时就创建,如果该对象比较大,或者初始化过程比较耗时,那么可能会造成内存资源的浪费,特别是如果这个单例对象在整个程序运行期间都不一定会被用到的情况下。

 3.懒汉模式优点

  延迟初始化,节约内存资源,尤其适合那些大型对象或者需要较多初始化操作的单例

  4.懒汉模式缺点

  • 普通懒汉模式实现不具备线程安全,需要额外的同步手段,如上述的双重检查锁定。
  • 双重检查锁定增加了代码复杂度,并且在某些Java版本(旧版)或特定条件下可能受指令重排序的影响,需要使用volatile关键字确保线程安全。

3. 饿汉模式和懒汉模式的应用场景

1.饿汉模式

  • 对象创建成本低,生命周期长,且预计会被频繁使用的场景。
  • 不依赖于其他外部资源初始化的场景。

2.懒汉模式

  • 对象创建成本高,生命周期短,或者不确定是否会被使用的场景。
  • 需要在真正需要时才初始化单例对象的场景。

 综上,选择饿汉模式还是懒汉模式取决于具体的使用场景,如果优先考虑内存优化和延迟初始化,可以选择懒汉模式;如果希望实现简单,对初始化时间不太敏感,或者确定单例对象必然会被使用,那么饿汉模式是一个更好的选择。

三.工厂模式

1.什么是工厂模式

工厂模式(Factory Pattern)是一种常用的创建型设计模式,它的目的是用来处理对象的创建机制。在软件开发中,对象的创建通常不是简单的实例化操作,还需要考虑诸如对象的重用、对象创建的封装、减少客户端与具体类的依赖等问题。工厂模式通过提供一个创建对象的接口,让子类决定实例化哪一个类,从而把对象的创建和使用进行分离。

1.工厂模式的分类

工厂模式主要分为以下三种类型:

  1. 简单工厂模式(Simple Factory)

    • 也称为静态工厂方法,通过一个单一的工厂类来创建不同类型的对象。
    • 工厂类通常包含多个静态方法,每个方法对应一种产品类的实例化。
    • 简单工厂模式的缺点是当产品类别增多时,工厂类的方法也会相应增多,导致难以维护。
  2. 工厂方法模式(Factory Method)

    • 定义了一个创建对象的接口,但让实现这个接口的类来决定实例化哪一个类。
    • 每个产品类都有一个对应的工厂类,负责创建该产品类的实例。
    • 工厂方法模式把产品的创建过程封装在具体的工厂类中,较好地解决了简单工厂模式的缺点。
  3. 抽象工厂模式(Abstract Factory)

    • 提供了一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
    • 通常用于系统有多个产品族,且需要统一管理这些产品族的情况。
    • 抽象工厂模式允许客户端使用一个统一的接口来创建不同类型的产品,而不需要关心具体的实现。

2.工厂模式的应用场景

  • 当一个类不知道它所必须创建的具体类的时候。
  • 当一个类希望其子类来指定创建的对象时。
  • 当类的具体类应该由第三方来决定的时候。
  • 当系统不依赖于具体的类,而是依赖于它们共同的接口时。

3.工厂模式的优点

  • 解耦:将对象的创建和使用分离,客户端不需要知道具体的实现类,只需要知道它们的超类或接口。
  • 可扩展性:当需要添加新的产品类时,只需添加一个具体的类和对应的工厂类,而无需修改现有的代码。
  • 封装性:封装了产品的创建逻辑,客户端不需要关心产品的具体实现。
  • 代码清晰:使得客户端代码更加清晰,易于理解和维护。

4.工厂模式的缺点

  • 增加复杂性:对于简单工厂来说,可能会有大量的工厂类,增加了系统的复杂性。
  • 难以选择:对于客户端来说,可能需要从多个工厂类中选择一个合适的工厂来创建对象。

5.总结

工厂模式是一种非常实用的设计模式,它通过定义创建对象的接口,让子类决定具体要实例化的类,从而实现了对象创建和使用的分离。这种模式在实际开发中被广泛应用,特别是在需要灵活创建和管理对象的场景中。通过使用工厂模式,可以提高代码的可维护性、可扩展性和灵活性。

2.Java代码实现

1.简单工厂模式

// 简单工厂模式
interface Product {void show();
}class ConcreteProduct1 implements Product {@Overridepublic void show() {System.out.println("这是产品1");}
}class ConcreteProduct2 implements Product {@Overridepublic void show() {System.out.println("这是产品2");}
}class SimpleFactory {public static Product createProduct(String type) {if ("product1".equals(type)) {return new ConcreteProduct1();} else if ("product2".equals(type)) {return new ConcreteProduct2();} else {throw new IllegalArgumentException("无法识别的产品类型");}}
}// 使用
public class Main {public static void main(String[] args) {Product product1 = SimpleFactory.createProduct("product1");product1.show();Product product2 = SimpleFactory.createProduct("product2");product2.show();}
}

2.工厂方法模式 

// 工厂方法模式
interface Product {void show();
}class ConcreteProduct1 implements Product {@Overridepublic void show() {System.out.println("这是工厂1生产的具体产品1");}
}class ConcreteProduct2 implements Product {@Overridepublic void show() {System.out.println("这是工厂2生产的具体产品2");}// ... 更多具体产品类
}abstract class AbstractFactory {abstract Product createProduct();
}class ConcreteFactory1 extends AbstractFactory {@OverrideProduct createProduct() {return new ConcreteProduct1();}
}class ConcreteFactory2 extends AbstractFactory {@OverrideProduct createProduct() {return new ConcreteProduct2();}
}// 使用
public class Main {public static void main(String[] args) {AbstractFactory factory1 = new ConcreteFactory1();Product product1 = factory1.createProduct();product1.show();AbstractFactory factory2 = new ConcreteFactory2();Product product2 = factory2.createProduct();product2.show();}
}

3.抽象工厂模式 

// 抽象工厂模式
interface Color {void fill();
}interface Shape {void draw();
}class Red implements Color {@Overridepublic void fill() {System.out.println("填充红色");}
}class Blue implements Color {@Overridepublic void fill() {System.out.println("填充蓝色");}// ... 更多颜色类
}class Circle implements Shape {private Color color;public Circle(Color color) {this.color = color;}@Overridepublic void draw() {System.out.println("绘制圆形");color.fill();}
}class Square implements Shape {private Color color;public Square(Color color) {this.color = color;}@Overridepublic void draw() {System.out.println("绘制正方形");color.fill();}// ... 更多形状类
}interface AbstractFactory {Color getColor(String colorType);Shape getShape(String shapeType);
}class ShapeFactory implements AbstractFactory {@Overridepublic Color getColor(String colorType) {if ("Red".equalsIgnoreCase(colorType)) {return new Red();} else if ("Blue".equalsIgnoreCase(colorType)) {return new Blue();}return null;}@Overridepublic Shape getShape(String shapeType) {if ("Circle".equalsIgnoreCase(shapeType)) {return new Circle(getColor("Red")); // 这里假设默认使用红色} else if ("Square".equalsIgnoreCase(shapeType)) {return new Square(getColor("Blue")); // 这里假设默认使用蓝色}return null;}
}// 使用
public class Main {public static void main(String[] args) {AbstractFactory factory = new ShapeFactory();Shape circle = factory.getShape("Circle");circle.draw();Shape square = factory.getShape("Square");square.draw();}
}

以上就是关于设计模式的所有内容了,感谢你的阅读

 

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

算法——倍增

. - 力扣(LeetCode) 给你一棵树,树上有 n 个节点,按从 0 到 n-1 编号。树以父节点数组的形式给出,其中 parent[i] 是节点 i 的父节点。树的根节点是编号为 0 的节点。 树节点的第 k 个祖先节点是从该节点到根节点路径…

步骤大全:网站建设3个基本流程详解

一.领取一个免费域名和SSL证书,和CDN 1.打开网站链接:https://www.rainyun.com/z22_ 2.在网站主页上,您会看到一个"登陆/注册"的选项。 3.点击"登陆/注册",然后选择"微信登录"选项。 4.使用您的…

恢复MySQL!是我的条件反射,PXB开源的力量...

📢📢📢📣📣📣 哈喽!大家好,我是【IT邦德】,江湖人称jeames007,10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】!😜&am…

二极管分类及用途

二极管分类及用途 通用开关二极管 特点:电流小,工作频率高 选型依据:正向电流、正向压降、功耗,反向最大电压,反向恢复时间,封装等 类型:BAS316 ; IN4148WS 应用电路: 说明:应用…

并发编程之ThreadLocal使用及原理

ThreadLocal主要是为了解决线程安全性问题的 非线程安全举例 public class ThreadLocalDemo {// 非线程安全的private static final SimpleDateFormat sdf new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");public static Date parse(String strDate) throws ParseExc…

Python-VBA函数之旅-complex函数

目录 1、complex函数: 1-1、Python: 1-2、VBA: 2、相关文章: 个人主页:非风V非雨-CSDN博客 complex函数创建的复数对象在Python中具有广泛的应用场景,特别是在处理涉及数学计算、信号处理、物理模拟、…

数学:人工智能学习之路上的“拦路虎”及其背后的奥秘

在人工智能的浪潮席卷全球的今天,越来越多的人开始涉足这一领域,以期掌握其核心技术,为未来的科技发展贡献力量。然而,在学习的道路上,许多人却遇到了一个不小的挑战——数学。为何数学会成为学习人工智能的“拦路虎”…

Pandas相比Excel的优势是哪些?

熟悉Pandas的同学会知道,Pandas相当于Python中的Excel,都是基于二维表的进行数据处理分析,不同的是,Pandas基于代码操作数据,Excel是图形化的分析工具。 不少人会问Excel比Pandas更简单,为什么还要学习Pan…

【数学】主成分分析(PCA)的详细深度推导过程

本文基于Deep Learning (2017, MIT),推导过程补全了所涉及的知识及书中推导过程中跳跃和省略的部分。 blog 1 概述 现代数据集,如网络索引、高分辨率图像、气象学、实验测量等,通常包含高维特征,高纬度的数据可能不清晰、冗余&am…

【学习】软件测试人员使用Loadrunner进行性能测试的优势

在软件测试领域,性能测试是一项至关重要的环节,它关乎到软件系统的稳定性和用户体验。而在这其中,Loadrunner作为一款久经考验的性能测试工具,凭借其独特的优势,成为了众多企业和开发者眼中的“得力助手”。 首先&…

在 Google Cloud 上轻松部署开放大语言模型

今天,“在 Google Cloud 上部署”功能正式上线! 这是 Hugging Face Hub 上的一个新功能,让开发者可以轻松地将数千个基础模型使用 Vertex AI 或 Google Kubernetes Engine (GKE) 部署到 Google Cloud。 Model Garden (模型库) 是 Google Clou…

C语言高质量编程之assert()和const

目录 编程中常见的错误 assert() const 编程中常见的错误 在编程中我们通常会遇到三种错误形式,分别是:编译型错误,链接型错误,运行时错误。 编译型错误: 在编译阶段发生的错误,绝大多数情况是由语法错误…

Golang | Leetcode Golang题解之第18题四数之和

题目&#xff1a; 题解&#xff1a; func fourSum(nums []int, target int) (quadruplets [][]int) {sort.Ints(nums)n : len(nums)for i : 0; i < n-3 && nums[i]nums[i1]nums[i2]nums[i3] < target; i {if i > 0 && nums[i] nums[i-1] || nums[i]…

[GDC24]TheFInals的破坏系统

GDC24上TheFinals的开发工作室–EmbarkStudios带来; TheFinals把实时破坏在主流游戏上提升到了新的高度,可以说是新的标杆,达成了: 可以出现大规模的任意破坏破坏之后充分影响gameplay,可以把建筑任意炸毁之后,坍塌的建筑继续保留&物理正确(有正确的网络同步),可以废墟中继…

微服务之Consul 注册中心介绍以及搭建

一、微服务概述 1.1单体架构 单体架构&#xff08;monolithic structure&#xff09;&#xff1a;顾名思义&#xff0c;整个项目中所有功能模块都在一个工程中开发&#xff1b;项目部署时需要对所有模块一起编译、打包&#xff1b;项目的架构设计、开发模式都非常简单。 当项…

ES6: promise对象与回调地狱

ES6&#xff1a; promise对象与回调地狱 一、回调地狱二、Promise概述三、Promise的组成四、用函数封装Promise读取文件操作 一、回调地狱 在js中大量使用回调函数进行异步操作&#xff0c;而异步操作什么时候返回结果是不可控的&#xff0c;所以希望一段程序按我们制定的顺序执…

电脑无法开机?原因分析与解决方案

电脑无法开机是一种常见的问题&#xff0c;可能会给用户带来诸多困扰。无法启动可能是由于硬件故障、软件问题或者其他未知原因引起的。在本文中&#xff0c;我们将介绍三种常见的方法来解决电脑无法开机的问题&#xff0c;以帮助用户尽快恢复正常使用。 方法1&#xff1a;检查…

电影《你想活出怎样的人生》观后感

上周去看了宫崎骏电影《你想活出怎样的人生》&#xff0c;就像作为导演问观众的一个问题一样&#xff0c;宫崎骏老爷子&#xff0c;在电影中&#xff0c;给出了他的一些开放式答案。自己可是说是宫崎骏的粉丝&#xff0c;宫崎骏老爷子的大部分电影&#xff0c;自己基本都看过了…

Nevercenter CameraBag Pro--专业级摄影后期处理利器

Nevercenter CameraBag Pro是一款功能强大的照片滤镜软件&#xff0c;专为摄影爱好者和专业摄影师设计。它拥有超过200种预设滤镜和效果&#xff0c;包括黑白、复古、胶片等多种风格&#xff0c;能够轻松改变照片的外观&#xff0c;并赋予作品独特的艺术感。此外&#xff0c;Ca…

数据库(3)

目录 11.那你知道什么是覆盖索引和回表吗&#xff1f; 12.什么是MVCC&#xff1f;说说MySQL实现MVCC的原理&#xff1f; 13.MySQL的锁的类型有哪些呢&#xff1f; 14.你们数据量级多大&#xff1f;分库分表是怎么做的&#xff1f; 15.分表后非分库字段sharding_key的查询怎…