【JAVA入门】Day36 - 异常

news2024/11/25 22:40:37

【JAVA入门】Day36 - 异常


文章目录

  • 【JAVA入门】Day36 - 异常
    • 一、异常结构体系综述
      • 1.1 错误(Error)
      • 1.2 异常(Exception)
      • 1.3 运行时异常(RuntimeException)
      • 1.4 其他异常
    • 二、编译时异常和运行时异常
    • 三、异常的作用
      • 3.1 查询 bug 的关键参考信息
      • 3.2 作为方法内部一种特殊的返回值
    • 四、异常的处理方式
      • 4.1 JVM 默认的处理方式
      • 4.2 自己处理(捕获异常)
      • 4.3 如果 try 中没有遇到问题,怎么执行?
      • 4.4 如果 try 中可能会遇到多个问题,怎么执行?
      • 4.5 如果 try 中碰到的问题没有被捕获?
      • 4.6 如果 try 中遇到了问题,那么 try 下面的其他代码还会执行吗?
    • 五、Throwable 类
    • 六、抛出处理
    • 七、自定义异常


        异常就是代表程序出现的问题。Java 的异常机制可以告知 JVM,程序出现异常之后,应该如何处理。
        比如下面两种异常情况:

int[] arr = {10, 20, 30};
System.out.println(arr[3]);

ArrayIndexOutOfBoundsException 数组越界异常

int a = 10;
int b = 0;
System.out.println(a / b);

ArithmeticException 算术异常

        Java 中有太多异常类型了,它们组成了异常结构体系。

一、异常结构体系综述

        所有的错误和异常都继承自 Java.lang.Throwable 类,然后分为两个分支,一个叫“错误”(Error),一个叫“异常”(Exception),其中异常中最重要的一个总类就是“运行时异常”(RuntimeException),它下面还有很多很多异常类。
在这里插入图片描述

1.1 错误(Error)

        Error 代表的是系统级别的错误(属于严重问题),它们是 JVM 无法解决的问题,如:栈溢出(StackOverflowError)、内存溢出(OOM)等,系统一旦出现问题,sun 公司会把这些错误封装成 Error 对象给公司内部研究,我们开发人员无需关注。

1.2 异常(Exception)

        Exception 代表程序可能出现的问题,我们通常会用 Exception 及它的子类来封装程序出现的问题。

1.3 运行时异常(RuntimeException)

        RuntimeException 及其子类,编译阶段不会出现异常提醒,在运行时才会出现异常(如:数组索引越界异常)。

1.4 其他异常

        指的是编译阶段就会出现提醒的异常(如:日期解析异常)。

二、编译时异常和运行时异常

        以下代码明确了编译时异常和运行时异常的区别:

package Exceptions;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class ExceptionDemo1 {
    public static void main(String[] args) throws ParseException {

        //编译时异常(在编译阶段,必须要手动处理,否则代码报错)
        String time = "2030年1月1日";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
        Date date = sdf.parse(time);
        System.out.println(date);

        //运行时异常(编译阶段不会出现报错,在运行时才会出现)
        int[] arr = {1, 2, 3, 4, 5};
        System.out.println(arr[10]);        //ArrayIndexOutOfBoundsException
    }
}

在这里插入图片描述

        Java 为什么设计这两种异常?这正是因为 Java 在把 java 文件编译成字节码 class 文件时,不会运行代码,只会检查语法是否错误,或者做一些性能的优化。而 JVM 才是真正运行代码的。编译时异常更多地是提醒程序员检查本地信息,而运行时异常并不在于提醒,它是真的代码出错导致程序运行时出现了问题。

三、异常的作用

        异常的两个重要作用就是:

  • 作用一:异常是用来查询 bug 的关键参考信息。
  • 作用二:异常可以作为方法内部的一种特殊返回值,以便通知调用者底层的执行情况。

3.1 查询 bug 的关键参考信息

        开发环境运行代码后的异常往往会在下方提示,根据异常提示的名字、信息,我们可以快速找到 bug 产生的原因。

package Exceptions;

public class ExceptionDemo2 {
    public static void main(String[] args) {
        /*
            - 作用一:异常是用来查询 bug 的关键参考信息。
            - 作用二:异常可以作为方法内部的一种特殊返回值,以便通知调用者底层的执行情况。
         */

        Student[] arr = new Student[3];
        String name = arr[0].getName();
        System.out.println(name);

        /*
        Exception in thread "main" java.lang.NullPointerException: Cannot invoke "Exceptions.Student.getName()" because "arr[0]" is null
	    	at Exceptions.ExceptionDemo2.main(ExceptionDemo2.java:11)
         */
    }
}

3.2 作为方法内部一种特殊的返回值

        异常可以作为方法内部的一种特殊返回值,以便通知调用者底层的执行情况。
        例如下面的代码,在同学类的setAge()方法中,当年龄小于18岁或超过40岁时,抛出运行时异常。

    public void setAge(int age) {
        if(age < 18 || age > 40){
            //年龄超出范围
            throw new RuntimeException();
        } else {
            this.age = age;
        }
    }

        在测试类中如果存入异常数据,会出现异常提醒。

package Exceptions;

public class ExceptionDemo3 {
    public static void main(String[] args) {
        //1.创建学生对象
        Student s1 = new Student();
        //年龄:(同学)18~40岁
        //返回异常获知赋值失败
        s1.setAge(50);

        /*
        Exception in thread "main" java.lang.RuntimeException
	at Exceptions.Student.setAge(Student.java:39)
	at Exceptions.ExceptionDemo3.main(ExceptionDemo3.java:9)
         */
    }
}

四、异常的处理方式

        在 Java 中有三种异常的处理方式:
① JVM 默认的处理方式。
② 自己处理。
③ 抛出异常(交给调用者处理)。

4.1 JVM 默认的处理方式

  • 虚拟机把异常的名称,异常原因及异常出现的位置等信息输出在控制台。
  • 程序停止执行。

4.2 自己处理(捕获异常)

格式:

try {
	可能出现异常的代码;
} catch(异常类名 变量名) {
	异常处理的代码;
}

例子:

package Exceptions;

public class ExceptionDemo4 {
    public static void main(String[] args) {

        int[] arr = {1, 2, 3, 4, 5, 6};

        try {
            System.out.println(arr[10]);
        } catch(ArrayIndexOutOfBoundsException e){
            System.out.println("索引越界了");
        }
        
        System.out.println("看看我执行了吗?");
    }
}

        如果 try{ } 中的语句出现了异常,就会创建一个异常对象,创建什么对象取决于异常的类型,上面代码的异常类型是 ArrayIndexOutOfBoundsException (数组索引越界异常),然后会把这个对象和 catch() 中的异常变量进行对比,看这个变量是否可以接收这种对象,如果异常种类相同就可以接收,表示该异常被捕获,然后执行 catch() { } 中的代码,当这些代码执行完毕,会继续执行 try…catch 体系之后的其他代码,并不会导致程序的中断。

4.3 如果 try 中没有遇到问题,怎么执行?

        如果 try 中没有遇到问题,会直接执行 try{ } 中的代码,而不会去执行 catch() { } 中的代码了,然后执行 try…catch 体系后面的代码。

package Exceptions;

public class ExceptionDemo5 {
    public static void main(String[] args) {

        int[] arr = {1, 2, 3, 4, 5, 6};

        try {
            System.out.println(arr[0]);
        } catch(ArrayIndexOutOfBoundsException e){
            System.out.println("索引越界了");
        }

        System.out.println("看看我执行了吗?");
    }
}

4.4 如果 try 中可能会遇到多个问题,怎么执行?

        如果 try{ } 中可能出现多种问题,那么我们就需要写多个 catch(){ } 与之对应。

package Exceptions;

public class ExceptionDemo6 {
    public static void main(String[] args) {
        /*
            细节:如果我们要捕获多个异常,这些异常中如果存在父子关系,那么父类一定要写在下面
         */

        int[] arr = {1, 2, 3, 4, 5, 6};

        try {
            System.out.println(arr[10]);        //ArrayIndexOutOfBoundsException
            System.out.println(2 / 0);            //ArithmeticException
            String s = null;
            System.out.println(s.equals("abc"));    //NullPointerException
        }catch(ArrayIndexOutOfBoundsException e){
            System.out.println("索引越界了");
        }catch(ArithmeticException e){
            System.out.println("除零错误");
        }catch(NullPointerException e){
            System.out.println("空指针异常");
        }catch(Exception e){
            System.out.println("存在异常");
        }

        //在 JDK7 以前,异常的一个捕获书写一个异常
        //如果有多个异常,处理方式是一样的,可以一起写,中间用 |
        try {
            System.out.println(2 / 0);
        }catch(ArrayIndexOutOfBoundsException | ArithmeticException e) {
            System.out.println("索引越界或除数为0");
        }
        
        System.out.println("看看我执行了吗?");
    }
}

4.5 如果 try 中碰到的问题没有被捕获?

        如果 try{ } 中的代码发生的异常没有被 catch() { } 捕获到(catch 中写的异常类型和你发生的异常类型不同,所以没捕获到),虚拟机会直接报错(相当于 catch(){ } 没捕获到异常,直接交给了虚拟机处理)。

package Exceptions;

public class ExceptionDemo7 {
    public static void main(String[] args) {

        int[] arr = {1, 2, 3, 4, 5, 6};

        try {
            System.out.println(arr[10]);
        } catch(NullPointerException e){
            System.out.println("索引越界了");
        }

        System.out.println("看看我执行了吗?");	//没执行

		/*
		Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 10 out of bounds for length 6
	at Exceptions.ExceptionDemo7.main(ExceptionDemo7.java:9)
	*/


    }
}

4.6 如果 try 中遇到了问题,那么 try 下面的其他代码还会执行吗?

        try{ } 中某一行代码遇到问题,它会直接跳转到 catch() { } 结构中,并不会继续执行此行代码之后的代码。

package Exceptions;

public class ExceptionDemo8 {
    public static void main(String[] args) {

        int[] arr = {1, 2, 3, 4, 5, 6};

        try{
            System.out.println(arr[10]);
            System.out.println("看看我执行了吗?... try");
        }catch(ArrayIndexOutOfBoundsException e){
            System.out.println("索引越界了");
        }

        System.out.println("看看我执行了吗?... 其他代码");
    }
}

五、Throwable 类

        Throwable 类是异常的最高层类,它有三个常用方法。

在这里插入图片描述
        三个方法的使用特征如下:

package Exceptions;

public class ExceptionDemo9 {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3, 4, 5, 6};

        try {
            System.out.println(arr[10]);
        } catch (ArrayIndexOutOfBoundsException e) {
            String message = e.getMessage();
            System.out.println(message);            //Index 10 out of bounds for length 6

            String str = e.toString();
            System.out.println(str);                //java.lang.ArrayIndexOutOfBoundsException: Index 10 out of bounds for length 6

            e.printStackTrace();                    //java.lang.ArrayIndexOutOfBoundsException: Index 10 out of bounds for length 6
                                                    //      at Exceptions.ExceptionDemo9.main(ExceptionDemo9.java:8)
            //printStackTrace方法会把异常信息以红色字体打印在虚拟机控制台
            //但是这样做不会结束代码的执行,后面的代码仍旧可以执行
        }

        System.out.println("看看我执行了吗");
    }
}

        printStackTrace() 方法所包含的信息已经包含了前两个方法的信息,我们在使用时一般都使用这个方法,且这个方法是 try…catch 结构的默认处理方法。
        这个方法在底层是利用 System.err.println() 方法进行输出,因此可以把字体转为红色打印在控制台。

六、抛出处理

        throws 和 throw 的区别:

  • throws:写在方法定义处,表示声明一个异常,告诉调用者,使用本方法可能会有哪些异常。
public void 方法() throws 异常类名1,异常类名2... {
	...
}

注意:如果异常是编译时异常,那就必须要写;如果是运行时异常,可以不写。

  • throw:写在方法内部,手动抛出异常对象,交给调用者,方法中下面的代码就不再执行了。
public void 方法(){
	throw new NullPointerException();
}

        异常抛出的用例:

package Exceptions;

public class ExceptionDemo10 {
    public static void main(String[] args) {
        /*
           调用方法求一个数组的最大值
         */
        int[] arr = null;
        try {
            int max = getMax(arr);
        } catch (NullPointerException e) {
            System.err.println("空指针异常");
        } catch (ArrayIndexOutOfBoundsException e) {
            System.err.println("索引越界异常");
        }


    }

    public static int getMax(int[] arr){
        if(arr == null) {
            throw new NullPointerException();       //手动创建一个异常对象,并把这个异常交给方法调用者处理
            //之后的代码就不会再执行
        }

        if(arr.length == 0) {
            throw new ArrayIndexOutOfBoundsException();
        }

        System.out.println("看看我执行了吗?");
        int max = arr[0];
        for (int i = 1; i < arr.length; i++) {
            if(arr[i] > max) {
                max = arr[i];
            }
        }
        return max;
    }
}

【练习】使用异常完成需求。
需求:
        键盘录入自己心仪的女朋友姓名和年龄。姓名的长度在3~10之间,
        年龄的范围为18– 40岁,
        超出这个范围是异常数据不能赋值,需要重新录入,一直录到正确为止。
提示:
        需要考虑用户在键盘录入时的所有情况。
        比如:录入年龄时超出范围,录入年龄时录入了abc等情况。

package Exceptions;

import java.util.Scanner;

public class ExceptionDemo11 {
    public static void main(String[] args) {

        /*
              姓名长度为 3-10
              年龄范围为 18-40
              否则不赋值,重新录入
              改写set方法
         */


        //1.键盘录入
        Scanner sc = new Scanner(System.in);

        //2.女朋友对象
        GirlFriend gf = new GirlFriend();


        while (true) {
            //3.接收女朋友的姓名

            try {
                System.out.println("请输入女朋友名字:");
                String name = sc.nextLine();
                gf.setName(name);

                //4.接收女朋友的年龄
                System.out.println("请输入女朋友的年龄:");
                String ageStr = sc.nextLine();
                int age = Integer.parseInt(ageStr);
                gf.setAge(age);

                //如果所有的输入数据都是正确的,跳出循环
                break;

            } catch (NumberFormatException e) {
                System.out.println("年龄的格式有误,请输入数字。");

            } catch (RuntimeException e) {                          //父类一定要写在下面
                System.out.println("姓名的长度或年龄的范围有误。");
            }

        }

        //5.打印
        System.out.println(gf.toString());
    }
}

        要注意,这里的抛出异常,需要自己设定,在 GirlFriend 类中写具体的抛出语句,因为 Java 不会知道你对姓名和年龄的特殊要求,这里的异常需要手动抛出。

    public void setName(String name) {
        int len = name.length();
        if(len < 3 || len > 10){
            throw new RuntimeException();
        }
        this.name = name;
    }
    public void setAge(int age) {
        if(age < 18 || age > 40){
            throw new RuntimeException();
        }
        this.age = age;
    }

七、自定义异常

        通过上面的例子我们意识到,Java 给我们准备的异常不能满足我们平时的需求,需要我们自定义想要的异常类型。定义一个异常类的目的,就是为了让控制台的报错信息更加见名知意。
        定义一个完整的异常类,我么要按照以下步骤:
① 定义异常类
② 写继承关系
③ 空参构造
④ 带参构造

        将上面的方法改为抛出自定义异常,可以分别告知“姓名”和“年龄”的异常,并且可以直接传递异常信息作为参数。
        先定义一个姓名格式异常,继承运行时异常。注意见名知意,然后带一个空参构造,一个有参构造,参数是错误信息。

package Exceptions;

public class NameFormatException extends RuntimeException {
    //NameFormat:当前异常名字,表示姓名格式化问题
    //Exception:当前类是一个异常类

    //运行时:继承RuntimeException
    //编译时:继承Exception


    public NameFormatException() {
    }

    public NameFormatException(String message) {
        super(message);
    }
}

        再定义一个年龄超范围异常。

package Exceptions;

public class AgeOutOfBoundsException extends RuntimeException{
    public AgeOutOfBoundsException() {
    }

    public AgeOutOfBoundsException(String message) {
        super(message);
    }
}

        改造 GirlFriend 类代码,抛出这两个异常,可以加提示信息作为参数。

    public void setName(String name) {
        int len = name.length();
        if(len < 3 || len > 10){
            throw new NameFormatException(name + "格式有误,长度应该为:3~10");
        }
        this.name = name;
    }
    public void setAge(int age) {
        if(age < 18 || age > 40){
            throw new AgeOutOfBoundsException(age + "年龄超出了范围");
        }
        this.age = age;
    }

        在测试类中捕获异常,可以分别捕获,分别处理,可用 printStackTrace() 方法直接打印异常信息。

package Exceptions;

import java.util.Scanner;

public class ExceptionDemo11 {
    public static void main(String[] args) {

        /*
              姓名长度为 3-10
              年龄范围为 18-40
              否则不赋值,重新录入
              改写set方法
         */


        //1.键盘录入
        Scanner sc = new Scanner(System.in);

        //2.女朋友对象
        GirlFriend gf = new GirlFriend();


        while (true) {
            //3.接收女朋友的姓名

            try {
                System.out.println("请输入女朋友名字:");
                String name = sc.nextLine();
                gf.setName(name);

                //4.接收女朋友的年龄
                System.out.println("请输入女朋友的年龄:");
                String ageStr = sc.nextLine();
                int age = Integer.parseInt(ageStr);
                gf.setAge(age);

                //如果所有的输入数据都是正确的,跳出循环
                break;

            } catch (NumberFormatException e) {
                System.out.println("年龄的格式有误,请输入数字。");

            } catch (NameFormatException e) {                          //父类一定要写在下面
                e.printStackTrace();

            } catch (AgeOutOfBoundsException e) {
                e.printStackTrace();
            }

        }

        //5.打印
        System.out.println(gf.toString());
    }
}

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

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

相关文章

WebDriver与Chrome DevTools Protocol:如何在浏览器自动化中提升效率

介绍 随着互联网数据的爆炸式增长&#xff0c;爬虫技术成为了获取信息的重要工具。在实际应用中&#xff0c;如何提升浏览器自动化的效率是开发者常常面临的挑战。Chrome DevTools Protocol&#xff08;CDP&#xff09;与Selenium WebDriver相结合&#xff0c;为浏览器自动化提…

vue中ES6的属性every使用@2@

every用于判断数组中的每一项是否均符合条件&#xff0c;并返回一个布尔值&#xff0c;都符合返回true&#xff0c;有一个不符合就返回false&#xff0c;并不再继续执行 //everyvar arr2 [1, 2, 3, 4, 5] let newArr2 arr2.every((num) > {return num < 3}) consol…

安卓13禁止声音调节对话框 删除音量调节对话框弹出 屏蔽音量对话框 android13

总纲 android13 rom 开发总纲说明 文章目录 1.前言2.问题分析3.代码分析3.1 方法13.2 方法24.代码修改4.1 代码修改方法14.2 代码修改方法25.编译6.彩蛋1.前言 客户需要,调整声音,不显示声音调节对话框了。我们在系统里面隐藏这个对话框。 2.问题分析 android在调整声音的…

Chainlit集成Mem0使用一个拥有个性化AI记忆的网页聊天应用

前言 Mem0 简介&#xff0c;可以看我上一篇文章《解决LLM的永久记忆的解决方案-Mem0实现个性化AI永久记忆功能》。本篇文章是对Mem0 实战使用的一个示例。通过Chainlit 快速实现ui界面和open ai的接入&#xff0c;通过使用Mem0 实现对聊天者的对话记录的记忆。 设计实现基本原…

网络空间信息安全实验

实验1 基础实验&#xff08;加密与隐藏&#xff09; 一、实验目的 提高对加密与解密原理的认识&#xff1b;提高对信息隐藏原理的认识&#xff1b;学会使用加密与隐藏软件。 二、实验环境 Pentiuum III、600 MHz以上CPU , 128M 以上内存&#xff0c;10G 以上硬盘&#xff0…

Hoverfly api/v2/simulation 任意文件读取漏洞复现(CVE-2024-45388)

0x01 产品简介 Hoverfly是一个为开发人员和测试人员提供的轻量级服务虚拟化/API模拟/API模拟工具。 0x02 漏洞概述 Hoverfly api/v2/simulation 接口存在任意文件读取漏洞,未经身份验证攻击者可通过该漏洞读取系统重要文件(如数据库配置文件、系统配置文件)、数据库配置文…

CSS学习13--学成网例子

CSS例子 学成网 需要使用的图片&#xff1a; 代码&#xff1a; <html><head><style>/*CSS初始化*/* { /*清除内外边框*/padding: 0;margin: 0;}ul {list-style: none; /*清除列表样式*/}.clearfix:before,.clearfix:after { /*清除浮动*/content: &qu…

今日早报 每日精选15条新闻简报 每天一分钟 知晓天下事 9月9日,星期一

每天一分钟&#xff0c;知晓天下事&#xff01; 2024年9月9日 星期一 农历八月初七 1、 三部门&#xff1a;拟允许在北京、天津、上海、广州、深圳、南京等地设立外商独资医院。 2、 巴黎残奥会结束&#xff1a;中国体育代表团获得94金76银50铜&#xff0c;连续六届残奥会位列…

C语言第二周课

目录 引言: 一、数据类型大小及分类 (1)计算机中常用存储单位 (2)整体介绍一下C语言的数据类型分类。 (3)下面是我们本节课要学的基本内容----常用的数据类型 二、 数据类型的数值范围 三、打印输出类型 数据类型打印示例: 引言: 我们常常在写C语言程序时&#xff0c;总…

用AI操作电脑:使用PyQt和Python结合AI生成代码的实用指南

​ 在github上有这样一个名字叫做open-interpreter的项目&#xff0c;收获了52k个Star。该项目通过自然语言来控制电脑&#xff0c;极大简化了使用电脑的难度&#xff0c;提高了工作效率。受该项目启发&#xff0c;我们可以做一个中文版桌面AI助手。 分步思考&#xff1a; 自…

算法工程师转行大模型:时代的选择or个人的选择

算法工程师的黄金时代&#xff1a;大模型转行之路 随着人工智能技术的飞速发展&#xff0c;尤其是深度学习领域的大规模预训练模型&#xff08;大模型&#xff09;的兴起&#xff0c;算法工程师们正面临前所未有的机遇与挑战。本文旨在探讨算法工程师如何顺利过渡到大模型领域…

基于Matlab的图像去雾系统(四种方法)关于图像去雾的基本算法代码的集合,方法包括局部直方图均衡法、全部直方图均衡法、暗通道先验法、Retinex增强。

基于Matlab的图像去雾系统&#xff08;四种方法&#xff09; 关于图像去雾的基本算法代码的集合&#xff0c;方法包括局部直方图均衡法、全部直方图均衡法、暗通道先验法、Retinex增强。 所有代码整合到App designer编写的GUI界面中&#xff0c;包括导入图片&#xff0c;保存处…

吴恩达发布企业AI转型手册,AI Transformation Playbook,对公司高管、正在创业的AIer是不错的指南。

AI 时代&#xff0c;人人都在创业。 今天看到一篇吴恩达发布的 AI 转型指南&#xff0c;原文《 AI Transformation Playbook——How to lead your company into the AI era》。 对公司高管、正在创业的 AIer 是个不错的指南。 这本人工智能转型手册借鉴了领导谷歌大脑团队和百…

浅谈OLTP 与 OLAP 数据建模的差异

OLTP 与 OLAP&#xff1a;常见工作流 联机分析处理 (OLAP) 和联机事务处理 (OLTP) 是两种主要的数据处理系统。两者之间存在多种差异。 OLTP 系统旨在处理来自多个用户的多个事务&#xff0c;它们通常用于许多应用程序的后端。例如&#xff0c;在线商务网站将使用 OLTP 系统来…

chapter13-常用类——(Arrays)——day16

目录 481-Arrays排序源码解读 483-Arrays模拟排序 484-Arrays其他方法 485-Arrays课堂练习 481-Arrays排序源码解读 接口编程-compare 483-Arrays模拟排序 484-Arrays其他方法 二分搜索查找要求有序&#xff0c;如果数组中不存在这个元素&#xff0c;返回-&#xff08;low1&…

Sentence-BERT实现文本匹配【CoSENT损失】

引言 还是基于Sentence-BERT架构&#xff0c;或者说Bi-Encoder架构&#xff0c;但是本文使用的是苏神提出的CoSENT损失函数1。 点击来都是缘分&#xff0c;之前过时的方法可以不细看&#xff0c;别的文章可以不收藏&#xff0c;现在是最流行的方法&#xff0c;这篇文章建议收藏…

ASIO网络调试助手之一:简介

多年前&#xff0c;写过几篇《Boost.Asio C网络编程》的学习文章&#xff0c;一直没机会实践。最近项目中用到了Asio&#xff0c;于是抽空写了个网络调试助手。 开发环境&#xff1a; Win10 Qt5.12.6 Asio(standalone) spdlog 支持协议&#xff1a; UDP TCP Client TCP Ser…

利用高德+ArcGIS优雅获取任何感兴趣的矢量边界

荷花十里&#xff0c;清风鉴水&#xff0c;明月天衣。 四时之景不同&#xff0c;乐亦无穷尽也。今天呢&#xff0c;梧桐君给大家讲解一下&#xff0c;如何利用高德地图&#xff0c;随机所欲的获取shp边界数据。 文章主要分成以下几个步骤&#xff1a; 首先搜索你想获取的矢量…

深度学习中常见的损失函数

关注B站可以观看更多实战教学视频&#xff1a;hallo128的个人空间 深度学习中常见的损失函数 损失函数的作用 损失函数是衡量神经网络输出与真实标签之间差距的指标。在训练过程中&#xff0c;神经网络的目标是最小化损失函数的值。常见的损失函数包括均方误差&#xff08;MS…

HCIA--实验十二:交换机TRUNK接口实验

两个交换机TRUNK接口实验 一、实验内容 1.需求/要求&#xff1a; 通过两台交换机和四台主机连通&#xff0c;划分两个VLAN&#xff0c;实现同VLAN间通信。理解access接口和trunk接口的区别&#xff0c;熟记access和trunk的配置命令。 二、实验过程 1.拓扑图&#xff1a; 2…