设计模式:享元模式(C#、JAVA、JavaScript、C++、Python、Go、PHP)

news2024/11/25 20:37:42

上一篇《原型模式》                                                                      下一篇《责任链模式》

简介:

享元模式,它是一种结构型设计模式,旨在有效地支持大量细粒度的对象共享,通过共享对象来减少内存消耗和提高性能。享元模式将对象的状态分为内部状态和外部状态。内部状态是对象的固定部分,可以在多个对象之间共享,而外部状态是对象的变化部分,需要在使用时传递给对象。享元模式将内部状态存储在享元对象中,并将外部状态作为参数传递给方法。

享元模式包含以下几个关键组件:
1、享元接口:定义了享元对象的通用接口,通过该接口可以获取内部状态和操作享元对象。
2、具体享元:实现了享元接口,并包含内部状态。具体享元对象需要是可共享的,也就是说它们可以在多个上下文中共享。
3、享元工厂:负责创建和管理享元对象。它维护一个享元池,用于存储已经创建的享元对象,以便在需要时进行复用。当客户端需要使用享元对象时,可以通过享元工厂获取对象的实例。如果享元池中已经存在相应的对象实例,则直接返回该实例;如果不存在,则创建一个新的享元对象并添加到享元池中。这样可以确保相同的对象在多个地方共享使用,减少内存消耗。

需要注意的是,当对象数量太多时,享元模式会导致运行代价过高,带来性能下降等问题。因此,在使用享元模式时,要根据实际情况慎重考虑。

享元模式的使用场景:
1、系统中存在大量的相似对象。
2、细粒度的对象都具备较接近的外部状态,而且内部状态与环境无关,也就是说对象没有特定身份。
3、需要缓冲池的场景。

享元模式通过共享对象来减少内存消耗和提高性能,适用于存在大量相似对象的场景,特别是当对象的内部状态较少并且可以共享时。它常用于系统底层的开发,解决系统的性能问题,比如数据库连接池、String常量池、缓冲池等都是享元模式的使用。

虽然可以使用享元模式来实现对象池,但是这两者还是有比较大的差异。对象池着重在对象的复用上,池中的每个对象是可替换的,从同一个池中获得A对象和B对象对客户端来说是完全相同的;而享元模式主要解决的对象的共享问题,如何建立多个可共享的细粒度对象是其主要关注的重点。

享元模式的创建步骤:
1、定义抽象享元类:这是一个抽象类,内部状态和外部状态的定义,以及抽象方法的定义。抽象类通常用于声明享元工厂类和用户调用中涉及的对象类型。
2、定义内部状态:内部状态是多个细粒度对象共享的信息。这些信息是在对象池中维护一个享元对象的共享信息。当多个细粒度对象从享元工厂类中获取该享元对象时,它们获取的都是相同的享元对象。
3、定义外部状态:外部状态很重要,它作为从对象池中获取对象的依据。外部状态相等的两个对象说明它们是相同的。
4、创建享元工厂:负责维护享元池,用于存储具有相同内部状态的享元对象。享元模式中共享的仅仅是享元对象,外部状态是需要通过环境类设置的。

在实际使用中,能共享的内部状态不是很多的,所以设计享元对象是比较小的,也就是细粒度对象。所以说享元模式就是通过共享技术实现大量细粒度对象的复用。

享元模式的优点,主要包括:
1、减少内存消耗:享元模式通过共享对象实例来减少内存消耗,特别是在存在大量相似对象的场景中,可以显著降低内存消耗。
2、提高性能:由于享元对象是被共享的,所以它可以减少内存占用,从而降低系统的开销。同时,享元模式还可以提高系统的性能和效率。
3、提高系统的灵活性:享元模式将对象的内部状态和外部状态分离开来,使得系统更加易于扩展和维护。

享元模式的缺点,主要包括:
1、维护一个享元池需要引入额外的复杂性。在享元模式中,需要维护一个存储享元对象的享元池,这可能会增加系统的复杂性和开销。
2、为了使对象可以共享,享元模式需要将享元对象的部分状态外部化,而读取外部状态将使得运行时间变长。这可能会对系统的性能产生一定的影响。
3、享元模式使得系统变得复杂,需要分离出内部状态和外部状态,这使得程序的逻辑复杂化。这可能会增加开发人员的工作量和开发难度。
4、享元模式不适用于所有情况。在某些情况下,使用享元模式可能会导致系统的设计和实现变得复杂化和难以理解,从而增加开发和维护的成本。

示例:

一、C#享元模式

以下是一个示例,展示了如何在C#中实现享元模式:

using System;  
using System.Collections.Generic;  
  
public abstract class Shape  
{  
    protected int _x;  
    protected int _y;  
      
    public Shape(int x, int y)  
    {  
        _x = x;  
        _y = y;  
    }  
      
    public virtual void Draw()  
    {  
        Console.WriteLine("Drawing Shape at ({0}, {1})", _x, _y);  
    }  
}  
  
public class Circle : Shape  
{  
    public Circle(int x, int y) : base(x, y) { }  
      
    public override void Draw()  
    {  
        Console.WriteLine("Drawing Circle at ({0}, {1})", _x, _y);  
    }  
}  
  
public class Rectangle : Shape  
{  
    public Rectangle(int x, int y) : base(x, y) { }  
      
    public override void Draw()  
    {  
        Console.WriteLine("Drawing Rectangle at ({0}, {1})", _x, _y);  
    }  
}  
  
public class ShapeFactory  
{  
    private Dictionary<string, Shape> _shapes = new Dictionary<string, Shape>();  
      
    public Shape GetShape(string shapeType)  
    {  
        if (_shapes.ContainsKey(shapeType))  
        {  
            return _shapes[shapeType];  
        }  
        else  
        {  
            Shape shape = null;  
            switch (shapeType)  
            {  
                case "Circle":  
                    shape = new Circle(0, 0);  
                    break;  
                case "Rectangle":  
                    shape = new Rectangle(0, 0);  
                    break;  
                default:  
                    Console.WriteLine("Unsupported shape type: {0}", shapeType);  
                    break;  
            }  
            _shapes[shapeType] = shape;  
            return shape;  
        }  
    }  
}  
  
public class Program  
{  
    public static void Main(string[] args)  
    {  
        ShapeFactory factory = new ShapeFactory();  
        Shape circle = factory.GetShape("Circle"); 
        circle.Draw();
    }
}

二、java享元模式

享元模式通常通过以下方式实现:

import java.util.HashMap;  
import java.util.Map;  
  
// 抽象享元类  
abstract class AbstractFlyweight {  
    protected int color;  
    protected int size;  
  
    // 外部传入的颜色和大小值  
    public void set(int color, int size) {  
        this.color = color;  
        this.size = size;  
    }  
  
    // 内部方法,用于展示对象的状态  
    public void display() {  
        System.out.println("Color: " + color + ", Size: " + size);  
    }  
}  
  
// 具体享元类1  
class ConcreteFlyweight1 extends AbstractFlyweight {  
    public ConcreteFlyweight1(int color, int size) {  
        set(color, size);  
    }  
}  
  
// 具体享元类2  
class ConcreteFlyweight2 extends AbstractFlyweight {  
    public ConcreteFlyweight2(int color, int size) {  
        set(color, size);  
    }  
}  
  
// 享元工厂类  
class FlyweightFactory {  
    private Map<String, AbstractFlyweight> flyweights;  
  
    public FlyweightFactory() {  
        this.flyweights = new HashMap<>();  
    }  
  
    public AbstractFlyweight getFlyweight(String key) {  
        if (flyweights.containsKey(key)) {  
            return flyweights.get(key);  
        } else {  
            ConcreteFlyweight1 concreteFlyweight1 = new ConcreteFlyweight1(0, 0); // default values for testing purpose only. 0,0 would not be a valid values in real scenarios.  
            flyweights.put(key, concreteFlyweight1);  
            return concreteFlyweight1;  
        }  
    }  
}  
  
public class FlyweightPatternDemo {  
    public static void main(String[] args) {  
        FlyweightFactory flyweightFactory = new FlyweightFactory();  
        AbstractFlyweight flyweight1 = flyweightFactory.getFlyweight("Object1"); // for the first time this object is created. It will be shared across multiple requests.   
        AbstractFlyweight flyweight2 = flyweightFactory.getFlyweight("Object2"); // for the second time this object is not created again. It will be retrieved from the flyweights map.   
        flyweight1.display();   
        flyweight2.display();   
    }   
}

三、javascript享元模式

在JavaScript中,享元实现方式如下:

// 抽象享元类  
class AbstractFlyweight {  
  constructor(color, size) {  
    this.color = color;  
    this.size = size;  
  }  
  
  display() {  
    console.log(`Color: ${this.color}, Size: ${this.size}`);  
  }  
}  
  
// 具体享元类1  
class ConcreteFlyweight1 extends AbstractFlyweight {  
  constructor(color, size, additionalInfo) {  
    super(color, size);  
    this.additionalInfo = additionalInfo;  
  }  
  
  display() {  
    super.display();  
    console.log(`Additional Info: ${this.additionalInfo}`);  
  }  
}  
  
// 具体享元类2  
class ConcreteFlyweight2 extends AbstractFlyweight {  
  constructor(color, size, additionalInfo) {  
    super(color, size);  
    this.additionalInfo = additionalInfo;  
  }  
  
  display() {  
    super.display();  
    console.log(`Additional Info: ${this.additionalInfo}`);  
  }  
}  
  
// 享元工厂类  
class FlyweightFactory {  
  constructor() {  
    this.flyweights = new Map(); // 使用 Map 存储享元对象,方便查找和管理  
  }  
  
  getFlyweight(key) {  
    if (this.flyweights.has(key)) {  
      return this.flyweights.get(key); // 如果已经存在,直接返回已有的享元对象  
    } else {  
      const flyweight = new ConcreteFlyweight1(0, 0, 'New Flyweight'); // 默认创建一个新的享元对象,0,0 和 New Flyweight 是示例值,实际使用时需要替换为真实值或随机值等  
      this.flyweights.set(key, flyweight); // 将新创建的享元对象存储到 Map 中,以便后续重复使用  
      return flyweight; // 返回新创建的享元对象给调用方使用  
    }  
  }  
}

四、C++享元模式

以下是在C++中实现享元模式:

#include <iostream>  
#include <map>  
  
// 抽象享元类  
class AbstractFlyweight {  
public:  
    virtual void operation() = 0;  
};  
  
// 具体享元类1  
class ConcreteFlyweight1 : public AbstractFlyweight {  
public:  
    void operation() override {  
        std::cout << "ConcreteFlyweight1 operation" << std::endl;  
    }  
};  
  
// 具体享元类2  
class ConcreteFlyweight2 : public AbstractFlyweight {  
public:  
    void operation() override {  
        std::cout << "ConcreteFlyweight2 operation" << std::endl;  
    }  
};  
  
// 享元工厂类  
class FlyweightFactory {  
private:  
    std::map<int, AbstractFlyweight*> flyweights; // 使用 map 存储享元对象,方便查找和管理  
public:  
    AbstractFlyweight* getFlyweight(int key) {  
        if (flyweights.count(key) > 0) { // 如果已经存在,直接返回已有的享元对象  
            return flyweights[key];  
        } else { // 否则,创建一个新的享元对象,并将其存储到 map 中  
            AbstractFlyweight* flyweight = new ConcreteFlyweight1(); // 默认创建一个 ConcreteFlyweight1 对象作为享元对象,也可以根据需要创建 ConcreteFlyweight2 对象或其他对象作为享元对象  
            flyweights[key] = flyweight; // 将新创建的享元对象存储到 map 中,以便后续重复使用  
            return flyweight; // 返回新创建的享元对象给调用方使用  
        }  
    }  
};  
  
int main() {  
    FlyweightFactory factory; // 创建享元工厂对象  
    AbstractFlyweight* flyweight1 = factory.getFlyweight(1); // 从工厂中获取一个享元对象,可以是 ConcreteFlyweight1 或 ConcreteFlyweight2 等其他对象,这里假设是 ConcreteFlyweight1 对象,并将其指针保存到 flyweight1 中  
    flyweight1->operation(); // 调用享元对象的 operation 方法,输出 "ConcreteFlyweight1 operation" 到控制台中  
    AbstractFlyweight* flyweight2 = factory.getFlyweight(2); // 从工厂中获取另一个享元对象,同样可以是 ConcreteFlyweight1 或 ConcreteFlyweight2 等其他对象,这里假设是 ConcreteFlyweight2 对象,并将其指针保存到 flyweight2 中  
    flyweight2->operation(); // 调用享元对象的 operation 方法,输出 "ConcreteFlyweight2 operation" 到控制台中,由于 flyweight2 是新创建的 ConcreteFlyweight2 对象,因此输出结果与之前的 flyweight1 不相同  
    return 0;  
}

五、python享元模式

以下是在python中实现享元模式:

from abc import ABC, abstractmethod  
  
# 享元类  
class Flyweight(ABC):  
    @abstractmethod  
    def operation(self):  
        pass  
  
# 具体享元类1  
class ConcreteFlyweight1(Flyweight):  
    def operation(self):  
        super().operation()  
        print("ConcreteFlyweight1 operation")  
  
# 具体享元类2  
class ConcreteFlyweight2(Flyweight):  
    def operation(self):  
        super().operation()  
        print("ConcreteFlyweight2 operation")  
  
# 享元工厂类  
class FlyweightFactory:  
    _flyweights = {}  
  
    def get_flyweight(self, key):  
        if key in self._flyweights:  
            return self._flyweights[key]  
        else:  
            flyweight = ConcreteFlyweight1() # 或者 ConcreteFlyweight2 等其他具体享元类  
            self._flyweights[key] = flyweight  
            return flyweight  
      
    def put_flyweight(self, key, flyweight):  
        self._flyweights[key] = flyweight
    
#使用示例:    
factory = FlyweightFactory()  
flyweight1 = factory.get_flyweight(1) # 返回一个 ConcreteFlyweight1 对象,key 为 1 的对象已经存在则直接返回,否则创建一个新的对象并存储到字典中  
flyweight2 = factory.get_flyweight(2) # 返回一个 ConcreteFlyweight1 对象,key 为 2 的对象已经存在则直接返回,否则创建一个新的对象并存储到字典中  
flyweight1.operation() # 输出 "ConcreteFlyweight1 operation"  
flyweight2.operation() # 输出 "ConcreteFlyweight1 operation"       

 六、go享元模式

以下是一个示例,展示了如何在go中实现享元模式:

package main  
  
import (  
 "fmt"  
)  
  
// Flyweight 接口定义了享元对象的行为  
type Flyweight interface {  
 Operation()  
}  
  
// ConcreteFlyweight1 和 ConcreteFlyweight2 是具体的享元对象  
type ConcreteFlyweight1 struct {  
 // 共享状态  
 state1 string  
}  
  
func (f *ConcreteFlyweight1) Operation() {  
 fmt.Println("ConcreteFlyweight1 operation with state1:", f.state1)  
}  
  
type ConcreteFlyweight2 struct {  
 // 共享状态  
 state2 int  
}  
  
func (f *ConcreteFlyweight2) Operation() {  
 fmt.Println("ConcreteFlyweight2 operation with state2:", f.state2)  
}  
  
// FlyweightFactory 是享元工厂,用于创建和管理享元对象  
type FlyweightFactory struct {  
 flyweights map[string]Flyweight  
}  
  
func NewFlyweightFactory() *FlyweightFactory {  
 return &FlyweightFactory{  
 flyweights: make(map[string]Flyweight),  
 }  
}  
  
func (f *FlyweightFactory) GetFlyweight(key string) Flyweight {  
 if flyweight, ok := f.flyweights[key]; ok {  
 return flyweight // 如果已存在,则直接返回已有的享元对象  
 } else {  
 // 如果不存在,则创建一个新的享元对象,并将其存储到 flyweights 中  
 switch key {  
 case "state1":  
 flyweight := &ConcreteFlyweight1{state1: "shared state 1"}  
 f.flyweights[key] = flyweight  
 return flyweight  
 case "state2":  
 flyweight := &ConcreteFlyweight2{state2: 42}  
 f.flyweights[key] = flyweight  
 return flyweight  
 default:  
 return nil  
 }  
 }  
}  
  
func main() {  
 factory := NewFlyweightFactory() // 创建享元工厂对象  
 flyweight1 := factory.GetFlyweight("state1") // 从工厂中获取一个享元对象,这里使用 key 为 "state1" 的 ConcreteFlyweight1 对象作为示例,并将其指针保存到 flyweight1 中  
 flyweight1.Operation() // 调用享元对象的 Operation 方法,输出 "ConcreteFlyweight1 operation with state1: shared state 1" 到控制台中  
 flyweight2 := factory.GetFlyweight("state2") // 从工厂中获取另一个享元对象,这里使用 key 为 "state2" 的 ConcreteFlyweight2 对象作为示例,并将其指针保存到 flyweight2 中
}

七、PHP享元模式

以下是一个示例,展示了如何在PHP中实现享元模式:

<?php  
  
// 享元接口  
interface Flyweight {  
    public function operation();  
}  
  
// 具体享元类1  
class ConcreteFlyweight1 implements Flyweight {  
    private $state1;  
      
    public function operation() {  
        // 具体操作  
        $this->state1 = "shared state 1";  
        echo "ConcreteFlyweight1 operation with state1: " . $this->state1 . "\n";  
    }  
}  
  
// 具体享元类2  
class ConcreteFlyweight2 implements Flyweight {  
    private $state2;  
      
    public function operation() {  
        // 具体操作  
        $this->state2 = 42;  
        echo "ConcreteFlyweight2 operation with state2: " . $this->state2 . "\n";  
    }  
}  
  
// 享元工厂类  
class FlyweightFactory {  
    private $flyweights;  
      
    public function __construct() {  
        $this->flyweights = [];  
    }  
      
    public function getFlyweight($key) {  
        if (isset($this->flyweights[$key])) {  
            return $this->flyweights[$key]; // 如果已存在,则直接返回已有的享元对象  
        } else {  
            // 如果不存在,则创建一个新的享元对象,并将其存储到 flyweights 中  
            switch ($key) {  
                case "state1":  
                    $flyweight = new ConcreteFlyweight1();  
                    $this->flyweights["state1"] = $flyweight;  
                    return $flyweight;  
                case "state2":  
                    $flyweight = new ConcreteFlyweight2();  
                    $this->flyweights["state2"] = $flyweight;  
                    return $flyweight;  
                default:  
                    return null;  
            }  
        }  
    }  
}  
  
// 使用享元模式示例  
$factory = new FlyweightFactory(); // 创建享元工厂对象  
$flyweight1 = $factory->getFlyweight("state1"); // 从工厂中获取一个享元对象,这里使用 key 为 "state1" 的 ConcreteFlyweight1 对象作为示例,并将其指针保存到 $flyweight1 中  
$flyweight1->operation(); // 调用享元对象的 Operation 方法,输出 "ConcreteFlyweight1 operation with state1: shared state 1" 到控制台中  
$flyweight2 = $factory->getFlyweight("state2"); // 从工厂中获取另一个享元对象,这里使用 key 为 "state2" 的 ConcreteFlyweight2 对象作为示例,并将其指针保存到 $flyweight2 中  
$flyweight2->operation(); // 调用享元对象的 Operation 方法,输出 "ConcreteFlyweight2 operation with state2: 42" 到控制台中  
?>

《完结》

上一篇《原型模式》                                                                     下一篇《责任链模式》

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

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

相关文章

【C++】缺省参数及函数重载

&#x1f4d9; 作者简介 &#xff1a;RO-BERRY &#x1f4d7; 学习方向&#xff1a;致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 &#x1f4d2; 日后方向 : 偏向于CPP开发以及大数据方向&#xff0c;欢迎各位关注&#xff0c;谢谢各位的支持 目录 1. 缺省参数1.1 缺省…

常见持久层框架赏析,到底是什么让你选择 MyBatis?

在绝大多数在线应用场景中&#xff0c;数据是存储在关系型数据库中的&#xff0c;当然&#xff0c;有特殊要求的场景中&#xff0c;我们也会将其他持久化存储&#xff08;如 ElasticSearch、HBase、MongoDB 等&#xff09;作为辅助存储。但不可否认的是&#xff0c;关系型数据库…

Ubuntu20.04操作系统安装及重中之重:系统分区

最近因为学习原因&#xff0c;需要将电脑设置为双系统&#xff0c;在windows10的系统下去安装Ubuntu操作系统。本来看网上相关的安装教程蛮多的&#xff0c;以为比较简单&#xff0c;结果一路过五关斩六将&#xff0c;坑的七零八落的&#xff0c;折腾了好久&#xff0c;才算安装…

【Java】LinkedList 集合

LinkedList集合特点 LinkedList 底层基于双向链表实现增删 效率非常高&#xff0c;查询效率非常低。 LinkedList源码解读分析 LinkedList 是双向链表实现的 ListLinkedList 是非线程安全的&#xff08;线程是不安全的&#xff09;LinkedList 元素允许为null,允许重复元素Linked…

基于 ARM+FPGA+AD的高精度数据采集系统设计

随着图像处理 、 工业控制 、 无线通信等领域的飞速发 展 &#xff0c; 对数据采集系统的速度 、 精度等性能要求也越来越高 。 这些要求都对数据采集系统的设计和实现提出了新的挑 战 。 目前数据采集系统的设计方案通常分为以下几类 &#xff1a; &#xff11; &#xff0…

【持续交付】个人网站

今天给大家演示下如何基于Vuepress尝试持续交付博客网站。 也尝试过其他的方案&#xff0c;比如使用Typora导出html文件&#xff0c;并scp该文件到服务器上。 效果图 该持续交付主流程如下图 提交代码后会触发webHook生成version.txt,部署脚本每分钟轮询一次检测是否存在vers…

私有云:【14】桌面映射外网

私有云&#xff1a;【14】桌面映射外网 1、选择服务器设置2、选中以下项&#xff0c;填写自己的公网IP3、最后这个也修改掉 1、选择服务器设置 2、选中以下项&#xff0c;填写自己的公网IP 3、最后这个也修改掉 桌面映射外网设置完成&#xff0c;前提要有公网IP噶&#xff0c;…

Docker 笔记(上篇)

Docker 概述 Docker 概念 Docker 是一个开源的应用容器引擎&#xff0c;让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中&#xff0c;然后发布到任何流行的 Linux或Windows操作系统的机器上&#xff0c;也可以实现虚拟化。容器是完全使用沙箱机制&#xff0c;相互之…

【算法练习Day32】 斐波那契数爬楼梯使用最小花费爬楼梯

​&#x1f4dd;个人主页&#xff1a;Sherry的成长之路 &#x1f3e0;学习社区&#xff1a;Sherry的成长之路&#xff08;个人社区&#xff09; &#x1f4d6;专栏链接&#xff1a;练题 &#x1f3af;长路漫漫浩浩&#xff0c;万事皆有期待 文章目录 斐波那契数爬楼梯使用最小花…

所有电商API接口,淘宝API接口分类,1688API、拼多多API、京东API

前往接入API 淘宝API item_get 获取商品详情 根据商品ID查询商品标题价格描述等详情数据 淘宝API item_search 按关键字搜索商品 搜索关键字&#xff0c;显示商品总数&#xff0c;标题&#xff0c;图片&#xff0c;优惠价等数据 淘宝API item_fee 获取商品快递费用 输入商品…

基于RK3568高性价比全国产EMS储能解决方案(一)概述

储能产业链框架 储能产业链可分为上游“原材料及生产设备”、中游“储能系统”、下游“储能场景应用及后市场服务”。 图1 储能产业链框架图 产业链中游的“储能电池系统”主要包括“能量管理系统(EMS)”、“电池管理系统(BMS)”、“储能逆变器(PCS)”、“电池组”四个部分。…

Java创建一个长度为10的数组,利用Arrays.sort(), 为数组元素排序

程序要求&#xff1a;1&#xff09;创建一个整型数组&#xff0c;数组的长度为10. 2&#xff09;给数组元素赋值&#xff0c;要求乱序。 3&#xff09;利用fori循环将数组元素依次输出。 4&#xff09;利用Arrays.sort(), 为数组元素排序 5&#xff09;采用增加for循环将排…

shell语法大全(超级详细!!!!),非常适合入门

本文旨在对y总的Linux基础课shell语法做学习记录&#xff0c;指令较多&#xff0c;方便日后查找。 参考视频&#xff1a;Linux基础课 参考教程&#xff1a;Linux教程 1 概论 Linux中常见的shell脚本有很多种&#xff0c;常见的有&#xff1a; Bourne Shell(/usr/bin/sh或/bi…

Evade Deep Image Retrieval by Stashing Private Images in the Hash Space

摘要&#xff1a; 挑战&#xff1a; 当网络上的图像被大规模检索并被用作个人信息的丰富矿藏时&#xff0c;隐私也面临着风险&#xff1b; 攻击者可以通过从目标类别中查询类似图像以查找任何可用模型来提取私有图像。 提出&#xff1a; 提出了一种基于对抗性示例的新机制…

Cesium绕点旋转

目录 项目地址实现效果实现方法 项目地址 https://github.com/zhengjie9510/webgis-demo 实现效果 实现方法 let angle 0.0 viewer.camera.lookAt(position, new Cesium.HeadingPitchRange(Cesium.Math.toRadians(angle), Cesium.Math.toRadians(-30), 2000)) viewer.clock…

Ubuntu自建git服务器

Ubuntu 安装 gitlab-ce sudo apt-get update sudo apt-get install gitlab-ce 安装成功 sudo apt-get install gitlab-ce 正在读取软件包列表... 完成 正在分析软件包的依赖关系树 正在读取状态信息... 完成 下列【新】软件包将被安装&#xff1a;gitlab-ce 升…

基于鸟群算法的无人机航迹规划-附代码

基于鸟群算法的无人机航迹规划 文章目录 基于鸟群算法的无人机航迹规划1.鸟群搜索算法2.无人机飞行环境建模3.无人机航迹规划建模4.实验结果4.1地图创建4.2 航迹规划 5.参考文献6.Matlab代码 摘要&#xff1a;本文主要介绍利用鸟群算法来优化无人机航迹规划。 1.鸟群搜索算法 …

koa搭建服务器(二)

在上一篇文章已经成功的运行了一个http服务器&#xff0c;接下来就是使用Sequelize ORM&#xff08;官方文档&#xff1a;Sequelize 简介 | Sequelize中文文档 | Sequelize中文网&#xff09;来操作数据库。 1、安装依赖 首先也是需要安装相关的依赖 npm i sequelize npm i …

【Mysql】数据库三大范式

数据库三范式 &#xff1a;数据库三范式是指关系型数据库设计中的三种规范化设计原则&#xff0c;旨在减少数据冗余、提高数据一致性和可维护性。 第一范式&#xff1a;规定表中的每一列都应该是不可分割的最小单元。 为什么要这样实现呢&#xff1f; &#xff1a;举个栗子…

【Unity PlasticSCM】记录:从介绍 下载 到拉取项目

实习的时候项目是svn管理的&#xff0c;这次mini的项目管理最后选择了美术策划友好的plasticSCM&#xff0c;但之前没有接触过&#xff0c;所以决定花费一点时间去了解&#xff0c;然后记录一下中间遇到的一些问题。 了解及下载Plastic b站很详细介绍PlasticSCM&#xff1a;Un…