[JAVA]一步接一步的一起开发-图书管理系统(非常仔细,你一定能看懂)[1W字+]

目录

1.想法

2.框架的搭构

2.1图书

2.1.1Book类

2.1.2BookList类

2.2用户

2.2.1User抽象类

2.2.2AdminUser类(管理者)

2.2.3NormalUser

2.3操作

操作接口

借阅操作

删除操作

查询操作

归还图书

展示图书

退出系统

2.4小结

3.主函数的编写

4.操作类的实现

增加图书的实现

借阅图书的实现

删除图书的实现

退出系统的实现

查找图书的实现

归还图书的实现

展示图书的实现

5.代码总览


整体代码在本文最底部

1.想法

首先,关于系统的开发,我们第一步的是搭构整体的框架,再分步实现各个具体的功能。

对于这个图书管理系统的开发,我想达到的目的大致为:

用户分为:1.普通用户

                 2.管理者

根据用户分类的不同,我们会有相不同的菜单展示。菜单上展示有编号的操作供选择,根据选择的编号调用相应的操作。

每一本书的属性分为:书名,作者,价格,类型,借阅状态。

创建一个数组作为书架,存放书。

2.框架的搭构

创建三个包,分类好。因为我们从上面的导图中可以看出,此系统分为三个大类再相互调用链接。

2.1图书

2.1.1Book类

对于图书,我们要先创建一个类,定义其属性。

package book;

public class Book {
    private String name;//书名
    private String author;//作者
    private int price;//价格,此处定义为整数,可以自行决定
    private String type;//类型
    private boolean isBorrow;//借阅状态
    //写出相应的构造方法,因为后续我们要添加书,需要有传参的操作
    //借阅状态在创建书的时候就不用放进去了,boolean默认值为false我们可以将其认定为‘未借阅’
    public Book(String name, String author, int price, String type){   
        this.name = name;
        this.author = author;
        this.price = price;
        this.type = type;
    }
    //因为成员属性都用private修饰符进行了封装,相应的创建出setter与getter

    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 int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public boolean isBorrow() {
        return isBorrow;
    }

    public void setBorrow(boolean borrow) {
        isBorrow = borrow;
    }
    
    public String toString() {
        return "Book{" +
                "name='" + name + '\'' +
                ", author='" + author + '\'' +
                ", price=" + price +
                ", type='" + type + '\'' +
                (isBorrow ? ", 已借阅" : ", 未借阅") + isBorrow +
                '}';
    }
}

2.1.2BookList类

package book;

public class BookList {
    //我们之前创建了一个Book类型,代表一本书
    //此处我们就可以创建Book[]类型的数组,代表数组中每一个元素都为Book类型,
    //即每一个元素都能代表一本书
    private Book[] books = new Book[10];//引用名为books,暂定能存放为10本
    private int useSize;//创建一个引用存放书架上存放的图书数量
    //我们可以提前将图书放进去
    public BookList() {//BookList的构造方法,到时候创建BookList对象的时候会调用,生成三本书。
        books[0] = new Book("三国演义","罗贯中",19,"小说");
        books[1] = new Book("西游记","吴承恩",29,"小说");
        books[2] = new Book("水浒传","施耐庵",8,"小说");
        this.useSize = 3;
    }
    //Book[]和useSize的setter与getter
    //public Book[] getBooks() {
    //    return books;
    //}

    public Book getBooks(int pos) {
        return books[pos];
    }

    //public void setBooks(Book[] books) {
    //    this.books = books;
    //}

    public void setBooks(int pos,Book books) {
        this.books[pos] = books;
    }

    public int getUseSize() {
        return useSize;
    }

    public void setUseSize(int useSize) {
        this.useSize = useSize;
    }
}

2.2用户

对于用户,在屏幕前的人选择之前,我们是无法得知下一步要选择的类型是哪一个。这时候我们就可以运用上我们的抽象类。抽象类规定了每个用户下一定具有的成员,此外子类还可以根据作为不同的用户类型来构建新的专属的成员/成员方法。

所以第一步

2.2.1User抽象类

package user;

public abstract class User {
    protected String name;//用户名
    //构造方法
    public User(String name) {
        this.name = name;
    }
    //打印菜单
    public abstract int menu();
}

2.2.2AdminUser类(管理者)

package user;

import java.util.Scanner;

public class AdminUser extends User{
    //构造方法,要先构造父类的
    public AdminUser(String name) {
        super(name);
    }
    //每一个用户类型都要有不同的菜单
    //管理者菜单为:
    public int menu() {
        System.out.println("管理员菜单!");
        System.out.println("****************************");
        System.out.println("hello " + this.name +" 欢迎来到图书管理系统");
        System.out.println("1. 查找图书");
        System.out.println("2. 新增图书");
        System.out.println("3. 删除图书");
        System.out.println("4. 显示图书");
        System.out.println("0. 退出系统!");
        System.out.println("****************************");
        System.out.println("请输入你的操作:");
        Scanner scanner = new Scanner(System.in);
        int choice = scanner.nextInt();//获取所选择的功能编号
        return choice;//返回功能编号
    }
}

2.2.3NormalUser

package user;

import java.util.Scanner;

public class NormalUser extends User{
    //构造方法
    public NormalUser(String name) {
        super(name);
    }
    //普通用户的菜单
    public int menu() {
        System.out.println("普通用户的菜单!");
        System.out.println("****************************");
        System.out.println("hello " + this.name +" 欢迎来到图书馆");
        System.out.println("1. 查找图书");
        System.out.println("2. 借阅图书");
        System.out.println("3. 归还图书");
        System.out.println("0. 退出系统!");
        System.out.println("****************************");
        System.out.println("请输入你的操作:");
        Scanner scanner = new Scanner(System.in);
        int choice = scanner.nextInt();
        return choice;
    }
}

2.3操作

对于操作,我们可以创建一个接口来规范方法。因为我们不知道具体调用的是哪一个方法,通过接口来达到类似于继承的状态。

因为所有操作都是对书架上的书进行操作,所以参数上均为书架

此环节只是搭构框架,所以方法均没有实现,再后文中会逐一实现。

操作接口

package operation;

import book.BookList;

public class AddOperation implements IOperation {
    @Override
    public void work(BookList bookList) {//重写接口的方法
        System.out.println("新增图书");
    }
}

借阅操作

package operation;

import book.BookList;

public class BorrowOperation implements IOperation{
    @Override
    public void work(BookList bookList) {
        System.out.println("借阅图书");
    }
}

删除操作

package operation;

import book.BookList;

public class DelOperation implements IOperation{
    @Override
    public void work(BookList bookList) {
        System.out.println("删除图书");
    }
}

查询操作

package operation;

import book.BookList;

public class FindOperation implements IOperation{
    @Override
    public void work(BookList bookList) {
        System.out.println("查询图书");
    }
}

归还图书

package operation;

import book.BookList;

public class ReturnOperation implements IOperation{
    @Override
    public void work(BookList bookList) {
        System.out.println("归还图书");
    }
}

展示图书

package operation;

import book.BookList;

public class ShowOperation implements IOperation{
    @Override
    public void work(BookList bookList) {
        System.out.println("展示图书");
    }
}

退出系统

package operation;

import book.BookList;

public class ExitOperation implements IOperation{
    @Override
    public void work(BookList bookList) {
        System.out.println("退出系统");
    }
}

2.4小结

到了此处,我们已经把框架搭构完毕了,剩下的就是靠方法将他们联系起来构成一个整体

3.主函数的编写

因为我们还不知道要怎么将这一堆类链接起来,所以我们可以先试着写主函数。从头开始走一遍,查缺补漏。

第一步,我们创建的用户的登录方法,根据选择的不同可以创建不同的用户类型对象并接收。

import user.AdminUser;
import user.NormalUser;
import user.User;

import java.util.Scanner;

public class Test {
    public static User login(){
        //输入姓名
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入您的姓名:");
        String name = scanner.nextLine();//读取姓名
        System.out.println("请选择您的用户类型  1 -> ‘管理者’ 0 -> ‘普通用户’:");
        int choice = scanner.nextInt();//接收用户类型
        //得到了用户类型,就可以根据用户所选的编号创建用户对象
        if(choice == 1){//如果选择1,创建管理者对象
            return new AdminUser(name);
        }else{//如果选择0,创建普通用户对象
            return new NormalUser(name);
        }
        //在类中创建了一个对象,请问我们怎么得知创建的是普通用户还是管理者呢??
        //这时候我们就需要把这个方法的返回值设为‘User’,再将新建出的对象返回接收就好了
    }
    public static void main(String[] args) {
        //第一步,要做的是用户登录,输入信息,选择用户类型
        //我们可以创建一个类名为login来实现
        User user = login();//创建一个引用来接收新创建的对象,并发生了向上转型,子类对象给父类引用
    }
}

第二步,人有了,书还没呢。所以我们在主函数中new一个书架对象

在主函数中加上此语句即可。

BookList bookList = new BookList();//新建书架对象,并已经存放了三本书

第三步,我们选择好了用户类型,就该打印不同类型的菜单了。

//第三步,创建菜单
        while(true){
            int choice = user.menu();//向上转型,发生动态绑定,产生多态。
                        //虽是通过父类调用方法,得到的是相应子类对象的方法
                        //获取用户选择的操作编号
            
        }

第四步,根据所选编号调用相应的操作

我们该怎么根据标号选择相应的方法呢??我们可以创建一个IOperation[]类型的数组,数组中存放的下标对应菜单中的操作编号。

因为我们的操作方法都为IOperation接口的实现方法,所以使用IOperation类型来存放没有问题(其之间的关系可以看成”类继承“)。

既然用户和菜单之间区分了类型,我们存放操作的数组肯定也要根据菜单的不同来区分一二。通过这种想法我们可以在AdminUser类和NormalUser类所继承的抽象类User中,定义一个IOperation[]类型的成员属性。

再分别在两个子类中的构造方法中,创建存放不同操作的数组。

User抽象类,变更为:

package user;

import operation.IOperation;

public abstract class User {
    protected String name;//用户名

    //变更:增加
    protected IOperation[] iOperations;//定义一个IOperation[]类型,但还没有分配空间
    
    //构造方法
    public User(String name) {
        this.name = name;
    }
    //打印菜单
    public abstract int menu();

}

抽象类多了一个成员属性,相应的在子类的构造方法也要改变

AdminUser的构造方法变更为:

public AdminUser(String name) {
        super(name);
        this.iOperations = new IOperation[]{//实例化不同的对象,有了对象才能调用相应的方法
                new ExitOperation(),
                new FindOperation(),
                new AddOperation(),
                new DelOperation(),
                new ShowOperation()
        };
    }

NormalUser的构造方法变更为:

public NormalUser(String name) {
        super(name);
        this.iOperations = new IOperation[]{//分别实例化不同的操作方法
                new ExitOperation(),
                new FindOperation(),
                new BorrowOperation(),
                new ReturnOperation()
        };
    }

此时,我们已经创建了对应的对象,但还没使用方法来调用他。但我们并不知道用户的类型以及要使用的方法是什么,所以我们可以在抽象类User中创建doOperation方法来调用。

User抽象类新增:

public void doOperation(int choice ,BookList bookList){
        this.iOperations[choice].work(bookList);//调用iOperation[]下标为choice的方法,
                                                //每一个元素为IOperation类型,都有接口重写的work方法
                                                //这就是接口规范的意义了
    }
}

在主函数调用方法

    public static void main(String[] args) {
        BookList bookList = new BookList();//新建书架对象,并已经存放了三本书
        //第一步,要做的是用户登录,输入信息,选择用户类型
        //我们可以创建一个类名为login来实现
        User user = login();//创建一个引用来接收新创建的对象,并发生了向上转型,子类对象给父类引用
        //第三步,创建菜单
        while(true){
            int choice = user.menu();//向上转型,发生动态绑定,产生多态。虽是通过父类调用方法,得到的是相应子类对象的方法
                                     //获取用户选择的操作编号
            user.doOperation(choice,bookList);//根据choice调用对应操作方法
        }
    }

目前大致的框架以及构建起来了,剩下的操作逐一实现就可以了。

4.操作类的实现

bookList的getter和setter有所改变,记得回到上面看看噢。

增加图书的实现

思路:创建一个新的Book对象,再存放到bookList中

package operation;

import book.Book;
import book.BookList;

import java.util.Scanner;

public class AddOperation implements IOperation {
    @Override
    public 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 curSize = bookList.getUseSize();
        bookList.setBooks(curSize,book);//存放到末尾
        bookList.setUseSize(curSize+1);//数量+1
        System.out.println("新增完毕");
    }
}

借阅图书的实现

思路:先获取所要借阅的图书的书名,再根据书名遍历bookList,查看借阅状态,如果为false将相应书的借阅状态改为true。如果没有图书或状态为true(即已被借阅)则返回相应语句提醒且对数组不进行操作。

package operation;

import book.Book;
import book.BookList;

import java.util.Scanner;

public class BorrowOperation implements IOperation{
    @Override
    public void work(BookList bookList) {
        System.out.println("借阅图书");
        System.out.println("请输入要借阅的图书书名");
        Scanner scanner = new Scanner(System.in);
        String name = scanner.nextLine();
        int curSize = bookList.getUseSize();
        for(int i = 0;i < curSize; i++){
            Book book = bookList.getBooks(i);//创建一个暂时的Book类型引用存放在数组中的元素
            if(book.getName().equals(name)){//比较书名
                if(book.getBorrow()){//如果进入则证明已经被借阅
                    System.out.println("此书已被借阅");
                    return;
                }else{
                    book.setBorrow(true);
                    System.out.println("借阅成功");
                    return;
                }
            }
        }
        System.out.println("馆内无此书");//循环结束了 则证明没有此书
        return;
    }
}

删除图书的实现

思路:我们一般在数组中达成删除,就是将后面的元素移位到要删除的数组的下标位置上进行覆盖,达到删除的效果。所以我们先获取要删除的书名,遍历,找到相应的下标位置,将下标往后的元素全部向前移动一位,再将原本的数组最后一位置空,且图书数量-1。找不到则返回相应语句

package operation;

import book.Book;
import book.BookList;

import java.util.Scanner;

public class DelOperation implements IOperation{
    @Override
    public void work(BookList bookList) {
        System.out.println("删除图书");
        System.out.println("请输入要删除的书名");
        Scanner scanner = new Scanner(System.in);
        String name = scanner.nextLine();
        //遍历找书
        int curSize = bookList.getUseSize();
        int index = 0;
        int i = 0;
        for(i = 0; i < curSize; i++){
            Book book = bookList.getBooks(i);
            if(book.getName().equals(name)){
                System.out.println("已找到相应图书,正在进行删除");
                index = i;//获取下标
                break;
            }
        }
        //判断循环结束的原因
        if(i == curSize){//如果已经将图书全部遍历一遍
            System.out.println("没有要删除的图书");
            return;
        }
        for(int j = index; i < curSize - 1; j++){//最后一位不用移动,后面之间置空
            Book book = bookList.getBooks(i+1);//得到下标i+1的图书
            bookList.setBooks(i,book);//把i+1放到i进行覆盖
        }
        bookList.setBooks(curSize,null);//最后一位置空,因为我们已经整体往前移动了一位
        bookList.setUseSize(curSize-1);//总数-1
        return;
    }
}

退出系统的实现

直接退出就行,也可以在主函数进行break跳出while循环再retur结束

package operation;

import book.BookList;

public class ExitOperation implements IOperation{
    @Override
    public void work(BookList bookList) {
        System.out.println("退出系统");
        System.exit(0);
    }
}

查找图书的实现

思路:根据书名,遍历

package operation;

import book.Book;
import book.BookList;

import java.util.Scanner;

public class FindOperation implements IOperation{
    @Override
    public void work(BookList bookList) {
        System.out.println("查询图书");
        System.out.println("请输入书名");
        Scanner scanner = new Scanner(System.in);
        String name = scanner.nextLine();
        int curSize = bookList.getUseSize();//获取长度
        for(int i = 0; i < curSize; i++){
            Book book = bookList.getBooks(i);
            if(book.getName().equals(name)){
                //找到了,打印,使用book的toString
                System.out.println("已找到,如下:");
                System.out.println(book.toString());
                return;
            }
        }
        System.out.println("没有此书");
    }
}

归还图书的实现

思路:和借阅的想法差不多,只要查看其状态再更改就好了。

package operation;

import book.Book;
import book.BookList;

import java.util.Scanner;

public class ReturnOperation implements IOperation{
    @Override
    public void work(BookList bookList) {
        System.out.println("归还图书");
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入书名");
        String name = scanner.nextLine();
        int curSize = bookList.getUseSize();
        for(int i = 0; i < curSize; i++){
            Book book = bookList.getBooks(i);
            if(book.getName().equals(name)){
                if(book.getBorrow()){
                    //进入if证明为true,即已被借阅
                    book.setBorrow(false);
                    System.out.println("归还成功");
                }else{
                    System.out.println("此书不用归还");
                }
            }
        }
        System.out.println("没有要归还的书");
        return;
    }
}

展示图书的实现

思路:遍历再打印即可

package operation;

import book.Book;
import book.BookList;

public class ShowOperation implements IOperation{
    @Override
    public void work(BookList bookList) {
        System.out.println("展示图书");
        int curSize = bookList.getUseSize();
        for(int i = 0; i < curSize; i++){
            Book book = bookList.getBooks(i);
            System.out.println(book);
        }
        return;
    }
}

5.代码总览

图书管理系统 · 28b2ad4 · Pigee1228/JAVA记录 - Gitee.com

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

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

相关文章

【python实操】年轻人,别用记事本保存数据了,试试数据库吧

为什么用数据库&#xff1f; 数据库比记事本强在哪&#xff1f; 答案很明显&#xff0c;你的文件很多时候都只能被一个人打开&#xff0c;不能被重复打开。当有几百万数据的时候&#xff0c;你如何去查询操作数据&#xff0c;速度上要快&#xff0c;看起来要清晰直接 数据库比我…

Azure OpenAI 官方指南03|DALL-E 的图像生成功能与安全过滤机制

2021年1月&#xff0c;OpenAI 推出 DALL-E。这是 GPT 模型在图像生成方面的人工智能应用。其名称来源于著名画家、艺术家萨尔瓦多 • 达利&#xff08;Dal&#xff09;和机器人总动员&#xff08;Wall-E&#xff09;。DALL-E 图像生成器&#xff0c;能够直接根据文本描述生成多…

蓝桥杯真题——模拟灌溉系统

尽量每天都自己写一遍模板&#xff0c;记住模板就好写了 以下内容直接在模板内进行 基本任务&#xff1a;要求“模拟智能灌溉系统”能够实现土壤湿度测量、土壤湿度和时间显示、湿度阈值设 定及存储等基本功能。通过电位器 Rb2 输出电压信号&#xff0c;模拟湿度传感器输出信号…

常见排序算法(C语言实现)

文章目录排序介绍插入排序直接插入排序希尔排序选择排序选择排序堆排序交换排序冒泡排序快速排序递归实现Hoare版本挖坑法前后指针版本非递归实现Hoare版本挖坑法前后指针版本快排的优化三值取中小区间优化归并排序递归实现非递归实现计数排序排序算法复杂度及稳定性分析不同算…

C语言——字符串函数(2)和内存函数

(一)strtok函数dilimiters参数是个字符串&#xff0c;定义了用作分隔符的字符集合第一个参数指定一个字符串&#xff0c;它包含了0个或者多个由dilimiters字符串中一个或者多个分隔符分割的标记。strtok函数找到str中的下一个标记&#xff0c;并将其用 \0 结尾&#xff0c;返回…

第二章Vue组件化编程

文章目录模块与组件、模块化与组件化模块组件模块化组件化Vue中的组件含义非单文件组件基本使用组件注意事项使用 kebab-case使用 PascalCase组件的嵌套模板templateVueComponent一个重要的内置功能单文件组件Vue脚手架使用Vue CLI脚手架先配置环境初始化脚手架分析脚手架结构实…

vue路由的使用

地址&#xff1a; 入门 | Vue Router 一、导入vuerouter依赖包 注意&#xff0c;一定要先引入vue&#xff0c;再引入vue-router&#xff08;引入vue在引入vue-router的上面&#xff09;。不然会报错 <head><meta charset"utf-8"><title></ti…

算法:贪婪算法、分而治之

算法&#xff1a;贪婪算法、分而治之 文章目录1.贪婪算法计数硬币实例12.分而治之分割/歇征服/解决合并/合并实例23.动态规划对照实例34.基本概念算法数据定义数据对象内置数据类型派生数据类型基本操作1.贪婪算法 设计算法以实现给定问题的最佳解决方案。在贪婪算法方法中&am…

中国蚁剑AntSword实战

中国蚁剑AntSword实战1.基本使用方法2.绕过安全狗连接3.请求包修改UA特征伪造RSA流量加密4.插件使用1.基本使用方法 打开蚂蚁宝剑&#xff0c;右键添加数据&#xff1a; 输入已经上传马的路径和连接密码&#xff1a; 测试连接&#xff0c;连接成功&#xff01; GetShell了&…

【Linux】权限详解

前言首先我们先来看一下权限的概念&#xff1a;在多用户计算机系统的管理中&#xff0c;权限&#xff08;privilege&#xff09;是指某个特定的用户具有特定的系统资源使用权力&#xff0c;像是文件夹&#xff0c;特定系统指令的使用或存储量的限制。通常&#xff0c;系统管理员…

动态内存管理详细讲解

目录 1.为什么存在动态内存分配 2. 动态内存函数的介绍 2.1 malloc和free 2.2 calloc 2.3 realloc 今天要和大家分享的内容是的动态内存管理&#xff0c;我们先从他的定义入手学习。 1.为什么存在动态内存分配 我们到现在已经掌握了内存开辟的方式就是要么创建一个变量…

【差分数组】

差分数组一维差分差分数组的作用差分矩阵结语一维差分 输入一个长度为 n 的整数序列。接下来输入 m个操作&#xff0c;每个操作包含三个整数 l,r,c&#xff0c;表示将序列中 [l,r] 之间的每个数加上 c &#xff0c;请你输出进行完所有操作后的序列。 输入格式 第一行包含两个…

ArduPilot飞控之ubuntu22.04-Gazebo模拟

ArduPilot飞控之ubuntu22.04-Gazebo模拟1. 源由2. Gazebo安装2.1 ubuntu22.04系统更新2.2 安装Gazebo Garden2.3 安装ArduPilot Gazebo插件2.3.1 基础库安装2.3.2 源代码编译2.3.3 配置插件2.4 测试Gazebo Garden3. ArduPilot SITL Gazebo模拟3.1 Gazebo Garden模拟环境3.2 Ar…

大数据周会-本周学习内容总结07

目录 01【hadoop】 1.1【编写集群分发脚本xsync】 1.2【集群部署规划】 1.3【Hadoop集群启停脚本】 02【HDFS】 2.1【HDFS的API操作】 03【MapReduce】 3.1【P077- WordCount案例】 3.2【P097-自定义分区案例】 历史总结 01【hadoop】 1.1【编写集群分发脚本xsync】…

【Spring从成神到升仙系列 四】从源码分析 Spring 事务的来龙去脉

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱敲代码的小黄&#xff0c;独角兽企业的Java开发工程师&#xff0c;CSDN博客专家&#xff0c;阿里云专家博主&#x1f4d5;系列专栏&#xff1a;Java设计模式、数据结构和算法、Kafka从入门到成神、Kafka从成神到升仙…

YOLOv7训练自己的数据集(手把手教你)

YOLOv7训练自己的数据集整个过程主要包括&#xff1a;环境安装----制作数据集----模型训练----模型测试----模型推理 一&#xff1a;环境安装 conda create -n yolov7 python3.8 conda activate yolov7 #cuda cudnn torch等版本就不细说了&#xff0c;根据自己的显卡配置自行…

水果新鲜程度检测系统(UI界面+YOLOv5+训练数据集)

摘要&#xff1a;水果新鲜程度检测软件用于检测水果新鲜程度&#xff0c;利用深度学习技术识别腐败或损坏的水果&#xff0c;以辅助挑拣出新鲜水果&#xff0c;支持实时在线检测。本文详细介绍水果新鲜程度检测系统&#xff0c;在介绍算法原理的同时&#xff0c;给出Python的实…

给准备面试网络工程师岗位的应届生一些建议

你听完这个故事&#xff0c;应该会有所收获。最近有一个23届毕业的大学生和我聊天&#xff0c;他现在网络工程专业大四&#xff0c;因为今年6、7月份的时候毕业&#xff0c;所以现在面临找工作的问题。不管是现在找一份实习工作&#xff0c;还是毕业后找一份正式工作&#xff0…

100天精通Python丨基础知识篇 —— 03、Python基础知识扫盲(第一个Python程序,13个小知识点)

文章目录&#x1f41c; 1、Python 初体验Pycharm 第一个程序交互式编程第一个程序&#x1f41e; 2、Python 引号&#x1f414; 3、Python 注释&#x1f985; 4、Python 保留字符&#x1f42f; 5、Python 行和缩进&#x1f428; 6、Python 空行&#x1f439; 7、Python 输出&…

Linux基础知识点总结

♥️作者&#xff1a;小刘在C站 ♥️个人主页&#xff1a;小刘主页 ♥️每天分享云计算网络运维课堂笔记&#xff0c;努力不一定有收获&#xff0c;但一定会有收获加油&#xff01;一起努力&#xff0c;共赴美好人生&#xff01; ♥️夕阳下&#xff0c;是最美的绽放&#xff0…