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

03.开闭原则详细介绍

03.开闭原则详细介绍

目录介绍
  • 01.问题思考的分析
  • 02.如何理解开闭原则
  • 03.开闭原则的背景
  • 04.开闭原则比较难学
  • 05.实现开闭原则方式
  • 06.画图形案例分析
  • 07.银行业务案例分析
  • 08.开闭原则优缺点
  • 09.开闭原则的总结

推荐一个好玩网站

一个最纯粹的技术分享网站,打造精品技术编程专栏!编程进阶网

https://yccoding.com/

设计模式Git项目地址:https://github.com/yangchong211/YCDesignBlog

单一职责原则(SRP)是面向对象设计的重要原则,强调一个类或模块应仅负责完成一个特定的职责或功能。通过将复杂的功能分解为多个粒度小、功能单一的类,可以提高系统的灵活性、可维护性和可扩展性。

本文详细介绍了如何理解单一职责原则,包括方法、接口和类层面的应用,并通过具体例子解释了其优势和判断标准。此外,还探讨了在实际开发中如何平衡类的设计,避免过度拆分导致的复杂性增加。

01.问题思考的分析

  1. 什么叫作开闭原则,他的主要用途是什么?
  2. 如何做到拓展开放,修改封闭这一准则,结合案例说一下如何实现?
  3. 你平常是如何理解开闭原则的,判断的标准是什么?

02.如何理解开闭原则

开闭原则的英文全称是 Open Closed Principle,简写为 OCP。它的英文描述是:software entities (modules, classes, functions, etc.) should be open for extension , but closed for modification。

我们把它翻译成中文就是:软件实体(模块、类、方法等)应该“对扩展开放、对修改关闭”。

这个描述比较简略,如果我们详细表述一下,那就是,添加一个新的功能应该是,在已有代码基础上扩展代码(新增模块、类、方法等),而非修改已有代码(修改模块、类、方法等)

03.开闭原则的背景

在软件的生命周期内,因为变化、升级和维护等原因需要对软件原有代码进行修改时,可能会将错误引入原本已经经过测试的旧代码中,破坏原有系统。

因此,当软件需要变化时,我们应该尽量通过扩展的方式来实现变化,而不是通过修改已有的代码来实现。

当然,在现实开发中,只通过继承的方式来升级、维护原有系统只是一个理想化的愿景,因此,在实际的开发过程中,修改原有代码、扩展代码往往是同时存在的。

软件开发过程中,最不会变化的就是变化本身。产品需要不断地升级、维护,没有一个产品从第一版本开发完就再没有变化了,除非在下个版本诞生之前它已经被终止。

产品需要升级,修改原来的代码就可能会引发其他的问题。那么如何确保原有软件模块的正确性,以及尽量少地影响原有模块,答案就是尽量遵守本章要讲述的开闭原则

04.开闭原则比较难学

个人觉得,开闭原则是 SOLID 中最难理解、最难掌握,同时也是最有用的一条原则。

之所以说这条原则难理解,那是因为,“怎样的代码改动才被定义为‘扩展’?怎样的代码改动才被定义为‘修改’?怎么才算满足或违反‘开闭原则’?修改代码就一定意味着违反‘开闭原则’吗?”等等这些问题,都比较难理解。

之所以说这条原则难掌握,那是因为,“如何做到‘对扩展开放、修改关闭’?如何在项目中灵活地应用‘开闭原则’,以避免在追求扩展性的同时影响到代码的可读性?”等等这些问题,都比较难掌握。

之所以说这条原则最有用,那是因为,扩展性是代码质量最重要的衡量标准之一。在 23 种经典设计模式中,大部分设计模式都是为了解决代码的扩展性问题而存在的,主要遵从的设计原则就是开闭原则。

05.实现开闭原则方式

为了实现开闭原则,常用的设计技术有以下几种:

  1. 抽象类和接口:通过定义抽象类和接口来约定行为,然后通过继承和实现这些抽象类和接口来扩展功能。
  2. 策略模式:将算法的实现分离到不同的类中,通过组合方式来实现不同的行为。
  3. 装饰器模式:通过对对象进行包装,动态地添加新的行为或功能。

06.画图形案例分析

6.1 普通案例实现

假设有一个图形绘制程序,程序需要能够绘制不同形状的图形,比如矩形、圆形和三角形。最初的设计可能会像这样:

public class GraphicEditor {public void draw(Shape shape) {if (shape.m_type == 1) {drawRectangle();} else if(shape.m_type == 2) {drawCircle();}}public void drawRectangle() {System.out.println("画长方形");}public void drawCircle() {System.out.println("画圆形");}class Shape {int m_type;}class Rectangle extends Shape {Rectangle() {super.m_type=1;}}class Circle extends Shape {Circle() {super.m_type=2;}}
}

我们来看看,这个代码,初看是符合要求了,再想想,要是我增加一种形状呢? 比如增加三角形.

  1. 首先,要增加一个三角形的类, 继承自Shape
  2. 第二,要增加一个画三角形的方法drawTriage()
  3. 第三,在draw方法中增加一种类型type=3的处理方案

在这个设计中,每当我们需要添加新的图形类型,就需要修改 GraphicEditor 类,添加新的 if 条件。我们需要修改已有的代码来实现新功能。

这就违背了开闭原则-对扩展开发,对修改关闭。增加一个类型,修改了三处代码。

6.2 开闭原则演变

为了符合开闭原则,我们可以进行重构。首先,我们定义一个抽象类Shape

public class GraphicEditor {public void draw(Shape shape) {shape.draw();}interface Shape {void draw();}class Rectangle implements Shape {@Overridepublic void draw() {System.out.println("画矩形");}}class Circle implements Shape {@Overridepublic void draw() {System.out.println("画圆形");}}}

各种类型的形状自己规范自己的行为, 而GraphicEditor.draw()只负责画出来. 当增加一种类型三角形. 只需要

  1. 第一,增加一个三角形的类,实现Shape接口
  2. 第二,调用draw方法,划出来就可以了

整个过程都是在扩展,而没有修改原来的类。这个设计是符合开闭原则的。

6.3 使用例子分析

让我们来看一个具体的使用例子,展示如何遵循开闭原则来进行扩展。

public class Main {public static void main(String[] args) {Shape circle = new Circle();Shape rectangle = new Rectangle();GraphicEditor editor = new GraphicEditor();editor.drawShape(circle);editor.drawShape(rectangle);}
}

在这个例子中,我们创建了一个圆形对象和一个矩形对象,并通过 GraphicEditor 类来绘制它们。当我们需要添加新的图形类型(例如三角形)时,只需创建一个新的类实现 Shape 接口,而不需要修改现有的代码:

// 三角形类
public class Triangle implements Shape {@Overridepublic void draw() {// 绘制三角形的代码}
}// 使用新的三角形类
public class Main {public static void main(String[] args) {Shape circle = new Circle();Shape rectangle = new Rectangle();Shape triangle = new Triangle();GraphicEditor editor = new GraphicEditor();editor.drawShape(circle);editor.drawShape(rectangle);editor.drawShape(triangle);}
}

通过这种方式,我们可以在不修改 GraphicEditor 类的情况下,轻松地扩展新的图形类型,真正实现了对扩展开放,对修改关闭的设计原则。

07.银行业务案例分析

7.1 业务基础实现

比如现在有一个银行业务,存钱,取钱和转账。最初我们会怎么思考呢?

  1. 首先有一个银行业务类, 用来处理银行的业务
  2. 银行有哪些业务呢? 存钱,取钱,转账, 这都是银行要执行的操作
  3. 那外部说我要存钱, 我要取钱,我要转账, 通过一个类型来告诉我们
public class BankBusiness {public void operate(int type) {if (type == 1) {save();} else if(type == 2) {take();} else if(type == 3) {transfer();}}public void save(){System.out.println("存钱");}public void take(){System.out.println("取钱");}public void transfer() {System.out.println("转账");}
}

咋一看已经实现了需求. 但是现在有新的需求来了, 银行要增加功能—理财. 理财是银行业务的一种, 自然是新增一个方法.

然后在operate()方法里增加一种类型. 这就是一个糟糕的设计, 增加新功能, 但是却修改了原来的代码

7.2 开闭原则演变

设计成接口抽象的形式,利用开关原则,可以尝试改造为下面的代码。将不同对象分类的服务方法进行抽象,把业务逻辑的紧耦合关系拆开,实现代码的隔离保证了方便的扩展。

public interface Business {public void operate();
}public class Save implements Business {@Overridepublic void operate() {System.out.println("存钱业务");}
}public class Take implements Business {@Overridepublic void operate() {System.out.println("取钱业务");}
}public class Transfer implements Business {@Overridepublic void operate() {System.out.println("转账业务");}
}public class BankBusinesses {/*** 处理银行业务* @param business*/public void operate(Business business) {System.out.println("处理银行业务");business.operate();}
}

通过接口抽象的形式方便扩展, 加入要新增理财功能. 只需新增一个理财类, 其他业务代码都不需要修改.

其实, 在日常工作中, 经常会遇到这种情况. 因为我们平时写业务逻辑会更多一些, 而业务就像流水账, 今天一个明天一个一点一点的增加. 所以,当业务增加到3个的时候, 我们就要思考, 如何写能够方便扩展

08.开闭原则优缺点

8.1 开闭原则的优点

  1. 提高了代码的可维护性与复用性:遵循开闭原则可以让代码更加稳定和可维护,同时也使得代码更容易被复用。如果我们需要修改某个模块的行为,只需要扩展该模块而不需要直接修改源代码,这样就不会影响到其他的模块。
  2. 提高了代码的可扩展性:开闭原则还可以提高代码的可扩展性。通过扩展已有的代码,我们可以很容易地添加新的功能或改进现有功能,从而适应业务需求的更改。
  3. 提高了代码的可测试性:遵循开闭原则可以降低代码的耦合度,使得测试更加容易。因为我们只需要测试新增的代码,而不必验证已有代码的正确性。

8.2 开闭原则的缺点

  1. 对代码的设计要求高:遵循开闭原则需要对代码进行良好的抽象和封装,这对程序员的设计能力和经验要求较高。如果设计不好,可能会导致代码过于复杂难以维护。
  2. 可能会增加代码量:通过扩展已有的代码来实现新功能,可能会增加代码量,使得系统变得更加复杂。这需要我们在平衡可维护性和代码量之间做出权衡。
  3. 可能会带来设计上的限制:在某些情况下,为了遵循开闭原则,我们可能需要引入更多的抽象层或接口。这可能会带来一定的设计上的限制,限制了代码的表达能力和灵活性。

09.开闭原则的总结

9.1 理解开闭原则

如何理解“对扩展开放、对修改关闭”?

添加一个新的功能,应该是通过在已有代码基础上扩展代码(新增模块、类、方法、属性等),而非修改已有代码(修改模块、类、方法、属性等)的方式来完成。

关于定义,我们有两点要注意。

  1. 第一点是,开闭原则并不是说完全杜绝修改,而是以最小的修改代码的代价来完成新功能的开发。
  2. 第二点是,同样的代码改动,在粗代码粒度下,可能被认定为“修改”;在细代码粒度下,可能又被认定为“扩展”。

9.2 如何做到开闭原则

如何做到“对扩展开放、修改关闭”?

我们要时刻具备扩展意识、抽象意识、封装意识。在写代码的时候,我们要多花点时间思考一下,这段代码未来可能有哪些需求变更,如何设计代码结构,事先留好扩展点,以便在未来需求变更的时候,在不改动代码整体结构、做到最小代码改动的情况下,将新的代码灵活地插入到扩展点上。

学习设计原则,要多问个为什么。

不能把设计原则当真理,而是要理解设计原则背后的思想。搞清楚这个,比单纯理解原则讲的是啥,更能让你灵活应用原则。

9.3 开闭原则的总结

  1. 问题思考:开闭原则的主要用途是什么?如何才能做到对外拓展开放,对内修改关闭?你平常是如何理解开闭原则的,判断的标准是什么?
  2. 如何理解开闭原则:软件实体(模块、类、方法等)应该“对扩展开放、对修改关闭”。
  3. 为何开闭原则比较难学:怎样的代码改动才被定义为‘修改’?怎么才算满足或违反‘开闭原则’?如何理解大部分设计模式都是遵循开闭原则!
  4. 开笔原则的背景:软件/业务迭代升级中,面对代码变化,修改原来代码可能引入原有模块bug风险,因此尽量通过对外拓展来实现功能迭代。
  5. 实现开闭原则的方式:常用的设计技术有以下几种,1.抽象类和接口;2.策略模式;3.装饰器模式等。
  6. 开闭原则的案例教学:绘制圆形/矩形,通过if-else来执行不同case逻辑,新增一种类型则需要修改原逻辑。因此考虑通过接口+抽象类方式实现友好拓展。
  7. 开闭原则的优点:1.提高代码拓展性和可维护性;2.提高代码可测试的粒度;3.降低的代码耦合度。
  8. 开闭原则的缺点:1.对代码设计要求高;2.可能会导致代码量增大和变得复杂;3.可能会带来设计上的限制。
  9. 总结如何理解开闭原则:当需求发生变化时,我们应该通过添加新的代码来扩展功能,而不是修改已有的代码。
  10. 总结如何运用开闭原则:通过封装变化、使用抽象化、利用扩展点和遵循依赖倒置原则来实现。

10.更多内容推荐

模块描述备注
GitHub多个YC系列开源项目,包含Android组件库,以及多个案例GitHub
博客汇总汇聚Java,Android,C/C++,网络协议,算法,编程总结等YCBlogs
设计模式六大设计原则,23种设计模式,设计模式案例,面向对象思想设计模式
Java进阶数据设计和原理,面向对象核心思想,IO,异常,线程和并发,JVMJava高级
网络协议网络实际案例,网络原理和分层,Https,网络请求,故障排查网络协议
计算机原理计算机组成结构,框架,存储器,CPU设计,内存设计,指令编程原理,异常处理机制,IO操作和原理计算机基础
学习C编程C语言入门级别系统全面的学习教程,学习三到四个综合案例C编程
C++编程C++语言入门级别系统全面的教学教程,并发编程,核心原理C++编程
算法实践专栏,数组,链表,栈,队列,树,哈希,递归,查找,排序等Leetcode
Android基础入门,开源库解读,性能优化,Framework,方案设计Android

23种设计模式

23种设计模式 & 描述 & 核心作用包括
创建型模式
提供创建对象用例。能够将软件模块中对象的创建和对象的使用分离
工厂模式(Factory Pattern)
抽象工厂模式(Abstract Factory Pattern)
单例模式(Singleton Pattern)
建造者模式(Builder Pattern)
原型模式(Prototype Pattern)
结构型模式
关注类和对象的组合。描述如何将类或者对象结合在一起形成更大的结构
适配器模式(Adapter Pattern)
桥接模式(Bridge Pattern)
过滤器模式(Filter、Criteria Pattern)
组合模式(Composite Pattern)
装饰器模式(Decorator Pattern)
外观模式(Facade Pattern)
享元模式(Flyweight Pattern)
代理模式(Proxy Pattern)
行为型模式
特别关注对象之间的通信。主要解决的就是“类或对象之间的交互”问题
责任链模式(Chain of Responsibility Pattern)
命令模式(Command Pattern)
解释器模式(Interpreter Pattern)
迭代器模式(Iterator Pattern)
中介者模式(Mediator Pattern)
备忘录模式(Memento Pattern)
观察者模式(Observer Pattern)
状态模式(State Pattern)
空对象模式(Null Object Pattern)
策略模式(Strategy Pattern)
模板模式(Template Pattern)
访问者模式(Visitor Pattern)

相关文章:

03.开闭原则详细介绍

03.开闭原则详细介绍 目录介绍 01.问题思考的分析02.如何理解开闭原则03.开闭原则的背景04.开闭原则比较难学05.实现开闭原则方式06.画图形案例分析07.银行业务案例分析08.开闭原则优缺点09.开闭原则的总结 推荐一个好玩网站 一个最纯粹的技术分享网站,打造精品…...

前端职业规划

前端开发的职业规划可以根据个人兴趣、技术深度和职业目标来制定。以下是一个典型的前端开发者职业发展路径,涵盖了从初级到高级的不同阶段,以及未来的发展方向: 1. 初级阶段(0-2 年) 目标:掌握基础技能&a…...

杂记:STM32 调试信息打印实现方式

杂记:STM32 调试信息打印实现方式 一、引言二、使用 USART 串口打印原理(二)实现步骤硬件连接代码实现 使用 ST - LINK 调试器 ITM 打印(一)原理(二)实现步骤硬件连接代码实现 四、使用 Semihos…...

python+unity落地方案实现AI 换脸融合

先上效果再说技术结论,使用的是自行搭建的AI人脸融合库,可以离线不受限制无限次生成,有需要的可以后台私信python ai换脸融合。 TODO 未来的方向:3D人脸融合和AI数据训练 这个技术使用的是openvcinsighface,openvc…...

ComfyUI流程图生图原理详解

一、引言 ComfyUI 是一款功能强大的工具,在图像生成等领域有着广泛应用。本文补充一点ComfyUI 的安装与配置过程遇到的问题,并深入剖析图生图过程及相关参数,帮助读者快速入门并深入理解其原理。 二、ComfyUI 的安装与配置中遇到的问题 &a…...

【C++ 真题】P1824 进击的奶牛

P1824 进击的奶牛 题目描述 Farmer John 建造了一个有 N N N( 2 ≤ N ≤ 1 0 5 2 \leq N \leq 10 ^ 5 2≤N≤105) 个隔间的牛棚,这些隔间分布在一条直线上,坐标是 x 1 , x 2 , ⋯ , x N x _ 1, x _ 2, \cdots, x _ N x1​,x2​,⋯,xN​&a…...

26、深度学习-自学之路-NLP自然语言处理-理解加程序,怎么把现实的词翻译给机器识别。

一、怎么能让机器能够理解我们的语言呢,我们可以利用神经网络干很多的事情,那么我们是不是也可以用神经元做自然语言处理呢,现在很多的实际应用已经说明了这个问题,可以这么做。 那我们考虑一下该怎么做,首先我们应该…...

24电子信息类研究生复试面试问题汇总 电子信息类专业知识问题最全!电子信息复试全流程攻略 电子信息考研复试真题汇总

你是不是在为电子信息考研复试焦虑?害怕被老师问到刁钻问题、担心专业面答不上来?别慌!作为复试面试92分逆袭上岸的学姐,今天手把手教你拆解电子信息类复试通关密码!看完这篇,让你面试现场直接开大&#xf…...

leetcode25. K 个一组翻转链表

代码如图所示:下面还有一个跑代码的流程图,结合两个图片理解起来就好,感觉已经解释的很清晰了!! 一定要记住return dummy.next;这表示伪节点的下一个节点才是反转完的整个链表的头结点 补一个最后的,有点纰…...

工厂方法模式详解(Java)

一、工厂方法模式基础 1.1 定义与角色 工厂方法模式(Factory Method Pattern)是一种创建型设计模式,它提供了一种创建对象的接口,但允许子类决定实例化哪一个类。这种模式的核心在于定义一个创建产品对象的工厂接口,将实际创建产品的过程延迟到子类中实现。这样做的主要…...

SpringBoot+Dubbo+zookeeper 急速入门案例

项目目录结构&#xff1a; 第一步&#xff1a;创建一个SpringBoot项目&#xff0c;这里选择Maven项目或者Spring Initializer都可以&#xff0c;这里创建了一个Maven项目&#xff08;SpringBoot-Dubbo&#xff09;&#xff0c;pom.xml文件如下&#xff1a; <?xml versio…...

pdf.js默认显示侧边栏和默认手形工具

文章目录 默认显示侧边栏(切换侧栏)默认手形工具(手型工具) 大部分的都是在viewer.mjs中的const defaultOptions 变量设置默认值,可以使用数字也可以使用他们对应的变量枚举值 默认显示侧边栏(切换侧栏) 在viewer.mjs中找到defaultOptions,大概在732行,或则搜索sidebarViewOn…...

数据库第三次作业

第一题&#xff1a; 学生表&#xff1a;Student (Sno, Sname, Ssex , Sage, Sdept) 学号&#xff0c;姓名&#xff0c;性别&#xff0c;年龄&#xff0c;所在系 Sno为主键 课程表&#xff1a;Course (Cno, Cname,) 课程号&#xff0c;课程名 Cno为主键 学生选课表&#xff1a;S…...

渗透利器:YAKIT 工具-基础实战教程.

YAKIT 工具-基础实战教程. YAKIT&#xff08;Yak Integrated Toolkit&#xff09;是一款基于Yak语言开发的集成化网络安全单兵工具&#xff0c;旨在覆盖渗透测试全流程&#xff0c;提供从信息收集、漏洞扫描到攻击实施的自动化支持。其核心目标是通过GUI界面降低Yak语言的使用…...

变分边界详解

起因 当时看VAE论文时有这么一段&#xff0c;但是看完直接一头雾水&#xff0c;这都那跟哪&#xff0c;第一个公式咋做的变换就变出那么一堆。网上搜了很多博客都语焉不详&#xff0c;只好自己来写一篇&#xff0c;希望能解答后来人的疑惑。 公式1 参考文章&#xff1a;证据…...

计算机毕业设计——Springboot餐厅点餐系统

&#x1f389;**欢迎来到琛哥的技术世界&#xff01;**&#x1f389; &#x1f4d8; 博主小档案&#xff1a; 琛哥&#xff0c;一名来自世界500强的资深程序猿&#xff0c;毕业于国内知名985高校。 &#x1f527; 技术专长&#xff1a; 琛哥在深度学习任务中展现出卓越的能力&a…...

Dav_笔记14:优化程序提示 HINTs -3

查询转换的提示 以下每个提示都指示优化程序使用特定的SQL查询转换&#xff1a; ■NO_QUERY_TRANSFORMATION ■USE_CONCAT ■NO_EXPAND ■REWRITE和NO_REWRITE ■MERGE和NO_MERGE ■STAR_TRANSFORMATION和NO_STAR_TRANSFORMATION ■事实和NO_FACT ■UNNEST和NO_UNNEST…...

Makefile的用法及算法应用

编译的过程 算法&#xff1a;解决特定问题的求解步骤 算法的设计 1.正确性 语法正确合法的输入能得到合理的结果对非法的输入&#xff0c;给出满足要求的规格说明对精心选择&#xff0c;甚至刁难的测试都能正常运行&#xff0c;结果正确 2.可读性&#xff0c;便于交流&…...

伯克利 CS61A 课堂笔记 08 —— Strings and Dictionaries

本系列为加州伯克利大学著名 Python 基础课程 CS61A 的课堂笔记整理&#xff0c;全英文内容&#xff0c;文末附词汇解释。 目录 01 Strings 字符串 Ⅰ Strings are An Abstraction. Ⅱ Strings Literals have Three Forms Ⅲ String are Sequences 02 Dictionaries 字典 …...

机器学习 - 理解偏差-方差分解

为了避免过拟合&#xff0c;我们经常会在模型的拟合能力和复杂度之间进行权衡。拟合能力强的模型一般复杂度会比较高&#xff0c;容易导致过拟合。相反&#xff0c;如果限制模型的复杂度&#xff0c;降低其拟合能力&#xff0c;又可能会导致欠拟合。因此&#xff0c;如何在模型…...

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周&#xff0c;有很多同学在写期末Java web作业时&#xff0c;运行tomcat出现乱码问题&#xff0c;经过多次解决与研究&#xff0c;我做了如下整理&#xff1a; 原因&#xff1a; IDEA本身编码与tomcat的编码与Windows编码不同导致&#xff0c;Windows 系统控制台…...

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…...

【Python】 -- 趣味代码 - 小恐龙游戏

文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...

C++实现分布式网络通信框架RPC(3)--rpc调用端

目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中&#xff0c;我们已经大致实现了rpc服务端的各项功能代…...

高防服务器能够抵御哪些网络攻击呢?

高防服务器作为一种有着高度防御能力的服务器&#xff0c;可以帮助网站应对分布式拒绝服务攻击&#xff0c;有效识别和清理一些恶意的网络流量&#xff0c;为用户提供安全且稳定的网络环境&#xff0c;那么&#xff0c;高防服务器一般都可以抵御哪些网络攻击呢&#xff1f;下面…...

华硕a豆14 Air香氛版,美学与科技的馨香融合

在快节奏的现代生活中&#xff0c;我们渴望一个能激发创想、愉悦感官的工作与生活伙伴&#xff0c;它不仅是冰冷的科技工具&#xff0c;更能触动我们内心深处的细腻情感。正是在这样的期许下&#xff0c;华硕a豆14 Air香氛版翩然而至&#xff0c;它以一种前所未有的方式&#x…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码

目录 一、&#x1f468;‍&#x1f393;网站题目 二、✍️网站描述 三、&#x1f4da;网站介绍 四、&#x1f310;网站效果 五、&#x1fa93; 代码实现 &#x1f9f1;HTML 六、&#x1f947; 如何让学习不再盲目 七、&#x1f381;更多干货 一、&#x1f468;‍&#x1f…...

Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问&#xff08;基础概念问题&#xff09; 1. 请解释Spring框架的核心容器是什么&#xff1f;它在Spring中起到什么作用&#xff1f; Spring框架的核心容器是IoC容器&#…...

MySQL 8.0 事务全面讲解

以下是一个结合两次回答的 MySQL 8.0 事务全面讲解&#xff0c;涵盖了事务的核心概念、操作示例、失败回滚、隔离级别、事务性 DDL 和 XA 事务等内容&#xff0c;并修正了查看隔离级别的命令。 MySQL 8.0 事务全面讲解 一、事务的核心概念&#xff08;ACID&#xff09; 事务是…...

Git 3天2K星标:Datawhale 的 Happy-LLM 项目介绍(附教程)

引言 在人工智能飞速发展的今天&#xff0c;大语言模型&#xff08;Large Language Models, LLMs&#xff09;已成为技术领域的焦点。从智能写作到代码生成&#xff0c;LLM 的应用场景不断扩展&#xff0c;深刻改变了我们的工作和生活方式。然而&#xff0c;理解这些模型的内部…...