194,对象内存布局

基本数据类型放在堆里面,字符串类型放在方法区。

栈:一般存放基本数据类型(局部变量)

堆:存放对象(Cat cat,数组等)

方法区:常量池(常量,比如字符串),类加载信息

196,属性注意细节

1,属性可以是基本数据类型,也可以是引用类型(对象,数组)

2,属性的定义语法同变量,示例:访问修饰符 属性类型 属性名;这里简单介绍访问修饰符:控制属性的访问范围。有四种访问修饰符 public,protected,默认,private。

3,属性如果不赋值,有默认值,规则和数组一致。具体说:int   0,short   0,byte  0,long  0,float  0.0,double  0.0,char   \u0000,boolean false,String null。

public class test1{
public static void main(String[] args){
//创建Person对象
//p1 是对象名(对象引用)
Person p1 = new Person();//new Person() 创建的对象空间(数据)才是真正的对象 System.out.println("\n当前这个人的信息");
System.out.println("age = " + p1.age + " name = " + p1.name + " sal = " + p1.sal + " isPass = " + p1.isPass);
}
}
class Person{
//四个属性
int age;
String name;
double sal;
String isPass;
}

运行结果:

198,对象分配机制

引用赋值,即地址赋值

199,对象创建过程

1,先加载Person类信息(属性和方法信息,只会加载一次)

2,在堆中分配空间,进行默认初始化(看规则)

3,把地址赋给 p ,p 就指向对象 Person p = new Person()

4,进行指定初始化,比如 p.name = "jack"

206,方法使用细节

1,一个方法最多有一个返回值 [思考,如何返回多个结果,返回数组]

2,返回类型可以为任意类型,包含基本类型或引用类型(数组,对象)

public class test1{
public static void main(String[] args){
AA a = new AA();
int[] res = a.getSumAndSub(1,2);//用一个数组接收
System.out.println("和 = " + res[0]);
System.out.println("差 = " + res[1]);
}
}
class AA{
public int[] getSumAndSub(int n1, int n2)
{
int[] resArr = new int[2];//创建一个数组
resArr[0] = n1 + n2;
resArr[1] = n1 - n2;
return resArr;
}
}

运行结果:

3,如果方法要求有返回数据类型,则方法体中最后的执行语句必须为 return 值(值为常量或表达式);而且要求返回值类型必须和 return 的值类型一致或兼容(会发生自动类型转换)

4,如果方法是 void ,则方法体中可以没有 return 语句,或者只写 return;

5,接207;一个方法可以有0个参数,也可以有多个参数,中间用逗号隔开

6,调用带参数的方法时,一定对应着参数列表传入相同类型或兼容类型的参数

7,方法定义时的参数称为形式参数,简称形参;方法调用时的传入参数称为实际参数,简称实参,实参和形参的类型要一致或兼容,个数,顺序必须一致

8,方法体里面写完功能的具体的语句,可以为输入,输出,变量,运算,分支,循环,方法调用,但里面不能再定义方法!即:方法不能嵌套定义。

9,同一个类中的方法调用:直接调用即可。(我们想在A类里的一个方法里去调用A类里的另一个方法,直接调用即可)

public class test1{
public static void main(String[] args){
A a = new A();
a.sayOk();
}
}
class A{
public void print(int n)
{
System.out.println("print()方法被调用 n = " + n);
}
public void sayOk()// sayOk 调用 print(直接调用即可)
{
print(10);
System.out.println("继续执行sayOk");
}
}

运行结果:

10,跨类中的方法A类调用B类方法:需要通过对象名调用。(我们想在A类的一个方法里调用B类的一个方法,需要在A类的这个方法里创建B类的对象,再用B类的对象调用B类的一个方法)。

public class test1{
public static void main(String[] args){
A a = new A();
a.m1();
}
}
class A{
public void m1()
{
System.out.println("m1() 方法被调用");
B b = new B();//创建B对象
b.hi();
System.out.println("m1() 方法继续执行");
}
}
class B{
public void hi()
{
System.out.println("B类中的 hi() 被执行");
}
}

运行结果:

11,特别说明一下:跨类的方法调用和方法的访问修饰符相关,后面会细说。

213,克隆对象

编写一个方法 copyPerson,可以复制一个 Person 对象,返回复制的对象。克隆对象,注意要求得到新对象和原来的对象是两个独立的对象,只是他们的属性相同。

public class test1{
public static void main(String[] args){
Person p = new Person();
p.name = "milan";
p.age = 100;
//创建tools对象
MyTools tools = new MyTools();
Person p2 = tools.copyPerson(p); //到此 p 和 p2 是 Person对象,但是是两个独立的对象,属性相同
System.out.println("p的属性 age = " + p.age + " 名字 = " + p.name);
System.out.println("p2的属性 age = " + p2.age + " 名字 = " + p2.name);
}
}
class Person{
String name;
int age;
}
class MyTools{
//方法的返回类型 Person
// 方法的名字 copyPerson
// 方法的形参(Person p)
//方法体,创建一个新对象,并复制属性,返回即可
public Person copyPerson(Person p)
{
Person p2 = new Person();
p2.name = p.name;//把原来对象的名字赋给p2.name
p2.age = p.age;//把原来对象的年龄赋给p2.age
return p2;
}
}

运行结果:

218,递归执行机制

1,执行一个方法时,就创建一个新的受保护的独立空间(栈空间)

2,方法的局部变量是独立的,不会相互影响,比如n变量

3,如果方法中使用的是引用类型变量(比如数组),就会共享该引用类型的数据

4,递归必须向退出递归的条件逼近,否则就是无限递归,出现StackOverflowError

5,当一个方法执行完毕,或者遇到return,就会返回,遵守谁调用,就将结果返回给谁,同时当方法执行完毕或者返回时,该方法也就执行完毕。

220,猴子吃桃

有一堆桃子,猴子第一天吃了其中的一半,并再多吃了一个!以后每天猴子都吃其中的一半,然后再多吃一个。当到了第10天时,想再吃时(即还没吃完),发现只有1个桃子了。问题:最初共多少个桃子?

(已知第10天只剩1个桃子,猴子每天都吃其中的一半,并多吃一个。假设第9天有 x 个桃子,第 10天有 y 个桃子,(x / 2) - 1 = y,x = (y + 1) * 2)

思路:逆推

1,day = 10 时,有 1 个桃子

2,day = 9 时,有 (day10 + 1)* 2 = 4

3,day = 8 时,有 (day9 + 1)* 2 = 10

4,规律就是  前一天的桃子 = (后一天的桃子 + 1)* 2

5,递归

public class test1{
public static void main(String[] args){
T t = new T();
int day = 1;
int peachNum = t.peach(day);
if(peachNum != -1)
{
System.out.println("第" + day + "天有" + peachNum + "个桃子");
}
}
}
class T{
public int peach(int day)
{
if(day == 10)
{
return 1;
}else if(day >= 1 && day <= 9)
{
return (peach(day + 1) + 1) * 2;
}
else
{
System.out.println("day在1-10");
return -1;
}
}
}

运行结果:

221,老鼠出迷宫

思路:

1,先创建迷宫,用二维数组表示 int[][] map = new int[8][7]

2,先规定map 数组的元素值:0 表示可以走;1 表示障碍物

3,将最上面的一行和最下面的一行,全部设置为1

4,将最右面的一列和最左面的一列,全部设置为1

使用递归回溯的思想来解决老鼠出迷宫

1,findWay方法就是专门来找出迷宫的路径

2,如果找到,就返回 true,否则返回 false

3,map 就是二维数组,即表示迷宫

4,i,j 就是老鼠的位置,初始化的位置为(1,1)

5,因为我们是递归的找路,所以先规定 map 数组的各个值的含义:0 表示可以走;1 表示障碍物;2 表示可以走;3 表示走过,但是走不通,是死路

6,当 map[6][5] = 2 就说明找到通路,就可以结束,否则就继续找

7,先确定老鼠找路策略:下 -> 右 -> 上 -> 左。(有不同的策略,先确定一个自己的策略)

public class test1{
public static void main(String[] args){
int[][] map = new int[8][7];//8行7列
for(int i = 0; i < 7; i++) //i 是列,
{
map[0][i] = 1;//将最上面的一行和最下面的一行,全部设置为1
map[7][i] = 1;
}
for(int i = 0; i < 8; i++)//i 是行
{
map[i][0] = 1;//将最右面的一列和最左面的一列,全部设置为1
map[i][6] = 1;
}
map[3][1] = 1;
map[3][2] = 1;
//输出当前地图
for(int i = 0; i < map.length; i++)
{
for(int j = 0; j < map[i].length; j++)
{
System.out.print(map[i][j] + " ");
}
System.out.println();
}
//使用findWay给老鼠找路
T t1 = new T();
t1.findWay(map,1,1);//对数组的修改,会把原数组修改了,参考引用赋值
System.out.println("\n====找路的情况如下=====");
for(int i = 0; i < map.length; i++)
{
for(int j = 0; j < map[i].length; j++)
{
System.out.print(map[i][j] + " ");
}
System.out.println();
}
}
}
class T{
public boolean findWay(int[][] map, int i, int j)
{
//0 表示可以走,还没走;1 表示障碍物;2 表示可以走;3 表示走过,但是走不通,是死路
if (map[6][5] == 2) //说明已经找到,走到终点了
{
return true;
}
else
{
if (map[i][j] == 0)//当前位置为0,也是起点。说明可以走
{
map[i][j] = 2;//假定可以走通,沿着找路策略开始走
//找路策略:下 -> 右 -> 上 -> 左
if (findWay(map, i + 1, j))//下
{
return true;
} else if (findWay(map, i, j + 1))//右
{
return true;
} else if (findWay(map, i - 1, j))//上
{
return true;
} else if (findWay(map, i, j - 1)) //左
{
return true;
}
else//四个方向都走不通了,就是死路
{
map[i][j] = 3;
return false;
}
}
else //map[i][j] = 1,2,3
{
return false;
}
}
}
}

运行结果:

225,汉诺塔

思路见代码:

public class test1{
public static void main(String[] args){
T t = new T();
t.move(3, 'A', 'B', 'C');
}
}
class T{
//num 表示要移动的个数,a,b,c分别表示A塔,B塔,C塔
public void move(int num, char a, char b, char c)
{
if(num == 1)//只有一个盘子,就直接从A移到C
{
System.out.println(a + "->" + c);
}
else
{
//1,如果有多个盘,可以看成两个,最下面的和上面的所有盘(num-1)
move(num - 1,a, c, b);//先移动上面的所有的盘到 b,借助 c,借助是指我们不能把上面的所有盘整体移过去,需要借助c
System.out.println(a + "->" + c); //3,把最下面的这个盘,移动到 c。
//4,再把 b 塔的所有盘,移动到 c,借助 a
move(num - 1, b, a, c);//把B塔的盘移动也当成两个盘在移动,和上面的 1 同理
}
}
}

运行结果:

229,重载使用细节

1,方法名:必须相同

2,形参列表:必须不同(形参类型或个数或顺序,至少有一样不同,参数名无要求)

3,返回类型:无要求

233,可变参数使用

概念:java允许将同一个类中多个同名同功能但参数个数不同的方法,封装成一个方法。就可以通过可变参数实现。

基本语法: 访问修饰符 返回类型 方法名(数据类型... 形参名){}

public class test1{
public static void main(String[] args){
HspMethods m = new HspMethods();
System.out.println(m.sum(1,2,3,4));
}
}
class HspMethods{
//可以计算 2个数的和,3个数的和,4,5....
//可以使用方法重载
// public int sum(int n1, int n2)//2个数的和
// {
// return n1 + n2;
// }
// public int sum(int n1, int n2, int n3)//3个数的和
// {
// return n1 + n2;
// }
//上面的两个方法名称相同,功能相同,参数个数不同 -> 使用可变参数优化
//1, int... 表示接受的是可变参数,类型是int,即可以接收多个int(0-多)
//2, 使用可变参数是,可以当做数组来使用,即 nums 可以当做数组
public int sum(int... nums)
{
int res = 0;
for(int i = 0; i < nums.length; i++)
{
res += nums[i];
}
return res;
}
}

运行结果:

234,可变参数细节

1,可变参数的实参可以为 0 个或任意多个(见 233 代码)

2,可变参数的实参可以为数组

public class test1{
public static void main(String[] args){
int[] arr = {1, 2, 3};
T t1 = new T();
t1.f1(arr);
}
}
class T{
public void f1(int... nums)
{
System.out.println("长度 = " + nums.length);
}
}

运行结果:

3,可变参数的本质就是数组

4,可变参数可以和普通类型的参数一起放在形参列表,但必须保证可变参数在最后(否则报错)

public void f2(String str, double... nums){}

5,一个形参列表中只能出现一个可变参数

235,可变参数练习

问题:有三个方法,分别实现返回姓名和两门课成绩(总分),返回姓名和三门课成绩(总分),返回姓名和五门课成绩(总分)。封装成一个可变参数的方法。类名 HspMethod 方法名 showScore

分析:两门课,三门课,五门课成绩,理解为一个可以接收多个double 类型的可变参数,问题要求返回姓名和三门课成绩(总分),所以方法的返回类型是 String,形参(String, double... )

public class test1{
public static void main(String[] args){
HspMethod t1 = new HspMethod();
System.out.println(t1.showScore("milan", 60,80));
System.out.println(t1.showScore("jack", 60,80,80));
System.out.println(t1.showScore("lucy", 60,80,80,90,80));
}
}
class HspMethod{
public String showScore(String name, double... scores)
{
double totalScore = 0;
for(int i = 0; i < scores.length; i++)
{
totalScore += scores[i];
}
return name + " 有" + scores.length + "门课的成绩总分 = " + totalScore;
}
}

运行结果:

236,作用域基本使用

1,在java编程中,主要的变量就是属性(成员变量)和局部变量

2,我们说的局部变量一般是指在成员方法中定义的变量

3,java 中作用域的分类。

全局变量:也就是属性,作用域为整个类体;

局部变量:也就是除了属性之外的其他变量,作用域为定义它的代码块中!

4,全局变量(属性)可以不赋值,直接使用,因为有默认值,局部变量必须赋值后才能使用,因为没有默认值。

237,作用域使用细节

1,属性和局部变量可以重名,访问时遵循就近原则。

public class test1{
public static void main(String[] args){
Person p1 = new Person();
p1.say();
}
}
class Person{
String name = "jack";
public void say()
{
String name = "king";
System.out.println("say() name = " + name);
}
}

运行结果:

2,在同一个作用域中,比如在同一个成员方法中,两个局部变量,不能重名

3,属性生命周期较长,伴随着对象的创建而创建,伴随着对象的销毁而销毁。局部变量,生命周期较短,伴随着它的代码块的执行而创建,伴随着代码块的结束而销毁。即在一次方法调用过程中。

4,全局变量/属性:可以被本类使用,或其他类使用(通过对象调用)。  局部变量:只能在本类中对应的方法中使用

public class test1{
public static void main(String[] args){
Person p1 = new Person();
T t1 = new T();
t1.test();//第1种跨类访问对象属性的方式
t1.test(p1);//第2种跨类访问对象属性的方式 }
}
class T{
public void test()
{
Person p1 = new Person();//Person类中的全局变量name,可以在T类中使用,通过对象调用
System.out.println(p1.name);//jack
}
public void test(Person p)
{
System.out.println(p.name);//jack
}
}
class Person{
String name = "jack";
}

运行结果:

5,修饰符不同 :全局变量/属性可以加修饰符;局部变量不可以加修饰符

239,构造器基本介绍

构造方法又叫构造器,是类的一种特殊方法,它的主要作用是完成对新对象的初始化

基本语法: 修饰符 方法名(形参列表) { 方法体 }

说明:1,构造器的修饰符可以默认,也可以是public  protected  private

2,构造器没有返回值

3,方法名和类名字必须一样

4,参数列表 和 成员方法 一样的规则

5,在创建对象时,系统会自动调用该类的构造器完成对对象的初始化

public class test1{
public static void main(String[] args){
Person p1 = new Person("smith", 80);//当我们new 一个对象时,直接通过构造器指定名字和年龄
System.out.println("p1的信息如下");
System.out.println("p1对象name = " + p1.name);
System.out.println("p1对象age = " + p1.age);
}
}
class Person{
String name;
int age;
public Person(String pName, int pAge)
{
System.out.println("构造器被调用~~ 完成对象的属性初始化");
name = pName;
age = pAge;
}
}

运行结果:

6,一个类可以定义多个不同的构造器,即构造器重载

7,如果程序员没有定义构造器,系统会自动给类生成一个默认无参构造器(也叫默认构造器),比如 Dog() { }

8,一旦定义了自己的构造器,默认的构造器就覆盖了,就不能再使用默认的无参构造器,除非显示的定义一下,即:Dog() {}

244,对象创建的流程分析

看一个案例

class Person{//类Person
int age = 90;
String name;
Person(String n, int a)//构造器
{
name = n;//给属性赋值
age = a;
}
}
Person p = new Person("小倩",20);

流程分析(面试题)

1,加载Person类信息(Person.class),只会加载一次

2,在堆中分配空间(地址)

3,完成对象初始化

3.1,默认初始化 age = 0,name = null             3.2,显示初始化 age = 90,name = null           3.3,构造器的初始化  age = 20,name = 小倩

4,在对象在堆中的地址,返回给 p(p是对象名,也可以理解成是对象的引用)

249,this 使用细节

1,哪个对象调用,this就代表哪个对象

2,this 关键字可以用来访问本类的属性,方法,构造器

3,this用于区分当前类的属性和局部变量

4,访问成员方法的语法:this.方法名(参数列表)

public class test1{
public static void main(String[] args){
T t = new T();
t.f2();
}
}
class T{
public void f1()
{
System.out.println("f1() 方法..");
}
public void f2()
{
System.out.println("f2() 方法..");
//调用本类的 f1
f1();//第一种方式
this.f1();//第二种方式 this.方法名(参数列表)
}
}

运行结果:

5,访问构造器语法:this(参数列表);注意只能在构造器中使用(即只能在构造器中访问另外一个构造器,必须放置第一条语句)

public class test1{
public static void main(String[] args){
T t = new T();
}
}
class T{
public T()
{
this("jack", 100);//这里去访问T(String name, int age) 构造器
System.out.println("T() 构造器");
}
public T(String name, int age)
{
System.out.println("T(String name, int age) 构造器");
}
}

运行结果:

6,this不能在类定义的外部使用,只能在类定义的方法中使用

250,this课堂练习

问题:定义Person类,里面有name,age属性,并提供compareTo比较方法,用于判断是否和另一个人相等,提供测试类TestPerson 用于测试,名字和年龄完全一样,就返回true,否则返回false

public class TestPerson{
public static void main(String[] args){
Person p1 = new Person("mary", 20);
Person p2 = new Person("smith", 30);
System.out.println(p1.compareTo(p2)); }
}
class Person{
String name;
int age;
public Person(String name, int age)
{
this.name = name;
this.age = age;
}
public boolean compareTo(Person p)//和另一个人的姓名年龄比较,所以形参是Person对象,还要知道这个对象的信息(通过构造器)
{
return this.name.equals(p.name) && this.age == p.age;
}
}

运行结果:

253,本章作业03

问题:编写类Book,定义方法updatePrice,实现更改某本书的价格,具体:如果价格>150,则更改为150,如果价格>100,更改为100,否则不变。

分析:更改某本书的价格,可以理解为更改一个对象的价格属性,需要先用构造器完成对这个对象的价格的初始化,再到方法中进行更改。

public class test1{
public static void main(String[] args){
Book book = new Book("小王子", 120);
book.info();
book.updatePrice();
book.info();
}
}
class Book
{
String name;
double price;
public Book(String name, double price)
{
this.name = name;
this.price = price;
}
public void updatePrice()
{ //如果方法中,没有 price 局部变量,this.price 等价 price
if(price > 100)
{
price = 100;
}else if(price > 150)
{
price = 150;
}
}
public void info()
{
System.out.println("书名 = " + this.name + " 价格 = " + this.price);
}
}

运行结果:

260,本章作业10

public class test1 {
public static void main(String[] args) {
Circle c = new Circle();
PassObject po = new PassObject();
po.printAreas(c,5);
}
}
class Circle
{
double radius;
public Circle()//在第2问我们没有办法确认半径值,在for循环那里才知道半径值是变化的,所以要重写默认构造器
{ }
public Circle(double radius)//第1问要用到这个
{
this.radius = radius;
}
public double findArea()//返回面积
{
return radius * radius * Math.PI;
}
public void setRadius(double radius)//添加方法 setRadius,修改对象的半径值
{
this.radius = radius;
}
}
class PassObject
{
public void printAreas(Circle c, int times)
{
System.out.println("radius\tarea");
for(int i = 1; i <= times; i++)
{
c.setRadius(i);//可以用到Circle对象,并能把i传进去,如果每次都new 一个新对象(用构造器),就不划算
System.out.println(i + "\t" + c.findArea()); }
}
}

运行结果:

java基础 韩顺平老师的 面向对象(基础) 自己记的部分笔记的更多相关文章

  1. java韩顺平老师视频有需要可以留言

    java韩顺平老师视频有需要可以留言

  2. 韩顺平老师java视频全套-java视频教程下载

    解压压缩包会有一个种子文件.直接迅雷下载即可,包含了韩顺平老师的java入门视频,jdbc,jsp,servlet,oracle,hibermate,spring,SHH框架,struct,linux ...

  3. Linux基础指令--韩顺平老师课程笔记

    一.vi和vim编辑器 ①.三种模式 所有的 Linux 系统都会内建 vi 文本编辑器.vim 具有程序编辑的能力,可以看做是 vi 的增强版本,可以主动的以字体颜色辨别语法的正确性,方便程序设计. ...

  4. 《Java技术》第二次作业--面向对象基础

    (一)学习总结 1.什么是构造方法?什么是构造方法的重载?下面的程序是否可以通过编译?为什么? public class Test { public static void main(String a ...

  5. Java【第六篇】面向对象基础

    类和对象 面向对象的概念 面向过程 核心是过程二字,过程指的是解决问题的步骤,设计一条流水线,机械式的思维方式: 面向对象 核心就是对象二字,对象就是特征与技能的结合体,利用“类”和“对象”来创建各种 ...

  6. 学韩顺平老师linux教程--笔记

    第二讲:1.startx  进入图形界面2.shutdown -h now 立刻进行关机3.shutdown -r now 现在重新启动计算机4.reboot          现在重新启动计算机5. ...

  7. 初级Oracle和SQL学习者的学习笔记。韩顺平-玩转oracle。

    我自己就是一个oracle和sql的初学者,前段时间看了韩顺平老师的oracle视频教程,觉得很深入浅出,收获了很多.同时自己也做了不少笔记,现在想将纸质笔记以自己的话总结出来.俗话说得好:教学总是相 ...

  8. 到头来还是逃不开Java - Java13面向对象基础

    面向对象基础 没有特殊说明,我的所有学习笔记都是从廖老师那里摘抄过来的,侵删 引言 兜兜转转到了大四,学过了C,C++,C#,Java,Python,学一门丢一门,到了最后还是要把Java捡起来.所以 ...

  9. java基础学习05(面向对象基础01)

    面向对象基础01 1.理解面向对象的概念 2.掌握类与对象的概念3.掌握类的封装性4.掌握类构造方法的使用 实现的目标 1.类与对象的关系.定义.使用 2.对象的创建格式,可以创建多个对象3.对象的内 ...

  10. 【重走Android之路】【Java面向对象基础(三)】面向对象思想

    [重走Android之路][基础篇(三)][Java面向对象基础]面向对象思想   1 面向对象的WWH   1.1 What--什么是面向对象         首先,要理解“对象”.在Thinkin ...

随机推荐

  1. go 1.21:cmp

    标准库 cmp 原文在这里 go 1.21 新增 cmp 包提供了与有序变脸比较相关的类型和函数. Ordered 定义如下: type Ordered interface { ~int | ~int ...

  2. vim 从嫌弃到依赖(10)——缓冲区列表

    之前的一系列文章主要介绍了vim文本相关的操作,并且也介绍了vim的几种模式.通过前面的内容,相信各位小伙伴们已经对vim有了一个基本的了解,同时也能够使用vim快速编辑文本,从这篇开始,我们将要介绍 ...

  3. 【3】opencv_contrib 4.3.0库配置+opencv安装

    相关文章: [1]windows下安装OpenCV(4.3)+VS2017安装+opencv_contrib4.3.0配置 [2]Visual Studio 2017同时配置OpenCV2.4 以及O ...

  4. 3.2 Windows驱动开发:内核CR3切换读写内存

    CR3是一种控制寄存器,它是CPU中的一个专用寄存器,用于存储当前进程的页目录表的物理地址.在x86体系结构中,虚拟地址的翻译过程需要借助页表来完成.页表是由页目录表和页表组成的,页目录表存储了页表的 ...

  5. C/C++ 反汇编:函数与结构体

    反汇编即把目标二进制机器码转为汇编代码的过程,该技术常用于软件破解.外挂技术.病毒分析.逆向工程.软件汉化等领域,学习和理解反汇编对软件调试.系统漏洞挖掘.内核原理及理解高级语言代码都有相当大的帮助, ...

  6. Python 多线程爬取西刺代理

    西刺代理是一个国内IP代理,由于代理倒闭了,所以我就把原来的代码放出来供大家学习吧. 首先找到所有的tr标签,与class="odd"的标签,然后提取出来. 然后再依次找到tr标签 ...

  7. Netty-介绍-1

    Netty介绍和应用场景 要求 已经掌握了 主要技术构成: Java OOP 编程. Java 多线程编程. Java IO 编程 . Java 网络编程. 常用的Java 设计模式(比如 观察者模式 ...

  8. Python3.11.3解决ModuleNotFoundError: No module named 'Crypto'

    安装了Crypto但程序还提示 ModuleNotFoundError: No module named 'Crypto' 反复卸载安装都不行,最后修改了文件夹的名称解决了. 找到Python的安装路 ...

  9. T406696 『STA - R4』冰红茶 题解

    题目链接:冰红茶 比较有意思的套路题(前提是接触过) 首先,一个最基本的线段树包含两种操作的板子要会,分别为区间赋值与区间加,同时维护区间最值.这个挺简单的,区间赋值优先级高于区间加,可以将区间加覆盖 ...

  10. OLED 驱动模块程序代码

    1.前言 作为嵌入式软件开发,可能经常会使用单片机连接驱动显示屏,实现人机交互的功能,通常可选择的有 OLED 和 LCD 等,其中相关驱动代码例程网上更是数不胜数. 本文介绍的是 OLED, 常见代 ...