零基础学习java------day7------面向对象
1. 面向对象
1.1 概述
面向过程:c语言
面向对象:java ;python;C++等等
面向对象的概念:
(万物皆对象)------think in java everything in an object
把现实中的事务抽象成由一系列属性和行为组成的结构体(类),每个结构体都有属于自己的功能,在软件开发的过程中,通过对不同功能的结构体进行组合,完成整个软件功能。且结构体可服用
例如; 若要将现实中的飞机抽象成一个对象
首先你要先定义一个飞机类(看到这个名字就知道是飞机),其次飞机的一些特征如有轮子,有机翼等,这些特征在抽象类中(即类中的代码中)怎么体现出来呢,这时我们就需要在类中定义一些属性来表示现实中飞机的这些特性。好了,一个飞机的固有属性描述完了。但是,其能飞的行为又该怎么来描述呢?这时就需要在类中定义一个‘’飞‘’的方法去表示飞机会飞的行为,飞机的其他行为,如加速减速都需要在类中定义方法去描述。当调用这些方法时,表示的就是飞机对应的行为(如,当调用“飞”方法时,表示的就是飞机飞的行为)。若是不同的飞机类型(如,歼-20,歼-10)该怎么表示呢?这里的话对象就起作用了,这里我们使用airplane1表示飞机歼-20,airplane2表示飞机歼-10,当用airplane1对象调用”飞”方法时,表示的是歼-20飞行的行为,当用airplane2对象调用“飞”方法时,表示的是歼-10飞行的行为。
OO: object-oriented 面向对象
ooa:面向对象的分析
ood:面向对象的设计
oop:面向对象的编程(program)
软件的生命周期:
需求分析,概要设计,详细设计,系统开发,系统测试,部署,运行和维护
需求:
存储全班同学的信息(姓名,性别,分数)
最直观的想法:利用3个数组去分别存储姓名,性别,分数,但这样不便于查找某个学生的性别和分数
所以就需要一种类型能够将姓名,性别,和分数聚合到一起,那就使用一种自定义的类型-------类
1.2 三大特征
封装 继承 多态 (抽象)
1.3 类和对象的关系
类:一种(引用)数据类型,自定义的一种数据类型
对象:具体存在的事物,符合类的定义特征
(1)类的定义:
class 类名{
// 属性,变量 // 行为,方法
}
类中需要注意的内容:
成员变量,成员方法,静态变量,静态方法,局部变量,构造方法
成员变量和静态变量的区别,一个加static一个不加 如static String name
成员方法和静态方法的区别:一个有static一个没有,静态方法是通过类名调用,而成员方法是通过对象调用
局部变量:定义在方法或者是方法的参数列表上的变量
(2) 如何创建对象:
类名 对象名 = new 类名()
(3) 给对象赋值
对象名.属性 = 要赋的值
案例
创建一个Teacher 类,包含属性: 姓名,性别,年龄; 定义一个讲课的行为,和自我介绍的方法(用于打印所有的属性值),创建三个老师对象创建到数组中
创建教师类
public class Teacher {
// 成员变量---属性
String name;
char gender;
int age;
double salary;
// 成员方法:无static修饰的方法
public void teaching() {
System.out.println("上课");
}
public void chuiNiu() {
System.out.println("吹牛");
}
public void show() {
System.out.println("我的姓名是" + name + ",性别是" + gender + ",今年" + age);
}
}
测试类
public class TeacherDemo1 {
public static void main(String[] args) {
// 创建对象
Teacher t1 = new Teacher();
t1.name = "老王";
t1.gender = '男';
t1.age = 25;
t1.salary = 4000;
t1.teaching();
t1.chuiNiu();
t1.show(); Teacher t2 = new Teacher();
t1.name = "小红";
t1.gender = '女'; //false表示女性
t1.age = 28;
t1.salary = 5000;
t1.teaching();
t1.chuiNiu();
t1.show(); }
1.4 内存分析
栈(stack):方法的执行,局部变量的存放,其没有初始值(有指向存放初始值地方(堆)的地址)
堆:new出来的事物,有初始值,基本数据类型初始值就是默认值,引用数据类型初始值为null
方法区:
class区:所有字节码文件(.calss),类加载的时候会把相关字节码文件加载到class区中,同时把用static修饰的事物存入到静态区
static区:用static修饰的东西
案例(注释中为运行结果)
public class TeacherDemo {
public static void main(String[] args) {
Teacher t = new Teacher(); // 上面中的teacher类
System.out.println(t); // com._51doit.javase.day7.Teacher@2ff4acd0(此叫全类名:包名+类名)
System.out.println(t.name); // null
System.out.println(t.age); // 0
System.out.println(t.salary); //0.0
}
}
运行的结果可通过内存分析来理解,如下
大致流程(这里自己也疑惑,就把视频中老师讲的话记录下来了,感觉老师没把这块讲清楚,等以后看jvm原理再来修改):
程序最开始不是从main方法开始执行,执行main方法前会有个加载的过程,得把类先加载到内存中才能执行。先执行main方法,而main方法的所在的类为TeacherDemo1,所以TeacherDemo1就得编译成.class文件。然后TeacherDemo1在编译的过程中发现用到了Teacher类,而要使用这个类,也得进行编译,并加载到内存当中,否则要用的话就找不到相应的类。其加载至class区域,即变成TeacherDemo1.class 和Teacher.class。紧接着会加载这两个字节码文件,加载的时候若发现有用static修饰的变量和方法就要将其放到static区域,如TeacherDemo1中的静态方法main就被存放到方法区中的static区,并给其一个地址假设为0x001(若是成员方法就存放在class区,本例中Teacher类中的成员变量都放到了class区)
当jvm执行时,其就会去找main方法(jvm只认识main方法),通过地址值找到static区域的main方法,然后就会去栈内存执行这个main方法。
首先Teacher t为局部变量,所以就被存储到栈的main方法中,而new Teacher()被存放到堆中,同时在堆中开辟了一个内存空间,用来存放从class区获取到的事务(此处时name,gender,age,salary)。由于放到堆里的事务都是有初始值的,所以就要进行赋值(按规则赋值,如int类型赋值0等),此时会赋予这个空间一个地址号,main方法中也会有此地址号(本例为7852e922),前者就可以通过地址号找到后者。Main方法执行完后就从栈中弹出去,因此栈中就无指向堆中的指针,堆中的new Teacher()就通过垃圾回收机制(GC)被回收掉。而方法区一般时jvm停掉后也没有了,只不过其存放的时间相比堆中会长点(方法存储区为内存永久带,不容易被回收)
以后整理可能有用的材料
假如在TeacherDemo类中再加入以下代码,运行的结果会是怎么样
t.name = "张三";
t.age = 13;
Teacher t1 = new Teacher();
t1.name = "李四";
t = t1;
System.out.println(t.name); // 李四
System.out.println(t1.name); // 李四
t.age = 80;
System.out.println(t1.age); // 80
分析如下图
1.5 成员变量和局部变量的区别
成员变量:定义在类中方法外的变量,没有static修饰;
局部变量:定义在方法中或者是方法的参数列表上的变量
区别:
(1)在类中的位置不同
成员变量:方法外,类内
局部变量:方法内或者方法的参数列表中
(2)在内存中的位置不同
成员变量:堆内存
局部变量:栈内存
(3)生命周期不同
成员变量:随着对象的存在而存在,随着对象的消失而消失
局部变量:随着方法的调用而存在,随着方法的调用完毕而消失
(4)初始化值不同
成员变量:有默认的初始值
局部变量:没有默认的初始化值,必须先定义,赋值,才能使用
1.6 匿名对象
匿名对象就是没有名字的对象,是对象的一种简化表现形式
匿名对象的两种使用情况:
(1)对象的调用方法仅仅一次的时候
(2)作为实际参数传递
package com._51doit.javase.day7; public class NoNameObjectDemo {
public static void main(String[] args) {
Teacher t = new Teacher();
// 调用属性时,一般会用命名后的对象.属性
System.out.println(t.name);
System.out.println(t.age);
// 下面就是匿名对象,其无名字,结果等价于上面代码
// 注意:下面两行代码相当于在堆中开辟了两个空间
// 匿名对象一般不用在调用属性,因为属性没有赋值,调用的也是默认值,没什么意义,所以匿名对象一般用在调用方法
System.out.println(new Teacher().name);
System.out.println(new Teacher().age);
}
}
为什么说对象的调用方法仅仅一次?
原因:若调用多次(如下),会创建多个对象,堆中就要开辟多个空间,但若不使用匿名对象,同样调用多次,只在堆中开辟一个空间,所以使用匿名对象这种情况会浪费空间
new Teacher().show()
new Teacher().show()
t.show()
t.show()
匿名对象作为实际参数传递
首先在
NoNameObjectDemo类中创建一个test方法,如下:
// 注意此处test方法要接受的参数类型为Teacher类型的参数
public static void test(Teacher t) {
t.show();
}
在main()方法中调用test()方法,代码如下
test(t);
test(new Teacher());// 此即为匿名对象作为参数传递
1.7 给类重命名的方法
第一种方式,在类文件上右键-->refactor-->rename
第二种方式,直接在雷伤改名(代码中),改完之后将光标放在类明上,根据自动提示,选择第一个
1.8 形参和实参
形参:定义方法时,方法参数列表上的变量
实参:调用方法时,传进去的具体值
注意:(1)基本数据类型作为参数,形参的改变不影响实参的值,如案例1
(2)引用数据类型作为参数时,形参的改变,影响实参的值(String和包装类除外),如案例2
包装类有8种(图中右边)
package com._51doit.javase.day7; public class ParamDemo {
public static void main(String[] args) {
sum(12,14); // 12,14为实参
}
public static void sum(int a,int b) { // int a和b为形参
System.out.println(a+b);
}
}
案例1
下面代码打印的a值为什么?
package com._51doit.javase.day7; public class ParamDemo {
public static void main(String[] args) {
int a = 10;
change(a);
System.out.println(a);
}
public static void change(int a) {
a = 100;
}
}
运行结果: a=10
解释:
首先执行main()方法(方法的执行时在栈中),所以在栈中就存有一个main方法(入栈),main()方法中有一个局部变量a,并将a存放到main方法中,紧接着是change()方法的执行,所以又会有一个change()方法入栈
change()方法执行完后就出栈,此处给change方法传了参数a=10,然后方法里面将a改成了100,但是修改后的a值并没有返回给main方法,所以a打印的值还是为10
案例2
下面代码打印的值为什么?
package com._51doit.javase.day7; public class ParamDemo {
public static void main(String[] args) {
int[] arr = new int[]{10,20};此处换成新建一个对象并传递给相应方法时也是一样的效果
change(arr);
System.out.println(arr[0]);
System.out.println(arr[1]);
}
public static void change(int[] arr) {
arr[0] = 100;
arr[1] = 200;
}
}
运行结果为:100,200
1.9 封装
(1)封装的概述:
指隐藏对象的属性和实现细节,仅对外提供公共访问方式。
(2)优点
隐藏实现细节;提高代码的复用性;提高安全性
(3)封装原则:
将不需要对外提供的内容都隐藏起来
把属性隐藏,提供公共方法对其访问
实现封装的步骤
成员变量私有化:用private修饰成员变量
权限修饰符:
public:修饰类,方法,变量;可在本项目中访问,跨包需要导包
(default):修饰类,方法,变量,什么都不加,只能在本包中使用
private:修饰方法,变量;被private修饰的方法和变量只能在本类中访问
提供get和set
get方法:获取属性值
public 返回属性的类型 getXxx(){return 属性}
set方法:修改属性值
public void setXxxx(属性类型 用来接收属性值的参数){属性变量名=用来接收属性值的参数}
注意点
(1)get方法中需要有返回值,所以public后需接返回属性的类型,但set方法不需要返回值,所以直接void就行(见案例3)
(2)this关键字:
用来区分同名的成员变量和局部变量,this指代成员变量,this看做是一个本类的对象,this所在的方法正在被哪个对象调用,this就指代哪个对象
public void setName(String name){
// 此处不加this的话就不能区分哪个是参数列表中的name哪个是成员变量name
this.name = name // 若去掉this就会报错
}
具体见案例2
案例1
创建一个BeautifulGirl类,其包含属性name,weight,legLenth,并创建一个BeautifulGirlDemo类,在此类中对BeautifulGirl中的属性进行赋值
package com._51doit.javase.day7.fz; public class BeautifulGirl {
String name;
double weight;
double legLenth;
}
创建一个BeautifulGirlDemo类
package com._51doit.javase.day7.fz; public class BeautifulGirlDemo {
public static void main(String[] args) {
BeautifulGirl b1 = new BeautifulGirl();
b1.name = "小红";
b1.legLenth = 150;
b1.weight = 80;
System.out.println(b1.weight);
System.out.println(b1.legLenth);
}
}
这种形式可以实现给类或者对象的属性赋值,但是不安全,使用者(此处是BeautifulGirl)可以随便修改类或者对象中的属性,很不安全,为了解决这个问题就出现了封装,如下
防止类中的属性被随意访问和修改,就要将变量私有化(加权限),代码如下
package com._51doit.javase.day7.fz; public class BeautifulGirl {
private String name;
private double weight;
private double legLenth;
}
改完之后,eclipse上就会显示这几个变量都未被使用,如下图
同时BeautifulGirlDemo类中的代码也出现了问题(The field BeautifulGirl.legLenth is not visible),如下
说明加上private的修饰后,BeautifulGirlDemo类就无法查看并修改BeautifulGirl类中的属性(变量)了,但有些时候又要给特定事务提供获取或修改该私有属性的方法,这个时候就用到了get方法和set方法,如下
案例2 使用封装的特性去实现案例1(这里为例方便,就只写出了一个name属性)
创建BeautifulGirl类
package com._51doit.javase.day7.fz; public class BeautifulGirl {
// 定义的私有属性
private String name;
// 定义返回name属性的get方法
public String getName() {
return name;
}
// 定义修改name属性的set方法
public void setName(String name) {
this.name = name;
}
}
创建BeautifulGirlDemo类
package com._51doit.javase.day7.fz; public class BeautifulGirlDemo {
public static void main(String[] args) {
BeautifulGirl b1 = new BeautifulGirl();
b1.setName("小红");
System.out.println(b1.getName());
}
}
// 运行的结果为小红,说明设置姓名以及访问这个姓名的属性成功
为什么说这种设置,访问类或对象属性的方法更安全呢?因为这里的设置或访问属性都是通过调用方法的形式进行的,这种情况下可以在方法中设置前提条件(案例3是在setName和getName方法中加前提条件),设置这个私有属性谁可以访问,谁可以修改等
练习
使用封装的特性创建一个Dog类,类中包括的属性分别为为name,furColor, gender, age, type,此外要提供get和set方法。在DogTest类中创建2个对象,使用set方法赋值,使用get方法获取值
创建Dog类
package com._51doit.javase.day7.fz; public class Dog {
private String name;
private String furColor;
private char gender;
private int age;
private String type;
// name属性的设置和查看
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
// furColor属性的设置和查看
public String getFurColor() {
return furColor;
}
public void setFurColor(String furColor) {
this.furColor = furColor;
}
// gender属性的设置和查看
public char getGender() {
return gender;
}
public void setGender(char gender) {
this.gender = gender;
}
// age属性的设置和查看
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
// type属性的设置和查看
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
创建DogTest类
package com._51doit.javase.day7.fz; public class DogTest {
public static void main(String[] args) {
Dog d1 = new Dog(); // 创建第一个对象d1
d1.setName("旺财");
d1.setFurColor("黑色");
d1.setGender('公');
d1.setAge(3);
d1.setType("土狗"); Dog d2 = new Dog(); // 创建第二个对象d2
d2.setName("富贵");
d2.setFurColor("黄色");
d2.setGender('母');
d2.setAge(2);
d2.setType("中华田园犬"); System.out.println(d1.getName()+","+d1.getFurColor()+","+d1.getGender()+","+d1.getAge()+","+d1.getType()); // 将属性获取并打印出来
System.out.println(d2.getName()+","+d2.getFurColor()+","+d2.getGender()+","+d2.getAge()+","+d2.getType());
}
}
1.10 构造方法
构造方法,也叫构造器(constructor),是类中比较特殊的一种方法
(1)格式
修饰符 类名(参数列表){方法体;}
注意事项:
1. 方法和类名相同
2. 没有返回值,连void都没有
3. 构造方法是可以重载的
(2)构造方法何时被调用?
使用new 关键字创建对象的时候,就是在调用构造方法
如果要调用其他的构造方法,只需要在new后面的括号中,传入相应的参数即可
注意:如果我们不在类中创建构造方法,那么系统会为我们自动生成无参数的构造方法,但若我们在类中写了构造方法,那么系统则不再为我们生成
案例1 上面dog类的练习中,利用构造方法给变量赋值(传参)
直接在Dog类中添加一下代码,如下
1 public class Dog {
2 public Dog() {};
3 public Dog(String name,int age,String furColor,String type,char gender) {
4 this.name = name;
5 this.furColor = furColor;
6 this.gender = gender;
7 this.age = age;
8 this.type = type;
9 };
10 //下面的代码同上诉Dog类
这时就不需要set来给变量赋值,直接在新创建的对象中传实参就行,如下
Dog d3 = new Dog("小强",12,"哈士奇","紫色",'母');
System.out.println(d3.getName()+","+d3.getFurColor()+","+d3.getGender()+","+d3.getAge()+","+d3.getType());
由低2和第3行的代码可知,构造方法是重载的,新建的对象会根据参数类型找相应的构造方法
注意:若将第二行代码去掉,则原先创建的无参数的对象就找不到对应的构造方法就会报错(自己创建了构造方法,就不会自动生成默认的无参数的构造方法了)
1.11 六大组件
成员变量
静态变量
局部变量
成员方法
静态方法
构造方法
1.12 给对象赋值的方式(前面内容也涉及,这里总结在一起)
第一种
对象名.属性名= 要赋的值
Teacher t = new Teacher();
t.name = “zhang san”;
第二种
使用set 方法:
t.setName(“李四”);
第三种
使用构造方法
Teacher t = new Teacher(“赵柳”,19);
class Teacher{
public Teacher(String name,int age){
this.name = name;
this.age = age;
}
}
1.13 作业
1. 定义一个类Demo,其中定义一个求两个数据和的方法,定义一个测试类Test,进行测试。
public class AddDemo {
double a;
double b;
public AddDemo(double a, double b) {
this.a = a;
this.b = b;
}
public double getSum() {
return a+b;
}
}
测试类
import java.util.Scanner; public class AddDemoTest {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入第一个数");
double a = sc.nextDouble();
System.out.println("请输入第一个数");
double b = sc.nextDouble();
AddDemo ad1 = new AddDemo(a, b);
System.out.println("两数的和为:" + ad1.getSum());
}
}
随意输入两个数,即可得到加和的值
2 定义一个长方形类,定义求周长和面积的方法,然后定义一个测试了Test2,进行测试。
public class Circle {
private double r;
private double pi;
// r的获取和设置
public double getR() {
return r;
}
public void setR(double r) {
this.r = r;
}
// pi的获取和设置
public double getPi() {
return pi;
}
public void setPi(double pi) {
this.pi = pi;
}
// 求圆面积
public double cirArea() {
return pi*r*r;
}
// 求圆的周长
public double cirGirth() {
return 2*pi*r;
}
}
测试类
import java.util.Scanner; public class CircleTest {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入r的值");
double r = sc.nextDouble();
System.out.println("请输入pi的值");
double pi = sc.nextDouble();
Circle c1 = new Circle();
c1.setR(r) ;
c1.setPi(pi);
System.out.println("圆的面积为:"+ c1.cirArea());
System.out.println("圆的周长为:"+ c1.cirGirth());
}
}
3. 定义一个员工类,自己分析出几个成员,然后给出成员变量,构造方法,getXxx()/setXxx()方法,以及一个显示所有成员信息的方法。并测试。
4. 定义一个类MyMath,提供基本的加减乘除(add,sub,mul,div)功能,然后进行测试。
零基础学习java------day7------面向对象的更多相关文章
- 音乐出身的妹纸,零基础学习JAVA靠谱么
问:表示音乐出身的妹纸一枚 某一天突然觉得身边认识的是一群程序员 突然想 要不要也去试试... 众好友都觉得我该去做个老师,可是我怕我会误人子弟,祸害祖国下一代..... 要不要 要不要 学Ja ...
- 总结了零基础学习Java编程语言的几个基础知识要点
很多Java编程初学者在刚接触Java语言程序的时候,不知道该学习掌握哪些必要的基础知识.本文总结了零基础学习Java编程语言的几个基础知识要点. 1先了解什么是Java的四个方面 初学者先弄清这 ...
- 零基础学Java第五节(面向对象一)
本篇文章是<零基础学Java>专栏的第五篇文章,文章采用通俗易懂的文字.图示及代码实战,从零基础开始带大家走上高薪之路! 本文章首发于公众号[编程攻略] 类与对象 在哲学体系中,可以分为主 ...
- 零基础学Java第六节(面向对象二)
本篇文章是<零基础学Java>专栏的第六篇文章,文章采用通俗易懂的文字.图示及代码实战,从零基础开始带大家走上高薪之路! 本文章首发于公众号[编程攻略] 继承 创建一个Person类 我们 ...
- 零基础学Java,PayPal技术专家手把手带你入门
在最权威的 TIOBE 编程语言排名榜单上,Java 常年稳居第一,可以说是世界上应用最为广泛的一门语言. 同时,在微服务.云计算.大数据.Android App 开发等领域,Java 也是当之无愧的 ...
- 零基础学Java第三节(基本输入输出)
本篇文章是<零基础学Java>专栏的第三篇文章,文章采用通俗易懂的文字.图示及代码实战,从零基础开始带大家走上高薪之路! 本文章首发于公众号[编程攻略] Java程序的命令行参数 我们可以 ...
- 如何从零基础学习VR
转载请声明转载地址:http://www.cnblogs.com/Rodolfo/,违者必究. 近期很多搞技术的朋友问我,如何步入VR的圈子?如何从零基础系统性的学习VR技术? 本人将于2017年1月 ...
- 【零基础学习iOS开发】【转载】
原文地址:http://www.cnblogs.com/mjios/archive/2013/04/24/3039357.html 本文目录 一.什么是iOS 二.主流手机操作系统 三.什么是iOS开 ...
- 李洪强iOS开发之【零基础学习iOS开发】【01-前言】01-开篇
从今天开始,我就开始更新[零基础学习iOS开发]这个专题.不管你是否涉足过IT领域,也不管你是理科生还是文科生,只要你对iOS开发感兴趣,都可以来阅读此专题.我尽量以通俗易懂的语言,让每个人都能够看懂 ...
- 零基础学习hadoop到上手工作线路指导
零基础学习hadoop,没有想象的那么困难,也没有想象的那么容易.在刚接触云计算,曾经想过培训,但是培训机构的选择就让我很纠结.所以索性就自己学习了.整个过程整理一下,给大家参考,欢迎讨论,共同学习. ...
随机推荐
- binary-tree-preorder-traversal leetcode C++
Given a binary tree, return the preorder traversal of its nodes' values. For example: Given binary t ...
- hdu 1159 Common Subsequence(最长公共子序列,DP)
题意: 两个字符串,判断最长公共子序列的长度. 思路: 直接看代码,,注意边界处理 代码: char s1[505], s2[505]; int dp[505][505]; int main(){ w ...
- APP自动化环境搭建之appium工具介绍(二)
1.下载解压android-sdk-windows-appium //配置环境: ANDROID_HOME:D:\android-sdk-windows-appium path:...;%ANDROI ...
- CSS 海盗船加载特效
CSS 海盗船加载特效 <!DOCTYPE html> <html lang="en"> <head> <meta charset=
- 将python代码转化为c语言代码,提高运行效率
将python代码转化为c语言代码,提高运行效率 首先,需要安装cpython库: pip install cython 安装完成之后,写一段简单的代码,例如下面这个利用递归求斐波那契数列的函数,然后 ...
- 『学了就忘』Linux基础命令 — 36、查看系统痕迹相关命令
目录 1.w命令 2.who命令 3.last命令 4.lastlog命令 5.lastb命令 系统中有一些重要的痕迹日志文件,如/var/log/wtmp./var/run/utmp./var/lo ...
- es添加index template
在kibana页面选择最下方的management--elasticsearch--Index Management--Index Management 选择create a template添加in ...
- Linux服务——二、配置NFS及autofs自动挂载服务
一.NFS服务配置步骤 NFS的作用:能够使两台虚拟机之间实现文件共享.数据同步 准备:主机名.网络.yum源 Server端: 1.安装nfs-util和rpcbind:(图形化自带) [root@ ...
- 如何正确的找BUG
什么是BUG 漏洞是在硬件.软件.协议的具体实现或系统安全策略上存在的缺陷,从而可以使攻击者能够在未授权的情况下访问或破坏系统.具体举例来说,比如在Intel Pentium芯片中存在的逻辑错误,在S ...
- [hdu7074]Little prince and the garden of roses
显然每种颜色的花是独立的,可以分别求出答案后取$\max$ 对于某种颜色$C$,建立一张二分图,左右分别为$n$行$n$列,且第$i$行和第$j$列有边当且仅当$c_{i,j}=C$ 此时,问题即对边 ...