【JAVASE】图书管理系统

⭐ 作者:小胡_不糊涂
🌱 作者主页:小胡_不糊涂的个人主页
📀 收录专栏:浅谈Java
💖 持续更文,关注博主少走弯路,谢谢大家支持 💖

图书管理系统

  • 1. 设计思路图
  • 2. 创建 book 包
    • 2.1 Book 类
    • 2.2 BookList 类
  • 3. 创建 operation 包
    • 3.1 FindOperation 类-查找图书
    • 3.2 AddOperation 类-增加图书
    • 3.3 DelOperation 类-删除图书
    • 3.4 ShowOperation 类-显示图书
    • 3.5 BorrowOperation 类-借阅图书
    • 3.6 ReturnOperation 类-归还图书
    • 3.5 ExitOperation 类-退出系统
  • 4. 创建 user 包
    • 4.1 User 类
    • 4.2 NormUser 类
    • 4.3 AdminUser 类
  • 5. 建立 Main 类

1. 设计思路图

图书管理系统的使用者有两类,一类是图书管理员,一类是借书用户。
他们在管理系统中的需求与操作是不同的,所以要分别进行设计。
在这里插入图片描述

2. 创建 book 包

建立一个 book 包,用来存放与书相关的内容。
在这里插入图片描述

2.1 Book 类

Book 类中存放与书有关的属性,而一本书的属性有很多,比如:书名、作者、价格、类型、编号…

代码实现:

	//属性private String name;//书名private String author;//作者private double price;//价格private String type;//类型private boolean isBorrowed;//是否被借出

对以上私有的属性提供 Getter and Setter 方法:

右击选择 Generate,点击 Getter and Setter方法,然后选择所有属性

得到:

	public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAuthor() {return author;}public void setAuthor(String author) {this.author = author;}public double getPrice() {return price;}public void setPrice(double price) {this.price = price;}public String getType() {return type;}public void setType(String type) {this.type = type;}public boolean isBorrowed() {return isBorrowed;}public void setBorrowed(boolean borrowed) {isBorrowed = borrowed;}

构造书的对象(没有必要写书是否被借出,只需提供书的信息即可):

右击选择 Generate,点击 Constructor方法,然后选择属性

得到:

//构造书的对象--没必要写书是否被借出public Book(String name, String author, double price, String type) {this.name = name;this.author = author;this.price = price;this.type = type;}

打印一本书:

右击选择 Generate,点击 toString方法,然后选择所有属性

得到:

//打印图书@Overridepublic String toString() {return "Book{" +"name='" + name + '\'' +", author='" + author + '\'' +", price='" + price + '\'' +", type='" + type + '\'' +((isBorrowed == true) ? " 已经借出" : " 未被借出") +'}';}

整合代码:

package book;
//存放与书相关的
public class Book {//属性private String name;//书名private String author;//作者private double price;//价格private String type;//类型private boolean isBorrowed;//是否被借出//构造书的对象--没必要写书是否被借出public Book(String name, String author, double price, String type) {this.name = name;this.author = author;this.price = price;this.type = type;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAuthor() {return author;}public void setAuthor(String author) {this.author = author;}public double getPrice() {return price;}public void setPrice(double price) {this.price = price;}public String getType() {return type;}public void setType(String type) {this.type = type;}public boolean isBorrowed() {return isBorrowed;}public void setBorrowed(boolean borrowed) {isBorrowed = borrowed;}//打印图书@Overridepublic String toString() {return "Book{" +"name='" + name + '\'' +", author='" + author + '\'' +", price='" + price + '\'' +", type='" + type + '\'' +", isBorrowed=" + isBorrowed +'}';}
}

2.2 BookList 类

BookList 类(书架)用来存放书与借书,而对于书架上的书,我们需要知道一个书架能放多少本书,有几本书未被借出,书架上所存放的书都有哪些,书架上还能继续存放几本书等。

基于这些问题,我们先定义一个 books 数组来控制书架上存放书的数量,

	private Book[] books ;private int usedSize;//记录当前书架上 实际存放的书的数量private static final int DEFAULT_CAPACITY = 10;public BookList() {this.books = new Book[DEFAULT_CAPACITY];//初始化书的数量}

因为usedSize是private修饰的,我们就可以提供Getter and Setter 方法:

	public int getUsedSize() {return usedSize;}public void setUsedSize(int usedSize) {this.usedSize = usedSize;}

而对于books数组,当我们想获取或设置某个下标的书时,也可以提供Getter and Setter方法,但是需要进行改进:

	public Book getBook(int pos) {return books[pos];//返回书的位置}public void setBooks(int pos,Book book) {books[pos] = book;//将books的pos位置存放一本书}

提前存入一些书进去:

this.books[0] = new Book("三国演义","罗贯中",10,"小说");
this.books[1] = new Book("西游记","吴承恩",9,"小说");
this.books[2] = new Book("红楼梦","曹雪芹",19,"小说");
this.usedSize = 3;

整合代码:

package book;
//书架
public class BookList {private Book[] books ;private int usedSize;//记录当前书架上 实际存放的书的数量private static final int DEFAULT_CAPACITY = 10;public BookList() {this.books = new Book[DEFAULT_CAPACITY];//初始化书的数量//放好书!!this.books[0] = new Book("三国演义","罗贯中",10,"小说");this.books[1] = new Book("西游记","吴承恩",9,"小说");this.books[2] = new Book("红楼梦","曹雪芹",19,"小说");this.usedSize = 3;}public int getUsedSize() {return usedSize;}public void setUsedSize(int usedSize) {this.usedSize = usedSize;}public Book getBook(int pos) {return books[pos];}public void setBooks(int pos,Book book) {books[pos] = book;}public Book[] getBooks() {return books;}
}

3. 创建 operation 包

存放操作相关的内容:

管理员:查找图书、增加图书、删除图书、显示图书、退出系统
用户:查找图书、借阅图书、归还图书、退出系统
其中查找图书、退出系统两者都具备,可以在一个类中进行操作。

在上述操作中都需要对 BookList 进行操作,为了统一管理,我们在 operation 包内定义一个接口 IOPeration,通过IOPeration就可以对这些操作进行组织,从而实现了接口的统一性:

请添加图片描述
在该接口中定义一个 work方法,对书架上的书进行统一管理:

package operation;
import book.BookList;
public interface IOPeration {void work(BookList bookList);
}

3.1 FindOperation 类-查找图书

package operation;
import book.Book;
import book.BookList;
import java.util.Scanner;public class FindOperation implements IOPeration{@Overridepublic void work(BookList bookList) {System.out.println("查找图书!");//通过书名查找图书Scanner scanner = new Scanner(System.in);String name = scanner.nextLine();//遍历这个数组int currentSize = bookList.getUsedSize();for (int i = 0; i < currentSize; i++) {Book book = bookList.getBook(i);if(book.getName().equals(name)) {System.out.println("找到了这本书,信息如下:");System.out.println(book);return;}}`在这里插入代码片`System.out.println("没有找到这本书!");}
}

3.2 AddOperation 类-增加图书

import book.Book;
import book.BookList;
import java.util.Scanner;public class AddOperation implements IOPeration{@Overridepublic void work(BookList bookList) {System.out.println("新增图书!");Scanner scanner = new Scanner(System.in);System.out.println("请输入书名:");String name = scanner.nextLine();System.out.println("请输入作者:");String author = scanner.nextLine();System.out.println("请输入类型:");String type = scanner.nextLine();System.out.println("请输入价格:");int price = scanner.nextInt();Book book = new Book(name,author,price,type);//检查 数组当中 有没有这本书int currentSize = bookList.getUsedSize();for (int i = 0; i < currentSize; i++) {Book book1 = bookList.getBook(i);if(book1.getName().equals(name)) {System.out.println("有这本书,不进行存放了!");return;}}if(currentSize == bookList.getBooks().length) {System.out.println("书架满了!");}else {bookList.setBooks(currentSize,book);bookList.setUsedSize(currentSize+1);}}
}

3.3 DelOperation 类-删除图书

package operation;
import book.Book;
import book.BookList;
import java.util.Scanner;public class DelOperation implements IOPeration{@Overridepublic void work(BookList bookList) {System.out.println("删除图书!");Scanner scanner = new Scanner(System.in);System.out.println("请输入你要删除的图书:");String name = scanner.nextLine();int pos = -1;int currentSize = bookList.getUsedSize();int i = 0;for (; i < currentSize; i++) {Book book = bookList.getBook(i);if(book.getName().equals(name)) {pos = i;break;}}if(i == currentSize) {System.out.println("没有你要删除的图书!");return;}//开始删除int j = pos;for (; j < currentSize-1; j++) {//[j] = [j+1]Book book = bookList.getBook(j+1);bookList.setBooks(j,book);}bookList.setBooks(j,null);bookList.setUsedSize(currentSize-1);}
}

3.4 ShowOperation 类-显示图书

因为我们的书都是在数组中保存,所以可以通过数组元素的打印方法,来显示所有图书:

package operation;
import book.Book;
import book.BookList;public class ShowOperation implements IOPeration{@Overridepublic void work(BookList bookList) {System.out.println("显示图书!");int currentSize = bookList.getUsedSize();//获取书架上书的数量for (int i = 0; i < currentSize; i++) {Book book = bookList.getBook(i);System.out.println(book);}}
}

3.5 BorrowOperation 类-借阅图书

package operation;
import book.Book;
import book.BookList;
import java.util.Scanner;public class BorrowOperation implements IOPeration{@Overridepublic void work(BookList bookList) {System.out.println("借阅图书!");/*** 1. 你要借阅哪本书?* 2. 你借阅的书有没有?* 3. 借阅的方式是什么? -》 isB.... = true*/Scanner scanner  = new Scanner(System.in);System.out.println("请输入你要借阅的图书:");String name = scanner.nextLine();int currentSize = bookList.getUsedSize();for (int i = 0; i < currentSize; i++) {Book book = bookList.getBook(i);if(book.getName().equals(name)) {book.setBorrowed(true);System.out.println("借阅成功!");System.out.println(book);return;}}System.out.println("你借阅的图书 不存在!! ");}
}

3.6 ReturnOperation 类-归还图书

package operation;
import book.Book;
import book.BookList;
import java.util.Scanner;public class ReturnOperation implements IOPeration{@Overridepublic void work(BookList bookList) {System.out.println("归还图书!");Scanner scanner  = new Scanner(System.in);System.out.println("请输入你要归还的图书:");String name = scanner.nextLine();int currentSize = bookList.getUsedSize();for (int i = 0; i < currentSize; i++) {Book book = bookList.getBook(i);if(book.getName().equals(name)) {book.setBorrowed(false);System.out.println("归还成功!");System.out.println(book);return;}}System.out.println("你归还的图书 不存在!! ");}
}

3.5 ExitOperation 类-退出系统

package operation;
import book.BookList;public class ExitOperation implements IOPeration{@Overridepublic void work(BookList bookList) {System.out.println("退出系统!");System.exit(0);}
}

4. 创建 user 包

用来维护使用者。对于该系统来讲,使用者有管理员和普通用户,所以在 user 包中我们分别建立用户类(User)、管理员类(AdminUser)和普通用户类(NormUser)。
User用来存放和声明AdminUser和NormUser两类中相同的一些属性与方法,而不同的方法分别在各类中进行重写即可,比如:两者的使用时所显示的菜单以及各自所调用的一些功能。

4.1 User 类

管理员和用户在进行系统操作时,会有一些相同的操作,在User类中就会实现他们之间共有的属性与方法。
先在User类中先定义一个name成员:

package user;
public abstract class User {protected String name;//只能User包中的子类访问//构造方法public User(String name) {this.name = name;}public abstract int menu();//声明menu方法,没有具体实现的抽象方法}

创建doOperation方法,用来调用用户需要进行的操作:

public void doOperation(int choice, BookList bookList){ioPerations[choice].work(bookList);}

整合代码:

package user;
import book.BookList;
import operation.IOPeration;public abstract class User {protected String name;//只能同一个包中的子类访问protected IOPeration[] ioPerations;//构造方法public User(String name) {this.name = name;}public abstract int menu();//声明menu方法,没有具体实现的抽象方法public void doOperation(int choice, BookList bookList){ioPerations[choice].work(bookList);}
}

4.2 NormUser 类

与AsminUser相同的一些操作已经在User类中说明,所以这里只需继承父类(User)即可:

public class NormalUser extends User{//帮助父类进行构造,对父类中的name成员进行初始化public NormalUser(String name) {super(name);};
}

设计用户菜单:
在每次打印完菜单后,提醒用户输入所需操作对应的数字,并返回对应操作数。

public int menu() {System.out.println("**********管理员用户*****");System.out.println("1. 查找图书");System.out.println("2. 新增图书");System.out.println("3. 删除图书");System.out.println("4. 显示图书");System.out.println("0. 退出系统");System.out.println("**********************");Scanner scanner = new Scanner(System.in);System.out.println("请输入你的操作:");int choice = scanner.nextInt();return choice;}

因为继承了User类,需要帮助父类初始化ioPerations,所以在该数组中存入属于普通用户的操作,且放入顺序与对应的操作数字一致:

this.ioPerations=new IOPeration[]{new ExitOperation(),new FindOperation(),new BorrowOperation(),new ReturnOperation()
};

整合代码:

package user;
import operation.*;
import java.util.Scanner;public class NormalUser extends User{public NormalUser(String name) {super(name);this.ioPerations=new IOPeration[]{new ExitOperation(),new FindOperation(),new BorrowOperation(),new ReturnOperation()};}public int  menu() {System.out.println("**********普通用户******");System.out.println("1. 查找图书");System.out.println("2. 借阅图书");System.out.println("3. 归还图书");System.out.println("0. 退出系统");System.out.println("**********************");Scanner scanner = new Scanner(System.in);System.out.println("请输入你的操作:");int choice = scanner.nextInt();return choice;}
}

4.3 AdminUser 类

继承User类:

public class AdminUser extends User{//帮助父类进行构造,对父类中的name成员进行初始化public AdminUser(String name) {super(name);};
}

设计管理者菜单:
提醒管理员输入所需操作对应的数字,并返回对应操作数。

    public int  menu() {System.out.println("**********普通用户******");System.out.println("1. 查找图书");System.out.println("2. 借阅图书");System.out.println("3. 归还图书");System.out.println("0. 退出系统");System.out.println("**********************");Scanner scanner = new Scanner(System.in);System.out.println("请输入你的操作:");int choice = scanner.nextInt();return choice;}

初始化父类ioPerations:

this.ioPerations=new IOPeration[]{new ExitOperation(),new FindOperation(),new BorrowOperation(),new ReturnOperation()
};

整合代码:

package user;
import operation.*;
import java.util.Scanner;public class NormalUser extends User{public NormalUser(String name) {super(name);this.ioPerations=new IOPeration[]{new ExitOperation(),new FindOperation(),new BorrowOperation(),new ReturnOperation()};}public int  menu() {System.out.println("**********普通用户******");System.out.println("1. 查找图书");System.out.println("2. 借阅图书");System.out.println("3. 归还图书");System.out.println("0. 退出系统");System.out.println("**********************");Scanner scanner = new Scanner(System.in);System.out.println("请输入你的操作:");int choice = scanner.nextInt();return choice;}
}

5. 建立 Main 类

Main类的作用:联合三个包中的方法实现程序运行。
在这里插入图片描述
设置一个用户登录界面。先输入使用者的姓名,然后选择自己的身份(1–>管理员 2–>普通用户),通过所选数字的不同,使系统调用两类用户各自所属的方法。
在这里插入图片描述

import user.AdminUser;
import user.NormalUser;
import user.User;
import java.util.Scanner;public class Main {public static User login(){System.out.println("请输入你的姓名:");Scanner scanner=new Scanner(System.in);String name=scanner.nextLine();System.out.println("请输入你的身份:1->管理员  2->普通用户");int choice =scanner.nextInt();if(choice==1){//管理员return new AdminUser(name);}else{//普通用户return new NormalUser(name);}}public static void main(String[] args) {User user=login();//向上转型,user指向哪个对象要看返回值是什么int choice=user.menu();//动态绑定,要通过user调用menu方法,就要在User先声明。并用choice接收返回的操作数}
}

根据上述choice的值可以选择调用哪个方法,因此我们创建一个 doOperation 方法来调用用户想要执行的操作:
在这里插入图片描述

BookList bookList=new BookList();
user.doOperation(choice,bookList);

整合代码:

import book.BookList;
import user.AdminUser;
import user.NormalUser;
import user.User;
import java.util.Scanner;public class Main {public static User login(){System.out.println("请输入你的姓名:");Scanner scanner=new Scanner(System.in);String name=scanner.nextLine();System.out.println("请输入你的身份:1->管理员  2->普通用户");int choice =scanner.nextInt();if(choice==1){//管理员return new AdminUser(name);}else{//普通用户return new NormalUser(name);}}public static void main(String[] args) {User user=login();//向上转型,user指向哪个对象要看返回值是什么//根据choice选择来调用哪个方法BookList bookList=new BookList();while(true) {int choice = user.menu();//动态绑定,要通过user调用menu方法,就要在User先声明。并用choice接收返回的操作数user.doOperation(choice, bookList);}}
}

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

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

相关文章

MySQL常见面试题(一)

&#x1f600;前言 在数据库管理系统中&#xff0c;存储引擎起着核心的角色&#xff0c;它决定了数据管理和存储的方式。MySQL作为一个领先的开源关系型数据库管理系统&#xff0c;提供了多种存储引擎来满足不同的需求和优化不同的应用。除了选择合适的存储引擎&#xff0c;数据…

四川百幕晟科技:抖店精选联盟怎么使用?

近年来&#xff0c;电商平台的兴起让很多人纷纷加入进来&#xff0c;希望通过在网上销售产品来赚取更多的利润。在这个竞争激烈的市场中&#xff0c;如何找到稳定的渠道来推广自己的产品成为了每个卖家的追求。抖店精选联盟是一个不错的选择&#xff0c;可以帮助卖家快速提升销…

Mybatis学习笔记8 查询返回专题

Mybatis学习笔记7 参数处理专题_biubiubiu0706的博客-CSDN博客 1.返回实体类 2.返回List<实体类> 3.返回Map 4.返回List<Map> 5.返回Map<String,Map> 6.resultMap结果集映射 7.返回总记录条数 新建模块 依赖 目录结构 1.返回实体类 如果返回多条,用…

PDF文件的页眉页脚无法删除的原因和三种替代方法

大家好&#xff01; 今天六分职场为大家介绍一个PDF的常用操作。有的时候我们需要为PDF文件添加页眉页脚&#xff0c;但如果我们这个PDF文档是从其他地方参考的&#xff0c;经常会发现无法直接编辑或者删除PDF文件中页眉页脚。 不用担心&#xff0c;我们使用WPS的PDF软件&…

计算机竞赛 深度学习 opencv python 实现中国交通标志识别

文章目录 0 前言1 yolov5实现中国交通标志检测2.算法原理2.1 算法简介2.2网络架构2.3 关键代码 3 数据集处理3.1 VOC格式介绍3.2 将中国交通标志检测数据集CCTSDB数据转换成VOC数据格式3.3 手动标注数据集 4 模型训练5 实现效果5.1 视频效果 6 最后 0 前言 &#x1f525; 优质…

Go面试题:锁的实现原理sync-mutex篇

在Go中&#xff0c;主要实现了两种锁&#xff1a;sync.Mutex(互斥锁) 以及 sync.RWMutex(读写锁)。 本篇主要给大家介绍sync.Mutex的使用和实现原理。 文章目录 为什么需要锁在Go中对于并发程序进行公共资源的访问的限制最常用的就是互斥锁&#xff08;sync.mutex&#xff09…

前后端分离毕设项目之基于springboot+vue的笔记记录分享网站设计与实现(内含源码+文档+部署教程)

博主介绍&#xff1a;✌全网粉丝10W,前互联网大厂软件研发、集结硕博英豪成立工作室。专注于计算机相关专业毕业设计项目实战6年之久&#xff0c;选择我们就是选择放心、选择安心毕业✌ &#x1f345;由于篇幅限制&#xff0c;想要获取完整文章或者源码&#xff0c;或者代做&am…

【陕西理工大学-数学软件实训】数学实验报告(8)(数值微积分与方程数值求解)

目录 一、实验目的 二、实验要求 三、实验内容与结果 四、实验心得 一、实验目的 1. 掌握求数值导数和数值积分的方法。 2. 掌握代数方程数值求解的方法。 3. 掌握常微分方程数值求解的方法。 二、实验要求 1. 根据实验内容&#xff0c;编写相应的MATLAB程序&#xff0c…

Linux常用工具

文章目录 前言一、Linux编辑器-vim使用1.vim的基本概念2. vim的基本操作3. vim命令集1. 正常模式1. 模式切换和光标移动2. 删除文字及复制3. 其他操作 2. 底行模式 二、Linux编译器-gcc/g使用1. 命令和选项2. 预处理3. 编译4. 汇编(生成机器可识别代码)5. 连接(生成可执行文件或…

抖音seo矩阵系统源代码分享

技术开发注意事项&#xff1a; 确定业务需求&#xff1a;在开发前&#xff0c;需要明确抖音矩阵系统的业务需求&#xff0c;了解用户的需求和使用习惯&#xff0c;明确系统的功能、性能和安全需求。 选择合适的技术方案&#xff1a;根据系统的需求和复杂度&#xff0c;选择合适…

JavaWeb 学习笔记 3:Servlet

JavaWeb 学习笔记 3&#xff1a;Servlet 1.简介 Servlet 是 JavaEE 定义的一套 Web 应用开发标准&#xff08;接口&#xff09;&#xff0c;实现了该技术的 Web 服务器软件&#xff08;如 Tomcat&#xff09;上可以运行一个 Servlet 容器&#xff0c;只要我们使用 Servlet 技…

【测试开发】基础篇 · 专业术语 · 软件测试生命周期 · bug的描述 · bug的级别 · bug的生命周期 · 处理争执

【测试开发】基础篇 文章目录 【测试开发】基础篇1. 软件测试生命周期1.1 软件生命周期1.2 软件测试生命周期 2. 描述bug3. 如何定义bug的级别3.1 为什么要对bug进行级别划分3.2 bug的一些常见级别 4. bug的生命周期5. 产生争执这么怎么办&#xff08;处理人际关系&#xff09;…

服务器数据恢复-LINUX操作系统下各文件系统误删除/格式化数据的恢复方案

服务器数据恢复环境&#xff1a; 基于EXT2/EXT3/EXT4/Reiserfs/Xfs文件系统的Linux操作系统。 服务器故障&#xff1a; LINUX操作系统下误删除/格式化数据。 服务器数据恢复过程&#xff1a; 1、首先会检测服务器是否存在硬件故障&#xff0c;如果检测出硬件故障&#xff0c;交…

Golang Linux 安装与环境变量配置

下载 Go 二进制包 wget https://dl.google.com/go/go1.21.1.linux-amd64.tar.gz 解压文件并将其移至 /usr/local 目录 sudo tar -C /usr/local -xzf go1.20.1.linux-amd64.tar.gz -C 选项解压文件到 /usr/local 目录&#xff0c;查看 /usr/local/go 目录的内容 将 Go 二进…

19 视图定义 union 是根据第一个 select 字段列表顺序,来进行 merge 的

前言 这个问题主要是 在之前存在这样的一个问题, 在生产环境上面 按照 我的直观理解, mysql 应该是根据 key 进行 merge, 所以 select 的顺序应该是 “不重要”??, 但是 结果我理解错了 然后 线上的查询也出现了问题, 发现很奇怪的问题, 明明 key01 列 是 id, 但是有一部…

深度学习——线性神经网络一

深度学习——线性神经网络一 文章目录 前言一、线性回归1.1. 线性回归的基本元素1.1.1. 线性模型1.1.2. 损失函数1.1.3. 解析解1.1.4. 随机梯度下降1.1.5. 用模型进行预测 1.2. 向量化加速1.3. 正态分布与平方损失1.4. 从线性回归到深度网络 二、线性回归的从零开始实现2.1. 生…

Java面试题整理(带答案)

目录 TCP和UDP的区别 get和post的区别 Cookie和session的区别 Java的基本类型有哪些&#xff1f; 抽象类和接口区别&#xff1f; 对于堆栈的理解 和equals区别 如何理解Java多态&#xff1f; 创建线程都有哪些方式 脏读、不可重复度、幻读都是什么&#xff1f; Jav…

多线程详解(上)

文章目录 一、线程的概念1&#xff09;线程是什么2&#xff09;为甚要有线程&#xff08;1&#xff09;“并发编程”成为“刚需”&#xff08;2&#xff09;在并发编程中, 线程比进程更轻量. 3&#xff09;线程和进程的区别 二、Thread的使用1&#xff09;线程的创建继承Thread…

算法通关村-----链表中环的问题

环形链表 问题描述 给你一个链表的头节点 head &#xff0c;判断链表中是否有环。如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&#xff0c;评测系统内部使用整数 pos 来表示链表尾连接到链表中…

使用Scrapy构建高效的网络爬虫

&#x1f482; 个人网站:【工具大全】【游戏大全】【神级源码资源网】&#x1f91f; 前端学习课程&#xff1a;&#x1f449;【28个案例趣学前端】【400个JS面试题】&#x1f485; 寻找学习交流、摸鱼划水的小伙伴&#xff0c;请点击【摸鱼学习交流群】 Scrapy是一个强大的Pyth…