精华内容
下载资源
问答
  • win10 null.sys文件

    2018-03-26 18:19:19
    win10安装git报错 fatal:open /dev/null or dup failed: No such file or directory错误,将该文件复制到C:\Windows\System32\drivers下并覆盖即可
  • MySQL 中NULL和空值的区别?

    万次阅读 多人点赞 2019-07-03 12:04:57
    作为后台开发,在日常工作中如果要接触Mysql数据库,那么不可避免会遇到Mysql中的NULL和空值。那你知道它们有什么区别吗? 学不动了,也不想知道它们有什么区别。大兄弟,不行啊,要面试! 前些天我的好朋友小木...

    做一个积极的人

    编码、改bug、提升自己

    我有一个乐园,面向编程,春暖花开!

    在这里插入图片描述

    01 小木的故事

    作为后台开发,在日常工作中如果要接触Mysql数据库,那么不可避免会遇到Mysql中的NULL和空值。那你知道它们有什么区别吗?

    学不动了,也不想知道它们有什么区别。大兄弟,不行啊,要面试!

    前些天我的好朋友小木去应聘工作,他面试完回来和我聊天回味了一道他的面试题。


    面试官:你有用过MySQL吗?

    小木:有!

    面试官:那你能大概说一下Mysql中 NULL值和空值的区别吗?

    小木:(思考…)NULL和空值都用过,你要我说它两有啥区别,这个我还真没仔细想过,反正实际开发中会用!

    听了小木的这个回答。

    我说:你这样回答肯定是不妥的,这个问题你是必挂了。

    小木说: NULL翻译过来不就是空吗?我是真的没有仔细想过,这个还是挺迷惑人的。


    为了其他的伙伴在遇到这个问题的时候不要像我的好友小木一样在此处跌倒,错过心仪的公司,下面简单整理聊聊这两者的一些区别和使用。

    02 NULL和空值

    NULL也就是在字段中存储NULL值,空值也就是字段中存储空字符(’’)。

    1、占用空间区别

    mysql>  select length(NULL), length(''), length('1');
    +--------------+------------+-------------+
    | length(NULL) | length('') | length('1') |
    +--------------+------------+-------------+
    | NULL         |          0 |           1 |
    +--------------+------------+-------------+
    1 row in set
    

    小总结:从上面看出空值(’’)的长度是0,是不占用空间的;而的NULL长度是NULL,其实它是占用空间的,看下面说明。

    NULL columns require additional space in the row to record whether their values are NULL.

    NULL列需要行中的额外空间来记录它们的值是否为NULL。

    通俗的讲:空值就像是一个真空转态杯子,什么都没有,而NULL值就是一个装满空气的杯子,虽然看起来都是一样的,但是有着本质的区别。

    2、插入/查询方式区别

    创建一个表,tb_test

    CREATE TABLE `tb_test` (
      `one` varchar(10) NOT NULL,
      `two` varchar(255) DEFAULT NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    

    插入进行验证:

    -- 全部插入 NULL,失败
    mysql> INSERT tb_test VALUES (NULL,NULL);
    1048 - Column 'one' cannot be null
    
    -- 全部插入 空值,成功
    mysql> INSERT tb_test VALUES ('','');
    Query OK, 1 row affected
    

    模拟数据:

    INSERT tb_test VALUES (1,NULL);
    INSERT tb_test VALUES ('',2);
    INSERT tb_test VALUES (3,3);
    

    空值字段:

    -- 使用 is null/is not null
    mysql> SELECT * FROM tb_test where one is NULL;
    Empty set
    
    mysql> SELECT * FROM tb_test where one is not NULL;
    +-----+------+
    | one | two  |
    +-----+------+
    | 1   | NULL |
    |     | 2    |
    | 3   | 3    |
    +-----+------+
    3 rows in set
    -- 使用 = 、!=
    mysql> SELECT * FROM tb_test where one = '';
    +-----+-----+
    | one | two |
    +-----+-----+
    |     | 2   |
    +-----+-----+
    1 row in set
    
    mysql> SELECT * FROM tb_test where one != '';
    +-----+------+
    | one | two  |
    +-----+------+
    | 1   | NULL |
    | 3   | 3    |
    +-----+------+
    2 rows in set
    
    

    NULL值字段:

    -- 使用 is null/is not null
    mysql> SELECT * FROM tb_test where two is not NULL;
    +-----+-----+
    | one | two |
    +-----+-----+
    |     | 2   |
    | 3   | 3   |
    +-----+-----+
    2 rows in set
    
    mysql> SELECT * FROM tb_test where two is NULL;
    +-----+------+
    | one | two  |
    +-----+------+
    | 1   | NULL |
    +-----+------+
    1 row in set
    
    -- 使用 = 、!=
    mysql> SELECT * FROM tb_test where two = '';
    Empty set
    
    mysql> SELECT * FROM tb_test where two != '';
    +-----+-----+
    | one | two |
    +-----+-----+
    |     | 2   |
    | 3   | 3   |
    +-----+-----+
    2 rows in set
    

    小总结:如果要单纯查NULL值列,则使用 is NULL去查,单纯去查空值(’’)列,则使用 =''

    建议查询方式:NULL值查询使用is null/is not null查询,而空值(’’)可以使用=或者!=、<、>等算术运算符。

    3、COUNT 和 IFNULL函数

    使用COUNT函数:

    mysql> SELECT count(one) FROM tb_test;
    +------------+
    | count(one) |
    +------------+
    |          3 |
    +------------+
    1 row in set
    
    mysql> SELECT count(two) FROM tb_test;
    +------------+
    | count(two) |
    +------------+
    |          2 |
    +------------+
    1 row in set
    
    mysql> SELECT count(*) FROM tb_test;
    +----------+
    | count(*) |
    +----------+
    |        3 |
    +----------+
    1 row in set
    

    使用IFNULL函数:

    mysql> SELECT IFNULL(one,111111111) from tb_test WHERE one = '';
    +-----------------------+
    | IFNULL(one,111111111) |
    +-----------------------+
    |                       |
    +-----------------------+
    1 row in set
    
    mysql> SELECT IFNULL(two,11111111) from tb_test where two is NULL;
    +----------------------+
    | IFNULL(two,11111111) |
    +----------------------+
    | 11111111             |
    +----------------------+
    1 row in set
    

    小总结:使用 COUNT(字段) 统计会过滤掉 NULL 值,但是不会过滤掉空值。

    说明:IFNULL有两个参数。 如果第一个参数字段不是NULL,则返回第一个字段的值。 否则,IFNULL函数返回第二个参数的值(默认值)。

    4、索引字段说明

    看到网上有一些人说: MySql中如果某一列中含有NULL,那么包含该列的索引就无效了。

    onetwo 字段分别加上普通索引。之前有写过,在复习添加索引:Mysql索引整理总结

    -- ALTER TABLE table_name ADD INDEX index_name(col_name);
    ALTER TABLE tb_test ADD INDEX index_oat (one, two);
    ALTER TABLE tb_test add INDEX index_two(two);
    

    使用 show keys from 表名;show indexes from 表名; ,查看这个表的所有索引信息。

    一个普通索引,一个复合索引。

    复合索引遵守“最左前缀”原则即在查询条件中使用了复合索引的第一个字段,索引才会被使用。因此,在复合索引中索引列的顺序至关重要。

    可以看到,创建了两个索引,并且index_tow NULL 那一列是 YES。

    使用EXPLAIN 来进行演示说明,EXPLAIN 的使用说明:Mysql中explain用法和结果字段的含义介绍

    复合索引

    普通索引

    发现查询two字段 是可以正常使用索引的。我使用的MYSQL 5.7 ,InnoDB 引擎。也看了一些网上的资料,MySQL中NULL对索引的影响 这个文章中用例子验证,MySQL可以在含有null的列上使用索引

    备注:可能是其他条件下不行,看网上资料说使用空间索引会失效,具体我没有去验证,空间索引没有用到过。查询官网create-index-spatial,感兴趣的伙伴可以自行验证。

    这里我想到一点,很多问题的答案都是在指定的条件和环境下才成立,多质疑,多验证。

    小总结 :在有NULL值得字段上使用常用的索引,如普通索引、复合索引、全文索引等不会使索引失效。在官网查看在空间索引的情况下,说明了 索引列必须为NOT NULL。

    03 总结提升

    如果你可以从上面的几个方面和面试官进行一个沟通,即使回答的不是那么的完美,但总比 “这两个都用过,具体有啥区别就不知道了” 这样的回答能好那么一点点。

    1、空值不占空间,NULL值占空间。当字段不为NULL时,也可以插入空值。

    2、当使用 IS NOT NULL 或者 IS NULL 时,只能查出字段中没有不为NULL的或者为 NULL 的,不能查出空值。

    3、判断NULL 用IS NULL 或者 is not null,SQL 语句函数中可以使用IFNULL()函数来进行处理,判断空字符用 =’‘或者<>’'来进行处理。

    4、在进行count()统计某列的记录数的时候,如果采用的NULL值,会别系统自动忽略掉,但是空值是会进行统计到其中的。

    5、MySql中如果某一列中含有NULL,那么包含该列的索引就无效了。这一句不是很准确。

    6:实际到底是使用NULL值还是空值(’’),根据实际业务来进行区分。个人建议在实际开发中如果没有特殊的业务场景,可以直接使用空值。

    以上就是我的对此问题的整理和思考,希望可以在面试中帮助到你。如果你对此话题有自己的思考和理解,也欢迎留言一起探讨!

    04 参考资料

    https://www.cnblogs.com/wzmenjoy/p/4244590.html

    https://dev.mysql.com/doc/refman/5.7/en/working-with-null.html


    谢谢你的阅读,如果您觉得这篇博文对你有帮助,请点赞或者喜欢,让更多的人看到!祝你每天开心愉快!


    Java编程技术乐园:一个分享编程知识的公众号。跟着老司机一起学习干货技术知识,每天进步一点点,让小的积累,带来大的改变!

    扫描关注,后台回复【资源】,获取珍藏干货! 99.9%的伙伴都很喜欢

    image.png | center| 747x519

    © 每天都在变得更好的阿飞云
    展开全文
  • 在javascript中, 前端把null值展示到页面上, 对用户来说是不太友好的, 我们所以经常写很多对 null 值判断的代码, 费时费力, 所以写了一个统一的函数来处理 介绍 /** * data 需要传入的去除null值的对象或者值 ...

    简介

    在javascript中, 前端把null值展示到页面上, 对用户来说是不太友好的, 我们所以经常写很多对 null 值判断的代码, 费时费力,  所以写了一个统一的函数来处理

     

    介绍

    /**
     *  data 需要传入的去除null值的对象或者值
     *  defaultStr 将null值转为该字符串, 不传默认为 空字符串 ''
     */
    function removeNull(data, defaultStr = '') {
        // 普通数据类型
        if (typeof data != 'object' || data == null) {
            if ((data == null || data == 'null')) {
                return defaultStr;
            } else {
                return data;
            }
        }
        // 引用数据类型
        for (const v in data) {
            if (data[v] == null || data[v] == 'null') {
                data[v] = defaultStr;
            }
            if (typeof data[v] == 'object') {
                removeNull(data[v])
            }
        }
    }

    测试

    
    // 测试数据
    const data = {
        aa: null,
        bb: 'bb',
        cc: 'null',
        dd: {
            dd1: 'dd1',
            dd2: null,
            dd3: 'null'
        },
        ee: [{
            ee: 'null',
            ff: ['null', {
                ff1: {
                    ff2: null
                }
            }]
        }, null]
    }
    
    // 如果是object, 因为是引用传递, 我没有将data return回来, 调用方法之后该data已经去除完成 
    removeNull(data)
    console.log(data)
    

    总结

      至此一个简单的去除对象中null值的方法就写好了, 是不是很简单呢 0..0

      可以递归的去除对象里的子对象的null值, 很方便

      如果说不希望改变原有的值, 可以拷贝一个对象再执行该方法 

     

    感谢您的阅读!如果文章中有任何错误,或者您有更好的理解和建议,欢迎和我联系!

    展开全文
  • c语言NULL和0区别及NULL详解

    万次阅读 多人点赞 2016-10-13 21:32:41
    转载于一位牛人:http://www.cnblogs.com/youxin/archive/2012/03/27/2420023.html ~谢谢。 先看下面一段代码输出什么: #include int main() ... int *p=NULL;...输出 ,单步调试可以看出执行int *p=NULL,p的值

    转载于一位牛人:http://www.cnblogs.com/youxin/archive/2012/03/27/2420023.html

    ~(翻译是我自己理解翻译的,嘻嘻,难免会有错误还请多多指点)谢谢~。

    先看下面一段代码输出什么:

    复制代码
    #include<stdo.h>
    int main()
    {
        int *p=NULL;
        printf("%s",p);
     
    }
    复制代码

    输出<null> ,单步调试可以看出执行int *p=NULL,p的值为0x00000000,可以看出,NULL在实际底层调用中就是0,

    在C语言中,

    NULL和0的值都是一样的,但是为了目的和用途及容易识别的原因,NULL用于指针和对象,0用于数值


    对于字符串的结尾,使用'\0',它的值也是0,但是让人一看就知道这是字符串的结尾,不是指针,也不是普通的数值

    在不同的系统中,

    NULL并非总是和0等同,NULL仅仅代表空值,也就是指向一个不被使用的地址,在大多数系统中,都将0作为不被使用的地址,所以就有了类似这样的定义

    #define NULL 0

    但并非总是如此,也有些系统不将0地址作为NULL,而是用其他的地址,所以说,千万别将NULL和0等价起来,特别是在一些跨平台的代码中,这更是将给你带来灾难。

    看下面解释:

    问 0 '0' '\0' "\0"

     

    To me, when doing C/C++:

     

    0 would digit zero, that is, a numerical value.

    //0可能是数字0,也就是一个数值。

     

    '0' could be the character capital oh or the character zero. For example: char word[10] = "Oxford"; char number[10] = "01234";

     

    Depending on typeface used 'O' may look exactly like '0' making it difficult to tell them apart out of context.

     //上面两句要一起理解。0可能会被作为大写字母O或者字符0.仅仅根据字体使用“O”看起来就像' 0 '很难分辨他们。

    '\0' is the null character used to terminate strings in C/C++.

    //'\0'是null字符用于中止C/C++字符串

     

    "\0" is an empty string.

    //"\0"是一个空字符串

    NULL在stdio.h中定义:

    复制代码
    #if !defined(NULL) && defined(__NEEDS_NULL)
    #ifdef __cplusplus
    #define NULL    0
    #else
    #define NULL    ((void *)0)
    #endif
    #endif
    复制代码

    在c++定义为0,在c中定义为(void *)0;为什么,参考:http://stackoverflow.com/questions/7016861/null-pointer-in-c-and-c

    在探究的过程中找到下面的一个帖子。很是不错,COPY如下。
    转载自:http://blog.chinaunix.net/u/18517/showart_309917.html


        帖子里讨论了C语言中的空指针、空指针常量、NULL、0等概念及相互关系及区别。这里摘录whyglinux兄的总结。做个标签,呵呵^_^

    1. 什么是空指针常量(null pointer constant)?

      [6.3.2.3-3] An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant//一个整数常量表达式的值0,或这样的表达式类型void *,称为空指针常量
    2. 这里告诉我们:0、0L、'\0'、3 - 3、0 * 17 (它们都是“integer constant expression”)以及 (void*)0 (tyc: 我觉得(void*)0应该算是一个空指针吧,更恰当一点)等都是空指针常量(注意 (char*) 0 不叫空指针常量,只是一个空指针值)。至于系统选取哪种形式作为空指针常量使用,则是实现相关的。一般的 C 系统选择 (void*)0 或者 0 的居多(也有个别的选择 0L);至于 C++ 系统,由于存在严格的类型转化的要求,void* 不能象 C 中那样自由转换为其它指针类型,所以通常选 0 作为空指针常量(tyc: C++标准推荐),而不选择 (void*)0。

    3. 什么是空指针(null pointer)?

      [6.3.2.3-3] If a null pointer constant is converted to a pointer type, the resulting pointer, called a null pointer, is guaranteed to compare unequal to a pointer to any object or function.//如果一个空指针常量被转换为一个指针类型,产生的指针,称为空指针,保证比作一个指针指向任何对象或函数是不平等的。
      char *p=0;此时p就是一个空指针,不指向任何实际对象。
      因此,如果 p 是一个指针变量,则 p = 0;、p = 0L;、p = '\0';、p = 3 - 3;、p = 0 * 17; 中的任何一种赋值操作之后(对于 C 来说还可以是 p = (void*)0;), p 都成为一个空指针,由系统保证空指针不指向任何实际的对象或者函数。反过来说,任何对象或者函数的地址都不可能是空指针。(tyc: 比如这里的(void*)0就是一个空指针。把它理解为null pointer还是null pointer constant会有微秒的不同,当然也不是紧要了

    4. 什么是 NULL?

      [6.3.2.3-Footnote] The macro NULL is defined in <stddef.h> (and other headers) as a null pointer constant//宏定义空< stddef.h >(和其他标题)作为一个空指针常量

      即 NULL 是一个标准规定的宏定义,用来表示空指针常量。因此,除了上面的各种赋值方式之外,还可以用 p = NULL; 来使 p 成为一个空指针。tyc:很多系统中的实现:#define NULL (void*)0,与这里的“a null pointer constant”并不是完全一致的

    5. 空指针(null pointer)指向了内存的什么地方(空指针的内部实现)?

      标准并没有对空指针指向内存中的什么地方这一个问题作出规定,也就是说用哪个具体的地址值(0x0 地址还是某一特定地址)表示空指针取决于系统的实现。我们常见的空指针一般指向 0 地址即空指针的内部用全 0 来表示(zero null pointer,零空指针);也有一些系统用一些特殊的地址值或者特殊的方式表示空指针(nonzero null pointer,非零空指针),具体请参见C FAQ

      幸运的是,在实际编程中不需要了解在我们的系统上空指针到底是一个 zero null pointer 还是 nonzero null pointer,我们只需要了解一个指针是否是空指针就可以了——编译器会自动实现其中的转换,为我们屏蔽其中的实现细节。注意:不要把空指针的内部表示等同于整数 0 的对象表示——如上所述,有时它们是不同的。

    6. 如何判断一个指针是否是一个空指针?

      这可以通过与空指针常量或者其它的空指针的比较来实现(注意与空指针的内部表示无关)。例如,假设 p 是一个指针变量,q 是一个同类型的空指针,要检查 p 是否是一个空指针,可以采用下列任意形式之一——它们在实现的功能上都是等价的,所不同的只是风格的差别。

      指针变量 p 是空指针的判断:
      if ( p == 0 )
      if ( p == '\0' )
      if ( p == 3 - 3 )
      if ( p == NULL )  /* 使用 NULL 必须包含相应的标准库的头文件 */
      if ( NULL == p )
      if ( !p )
      if ( p == q )
      ...

      指针变量 p 不是空指针的判断:
      if ( p != 0 )
      if ( p != '\0' )
      if ( p != 3 - 3 )
      if ( p != NULL )  /* 使用 NULL 必须包含相应的标准库的头文件 */
      if ( NULL != p )
      if ( p )
      if ( p != q )
      ...

    7. 可以用 memset 函数来得到一个空指针吗?

      这个问题等同于:如果 p 是一个指针变量,那么

      memset( &p, 0, sizeof(p) ); 和 p = 0;

      是等价的吗?

      答案是否定的,虽然在大多数系统上是等价的,但是因为有的系统存在着“非零空指针” (nonzero null pointer),所以这时两者不等价。由于这个原因,要注意当想将指针设置为空指针的时候不应该使用 memset,而应该用空指针常量或空指针对指针变量赋值或者初始化的方法。

    8. 可以定义自己的 NULL 的实现吗?兼答"NULL 的值可以是 1、2、3 等值吗?"类似问题

      [7.1.3-2] If the program declares or defines an identifier in a context in which it is reserved (other than as allowed by 7.1.4), or defines a reserved identifier as a macro name, the behavior is undefined.//如果程序声明或定义一个标识符在一个上下文的保留(7.1.4所允许的以外),或将保留标识符定义为宏名称,其行为是未定义的。

      NULL 是标准库中的一个符合上述条件的 reserved identifier (保留标识符)。所以,如果包含了相应的标准头文件而引入了 NULL 的话,则再在程序中重新定义 NULL 为不同的内容是非法的,其行为是未定义的。也就是说,如果是符合标准的程序,其 NULL 的值只能是 0,不可能是除 0 之外的其它值,比如 1、2、3 等。

    9. malloc 函数在分配内存失败时返回 0 还是 NULL?

      malloc 函数是标准 C 规定的库函数。在标准中明确规定了在其内存分配失败时返回的是一个 “null pointer”(空指针):

      [7.20.3-1] If the space cannot be allocated, a null pointer is returned.//如果无法分配空间,将返回一个空指针。

      对于空指针值,一般的文档(比如 man)中倾向于用 NULL 表示,而没有直接说成 0。但是我们应该清楚:对于指针类型来说,返回 NULL 和 返回 0 是完全等价的,因为 NULL 和 0 都表示 “null pointer”(空指针)。(tyc:一般系统中手册中都返回NULL,那我们就用NULL吧

    另外,附C FAQ上关于null pointer的解释:C FAQ:null pointer

    百度百科解释;

    \0是C++中字符串的结尾标志,存储在字符串的结尾。比如char cha[5]表示可以放5个字符的字符串,由于c/c++中规定字符串的结尾标志为'\0',它虽然不计入串长,但要占内存空间,而一个汉字一般用两个字节表示,且c/c++中如一个数组cha[5],有5个变量,分别是 cha[0] , cha[1] , cha[2] , cha[3] , cha[4] , 所以cha[5]可以放5个字母或者放2个汉字(1个汉字占2个字节,1个字母占一个字节),cha[5]占5个字节内存空间.

      例如:

     
    复制代码
        char str[5];
        str[0]='a';
        str[1]='b';
        str[2]='c';
        str[3]='d';
        //str[4]='\0'; //abcd
        str[4]='e'; /*这样输出就是abcde和一堆乱码,甚至跳出系统错误,因为没有字符串结尾符*/
        printf("%s",str);
      
    复制代码

    展开全文
  • 今天在使用的时候使用GuavaCache的refreshAfterWrite的功能时,发现在少数场景下会报错CacheLoader returned null for key。但是如果把refreshAfterWrite去掉时,又不会报错。具体错误内容是这样的。 ...

    背景

    今天在使用的时候使用GuavaCache的refreshAfterWrite的功能时,发现在少数场景下会报错CacheLoader returned null for key。但是如果把refreshAfterWrite去掉时,又不会报错。具体错误内容是这样的。

    com.google.common.cache.CacheLoader$InvalidCacheLoadException: CacheLoader returned null for key ValueOfKeyIsNull.
    
    	at com.google.common.cache.LocalCache$Segment.getAndRecordStats(LocalCache.java:2348)
    	at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2318)
    	at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2280)
    	at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2195)
    	at com.google.common.cache.LocalCache.get(LocalCache.java:3934)
    	at com.google.common.cache.LocalCache.getOrLoad(LocalCache.java:3938)
    	at com.google.common.cache.LocalCache$LocalLoadingCache.get(LocalCache.java:4821)
    	at com.google.guava.cache.GuavaRefreshWhenCacheIsNullTest.testGuavaRefreshWhenCacheIsNullThrowsException(GuavaRefreshWhenCacheIsNullTest.java:49)
    

    探寻

    首先为什么如果不用refreshAfterWrite功能时为什么不会有问题?由于好奇,只能去源码里查找答案。基于报错内容,在com.google.common.cache.LocalCache.Segment#getAndRecordStats找到这一段源代码

            value = getUninterruptibly(newValue);
            if (value == null) {
              throw new InvalidCacheLoadException("CacheLoader returned null for key " + key + ".");
            }
    

    大致意思是从ListenableFuture newValue这个Future中获取到的值不能为空,如果为空,则直接报一个InvalidCacheLoadException异常。

    当我们使用了refreshAfterWrite功能时,必须build一个自己实现的CacheLoader,这时会返回一个com.google.common.cache.LocalCache.LocalLoadingCache的LoadingCache实例。从org.springframework.cache.guava.GuavaCache代码中,发现这么一段代码

    	@Override
    	public ValueWrapper get(Object key) {
    		if (this.cache instanceof LoadingCache) {
    			try {
    				Object value = ((LoadingCache<Object, Object>) this.cache).get(key);
    				return toValueWrapper(value);
    			}
    			catch (ExecutionException ex) {
    				throw new UncheckedExecutionException(ex.getMessage(), ex);
    			}
    		}
    		return super.get(key);
    	}
    

    当这个cache是LoadingCache时,走的获取key对应的value的方式是不同的。依次会走到com.google.common.cache.LocalCache S e g m e n t . l o a d S y n c , 然 后 到 c o m . g o o g l e . c o m m o n . c a c h e . L o c a l C a c h e Segment.loadSync,然后到com.google.common.cache.LocalCache Segment.loadSynccom.google.common.cache.LocalCacheSegment.getAndRecordStats,最终获取的value如果为null的话,则直接报错,即使你在GuavaCacheManager层面设置了setAllowNullValues(true)也依然会报错。

    分析

    如果不是LoadingCache的话,那是允许返回null值的,且不会报错。但是使用了refreshAfterWrite功能后,是不允许的。其实仔细想一想也是很合理的,这里我们重写了CacheLoader,CacheLoader的一个重要的工作就是在2次获取同一个key时,且key到了该refresh的时间,就会后台异步刷新,如果刷新这个key得到了新值,就会覆盖key对应的旧值。但是如果得到了null,应该怎么做呢?刷新还是不管?GuavaCache表示自己也很无奈,干脆报错,让业务层自己去理会好了。

    不过,个人觉得这种方式还是比较粗暴。就算是使用了refreshAfterWrite,也不敢保证自己的每个key都能对应值。但是从报错位置的代码来看,确实没有可设置的参数给业务来屏蔽这个异常。

    处理方法1:异常捕捉

    有一种最挫最简单的方法,在get的时候catch住异常,异常情况下直接返回null,这种方法简单粗暴又有效

    处理方法2:使用Optional

    对于null值的处理,java8是提供了一种很好的处理方法,就是Optional类。对value值统一使用Optional封装,业务方拿到Optional时,通过Optional.orElse(null)方法拿到真实值,避免在CacheLoader的load中返回null。关于Optional,更多详细内容可以参考我的另一篇博客Java8新特性学习(二)- Optional类

    下面代码已上传到 github - common-caches

    
        @Test
        public void testGuavaRefreshWhenCacheIsNullReturnNull() {
    
            CacheBuilder<Object, Object> cacheBuilder = CacheBuilder.newBuilder()
                    .refreshAfterWrite(10, TimeUnit.SECONDS)
                    .expireAfterWrite(20, TimeUnit.SECONDS);
            
            LoadingCache<String, Optional<String>> refreshWarehouseCache = cacheBuilder.build(new CacheLoader<String, Optional<String>>() {
                @Override
                public Optional<String> load(String key) {
                    if ("ValueOfKeyIsNull".equals(key)) {
                        return Optional.empty();
                    }
                    return Optional.of("1234567890");
                }
    
                @Override
                public ListenableFuture<Optional<String>> reload(String key, Optional<String> oldValue) {
                    System.out.println("testGuavaRefresh reload : key=" + key);
                    return Futures.immediateFuture(load(key));
                }
            });
    
            try {
                Optional<String> myValue = refreshWarehouseCache.get("myKey");
                Assert.assertEquals("1234567890", myValue.orElse(null));
    
                myValue = refreshWarehouseCache.get("ValueOfKeyIsNull");
                //get myValue is null
                Assert.assertNull(myValue.orElse(null));
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
    

    处理方法3:使用特殊值标记null值

    这是找一个特殊的值,且不会在真实环境中不会有和这个特殊值相同。这里以value是String类型为例,当然如果是Object类型的,也是可以判断的,只要XXXObject某些关键字段的值不一样就行,可以使用Objects.equals()来判定是否是特殊值,主要要重写这个XXXObject的equals和hashCode方法就行了。

    下面代码已上传到 github - common-caches

        @Test
        public void testGuavaRefreshWhenCacheIsNullReturnDefaultNullValue() {
    
            CacheBuilder<Object, Object> cacheBuilder = CacheBuilder.newBuilder()
                    .refreshAfterWrite(10, TimeUnit.SECONDS)
                    .expireAfterWrite(20, TimeUnit.SECONDS);
            
            String nullValue = "nullValue";
    
            LoadingCache<String, String> refreshWarehouseCache = cacheBuilder.build(new CacheLoader<String, String>() {
                @Override
                public String load(String key) {
                    if ("ValueOfKeyIsNull".equals(key)) {
                        return nullValue;
                    }
                    return "1234567890";
                }
    
                @Override
                public ListenableFuture<String> reload(String key, String oldValue) {
                    System.out.println("testGuavaRefresh reload : key=" + key);
                    return Futures.immediateFuture(load(key));
                }
            });
    
            try {
                String myValue = refreshWarehouseCache.get("myKey");
                Assert.assertEquals("1234567890", myValue);
    
                //throws Exception
                myValue = refreshWarehouseCache.get("ValueOfKeyIsNull");
                Assert.assertEquals(nullValue, myValue);
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
    

    总结

    前面的博客有讲过GuavaCache相关的内容,包括缓存篇(一)- GuavaGuava Cache expireAfterWrite 与 refreshAfterWrite区别.

    关于GuavaCache,其实有一些设计比较好的方面,但是也存在一些可以完善的方面。在使用的过程中,不断发现设计好的学习过来。你觉得还有哪些设计不好的方面,欢迎一起交流。

    我先来一个觉得不好的吧。spring中集成的Guava Cache,一个GuavaCacheManager,只设计了一个CacheLoader,但是cacheName却有多个,这就意味着一个CacheName在后台异步刷新时,需要考虑多个不同的cacheName的情况。而CacheLoader中只能通过Object key来判断当前这个key是属于哪个cacheName的,进而再调用对应的cacheName的刷新方法去刷新,这是比较困难的一件事,如果你的多个cacheName的key是没有什么特别的规则的话,这简直就是一个灾难。

    展开全文
  • java null==null是否成立

    千次阅读 2019-09-06 15:47:16
    看Arrys.equals()源码的时候,第一行是判断两个参数是否==,突然很好奇,如果==号两边都是null这种写法是否可行,可行的话结果是true还是false? public static boolean equals(int[] a, int[] a2) { if (a==a2) ...
  • 系统错误null是什么意思 Java中NULL用法的简单示例: public Employee getByName(String name) { int id = database.find(name); if (id == 0) { return null; } return new Employee(id); } 这种方法有什么...
  • JAVA与SQL 中的nullNULL

    千次阅读 2016-10-14 22:55:54
     nullNULL不都是表示空值吗?这有什么值得深入讨论的的?首先你在编写Java代码时使用过NULL吗?大概用IDE用习惯了,自动给生成以及纠正没有注意过也很正常。同样道理在数据库中的疑问我就不提问了。如果你不了解...
  • 有意思,原来SQL中的NULL是这么回事儿

    千次阅读 多人点赞 2020-04-30 13:37:09
    在日常使用数据库时,你在意过NULL值么? 其实,NULL值在数据库中是一个很特殊且有趣的存在,下面我们一起来看看吧; 在查询数据库时,如果你想知道一个列(例如:用户注册年限 USER_AGE)是否为 NULL,SQL ...
  • clickhouse中对于null的处理和其他数据库有点差别。测试分析如下: 1.建表语句 CREATE TABLE default.testeasy ( `sequenceId` UInt32, `tableaId` String, `eventOccurTime` DateTime, `abnormalTags` ...
  • @NotNull(message = "primary is not null",groups = {GroupInterface1.class}) private Long id; } 我就想问一下 我知道这个@NotNull是校验为不为空得东西,我想知道的是里面得groups 定义是有什么作用,...
  •  1.1 null与not null  null 和 not null是mysql的字段属性,或称为数据类型的属性,不属于任何类型。null值也不等同于空值,空值是不占用存储空间的,null占用存储空间,如对myisam表占用1bit额外存储空间。  1.2...
  • MySQL nullif()函数

    千次阅读 2018-09-01 19:59:41
    转载自 MySQL nullif()函数 MySQL NULLIF函数简介 NULLIF函数是接受2个参数的控制流函数之一。如果第一个参数等于第二个参数,则NULLIF函数返回NULL,否则返回第一个参数。 NULLIF函数的语法如下: NULLIF...
  • hive:null 和 '' , 'NULL'

    千次阅读 2018-10-13 00:18:30
    说下hive中的null employee表   hive&gt;desc employee; empid string deptid string salary string 查询employee hive&gt;select * from employee 1 NULL NULL hive 中null实际在HDFS中默认存储为'...
  • spring mvc 校验@NULL @notNULL

    万次阅读 2018-03-27 09:45:41
    一、准备校验时使用的JAR [java] view plain copy validation-api-1.0.0.GA.jar:JDK的接口... log4j、slf4j、slf4j-log4j 二、编写需要校验的bean@NotNull(message="名字不能为空") private St...
  • 虽然在变量表的下方都是一个 null ,但是上方的属性不一样,此null 非彼null 。 这是个 JsonNull 。 如果你要判断 object_vehicleLocation 变量是否是null ,需要这样写:  if(object_vehicleLocation ==...
  • Java中关于Null的9个解释(Java Null详解)

    千次阅读 2017-09-21 11:04:04
    对于Java程序员来说,null是令人头痛的东西。时常会受到空指针异常(NPE)的骚扰。连Java的发明者都承认这是他的一项巨大失误。Java为什么要保留null呢?null出现有一段时间了,并且我认为Java发明者知道null与它...
  • HIVE中的NULL处理

    千次阅读 2019-01-30 10:35:47
    在此记录下使用 sqoop将数据从mysql导出到 hive过程中需要注意的几个地方,包括 NULL值处理、增量导入、parquet格式的日期类型 注:这种数据传输工具其实没必要深究所有用法,用到哪块去研究下就行了 Sqoop版本:...
  • 有可能是因为TextField没有设置宽度,用一个SizedBox包裹起来就可以了。
  • Mysql中is null 和 is not null的使用

    万次阅读 2020-03-17 16:51:28
    MySQL 使用 SQL SELECT 命令及 WHERE 子句来读取数据表中的数据,但是当提供的查询条件字段为 NULL 时,该命令可能就无法正常工作。 为了处理这种情况,MySQL提供了三大运算符: IS NULL: 当列的值是 NULL,此运算符...
  • Java8 : Optional 类,优雅判定null

    万次阅读 多人点赞 2019-02-17 14:49:20
    Optional不是对null关键字的一种替代,而是对于null判定提供了一种更加优雅的实现 NullPointException可以说是所有java程序员都遇到过的一个异常,虽然java从设计之初就力图让程序员脱离指针的苦海,但是指针确实...
  • SQL中NULL 值!= NULL

    千次阅读 2019-10-23 09:16:08
    sql 中的null 值是不等于null的,当你在使用sql左连接查询的时候(类似连接),即使途中这两条记录的name,year,month 是一致的(包含null)但在sql 筛选出来的结果是认为不一致的 tips: sql 中: null !=null --&...
  • 上午我收到一条短信,内容是“尊敬的 null 你好,XXX”,当时我就笑了。真是外行看热闹,内行看门道,这是程序员都能 Get 的笑点,说明程序没有正确从数据库获取到我的姓名,然后把空值格式化为了 null
  • 来吧,一文彻底搞懂Java中最特殊的存在——null

    万次阅读 多人点赞 2020-01-13 07:20:42
    比如说:Java 中的 null 到底是什么鬼?像这类灵魂拷问的主题,非常值得深入地研究一下。 null 在 Java 中是一个特殊的存在,因为它和大名鼎鼎的 NullPointerException(NPE)如影随形。NPE 的发明人 T...
  • undefined与null的区别

    万次阅读 2017-11-28 09:42:10
    undefined与null的区别 转载自:http://www.ruanyifeng.com/blog/2014/03/undefined-vs-null.html 大多数计算机语言,有且仅有一个表示"无"的值,比如,C语言的NULL,Java语言的null,Python语言的...
  • MySQL查询优化之九-IS NULL优化(IS NULL Optimization) 如需转载请标明出处:http://blog.csdn.net/itas109 QQ技术交流群:12951803 环境: MySQL版本:5.5.15 操作系统:windows 本文讨论IS NULL优化(IS ...
  • 在用mybatis-plus封装的updateById方法来更新数据时,想把一个字段设置为null值,但是发现更新后数据没有为null还是原来的值,这是因为mybatis-plus在更新的时候做了null判断,默认不更新为null的传参。 2 解决方法...
  • 2>/dev/null和>/dev/null 2>&1和2>&1>/dev/null的区别

    万次阅读 多人点赞 2019-05-24 17:05:08
    /dev/null 意思就是把错误输出到“黑洞” >/dev/null 2>&1 默认情况是1,也就是等同于1>/dev/null 2>&1。意思就是把标准输出重定向到“黑洞”,还把错误输出2重定向到标准输出1,也就是标准输出...
  • Not showing null elements

    千次阅读 2020-05-06 10:19:02
    Not showing null elements 有时候看见list的size与结果不一致,例如下面这样 导致原因: list集合允许null值,list的size还是有的,实际上的数据跟size不一致 解决办法: debug测试一下,看看是否出现 Not showing null ...
  • mysql 中is not null 和 !=null的区别

    千次阅读 2020-05-15 09:51:54
    今天做定时任务,需要用到一个mysql查询 ...=null看着有点不顺眼啊,我改成is not null 找到了,根据条件因素的唯一变化原理,我很明智的判断出了是is notnull和!=null的区别 我知道了他们的区别,但是为...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 7,806,607
精华内容 3,122,642
关键字:

null