Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >最近线上发生的两个坑爹锅!

最近线上发生的两个坑爹锅!

作者头像
艾小仙
发布于 2021-01-14 02:23:29
发布于 2021-01-14 02:23:29
3000
举报
文章被收录于专栏:艾小仙艾小仙

最近由于在技改,发生了不少问题,前文中说的缓存穿透只是其中之一,想了想,虽然都是比较简单的问题,但是应该实际中还是有不少人碰到过,这些问题看似很简单,但是你绝对应该踩过。

==和equals

关于==和equals区别,我相信稍微做过一两年开发的同学都应该很清楚,可是,然而,这个坑在很多开发的时候仍然频繁出现,为什么?因为有时候有的同学认为没什么区别,就用==吧,然而,一些意外总是如期而至。

不久前,由于线上RPC框架切换,我们就发生了一点小问题。

本来,线上的接口是这样定义的:

然后,接口查询中使用到了一个枚举类型,根据id获取枚举值,只不过这里使用的是==号来判断。

调用方的写法:

本来,这个代码在线上跑了两年了,一点问题没有,怎么就突然不行了呢?

但是,切换框架之后,这个接口报错了,当时我也看了这个地方半天,猜测是这里的问题,但是想了想貌似又不应该啊。

结果最后发现,原来的RPC框架传输中使用的是valueOf,从缓存中取值,加上自动装箱拆箱,判断可以通过。但是,新的框架使用的是new Byte(),所以这个老代码就永远无法通过了,因为这是一个新的对象。

看看这个测试的结果。

后面,通过安装Alibaba Java Coding Guidelines插件统一扫描所有代码,还又发现了一个坑爹的问题。

这个写法又不太一样,这个枚举只是单纯的把code成员变量定义成了byte基础类型,不是包装类型。这样,代码用==判断又都OK了。

坑爹1

想象一下,因为是基础数据类型,拆箱后==判断当然是通过的。

还有更奇葩的写法,成员变量是Byte包装类型,getEnumByCode(byte code)这里用的又是基础类型,当然,这种写法也能判断通过。

坑爹2

所以,心累... ...

最后,我想再补充一下关于基础数据类型缓存的知识。能用==判断的原因也都是依赖于缓存的原因。

数据类型

包装类型

缓存类型

缓存值范围

byte

Byte

ByteCache

-128~127

short

Short

ShortCache

-128~127

int

Integer

IntegerCache

-128~127

long

Long

LongCache

-128~127

char

Character

CharacterCache

0~127

最后,奉劝大家一句,千万,千万,在项目中判断包装数据类型都用equals,因为就算这段代码你很确信现在是对的,然而鬼都不知道后面会发生什么!不要抱有侥幸心理。

日志打满

项目技改上线后不久,发现接口成功率直接跌0(跌0的告警监控必须得有,不然死都不知道怎么死的)。排查了很久,看其他都是正常的,最后发现GC耗时狂增,登录服务器一看,居然是硬盘被打满了。

然后果断去看日志,因为我们的硬盘实际上很小,先怀疑日志,果不其然,日志炸了。通过ls -lht查看文件大小。

通过rm -rf删除后发现硬盘空间并没有释放。正常情况下是不会出现这个问题的,但是如果文件被锁定或者有另外的进程在向文件写数据的话就会有问题了。

Linux中,一个文件在文件系统中存放包含两个部分:

  1. 指针部分:指针位于文件系统的meta-data中,在将数据删除后,这个指针就从meta-data中清除了。
  2. 数据部分:而数据部分存储在磁盘中。

像上面的情况,虽然我们删除了service.log,但是由于进程锁定,指针部分没有从meta-data中删除,所以也就看到存储空间没有释放的问题。

解决办法有两种:

  1. 使用lsof -n |grep delete查看什么进程在写service.log,通过命令发现是我们的java进程在一直写文件,然后通过后台工具直接重启应用,重启之后发现恢复正常。
  2. 清空日志文件,执行命令echo "">/service.log,这个方法可以立刻释放磁盘空间,进程继续写入日志也不会受到影响。

- END -

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-01-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 艾小仙 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
有关JAVA自动装箱-拆箱的分析
在java常量与常量池 中已经介绍过一些java自动装箱与拆箱的例子。现在单独对自动装箱/拆箱进行总结。
冬天里的懒猫
2020/08/03
9060
太炸裂啦!4题看出你的基础能力!
八个基本类型包括:boolean、byte、char、short、int、float、long和double。它们各自占用存储空间(字节)如下。
程序视点
2023/09/22
1170
太炸裂啦!4题看出你的基础能力!
Leader:这样的 Bug 你也写的出来???
Hello~各位读者新年好!不知道大家春节假期是否已延长,小黑哥刚接到通知,假期延长到 2 月 2 号,另外回去之后需要在家办公,自行隔离两周。还没试过在家办公,小黑哥就怕到时候生物钟还没调整过来,一觉睡醒已经是下午了。。。
andyxh
2020/02/14
4400
Leader:这样的 Bug 你也写的出来???
int 和 integer :装箱和拆箱的过程,会用到什么方法,你觉得这个会对性能有影响吗,原因是什么(百度一面)
今天继续来讲面试,已经出了很多java一面真题系列文章了,之后也会整理成一个系列,欢迎持续关注哦。
用户7656790
2020/09/01
2.7K0
Objects.equals有坑
最近review别人代码的时候,发现有个同事,在某个业务场景下,使用Objects.equals方法判断两个值相等时,返回了跟预期不一致的结果,引起了我的兴趣。
苏三说技术
2022/08/25
4250
Objects.equals有坑
【小家java】大杂烩---那些年我们一起躺过的坑
此篇博文没有具体的主题,主要针对于平时开发过程中遇到的一些小问题的记录,并且大都从源码的角度去解释为什么会报错。并且此篇博文是持续更新中。。。
YourBatman
2019/09/03
3780
【小家java】大杂烩---那些年我们一起躺过的坑
Java 面试知识点合集
摘要:网上java面试知识杂乱而繁多,每次想看的时候总会挑挑拣拣许多时间就过去了,所以我对其进行一次学习,整理。 学习:许多的基础知识掌握并不牢固,借此机会学习一发。 整理:对知识做出合理的分类,设置目录,方便自己以后回顾时查看
呼延十
2019/07/01
1.1K0
Java 面试知识点合集
Java八大常用类(二) 包装类
基本数据类型 包装类 byte Byte boolean Boolean short Short char Character int Integer long Long float Float double Double 优点:
卢衍飞
2023/02/14
2470
Java基础八股文第一弹
春招来啦,今天给大家分享Java基础高频面试题(第一弹),希望小伙伴们看完之后面试稳过!
程序员大彬
2022/07/08
1K0
【优雅的避坑】不要轻易使用==比较两个Integer的值
自然,我们都知道会打印 j = 667,曾经我很好奇,i是Integer对象,属于包装类型,而j是int基础数据类型,他俩怎么会在一起运算呢?直到我扒开Integer的外表,直接看到了他的内涵...
行百里er
2020/12/02
9270
【优雅的避坑】不要轻易使用==比较两个Integer的值
JavaSE的自动装箱和自动拆箱
内心怀揣自己的真是答案,我们看看下边的源代码: 先看看Integer装箱和拆箱的函数源码:
静默加载
2020/05/31
4580
夯实Java基础系列8:深入理解Java内部类及其实现原理
本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看
Java技术江湖
2019/09/28
3.5K0
基本数据类型
关于java的类型,这里讲解基本类型,引用类型较复杂,分开来讲,那么开始把,基本类型有8种:
晚上没宵夜
2020/03/10
5720
你真的理解Java中的包装类吗?还有不少人踩坑了
   基础数据类型不是在计算机中运算更快吗?为啥还要有包装类?    因为想要对基本类型数据进行更多的操作,最方便的方式就是将其封装成对象。为啥呢?因为在对象描述中就可以定义更多的属性和行为对该基本数据类型进行操作。基本数据类型的包装类是为了解决基本数据类型有些操作不方便带来的问题。
程序员云帆哥
2022/05/12
5070
Java 中为什么设计了包装类
在 Java 中,万物皆对象,所有的操作都要求用对象的形式进行描述。但是 Java 中除了对象(引用类型)还有八大基本类型,它们不是对象。那么,为了把基本类型转换成对象,最简单的做法就是「将基本类型作为一个类的属性保存起来」,也就是把基本数据类型包装一下,这也就是包装类的由来。
飞天小牛肉
2021/03/18
1.3K0
Java 中为什么设计了包装类
Java基础笔记之数据类型
(二)包装类型(与基本数据类型一一对应,把基本数据类型封装成对象的形式)
CherishTheYouth
2019/07/30
3710
Java基础笔记之数据类型
面试官六连问拆箱装箱Integer那些事,给我整懵圈了!
小萌:由于基本数据类型不是对象,所以java并不是纯面向对象的语言,好处是效率较高(全部包装为对象效率较低)。Java是一个面向对象的编程语言,基本类型并不具有对象的性质,为了让基本类型也具有对象的特征,就出现了包装类型(如我们在使用集合类型Collection时就一定要使用包装类型而非基本类型),它相当于将基本类型“包装起来”,使得它具有了对象的性质,并且为其添加了属性和方法,丰富了基本类型的操作。
乔戈里
2020/02/21
5590
面试官六连问拆箱装箱Integer那些事,给我整懵圈了!
Java线上惨痛踩坑记录,你也一定遇到过
如果调用上面的方法会发生什么?id是Integer类型,而方法的返回值int类型,会自动拆箱转换,由于id是null,转换成int类型的时候,就会报NullPointerException异常。
一灯架构
2022/09/15
6080
Java线上惨痛踩坑记录,你也一定遇到过
5分钟彻底理解-Java自动装箱、拆箱
当表格中左边列出的基础类型与它们的包装类有如下几种情况时,编译器会自动帮我们进行装箱或拆箱.
三好码农
2018/09/11
1.1K0
5分钟彻底理解-Java自动装箱、拆箱
从一个 NullPointerException 探究 Java 的自动装箱拆箱机制
前天遇到了一个 NullPointerException,触发的代码类似下面这样:
零式的天空
2022/03/28
4660
相关推荐
有关JAVA自动装箱-拆箱的分析
更多 >
领券
💥开发者 MCP广场重磅上线!
精选全网热门MCP server,让你的AI更好用 🚀
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档