Java程序设计基础学习笔记——类与对象、方法、递归、重载、可变参数、作用域、构造器、this

news2024/11/15 13:54:56

以下笔记整理自B站UP主韩顺平【零基础 快速学Java】韩顺平 零基础30天学会Java课程

OOP

面向对象程序设计(Object Oriented Programming)

类就是数据类型,有属性和行为;对象是一个具体的实例

从类到对象,目前有几种说法:

  1. 创建一个对象

  1. 实例化一个对象

  1. 把类实例化

Java最大的特点就是面向对象

养猫问题(引出类与对象)

public class Object01 {

    public static void main(String[] args) {

        //使用OOP面向对象
        //实例化一只猫【创建一只猫】
        //new Cat() —— 创建一只猫
        //把创建的猫赋给cat1   Cat cat1 = new cat();
        Cat cat1 = new Cat();
        cat1.name = "小白";
        cat1.age = 18;
        cat1.color = "白色";

        //创建了第二只猫,赋给cat2
        Cat cat2 = new Cat();
        cat2.name = "小黄";
        cat2.age = 4;
        cat2.color = "黄色";

        //怎么访问对象的属性
        System.out.println("第1只猫的信息" + cat1.name + " " + cat1.age + 
                            " " + cat1.color);
        System.out.println("第2只猫的信息" + cat2.name + " " + cat2.age + 
                            " " + cat2.color);
    }
}

//使用面向对象的方式来解决养猫问题
//定义一个猫类Cat -> 自定义的数据类型
class Cat {
    //属性
    String name;
    int age;
    String color;

    //后面还可以添加行为
}

对象内存布局

根据数据类型的不同,存放的位置也不同

成员变量 = 属性 = field(字段)

属性是类的一个组成部分,一般是基本数据类型,也可是引用类型(对象,数组)。比如我们前面定义猫类 的 int age 就是属性

属性的定义语法同变量,示例:访问修饰符 属性类型 属性名;

访问修饰符:控制属性的访问范围(public protected private 默认)

properties:属性

创建对象

如果只是声明对象,那它还是空的(null),new之后才开辟空间有地址。

Java 内存的结构分析

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

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

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

类与对象练习

编译运行结果如下图:

成员方法

public class Method {

    public static void main(String[] args) {

        //方法使用
        //先创建对象,然后调用方法
        Person p1 = new Person();

        p1.speak(); //调用speak方法
        p1.cal01(); //调用cal01方法
        p1.cal02(50); //调用cal02方法
        
        int returnRes = p1.getSum(10, 20);  //调用getSum方法
        System.out.println("getSum方法返回的值" + returnRes);    
    }
}

class Person {
    //属性
    String name;
    int age;

    //方法(成员方法)
    //添加speak成员方法,输出"我是一个好人"
    //public 表示 方法是公开的
    //void 表示 方法没有返回值
    //speak() speak表示方法名 ()表示形参列表
    //{} 方法体 可以写我们要执行的代码
    public void speak() {

        System.out.println("我是一个好人");
    }

    //添加cal01成员方法,可以计算从1+2+3+...+1000
    public void cal01() {
        int res = 0;
        for( int i = 0; i <= 1000; i ++ ) {
            res += i;
        }
        System.out.println("计算结果=" + res);
    }

    //添加 cal02 成员方法,该方法可以接收一个数 n,计算从 1+..+n 的结果
    //(int n)形参列表,表示当前有一个形参n,可以接收用户的输入
    public void cal02(int n) {
        int res = 0;
        for( int i = 0; i <= n; i ++ ) {
            res += i;
        }
        System.out.println("计算结果=" + res);

    }

    //添加 getSum 成员方法,可以计算两个数的和
    /*
    public 表示 方法是公开的
    int 表示方法执行后返回一个int值
    getSum 方法名
    */
    public int getSum(int num1, int num2) {
        int res = num1 + num2;
        return res;
    }
}

方法的调用机制原理【重点】

成员方法的定义

注意事项

  • 访问修饰符 (作用是控制 方法使用的范围),如果不写默认访问,[有四种: public, protected, 默认, private]

  • 一个方法最多有一个返回值 【如何返回多个结果?返回数组】

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

  • 方法不能嵌套定义

  • 同一个类中的方法调用,直接调用即可,如下图

  • 跨类中的方法A类调用B类方法,需要通过对象名调用

  • 跨类的方法调用和方法的访问修饰符相关

parameter:参数

基本数据类型的传参机制

基本数据类型,传递的是值(值拷贝),形参的任何改变不影响实参【参考方法的调用机制原理图】

引用数据类型的传参机制【重点】

引用类型传递的是地址(传递也是值,但是值是地址),可以通过形参影响实参!

看下面代码加深理解【重难点】

public class MethodParameter {

    public static void main(String[] args) {

        B b = new B();
        Person p = new Person();
        p.name = "Jack";
        p.age = 10;

        b.text200(p);

        System.out.println("main中p.age=" + p.age);
        //输出main中p.age=10
    }
}

class Person {

    String name;
    int age;
}

class B {

    public void text200(Person p) {

        //这里并没有影响main栈p对象,只是text200栈中的p置空了
        p = null;
    }
}
public class MethodParameter02 {

    public static void main(String[] args) {

        B b = new B();
        Person p = new Person();
        p.name = "jack";
        p.age = 100;
        b.text300(p);
        System.out.println("main中p.age=" + p.age);
        //输出结果:main中p.age=100
    }
}

class Person {
    String name;
    int age;
}

class B {

    public void text300(Person p) {
        p = new Person(); //会在堆中创建一个新的p对象,text300栈中的p指向这个对象,main栈依然没变
        p.name = "tom";
        p.age = 10;
    }
}

克隆对象

public class MethodExercise02 {

    public static void main(String[] args) {

        Person p = new Person();
        p.name = "milan";
        p.age = 10;

        MyTools tool = new MyTools();
        Person p2 = tool.copyPerson(p);
        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 {

    public Person copyPerson(Person p) {
        Person p2 = new Person();
        p2.name = p.name;
        p2.age = p.age;
        return p2;
    }
}

递归

recursion:递归

阶乘

factorial:阶乘

public class Recursion {

    public static void main(String[] args) {

        myTool tool = new myTool();
        int res = tool.factorial(10);
        System.out.println("res=" + res);
    }
}

class myTool {

    public int factorial(int n) {
        if(n == 1)
            return 1;
        else
            return factorial(n - 1) * n;
    }
}
/*
10的阶乘3628800
*/

递归重要原则

斐波那契数列

fibonacci:斐波那契

import java.util.Scanner;

public class RecursionExercise01 {

    public static void main(String[] args) {
        
        Scanner myScanenr = new Scanner(System.in);
        System.out.println("请输入一个整数:");
        int n = myScanenr.nextInt();
        myTool tool = new myTool();
        int res = tool.Fibonacci(n);
        System.out.println("第" + n + "项对应的斐波那契数为" + res);

    }
}

class myTool {

    public int Fibonacci(int n) {
        if(n == 1 || n == 2)
            return 1;
        else
            return Fibonacci(n - 1) + Fibonacci(n - 2);
    }
} 
/*
斐波那契数列:1 1 2 3 5 8 13 21 ...
*/

猴子吃桃

第10天要吃的时候只剩1个桃子,问原来第1天有多少桃子?

public class RecursionExercise02 {

    public static void main(String[] args) {

        myTool tool = new myTool();
        int res = tool.Monkey_peach(1);
        System.out.println("res=" + res);  //res=1534
    }
}

class myTool {

    public int Monkey_peach(int n) {
        if(n == 10)
            return 1;
        else
            return (Monkey_peach(n + 1) + 1) * 2;
    }    
}

老鼠出迷宫

import java.util.Scanner;

public class Maze {

    public static void main(String[] args) {

        Scanner myScanner = new Scanner(System.in);
        System.out.println("请输入您要创建的地图大小:");
        int row = myScanner.nextInt();
        int column = myScanner.nextInt();

        //创建一个地图,用二维数组表示
        int[][] map = new int[row][column];
        System.out.println("请绘制地图(每行以空格隔开,0表示没有障碍物,1表示有障碍物):");
        //绘制地图
        for( int i = 0; i < map.length; i ++ ) {
            for(int j = 0; j < map[i].length; j ++ ) {
                map[i][j] = myScanner.nextInt();
            }
        }
        // //设置障碍物,1表示有障碍物,0表示没有障碍物
        // for( int i = 0; i < 7; i ++ ) {
        //     map[0][i] = 1;
        //     map[7][i] = 1;
        // }
        // for( int j = 0; j < 8; j ++ ) {
        //     map[j][0] = 1;
        //     map[j][6] = 1;
        // }
        // map[3][1] = 1;
        // map[3][2] = 1;

        System.out.println("当前地图为:");
        //打印当前地图
        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();
        }
        System.out.println("===================");
        myTool tool = new myTool();
        tool.findWay(map, 1, 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();
        }
    }
}

class myTool {

    //对地图的说明:0表示没有障碍物,可以走;1表示有障碍物;2表示可以走;3表示走过,但是死路
    //如果找到出口返回true,反之返回false
    public boolean findWay(int[][] map, int i, int j) {

        if(map[6][5] == 2){  // map[6][5] 为迷宫出口,说明已经找到出口
            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 {
                return false;
            }
        }
    }
}
/*
地图1:
8 * 7
1 1 1 1 1 1 1
1 0 0 0 0 0 1
1 0 0 0 0 0 1
1 1 1 0 0 0 1
1 0 0 0 0 0 1
1 0 0 0 0 0 1
1 0 0 0 0 0 1
1 1 1 1 1 1 1
地图2:
8 * 7
1 1 1 1 1 1 1
1 0 0 0 0 0 1
1 1 1 1 1 0 1
1 1 1 1 0 0 1
1 0 0 0 0 1 1
1 1 1 0 0 0 1
1 1 1 0 0 0 1
1 1 1 1 1 1 1
*/

汉诺塔

public class HanoiTower {

    public static void main(String[] args) {

        myTool tool = new myTool();
        tool.move(3, 'A', 'B', 'C');

    }
}

class myTool {

    //num表示要移动的个数,a,b,c分别表示A塔,B塔,C塔
    public void move(int num, char a, char b, char c) {
        //如果只有一个盘
        if(num == 1) {
            System.out.println(a + "->" + c);
        } else {
            //如果有多个盘,可以看成两个,最下面的和上面的所有盘
            //1.先移动上面所有的盘到b,借助c
            move(num - 1, a, c, b);
            //2.把最下面的盘移动到c
            System.out.println(a + "->" + c);
            //3.再把b塔的所有盘移动到c,借助a塔
            move(num - 1, b, a, c);
        }
    }
}
/*
tool.move(3, 'A', 'B', 'C')
A->C
A->B
C->B
A->C
B->A
B->C
A->C
*/

重载

out是一个对象

注意事项和使用细节

可变参数

Variable parameter:可变参数

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

public class VarParameter01 {

    public static void main(String[] args) {

        Method m = new Method();
        int res = m.sum(1, 2, 3);
        System.out.println("res=" + res);
    }
}

class Method {

    //可以计算2个数的和,3个数的和,4个数的和,...
    //可以使用方法重载,但较麻烦
    //使用可变参数优化
    /*
    1.int...表示接收的是可变参数,类型是int,即可以接收多个int(0~)
    2.使用可变参数时,可以当做数组来使用,即nums可以当做数组
    3.遍历nums,求和即可
    */
    public int sum(int... nums) {
        System.out.println("接收的参数个数=" + nums.length);
        int res = 0;
        for( int i = 0; i < nums.length; i ++ ) {
            res += nums[i];
        }
        return res;
    }
}

注意事项和使用细节

作用域

scope:作用域

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

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

  • 全局变量(属性)作用域为整个类体,成员方法可以使用属性

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

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

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

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

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

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

  • 全局变量(属性)可以加修饰符;局部变量不可以加修饰符

构造器(构造方法)

构造方法又叫构造器(constructor),是类的一种特殊的方法,它的主要作用是完成对新对象的初始化。它有几个特点:

1) 方法名和类名相同

2) 没有返回值

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

javap指令

练习题

在前面定义的 Person 类中添加两个构造器:

第一个无参构造器:利用构造器设置所有人的 age 属性初始值都为 18

第二个带 pName 和 pAge 两个参数的构造器:使得每次创建 Person 对象的同时初始化对象的 age 属性值和 name 属性值。

分别使用不同的构造器,创建对象.

public class ConstructorExercise {

    public static void main(String[] args) {

        Person p1 = new Person();
        System.out.println("p1.name=" + p1.name + " p1.age=" + p1.age);
        Person p2 = new Person("jack", 20);
        System.out.println("p2.name=" + p2.name + " p2.age=" + p2.age);
    }
}

class Person {

    String name;
    int age;
    //第一个无参构造器:利用构造器设置所有人的 age 属性初始值都为 18
    public Person() {
        age = 18;
    }
    //第二个带 pName 和 pAge 两个参数的构造器:使得每次创建 Person 对象的同时初始化对象的 age 属性值和 name 属性值。
    public Person(String pName, int pAge) {
        name = pName;
        age = pAge;
    }
}
/*
输出结果
p1.name=null p1.age=18
p2.name=jack p2.age=20
*/

面试题——对象创建流程分析【重点】

this

hashCode

返回该对象的哈希码值

该方法会针对不同的对象返回不同的整数,这一般是通过将该对象的内部地址转换成一个整数

来实现的

用hashCode方法来验证this关键字

public class This02 {

    public static void main(String[] args) {

        Dog dog1 = new Dog("jack", 20);
        System.out.println("dog1的hashcode=" + dog1.hashCode());
        dog1.info();
    }
}

class Dog {

    String name;
    int age;
    /*
    如果我们构造器的形参,直接写成属性名,就比较好
    但是出现了一个问题,根据变量的作用域原则
    构造器的name / age就是局部变量,而不是属性
    */
    public Dog(String name, int age) {
        //this.name就是当前对象的属性name
        this.name = name;
        //this.age就是当前对象的属性age
        this.age = age;
        System.out.println("this.hashcode=" + this.hashCode());
    }

    public void info() {  //这里的name和age还是属性
        System.out.println(name + "\t" + age + "\t");
    }
}
/*
hashcode:返回该对象的哈希码值
该方法会针对不同的对象返回不同的整数,这一般是通过将该对象的内部地址转换成一个整数
来实现的
输出结果:
this.hashcode=366712642
dog1的hashcode=366712642
*/

this小结

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

注意事项和使用细节

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

public class ThisDetail {

    public static void main(String[] args) {

        T t1 = new T();
        t1.f2();
        
    }
}

class T {

    //细节:访问成员方法的语法:this.方法名(参数列表);

    public void f1() {
        System.out.println("f1() 方法...");
    }

    public void f2() {
        System.out.println("f2() 方法...");
        //调用本类的f1方法
        //第一种方式
        this.f1();
        //第二种方式
        f1();
        //这两种方法是有区别的,在讲继承的时候会说

    }
}

输出

f2() 方法...
f1() 方法...
f1() 方法...
  • 访问构造器语法:this(参数列表),注意只能在构造器中使用(即只能在构造器中访问另外一个构造器)

public class ThisDetail {

    public static void main(String[] args) {

        // T t1 = new T();
        // t1.f2();
        T t2 = new T();

    }
}

class T {

    /*
    访问构造器语法:this(参数列表),必须放在第一条语句,注意只能在构造器中使用
    (即只能在构造器中访问另外一个构造器)
    */
    public T() {
        //访问T(String name, int age)构造器
        this("jack", 20);

        System.out.println("T() 构造器");

    }

    public T(String name, int age) {
        System.out.println("T(String name, int age) 构造器");
    }

    //细节:访问成员方法的语法:this.方法名(参数列表);

    public void f1() {
        System.out.println("f1() 方法...");
    }

    public void f2() {
        System.out.println("f2() 方法...");
        //调用本类的f1方法
        //第一种方式
        this.f1();
        //第二种方式
        f1();
        //这两种方法是有区别的,在讲继承的时候会说

    }
}

输出

T(String name, int age) 构造器
T() 构造器
  • this不能在类定义的外部使用,只能在类定义的方法中使用

作业题

  • 编写类A01,定义方法max,实现求某个double数组的最大值,并返回

/*
编写类A01,定义方法max,实现求某个double数组的最大值,并返回
*/
public class Homework01 {

    public static void main(String[] args) {

        double nums[] = {2.0, 0.2, 9.9, 3.25, 4.26};
        A01 a01 = new A01();
        Double res = a01.Findmax(nums);
        if(res != null) {
            System.out.println("最大的数为:");
            System.out.println(res);
        } else {
            System.out.println("输入有误");
        }
        
    }
}

class A01 {

    public Double Findmax(double... nums) {
        if(nums != null && nums.length > 0) {
            double MaxNum = nums[0];
            for( int i = 1; i < nums.length; i ++ ) {
                if(nums[i] > MaxNum) {
                    MaxNum = nums[i];
                }
            }
            return MaxNum;
        } else {
            return null;
        }
    }
}
/*
如果double nums[] = {2.0, 0.2, 9.9, 3.25, 4.26};
输出结果:9.9
为增强代码健壮性
如果double nums[] = {};
如果double nums[] = null;
*/

成员方法的接收采用Double类的方式,既可以接收一个double类型的变量,也可以接收null

  • 编写类A02,定义方法Find,实现查找某字符串是否在字符串数组中,并返回索引,如果找不到返回-1

/*
编写类A02,定义方法Find,实现查找某字符串是否在字符串数组中,并返回索引,如果找不到
返回-1
*/
public class Homework02 {

    public static void main(String[] args) {

        A02 a02 = new A02();
        String[] str = {"jack", "tom", "merry", "jone"};
        System.out.println(a02.Find("merry", str));
    }
}

class A02 {

    public int Find(String findstr, String[] str) {
        for( int i = 0; i < str.length; i ++ ) {
            if(findstr.equals(str[i])) 
                return i;
        }
        return -1;
    }
}
  • 编写类Book,定义方法updatePrice,实现更改某本书的价格,具体:如果价格>150,则更改为150;如果价格>100,则更改为100,否则不变

public class Homework03 {

    public static void main(String[] args) {

        book b = new book("悲惨世界", 128.5);
        b.updatePrice();
        b.info();
    }
}

class book {

    String name;
    double price;
    public book(String name, double price) {
        this.name = name;
        this.price = price;
    }

    public void updatePrice() {
        if(this.price > 150) {
            this.price = 150;
        } else if(this.price > 100) {
            this.price = 100;
        }
    }

    public void info() {
        System.out.println("书名:" + this.name + " 价格:" + this.price);
    }
}
  • 编写类A03,实现数组的复制功能copyArr,输入旧数组,返回一个新数组,元素和旧数组一样

public class Homework04 {

    public static void main(String[] args) {

        A03 a03 = new A03();
        int[] arr = {1, 2, 3, 4, 5};
        int[] newarr = a03.copyArr(arr);
        for( int i = 0; i < newarr.length; i ++ ) {
            System.out.print(newarr[i] + " ");
        }
    }
}

class A03 {

    public int[] copyArr(int[] arr) {

        int[] newarr = new int[arr.length];
        for( int i = 0; i < arr.length; i ++ ) {
            newarr[i] = arr[i];
        }
        return newarr;
    }
}
  • 定义一个圆类Circle,定义属性:半径,提供显示圆周长功能的方法,提供显示圆面积的方法

public class Homework05 {

    public static void main(String[] args) {

        Circle c = new Circle();

        System.out.println(c.perimeter(3.0));
        System.out.println(c.area(3.0));

    }
}

class Circle {

    double radius;
    public double perimeter(double radius) {
        return 2 * Math.PI * radius;
    }

    public double area(double radius) {
        return Math.PI * radius * radius;
    }

}
  • 编程创建一个Cale计算类,在其中定义2个变量表示两个操作数,定义四个方法实现求和、查、乘、商(要求除数为0的话,并提示),并创建两个对象,分别测试

public class Homework06 {

    public static void main(String[] args) {

        Cale cale = new Cale(2, 0);
        System.out.println("和=" + cale.add());
        System.out.println("差=" + cale.minus());
        System.out.println("乘=" + cale.mul());
        Double Divres = cale.div();
        if(Divres == null) {
            System.out.println("除数不能为0");
        } else {
            System.out.println("除=" + cale.div());
        }
        
    }
}

class Cale {

    double num1;
    double num2;
    public Cale(double num1, double num2) {
        this.num1 = num1;
        this.num2 = num2;
    }
    public double add() {
        return num1 + num2;
    }
    public double minus() {
        return num1 - num2;
    }
    public double mul() {
        return num1 * num2;
    }
    public Double div() {
        if(num2 == 0)
            return null;
        else
            return num1 / num2;
    }
}
  • 阅读以下代码,分析输出结果

10 9 10

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

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

相关文章

【网络安全入门】零基础小白必看!!!

看到很多小伙伴都想学习 网络安全 &#xff0c;让自己掌握更多的 技能&#xff0c;但是学习兴趣有了&#xff0c;却发现自己不知道哪里有 学习资源◇瞬间兴致全无&#xff01;◇ &#x1f604;在线找人要资料太卑微&#xff0c;自己上网下载又发现要收费0 &#x1f643;差点当…

HttpRunnerManager部署

基于HttpRunner的接口自动化测试平台: HttpRunner, djcelery and Django_. HttpRunner手册: http://cn.httprunner.org/git地址&#xff1a;httprunner/HttpRunnerManager: 基于 HttpRunner 的 Web 测试平台&#xff0c;已停止维护。 (github.com)部署机器&#xff1a;linux部署…

强强角逐,筑梦开源——2022年度启智社区优秀项目及开发者评选结果正式揭晓

2月24日&#xff0c;第四届OpenI/O启智开发者大会在深圳隆重开幕。本届大会以“算网筑基、开源启智、AI赋能”为主题&#xff0c;邀请国内人工智能开源领域领军院士亲自参加&#xff0c;汇聚学术界、产业界的技术专家&#xff0c;围绕中国算力网资源基座、开源社区服务支撑环境…

Tik Tok shop2023年度策略解读

一、TikTok Shop跨境电商数据显示自2022年上半年东南亚开放跨境电商入驻以来&#xff0c;全年GMV月均复合增速近90%&#xff1b;英国市场2022年下半年的平均交易客单价也同比2021年增长超40%&#xff1b;全年多个重要节点跨境GMV增长显著&#xff0c;例如2022年的圣诞季跨境GMV…

ESP32设备驱动-PCF8574IO扩展模块驱动

PCF8574IO扩展模块驱动 1、PCF8574介绍 PCF8574 是一个使用 I2C 协议的 8 位 I/O 端口扩展器。 通过开发板的SDA 和 SCL 引脚来控制多达 8 个数字 I/O 端口。 其中,A0,A1,A2 为地址引脚,P0,P1,P2,P3,P4,P5,P6,P7 为数字端口。PCF8574的地址如下: 在前面的文章,对PCF8574的…

【渐进交互学习网络:轻量级:超分:工业应用】

Progressive Interaction-Learning Network for Lightweight Single-Image Super-Resolution in Industrial Applications &#xff08;工业应用中轻量级单幅图像超分辨率渐进交互学习网络&#xff09; 近年来&#xff0c;基于深度学习&#xff08;DL&#xff09;的工业应用因…

大数据技术之Hive(四)分区表和分桶表、文件格式和压缩

一、分区表和分桶表1.1 分区表partitionhive中的分区就是把一张大表的数据按照业务需要分散的存储到多个目录&#xff0c;每个目录就称为该表的一个分区。在查询时通过where子句中的表达式选择式选择查询所需要的分区&#xff0c;这样的查询效率辉提高很多。1.1.1 分区表基本语…

Python 不同分辨率图像峰值信噪比[PSNR]

PNNR&#xff1a;全称为“Peak Signal-to-Noise Ratio”&#xff0c;中文直译为峰值信噪比 前言 一、定义 二、Python代码 1.自定义 2.Tensorflow 总结 前言 峰值信噪比是一种衡量图像质量的指标&#xff0c;描述的是最大值信号与北京噪音之间的关系。 一般来说&#xff0c;P…

Allegro如何删除铜皮上多余的空洞操作指导

Allegro如何删除铜皮上多余的空洞操作指导 在做PCB设计的时候,设计铜皮的时候是不希望铜皮上有多余的空洞的,设计完成前需要把多余的空洞删除,如下图 如何删除,具体操作如下 点击Shape点击Manual Void/Cavity

springboot中集成redis,二次封装成工具类

大家好&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;** 雄雄的小课堂 ** 现在是&#xff1a;2023年2月28日11:01:56 前言 redis大家应该都不陌生&#xff0c;我们在好多场景下都会使用&#xff0c;最近在面试别人的时候&#xff0c;也会问一些关于redis的…

华为OD机试题,用 Java 解【求符合要求的结对方式】问题

最近更新的博客 华为OD机试题,用 Java 解【停车场车辆统计】问题华为OD机试题,用 Java 解【字符串变换最小字符串】问题华为OD机试题,用 Java 解【计算最大乘积】问题华为OD机试题,用 Java 解【DNA 序列】问题华为OD机试 - 组成最大数(Java) | 机试题算法思路 【2023】使…

博客系统--自动化测试

项目体验地址&#xff08;账号&#xff1a;123&#xff0c;密码&#xff1a;123&#xff09;http://120.53.20.213:8080/blog_system/login.html项目后端说明&#xff1a;http://t.csdn.cn/32Nnv项目码云Gitee地址&#xff1a;https://gitee.com/GoodManSS/project/tree/master…

【极狐 GitLab】在 web 端合并分支

一、概述 极狐GitLab是GitLab DevOps平台的中国发行版&#xff0c;一套完备的一站式DevOps平台&#xff0c;从根本上改变了开发、安全和运维团队协作和软件构建方式。极狐GitLab从构思到生产发布&#xff0c;帮助团队提高生产效率&#xff0c;将迭代周期从数周缩短至几分钟&am…

【Spring事物三千问】Spring的事务管理与MyBatis事物管理结合的原理

Spring的事务管理与MyBatis事物管理结合的原理前言正文原生的 MyBatis 的事务处理SqlSessionTransactionMyBatis 事务管理 与 Spring 事务管理的融合SpringManagedTransactionSqlSessionTemplateSqlSessionInterceptormybatis-spring 融合的原理连接获取 & 开启事务连接的关…

【Linux】理解进程地址空间

&#x1f34e;作者&#xff1a;阿润菜菜 &#x1f4d6;专栏&#xff1a;Linux系统编程 ​我们在学习C语言的时候&#xff0c;都学过内存区域的划分如栈、堆、代码区、数据区这些。但我们其实并不真正理解内存 — 我们之前一直说的内存是物理上的内存吗&#xff1f; 前言 我们…

18- TensorFlow实现CIFAR10分类 (tensorflow系列) (项目十八)

项目要点 导入cifar图片集: (train_image, train_label), (test_image, test_label) cifar.load_data() # cifar keras.datasets.cifar10图片归一化处理: train_image train_image / 255定义模型: model keras.Sequential() 输入层: model.add(layers.Conv2D(64, (3, 3…

HTML基础语法

一 前端简介构成语言说明结构HTML页面元素和内容表现CSS网页元素的外观和位置等页面样式&#xff08;美化&#xff09;行为JavaScript网页模型的定义和页面交互二 HTML1.简介HTML&#xff08;Hyper Text Markup Language&#xff09;&#xff1a;超文本标记语言。网页结构整体&…

Kubernetes05: Pod

Kubernetes05: Pod 1、概述 1&#xff09;最小部署的单元 2&#xff09;K8s不会处理容器&#xff0c;而是Pod&#xff0c;Pod里边包含多个容器&#xff08;一组容器的集合&#xff09; 3&#xff09;一个Pod中的容器共享一个网络命名空间 4) Pod是短暂存在的东西&#xff08;重…

使用shiroshiro整合其他组件

什么是shiro&#xff1f; 一款apache公司出品的Java安全框架&#xff0c;主要用于设计针对应用程序的保护&#xff0c;使用shiro可以完成认证、授权、加密、会话管理等。保证系统稳定性、数据安全性 优势&#xff1a;易于使用、易于理解、兼容性强&#xff08;可以与其他框架集…

SE-SSD论文阅读

摘要 本文提出了一种基于自集成单级目标检测器(SE-SSD)的室外点云三维目标检测方法。我们的重点是利用我们的公式约束开发软目标和硬目标来联合优化模型&#xff0c;而不引入额外的计算在推理中。具体来说&#xff0c;SE-SSD包含一对teacher 和student ssd&#xff0c;在其中我…