当前位置: 首页 > news >正文

观察者设计模式详解:解耦通知机制的利器

在面向对象设计中,设计模式为我们提供了通用的解决方案,以应对常见的开发问题。观察者设计模式是其中非常经典且实用的一种模式,广泛应用于GUI系统、事件处理、消息推送等场景。今天,我们就深入探讨观察者模式的概念、结构和特点,以及如何在实际项目中使用它。
 

一、什么是观察者设计模式?

观察者设计模式(Observer Pattern),属于行为型模式。它定义了对象之间的一种一对多依赖关系,当一个对象的状态发生变化时,所有依赖于它的对象都会自动收到通知并更新状态。简而言之,它是一种发布-订阅的机制,其中**主体(Subject)**发布通知,**观察者(Observer)**订阅并接收通知。

主要角色

观察者模式的核心是观察者被观察者。我们来看一下其主要角色:
 

  1. Subject(被观察者):被观察的对象,负责维护所有依赖于它的观察者,并在自身状态改变时通知它们。

    • 主要操作:addObserver(Observer)removeObserver(Observer)notifyObservers()

  2. Observer(观察者):接收通知的对象。当被观察者的状态发生变化时,观察者会被自动通知并执行更新逻辑。

    • 主要操作:update(),用于接收并处理通知。

  3. ConcreteSubject(具体的被观察者):实现了 Subject 接口,并持有观察者列表。当状态发生变化时,通知所有观察者。

  4. ConcreteObserver(具体的观察者):实现了 Observer 接口,并注册自己为被观察者的观察者。收到通知时,更新自身的状态。

二、观察者模式的结构与特点

1. 结构分析

观察者模式的结构非常简洁,主要由SubjectObserverConcreteSubjectConcreteObserver构成。

  • Subject 接口提供了注册、注销观察者和通知观察者的方法。

  • ConcreteSubject 实现了 Subject 接口,包含实际的状态数据并负责通知观察者。

  • Observer 接口定义了 update() 方法,供观察者实现。

  • ConcreteObserver 实现了 Observer 接口,接收通知并执行自己的更新逻辑。

2. 观察者模式的特点

  • 一对多依赖关系:一个被观察者可以同时通知多个观察者,适用于多个系统组件依赖同一数据源的场景。

  • 松耦合:观察者与被观察者之间仅通过接口进行交互,双方不知道彼此的具体实现,符合“开闭原则”,方便扩展。

  • 自动通知:一旦被观察者的状态变化,所有已注册的观察者会自动接收到通知并进行状态更新,无需额外的操作。

  • 动态订阅/退订:观察者可以在运行时注册或注销,灵活应对不同的业务需求。

三、观察者模式的应用场景

观察者模式广泛应用于以下几种场景:

  1. 事件处理系统:例如,在GUI框架中,当用户与界面进行交互时,界面元素(按钮、文本框等)作为观察者监听并响应事件的变化。

  2. 消息推送系统:例如,社交媒体平台的通知系统,当某个用户发布内容时,关注此用户的其他用户会收到通知。

  3. 实时数据更新系统:例如,股票交易平台,当某个股票价格发生变化时,所有订阅该股票的用户都会被自动通知。

  4. 日志系统:多个系统组件可以作为观察者订阅一个日志发布者,日志发布者在运行时生成日志并推送给各个观察者进行显示或存储。

四、代码示例:天气监测系统

让我们通过一个简单的天气监测系统来演示观察者模式的应用。

import java.util.ArrayList;
import java.util.List;// Observer 接口
interface Observer {void update(float temperature);
}// Subject 接口
interface Subject {void addObserver(Observer observer);void removeObserver(Observer observer);void notifyObservers();
}// ConcreteSubject(具体的被观察者)
class WeatherStation implements Subject {private List<Observer> observers = new ArrayList<>();private float temperature;@Overridepublic void addObserver(Observer observer) {observers.add(observer);}@Overridepublic void removeObserver(Observer observer) {observers.remove(observer);}@Overridepublic void notifyObservers() {for (Observer observer : observers) {observer.update(temperature);}}public void setTemperature(float temperature) {this.temperature = temperature;notifyObservers();}
}// ConcreteObserver(具体的观察者)
class PhoneDisplay implements Observer {@Overridepublic void update(float temperature) {System.out.println("Phone display updated with temperature: " + temperature);}
}class TVDisplay implements Observer {@Overridepublic void update(float temperature) {System.out.println("TV display updated with temperature: " + temperature);}
}public class ObserverPatternDemo {public static void main(String[] args) {WeatherStation weatherStation = new WeatherStation();PhoneDisplay phoneDisplay = new PhoneDisplay();TVDisplay tvDisplay = new TVDisplay();weatherStation.addObserver(phoneDisplay);weatherStation.addObserver(tvDisplay);weatherStation.setTemperature(25.5f);weatherStation.setTemperature(30.0f);}
}

五、展示多个观察者的行为

class AlarmSystem implements Observer {@Overridepublic void update(float temperature) {if (temperature > 35.0) {System.out.println("Alarm: Temperature too high! Triggering alert...");} else {System.out.println("Alarm: Temperature is normal.");}}
}class WeatherApp implements Observer {@Overridepublic void update(float temperature) {System.out.println("Weather App: Showing the updated temperature: " + temperature);}
}

 修改

// 扩展观察者模式的演示
public class ObserverPatternDemo {public static void main(String[] args) {// 创建一个天气监测站(被观察者)WeatherStation weatherStation = new WeatherStation();// 创建多个观察者PhoneDisplay phoneDisplay = new PhoneDisplay();TVDisplay tvDisplay = new TVDisplay();AlarmSystem alarmSystem = new AlarmSystem();WeatherApp weatherApp = new WeatherApp();// 注册观察者weatherStation.addObserver(phoneDisplay);weatherStation.addObserver(tvDisplay);weatherStation.addObserver(alarmSystem);weatherStation.addObserver(weatherApp);// 设置温度,模拟状态变化并通知所有观察者weatherStation.setTemperature(30.0f); // 正常温度weatherStation.setTemperature(36.5f); // 高温,触发报警}
}

六、总结

通过这次代码扩展,我们可以清晰地看到观察者模式中的一对多依赖关系。在实际应用中,多个组件(观察者)可以依赖同一个数据源(被观察者),当数据源发生变化时,所有依赖于它的组件都会自动得到更新。这个特性非常适用于需要分发状态变化的系统,如 GUI 界面、事件驱动系统、实时数据更新等场景。

观察者模式的最大优点是实现了松耦合,即被观察者和观察者之间没有直接的依赖关系,便于扩展和维护。如果我们需要添加更多类型的观察者(例如,电子邮件通知、短信提醒等),只需实现 Observer 接口并将其添加到被观察者中即可,不会影响其他部分的代码。

相关文章:

观察者设计模式详解:解耦通知机制的利器

在面向对象设计中&#xff0c;设计模式为我们提供了通用的解决方案&#xff0c;以应对常见的开发问题。观察者设计模式是其中非常经典且实用的一种模式&#xff0c;广泛应用于GUI系统、事件处理、消息推送等场景。今天&#xff0c;我们就深入探讨观察者模式的概念、结构和特点&…...

Vim使用完全指南:从基础到高效编辑

Vim使用完全指南&#xff1a;从基础到高效编辑 一、Vim简介与基本概念 Vim&#xff08;Vi IMproved&#xff09;是从vi发展出来的一个功能强大的文本编辑器&#xff0c;以其高效性和灵活性著称&#xff0c;特别适合程序开发和系统管理任务。与常规文本编辑器不同&#xff0c;…...

C语言——数组

在C语言中&#xff0c;数组是一组相同类型元素的集合&#xff0c;并且每个数据都有自己对应的一个序号&#xff0c;我们称之为数组下标或者索引。接下来我们就来看看数组是如何定义的吧&#xff01; 目录 1.一维数组 1.1 定义与初始化 1.2 一维数组的使用 1.3 一维数组在内…...

电商|基于java+vue的农业电商系统(源码+数据库+文档)

农业电商系统 目录 基于java的农业电商系统 一、前言 二、系统设计 三、系统功能设计 系统功能实现 前台&#xff1a; 后台&#xff1a; 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 博主介绍&#xff1a;✌️…...

ServletContextAttributeListener 的用法笔记250417

ServletContextAttributeListener 的用法笔记250417 以下是关于 ServletContextAttributeListener 的用法详解&#xff0c;涵盖核心方法、实现场景、注意事项及最佳实践&#xff0c;帮助您有效监听应用级别属性&#xff08;ServletContext&#xff09;的变化&#xff1a; 1. 核…...

iptables 防火墙

目录 熟悉Linux防火墙的表&#xff0c;链结构 理解数据包匹配的基本流程 学会编写iptables规则 前言 在当今信息化时代,网络安全已成为企业和个人不可忽视的重要议题。随着网络攻击手段的不断升级,构建一个坚固的网络安全防线显得尤为迫切。在Linux系统中,iptables作为一款…...

【厦门大学】DeepSeek大模型及其企业应用实践

DeepSeek大模型及其企业应用实践 前言1. 大模型&#xff1a;人工智能的前沿1.1 大模型的概念1.2 大模型的发展历程1.3 人工智能与大模型的关系1.4 大模型的分类 2. 大模型产品2.1 国外的大模型产品2.2 国内的大模型产品2.3 主流大模型“幻觉”评测 3. 大模型的行业应用3.1 自然…...

解锁智能制造:PLC远程下载如何让设备运维效率提升10倍?

一、2025年远程运维的三大变革驱动力 政策强制&#xff1a; 欧盟CE新规要求&#xff1a;2025年起工业设备必须具备远程审计接口 中国等保2.0&#xff1a;工业控制系统远程访问需达到三级防护 技术成熟&#xff1a; 5G专网边缘计算实现ms级响应 算法自动诊断PLC程序异常&#x…...

卷积神经网络CNN(李宏毅)

目录 怎么把一张影响当成一个模型输入&#xff1f; 同样的 pattern出现在图片不同的位置。 第三个问题&#xff1a;Pooling&#xff1a; 阿尔法Go是怎么下围棋的&#xff1a; CNN不能处理的问题 CNN专门用在影像辨识方面 怎么把一张影响当成一个模型输入&#xff1f; 一张…...

URL / GET请求 中文UTF-8编码JS转化

以长颈鹿为例 decodeURIComponent 将编码转为中文 encodeURIComponent 会对整个参数字符串转义&#xff08;包括 :// 等符号&#xff09;。 encodeURI 仅转义非合法 URL 字符&#xff08;不转义 :/?& 等保留字符&#xff09;。 decodeURIComponent("%E9%95%BF%E9…...

Flink 内部通信底层原理

Flink 集群内部节点之间的通信是用 Akka 实现,比如 JobManager 和 TaskManager 之间的通信。而 operator 之间的数据传输是用 Netty 实现。 RPC 框架是 Flink 任务运行的基础,Flink 整个 RPC 框架基于 Akka 实现。 一、相关概念 RPC(Remote Procedure Call) 概念 定义:…...

async-profiler火焰图找出耗CPU方法

事情起于开发应用对依赖的三方包&#xff08;apache等等&#xff09;进行了升级后&#xff08;主要是升级spring&#xff09;&#xff0c;CPU的使用率较原来大幅提升&#xff0c;几个应用提升50%-100%。 查找半天&#xff0c;对比每次版本的cpu火焰图&#xff0c;看不出有什么…...

深入理解Qt状态机的应用

深入理解Qt状态机的应用 Chapter1 深入理解Qt状态机的应用&#xff08;一&#xff09;什么是有限状态机&#xff1f;状态机的组成应用示例交通信号控制灯系统简单在线购物流程系统 Qt状态机框架Qt状态机框架组成常用接口说明 应用示例源码 Chapter2 深入理解Qt状态机的应用&…...

Python入门安装和语法基础

1.Python简介 Python是解释型语言, ython就为我们提供了非常完善的基础代码库&#xff0c;覆盖了网络、文件、GUI、数据库、文本等大量内容&#xff0c;被形象地称作“内置电池&#xff08;batteries included&#xff09;”。用Python开发&#xff0c;许多功能不必从零编写&am…...

Windows 图形显示驱动开发-WDDM 1.2功能—Windows 8 中的 DirectX 功能改进(四)

一、无覆盖和放弃 在基于磁贴的延迟呈现 (TBDR) 体系结构上呈现内容&#xff1a; Direct3D 11.1 中的呈现目标现在可以使用一组新的资源 API 来支持放弃行为。 开发人员必须了解此功能&#xff0c;并调用额外的 Discard () 方法&#xff0c;以在 TBDR 体系结构 (更高效地运行…...

如何分析服务器日志以追踪黑客攻击行为

分析服务器日志是追踪黑客攻击行为的关键手段。通过系统性地检查日志文件&#xff0c;可以发现异常访问模式、入侵痕迹和后门活动。以下是详细的日志分析方法&#xff1a; 一、重点日志文件定位 Web服务器日志 Nginx: /var/log/nginx/access.log&#xff08;访问日志&#xff0…...

React 对state进行保留和重置

对 state 进行保留和重置 各个组件的 state 是各自独立的。根据组件在 UI 树中的位置&#xff0c;React 可以跟踪哪些 state 属于哪个组件。你可以控制在重新渲染过程中何时对 state 进行保留和重置。 开发环境&#xff1a;Reacttsantd 学习内容 React 何时选择保留或重置状态…...

EmbeddingBag介绍与案例

我们可以用一个具体的例子来说明 EmbeddingBagCollection 的核心作用和它如何处理用户特征。假设我们的用户特征包括 “item_id” 和 “cate_id” 两个字段&#xff0c;每个字段都有各自的离散取值&#xff0c;也就是一些整数 ID。为了让模型能处理这些离散数据&#xff0c;我们…...

css button 点击效果

<!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><title>button点击效果</title><style>#container {display: flex;align-items: center;justify-content: center;}.pushable {position: relat…...

Missashe考研日记-day22

Missashe考研日记-day22 1 专业课408 学习时间&#xff1a;3h学习内容&#xff1a; 先把昨天关于进程调度的课后习题做了&#xff0c;然后花了挺长时间预习OS的最最最最重要的一部分——同步与互斥问题&#xff0c;这部分大二上课的时候就懵懵懂懂的&#xff0c;得认真再领悟…...

二十、FTP云盘

1、服务端 #include <stdio.h> #include <string.h> #include <stdlib.h> #include <sys/types.h> #include <unistd.h> #include <sys/types.h> /* See NOTES */ #include <sys/socket.h> #include <netinet/in.h>…...

SVM-RF回归预测matlab代码

数据为Excel股票预测数据。 数据集划分为训练集、验证集、测试集,比例为8&#xff1a;1&#xff1a;1 模块化结构: 代码将整个流程模块化&#xff0c;使得代码更易于理解和维护。不同功能的代码块被组织成函数或者独立的模块&#xff0c;使得代码逻辑清晰&#xff0c;结构化程…...

Lombok @Builder 注解的进阶玩法:自定义 Getter/Setter 方法全攻略

大家好呀&#xff01;&#x1f44b; 今天我们来聊聊 Java 开发中超级实用的 Lombok 库&#xff0c;特别是它的 Builder 注解。很多小伙伴都用过 Builder 来简化对象的创建&#xff0c;但你们知道吗&#xff1f;当我们需要自定义 getter/setter 方法时&#xff0c;Builder 也能玩…...

C++每日训练 Day 16:构建 GUI 响应式信号机制(面向初学者)

&#x1f4d8; 本篇我们将结合之前的 SignalHub 与 Dispatcher 机制&#xff0c;构建一个适合 GUI 场景的响应式信号系统。以按钮点击为例&#xff0c;构建一个跨线程安全的事件响应系统&#xff0c;配合协程挂起/恢复&#xff0c;让 UI 编程也能更优雅易读。本篇以通俗方式讲解…...

HCIP(OSPF )(2)

OSPF 公共报文头部 版本&#xff08;8bit&#xff09;&#xff1a;目前常用版本为 2&#xff0c;用于标识 OSPF 协议版本。不同版本在功能特性和报文格式上可能存在差异&#xff0c;高版本通常会修复旧版本的漏洞、扩展功能&#xff0c;如支持更多类型的网络拓扑、增强安全性等…...

zynq7020 ubuntu_base 跟文件系统

整体流程 制作 ubuntu_base 镜像运行 petalinux 构建的 ramdisk 系统用 ramdisk 系统把 ubuntu_base 镜像烧录到 emmc从 emmc 跟文件系统 启动内核 制作 ubuntu_base 镜像 制作 ubuntu_base 镜像 sudo apt-get install qemu-user-static # 安装 q…...

51、Spring Boot 详细讲义(八) Spring Boot 与 NoSQL

3、 Elasticsearch 集成 3.1 Elasticsearch 概述 3.1.1 Elasticsearch 的核心概念 Elasticsearch 是一个开源的分布式搜索引擎,主要用于实时数据检索和分析。它的核心功能包括全文检索、结构化查询和分析大规模数据。 分布式搜索引擎: Elasticsearch 将数据分布存储在多个…...

什么是分库分表?

分库分表是一种数据库的分布式架构设计策略&#xff0c;以下是详细介绍&#xff1a; 概念 • 随着互联网的发展&#xff0c;数据量呈爆炸式增长&#xff0c;单个数据库服务器可能难以应对海量数据的存储和访问压力。分库分表就是将原本庞大的数据库拆分成多个小的数据库&#…...

如何让别人访问到自己本地项目?使用内网穿透工具简单操作下实现公网连接!

本地搭建服务器的系统项目网络地址&#xff0c;在没有公网IP使用的情况下&#xff0c;如何让局域网外别人访问到自己本地网站和应用呢&#xff1f;这里介绍一种通用的内网发布公网访问&#xff0c;且简便操作的内网穿透实现方法。 一、什么是内网穿透&#xff1f; 1. 先了解内…...

第一篇:linux之虚拟环境与centos安装

第一篇&#xff1a;linux之虚拟环境与centos安装 文章目录 第一篇&#xff1a;linux之虚拟环境与centos安装一、vmware安装二、centos安装1、centos虚拟环境安装2、centos操作系统配置3、常见问题解决 一、vmware安装 我们想要运行linux&#xff0c;需要先安装一个虚拟软件&am…...

Redis List 的详细介绍

Redis List 的详细介绍 以下是 Redis List 的详细介绍&#xff0c;从基础命令、内部编码和使用场景三个维度展开&#xff1a; 一、基础命令 Redis List 支持双向操作&#xff08;头尾插入/删除&#xff09;&#xff0c;适用于队列、栈等场景&#xff0c;以下是核心命令分类&a…...

docker占用磁盘100%

1. 立即清理方案 快速清理命令 bash 复制 # 停止Docker服务 sudo systemctl stop docker# 清理所有无用数据&#xff08;包括未使用的镜像、容器、网络和卷&#xff09; sudo docker system prune -a --volumes# 重启Docker sudo systemctl start docker 手动清理overlay2…...

20250417-vue-条件插槽

有时候我们需要根据内容是否被传入了插槽来渲染某些内容。 你可以结合使用 $slot 属性与 v-if 来实现。 在下面的示例中&#xff0c;我们定义了一个卡片组件&#xff0c;它拥有三个条件插槽&#xff1a;header、footer 和 default。当 header、footer 或 default 的内容存在时…...

【Unity】UI点击事件处理器

目录 前言脚本 前言 在开发过程中&#xff0c;经常需要监听UI的点击事件&#xff0c;这里我给大家整理一下&#xff0c;脚本直接挂在需要监听的节点上即可。 脚本 using UnityEngine; using UnityEngine.Events; using UnityEngine.EventSystems;namespace GameLogic {/// &…...

阿里云服务器的docker环境安装nacos--实践

阿里云服务器的docker环境安装nacos–实践 前提先安装mysql数据库&#xff0c;mysql中创建nacos所需的表以下为阿里云服务器docker环境安装&#xff0c;需在安全组开放8848端口 1. 拉取nacos-server镜像 //最新版本nacos docker pull nacos/nacos-server//或者指定nacos版本…...

每日算法-链表(23.合并k个升序链表、25.k个一组翻转链表)

一.合并k个升序链表 1.1题目描述 1.2题解思路 解法一&#xff1a;小根堆 我们可以先定义一个小根堆&#xff0c;将k个指针的头结点如堆&#xff0c;每次取堆顶元素尾插到newhead中&#xff0c;然后再pop()&#xff0c;接着push堆顶原来堆顶元素的下一个节点 重点分析&#…...

数据结构——反射、枚举以及lambda表达式

1. 反射 Java的反射&#xff08;reflection&#xff09;机制是在运⾏时检查、访问和修改类、接⼝、字段和⽅法的机制&#xff1b;这种动态获取信息以及动态调⽤对象⽅法的功能称为java语⾔的反射&#xff08;reflection&#xff09;机制。 用途 1. 框架开发 2. 注解处理 3.…...

深入理解 HTML5 Web SQL 数据库:用法、现状与替代方案

一、引言 在 Web 开发的领域中,客户端存储一直是一个关键的话题。HTML5 带来了多种客户端存储的解决方案,其中 Web SQL 数据库曾经是一个备受关注的选项。尽管如今它已被废弃,但了解其原理、使用方法以及为何被替代,对于 Web 开发者来说仍然具有重要的意义。本文将深入探讨…...

系统架构设计(一):UML与软件架构

什么是系统架构设计&#xff1f; 系统架构设计是对系统高层结构和行为的描述&#xff0c;包括&#xff1a; 系统的各个模块&#xff08;组件&#xff09;模块之间的交互方式数据流动、控制流动技术选型与部署策略 系统架构常见的风格有&#xff1a; 分层架构&#xff08;La…...

极狐GitLab 外部流水线验证功能解读

极狐GitLab 是 GitLab 在中国的发行版&#xff0c;关于中文参考文档和资料有&#xff1a; 极狐GitLab 中文文档极狐GitLab 中文论坛极狐GitLab 官网 外部流水线验证 (BASIC SELF) 您可以使用外部服务在创建流水线之前进行验证。 极狐GitLab 发送一个 POST 请求到外部服务的…...

MCP和A2A是什么?

MCP和A2A是什么&#xff1f; MCP&#xff08;Model-Connect Protocol&#xff09;和A2A&#xff08;Agent-to-Agent&#xff09;协议逐渐成为行业关注的焦点。这两个协议分别由Anthropic和谷歌推出&#xff0c;旨在提升智能体与外部工具、数据源及API资源的连接效率&#xff0c…...

CNN卷积神经网络

一、什么是卷积神经网络&#xff08;CNN&#xff09; CNN&#xff08;卷积神经网络&#xff09;是一种专门用于处理图像的神经网络&#xff0c;尤其在图像识别任务中表现出色&#xff0c;例如识别手写数字。它通过多层结构逐步提取图像特征&#xff0c;最终输出识别结果。与传…...

生物信息学技能树(Bioinformatics)与学习路径

李升伟 整理 生物信息学是一门跨学科领域&#xff0c;涉及生物学、计算机科学以及统计学等多个方面。以下是关于生物信息学的学习路径及相关技能的详细介绍。 一、基础理论知识 1. 生物学基础知识 需要掌握分子生物学、遗传学、细胞生物学等相关概念。 对基因组结构、蛋白质…...

Obsidian无门槛简明教程

Obsidian简明教程 Markdown基本语法基本码字标题换行段落引用分割线代码块链接带名字的链接超链接插入图片 强调语法加粗斜体删除线高亮 列表有序列表无序列表任务列表 Obsidian核心用法软件基本使用安装仓库文件夹笔记编辑与查看 资源 核心插件双链标签 三方插件Various Compl…...

常用 Git 命令详解

Git 是一个强大的版本控制工具&#xff0c;广泛用于软件开发和团队协作中。掌握 Git 命令可以帮助开发者更高效地管理代码版本和项目进度。本文将介绍一些常用的 Git 命令&#xff0c;并提供示例以帮助你更好地理解和应用这些命令。 目录 常用命令 git clonegit stashgit pul…...

【HDFS入门】HDFS与Hadoop生态的深度集成:与YARN、MapReduce和Hive的协同工作原理

目录 引言 1 HDFS核心架构回顾 2 HDFS与YARN的集成 3 HDFS与MapReduce的协同 4 HDFS与Hive的集成 4.1 Hive架构与HDFS交互 4.2 Hive数据组织 4.3 Hive查询执行流程 5 HDFS在生态系统中的核心作用 6 性能优化实践 7 总结 引言 在大数据领域&#xff0c;Hadoop生态系统…...

多路由器通过三层交换机互相通讯(单臂路由+静态路由+默认路由版),通过三层交换机让pc端相互通讯

多路由器通过三层交换机互相通讯&#xff08;单臂路由静态路由默认路由版&#xff09; 先实现各个小框框里能够互通 哇咔 交换机1&#xff08;二层交换机,可看配置单臂路由的文章) Switch>en Switch#conf t Switch(config)#int f0/1 Switch(config-if)#switchport access…...

电控---CMSIS概览

1. CMSIS库简介 CMSIS&#xff08;Cortex Microcontroller Software Interface Standard&#xff0c;Cortex微控制器软件接口标准&#xff09;是由ARM公司开发的一套标准化软件接口&#xff0c;旨在为基于ARM Cortex-M系列处理器&#xff08;如Cortex-M0/M0/M3/M4/M7/M33等&am…...

2025.04.17【Stacked area】| 生信数据可视化:堆叠区域图深度解析

文章目录 生信数据可视化&#xff1a;堆叠区域图深度解析堆叠面积图简介为什么使用堆叠面积图如何使用R语言创建堆叠面积图安装和加载ggplot2包创建堆叠面积图的基本步骤示例代码 解读堆叠面积图堆叠面积图的局限性实际应用案例示例&#xff1a;基因表达量随时间变化 结论 生信…...

XSS之同源、跨域、内容安全策略

一、什么是同源策略 HTML的同源策略是浏览器的一个重要的安全机制&#xff0c;它用于限制一个源的网页如何与另一个源的资源进行交互&#xff0c;以此来减少夸站脚本攻击(XSS)和跨站请求伪造(CSRF)等安全风险。 同源的定义 若两个URL的协议&#xff08;protocol&#xff09;、…...