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

Java基础知识

一、标识符规范

标识符必须以字母(汉字)、下划线、美元符号开头,其他部分可以是字母、下划线、美元符号,数字的任意组合。谨记不能以数字开头。java使用unicode字符集,汉字也可以用该字符集表示。因此汉字也可以用作变量名。
关键字不能用作标识符。
类名首字母需大写(Welcome)、方法和变量名遵循驼峰原则 snRsfService()

二、数据类型

java的数据类型由8种基本数据类型和多种引用数据类型构成。

1. 基本数据类型

1.1数值型

数值型又分为整数类型和浮点类型。

long l = 10000000000L;   //整型数据默认是int, 转成long后面要加 L 或 l
float f = 3.14F;   //浮点常量默认是double,改成float后面要加F 或 f

  <一些可有可无的科普:计算机底层浮点数表示方法>
  在计算机底层float和double都是由IEEE754标准进行储存的,该标准将浮点数分成符号位、指数位、尾数位。分配如下:
单精度浮点数float:32bit(4字节)
1bit(符号位)
8bits(指数位) 
23bits(尾数位)

双精度浮点数double:64bit(8字节)
1bit(符号位)
11bits(指数位)
52bits(尾数位)
数据的表示范围是由指数的位数来决定的。float的指数位有8位,能表示0-255一共256个状态。加之IEEE标准规定有127的偏移量,float的指数最大值为128。float的范围为-2^128 ~ +2^128,也即-3.40E+38 ~ +3.40E+38;double范围的计算方法和float同理。double的范围为-2^1024 ~ +2^1024,也即-1.79E+308 ~ +1.79E+308。
精确度是由尾数的位数来决定的。float的尾数位有23位,能表示最大7位十进制数字,但实际精度取决于浮点数的具体值。double的尾数位有52位,能表示最大16位十进制数字,但实际精度同样取决于浮点数的具体值。
(尽量不要在比较和金额计算中使用浮点数,精确计算用BigDecimal)

1.2 字符型

内存中占2个字节,unicode就是用char表示的

1.3 布尔型

在内存中占1 或4个字节(JVM用int表示bool,CPU层面有利于高效存取)

2. 引用数据类型

类(Class):自定义的类。类是对象的模板,它定义了对象的属性和方法。
接口(Interface):一种完全抽象的类,它只包含常量和方法的声明,没有实现。接口可以被类实现,以实现特定的行为。
数组(Array):一种数据结构,用于存储固定大小的同类型元素集合。
字符串(String):一种特殊的对象,用于表示文本数据。Java中的字符串是不可变的,一旦创建就不能修改其内容。
包装类(Wrapper Classes):基本数据类型的封装类,如Integer、Double、Character等。它们提供了基本数据类型到对象类型的桥梁,并提供了额外的功能。
其他自定义对象:除了上述提到的类型外,还包括用户自定义的类、枚举(Enum)、注解(Annotation)等。

三、关键字

1. static

static修饰变量:静态变量又称为类变量,也就是说这个变量属于类的,类所有的实例都共享静态变量,可以直接通过类名来访问它。静态变量在内存中只存在一份

static修饰函数:静态方法在类加载的时候就存在了,它不依赖于任何实例。所以静态方法必须有实现,也就是说它不能是抽象方法。

static修饰代码块:静态代码块在类构造函数之前被执行。

2. final

final修饰变量:修饰基本数据类型时,表示这个变量值不可变。

final修饰引用数据类型:表示这个变量引用不可变,但引用的对象具体内容是可以改变的(比如对象的某个属性值是可变的)。

final修饰方法:表示此方法不可被子类重写。

final修饰类:表示此类不可以被继承。

3. this

this的本质就是当前对象的地址。普通方法中,this指向调用该方法的对象。构造方法中,指向正要初始化的对象。

class User{int id;String name;String pwd;User(){}public User(int id, String name){this.id = id;this.name = name;}public User(int id, String name, String pwd){this(id, name);//构造方法重载,该种调用必须位于构造方法的第一行this.pwd = pwd;}
}

 4. super

super可以看做父类对象的引用,但是创建子类对象的过程并没有产生父类对象,super代表当前对象的父类型特征。在一个类中,如果构造方法的第一行代码没有显式的使用super()或this(),那么java都会默认调用super()

5. String StringBuilder StringBuffer

String表示字符串,从jdk1.0开始就出现了。从Java7版本开始存在于堆中的字符串常量池中。其底层使用一个数组进行存放,在JAVA8中是一个char数组,而在JAVA9中是一个byte数组,并且这个数组使用final进行修饰,表示不可变的。所以String类是天生线程安全的。

StringBuffer是为了解决String类在内容频繁变化时,性能不高这个问题。表示的是一个可变长度字符串,他也是在Jdk1.0中就出现了,其内部的方法都是被Synchronized修饰,所以他是线程安全的。并且在stringBuffer有个缓存数组一直缓存变化着的内容(缓存最后一个值)。它的toString方法的返回值就是这个缓存数组的String对象。这一点和stringBuilder不一样,stringbuilder的tostring返回值是通过存储他的那个数组创建的。

虽然说这一点不同StringBuilder也是表示可变长度字符串。他是从JDK1.5开始出现的,其方法没有被Synchronized修饰,是非线程安全的,但它的性能相对于StringBuilder更高。

四、方法与对象

1. 方法重载的条件

形参类型,个数,顺序不同即可构成方法重载。只有返回值不同不构成方法重载,会报编译错误。

2. 对象实例化的方式

2.1 new

2.2 clone()

2.3 通过反射机制创建

//用 Class.forName方法获取类,在调用类的newinstance()方法
Class<?> cls = Class.forName("com.dao.User");
User u = (User)cls.newInstance();

2.4 序列化反序列化

//将一个对象实例化后,进行序列化,再反序列化,也可以获得一个对象(远程通信的场景下使用)
ObjectOutputStream out = new ObjectOutputStream (new FileOutputStream("D:/data.txt"));
//序列化对象
out.writeObject(user1); 
out.close();
//反序列化对象
ObjectInputStream in = new ObjectInputStream(new FileInputStream("D:/data.txt"));
User user2 = (User) in.readObject();
System.out.println("反序列化user:" + user2);
in.close();

 3. 对象复制的方式

通过构造方法、通过对象的值、通过object的clone方法。

//通过构造方法
TestClone tc = new TestClone();
tc.name = 123;
TestClone tc2 = new TestClone(tc);
//通过对象的值
直接将老对象的值挨个复制给新对象即可
//通过object的clone方法
通过该方式复制对象时必须重写cloneable的clone方法。

 4. 深拷贝与浅拷贝的区别

浅拷贝:仅仅克隆基本类型变量,不克隆引用类型变量;

深拷贝:既克隆基本类型变量,又克隆引用类型变量;

五、面向对象特性

1. 封装

将对象的属性包裹起来,并通过接口控制访问。高内聚低耦合,并隐藏实现细节,安全性高。

2. 继承

java类没有多继承,即子类只能继承一个父类,接口有多继承。子类继承父类可以得到除构造方法外的全部非私有属性和方法。java.lang.Object是所有类的父类。

//instanceof 判断对象是否是某个类的实例对象
Stu stu = new Stu();
System.out.print(stu instanceof Stu);

3. 多态

同一个方法调用,由于对象不同,可能有不同的行为。多态是方法的多态不是属性的多态。优点是简化灵活,替换性强,可拓展性高。 

三个必要条件是重写,继承和父类引用指向子类对象。

当指向子类对象的父类引用,调用子类重写的父类方法时,多态就出现了。

public class Test {public static void main(String[] args) {show(new Cat());  // 以 Cat 对象调用 show 方法show(new Dog());  // 以 Dog 对象调用 show 方法Animal a = new Cat();  // 向上转型  a.eat();               // 调用的是 Cat 的 eatCat c = (Cat)a;        // 向下转型  c.work();        // 调用的是 Cat 的 work}  public static void show(Animal a)  {a.eat();  // 类型判断if (a instanceof Cat)  {  // 猫做的事情 Cat c = (Cat)a;  c.work();  } else if (a instanceof Dog) { // 狗做的事情 Dog c = (Dog)a;  c.work();  }  }  
}abstract class Animal {  abstract void eat();  
}  class Cat extends Animal {  public void eat() {  System.out.println("吃鱼");  }  public void work() {  System.out.println("抓老鼠");  }  
}  class Dog extends Animal {  public void eat() {  System.out.println("吃骨头");  }  public void work() {  System.out.println("看家");  }  
}

六、抽象类

使用abstract修饰的类是抽象类,包含抽象方法的类是抽象类。 

//模板方法模式(抽象类的应用)
public abstract class DBOperator {//1. 建立连接  2. 打开数据库  3. 使用数据库  4. 关闭连接public abstract void connection();public void open(){System.out.println("打开数据库");}public void use(){System.out.println("使用数据库");}public void close(){System.out.println("关闭连接");}public void process(){connection();open();use();close();}public static void main(String[] args) {
//        new MySqlOperator().process();new OracleOperator().process();}}class MySqlOperator extends DBOperator {@Overridepublic void connection() {System.out.println("建立和Mysql数据库的连接");}
}class OracleOperator extends  DBOperator {@Overridepublic void connection() {System.out.println("建立和Oracle数据库的连接");}
}

七、接口

由全局常量(public static final 可省略)、抽象方法(public abstract)、默认方法(public default)、静态方法(public static)组成,其中方法的public可省略。java9中接口可以包含只能被接口内部调用的私有方法。
常量:接口中可以定义常量,这些常量默认是public static final的,即它们是公共的、静态的、不可变的。接口不能包含变量。
抽象方法:接口中可以包含抽象方法,这些方法只有方法签名,没有方法体。抽象方法默认是public abstract的,即它们是公共的、抽象的。实现接口的类必须提供接口中所有抽象方法的具体实现。
默认方法:这些方法有方法体,因此可以提供默认实现。可以被重写。
静态方法:这些方法有方法体,可以直接通过接口名调用,而不需要实现类的实例。静态方法使用static关键字定义,实现类不能重写接口的静态方法。静态方法只能调用接口中的其他静态方法或私有静态方法。
命名冲突问题:
对于一个实现了多个接口且继承自某一个父类的子类,如果方法名和形参列表相同,会发生命名冲突。若父类的方法和接口默认方法名冲突,则父类优先。若多个接口默认方法导致命名冲突,则子类需重写该方法。

八、内部类

为了方便使用外部类相关的属性和方法,通常会在开发中定义一个内部类。

内部类可以直接访问外部类的私有属性,但外部类不能访问内部类的属性。内部类被当成外部类的成员。SubList就是ArrayList的内部类。

//非静态内部类初始化
Outer.Inner inner = new Outer().new Inner();
//静态内部类初始化
Outer.Inner inner = new Outer.Inner();//匿名内部类,适合只使用一次的类
/**目标:掌握匿名内部类的使用形式*/
public class Test {public static void main(String[] args) {//使用匿名内部类替代学生类,创建的类型是new的那个类的子类Swimming s = new Swimming() {@Overridepublic void Swim() {System.out.println("学生游的很快");}};go(s);}/**方法:学生、老师、运动员可以一起游泳*/public static void go(Swimming s){System.out.println("开始游泳了~~");s.Swim();System.out.println("结束游泳了~~");}
}
//创建学生类
/*class Student implements Swimming{@Overridepublic void Swim() {System.out.println("学生游的很快");}
}*///定义一个接口规范游泳
interface Swimming{void Swim();
}

九、包装类

包装类与基本数据类型的转换过程就是java的自动装箱与拆箱,在性能敏感的应用中,过度使用会导致性能下降,因为需要额外的内存分配和垃圾回收。

Integer ele = new Integer(10);
int ele3 = ele.intValue();//自动装箱
Integer ele2 = 10;
//自动拆箱
int ele4= ele;//Integer包装类缓存范围[-128,127]
Integer a = 100;
Integer b = 100;
System.out.println(a==b);//true
Integer a1 = 200;
Integer b1 = 200;
System.out.println(a1==b1);//false

<一些不必要的知识点:包装类默认缓存范围>
Boolean:true和false
Integer:-128~127
Byte:-128~127
Character:0~127
Short:-128~127
Long:-128~127
Float和Double无缓存

十、异常机制

java中的异常都继承自Throwable类,分为Error和Exception。Error表示编译或系统错误,如OOM和StackOverFlow。Exception表示程序可以捕获或处理的异常,又分为运行时异常和非运行时异常。

RuntimeException 是运行时异常,这类异常是不受检查的,需要程序员自己决定要不要做处理。RuntimeException 以外的异常都属于非运行时异常。例如 IOException、ClassCastException 等以及用户自定义的 Exception 异常等。

<一些不必要的知识点:try-cache-finally 与 try-with-resouce>

前者中的finally一定会被运行,但遇见如下情况不会执行:比如退出程序,finally 语句块中发生了异常,还有程序所在的线程死亡。try-with-resouce可以保证运行结束后每个资源都被自动关闭。任何实现了 java.lang.AutoCloseable 的对象, 包括所有实现了 java.io.Closeable 的资源对象, 都可以用它进行关闭。

public class MyAutoClosable implements AutoCloseable {public void doIt() {System.out.println("MyAutoClosable doing it!");}@Overridepublic void close() throws Exception {System.out.println("MyAutoClosable closed!");}public static void main(String[] args) {try(MyAutoClosable myAutoClosable = new MyAutoClosable()){myAutoClosable.doIt();} catch (Exception e) {e.printStackTrace();}}
}

十一、泛型

(待施工)

相关文章:

Java基础知识

一、标识符规范 标识符必须以字母(汉字)、下划线、美元符号开头&#xff0c;其他部分可以是字母、下划线、美元符号&#xff0c;数字的任意组合。谨记不能以数字开头。java使用unicode字符集&#xff0c;汉字也可以用该字符集表示。因此汉字也可以用作变量名。 关键字不能用作…...

并发编程-Synchronized

什么是Synchronized synchronized是Java提供的一个关键字&#xff0c;Synchronized可以保证并发程序的原子性&#xff0c;可见性&#xff0c;有序性。 我们会把synchronized称为重量级锁。主要原因&#xff0c;是因为JDK1.6之前&#xff0c;synchronized是一个重量级锁相比于J…...

C语言——从头开始——深入理解指针(1)

一.内存和地址 我们知道计算上CPU&#xff08;中央处理器&#xff09;在处理数据的时候&#xff0c;是通过地址总线把需要的数据从内存中读取的&#xff0c;后通过数据总线把处理后的数据放回内存中。如下图所示&#xff1a; 计算机把内存划分为⼀个个的内存单元&#xff0c;每…...

微信小程序-绑定数据并在后台获取它

如图 遍历列表的过程中需要绑定数据&#xff0c;点击时候需要绑定数据 这里是源代码 <block wx:for"{{productList}}" wx:key"productId"><view class"product-item" bindtap"handleProductClick" data-product-id"{{i…...

【删除数组用delete和Vue.delete有什么区别】

删除数组用delete和Vue.delete有什么区别&#xff1f; 在 JavaScript 中&#xff0c;delete 和 Vue.js 中的 Vue.delete 是两个完全不同的概念&#xff0c;它们在删除数组元素时的作用和效果也有所不同。 JavaScript 中的 delete 关键字&#xff1a; 在原生 JavaScript 中&a…...

【QT+QGIS跨平台编译】之四十二:【QWT+Qt跨平台编译】(一套代码、一套框架,跨平台编译)

文章目录 一、QWT介绍二、QWT下载三、文件分析四、pro文件五、编译实践5.1 Windows下编译4.2 Linux下编译5.3 MacOS下编译一、QWT介绍 QWT是一个基于Qt框架的开源C++库,用于创建交互式的图形用户界面。它提供了丰富的绘图和交互功能,可以用于快速开发图形化应用程序。 QWT包…...

yum方式快速安装mysql

问题描述 使用yum的方式简单安装了一下mysql&#xff0c;对过程进行简单记录。 步骤 ①安装wget和vim sudo yum -y install wget vim②下载mysql的rpm包 sudo wget https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm③升级和更新rpm包 sudo rpm -Uv…...

基于Java的家政预约管理平台

功能介绍 平台采用B/S结构&#xff0c;后端采用主流的Springboot框架进行开发&#xff0c;前端采用主流的Vue.js进行开发。 整个平台包括前台和后台两个部分。 前台功能包括&#xff1a;首页、家政详情、家政入驻、用户中心模块。后台功能包括&#xff1a;家政管理、分类管理…...

C语言前世今生

C语言前世今生 C语言的发展历史 C语言于1972年11月问世&#xff0c;1978年美国电话电报公司&#xff08;AT&T&#xff09;贝尔实验室正式发布C语言&#xff0c;1983年由美国国家标准局&#xff08;American National Standards Institute&#xff0c;简称ANSI&#xff09…...

android aidl进程间通信封装通用实现-用法说明

接上一篇&#xff1a;android aidl进程间通信封装通用实现-CSDN博客 该aar包的使用还是比较方便的 一先看客户端 1 初始化 JsonProtocolManager.getInstance().init(mContext, "com.autoaidl.jsonprotocol"); //客户端监听事件实现 JsonProtocolManager.getInsta…...

【Java中23种设计模式-单例模式2--懒汉式线程不安全】

加油&#xff0c;新时代打工人&#xff01; 今天&#xff0c;重新回顾一下设计模式&#xff0c;我们一起变强&#xff0c;变秃。哈哈。 23种设计模式定义介绍 Java中23种设计模式-单例模式 package mode;/*** author wenhao* date 2024/02/19 09:16* description 单例模式--懒…...

【后端高频面试题--Linux篇】

&#x1f680; 作者 &#xff1a;“码上有前” &#x1f680; 文章简介 &#xff1a;后端高频面试题 &#x1f680; 欢迎小伙伴们 点赞&#x1f44d;、收藏⭐、留言&#x1f4ac; 后端高频面试题--Linux篇 往期精彩内容Windows和Linux的区别&#xff1f;Unix和Linux有什么区别…...

网络原理HTTP/HTTPS(2)

文章目录 HTTP响应状态码200 OK3xx 表示重定向4xx5xx状态码小结 HTTPSHTTPS的加密对称加密非对称加密 HTTP响应状态码 状态码表⽰访问⼀个⻚⾯的结果.(是访问成功,还是失败,还是其他的⼀些情况…).以下为常见的状态码. 200 OK 这是⼀个最常⻅的状态码,表⽰访问成功 2xx都表示…...

【Java中23种设计模式-单例模式2--懒汉式2线程安全】

加油&#xff0c;新时代打工人&#xff01; 简单粗暴&#xff0c;学习Java设计模式。 23种设计模式定义介绍 Java中23种设计模式-单例模式 Java中23种设计模式-单例模式2–懒汉式线程不安全 package mode;/*** author wenhao* date 2024/02/19 09:38* description 单例模式…...

由LeetCode541引发的java数组和字符串的转换问题

起因是今天在刷下面这个力扣题时的一个报错 541. 反转字符串 II - 力扣&#xff08;LeetCode&#xff09; 这个题目本身是比较简单的&#xff0c;所以就不讲具体思路了。问题出在最后方法的返回值处&#xff0c;要将字符数组转化为字符串&#xff0c;第一次写的时候也没思考直…...

HTTP 头部- Origin Referer

Origin & Referer Origin Header 示例 Origin 请求头部是一个 HTTP 头部&#xff0c;它提供了发起请求的网页的源&#xff08;协议、域名和端口&#xff09;信息。它通常在进行跨域资源共享&#xff08;CORS&#xff09;请求时使用&#xff0c;以便服务器可以决定是否接受…...

Python 实现Excel 文件合并

Excel 文件合并方法较多,前面文章有通过Uipath RPA 对文件进行合并,也可以通过Python或VBA写脚本合并。 通常写脚本维护性更加简洁,本文提供Python 脚本对Excel 文件进行合并,参考Uipath 调用Python 文章,Uipath 调用Python 脚本程序详解-CSDN博客 便能快速实现。代码如…...

ECMAScript 6+ 新特性 ( 一 )

2.1.let关键字 为了解决之前版本中 var 关键字存在存在着越域, 重复声明等多种问题, 在 ES6 以后推出 let 这个新的关键字用来定义变量 //声明变量 let a; let b,c,d; let e 100; let f 123, g hello javascript, h [];let 关键字用来声明变量&#xff0c;使用 let 声明的…...

动态DP入门线性动态DP

动态DP入门&线性动态DP 前言核心思想例1例22024牛客寒假4K2022牛客寒假2J结论 前言 OI-WiKi上有一个动态DP讲解&#xff0c;直接讲到了树型DP领域&#xff0c;同时需要树链剖分&#xff0c;门槛有点高。本文针对线性DP做一个动态DP的讲解。 首先当然要懂得一定的DP的相关…...

基于python+django+vue.js开发的停车管理系统

功能介绍 平台采用B/S结构&#xff0c;后端采用主流的Python语言进行开发&#xff0c;前端采用主流的Vue.js进行开发。 功能包括&#xff1a;车位管理、会员管理、停车场管理、违规管理、用户管理、日志管理、系统信息模块。 源码地址 https://github.com/geeeeeeeek/pytho…...

网站管理新利器:免费在线生成 robots.txt 文件!

&#x1f916; 探索网站管理新利器&#xff1a;免费在线生成 robots.txt 文件&#xff01; 你是否曾为搜索引擎爬虫而烦恼&#xff1f;现在&#xff0c;我们推出全新的在线 robots.txt 文件生成工具&#xff0c;让你轻松管理网站爬虫访问权限&#xff0c;提升网站的可搜索性和…...

【Java程序员面试专栏 Java领域】Java虚拟机 核心面试指引

关于Java 虚拟机部分的核心知识进行一网打尽,主要包括Java虚拟机的内存分区,执行流程等,通过一篇文章串联面试重点,并且帮助加强日常基础知识的理解,全局思维导图如下所示 JVM 程序执行流程 包括Java程序的完整执行流程,以及Javac编译,JIT即时编译 Java程序的完整执…...

洛谷C++简单题小练习day15—计算阶乘小程序(不用循环)

day15--计算阶乘小程序--2.19 习题概述 题目描述 求 n!&#xff0c;也就是 123⋯n。 挑战&#xff1a;尝试不使用循环语句&#xff08;for、while&#xff09;完成这个任务。 输入格式 第一行输入一个正整数 n。 输出格式 输出一个正整数&#xff0c;表示 n! 代码部分 …...

Vue报错,xxx is defined #变量未定义

vue.js:5129 [Vue warn]: Error in v-on handler: "ReferenceError: count is not defined" 浏览器将这个变量 当做全局变量了&#xff0c;事实上它只是实例中的变量 加上this指定&#xff0c;是vue实例中的变量...

Idea启动Gradle报错: Please, re-import the Gradle project and try again

Idea启动Gradle报错&#xff1a;Warning:Unable to make the module: reading, related gradle configuration was not found. Please, re-import the Gradle project and try again. 解决办法&#xff1a; 开启步骤&#xff1a;View -> Tool Windows -> Gradle 点击refe…...

Python函数(一)

目录 一、定义函数 &#xff08;一&#xff09;向函数传递信息 &#xff08;二&#xff09;实参和形参 二、传递实参 &#xff08;一&#xff09;位置实参 &#xff08;二&#xff09;关键字实参 &#xff08;三&#xff09;默认值 &#xff08;四&#xff09;等效的函…...

Excel表的内容批量生成个人加水印的Word文档

Excel表的内容批量生成个人加水印的Word文档 以下代码可以直接复制到docm文件里使用 Sub 宏1()Dim MyDialog As FileDialogDim GetStr As String, Adoc As StringDim PsDoc As DocumentApplication.ScreenUpdating FalseSet MyDialog Application.FileDialog(msoFileDialogF…...

微服务设计:Spring Cloud API 网关概述

Spring Cloud API 网关是指一个位于微服务架构中的代理服务器&#xff0c;它负责将外部请求路由到内部微服务。API 网关可以提供多种功能&#xff0c;包括&#xff1a; 路由: 将请求路由到特定的微服务。负载均衡: 将请求分散到多个微服务实例上。安全: 身份验证、授权和安全策…...

stm32学习笔记-STLINK使用

stm32学习笔记-STLINK使用 使用ST-LINK调试程序进度表格 使用ST-LINK调试程序 说明 组成 总结 记录使用STLINK进行项目的烧写和调试&#xff0c;旨在高效的进行代码调试学习工具包括笔记本、keil5MDK、stm32f030c8t6电表主机、STLINK V2、导线、电表代码总的来说&#xff0…...

Linux CentOS stream 9 firewalld

随着互联网行业快速发展&#xff0c;服务器成为用户部署网络业务重要的网络工具&#xff0c;但随之而来的就是更密集的网络攻击&#xff0c;这给网站带来了很大的阻碍。防火墙作为保障网络安全的主要设备&#xff0c;可以很好的抵御网络攻击。 防火墙基本上使用硬件和软件两种…...