精华内容
下载资源
问答
  • 10分钟 举例子Python 单元测试实践 入门教程 作者:知乎 Ai酱 ​首发于:知乎专栏《适合初学者的机器学习神经网络理论到实践》,转载需注明出处 华南理工大学 计算机技术硕士在读 2 人赞同了该文章 为何要...

    10分钟 举例子Python 单元测试实践 入门教程

    作者:知乎 Ai酱

    首发于:知乎专栏《适合初学者的机器学习神经网络理论到实践》,转载需注明出处

    华南理工大学 计算机技术硕士在读

    2 人赞同了该文章

    为何要测试:设定预期结果让计算机判断结果是否符合预期。省得组件很多的时候一个一个的检测这些组件是否运行结果正确。

    - 如何比较运行时某变量大小或类型是否与预期值一致: assert(断言)

    assert的语法是这样(如果条件不成立则报错,成立则不报错):

    assert 条件语句

    或许你会问条件不成立报错了,然后呢?。Good Question。

    :这个条件语句是用来判断结果是否在我们预期范围呢。条件不成立证明运行的结果是错误的。大家一般非常讨厌报错,但是它报错了有什么好处呢?报错信息会提示哪句报错了在哪行。这就节省了我们找错误在哪的时间。

    assert例子:

    定义一个最简单的assert测试代码

    x = 1
    assert x < 0

    输出,提示第二行报错,我们预期x是负数但是程序运行结果的x是非负所以报错。这提示我们看看产生x的那段代码是否有问题:

    Traceback (most recent call last):
      File "<ipython-input-4-8363583f3b92>", line 2, in <module>
        assert x < 0
    AssertionError

    assert练习:

    问题描述:小明写了个函数求一个数组的平均数给别人调用。但是不确定别人传进来是否是一个数组,如果不是数组就得报错提示用户。(平常我们用别人写的包报错提示类型不正确就是这么做的)。
    参考代码:
    def mean(num_list):
        '''
        求平均数
        num_list: 数字组成的列表
        '''
        assert isinstance(num_list,list) # 检查传进来的参数是列表,不是就报错
        return sum(num_list)/len(num_list)
    
    # mean(1) #传递错误类型参数进去会报错,你取消注释看看会怎么报错
    mean([1,2,3]) # 参数类型正确,不报错

    你可以调用这个函数看看如果传递进去不是数组而是一个数看会怎么报错。多主动试错才能看到报错信息知道怎么改。

    - Python单元测试实践

    我们写了一个求平均数的函数mean(),那怎么验证它是否正确呢?这就是单元测试。每次只测试一个函数是否正确。而不是测试整个包运行是否正确。就像测试手机,我首先测试电源能不能导电而不是开机运行测试整机。

    这样一个单元一个单元的测试好处是能保证各个单元基本正确,而且可以预先发现哪个单元出现了bug。

    怎么写单元测试用例呢?

    一个函数就是一个测试用例,这个函数名需要以test_开头 ,因为pytest会自动一次性批量执行前缀名是"test_"的函数。

    # -*- coding: utf-8 -*-
    def mean(num_list):
        '''
        求平均数
        num_list: 数字组成的列表
        '''
        assert isinstance(num_list,list) # 检查传进来的参数是列表,不是就报错
        return sum(num_list)/len(num_list)
    
    ##########下面是单元测试用例,测试求平均数这个函数是否正确##############
    def test_mean_ints():
        """测试求预期结果是整数情况下是否正确"""
        num_list = [1,2,3,4,5]
        result = mean(num_list)
        desire = 3
        assert result == desire
        
    def test_mean_floats():
        """
        测试求预期结果是浮点数情况下是否正确
        小提示:这个在Python2下测试是不通过,Python2输出结果是2, Python3下结果是2.5
        """
        num_list = [1,2,3,4]
        result = mean(num_list)
        desire = 2.5
        assert result == desire
    
    def test_mean_zero():
        """测试含有0的数组求平均数是否正确"""
        num_list = [0,3,4,5]
        result = mean(num_list)
        desire = 3
        assert result == desire
    
    


    运行测试

    pytest -v 文件名.py
    pytest原理:pytest会自动执行前缀名是"test_"的函数
    下面是运行的结果,你可以修改下代码看测试失败的情况。

    - 如何测试近似相等,非常接近我们就认为是相等(需要用到numpy)

    在写什么网络的时候输出总是接近标签但是不等于标签,此时用assert就不行了。

    比如: 我们的标签是1而神经网络的输出总是0.999999999. "assert 0.99999999 == 1",这个肯定会不成立。但是事实它已经是符合预期了。此时,我们只需要判断它是否接近预期值就可以。

    近似相等测试例子:

    from numpy.testing import assert_allclose
    # rtol设置的是精度,比如1e-4那就是只要两者相差在0.0001内就认为测试通过
    assert_allclose(0.999999,1,rtol=1e-4)

    如果对你有启发,欢迎给 

    @Ai酱

     点赞或关注,你的支持是创作动力

    适合初学者的神经网络理论到实践(1):单个神经元+随机梯度下降学习逻辑与规则

    Ai酱:概率统计与机器学习神经网络的联系?

    计算机生态圈是怎么样的?

    有哪些事实没有一定计算机知识的人不会相信?

    适合初学者的机器学习神经网络理论到实践

    转载于:https://www.cnblogs.com/ailitao/p/11047298.html

    展开全文
  • ...贪心策略:2种方式:1)先取顺子,再取对子:具体操作起来是取顺子需要判断是否能取(即如果取对子拆散两个或三个对子时则不能取),而这个操作由于需要考虑后面的数,这就导致需要考虑的更...

    http://acm.hdu.edu.cn/showproblem.php?pid=6188

    输入一个n,接下来有n个数,让你求出能组成最多的对子或者顺子的和。 对子: (2,2),顺子: (1,2,3)。

    贪心策略:2种方式:1)先取顺子,再取对子:具体操作起来是取顺子需要判断是否能取(即如果取对子拆散两个或三个对子时则不能取),而这个操作由于需要考虑后面的数,这就导致需要考虑的更多了,首先组成顺子的三个数的个数必须有至少两个奇数,刚开始以为三个数随便两个是奇数就行,结果wa了一发,写了两个例子之后发现必须是前两个是奇数,后面,,改过之后顺利AC

    对于某些贪心问题举例子强行凑出规律(我在说什么啊,,)2)先取对子,再取顺子,刚刚那个是取当前的和后面两张,这种是取当前和之前的两张,所以这个需要考虑很少(因为前面的没什么需要考虑啊,能凑顺子就凑,毕竟前面的已经不能凑成对子了,不像上一种,后面的数具有更多可能性)

    以下是第一种的代码

     

    转载于:https://www.cnblogs.com/MekakuCityActor/p/8672853.html

    展开全文
  • 怎么判断作文有没有给出题目呢?一般题目说明里用了entitled这个词,后面的短语就是题目。小编以2012年的六级作文真题为例:Directions:For this part, you are allowed 30 minutes to write a short essayentitled...

    8866793bb4aa78bcc05d61e21a719da4.png

    一、四六级作文要写题目吗?

    分两种情况。

    1. 要求写题目的, 照抄一遍即可。

    怎么判断作文有没有给出题目呢?一般题目说明里用了entitled这个词,后面的短语就是题目。

    小编以2012年的六级作文真题为例:

    Directions:For this part, you are allowed 30 minutes to write a short essayentitled Man andComputer by commenting on the saying, "The real danger is not that the computer will begin to think like man, but that man will begin to think like the computer."

    You should write at least 150 words but no more than 200 words.

    像上面这种,要求以Man and Computer为题目,照抄一遍即可。

    不过,这种情况多出现在2012以前的四六级考卷上,且题目多已经印刷在试卷上了。写之前看清楚题目哦~

    提醒各位:作文题目要求里让大家阐述讨论的话题,并不是作文题目。

    以2017年6月的六级作文题目为例:

    Suppose you are asked to give advice on whether to attend college at home or abroad, write an essay to state your opinion. You are required to write at least 150 words but no more than 200 words.

    上文加粗部分是要你在作文里展开讨论的内容,而不是题目,不要弄错哦~

    2. 没有给出题目的,就不要写了。

    多一事不如少一事,且有的同学看到题目说明里有不认识的词,紧张抄错还会扣分,就不要写了。

    二、怎样才能防止作文跑题?

    作文出现跑题,一般有以下3个原因:

    第一,平时复习单词没背好,作文题目要求里出现了不认识的单词或短语,导致写作时离题万里。

    比如,2012年12月四级作文题目:

    Directions: For this part, you are allowed 30 minutes to write a short essay entitled Education Pays based on the statistics provided in the chart below(Weekly earnings in 2010).

    很多同学拿到题目,懵了,按照字面意思理解为“教育支出,教育花费”,而实际上题目是指“教育可以获利”。

    当时的题目下面还有一张图,对比了不同教育水平的人收入和失业率。依然没能唤醒广大考生。

    再比如2017年6月考过的六级 whether to major in humanities or science,学文科还是理科,也有很多同学反映看不懂题目,考场上不知道自己都扯了啥。

    对策:考前疯狂背单词,考场上根据上下文推断。

    第二,单词认识,但是对所考话题不熟不了解,提笔无话可说。

    2016年6月的六级作文考到了机器人(to write a short essay on the use of robots),虚拟世界(to write a short essay on living in the virtual world)。

    平时对这些话题不了解的话,写起来估计很吃力。

    对策:四六级作文多涉及当代热点话题,考前多看多积累不同话题的作文素材。多看微信公众号,平时主动思考。

    第三,话题和单词都熟悉,但抓不住写作重点,导致写跑题。

    这种情况最不应该。但偏偏,有相当一部分同学跑题都是这个原因。

    四六级作文虽然近年来不再出现提纲式作文,但题目要求里也写清楚了:要从什么方面展开、文章应该包括什么内容。

    跑题的原因无非是平时练得少,写起来要么抓着一个点讲的太多,导致该讲的点没有讲到,而跑题。

    对策:建议大家考前做定时训练。

    动笔写之前,仔细审题,先列提纲。尽量三段式展开。

    四级作文120~180字,六级150-200字,大概在10~15句左右。

    列提纲的时候,结合字数给自己定一下每段的长度和功能,以四级作文为例:

    首段:描述现象/论点(3句)

    中间段:分析原因/论据(4句)

    末尾段:提出建议/总结(3句)

    大概这样↑ 以上是小编举的例子,考试时大家按题目的要求,具体分析。

    提醒:作文不要写的太长,最好按照要求把这10~15句话均匀分布到每一段里。

    写的越多,越容易出错。谋篇布局,每一句话发挥应有的作用,方为上策。

    三、考察观点的写作题要怎么写?觉得引入观点太难了。

    常规导入:背景引入话题,给出作者态度。

    比如:全球化的进程引发了人们热烈的讨论:我们到底应该教孩子合作还是教孩子竞争。我认为…

    矫情导入:问句导入,给出个人观点。

    比如:竞争是否真的比合作重要?我对此深表怀疑。

    装逼导入:名人名言改写,给出个人观点。

    教孩子合作还是教孩子竞争?这是个问题!我认为…

    四、写作和翻译需要使用高大上的词汇吗?

    要达到425分,写作和翻译至少要在8分档。

    8分档具体要求如下:

    写作(基本切题,语言错误相当多,甚至有一部分是严重错误)

    翻译(译文勉强表达原文意思,语言错误相当多,甚至有一部分是严重错误)

    11分档的具体要求:

    写作(切题。表达思想清楚,文字连贯,但有少量语言错误)

    翻译(译文基本表达了原文的意思。结构较清晰,语言通顺,但有少量语言错误)

    也就是说,只要正确地表达了意思,结构清晰,写作和翻译就能拿高分了。

    没学会走之前,别想着跑啦~ 先把意思表达对就行。

    推荐阅读:四六级考到425/500/600分,要做对多少道题?

    五、翻译遇到不会的怎么办?

    四六级翻译可以通过考试技巧降低难度:

    1. 中文句子过长,逗号很多,一句话中内容太多,可以采用断句的方式降低难度。

    例如:在中国,父母总是竭力帮助孩子,甚至为孩子做重要决定,而不管孩子想要什么,因为他们相信这样做是为孩子好。

    经过断句之后就可以处理成:

    ① 在中国,父母总是竭力帮助孩子,

    ② 甚至为孩子做重要决定,

    ③ 而不管孩子想要什么,

    ④ 因为他们相信这样做是为孩子好。

    每一个句子都变短,独立一句一句翻译,翻译起来比较好处理。

    2. 遇到不会翻译的中文词语,可以灵活应用自己已经掌握的词汇来翻译。

    例如:消除贫困eliminate poverty中eliminate不会翻译,可以用end代替,end poverty也是消除贫困的意思。

    六、最后几天,作文和翻译都背什么?

    写作:学渣请背四六级作文必背词,学霸可以背高分替换词。

    模板句的话,注意被背诵表示开头、结尾、转折总结等功能的句子。

    120组高分同义替换词,翻译写作都用得上!

    七、小编,考官喜欢什么样的字呀~

    一个人的字写了这么多年,很难改啦。现在练字也来不及了。

    考场上,字迹工整,清晰整洁就行。一定不要涂改太多。会显得很乱。

    提醒:作文和翻译如果来不及,可以直接写在答题纸上,有写错的直接划掉就行。阅卷老师接受这种程度的修改,但不要涂得太乱,看不清楚的话就危险了。

    要知道阅卷老师工作量很大的,尽量涂得干净一些。比如把错误的划掉,另起一行再写。这样也方便老师改卷时找到采分点,给你分数!

    干净整洁的文章,会给考官留下好的印象。

    文字对齐方式的话,有齐头式和缩进式两种,供大家参考:

    齐头式:所有文字顶格,段与段之间空一行,千万别写成一大片。

    缩进式:首行缩进四个字母,首行缩进四个字母,首行缩进四个字母,自己掌握距离,这是标准格式。

    展开全文
  • 作者:duanxzcnblogs.com/duanxz/p/3511695.htmlserialVersionUID适用于Java的序列化机制。简单来说,Java的序列化机制是通过判断类的...

    作者duanxz

    cnblogs.com/duanxz/p/3511695.html

    serialVersionUID适用于Java的序列化机制。简单来说,Java的序列化机制是通过判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体类的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常,即是InvalidCastException。

    具体的序列化过程是这样的:序列化操作的时候系统会把当前类的serialVersionUID写入到序列化文件中,当反序列化时系统会去检测文件中的serialVersionUID,判断它是否与当前类的serialVersionUID一致,如果一致就说明序列化类的版本与当前类版本是一样的,可以反序列化成功,否则失败。

    serialVersionUID有两种显示的生成方式:

    • 默认的1L,比如:private static final long serialVersionUID = 1L;

    • 根据类名、接口名、成员方法及属性等来生成一个64位的哈希字段,比如:
      private static final  long   serialVersionUID = xxxxL;

    当一个类实现了Serializable接口,如果没有显示的定义serialVersionUID,Eclipse会提供相应的提醒。面对这种情况,我们只需要在Eclipse中点击类中warning图标一下,Eclipse就会自动给定两种生成的方式。

    如果不想定义,在Eclipse的设置中也可以把它关掉的,设置如下:Window ==> Preferences ==> Java ==> Compiler ==> Error/Warnings ==> Potential programming problems 将Serializable class without serialVersionUID的warning改成ignore即可。

    当实现java.io.Serializable接口的类没有显式地定义一个serialVersionUID变量时候,Java序列化机制会根据编译的Class自动生成一个serialVersionUID作序列化版本比较用,这种情况下,如果Class文件(类名,方法明等)没有发生变化(增加空格,换行,增加注释等等),就算再编译多次,serialVersionUID也不会变化的。

    如果我们不希望通过编译来强制划分软件版本,即实现序列化接口的实体能够兼容先前版本,就需要显式地定义一个名为serialVersionUID,类型为long的变量,不修改这个变量值的序列化实体都可以相互进行串行化和反串行化。

    下面用代码说明一下serialVersionUID在应用中常见的几种情况。

    (1)序列化实体类

    package com.sf.code.serial;
    
    import java.io.Serializable;
    
    public class Person implements Serializable {
        private static final long serialVersionUID = 123456789L;
        public int id;
        public String name;
    
        public Person(int id, String name) {
            this.id = id;
            this.name = name;
        }
    
        public String toString() {
            return "Person: " + id + " " + name;
        }
    }
    

    (2)序列化功能:

    package com.sf.code.serial;
    
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.ObjectOutputStream;
    
    public class SerialTest {
    
        public static void main(String[] args) throws IOException {
            Person person = new Person(1234, "wang");
            System.out.println("Person Serial" + person);
            FileOutputStream fos = new FileOutputStream("Person.txt");
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(person);
            oos.flush();
            oos.close();
        }
    }
    

    (3)反序列化功能:

    package com.sf.code.serial;
    
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    
    public class DeserialTest {
        public static void main(String[] args) throws IOException, ClassNotFoundException {
            Person person;
    
            FileInputStream fis = new FileInputStream("Person.txt");
            ObjectInputStream ois = new ObjectInputStream(fis);
            person = (Person) ois.readObject();
            ois.close();
            System.out.println("Person Deserial" + person);
        }
    
    }
    

    情况一:假设Person类序列化之后,从A端传输到B端,然后在B端进行反序列化。在序列化Person和反序列化Person的时候,A端和B端都需要存在一个相同的类。如果两处的serialVersionUID不一致,会产生什么错误呢?

    【答案】可以利用上面的代码做个试验来验证:

    先执行测试类SerialTest,生成序列化文件,代表A端序列化后的文件,然后修改serialVersion值,再执行测试类DeserialTest,代表B端使用不同serialVersion的类去反序列化,结果报错:

    Exception in thread "main" java.io.InvalidClassException: com.sf.code.serial.Person; local class incompatible: stream classdesc serialVersionUID = 1234567890, local class serialVersionUID = 123456789
        at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:621)
        at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1623)
        at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1518)
        at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1774)
        at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1351)
        at java.io.ObjectInputStream.readObject(ObjectInputStream.java:371)
        at com.sf.code.serial.DeserialTest.main(DeserialTest.java:13)
    

    情况二:假设两处serialVersionUID一致,如果A端增加一个字段,然后序列化,而B端不变,然后反序列化,会是什么情况呢?

    package com.sf.code.serial;
    
    import java.io.Serializable;
    
    public class Person implements Serializable {
        private static final long serialVersionUID = 1234567890L;
        public int id;
        public String name;
        public int age;
    
        public Person(int id, String name) {
            this.id = id;
            this.name = name;
        }
        
        public Person(int id, String name, int age) {
            this.id = id;
            this.name = name;
            this.age = age;
        }
    
        public String toString() {
            return "Person: " + id 
                    + ",name:" + name 
                    + ",age:" + age;
        }
    }
    
    public class SerialTest {
    
        public static void main(String[] args) throws IOException {
            Person person = new Person(1234, "wang", 100);
            System.out.println("Person Serial" + person);
            FileOutputStream fos = new FileOutputStream("Person.txt");
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(person);
            oos.flush();
            oos.close();
        }
    }
    

    Person DeserialPerson: 1234,name:wang

    【答案】新增 public int age; 执行SerialTest,生成序列化文件,代表A端。删除 public int age,反序列化,代表B端,最后的结果为:执行序列化,反序列化正常,但是A端增加的字段丢失(被B端忽略)。

    情况三:假设两处serialVersionUID一致,如果B端减少一个字段,A端不变,会是什么情况呢?

    package com.sf.code.serial;
    
    import java.io.Serializable;
    
    public class Person implements Serializable {
        private static final long serialVersionUID = 1234567890L;
        public int id;
        //public String name;
        
        public int age;
    
        public Person(int id, String name) {
            this.id = id;
            //this.name = name;
        }
    
        public String toString() {
            return "Person: " + id 
                    //+ ",name:" + name 
                    + ",age:" + age;
        }
    }
    

    Person DeserialPerson: 1234,age:0

    【答案】序列化,反序列化正常,B端字段少于A端,A端多的字段值丢失(被B端忽略)。

    情况四:假设两处serialVersionUID一致,如果B端增加一个字段,A端不变,会是什么情况呢?

    验证过程如下:

    先执行SerialTest,然后在实体类Person增加一个字段age,如下所示,再执行测试类DeserialTest.

    package com.sf.code.serial;
    
    import java.io.Serializable;
    
    public class Person implements Serializable {
        private static final long serialVersionUID = 1234567890L;
        public int id;
        public String name;
        public int age;
    
        public Person(int id, String name) {
            this.id = id;
            this.name = name;
        }
        
        /*public Person(int id, String name, int age) {
            this.id = id;
            this.name = name;
            this.age = age;
        }*/
    
        public String toString() {
            return "Person: " + id 
                    + ",name:" + name 
                    + ",age:" + age;
        }
    }
    

    结果:Person DeserialPerson: 1234,name:wang,age:0

    说明序列化,反序列化正常,B端新增加的int字段被赋予了默认值0。

    最后通过下面的图片,总结一下上面的几种情况。

    静态变量序列化

    情境:查看清单 2 的代码。

    清单 2. 静态变量序列化问题代码

    public class Test implements Serializable {
    
     private static final long serialVersionUID = 1L;
    
     public static int staticVar = 5;
    
     public static void main(String[] args) {
      try {
       //初始时staticVar为5
       ObjectOutputStream out = new ObjectOutputStream(
         new FileOutputStream("result.obj"));
       out.writeObject(new Test());
       out.close();
    
       //序列化后修改为10
       Test.staticVar = 10;
    
       ObjectInputStream oin = new ObjectInputStream(new FileInputStream(
         "result.obj"));
       Test t = (Test) oin.readObject();
       oin.close();
       
       //再读取,通过t.staticVar打印新的值
       System.out.println(t.staticVar);
       
      } catch (FileNotFoundException e) {
       e.printStackTrace();
      } catch (IOException e) {
       e.printStackTrace();
      } catch (ClassNotFoundException e) {
       e.printStackTrace();
      }
     }
    }
    

    清单 2 中的 main 方法,将对象序列化后,修改静态变量的数值,再将序列化对象读取出来,然后通过读取出来的对象获得静态变量的数值并打印出来。依照清单 2,这个 System.out.println(t.staticVar) 语句输出的是 10 还是 5 呢?

    最后的输出是 10,对于无法理解的读者认为,打印的 staticVar 是从读取的对象里获得的,应该是保存时的状态才对。之所以打印 10 的原因在于序列化时,并不保存静态变量,这其实比较容易理解,序列化保存的是对象的状态,静态变量属于类的状态,因此 序列化并不保存静态变量。

    父类的序列化与 Transient 关键字

    情境:一个子类实现了 Serializable 接口,它的父类都没有实现 Serializable 接口,序列化该子类对象,然后反序列化后输出父类定义的某变量的数值,该变量数值与序列化时的数值不同。

    解决:要想将父类对象也序列化,就需要让父类也实现Serializable 接口。如果父类不实现的话的,就 需要有默认的无参的构造函数。在父类没有实现 Serializable 接口时,虚拟机是不会序列化父对象的,而一个 Java 对象的构造必须先有父对象,才有子对象,反序列化也不例外。

    所以反序列化时,为了构造父对象,只能调用父类的无参构造函数作为默认的父对象。因此当我们取父对象的变量值时,它的值是调用父类无参构造函数后的值。如果你考虑到这种序列化的情况,在父类无参构造函数中对变量进行初始化,否则的话,父类变量值都是默认声明的值,如 int 型的默认是 0,string 型的默认是 null。

    Transient 关键字的作用是控制变量的序列化,在变量声明前加上该关键字,可以阻止该变量被序列化到文件中,在被反序列化后,transient 变量的值被设为初始值,如 int 型的是 0,对象型的是 null。

    特性使用案例

    我们熟悉使用 Transient 关键字可以使得字段不被序列化,那么还有别的方法吗?根据父类对象序列化的规则,我们可以将不需要被序列化的字段抽取出来放到父类中,子类实现 Serializable 接口,父类不实现,根据父类序列化规则,父类的字段数据将不被序列化,形成类图如图 2 所示。

    图 2. 案例程序类图

    上图中可以看出,attr1、attr2、attr3、attr5 都不会被序列化,放在父类中的好处在于当有另外一个 Child 类时,attr1、attr2、attr3 依然不会被序列化,不用重复抒写 transient,代码简洁。

    static final 修饰的serialVersionUID如何被写入到序列化文件中的,看下面的源码:

    序列化写入时的ObjectStreamClass.java中

    void writeNonProxy(ObjectOutputStream out) throws IOException {
            out.writeUTF(name);
            out.writeLong(getSerialVersionUID());
    
            byte flags = 0;
            ...
    
    public long getSerialVersionUID() {
            // REMIND: synchronize instead of relying on volatile?
            if (suid == null) {
                suid = AccessController.doPrivileged(
                    new PrivilegedAction<Long>() {
                        public Long run() {
                            return computeDefaultSUID(cl);
                        }
                    }
                );
            }
            return suid.longValue();
        }
    

    END

    推荐好文

    强大,10k+点赞的 SpringBoot 后台管理系统竟然出了详细教程!
    
    分享一套基于SpringBoot和Vue的企业级中后台开源项目,代码很规范!
    能挣钱的,开源 SpringBoot 商城系统,功能超全,超漂亮!
    
    
    
    
    展开全文
  • 简单来说,Java的序列化机制是通过判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体类的serialVersionUID进行比较,如果相同就认为是一致的...
  • 简单来说,Java的序列化机制是通过判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体类的serialVersionUID进行比较,如果相同就认为是一致的...
  • 简单来说,Java的序列化机制是通过判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体类的serialVersionUID进行比较,如果相同...
  • 关于 form onsubmit ...这里一个小例子: &lt;form action="userlogin" method="post" onsubmit="return check()" name="myForm"&gt; &lt;inpu...
  • 简单来说,Java的序列化机制是通过判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体类的serialVersionUID进行比较,如果相同就认为是一致的...
  • #include #include #define N 100 int main() { char a[N]; char b[N]; int len; int j = 0;  scanf("%s",&a); len = strlen(a); for(int i=0;i { if(a[i]>='a'&&a[i]='A'&&a[i]='0'&&a[i] ...b[j]
  • 简单来说,Java的序列化机制是通过判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体类的serialVersionUID进行比较,如果相同就认为是一致的...
  • 简单来说,Java的序列化机制是通过判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体类的serialVersionUID进行比较,如果相同就认为是一致的...
  • 简单来说,Java的序列化机制是通过判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体类的serialVersionUID进行比较,如果相同就认为是一致的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,024
精华内容 1,209
关键字:

判断举例子