Java-Review

题型分值总分分布
简答 5 ∗ 8 ′ 5*8' 58 4 0 ′ 40' 40面向对象、异常处理、多线程、输入输出处理
程序分析和补全 3 ∗ 1 0 ′ 3*10' 310 3 0 ′ 30' 30异常处理、Collection、图形化界面、输入输出处理
编程 2 ∗ 1 5 ′ 2*15' 215 3 0 ′ 30' 30Collections、多线程、图形化界面

“题量多,编程题有点难度。”

第十一章网络编程与第十二章数据库编程考试不涉及,除此之外前十章都有涉及。
本篇文章引用文本中的内容均为yy的原话(原意)。
新增了zaj复习课的内容,由于zaj是课程负责人,所以大概率可以将两张卷子的内容简化到一张卷子。

题目类型推测

大概有3~4个简答题会是面向对象及之前的内容。
后五章一定每章都有一个大题(程序分析和补全 / 编程)。
不排除图形化是程序分析和补全题的可能。

简答(考察可能性较大)

  • Java语言的特点
  • Java语言的执行过程
  • 单例设计模式
  • 抽象类与接口的比较
  • 面向对象的三大特征
  • 线程的互斥与协作是怎么实现的
  • 流的分类

程序分析和补全 / 简答

可能1:

  • A卷:
    程序分析与补全:异常+多线程+输入输出
    编程:Collection+图形化
  • B卷:
    程序分析与补全:异常+Collection+输入输出
    编程:多线程+图形化

可能2:

  • A卷:
    程序分析与补全:异常+Collection+图形化
    编程:Collection+多线程
  • B卷:
    程序分析与补全:异常+Collection+输入输出
    编程:多线程+图形化

附——Java文件及程序结构

对于小型项目和程序,我们一般把程序都写在一个.java文件中,这个.java文件我们通常将其命名为Main.java,这个文件的命名就是我们Java程序运行的入口类,该类必须为public。总结来说每个Java文件中只能有一个public类,而且这个public类的名称必须和文件名相同。在下面这个例子中,该程序的public类是Main,所以这个Java文件只能命名为Main.java。程序进入这个Main类之后,需要继续找执行的入口,也就是main()方法,即固定的public static void main(String[] args),从这个地方开始执行程序。

class Point {
    private int x, y;
    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
    public String toString() {
        return "<" + x + "," + y + ">";
    }
}
public class Main {
    public static void main(String[] args) {
        ArrayList<Point> s = new ArrayList<>();
        s.add(new Point(2, 1));
        s.add(new Point(1, 1));
        s.add(new Point(2, 2));
        s.add(new Point(1, 2));
        for (Point sett : s) {
            System.out.println(sett.toString());
        }
    }
}

在上面的例子中有两个类,分别是Point和Main,Java在编译时会为每个类都产生一个.class文件,然后寻找对应public类名字的.class文件作为运行的数据接口。
在这里插入图片描述
该程序的文件结构如上图所示,out/production文件夹中存放的是编译生成的.class文件,javaStructure为本项目名称,其下的Main和Point即为两个.class文件。src中存放的是.java文件,在Main.java中共有两个类,分别是Main和Point。

再看下面这个程序,比较一下和上面的有什么不同。

class Main {
    static class Point { // 静态
        private int x, y;
        public Point(int x, int y) {
            this.x = x;
            this.y = y;
        }
        public String toString() {
            return "<" + x + "," + y + ">";
        }
    }
    public static void main(String[] args) {
        ArrayList<Point> s = new ArrayList<>();
        s.add(new Point(2, 1));
        s.add(new Point(1, 1));
        s.add(new Point(2, 2));
        s.add(new Point(1, 2));
        for (Point sett : s) {
            System.out.println(sett.toString());
        }
    }
}

这个程序把Point类也放到了Main中,但是还有一个区别是Point类被设为了静态的。如果不加static的话,Point就是一个实例内部类,但访问实例内部类需要通过其外部内部类的实例,显然不符合我们的编程目的,符合我们要求的是静态内部类。
在这里插入图片描述
该程序的文件结构如上图所示。
所以为了避免使用内部类,最好将类分开定义,Main主类中只写主方法main(),就像第一个程序那样。

第十章——Java输入输出处理

“会有一个单独的题目来考察Java的输入输出。”
“这章主要是三个问题,流的分类和各个流的基本的功能,流的包装,流的基本的操作,read/write方法,包括DataInputStream和DataOutputStream,readInt()、writeInt()等方法都大概了解一下。”

这一章主要需要理清各个类之间的关系,它们分别的作用。详细读一下代码,比较各个代码的异同。

流的概念

流是针对外部I/O读写的一种模式。
对各种外部设备和网络进行数据的输入/输出操作称为I/O处理,Java用流封装对数据的读写操作,提供了对数据序列读/写的统一接口,封装了程序和操作系统的I/O细节。

(简答) ★ ★ \bigstar\bigstar ★★流的分类

  1. 根据数据流的流动方向分类:
    输入流:从数据源读数据到程序的数据流。
    输出流:将数据从程序写到数据宿的数据流。
  2. 根据数据的处理单位分类:
    节点流:从(向)某个特定的数据源读(写)数据的流。
    处理流(过滤流):将某个已存在的流作为自己的数据源或数据宿进行封装和处理。
  3. 根据数据的处理单位分类:
    字节流:数据未经加工,以字节为传输单位。
    字符流:经过一定编码后的数据,以字符为单位读写数据。

字节流

对于字节流,掌握FileInputStream/FileOutputStream、DataInputStream/DataOutputStream、BufferedInputStream/BufferedOutputStream.
在这里插入图片描述

  1. FileInputStream:从某个文件中读数据。
    int read():从输入流中读取一个字节。返回字节值。
    int read(byte[] b):从输入流中读取,写入b。返回实际读取字节数。
    int read(byte[] b, int off, int len):从输入流中读取len个数据,写入b,从索引off开始。返回实际读取字节数。
public class Main {
    public static void main(String[] args) {
        byte[] buf = new byte[25];
        try {
            File f = new File("./src/test.txt");
            FileInputStream in = new FileInputStream(f); // 用文件对象创建文件输入流
            int b;
            while ((b = in.read(buf)) != -1) { // read()读取文件信息
                String s = new String(buf, 0, b);
                System.out.println(s);
            }
            in.close();
        } catch (IOException e) {
            System.out.println("File not found");
        }
    }
}
  1. FileOutputStream:向某个文件中写入数据。
    void write(int b):将指定的整型数据b的低字节写入输出流。
    void write(byte[] b):把字节数组b中的数据写入输出流。
    void write(byte[] b, int off, int len):把字节数组b中从off开始的len个字节写入输出流。
public class Main {
    public static void main(String[] args) {
        byte[] buf = new byte[25];
        try {
            System.out.println("input one line words");
            int b = System.in.read(buf);
            FileOutputStream writefile = new FileOutputStream("./src/1.txt", true);
            writefile.write(buf);
            writefile.close();
        } catch (IOException e) {
            System.out.println("Error" + e);
        }
    }
}
  1. 过滤流FilterInputStream和FilterOutputStream
    字节流FileInputStream类和FileOutputStream类只提供纯字节或字节数组的输入/输出。如果要进行特殊数据的输入/输出,如基本数据类型的输入/输出,则要通过过滤流FilterInputStream类和FilterOutputStream类中的各种子类,如下面要着重介绍的DataInputStream/DataOutputStream和BufferedInputStream/BufferedOutputStream。

(1)DataInputStream与DataOutputStream一般成对出现,先使用DataOutputStream写入数据,然后使用DataInputStream读取数据。

public class Main {
    public static void main(String[] args) throws IOException { // 注意不写try-catch的话就要throws抛出异常
        FileInputStream in = new FileInputStream("./src/1.txt");
        DataInputStream in_data = new DataInputStream(in); // 包装
        FileOutputStream out = new FileOutputStream("./src/1.txt");
        DataOutputStream out_data = new DataOutputStream(out);

        out_data.writeInt(100);
        out_data.writeDouble(123.123);
        out_data.writeUTF("hello 1230");
        out_data.close();

        System.out.println(in_data.readInt());
        System.out.println(in_data.readDouble());
        System.out.println(in_data.readUTF());
        in_data.close();
    }
}

(2)缓冲字节流BufferedInputStream、BufferedOutputStream在基础字节流的基础上建立一个缓冲区,提高字节流处理的效率。

public class Main {
    public static void main(String[] args) {
        byte[] buf = new byte[25];
        try {
            File f = new File("./src/test.txt");
            FileInputStream in = new FileInputStream(f); // 用文件对象创建文件输入流
            BufferedInputStream bufferedInputStream = new BufferedInputStream(in); // 包装了一个缓存,其它没有什么不同
            int b;
            while ((b = bufferedInputStream.read(buf)) != -1) {
                String s = new String(buf, 0, b);
                System.out.println(s);
            }
            bufferedInputStream.close();
        } catch (IOException e) {
            System.out.println("File not found");
        }
    }
}

字符流

对于字符流,掌握InputStreamReader/OutputStreamWriter、FileReader/FileWriter、BufferedReader/BufferedWriter.
在这里插入图片描述

  1. InputStreamReader和OutputStreamReader
    将以字节方式表示的流转换为特定平台上的字符表示的流。
public class Main {
    public static void main(String[] args) throws IOException {
        File f = new File("./src/test.txt");
        FileInputStream in = new FileInputStream(f); // 字节流
        InputStreamReader isr = new InputStreamReader(in); // 转换为字符流
        BufferedReader br = new BufferedReader(isr); // 为了调用BufferedReader的readLine()方法
        System.out.println(br.readLine());
    }
}
  1. FileReader和FileWriter
public class Main {
    public static void main(String[] args) throws IOException {
        String s = "123 endl\r\n 456 endl\r\n";
        FileWriter fw = new FileWriter("./src/test.txt");
        fw.write(s); // 向test.txt中写入字符串s
        fw.close();
    }
}
  1. BufferedReader和BufferedWriter
    在基础字符流的基础上建立一个缓冲区,来提高字符流处理的效率,见1。

“文件顺序访问、随机访问这部分不考,串行化你得看是哪一套试卷,不一定考,要大概了解一下,做一个准备。”

对象的序列化(串行化)

zaj:“自己在自学的时候可以重点去看一下,但是考试的话不在我们的考试范围内。”

两个老师的说法有些不同,猜测zaj具体知道考哪张卷子,所以她说串行化不考。

创建的对象一般情况下,随着生成该对象的程序的终止而结束。但是有时候我们需要将对象的状态保存下来,在需要时将对象恢复。这种对象能记录自己状态以便将来再恢复的能力称为对象的持续性(Persistence)。
对象通过写出描述自己状态的数值来记录自己,这个过程叫对象的序列化(Serialization)。

第九章——多线程

“有一道编程的题目。结合一个算法来实现,比如在多线程环境下计算素数。”
“这章有一个编程,有一个简答。”

线程和进程有什么区别?它们之间的关系是什么?

程序处于执行状态就被称为进程。
在进程中,进程可以创建并管理多个并发的执行序列,每个执行序列被称为一个独立的线程。
一个进程中的所有线程共享相同的地址空间和这个进程所拥有的操作系统资源。

(编程)两种线程的构造方法

  1. 继承Thread类,重写run()方法,在Thread生成对象时调用Thread的start()方法。
class EvenOdd extends Thread {
    private int startNum;
    private int m;
    public EvenOdd(int o1, int o2) {
        startNum = o1;
        m = o2;
    }
    public void run() {
        for (int i = startNum; i <= 10; i += 2) {
            System.out.println("in the " + m + " thread :" + i);
        }
    }
}
public class Main {
    public static void main(String[] args) {
        EvenOdd ot = new EvenOdd(1, 1);
        EvenOdd et = new EvenOdd(0, 2);
        ot.start();
        et.start();
        System.out.println("Main thread done");
    }
}
  1. 实现Runnable接口,重写run()方法,用Thread类的构造函数传递Runnable对象,再调用该对象的start()方法。
class EvenOdd implements Runnable { // 区别
    private int startNum;
    private int m;
    public EvenOdd(int o1, int o2) {
        startNum = o1;
        m = o2;
    }
    public void run() {
        for (int i = startNum; i <= 10; i += 2) {
            System.out.println("in the " + m + " thread :" + i);
        }
    }
}
public class Main {
    public static void main(String[] args) {
        Thread ot = new Thread(new EvenOdd(1, 1)); // 区别
        Thread et = new Thread(new EvenOdd(0, 2));
        ot.start();
        et.start();
        System.out.println("Main thread done");
    }
}

由于Java是单一继承,所以当某个类已继承了别的类,则其无法再继承Thread类,这时需要通过实现Runnable接口来构造线程。

“这部分考察的比较简单,没有考察线程同步的内容(编程)。”
“在简答中会问到,线程同步方法中,互斥和协作是怎么实现的,有什么区别。”

线程的同步机制的目的

同步机制用来保证进程之间执行顺序正确,确保当两个或多个线程要同时访问共享数据时,一次只能有一个线程访问共享数据,保持共享资源的一致性,使线程之间实现协作。

(简答) ★ ★ ★ \bigstar\bigstar\bigstar ★★★线程互斥

在同一时刻只有一个线程可以操作共享资源。
我们用synchronized来描述互斥对象中的互斥方法。在Java中,每个对象都有一个监视器,当一个线程进入监视器的代码块时,就获得了该对象的锁,其他需要执行该锁代码块的线程就只能等待。当一个线程执行完毕后,释放该对象的锁,其他等待该对象的线程就可以进入代码块并重复上述过程。

(简答) ★ ★ ★ \bigstar\bigstar\bigstar ★★★线程协作

通过synchronized只实现了较低层次的互斥同步,解决了共享数据一致性的问题,下面还需要进一步解决线程同步中如何使任务之间可以协调工作的线程协作问题。
Java线程之间协作最简单的方式,是通过继承自Object类的wait()notify()notifyAll()方法来实现线程挂起和唤醒。wait()方法是使线程等待,直到其他线程调用notify()notifyAll()方法唤醒它;notify() 方法会随机唤醒等待中的一个线程并使它竞争锁;notifyAll() 方法会唤醒所有等待中的线程。

线程协作机制:协作机制建立在保证共享资源的一致性的基础上,而Java实现线程协作的其中一个方法是使用wait()notify()/notifyAll()方法。在这种模型中,线程首先需要请求共享对象的锁,如果没有取得锁则进入同步序列等待锁释放,如果取得锁则判断共享对象是否满足操作条件。如果不满足则使用wait()方法阻塞当前进程并进入对象的等待队列,同时释放锁;如果满足则执行相应逻辑,执行完后如果条件发生改变则使用notify()/notifyAll()方法通知所有等待在对象上的线程并释放锁,接收到通知的线程从等待队列离开,进入同步队列等待锁。

(编程)第八章——Collection

“Java的集合部分呢,也有一个编程题目。在AB卷里,不一定能考到。”
“掌握三个接口,Set、List和Map,结合泛型在一起使用。”
“在两套试卷里面,有编程,有简答,集合是和泛型结合在一起进行考察的。”

对于三种不同的集合,要掌握他们的定义、添加元素和遍历,重点掌握ArrayList(包括其排序和查找),Map可不看。

Set

集合里不能放重复对象,不能放基本数据类型,只能放引用数据类型(对象)。
Set有两个具体实现类:无序的HashSet、有序的TreeSet。

TreeSet支持两种排序方式:自然排序和客户化排序,可以将这两种方法对比理解。

  1. 使用自然排序时,只能向TreeSet集合中加入同一类型的对象,并且这些对象必须实现Comparable接口(中的compareTo()方法)。
class Point implements Comparable {
	private int x, y;
	public Point(int x, int y) {
		this.x = x;
		this.y = y;
	}
	public String toString() {
		return "<" + x + "," + y + ">";
	}
	public int compareTo(Object obj) {
		if (obj instanceof Point) {
			Point p = (Point)obj;
			return (x * 1000 + y) - (p.x * 1000 + p.y);
		} else {
			return -1;
		}
	}
}
public class Main {
	public static void main(String[] args) {
		Set<Point> s = new TreeSet<> ();
		s.add(new Point(2, 1)); // 向集合中加入元素
		s.add(new Point(1, 1));
		s.add(new Point(2, 2));
		s.add(new Point(1, 2));
		// 遍历方式1:迭代器
		Iterator<Point> it = s.iterator();
		while (it.hasNext()) {
			System.out.println(it.next().toString());
		}
		// 遍历方式2:使用增强for循环(推荐)
        for (Point sett : s) {
            System.out.println(sett.toString());
        }
	}
}
  1. 客户化排序需要自定义一个比较类,其中compare()方法用于比较大小。
class PointCompare implements Comparator<Point> { // 实现Comparator接口
    @Override
    public int compare(Point o1, Point o2) { // 重写compare方法
        return (o1.getX() * 1000 + o1.getY()) - (o2.getX() * 1000 + o2.getY());
    }
}
class Point {
    private int x, y;
    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
    int getX() {return x;}
    int getY() {return y;}
    public String toString() {
        return "<" + x + "," + y + ">";
    }
}
public class Main {
    public static void main(String[] args) {
        Set<Point> s = new TreeSet<> (new PointCompare()); // 在新建TreeSet时进行调用
        s.add(new Point(2, 1));
        s.add(new Point(1, 1));
        s.add(new Point(2, 2));
        s.add(new Point(1, 2));
        // 遍历方式1:迭代器
        Iterator<Point> it = s.iterator(); 
        while (it.hasNext()) {
            System.out.println(it.next().toString());
        }
        // 遍历方式2:使用增强for循环(推荐)
        for (Point sett : s) {
            System.out.println(sett.toString());
        }
    }
}

List

List里可以放重复的对象。
List有两个具体实现类:

  1. ArrayList:底层用数组实现,查询效率高
  2. LinkedList:底层用双链表实现,插入与删除效率高
public class Main {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<Integer> ();
        list.add(1);
        list.add(4);
        list.add(3);
        list.add(2);
        // 遍历方式1:利用for循环通过下标访问,只有ArrayList可用下标访问
        for (int i = 0; i < list.size(); i++) {
            System.out.print(list.get(i) + " ");
        }
        System.out.println("");
        Collections.sort(list);
        // 遍历方式2:迭代器
        Iterator<Integer> it = list.iterator();
        while (it.hasNext()) {
            System.out.print(it.next() + " ");
        }
        System.out.println("");
        // 遍历方式3:使用lambda表达式
        list.forEach(integer -> System.out.println(integer + " "));
        // 遍历方式4:使用增强for循环(推荐)
        for (Integer integer : list) {
            System.out.print(integer + " ");
        }
    }
}

ArrayList还有一个重点是binarySearch()方法,二分的前提是序列有序。下面用一个Point类来举例其用法。

class Point {
    private int x, y;
    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
    int getX() {return x;}
    int getY() {return y;}
}
public class Main {
    public static void main(String[] args) {
        List<Point> list = new ArrayList<>();
        list.add(new Point(2, 2));
        list.add(new Point(1, 1));
        list.add(new Point(1, 2));
        list.add(new Point(2, 1));
        for (Point point : list) {
            System.out.println(point.getX() + " " + point.getY());
        }
        System.out.println();
        Collections.sort(list, ((o1, o2) -> { // lambda表达式自定义排序
            if (o1.getX() != o2.getX()) return o1.getX() - o2.getX();
            else return o1.getY() - o2.getY();
        }));
        for (Point point : list) {
            System.out.println(point.getX() + " " + point.getY());
        }
        System.out.println(Collections.binarySearch(list, new Point(2, 1), ((o1, o2) -> {
            if (o1.getX() != o2.getX()) return o1.getX() - o2.getX();
            else return o1.getY() - o2.getY();
        })));
        // binarySearch有三个参数和一个返回值,分别是要二分的序列、要找的元素、比较方法,返回值是int类型,表示要找的元素的位置
    }
}

Map

Map也有两种具体实现类,HashMap和TreeMap,对应于Set两种具体实现类的名字,HashMap应该是无序的,TreeMap应该是有序的。但在Java8之后,HashMap改用红黑树实现,会按照元素插入时的顺序来维护元素的顺序,也能够保证有序性,但和TreeMap是两种不同的实现结构。所以在考试中不必特意区分HashMap和TreeMap,这两种都是有序的。

public class Main {
    public static void main(String[] args) {
        Map<String, String>  map = new TreeMap<>();
        map.put("4", "Monday");
        map.put("1", "Monday");
        map.put("one", "Monday");
        map.put("2", "Tuesday");
        map.put("3", "Wednesday");
        // 使用lambda表达式遍历map
        for (Map.Entry<String, String> mEntry : map.entrySet()) {
            System.out.println(mEntry.getKey() + " " + mEntry.getValue());
        }
    }
}

“泛型这块考察的内容不是很多,基本上你看完Set这一章节就ok了。”
“泛型主要看看它的原理,考察的重点是集合,不是泛型。”

泛型的实质

允许在定义接口、类时声明类型形参,类型形参在整个接口、类体内可当成类型使用,几乎所有可使用普通类型的地方都可以使用这种类型形参。
Java的泛型就类似C++的模板template。

使用泛型的目的

  1. 类型安全性:通过使用泛型,Java编译器可以在编译时进行类型检查,减少运行时出现的类型转换错误。
  2. 代码重用:使用泛型可以实现通用算法,将数据结构与操作分开,达到更好的代码重用。
  3. 代码可读性:使用泛型增加了代码的命名规范以及代码的易读性,在代码中使用泛型参数名称能够更加清晰地表达代码的意图。
  4. 减少强制类型转换:使用泛型的方式可以减少使用强制类型转换的情况,降低代码的复杂度同时提高代码的可读性。
  5. 提供更好的性能:对于类似 ArrayList 等集合类,使用泛型可以帮助编译器优化代码生成的字节码,从而提高代码的性能。

如何用泛型声明一个类

public class Apple<T> {
	private T info;
	public Apple(T info) {
		this.info = info;
	}
	public static void main(String args[]) {
		Apple<String> a1 = new Apple<>("苹果");
	}
}

(编程)第六章——图形用户界面

“也有一个大题,只考察Swing。”
“今年的题也和这个类似,界面的布局很简单。”
在这里插入图片描述

以上面这个窗口为例,介绍一种使用JPanel和FlowLayout的按行绘制的方法,不继承,直接全部在main中实现,适合横向平铺式普通布局,掌握这个就可以应对考试的简单布局。
在这里插入图片描述
这个窗口可纵向分为四部分,每部分看作一行。我们将整体看作一个JFrame,将其设置为流式布局,即从上到下、从左到右依次放置。为每一行创建一个JPanel(每个JPanel的宽度都大概是窗口JFrame的宽度),JPanel也都是流式布局,然后把每个元素都具体分到某一行,将元素放入对应行的JPanel中,最后将所有JPanel放入整体的JFrame中。

例如第一个红色矩形中,这一行有两个元素,分别是“您的姓名:”和一个输入框。首先创建一个JPanel命名为namePanel,为“您的姓名:”创建一个JLabel,为输入框创建一个JTextField,将namePanel的布局方式设置为流式布局,对齐方式设置为居中对齐,然后各自设置JLabel和JTextField的样式,设置完后加入namePanel中即可。
在第二个黄色矩形中,这一行只有一个元素,就是“您的建议:”这么一个文本。我们首先创建一个JPanel命名为advicePanel,创建一个JLabel,将namePanel的布局方式设置为流式布局,对齐方式设置为向左对齐,设置完JLabel的格式后将其加入advicePanel中即可。

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionListener;

public class Main {
    public static void main(String[] args) {
        /*新建JFrame的步骤
        1.定义JFrame: JFrame jf = new JFrame("title");
        2.设置布局(都用流式布局): jf.setLayout(new FlowLayout());
        3.设置窗口大小: jf.setSize(x, y);
        4.窗口居中显示(可选): jf.setLocationRelativeTo(null);
        5.设置点击右上角关闭即结束程序(可选): jf.setDefaultCloseOperation(3);
        6.设置窗口大小不可更改(可选): jf.setResizable(false);
        *7.设置窗口可见,**必须放在程序最后**: jf.setVisible(true);
         */
        // ********************定义Frame********************
        JFrame jf = new JFrame("GuestBook"); // 设置窗口标题
        jf.setLayout(new FlowLayout()); // 设置为流式布局
        jf.setSize(300, 280); // 窗口大小
        jf.setLocationRelativeTo(null); // 使绘制的画面居中显示(屏幕)
        jf.setDefaultCloseOperation(3); // 默认情况下(0),关闭窗口只隐藏界面,不释放占用的内存,通常情况下应使用3
        jf.setResizable(false); // 无法通过拖动改变画面大小
        Font font = new Font("song", Font.PLAIN, 14); // 定义一个全局字体
        /*为一行新建JPanel的步骤:
        1.定义JPanel: JPanel jp = new JPanel();
        2.设置大小: jp.setPreferredSize(new Dimension(x, y)); 必须用setPreferredSize()
        3.设置流式布局: jp.setLayout(new FlowLayout(FlowLayout.CENTER)); 可居中可靠左等
        4.新建该行中的所有元素:var1,var2,var3等
        5.将该行的所有元素(var1,var2,var3...)加入JPanel: jp.add(var1); jp.add(var2); ...
         */
        // ********************第一行Panel********************
        JPanel namePanel = new JPanel();
        namePanel.setPreferredSize(new Dimension(300, 30)); // Panel占一行,所以宽度可以和窗口相同,高度需要估计一下这一行的元素大概需要多高
        namePanel.setLayout(new FlowLayout(FlowLayout.CENTER)); // 居中显示
        JLabel nameLabel = new JLabel("您的姓名:"); // 字体用JLabel
        nameLabel.setFont(font);
        JTextField nameInput = new JTextField(); // 单行文本框用JTextField
        nameInput.setPreferredSize(new Dimension(100, 20)); // nameInput受namePanel的布局管理器管理,需要使用setPreferredSize()设置尺寸,setSize()无效,下同理
        namePanel.add(nameLabel); // 将这一行的元素都添加到这一行的Panel
        namePanel.add(nameInput);
        // ********************第二行Panel********************
        JPanel advicePanel = new JPanel();
        advicePanel.setPreferredSize(new Dimension(280, 25));
        advicePanel.setLayout(new FlowLayout(FlowLayout.LEFT)); // 由于流式布局有一个默认的上下左右间距为5,这里又是靠左对齐的,
                                                                // 所以如果宽度设为300和窗口一样宽的话,字就会跑出窗口去,所以这里设置宽度280
        JLabel adviceLabel = new JLabel("您的建议:");
        adviceLabel.setFont(font);
        advicePanel.add(adviceLabel); // 将这一行的元素都添加到这一行的Panel
        // ********************第三行Panel********************
        JPanel adviceTextPanel = new JPanel();
        adviceTextPanel.setPreferredSize(new Dimension(280, 110));
        adviceTextPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
        JTextArea adviceText = new JTextArea("请输入:", 5, 15); // 多行文本区域用JTextArea
        adviceText.setPreferredSize(new Dimension(260, 130));
        adviceText.setFont(font);
        adviceTextPanel.add(adviceText);
        // ********************第四行Panel********************
        JPanel buttonPanel = new JPanel();
        buttonPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 30, 5)); // 流式布局上下左右默认间距均为5,这里将水平间距调大,让两个按钮间隔大一些
        JButton submitButton = new JButton("提交");
        submitButton.setFont(font);
        submitButton.setPreferredSize(new Dimension(70, 30));
        JButton resetButton = new JButton("复位");
        resetButton.setFont(font);
        resetButton.setPreferredSize(new Dimension(70, 30));
        buttonPanel.add(submitButton);
        buttonPanel.add(resetButton);
        /* 添加按钮监听事件的步骤:
        1.通过ActionListener接口定义事件event
        2.将事件event加入接收操作的按钮的事件监听队列
        */
        // ********************提交按钮********************
        ActionListener submitListener = e -> {
            JDialog notice = new JDialog(new JFrame(), "notice");
            notice.setVisible(true);
            JLabel noticeLabel = new JLabel("已提交");
            noticeLabel.setFont(font);
            notice.setLayout(new FlowLayout(FlowLayout.CENTER));
            notice.add(noticeLabel);
            notice.setSize(100, 100);
            notice.setLocationRelativeTo(null);
            notice.setDefaultCloseOperation(1);
        };
        submitButton.addActionListener(submitListener);
        // ********************重置按钮********************
        ActionListener resetListener = e -> {
            adviceText.setText("请输入:");
        };
        resetButton.addActionListener(resetListener);
        // ********************将每个Panel都添加到Frame********************
        jf.add(namePanel);
        jf.add(advicePanel);
        jf.add(adviceTextPanel);
        jf.add(buttonPanel);
        // ********************最后设置Frame样式********************
        jf.setVisible(true); // 设置可见 ******必须写在最后******
    }
}

基本控件

“基本控件了解JButton、JLabel、JTextField、JTextArea、JCheckbox、JRadioButton.”

容器

“容器了解JFrame、JDialog、JPanel.”

布局管理器

FlowLayout:流式布局,从左到右从上到下依次填充元素,是JPanel默认的布局方式。
BorderLayout:边界布局,将界面分为东、西、南、北、中五个位置,是JFrame默认的布局方式。

事件处理

由于zaj太过于强调事件处理,所以不排除图形化考察程序分析与补全,补充事件处理流程的可能性,所以需要再多掌握一下事件处理。

事件源:事件产生者。鼠标点击一个按钮产生了事件,那么这个按钮就是事件源。
事件监听器:事件的监听者。是实现了相应的事件监听接口的类的对象,接口中定义了事件处理函数。
事件:某个按钮被按下、鼠标移动等。
Java中处理事件的模型是采用委托处理机制。事件源委托事件监听者负责事件处理。

设计事件监听器类共有三种方法:

  1. 让窗体本身来完成监听器。
  2. 用匿名内部类实现。
  3. 用外部类实现。

内部类在yy的课件里是单独的一章,yy也强调了匿名内部类的重要性,所以这里只介绍2方法。

public class Main {
    public static void main(String[] args) {
        JFrame jf = new JFrame("test");
        jf.setSize(200, 200);

        JButton jb = new JButton("submit");
        jb.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) { // 使用匿名内部类
                jb.setEnabled(false);
            }
        });

        jf.add(jb);
        jf.setLocationRelativeTo(null);
        jf.setDefaultCloseOperation(3);
        jf.setVisible(true);
    }
}

ActionListener是一个接口,addActionListener是一个方法,我们通过重写ActionListener接口中的actionPerformed方法实现了事件监听。但现在匿名内部类的写法大多可用lambda表达式来实现,所以上面的代码和下面的是等价的,下面的写法也就是我们图形化界面的大例子的写法。

public class Main {
    public static void main(String[] args) {
        JFrame jf = new JFrame("test");
        jf.setSize(200, 200);

        JButton jb = new JButton("submit");
        jb.addActionListener(e -> jb.setEnabled(false));

        jf.add(jb);
        jf.setLocationRelativeTo(null);
        jf.setDefaultCloseOperation(3);
        jf.setVisible(true);
    }
}

“绘图这一部分呢,大家简单看一下就行了。主要是去考察一下字体、Graphics类,了解一下draw方法和paint方法,把课件上的例子看一下就行了。”
“能把作业单独完成就完全没有问题了(解一元二次方程)。”

第五章——异常处理

“了解异常处理的结构、异常处理机制。”
“主要是简答和程序分析。”

掌握该异常类图,了解异常的分类与关系。
在这里插入图片描述

(简答)什么是运行时异常?什么是受检查异常?

Java运行时系统对字节码进行解释,并能在程序执行时检测到许多类型的异常,称为运行时异常(Runtime Exception),例如空指针、数组越界、除数为零等。从语法角度上,Java不要求捕获这类异常。
Error是指Java运行时系统的内部错误,属于致命性运行时错误。除了Error类和Runtime Exception类的所有其他异常成为受检查异常(Checked Exception),程序必须对可能发生的这类异常进行处理,否则编译不通过。

(简答)Java的异常处理机制有哪些?

  1. 捕获处理异常
    方法中出现的异常对象将被交给Java运行时系统,运行时系统在方法的调用栈中找到相应异常的捕获处理代码,并把异常对象交给其处理,如果找不到可以捕获异常的代码,程序将终止执行。使用try-catch-finally结构。
  2. 声明异常
    不捕获异常,声明异常只是声明方法有可能抛出的异常,从而让该方法上层调研方法捕获异常。使用throws及throw。

(简答)声明异常的目的是什么?怎样声明一个异常?

声明异常是将问题标识出来,报告给调用者。如果方法内通过throw抛出了编译时异常,而没有捕获处理,那么必须通过throws进行声明,让调用者去处理。
声明异常的方法:修饰符 返回值类型 方法名(参数) throws 异常类名1,异常类名2…{ }

(简答)Java中的异常是如何进行分类的,怎样抛出一个异常?

异常的分类可根据在编译时期还是运行时期去检查异常:

  1. 运行时异常(Runtime Exception):在运行时期检查异常,Java运行时系统对字节码进行解释,在程序执行时检测到许多类型的异常,这类异常可通过适当编程避免,不要求捕获这类异常。
  2. 编译时异常(受检查异常)(Checked Exception):在编译时期就会检查异常,程序必须对可能发生的异常进行处理,否则编译不通过。

Java有两种方法抛出异常:

  1. Java运行时环境自动抛出异常。
  2. 在一定条件下,用户使用throw语句显式抛出异常。

(程序分析)try catch finally结构

public class try_catch_finally {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
		// try不能单独存在,必须结合catch或finally来使用
		// try块中没有异常,会执行finally(如果有)
		// try块中有异常,会执行对应的catch块(如果有),try中异常发生点之后的代码将不会执行
        try {
            // try块中放可能发生异常的代码。
            // 如果执行完try且不发生异常,则接着去执行finally块和finally后面的代码(如果有的话)。
            // 如果发生异常,则尝试去匹配catch块。try异常点之后的代码不会运行。
            int num1 = sc.nextInt(); // 这行代码如果出现异常,那么后面的输出语句就不执行
            int num2 = sc.nextInt();
 			System.out.println(num1 + "\t" + num2);
 			System.out.println(num1 / num2);
            String str = null;
            System.out.println(str.charAt(0));
        } catch (InputMismatchException | NullPointerException e) { 
            // 每一个catch块用于捕获并处理一个特定的异常,或者这个异常类型的子类。Java7中可以将多个异常声明在一个catch中。
            // catch后面的括号定义了异常类型和异常参数。如果异常与之匹配且是最先匹配到的,则虚拟机将使用这个catch块来处理异常。
            // 在catch块中可以使用这个块的异常参数来获取异常的相关信息。异常参数是这个catch块中的局部变量,其它块不能访问。
            // 如果当前try块中发生的异常在后续的所有catch中都没捕获到,则先去执行finally,然后到这个函数的外部caller中去匹配异常处理器。
            // 如果try中没有发生异常,则所有的catch块将被忽略。
            System.out.println("catch块 - try里面发生了异常 - 空指针和输入不匹配异常都走这个catch");
        } catch (ArithmeticException e) {
            e.getMessage();
            System.out.println("算数异常:除数不能为0");
        } catch (Exception e) {
            System.out.println("程序发生未知异常");
        } finally {
            // finally块通常是可选的。
            // 无论异常是否发生,异常是否匹配被处理,finally都会执行。
            // 一个try至少要有一个catch块,否则,至少要有1个finally块。但是finally不是用来处理异常的,finally不会捕获异常。
            // finally主要做一些清理工作,如流的关闭,数据库连接的关闭等。 
            System.out.println("finally块");
        }
        System.out.println("异常捕获之后的代码");
    }
}	

throws

throws仅仅是将函数中可能出现的异常向调用者声明,自己不具体处理。
如果一个方法内部的代码会抛出受检查异常(Checked Exception),而方法自己又没有完全处理掉或并不能确定如何处理这种异常,则javac保证你必须在方法的签名上使用throws关键字声明这些可能抛出的异常,表明该方法将不对这些异常进行处理,而由该方法的调用者负责处理,否则编译不通过。
声明异常的方法:修饰符 返回值类型 方法名(参数) throws 异常类名1,异常类名2…{ }

import java.io.*;
public class ThrowsTest {
    public static void main(String[] args) {
        ThrowsTest t = new ThrowsTest();
        try {
            t.readFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public void readFile() throws IOException {
        FileInputStream in = new FileInputStream("hello.txt");
        int b;
        b = in.read();
        while (b != -1) {
            System.out.print((char) b);
            b = in.read();
        }
        in.close();
    }
}

throw

Java异常类对象除在程序执行过程中出现异常时由系统自动生成并抛出,也可根据需要使用throw人工创建并抛出。

public class StudentTest {
    public static void main(String[] args) {
        try {
            Student s = new Student();
            s.regist(-1001);
            System.out.println(s);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
}
class Student {
    private int id;
    public void regist(int id) throws Exception {
        if (id > 0) {
            this.id = id;
        } else {
            throw new Exception("您输入的数据非法!");
        }
    }
    @Override
    public String toString() {
        return "Student [id=" + id + "]";
    }
}

第四章——内部类

“内部类没有单独的考察,它是结合我们Java的GUI来一起进行考察的。”
“匿名内部类重点看一下,在多线程的题目、在用户界面编程的题目会碰到。”

内部类是什么

当A类为B类服务时,为了不让外界直接访问到A类,可把这个A类定义在B类的内部,变为内部类。

内部类的分类

实例内部类(成员内部类):如同类的普通成员一样。实例内部类即没有被static修饰的内部类。在创建实例内部类时,必须已经存在外部类的实例。
静态内部类:如同类的静态成员一样。如果不需要内部类对象与其外围类对象之间有联系,那么可以将内部类声明为static。
局部内部类:局部内部类和局部变量一样,是定义在方法内的类,也不能使用private\public\protected以及static修饰。
匿名内部类:在某些情况下,我们只需要内部类的一个对象,而不需要该类的名字。匿名内部类本身没有构造方法(也不能有),但会调用父类的构造方法。通过匿名内部类实现接口,可以达到隐藏接口的实现的目的。

第三章——面向对象(包括Java概述与基本语法)

(简答) ★ \bigstar Java语言的特点

简单性、面向对象、平台无关性、安全性、多线程、动态性。

(简答) ★ \bigstar Java语言的执行过程

Java程序运行时必须经过编译和运行两个步骤,首先编译后缀为.java的源文件,生成后缀名为.class的字节码文件,Java虚拟机将字节码文件解释执行,并将结果显示出来。

(简答) ★ ★ ★ \bigstar\bigstar\bigstar ★★★面向对象的三大特征

  1. 封装性的目的在于隔离对象的编写者与使用者,使用者无法知晓对象的具体细节,而是通过编写者对对象提供的外部接口来访问对象,降低了软件系统的藕合程度。
  2. 继承性表达了类之间特殊与一般的关系,一般类称为父类,特殊类称为子类,提高了代码的复用性。
  3. 多态性是指类的某个行为具有不同的表现形式,即单一的接口或方法具有不同的动作,Java中的多态包含两种情况:重载与重写(覆盖)。
    重载:多态性在单个类中表现为方法重载;一个类可以有多个名字相同、形参列表不同的方法,在使用时由传递给他们的实参来决定使用哪个方法。
    重写(覆盖):多态性在多个类中表现为继承结构中的方法重写(覆盖);父类和其子类中具有相同的方法头,但用不同的代码实现。

(简答)构造方法的特点

  1. 构造方法的方法名与类名相同。
  2. 构造方法没有返回类型,也不能有void。
  3. 构造方法用new操作符调用,主要作用是初始化对象。
  4. 每个类都至少有一个构造方法,如果没有显式地定义构造方法,Java会自动提供一个缺省的构造方法。

(简答)抽象类的特点

  1. 不能创建实例,即不能new一个抽象类。
  2. 可不含抽象方法,但只要有一个方法是抽象方法,这个类就要定义成抽象类。
  3. 若子类没有实现父类的所有抽象方法,那子类也必须为抽象类。
  4. 构造方法不能都定义为私有,否则不能有子类。
  5. 不能用final修饰,抽象方法必须在子类中才可实现。

(简答)接口的作用

接口提供了一个统一的操作方法名,同样的方法在不同类中可以有不同的具体实现过程,在操作实现了该接口类的对象时采用统一的名字进行调用。

(简答) ★ ★ ★ \bigstar\bigstar\bigstar ★★★抽象类与接口的比较

  1. 语法上,抽象类用关键字abstract class定义,并且可以定义自己的成员变量和非抽象及抽象的成员方法;接口用关键字interface定义,接口内只有公开的静态常量,所有的成员方法都是公开的抽象方法、默认方法和静态方法。
  2. 使用上,抽象类是用来被继承的,一个类只能继承一个父类,但可以实现多个接口,这样可以使用接口实现多重继承,在一定程度上弥补单继承的缺点。
  3. 设计上,抽象类作为父类,与子类之间存在“is-a”关系,即父子类本质上是一种类型;接口只能表示类支持接口的行为,具有接口的功能,因此接口和实现类之间表示的是“like-a”关系。所以在设计上,如果父子类型本质上是一种类型,那父类可设计成抽象类;如果子类型只是想额外具有一些特性,则可以将父类设计成接口,而且这些接口不宜过大,应该设计成多个专题的小接口。这也是面向对象设计的一个重要原则——接口隔离原则:一个类对另一个类的依赖性应建立在最小接口上,不应强迫调用者依赖他们不会使用到的行为,过大的接口是对接口的污染。

类的修饰符和类的成员的修饰符

修饰对象访问修饰符其他修饰符
类(外部)public、缺省final、abstract
语句块缺省static
字段public、protected、缺省、privatefinal、static、transient、volatile
方法public、protected、缺省、privatefinal、abstract、static、native、synchronized

包的相关概念

根据功能的相近性,我们可以将类组织到不同的目录下,这些目录被称为包(package)。
import语句可以引入所需要的类,它可以加载一个包中的所有类或者某个单独的类。
模块(module)是比包更高一个层次的组织单位。

“单例模式是要考的。”

★ ★ \bigstar\bigstar ★★单例设计模式

单例模式是指一个类有且仅有一个实例向整个系统提供。
单例模式设计方案:

  1. 构造方法设为私有权限,防止外界任意调用。
  2. 需要提供一个公有的静态方法获取创建的对象实例。
  3. 创建的唯一对象是被共享且只能被步骤2中的静态方法直接调用,所以需要将其定义为私有的静态对象。
  4. 静态对象的初始化可在外界首次需要对象时在步骤2的方法中调用构造方法创建对象,之后不再创建对象,也可在类的加载阶段初始化。
public class SingleTon {
	private static SingleTon sObj; // 私有且静态
	private SingleTon() {} // 构造方法必须私有
	public static SingleTon getInstance() { // 必须静态
		if (sObj == null) sObj = new SingleTon(); // 首次需要时创建
		return sObj;
	}
class TestSingleTon {
	public static void main(String args[]) {
		SingleTon t1 = SingleTon.getInstance();
		SingleTon t2 = SingleTon.getInstance();
		System.out.printIn(t1 == t2); // 返回true
	}
}

“接口这块大家也要去看一下。”
“简答重点是在面向对象、类和接口、异常处理、集合、IO、线程。”

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Docker Swarm: 容器编排的力量和优势深度解析

文章目录 Docker Swarm的核心概念1. 节点&#xff08;Node&#xff09;2. 服务&#xff08;Service&#xff09;3. 栈&#xff08;Stack&#xff09; 使用Docker Swarm1. 初始化Swarm2. 加入节点3. 创建服务4. 扩展和缩减服务5. 管理栈6. 管理服务更新 Docker Swarm的优势深度解…

JAVA深化篇_42—— 正则表达式

3 正则表达式 3.1正则表达式介绍 3.1.1 什么是正则表达式 正则表达式&#xff0c;又称规则表达式。&#xff08;英语&#xff1a;Regular Expression&#xff0c;在代码中常简写为 regex、regexp 或 RE&#xff09;&#xff0c;是计算机科学的一个概念。正则表达式通常被用来…

前端反卷计划-组件库-03-组件样式

Hi, 大家好&#xff01;我是程序员库里。 今天开始分享如何从0搭建UI组件库。这也是前端反卷计划中的一项。 在接下来的日子&#xff0c;我会持续分享前端反卷计划中的每个知识点。 以下是前端反卷计划的内容&#xff1a; 目前这些内容持续更新到了我的 学习文档 中。感兴趣…

2023年【陕西省安全员B证】考试题库及陕西省安全员B证找解析

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 陕西省安全员B证考试题库是安全生产模拟考试一点通生成的&#xff0c;陕西省安全员B证证模拟考试题库是根据陕西省安全员B证最新版教材汇编出陕西省安全员B证仿真模拟考试。2023年【陕西省安全员B证】考试题库及陕西省…

5g路由器赋能园区无人配送车联网应用方案

随着人工智能、无人驾驶技术和自动化技术的不断进步&#xff0c;无人配送技术得到了极大的发展。园区内的物流配送任务通常是繁琐的&#xff0c;需要大量的人力资源和时间。无人配送技术能够提高配送效率并减少人力成本。无人配送车辆和机器人能够根据预定的路线和计划自动完成…

23111701[含文档+PPT+源码等]计算机毕业设计javaweb点餐系统全套餐饮就餐订餐餐厅

文章目录 **项目功能简介:****点餐系统分为前台和后台****前台功能介绍&#xff1a;****后台功能介绍&#xff1a;** **论文截图&#xff1a;****实现&#xff1a;****代码片段&#xff1a;** 编程技术交流、源码分享、模板分享、网课教程 &#x1f427;裙&#xff1a;77687156…

实践小记——C#格式化小数输出

文章导航 格式化小数位数示例格式化小数总结参考文章 面向Winform的实践过程中&#xff0c;遇到的一些使用到的小细节&#xff1b; 当然其他地方基本上也同理。 写作不易&#xff0c;希望友善多金的码友能够随手点一个赞&#xff0c;共同创建氛围更加良好的开发者社区&#xf…

QTcpSocket发送结构体的做法

作者&#xff1a;朱金灿 来源&#xff1a;clever101的专栏 为什么大多数人学不会人工智能编程&#xff1f;>>> QTcpSocket发送结构体其实很简单:使用QByteArray类对象进行封装发送&#xff0c;示例代码如下&#xff1a; /* 消息结构体 */ struct stMsg {int m_A…

VRRP专题

一&#xff0c;VRRP&#xff1a;虚拟路由冗余协议 将多个路由设备联合组成一台虚拟的路由设备&#xff0c;这台虚拟的路由设备做用户的网关&#xff0c;转发数据&#xff1b;这台虚拟的设备的网关由一个高优先级的设备承载&#xff0c;该设备被称为master路由器&#xff0c;其…

Flutter 应用启动从闪屏页短暂黑屏再到第一个页面

由于应用初始状态启动会有白屏现象&#xff0c;便使用 flutter_native_splash 2.3.5 插件生成了启动相关的配置&#xff0c;并且按照示例使用了 import package:flutter_native_splash/flutter_native_splash.dart;void main() {WidgetsBinding widgetsBinding WidgetsFlutte…

软件开发和测试

一&#xff0c;敏捷软件开发 二&#xff0c;软件测试

Vue3.0和2.0语法不同分析

前言&#xff1a;本篇文章只做VUE3.0和VUE2.0语法上的不同分析&#xff0c;不做性能和源码架构等的分析。 一、VUE3.0和VUE2.0代码结构不同 VUE3.0代码实例 <template><div><span>count is {{ count }}</span><span>plusOne is {{ plusOne }}…

HHDESK资源管理批量修改

HHDESK自带客户端支持批量修改。 右键资源&#xff0c;选择“批量修改”。 在弹出框中&#xff0c;选择需要修改的选项&#xff1b; 以及资源类型&#xff1b; 点击确定&#xff1b; 可在对话框下方的操作日志中&#xff0c;查看结果。

【环境准备】NodeJs(压缩包版本)安装与配置

一、NodeJs(压缩包版本)安装与配置 1、下载、解压 访问 NodeJs官网,选择Window版本的.zip格式进行下载&#xff0c;下载完成后进行解压&#xff08;ps: 本人解压路径为D:\nodejs&#xff09; 2、 环境变量配置 配置环境变量&#xff0c;找到系统变量下的path并选中&#xf…

Windows 安装 汉化版 burp suite

注&#xff1a;个人笔记&#xff0c;仅供参考。 burpsuite 软件下载链接&#xff1a; https://www.alipan.com/s/cWxMF5S9sq4 提取码: 31ut 注&#xff1a;安装路径不要有中文 安装 配置 Java 环境 因为burpsuite是在JAVA环境下运行的&#xff0c;所以首先应该配置好JAVA环…

LabVIEW编程开发NI-USRP

LabVIEW编程开发NI-USRP 可编程性是SDR的关键特性&#xff0c;它使人们能够将无线电外围设备转换为先进的无线系统。USRP是市场上最开放、最通用的SDR&#xff0c;可帮助工程师在主机和FPGA上使用各种软件开发工具构建系统。 有多种选项可用于对基于SDR的系统的主机进行编程。…

LoRa知识点记录

CFO(Central Frequency Offset):&#xff1a;不同设备之间的硬件缺陷引起的&#xff0c;会造成bin 偏移。CFO 引起的 bin 偏移对于preamble和data symbol 都是相同的。 我们在FFT之前应用汉明窗口来抑制旁瓣的影响 lora的灵敏度依赖于峰值高度 没有零填充会导致峰值高度不稳定 …

# Python基础:输入输出详解-读写文件(还需完善)

open() 返回一个 file object &#xff0c;最常使用的是两个位置参数和一个关键字参数&#xff1a;open(filename, mode, encodingNone) f open(workfile, w, encoding"utf-8")第一个实参是文件名字符串。第二个实参是包含描述文件使用方式字符的字符串。mode 的值…

使用Ant Design Pro开发时的一个快速开发接口请求的技巧

使用Ant Design Pro开发时的一个快速开发接口的技巧 当我们的后端在写好接口以后&#xff0c;我们通过swagger knife4j可以生成一个接口文档&#xff0c;后端启动以后&#xff0c;可以生成一个接口文档&#xff0c;当输入地址 localhost:8101/api/v3/api-docs &#xff08;这…

C#语言的由来与发展历程

C#语言的由来与发展历程可以追溯到2000年&#xff0c;当时微软公司为了在.NET平台上开发应用程序&#xff0c;发布了一种新的编程语言——C#。C#语言的设计目标是成为一种简单、现代、通用和面向对象的编程语言&#xff0c;为开发者提供更强大的生产力、更强大的面向对象支持和…