C#知识点-19(七大设计原则、通过反射破坏单例设计模式、基于Task的异步编程模型、Winform中的异步)

通过反射,破坏单例设计模式

    internal class Program{static void Main(string[] args){//懒汉式//for (int i = 0; i < 10; i++)//{//    Thread th = new Thread(() => {//        LazyManClass lazyManClass = LazyManClass.GetLazyMan();//    });//    th.Start();//}//通过反射,破解单例设计模式//Assembly(获取要反射的程序集DLL--->Class Method INterface Delegate Event。。。。) TypeType type = typeof(LazyManClass);ConstructorInfo[] ci = type.GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance);//正常的调用静态方法创建对象//LazyManClass lazyManClass = LazyManClass.GetLazyMan();//ci[0]就是私有的构造函数//通过调用私有的构造函数,跳过判断,直接创建对象LazyManClass l1 = (LazyManClass)ci[0].Invoke(null);//在第二次创建对象之前,获取b的值,重新修改为falseFieldInfo fi = type.GetField("b", BindingFlags.NonPublic | BindingFlags.Static);//修改字段的值//参数1:要修改的字段//参数2:修改后的值fi.SetValue(fi, false);LazyManClass l2 = (LazyManClass)ci[0].Invoke(null);fi.SetValue(fi, false);LazyManClass l3 = (LazyManClass)ci[0].Invoke(null);fi.SetValue(fi, false);LazyManClass l4 = (LazyManClass)ci[0].Invoke(null);Console.WriteLine(l1.GetHashCode());Console.WriteLine(l2.GetHashCode());Console.WriteLine(l3.GetHashCode());Console.WriteLine(l4.GetHashCode());Console.ReadKey();}}class LazyManClass{private LazyManClass(){if (b == false){b = true;}else{throw new Exception("有人破坏单例设计模式!!!!!");}//if (_lazyManClass != null)//{//    throw new Exception("有人破坏单例设计模式!!!!!");//}Console.WriteLine("我被创建了一次");}private static LazyManClass _lazyManClass = null;private static object o = new object();private static bool b = false;public static LazyManClass GetLazyMan(){if (_lazyManClass == null){lock (o){if (_lazyManClass == null){return _lazyManClass = new LazyManClass();}}}return _lazyManClass;}}

基于Task的异步编程模型

    internal class Program{static async Task Main(string[] args){//以同步的方式,开发异步的代码//下载一个网页的数据---->写入到指定的路径下//异步会传染//异步方法的返回值类型必须放到Task<T>中 ,如果没有返回值,则写Task---->void    Task<int> intConsole.WriteLine("Main函数调用异步方法之前的线程" + Thread.CurrentThread.ManagedThreadId);int r = await DownHTML_WriteFile("http://www.taobao.com", @"C:\Users\ThinkPad\Desktop\abcabc.txt");Console.WriteLine("Main函数调用异步方法之后的线程" + Thread.CurrentThread.ManagedThreadId);Console.WriteLine("数据的长度是{0}", r);Task 底层就是线程池//Task task = new Task(() =>//{//    Console.WriteLine("开始了一个任务");//});//task.ContinueWith((t) =>//{//    Console.WriteLine("我是任务1");//    Console.WriteLine(Thread.CurrentThread.ManagedThreadId);//}).ContinueWith((t) =>//{//    Console.WriteLine("我是任务2");//    Console.WriteLine(Thread.CurrentThread.ManagedThreadId);//}).ContinueWith((t) => {//    Console.WriteLine("我是任务3");//    Console.WriteLine(Thread.CurrentThread.ManagedThreadId);//});//task.Start();//Task.Run(() =>//{//    Console.WriteLine("开始了一个任务");//});//Task.Factory.StartNew(() => {//    Console.WriteLine("开始了一个任务");//});//任务:I/O密集型  Input/OutPut------>写入一个文件   读取一个文件  读取一个数据  写入一个数据库 //任务:   计算密集型Console.ReadKey();}//Task:异步执行的任务//async 异步方法 [MehodImp(。。。。。sync....)]//await 等待异步方法执行后的结果static async Task<int> DownHTML_WriteFile(string url, string path){//状态机设计模式WebClient wc = new WebClient();Console.WriteLine("开始异步任务1之前的线程是" + Thread.CurrentThread.ManagedThreadId);//DownloadStringTaskAsync :基于任务的异步方法Task<string> task = wc.DownloadStringTaskAsync(url);string htmlStr = await task;  //等待任务执行---->开启一个新线程----->等待任务的执行Console.WriteLine("开始异步任务1之后的线程是" + Thread.CurrentThread.ManagedThreadId);//Console.WriteLine(htmlStr);using (FileStream fsWrite = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write)){byte[] buffer = Encoding.Default.GetBytes(htmlStr);Console.WriteLine("开始异步任务2之前的线程是" + Thread.CurrentThread.ManagedThreadId);//fsWrite.Write();同步方法await fsWrite.WriteAsync(buffer, 0, buffer.Length); //又开了一个新线程Console.WriteLine("开始异步任务2之后的线程是" + Thread.CurrentThread.ManagedThreadId);}//把数据的长度返回return htmlStr.Length;}}

Winform中的异步

    public partial class Form1 : Form{public Form1(){InitializeComponent();}//EventHandler   void object EventArgs//void:winform中事件的void,不许修改。可以标记为async,但是不能修改。private async void button1_Click(object sender, EventArgs e){int n = await DownHTML_WriteFile("a", "b");}static async Task<int> DownHTML_WriteFile(string url, string path){WebClient wc = new WebClient();Console.WriteLine("开始异步任务1之前的线程是" + Thread.CurrentThread.ManagedThreadId);//DownloadStringTaskAsync :基于任务的异步方法Task<string> task = wc.DownloadStringTaskAsync(url);string htmlStr = await task;  //等待任务执行---->开启一个新线程----->等待任务的执行Console.WriteLine("开始异步任务1之后的线程是" + Thread.CurrentThread.ManagedThreadId);//Console.WriteLine(htmlStr);using (FileStream fsWrite = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write)){byte[] buffer = Encoding.Default.GetBytes(htmlStr);Console.WriteLine("开始异步任务2之前的线程是" + Thread.CurrentThread.ManagedThreadId);//fsWrite.Write();同步方法await fsWrite.WriteAsync(buffer, 0, buffer.Length); //又开了一个新线程Console.WriteLine("开始异步任务2之后的线程是" + Thread.CurrentThread.ManagedThreadId);}//把数据的长度返回return htmlStr.Length;}}

七大设计原则

单一职责原则

应该有且只有一个引起类变更的原因。一个类,只负责一件事

好处:
1、提高了代码的可读性,提高系统的可维护性
2、降低类的复杂性,一个模块只负责一个职责,提高系统的可扩展性和可维护性
3、降低变更引起的风险。变更时必然的,如果单一职责做的好,当修改一个功能的时候可以显著的降低对另一个功能的影响


{internal class Program{static void Main(string[] args){//Dial//HangUp//SendMessage//ReciveMessageTelPhone tel = new TelPhone();tel.Dial = new DialClass(); //new DialMindClass();tel.Tel_Dial();Console.ReadKey();}}interface IDial{void Dial();}class DialClass:IDial{public void Dial(){Console.WriteLine("使用按键拨打电话");//使用意念拨打电话}}class DialMindClass:IDial{public void Dial(){Console.WriteLine("意念拨打电话");}}interface IHangUp{void HangUP();}class HangUpClass:IHangUp{public void HangUP(){Console.WriteLine("使用按键,挂断电话");}}interface ISendMessage{void SendMessage();}class SendClass: ISendMessage{public void SendMessage(){Console.WriteLine("发送短信");}}interface IRecMessage{void ResMsg();}class RecClass:IRecMessage{public void ResMsg(){Console.WriteLine("接收短信");}}class TelPhone   //引起类变更的原因,只有一个{//外部的变化:客观存在的。//内部的变化://导入依赖//public DialClass Dial { get; set; }//public HangUpClass HangUP { get; set; }//public SendClass SendMessage { get; set; }//public RecClass RecMessage { get; set; }//public DialMindClass DialMind { get; set; }//面向接口编程------->面向抽象编程 ---->【封装变化】  --->最少的代码,写出最通用的功能  ---->高内聚、低耦合--->可扩展public IDial Dial { get; set; }public IHangUp HangUp { get; set; }public ISendMessage SendMessage { get; set; }public IRecMessage RecMessage { get; set; }//开闭原则:对扩展开放,对修改关闭public void Tel_Dial(){this.Dial.Dial();}public void Tel_HangUp(){this.HangUp.HangUP();}public void Tel_Send(){this.SendMessage.SendMessage();}public void Tel_Rec(){this.RecMessage.ResMsg();}}}
开放封闭原则(OCP)

1、开放封闭原则是面向对象所有原则的核心
2、对功能扩展开放;对修改代码封闭
3、需求改变时,在不改变软件实体源代码(类、接口、方法等)的前提下,通过扩展功能,使其满足新的需求

使⽤代码,描述不同需求的⽤户去银⾏办理不同的业务


{internal class Program{static void Main(string[] args){//不同需求的用户,去银行找柜员办理业务  银行处理系统Client client = new Client() { Purpose = "存钱" };BankStuff bankStuff = new BankStuff();BankProcess bankProcess = new BankProcess();bankStuff.BankProcess = bankProcess;bankStuff.ProcessClient(client);Console.ReadKey();}}//不同需求的用户class Client{public string Purpose { get; set; }}//银行柜员class BankStuff{public BankProcess BankProcess { get; set; }//调用银行处理系统,处理用户的需求public void ProcessClient(Client client){//判断用户的需求//switch是一定不符合开闭的原则代码,你的程序中,只要出现了switch或者if elseif之类的多条件判断  OCP//shit Mountain  屎山switch (client.Purpose){case "存钱":this.BankProcess.CunMoney();break;case "取钱":this.BankProcess.QuMoney();break;default:Console.WriteLine("无法处理您的需求");break;}}}//银行处理系统class BankProcess{public void CunMoney(){Console.WriteLine("处理存钱");}public void QuMoney(){Console.WriteLine("处理取钱");}}}

银行办理业务2.0


{internal class Program{static void Main(string[] args){Client c = new Client() { Purpose = "取钱" };BankStuff bankStuff = new BankStuff();BankProcess bankProcess = new BankProcess();bankStuff.BankProcess = bankProcess;bankStuff.ProcessClient(c);Console.ReadKey();}}//不同需求的用户class Client{public string Purpose { get; set; }}class BankStuff{public BankProcess BankProcess { get; set; }//调用银行处理系统,处理用户的需求public void ProcessClient(Client client){//判断用户的需求//switch是一定不符合开闭的原则代码,你的程序中,只要出现了switch或者if elseif之类的多条件判断  OCP//shit Mountain  屎山switch (client.Purpose){case "存钱"://this.BankProcess.CunMoney();this.BankProcess.CunMoney = new CunClass();this.BankProcess.Cun();break;case "取钱":this.BankProcess.QuMoney = new QuClass();this.BankProcess.Qu();//this.BankProcess.QuMoney();break;default:Console.WriteLine("无法处理您的需求");break;}}}interface ICunMoney{void CunMoney();}class CunClass : ICunMoney{public void CunMoney(){Console.WriteLine("处理存钱");}}interface IQuMoeny{void QuMoney();}class QuClass : IQuMoeny{public void QuMoney(){Console.WriteLine("处理取钱");}}interface IBuyJJ{void BuyJJ();}class BuyClass: IBuyJJ{public void BuyJJ(){Console.WriteLine("买基金");}}class BankProcess{public ICunMoney CunMoney { get; set; }public IQuMoeny QuMoney { get; set; }public IBuyJJ BuyJJ { get; set; }public void Cun(){this.CunMoney.CunMoney();}public void Qu(){this.QuMoney.QuMoney();}public void Buy(){this.BuyJJ.BuyJJ();}}}
依赖倒置原则

开放封闭原则是面向对象设计的终极目标,而依赖倒置原则是实现开放封闭原则的基础
如果开放封闭原则是设计大楼的蓝图,那么依赖倒置原则就是大楼的钢铁架构

1、高层模块(调用者)不应该依赖于低层模块(被调用者),两个都应该依赖于抽象
2、抽象不应该依赖细节,细节应该依赖于抽象
3、依赖倒置原则的本质就是通过抽象(接口或抽象类)使各个类或模块的实现彼此独立,互不影响,实现模块间的松耦合


{internal class Program{static void Main(string[] args){//歌手歌唱不同国家的歌曲Singer singer = new Singer();singer.SingingChinese(new ChineseSong());singer.SingingChinese(new JapanSong());Console.ReadKey();}}interface ISong{string SingingASong();}class ChineseSong:ISong{public string SingingASong(){return "中国歌曲";}}class KoreaSong:ISong{public string SingingASong(){return "思密达";}}class JapanSong:ISong{public string SingingASong(){return "aligaduo";}}class Singer  //调用者{//调用者和被调用者,强耦合----->//使用抽象【接口/抽象类】封装变化//抽象不应该依赖细节,细节应该依赖于抽象   面向抽象编程public void SingingChinese(ISong cs) //被调用者{Console.WriteLine("正在唱"+cs.SingingASong());}//  通过抽象,使各个模块或者类的实现彼此独立,互不影响,实现模块间的松耦合}}

关于依赖:
1、一个优秀的面向对象程序设计,核心的原则之一就是将变化隔离(封装),使变化部分发生变化时,其他部分不受影响
2、为了实现这个目的,需要使用面向接口编程。使用后,客户类不再直接依赖于服务类,而是依赖一个抽象的接口。这样,客户类就不能在内部直接实例化服务类
3、但是客户类在运行的过程中,又需要具体的服务类来提供服务,因为接口是不能实例化的,就产生了一个矛盾:客户类不允许实例化服务类,但是客户类又需要服务类的服务
4、为了解决这个矛盾,我们设计了一种解决方案,既:客户类注定义一个注入点,用于服务类的注入,而客户类的客户类(Program类)负责根据情况,实例化服务类,注入到客户类中,从而解决了这个矛盾

依赖关系如何传递?(依赖注入)
1、通过接口传递(接口注入)
2、通过构造方法传递
3、通过属性的Set方法传递

里氏替换原则

1、如果S是T的子类型,则T类型的对象可以替换为S类型的对象
2、所有引用父类对象的地方,都可以使用其子类型代替
3、子类可以替换父类

接口分离原则

1、客户端不应该依赖它不需要的接口
2、一个类对另一个类的依赖应该建立在最小接口上
3、接口尽量细分,不要在一个接口中放很多方法
 


{internal class Program{static void Main(string[] args){}}interface IScore{//修改某个学生的成绩void ChangeScore();//void Login();}//1、接口要符合高内聚//2、接口要符合单一职责原则//3、还要考虑实现类权限的问题,对接口中的方法进行分类细分。interface ISuperScore{//添加某个学生的成绩void AddScore();//删除某个学生的成绩void DeleteScore();}interface IQueryScore{void QueryScore();}class Teacher : IScore,IQueryScore{public void AddScore(){throw new NotImplementedException();}public void ChangeScore(){throw new NotImplementedException();}public void DeleteScore(){throw new NotImplementedException();}public void QueryScore(){throw new NotImplementedException();}}class Student : IQueryScore{public void QueryScore(){throw new NotImplementedException();}}
}
迪米特原则(最小知识原则)

1、它要求一个对象应该对其他对象有最少的了解
2、降低类之间的耦合
3、迪米特原则实际上就是一个类在创建方法和属性时要遵守的原则(只和直接朋友通信)

直接朋友:
1、成员对象
2、方法参数
3、方法返回值
4、注意:出现在局部变量中的类,不是直接朋友


{internal class Program{static void Main(string[] args){//总公司员工类 :ID//总公司员工管理类//1、添加总公司员工//2、打印总公司每个员工//3、打印分公司每个员工//分公司员工类 :ID//分公司员工管理类//1、添加分公司员工HeadEmployeeManager headEmployeeManager = new HeadEmployeeManager();headEmployeeManager.PrintEmployees();Console.ReadKey();}}//总公司员工类 天高皇帝远class HeadEmployee{public int ID { get; set; }}//总公司员工管理类//谁是HeadEmployeeManager的直接朋友//成员对象  方法的参数类型  方法的返回值类型//List<HeadEmployee> listHeadEmployee  直接朋友//List<HeadEmployee> 直接朋友//BodyEmployeeManager bodyEmployeeManager  不是直接朋友//  List<BodyEmployee> listBodyEmployees  不是直接朋友class HeadEmployeeManager{//总公司员工集合private List<HeadEmployee> listHeadEmployee = new List<HeadEmployee>();//添加总公司员工public List<HeadEmployee> AddHeadEmployees(){for (int i = 0; i < 10; i++){listHeadEmployee.Add(new HeadEmployee() { ID = i + 1 });}return listHeadEmployee;}//打印总公司员工和分公司员工public void PrintEmployees(){this.AddHeadEmployees();Console.WriteLine("==========================以下是总公司员工ID=====================================================");//打印总公司员工for (int i = 0; i < listHeadEmployee.Count; i++){Console.WriteLine(listHeadEmployee[i].ID);}Console.WriteLine("==========================以下是分公司员工ID=====================================================");//3、打印分公司每个员工//3.1 创建分公司员工管理类的对象BodyEmployeeManager bodyEmployeeManager = new BodyEmployeeManager();//3.2 调用AddBodyEmployee添加分公司成员,并获取返回值List<BodyEmployee> listBodyEmployees = bodyEmployeeManager.AddBodyEmployees();//3.3 循环分公司员工的集合for (int i = 0; i < listBodyEmployees.Count; i++){Console.WriteLine(listBodyEmployees[i].ID);}}}class BodyEmployee{public int ID { get; set; }}class BodyEmployeeManager{private List<BodyEmployee> listBodyEmployee = new List<BodyEmployee>();public List<BodyEmployee> AddBodyEmployees(){for (int i = 0; i < 5; i++){listBodyEmployee.Add(new BodyEmployee() { ID = i + 1 });}return listBodyEmployee;}}}
合成复用原则

1、合成复用原则,又称组合\聚合复用原则
2、尽量使用对象组合,而不是继承来达到复用
3、继承的问题:a、破坏了系统的封装性,基类发生了变化,子类的实现也会发生变化
                           b、继承是静态的,不能在程序运行时发生变化
4、合成复用原则是将已有的对象纳入到新对象中,作为新对象的对象成员来实现的,新对象可以调用已有对象的功能,从而达到复用

类与类之间的关系:泛化、实现、组合、聚合、关联、依赖
泛化:Animal是Tiger的泛化,Tiger是Animal的特化
实现:类与接⼝的关系,表示类实现了接口
组合:组合是整体和部分的关系,部分没有独⽴的⽣命周期,组合是把部分作为整体类的对象
聚合:聚合也是整体与部分的关系,但是个体有独⽴的⽣命周期,聚合是把个体对象的指针(引⽤)作为整体类的属性
关联:关联是⼀种拥有关系,它使⼀个类知道另⼀个类的属性和⽅法。
依赖:依赖是一种使用关系
 

类与类之间的关系
{internal class Program{static void Main(string[] args){}}class Animal //泛化{public char Gender { get; set; }public void Eat(){Console.WriteLine("动物都能吃");}public void Sleep(){Console.WriteLine("动物都能睡觉");}}class Tiger:Animal ,IClimb //特化{//Tiger和Leg是组合关系,强拥有关系,两个对象的生命周期必须是一样的。public Leg Legs { get; set; }//在老虎的构造函数中,传入Leg的对象,表示Tiger跟Leg同时出生。public Tiger(Leg leg){this.Legs = leg;}//属性注入、构造注入、传参注入//关联public Food Food { get; set; }//依赖public Water Water { get; set; }public string Name { get; set; }public void Climb(){Console.WriteLine("老虎会爬树");}}class Food{public string Name { get; set; }public string Color { get; set; }}class Water{public double Weight { get; set; }}class TigerGroup{//聚合关系public Tiger[] Tigers { get; set; }}class Leg{public int Count { get; set; }}interface IClimb{void Climb();}
}
合成复用原则
{internal class Program{static void Main(string[] args){//继承问题://1、可能会造成子类功能泛滥//2、可能会造成子类数量爆炸//3、打破了类的封装性   //sealed   B:A   //创建油车对象YouCar youCar = new YouCar(new Blue());youCar.Move();Console.ReadKey();}}interface IColor{string GetColor();}class White : IColor{public string GetColor(){return "白色";}}class Red : IColor{public string GetColor(){return "红色";}}class Blue : IColor{public string GetColor(){return "蓝色";}}abstract class Car{public IColor Color { get; set; }public Car(IColor color) //组合,强拥有关系{this.Color = color;}public abstract void Move();}class DianCar : Car{public DianCar(IColor color) : base(color){ }public override void Move(){//是什么颜色的电动汽车在跑Console.WriteLine(this.Color.GetColor() + "的电动汽车,工业垃圾,在用电奔跑");  //发动机、底盘、变速箱}}class YouCar : Car{public YouCar(IColor color) : base(color){ }public override void Move(){//是什么颜色的电动汽车在跑Console.WriteLine(this.Color.GetColor() + "汽油车再用油奔跑");  //发动机、底盘、变速箱}}}

设计原则总结

1、设计原则是「高内聚、低耦合」的具体落地。
2、单一职责原则要求在软件系统开发、设计中,一个类只负责一个功能领域的相关职责。
3、开放封闭原则要求一个软件应该对扩展开放,对修改封闭,即在不修改源代码的情况下,完成系统功能的扩展。
4、里式替换原则决定了子类可以赋值给父类,
5、依赖倒置原则要求抽象不应该依赖于细节,细节应该依赖于抽象。要面向接口编程,不要面向实现编程。
6、迪米特原则要求一个对象尽可能少的与其他对象发生相互作用。
7、接口隔离原则要求客户端不应该依赖那些他不需要的接口,即将一些大的接口细化成一些小的接口供客户端使用。
8、合成复用原则要求我们尽量使用对象的组合,而非继承来达到复用的目标。

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

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

相关文章

Java Spring Boot面试题解析

1. 什么是 Spring Boot&#xff1f;【重点】 多年来&#xff0c;随着新功能的增加&#xff0c;Spring变得越来越复杂&#xff1b;一个Spring项目&#xff0c;我们必须做添加构建路径或添加Maven依赖关系&#xff0c;配置应用程序服务器&#xff0c;添加Spring配置等工作&#…

Flutter开发进阶之Flutter Web加载速度优化

Flutter开发进阶之Flutter Web加载速度优化 通常使用Flutter开发的web加载速度会比较慢,原因是Flutter web需要加载的资源处于国外,以下是据此所做的相应优化。 一、FlutterWeb打包 flutter build web --web-renderer canvaskit使用新命令打包 flutter build web --web-…

matlab批量替换txt文本文件的特定行的内容

1.下图所示&#xff0c;我想要替换第14行。 2.运行代码后&#xff0c;第14行已经更改为需要的内容。 clc,clear; %%----------------------需要更改的地方------------------------------------ % 设置要操作的文本文件路径&#xff0c;替换为你自己的文件路径 path D:\paper_…

【算法与数据结构】复杂度深度解析(超详解)

文章目录 &#x1f4dd;算法效率&#x1f320; 算法的复杂度&#x1f320; 时间复杂度的概念&#x1f309;大O的渐进表示法。 &#x1f320;常见复杂度&#x1f320;常见时间复杂度计算举例&#x1f309;常数阶O(1)&#x1f309;对数阶 O(logN)&#x1f309;线性阶 O(N)&#x…

高防服务器托管应注意什么

选择高防服务器托管主要考虑的因素&#xff1a;1.服务商的服务器大小。2.服务器的防御值大小。3.服务器机房的位置以及机房的资质。 具体内容如下&#xff1a; 1&#xff0e;服务器大小是按照U来定的&#xff0c;U是一种表示服务器外部尺寸的单位(计量单位&#xff1a;高度或厚…

揭示预处理中的秘密!(二)

目录 ​编辑 1. #运算符 2. ##运算符 3. 命名约定 4. #undef 5. 命令行定义 6. 条件编译 7. 头文件的被包含的方式 8.嵌套文件包含 9. 其他预处理指令 10. 完结散花 悟已往之不谏&#xff0c;知来者犹可追 …

微信小程序引入Vant插件

Vant官网&#xff1a;Vant Weapp - 轻量、可靠的小程序 UI 组件库 先查看官网的版本 新建一个package.json页面&#xff0c;代码写上&#xff1a;&#xff08;我先执行的npm安装没出package页面&#xff0c;所以先自己创建了一个才正常&#xff09; {"dependencies"…

【软件测试】--功能测试4-html介绍

1.1 前端三大核心 html:超文本标记语言&#xff0c;由一套标记标签组成 标签&#xff1a; 单标签&#xff1a;<标签名 /> 双标签:<标签名></标签名> 属性&#xff1a;描述某一特征 示例:<a 属性名"属性值"> 1.2 html骨架标签 <!DOC…

web组态软件

1、强大的画面显示web组态功能 2、良好的开放性。 开放性是指组态软件能与多种通信协议互联&#xff0c;支持多种硬件设备&#xff0c;向上能与管理层通信&#xff0c;实现上位机和下位机的双向通信。 3、丰富的功能模块。 web组态提供丰富的控制功能库&#xff0c;满足用户的测…

【数据分享】2019-2023年我国地级市逐月新房房价数据(Excel/Shp格式)

房价是一个城市发展程度的重要体现&#xff0c;一个城市的房价越高通常代表这个城市越发达&#xff0c;对于人口的吸引力越大&#xff01;因此&#xff0c;房价数据是我们在各项城市研究中都非常常用的数据&#xff01;之前我们分享过2011-2023年我国地级市逐月二手房房价数据&…

【pytorch】tensor.detach()和tensor.data的区别

文章目录 序言相同点不同点测试实例应用 序言 .detach()和.data都可以用来分离tensor数据&#xff0c;下面进行比较pytorch0.4及之后的版本&#xff0c;.data仍保留&#xff0c;但建议使用.detach() 相同点 x.detach()和x.data返回和x相同数据的tensor&#xff0c;这个新的t…

rpmrebuild 重新制作 rpm

重新制作 rpm 有两种方式 方式一&#xff1a; 1、rpm2cpio xxx.rpm |cpio -idv 2、修改相关文件 3、rpmrebuild -s my.spec xxx.rpm 4、rpmbuild -ba xxx.spec 方式二&#xff1a; 1、rpmrebuild -m /bin/bash -np rpm/xxx.rpm 2、此时我们得到一个交互shell&#xff0c; 3、比…

算法打卡day5|哈希表篇01|Leetcode 242.有效的字母异位词 、19.删除链表的倒数第N个节点、202. 快乐数、1. 两数之和

哈希表基础知识 哈希表 哈希表关键码就是数组的索引下标&#xff0c;然后通过下标直接访问数组中的元素&#xff1b;数组就是哈希表的一种 一般哈希表都是用来快速判断一个元素是否出现集合里。例如要查询一个名字是否在班级里&#xff1a; 要枚举的话时间复杂度是O(n)&…

docker发布dubbo服务 外部程序访问不到问题处理

一、问题简述 程序通过docker向zookeeper注册服务时&#xff0c;会将容器地址(内网地址)作为服务的通信地址。当我们的程序都在容器内相互通信时&#xff0c;可以凭借容器地址相互通信。但是外部程序想要直接通过宿主机取访问服务时&#xff0c;从zk上取到providers的地址&…

【数据结构】从链表到LinkedList类

&#x1f9e7;&#x1f9e7;&#x1f9e7;&#x1f9e7;&#x1f9e7;个人主页&#x1f388;&#x1f388;&#x1f388;&#x1f388;&#x1f388; &#x1f9e7;&#x1f9e7;&#x1f9e7;&#x1f9e7;&#x1f9e7;数据结构专栏&#x1f388;&#x1f388;&#x1f388;&…

标准库中的String类 String(C++)【2】

文章目录 String常用的接口&#xff08;黑框标记的是常用接口&#xff09;string类对象的反向遍历操作第一种第二种 容量string的扩容机制 String常用的接口&#xff08;黑框标记的是常用接口&#xff09; string类对象的反向遍历操作 第一种 通过下表进行遍历 void TestSt…

计算机网络期末复习笔记

一、引言 计算机网络是现代信息技术的核心&#xff0c;涉及计算机、通信、电子等多个领域。在信息时代&#xff0c;计算机网络已经深入到人们生活的各个方面&#xff0c;如社交、购物、教育、科研等。因此&#xff0c;理解和掌握计算机网络的基本概念和原理&#xff0c;对于计…

springboot226经方药食两用服务平台

经方药食两用服务平台的设计与实现 摘要 近年来&#xff0c;信息化管理行业的不断兴起&#xff0c;使得人们的日常生活越来越离不开计算机和互联网技术。首先&#xff0c;根据收集到的用户需求分析&#xff0c;对设计系统有一个初步的认识与了解&#xff0c;确定经方药食两用…

Redis、Memcache、MongoDB三者区别?

使用Redis、Memcache和MongoDB这些工具或数据库取决于具体的需求和应用场景。每种技术都有自己的优势和适用范围。 Redis&#xff1a; 高性能的内存存储&#xff1a;Redis是一个基于内存的数据存储系统&#xff0c;因此读取和写入速度非常快。 丰富的数据结构支持&#xff1a…

RK3568平台 RTC时间框架

一.RTC时间框架概述 RTC&#xff08;Real Time Clock&#xff09;是一种用于计时的模块&#xff0c;可以是再soc内部&#xff0c;也可以是外部模块。对于soc内部的RTC&#xff0c;只需要读取寄存器即可&#xff0c;对于外部模块的RTC&#xff0c;一般需要使用到I2C接口进行读取…