1. 观察者模式简介

  • 软件系统:一个对象的状态或行为的变化将导致其他对象的状态或行为也发生改变,它们之间将产生联动;
  • 观察者模式:
    • 定义了对象之间一种一对多的依赖关系,让一个对象的改变能够影响其他对象;
    • 发生改变的对象称为观察目标(主题对象),被通知的对象称为观察者;
    • 一个观察目标可以对应多个观察者。
  • 观察者模式又叫做发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。
  • 观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象(观察目标),使用面向对象技术,将这种依赖关系弱化,并形成一种稳定的依赖关系。从而实现软件体系结构的松耦合。

定义对象间的一种一对多的依赖关系,以便当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。
——《设计模式》GoF

观察者模式别名:
发布-订阅(Publish/Subscribe)模式
模型-视图(Model/View)模式
源-监听器(Source/Listener)模式
从属者(Dependents)模式

2. 观察者模式的结构

在这里插入图片描述

  • 抽象主题(Subject)角色:抽象主题角色把所有对观察者对象的引用保存在一个聚集(比如哈希表)里,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象,主题角色又叫做抽象被观察者(Observable)角色,一般用一个抽象类或者一个接口实现。
  • 抽象观察者(Observer)角色:为所有的具体观察者定义一个接口,在得到主题的通知时更新自己。这个接口叫做更新接口。抽象观察者角色一般用一个抽象类或者一个接口实现。更新方法一般包括增删改等。
  • 具体主题(ConcreteSubject)角色:将有关状态(即观察者需要了解的数据改变)存入具体现察者对象;在具体主题的内部状态改变时,给所有登记过的观察者发出通知(通知中携带改变的数据)。具体主题角色又叫做具体被观察者角色(Concrete Observable)。具体主题角色通常用一个具体子类实现。
  • 具体观察者(ConcreteObserver)角色:具体现察者角色实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态相协调。如果需要,具体现察者角色可以保存一个指向具体主题对象的引用(允许观察者调用主题对象)。具体观察者角色通常用一个具体子类实现。
  • 抽象主题角色与抽象观察者角色之间的合成关系,代表具体主题对象可以有任意多个对抽象观察者对象的引用。之所以使用抽象观察者而不是具体观察者,意味着主题对象不需要知道引用了哪些ConcreteObserver类型,而只知道抽象Observer类型。这就使得具体主题对象可以动态地维护一系列的对观察者对象的引用,并在需要的时候调用每一个观察者共有的Update()方法。这种做法即为前述的“针对抽象编程“—依赖倒置原则。

代码模式:

典型的抽象目标类代码:

using System.Collection
abstract class Subject
{//定义一个观察者集合用于存储所有观察者对象protected ArrayList observers = new ArrayList();//声明抽象注册方法,用于向观察者集合中增加一个观察者public abstract void Attach(Observer observer);//声明抽象注销方法,用于在观察者集合中删除一个观察者public abstract void Detach(Observer observer);//声明抽象通知方法public abstract void Notify();
}

典型的具体目标类代码:

class ConcreteSubject : Subject
{public override void Attach(Observer observer){observers.Add(observer);}public override void Detach(Observer observer){observers.Remove(observer);}//实现通知方法public override void Notify(){//遍历观察者集合,调用每一个观察者的响应方法foreach(object obs in observers){((Observer)obs).Update();}}
}

典型的抽象观察者代码:

interface Observer
{void Update();
}

典型的具体观察者代码:

class ConcreteObserver : Observer
{//实现响应方法public void Update(){//具体更新代码}
}

典型的客户端代码片段:

……
Subject subject = new ConcreteSubject();
Observer observer = new ConcreteObserver();
subject.Attach(observer);       //通常由观察者自己注册
subject.Notify();                       //通常由主题方自己发布
……

3. 观察者模式的示例

3.1 示例一

银行帐户改动通知系统:帐户的余额发生变化时,需要通过手机短信和E-Mail的方式通知到用户本人。
示例:BankAccount
示例: ObserverBankAccount

BankAccount示例代码:

namespace BankAccount{class Program{static void Main(string[] args){BankAccount account = new BankAccount();account.UpdateBalance(100);//余额加100account.UpdateBalance(-50);//余额减50}}
}
namespace BankAccount{// 银行帐户class BankAccount{// 帐户余额private double balance = 0; //--观察者关心的状态-数据//用到的通知操作对象--此处与这些具体类产生耦合Email email = new Email();Mobile mobile = new Mobile();// 存入/取出--调整余额// <param name="val"></param>public void UpdateBalance(double val){balance += val;//--修改后必须通知观察者,在此调用观察者的方法(各不相同)进行处理,此处耦合度较高//更不能将处理过程的代码在此处实现email.SendEMail("user@163.com", balance); mobile.SendMessage("1111111111", balance);}}
}
namespace BankAccount{// 帐户余额发生变化时,发送Email通知用户class Email{/// 发送Email通知操作/// <param name="address">用户邮件地址</param>/// <param name="val">余额数值</param>public void SendEMail(string address, double val){Console.WriteLine("发送邮件到{0}, 余额为{1}.", address, val);}//其他操作相关的属性和方法}
}
namespace BankAccount{/// 帐户余额发生变化时,通过手机发送短信通知用户class Mobile{public void SendMessage(string phone_number, double val){Console.WriteLine("发送短信至手机{0},余额为{1}.", phone_number, val);}//其他操作相关的属性和方法}
}

ObserverBankAccount示例代码

在这里插入图片描述

namespace ObserverBankAccount{class Program{static void Main(string[] args){//创建数据服务对象,因为后面要调用的UpdateBalance()方法在具体类中,此处定义不能使用抽象主题类BankAccount account = new BankAccount();//创建观察者对象,后面没有使用Email和Mobile的特殊方法,所以此处使用抽象观察者来定义AccountUpdated email = new Email("myemail@163.com");AccountUpdated mobile = new Mobile("12345678900");//注册观察者account.AddObserver(email);account.AddObserver(mobile);//改变数据-->自动通知所有的观察者account.UpdateBalance(100);//取消一个观察者account.RemoveObserver(mobile);Console.WriteLine("\n\n删除手机短信观察者后...");//再次改变数据-->取消的观察者将不能收到数据更新account.UpdateBalance(-50);Console.Read();}}
}
namespace ObserverBankAccount{    // Observer--抽象观察者接口public interface AccountUpdated{// 观察者接收/处理通知的方法// <param name="val">帐户余额</param>void BalanceUpdated(double val);}
}
namespace ObserverBankAccount{   /// 具体观察者--帐户余额发生变化时,发送Email通知用户    class Email:AccountUpdated{        // 接收邮件通知的E-Mail地址 private string EmailAddress;public Email(string address){EmailAddress = address;}// 发送Email通知操作       // <param name="val">余额数值</param>public void BalanceUpdated(double val){Console.WriteLine("发送邮件到{0}, 余额为{1}.", EmailAddress, val);}//其他操作相关的属性和方法}
}
namespace ObserverBankAccount{    // 具体观察者--帐户余额发生变化时,通过手机发送短信通知用户   class Mobile:AccountUpdated{ /// 接收短信通知的电话号码    private string PhoneNumber;public Mobile(string phone){PhoneNumber = phone;}public void BalanceUpdated(double val){Console.WriteLine("发送短信至手机{0},余额为{1}.", PhoneNumber, val);}//其他操作相关的属性和方法}
}
namespace ObserverBankAccount{   // 抽象主题    abstract class Subject{        /// 观察者列表  List<AccountUpdated> observers = new List<AccountUpdated>();/// 添加一个观察者  /// <param name="obs"></param>public void AddObserver(AccountUpdated obs){observers.Add(obs);}/// 删除一个已有的观察者    /// <param name="obs"></param>public void RemoveObserver(AccountUpdated obs){observers.Remove(obs);}/// 通知所有的观察者--数据已经更新-->具体的数据处理操作由各个观察者自己处理/// <param name="val"></param>protected virtual void Notify(double val){foreach (AccountUpdated obs in observers)obs.BalanceUpdated(val);}}
}
namespace ObserverBankAccount{    /// ConcreteSubject具体主题--银行帐户    class BankAccount:Subject{        /// 帐户余额--subjectState       private double balance=0;/// 存入/取出--调整余额        /// <param name="val"></param>public void UpdateBalance(double val){balance += val;Notify(balance); //调用父类的方法, 通知所有的观察者--〉余额改变了!}}
}

3.2 示例二

在某多人联机对战游戏中,多个玩家可以加入同一战队组成联盟,当战队中某一成员受到敌人攻击时,将给所有盟友发送通知,盟友收到通知后将作出响应。
现使用观察者模式设计并实现该过程,以实现战队成员之间的联动。
实现了主题对象与观察者,观察者之间的多向沟通

示例代码:

namespace ObserverSample{/// 抽象指挥中心--抽象目标类abstract class AllyControlCenter{//战队名称protected string allyName; //定义一个集合用于存储战队成员--观察者列表protected List<IObserver> players = new List<IObserver>(); public void SetAllyName(string allyName){this.allyName = allyName;}public string GetAllyName(){return this.allyName;}//注册方法--加入观察者--具体方法public void Join(IObserver obs) {Console.WriteLine("{0}加入{1}战队!", obs.Name, this.allyName);players.Add(obs);}//注销方法--删除观察者--具体方法public void Quit(IObserver obs) {Console.WriteLine("{0}退出{1}战队!", obs.Name, this.allyName);players.Remove(obs);}//声明抽象通知方法--通常通知方法在父类中实现,但是具体数据改动和通知方法的调用在子类中实现public abstract void NotifyObserver(string name);}
}
namespace ObserverSample{/// 具体指挥中心--具体目标类class ConcreteAllyControlCenter : AllyControlCenter{public ConcreteAllyControlCenter(string allyName) {Console.WriteLine("{0}战队组建成功!", allyName);Console.WriteLine("----------------------------");this.allyName = allyName;}//实现通知方法,此处的通知方法由观察者调用public override void NotifyObserver(string name) {Console.WriteLine("{0}战队紧急通知,盟友{1}遭受敌人攻击!", this.allyName, name);//遍历观察者集合,调用每一个盟友(自己除外)的支援方法foreach(object obs in players) {if (!((IObserver)obs).Name.Equals(name)){ // 自己除外((IObserver)obs).Help();}}		}}
}
namespace ObserverSample{/// 抽象观察者interface IObserver{string Name{get;set;}//声明支援盟友的响应方法--响应主题对象的通知-->被主题对象调用,用于接收其他队友被攻击的通知void Help();//声明遭受攻击方法--调用后转去主题对象,用于向其他所有队友发出通知void BeAttacked(AllyControlCenter acc); }
}
namespace ObserverSample{/// 具体观察者class Player : IObserver{private string name;public Player(string name){this.name = name;}public string Name{get { return name; }set { name = value; }}//支援盟友方法的实现public void Help(){Console.WriteLine("坚持住,{0}来救你!", this.name);}//遭受攻击方法的实现,当遭受攻击时将调用战队控制中心类的通知方法NotifyObserver()来通知盟友//需要引用具体主题对象public void BeAttacked(AllyControlCenter acc) {Console.WriteLine("{0}被攻击!", this.name);acc.NotifyObserver(name);		}}
}
namespace ObserverSample{class Program{static void Main(string[] args){//定义观察目标对象AllyControlCenter acc;acc = new ConcreteAllyControlCenter("金庸群侠");//定义四个观察者对象IObserver player1, player2, player3, player4;player1 = new Player("杨过");acc.Join(player1);player2 = new Player("令狐冲");acc.Join(player2);player3 = new Player("张无忌");acc.Join(player3);player4 = new Player("段誉");acc.Join(player4);//某成员遭受攻击player1.BeAttacked(acc);Console.Read();}}
}
执行结果:
金庸群侠战队组建成功!
----------------------------
杨过加入金庸群侠战队!
令狐冲加入金庸群侠战队!
张无忌加入金庸群侠战队!
段誉加入金庸群侠战队!
杨过被攻击!
金庸群侠战队紧急通知,盟友杨过遭受敌人攻击!
坚持住,令狐冲来救你!
坚持住,张无忌来救你!
坚持住,段誉来救你!

3.3 C#实现观察者模式

  • C# 中的委托(Delegate)类似于 C 或 C++ 中函数的指针。委托是存有对某个函数的引用的一种引用类型变量。引用可在运行时被改变。
  • 委托特别用于实现事件和回调函数。所有的委托(Delegate)都派生自 System.Delegate 类。
    委托就是一种引用方法的类型。可以看做是函数的抽象,是函数的“类”,委托的实例将代表一个具体的函数。
    一个委托,可以搭载多个函数(多播),所有函数可以被依次唤起;委托对象所搭载的函数并不需要属于同一个类。

语法:delegate

例如:public delegate int MyDelegate (string s);
上例用于引用任何一个带有一个单一的 string 参数的函数,并返回一个 int 类型变量。

  • 使用委托的前提条件:
    委托对象所搭载的所有函数必须有相同的原型和形式,也就是拥有相同的参数列表和返回值类型
    委托可以看作是一个稳定的接口(充当抽象观察者角色)。
  • 示例: DelegateObserver
namespace DelegateObserver{class Program{static void Main(string[] args){//创建数据服务对象和观察者对象BankAccount account = new BankAccount();Email email = new Email("myemail@163.com");Mobile mobile = new Mobile("1234567890");//添加观察者--由客户端程序自主添加,各方法之间没有耦合,且允许方法的名称不同account.Observers += email.SendEMail;account.Observers += mobile.SendMessage;//数据服务对象的更新方法中调用通知观察者account.UpdateBalance(100);account.Observers -= email.SendEMail;//删除观察者Console.WriteLine("\n\n删除E-Mail通知以后:");account.UpdateBalance(-50);Console.Read();}}
}
namespace DelegateObserver{/// 委托定义--指向处理余额通知的方法--委托相当于一个“类定义”--“类”中仅有一个方法--抽象观察者/// <param name="val">余额值</param>public delegate void AccountChangedHandler(double val);/// 银行帐户--具体主题与抽象主题合并class BankAccount{/// 用于存储观察者方法的委托对象--此处使用的是多播委托(MulticastDelegate)--具体观察者列表public AccountChangedHandler Observers = null; //初始值为null,需要客户端程序用"="或"+="来添加/// 帐户余额private double balance=0;/// 存入/取出--调整余额/// <param name="val">对帐户加减的金额</param>public void UpdateBalance(double val){balance += val;if (Observers != null) //此处通过委托依次调用所有的观察者方法Observers(balance);}}
}
namespace DelegateObserver{/// 帐户余额发生变化时,发送Email通知用户class Email{/// 接收通知的邮件地址private string EMailAddress;public Email(string address){EMailAddress = address;}/// 发送Email通知操作/// <param name="val">余额数值</param>public void SendEMail(double val){Console.WriteLine("发送邮件到{0}, 余额为{1}.", EMailAddress, val);}//其他操作相关的属性和方法}
}
namespace DelegateObserver{/// 帐户余额发生变化时,通过手机发送短信通知用户class Mobile{/// 接收短信通知的手机号码private string PhoneNumber;public Mobile(string phone_number){PhoneNumber = phone_number;}/// 发送短信通知/// <param name="val">余额数值</param>public void SendMessage(double val){Console.WriteLine("发送短信至手机{0},余额为{1}.", PhoneNumber, val);}//其他操作相关的属性和方法}
}

.NET中的事件处理模型是观察者模式的一种变形,它与观察者模式的实现原理本质上是一致的:
事件源对象充当主题角色,委托充当抽象观察者角色,事件处理对象充当具体观察者角色。如果事件源对象的某个事件触发,则调用事件处理对象中的事件处理程序来对事件进行处理。

示例:C#中的事件模拟ObserverExtend

示例代码:

namespace ObserverExtend{//定义一个委托--抽象观察者public delegate void UserInput(object sender, EventArgs e);/// 服务方--事件的发行者-Subject(抽象主题和具体主题合二为一)public class EventTest{//定义一个此委托类型的事件--观察者列表public event UserInput OnUserInput;//模拟事件触发,当输入“0”时引发事件public void Method(){bool flag = false;Console.WriteLine("请输入数字:");while (!flag){  //--类似Windows的消息循环if (Console.ReadLine() == "0"){OnUserInput(this, new EventArgs());}}}}
}
namespace ObserverExtend{/// 客户端程序--具体观察者--同一个类可以包含多个观察者public class Program{public Program(EventTest test){//注册事件或订阅事件--添加观察者test.OnUserInput += new UserInput(Handler);test.OnUserInput += new UserInput(HandlerMore);//注销事件或取消订阅--取消观察者//test.OnUserInput -= new UserInput(Handler);}/// 客户端测试函数-1--响应主题变化(通知)的方法--具体观察者/// <param name="sender"></param>/// <param name="e"></param>public void Handler(object sender, EventArgs e){Console.WriteLine("数据输入结束!");}/// 客户端测试函数-2--响应主题变化(通知)的方法--具体观察者/// <param name="sender"></param>/// <param name="e"></param>public void HandlerMore(object sender, EventArgs e){Console.WriteLine("真的结束了!");}static void Main(string[] args){EventTest test = new EventTest();Program program = new Program(test);test.Method();}}
}

4. 观察者模式的总结

  • 观察者模式使用面向对象的抽象,使得我们可以独立地改变数据服务者观察者,从而使二者之间的依赖关系达到松耦合
  • 目标发送通知时,无需指定观察者,通知(可以携带通知信息作为参数)会自动传播。观察者自己决定是否需要订阅通知,目标对象对此一无所知。
  • 在C#的实现方式中,委托定义充当了抽象的Observer接口,而管理委托对象的对象充当了目标对象。委托是比抽象Observer接口更为松耦合的设计----它不要求具体方法的名称相同,且同一个类可以充当多个观察者。

需要注意的问题:

  • 如果一个被观察者对象(目标对象Subject)有很多直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间
  • 如果在被观察者之间有循环依赖的话,被观察者会触发它们之间进行循环调用,导致系统崩溃。在使用观察者模式时要特别注意这一点。
  • 虽然观察者模式可以随时使观察者知道所观察的对象发生了变化,但是观察者模式没有相应的机制使观察者知道所观察的对象是怎么发生变化的。
查看全文
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

相关文章

  1. 推荐手机用WebDAV秒变云盘

    我之前一直是想把各种设备联起来用,终于用了WebDAV实现。我还多了解一些软件,害怕现在用的软件收费。 有些人肯定会问 WebDAV是什么? WebDAV就像一个存储服务,各种应用都可以连接到它,允许应用直接访问我们的云盘内容,对其进行读写操作。我们可以网络服务比作一只章鱼,云…...

    2024/4/9 1:55:57
  2. K12辅导机构信息化建设之《助学宝错题本云平台》介绍

    ----------------------------联系电话:15801691656 QQ:6822158---------------------------- 《助学宝错题本云平台》是一款面向K12校外辅导机构教学工作开发的软件平台,涵盖了机构教研工作的方方面面。该平台针对辅导机构授课效果巩固难、学生成绩提高难的痛点,以错题为牵…...

    2024/4/23 16:17:34
  3. 软件工程复习(一):软件工程学概述

    软件工程复习(一):软件工程学概述软件危机软件与程序(二者的区别:**程序是软件的一部分**)软件发展过程(四个阶段)软件的特征软件危机定义原因消除途径软件工程两个定义(重点)本质特性基本原理软件工程方法学(软工技术方面)软件生命周期(重要)基本流程软件定义软…...

    2024/4/21 23:12:50
  4. 视频聊天app源码模型处理及切片缓存优化

    使用超图 WebGL API 时需要将三维模型处理成S3M文件(超图三维数据标准),S3M文件的大小影响着在前端加载模型的体验。 S3M过大,使得前端请求S3M文件时需要更多的下载时间,占用请求队列,并且S3M文件过大,也说明了顶点或三角面多,导致渲染速度降低。 按照超图的文档,应尽量…...

    2024/4/27 21:19:36
  5. Python带你玩澳门赌场游戏

    Python带你玩澳门赌场游戏 1.开发环境:pycharm 2.完整代码: import random print(**40) print(欢迎进入澳门赌场) print(**40) username =input(请输入游戏名称) money =0 answer =input(确定进入游戏吗(Y/N)?) if answer==Y:while money<2:n =int(input(金币不足,请充…...

    2024/4/9 1:55:53
  6. 【遇见offer】微软专场直播强势来袭!快来领取你的专属面试福利吧~

    千呼万唤始出来,微软的直播招聘专场终于来啦!这次微软公司可是诚意满满,在四座大城市开放了三十余个正式职位,等你来投递。 不是什么时候都有机会进微软的哦!如果你有一颗近距离体验大厂工作的心,就快点把握机会,预约直播吧!(当然你可以在直播中看到微软的幕后大佬们!…...

    2024/4/9 1:55:52
  7. java/php/net/python中医体质的社区居民健康管理设计

    本系统带文档lw万字以上+答辩PPT+查重 如果这个题目不合适,可以去我上传的资源里面找题目,找不到的话,评论留下题目,或者站内私信我, 有时间看到机会给您发系统体系结构 中医体质的社区居民健康管理的结构图4-1所示:图4-1 系统结构登录系统结构图,如图4-2所示:图4-2 登…...

    2024/4/12 17:09:00
  8. Centos7安装LNMP环境

    Centos7安装LNMP环境 Centos7安装LNMP环境 我对于Centos7是基于阿里云云服务器进行一个部署的,然后我的系统是7.3的版本,就linux系统来说安装一个LNMP的环境,毕竟很多人可能有很多的坑。 修改yum源 [root@localhost ~]# rpm -Uvh https://dl.fedoraproject.org/pub/epel/epe…...

    2024/4/9 1:55:51
  9. 分布式架构知识体系

    1.问题1、何为分布式何为微服务?2、为什么需要分布式?3、分布式核心理论基础,节点、网络、时间、顺序,一致性?4、分布式是系统有哪些设计模式?5、分布式有哪些类型?6、如何实现分布式?2.关键词节点,时间,一致性,CAP,ACID,BASE,P2P,机器伸缩,网络变更,负载均衡…...

    2024/4/15 8:55:17
  10. 9.Pandas练习:美国个州的统计数据

    Pandas练习:美国各州的统计数据 前面讲解了那么多Pandas中的内容,下面将结合真实的数据集来进行Pandas数据分析练习, 我们这个练习只进行最简单的分析,目的是找出人口密度最高和最稀疏的州 数据集为美国各州的统计数据,包括每个州的缩写,人口信息和面积 数据集原地址为原书作者…...

    2024/4/23 5:32:24
  11. 简述RAKsmart香港服务器的的优势

    当今,我们处于互联网无处不在的时代,企业的发展更是少不了互联网的帮助,那么互联网之所以能够稳定的运行供我们使用其根本原因是因为有强大的服务器作为支撑。现在很多中小型企业以及外贸企业建站都会选择一些主机商进行服务器租用或者托管,其中RAKsmart香港服务器受到很多…...

    2024/4/8 21:58:00
  12. 这4款Python开发工具,帮你快速提升工作效率!

    “工欲善其事,必先利其器”,如果说编程是程序员的手艺,那么IDE就是程序员的吃饭家伙了。一个好的工具能让起到事半功倍的效果!但IDE并非功能越多越好,因为更多的功能往往意味着更大的复杂度,这不但会分散程序员本来的精力,而且还可能带来更多的错误。只要基本功能满足需…...

    2024/4/8 21:57:58
  13. 高德智慧景区随身听播放器框架设计与实现

    简介:我们开发选型并没有采用传统的TTS技术(由文本内容生成机器语音),而是采用了更加通用音频格式(比如mp3),作为讲解的音频输入源,方便讲解者进行二次创作。本文将简单回顾高德智慧景区随身听播放器的框架设计与实现。一、背景“远看山有色,近听水‘有’声”,景区语音…...

    2024/4/15 0:42:18
  14. 学习笔记(3):软件设计是怎样炼成的?-优秀设计从分析需求开始

    立即学习:https://edu.csdn.net/course/play/1058/15636?utm_source=blogtoedu需求分析考虑点:1.什么人会使用这个系统2.不同的人将会使用这个系统的什么功能3.还有哪些不确定或不具体的需求点4.哪些需求对技术提出了怎样的需求【需求和技术怎么关联起来】...

    2024/4/25 19:27:17
  15. python 爬虫爬取中国新闻网

    中国新闻网的新闻种类较多、而且新闻比较丰富,如果需要获取大量新闻的话,中国新闻网是个不错的选择。 界面是这样的:从url不难发现,改变日期就能获取不同日期的新闻那么,正文开始。。。 1、获取某一个链接的新闻详情页信息 import requests from bs4 import BeautifulSoup…...

    2024/4/24 0:16:55
  16. 哈尔滨工业大学计算学院保研预推免

    哈尔滨工业大学计算机学院预推免整体流程逻辑面试科技创新与项目经验专业课知识沟通能力总结 又到了一年一度的保研的时间,自己参加了一些夏令营和预推免,在这里记录一下哈工大计算机学院的预推免流程以及一些经验,分享给需要的人,希望可以帮到你。 整体流程 在2019年7月份…...

    2024/4/20 0:09:23
  17. 黑马程序员Java 全课程目录【999集】

    看过视频中的高级部分,老师讲的不错 。 视频链接 : https://www.bilibili.com/video/BV1uJ411k7wy下面是 999集全课程目录,tips : [ ctrl +f ]序号 视频名称1 01_Java语言发展史2 02_计算机进制转换3 03_计算机存储单元4 04_命令提示符_基本介绍5 05_命令提示符_常用命令…...

    2024/4/14 13:32:04
  18. 数据结构与算法之美:18 | 哈希算法(上):如何防止数据库中的用户信息被脱库?

    文章目录什么是哈希算法?应用一:安全加密应用二:唯一标识应用三:数据校验应用四:散列函数解答开篇课后思考 什么是哈希算法? 哈希算法的定义和原理非常简单,基本上一句话就可以概括:将任意长度的二进制值串映射为固定长度的二进制值串,这个映射的规则就是哈希算法,而…...

    2024/4/25 13:44:18
  19. Oracle 又裁员,传 N+6 补偿

    ​整理 | 伍杏玲出品 | 程序人生(ID:coder_life)近日,某社交平台有甲骨文(Oracle)的员工爆料,正在裁员中,N+6 补偿。其实从去年开始,Oracle一直在北京裁员:去年5月7日,甲骨文确认中国区首批裁员900余人,其中超500人来自北京研发中心。而上述N+6的补偿方案也可能是真…...

    2024/4/9 1:55:47
  20. zookeeper的简单介绍

    1.功能 2.特点 3.结构数据 4.简单使用 5.选举机制 6.监听器原理 7.client像zookeeper写数据流程一 功能 1:文件系统,存储数据 2:通知,当数据发生变化,zookeeper集群会通知订阅的单位 二 特点 1:角色:leader和follower 2:leader进行投票,更新系统状态 3:follower接收客…...

    2024/4/22 7:35:16

最新文章

  1. 【AI】一文介绍索引增强生成RAG的原理和结构

    今天向大家介绍一下关于RAG的一些知识和经验。 这里说的RAG可以理解为目前针对企业知识库问答等AI应用场景的解决方案,这个场景就是利用自然语言大模型LLM与用户自有的文件进行对话的能力。 【RAG的优势】 首先,讲一讲RAG的优势特征。 如果把AI想象成一个待上岗的人类助手,…...

    2024/4/28 1:23:45
  2. 梯度消失和梯度爆炸的一些处理方法

    在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言&#xff0c;在此感激不尽。 权重和梯度的更新公式如下&#xff1a; w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...

    2024/3/20 10:50:27
  3. vue项目引入微信sdk: npm install weixin-js-sdk --save报错

    网上查到要用淘宝的镜像 同事告知旧 域名&#xff1a;https://registry.npm.taobao.org/已经不能再使用 使用 npm config set registry http://registry.npmmirror.com...

    2024/4/22 1:20:24
  4. 包子凑数(蓝桥杯,闫氏DP分析法)

    题目描述&#xff1a; 小明几乎每天早晨都会在一家包子铺吃早餐。 他发现这家包子铺有 N 种蒸笼&#xff0c;其中第 i 种蒸笼恰好能放 Ai 个包子。 每种蒸笼都有非常多笼&#xff0c;可以认为是无限笼。 每当有顾客想买 X 个包子&#xff0c;卖包子的大叔就会迅速选出若干笼…...

    2024/4/27 13:26:04
  5. 416. 分割等和子集问题(动态规划)

    题目 题解 class Solution:def canPartition(self, nums: List[int]) -> bool:# badcaseif not nums:return True# 不能被2整除if sum(nums) % 2 ! 0:return False# 状态定义&#xff1a;dp[i][j]表示当背包容量为j&#xff0c;用前i个物品是否正好可以将背包填满&#xff…...

    2024/4/27 1:53:53
  6. 【Java】ExcelWriter自适应宽度工具类(支持中文)

    工具类 import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet;/*** Excel工具类** author xiaoming* date 2023/11/17 10:40*/ public class ExcelUti…...

    2024/4/27 3:39:11
  7. Spring cloud负载均衡@LoadBalanced LoadBalancerClient

    LoadBalance vs Ribbon 由于Spring cloud2020之后移除了Ribbon&#xff0c;直接使用Spring Cloud LoadBalancer作为客户端负载均衡组件&#xff0c;我们讨论Spring负载均衡以Spring Cloud2020之后版本为主&#xff0c;学习Spring Cloud LoadBalance&#xff0c;暂不讨论Ribbon…...

    2024/4/27 12:24:35
  8. TSINGSEE青犀AI智能分析+视频监控工业园区周界安全防范方案

    一、背景需求分析 在工业产业园、化工园或生产制造园区中&#xff0c;周界防范意义重大&#xff0c;对园区的安全起到重要的作用。常规的安防方式是采用人员巡查&#xff0c;人力投入成本大而且效率低。周界一旦被破坏或入侵&#xff0c;会影响园区人员和资产安全&#xff0c;…...

    2024/4/27 12:24:46
  9. VB.net WebBrowser网页元素抓取分析方法

    在用WebBrowser编程实现网页操作自动化时&#xff0c;常要分析网页Html&#xff0c;例如网页在加载数据时&#xff0c;常会显示“系统处理中&#xff0c;请稍候..”&#xff0c;我们需要在数据加载完成后才能继续下一步操作&#xff0c;如何抓取这个信息的网页html元素变化&…...

    2024/4/27 3:39:08
  10. 【Objective-C】Objective-C汇总

    方法定义 参考&#xff1a;https://www.yiibai.com/objective_c/objective_c_functions.html Objective-C编程语言中方法定义的一般形式如下 - (return_type) method_name:( argumentType1 )argumentName1 joiningArgument2:( argumentType2 )argumentName2 ... joiningArgu…...

    2024/4/27 3:39:07
  11. 【洛谷算法题】P5713-洛谷团队系统【入门2分支结构】

    &#x1f468;‍&#x1f4bb;博客主页&#xff1a;花无缺 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 花无缺 原创 收录于专栏 【洛谷算法题】 文章目录 【洛谷算法题】P5713-洛谷团队系统【入门2分支结构】&#x1f30f;题目描述&#x1f30f;输入格…...

    2024/4/27 3:39:07
  12. 【ES6.0】- 扩展运算符(...)

    【ES6.0】- 扩展运算符... 文章目录 【ES6.0】- 扩展运算符...一、概述二、拷贝数组对象三、合并操作四、参数传递五、数组去重六、字符串转字符数组七、NodeList转数组八、解构变量九、打印日志十、总结 一、概述 **扩展运算符(...)**允许一个表达式在期望多个参数&#xff0…...

    2024/4/27 12:44:49
  13. 摩根看好的前智能硬件头部品牌双11交易数据极度异常!——是模式创新还是饮鸩止渴?

    文 | 螳螂观察 作者 | 李燃 双11狂欢已落下帷幕&#xff0c;各大品牌纷纷晒出优异的成绩单&#xff0c;摩根士丹利投资的智能硬件头部品牌凯迪仕也不例外。然而有爆料称&#xff0c;在自媒体平台发布霸榜各大榜单喜讯的凯迪仕智能锁&#xff0c;多个平台数据都表现出极度异常…...

    2024/4/27 21:08:20
  14. Go语言常用命令详解(二)

    文章目录 前言常用命令go bug示例参数说明 go doc示例参数说明 go env示例 go fix示例 go fmt示例 go generate示例 总结写在最后 前言 接着上一篇继续介绍Go语言的常用命令 常用命令 以下是一些常用的Go命令&#xff0c;这些命令可以帮助您在Go开发中进行编译、测试、运行和…...

    2024/4/26 22:35:59
  15. 用欧拉路径判断图同构推出reverse合法性:1116T4

    http://cplusoj.com/d/senior/p/SS231116D 假设我们要把 a a a 变成 b b b&#xff0c;我们在 a i a_i ai​ 和 a i 1 a_{i1} ai1​ 之间连边&#xff0c; b b b 同理&#xff0c;则 a a a 能变成 b b b 的充要条件是两图 A , B A,B A,B 同构。 必要性显然&#xff0…...

    2024/4/27 18:40:35
  16. 【NGINX--1】基础知识

    1、在 Debian/Ubuntu 上安装 NGINX 在 Debian 或 Ubuntu 机器上安装 NGINX 开源版。 更新已配置源的软件包信息&#xff0c;并安装一些有助于配置官方 NGINX 软件包仓库的软件包&#xff1a; apt-get update apt install -y curl gnupg2 ca-certificates lsb-release debian-…...

    2024/4/27 3:39:03
  17. Hive默认分割符、存储格式与数据压缩

    目录 1、Hive默认分割符2、Hive存储格式3、Hive数据压缩 1、Hive默认分割符 Hive创建表时指定的行受限&#xff08;ROW FORMAT&#xff09;配置标准HQL为&#xff1a; ... ROW FORMAT DELIMITED FIELDS TERMINATED BY \u0001 COLLECTION ITEMS TERMINATED BY , MAP KEYS TERMI…...

    2024/4/27 13:52:15
  18. 【论文阅读】MAG:一种用于航天器遥测数据中有效异常检测的新方法

    文章目录 摘要1 引言2 问题描述3 拟议框架4 所提出方法的细节A.数据预处理B.变量相关分析C.MAG模型D.异常分数 5 实验A.数据集和性能指标B.实验设置与平台C.结果和比较 6 结论 摘要 异常检测是保证航天器稳定性的关键。在航天器运行过程中&#xff0c;传感器和控制器产生大量周…...

    2024/4/27 13:38:13
  19. --max-old-space-size=8192报错

    vue项目运行时&#xff0c;如果经常运行慢&#xff0c;崩溃停止服务&#xff0c;报如下错误 FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory 因为在 Node 中&#xff0c;通过JavaScript使用内存时只能使用部分内存&#xff08;64位系统&…...

    2024/4/27 1:03:20
  20. 基于深度学习的恶意软件检测

    恶意软件是指恶意软件犯罪者用来感染个人计算机或整个组织的网络的软件。 它利用目标系统漏洞&#xff0c;例如可以被劫持的合法软件&#xff08;例如浏览器或 Web 应用程序插件&#xff09;中的错误。 恶意软件渗透可能会造成灾难性的后果&#xff0c;包括数据被盗、勒索或网…...

    2024/4/27 3:22:12
  21. JS原型对象prototype

    让我简单的为大家介绍一下原型对象prototype吧&#xff01; 使用原型实现方法共享 1.构造函数通过原型分配的函数是所有对象所 共享的。 2.JavaScript 规定&#xff0c;每一个构造函数都有一个 prototype 属性&#xff0c;指向另一个对象&#xff0c;所以我们也称为原型对象…...

    2024/4/27 22:51:49
  22. C++中只能有一个实例的单例类

    C中只能有一个实例的单例类 前面讨论的 President 类很不错&#xff0c;但存在一个缺陷&#xff1a;无法禁止通过实例化多个对象来创建多名总统&#xff1a; President One, Two, Three; 由于复制构造函数是私有的&#xff0c;其中每个对象都是不可复制的&#xff0c;但您的目…...

    2024/4/27 3:39:00
  23. python django 小程序图书借阅源码

    开发工具&#xff1a; PyCharm&#xff0c;mysql5.7&#xff0c;微信开发者工具 技术说明&#xff1a; python django html 小程序 功能介绍&#xff1a; 用户端&#xff1a; 登录注册&#xff08;含授权登录&#xff09; 首页显示搜索图书&#xff0c;轮播图&#xff0…...

    2024/4/26 23:53:24
  24. 电子学会C/C++编程等级考试2022年03月(一级)真题解析

    C/C++等级考试(1~8级)全部真题・点这里 第1题:双精度浮点数的输入输出 输入一个双精度浮点数,保留8位小数,输出这个浮点数。 时间限制:1000 内存限制:65536输入 只有一行,一个双精度浮点数。输出 一行,保留8位小数的浮点数。样例输入 3.1415926535798932样例输出 3.1…...

    2024/4/27 20:28:35
  25. 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...

    解析如下&#xff1a;1、长按电脑电源键直至关机&#xff0c;然后再按一次电源健重启电脑&#xff0c;按F8健进入安全模式2、安全模式下进入Windows系统桌面后&#xff0c;按住“winR”打开运行窗口&#xff0c;输入“services.msc”打开服务设置3、在服务界面&#xff0c;选中…...

    2022/11/19 21:17:18
  26. 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。

    %读入6幅图像&#xff08;每一幅图像的大小是564*564&#xff09; f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...

    2022/11/19 21:17:16
  27. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...

    win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面&#xff0c;在等待界面中我们需要等待操作结束才能关机&#xff0c;虽然这比较麻烦&#xff0c;但是对系统进行配置和升级…...

    2022/11/19 21:17:15
  28. 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...

    有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows&#xff0c;请勿关闭计算机”的提示&#xff0c;要过很久才能进入系统&#xff0c;有的用户甚至几个小时也无法进入&#xff0c;下面就教大家这个问题的解决方法。第一种方法&#xff1a;我们首先在左下角的“开始…...

    2022/11/19 21:17:14
  29. win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...

    置信有很多用户都跟小编一样遇到过这样的问题&#xff0c;电脑时发现开机屏幕显现“正在配置Windows Update&#xff0c;请勿关机”(如下图所示)&#xff0c;而且还需求等大约5分钟才干进入系统。这是怎样回事呢&#xff1f;一切都是正常操作的&#xff0c;为什么开时机呈现“正…...

    2022/11/19 21:17:13
  30. 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...

    Win7系统开机启动时总是出现“配置Windows请勿关机”的提示&#xff0c;没过几秒后电脑自动重启&#xff0c;每次开机都这样无法进入系统&#xff0c;此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一&#xff1a;开机按下F8&#xff0c;在出现的Windows高级启动选…...

    2022/11/19 21:17:12
  31. 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...

    有不少windows10系统用户反映说碰到这样一个情况&#xff0c;就是电脑提示正在准备windows请勿关闭计算机&#xff0c;碰到这样的问题该怎么解决呢&#xff0c;现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法&#xff1a;1、2、依次…...

    2022/11/19 21:17:11
  32. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...

    今天和大家分享一下win7系统重装了Win7旗舰版系统后&#xff0c;每次关机的时候桌面上都会显示一个“配置Windows Update的界面&#xff0c;提示请勿关闭计算机”&#xff0c;每次停留好几分钟才能正常关机&#xff0c;导致什么情况引起的呢&#xff1f;出现配置Windows Update…...

    2022/11/19 21:17:10
  33. 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...

    只能是等着&#xff0c;别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚&#xff0c;只能是考虑备份数据后重装系统了。解决来方案一&#xff1a;管理员运行cmd&#xff1a;net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...

    2022/11/19 21:17:09
  34. 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?

    原标题&#xff1a;电脑提示“配置Windows Update请勿关闭计算机”怎么办&#xff1f;win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢&#xff1f;一般的方…...

    2022/11/19 21:17:08
  35. 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...

    关机提示 windows7 正在配置windows 请勿关闭计算机 &#xff0c;然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;关机提示 windows7 正在配…...

    2022/11/19 21:17:05
  36. 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...

    钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...

    2022/11/19 21:17:05
  37. 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...

    前几天班里有位学生电脑(windows 7系统)出问题了&#xff0c;具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面&#xff0c;长时间没反应&#xff0c;无法进入系统。这个问题原来帮其他同学也解决过&#xff0c;网上搜了不少资料&#x…...

    2022/11/19 21:17:04
  38. 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...

    本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法&#xff0c;并在最后教给你1种保护系统安全的好方法&#xff0c;一起来看看&#xff01;电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中&#xff0c;添加了1个新功能在“磁…...

    2022/11/19 21:17:03
  39. 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...

    许多用户在长期不使用电脑的时候&#xff0c;开启电脑发现电脑显示&#xff1a;配置windows更新失败&#xff0c;正在还原更改&#xff0c;请勿关闭计算机。。.这要怎么办呢&#xff1f;下面小编就带着大家一起看看吧&#xff01;如果能够正常进入系统&#xff0c;建议您暂时移…...

    2022/11/19 21:17:02
  40. 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...

    配置windows update失败 还原更改 请勿关闭计算机&#xff0c;电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;配置windows update失败 还原更改 请勿关闭计算机&#x…...

    2022/11/19 21:17:01
  41. 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...

    不知道大家有没有遇到过这样的一个问题&#xff0c;就是我们的win7系统在关机的时候&#xff0c;总是喜欢显示“准备配置windows&#xff0c;请勿关机”这样的一个页面&#xff0c;没有什么大碍&#xff0c;但是如果一直等着的话就要两个小时甚至更久都关不了机&#xff0c;非常…...

    2022/11/19 21:17:00
  42. 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...

    当电脑出现正在准备配置windows请勿关闭计算机时&#xff0c;一般是您正对windows进行升级&#xff0c;但是这个要是长时间没有反应&#xff0c;我们不能再傻等下去了。可能是电脑出了别的问题了&#xff0c;来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...

    2022/11/19 21:16:59
  43. 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...

    我们使用电脑的过程中有时会遇到这种情况&#xff0c;当我们打开电脑之后&#xff0c;发现一直停留在一个界面&#xff1a;“配置Windows Update失败&#xff0c;还原更改请勿关闭计算机”&#xff0c;等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢&#xff0…...

    2022/11/19 21:16:58
  44. 如何在iPhone上关闭“请勿打扰”

    Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...

    2022/11/19 21:16:57