最新要闻
- 世界新动态:传奇大佬、联想PC全球第一的功臣蒋凡可·兰奇去世 享年69岁
- 不叫003 极氪第三款车型ZEEKR X官图发布:20万买不
- 世界观焦点:智商碾压 新养的边牧把养5年金毛拐跑丢弃
- 当前滚动:办公党等到了!小米笔记本12.4二合一发布:2.5K触屏 2999元
- 荣耀Magic5通过3C认证:1/1.1英寸主摄、标配66W充电头
- 苹果业绩暴雷:iPhone卖不动了!库克感谢国人支持 要降价刺激销量?
- 《巫师3:狩猎》4.01版更新上线:光追性能更强 帧率又高了
- 美国新造车告急:造一辆亏23万 CEO深感抱歉
- 极氪009被吐槽像灵车、棺材 车主亲身评测:死人躺并不舒适
- 比亚迪又一大杀器 全新海鸥出街被拍:超个性涂装上身
- 快看:iPhone 12/13/14灵魂设计师离职 苹果直接取消工业设计总监职位
- 动态焦点:男孩为网游充值4万 家长控诉腾讯监控不力未尽义务:该不该退钱?
- 全球微动态丨国内油价今晚调整 或迎兔年“第一涨”:加满一箱预计多花8.5元
- 环球滚动:20个小猫身上笑死人的奇葩花纹:只有你想不到!
- 萌萌哒的兔子竟是“头号杀手”!澳大利亚曾研制病毒专杀兔兔
- 全球新资讯:澳大利亚搞丢一枚剧毒放射性胶囊 相关单位仅被罚款1000块:下不为例?
手机
iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
- 警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- 男子被关545天申国赔:获赔18万多 驳回精神抚慰金
- 3天内26名本土感染者,辽宁确诊人数已超安徽
- 广西柳州一男子因纠纷杀害三人后自首
- 洱海坠机4名机组人员被批准为烈士 数千干部群众悼念
家电
一次JSF上线问题引发的MsgPack深入理解,保证对你有收获
作者: 京东零售 肖梦圆
前序
某一日晚上上线,测试同学在回归项目黄金流程时,有一个工单项目接口报JSF序列化错误,马上升级对应的client包版本,编译部署后错误消失。
(资料图片)
线上问题是解决了,但是作为程序员要了解问题发生的原因和本质。但这都是为什么呢?
第一个问题:为什么测试的时候没有发现问题呢?
首先预发环境中,所有项目中的JSF别名和client包都是beta,每天都有项目进行编译部署,这样每个项目获取的都是最新的client包,所以在预发环境测试没有发现
第二个问题:为什么会出现序列化问题?
JDer的开发们都知道JSF接口如果添加字段需要在类的最后进行添加,对此我检查了自己的代码发现我添加的代码也是在类的最后进行添加的,但是特殊之处在于这是一个父类,有子类进行继承
第三个问题:如果在父类上添加一个字段有什么影响呢?
说实话,猛的这么一问,我犹豫了,JDer们都知道JSF的默认序列化使用的是MsgPack,一直都是口口相传说如果client类添加字段必须在类的最后,但是也没人告诉父类添加字段咋办呀,父子类这种场景MsgPack是如何处理序列化和反序列化的?
第四个问题:MsgPack是什么?MsgPack的序列化和反序化是怎么实现的?
对此问题我坦白了,我不知道;是否有很多JDer跟我对于MsgPack的认识仅限于名字的吗,更别提是如何实现序列化和反序列化了
到此我已经积累了这么多问题了,是时候努力了解一下MsgPack了,看看什么是MsgPack,为什么JSF的默认序列化选择MsgPack呢?
msgpack介绍
官网地址: https://msgpack.org/
官方介绍:
It"s like JSON. but fast and small.
翻译如下:
这就像JSON,但更快更小
MessagePack 是一种高效的二进制序列化格式。它允许您在多种语言(如 JSON)之间交换数据。但是速度更快,体积更小。小整数被编码成一个字节,而典型的短字符串除了字符串本身之外只需要一个额外的字节。
JSON格式占用27字节,msgpack只占用18字节
msgpack 核心压缩规范
msgpack制定了压缩规范,这使得msgpack更小更快。我们先了解一下核心规范:
format name | first byte (in binary) | first byte (in hex) |
---|---|---|
positive fixint | 0xxxxxxx | 0x00 - 0x7f |
fixmap | 1000xxxx | 0x80 - 0x8f |
fixarray | 1001xxxx | 0x90 - 0x9f |
fixstr | 101xxxxx | 0xa0 - 0xbf |
nil | 11000000 | 0xc0 |
(never used) | 11000001 | 0xc1 |
false | 11000010 | 0xc2 |
true | 11000011 | 0xc3 |
bin 8 | 11000100 | 0xc4 |
bin 16 | 11000101 | 0xc5 |
bin 32 | 11000110 | 0xc6 |
ext 8 | 11000111 | 0xc7 |
ext 16 | 11001000 | 0xc8 |
ext 32 | 11001001 | 0xc9 |
float 32 | 11001010 | 0xca |
float 64 | 11001011 | 0xcb |
uint 8 | 11001100 | 0xcc |
uint 16 | 11001101 | 0xcd |
uint 32 | 11001110 | 0xce |
uint 64 | 11001111 | 0xcf |
int 8 | 11010000 | 0xd0 |
int 16 | 11010001 | 0xd1 |
int 32 | 11010010 | 0xd2 |
int 64 | 11010011 | 0xd3 |
fixext 1 | 11010100 | 0xd4 |
fixext 2 | 11010101 | 0xd5 |
fixext 4 | 11010110 | 0xd6 |
fixext 8 | 11010111 | 0xd7 |
fixext 16 | 11011000 | 0xd8 |
str 8 | 11011001 | 0xd9 |
str 16 | 11011010 | 0xda |
str 32 | 11011011 | 0xdb |
array 16 | 11011100 | 0xdc |
array 32 | 11011101 | 0xdd |
map 16 | 11011110 | 0xde |
map 32 | 11011111 | 0xdf |
negative fixint | 111xxxxx | 0xe0 - 0xff |
示例解读:
json串:
对应的msgpack为:82 a7 63 6f 6d 70 61 63 74 c3 a6 73 63 68 65 6d 61 00
第一个82,查看规范表,落在fixmap上,fixmap的范围:0x80 - 0x8f,表示这是一个map结构,长度为2
后面一个为a7,查看规范表,落在fixstr的范围:0xa0 - 0xbf,表示是一个字符串,长度为7,后面7个为字符串内容:63 6f 6d 70 61 63 74 将16进制转化为字符串为:compact
往后一个为:c3,落在true的范围:oxc3
再往后一个为:a6,查看规范表,落在fixstr的范围:0xa0 - 0xbf,表示是一个字符串,长度为6,后面6个字符串内容为:
73 63 68 65 6d 61,将16进制转化为字符串为:schema
最后一个为:00,查看规范表,落在positive fixint,表示一个数字,将16进制转为10进制数字为:0
拼装一下
我们看一下官方给出的stringformat示意图:
对于上面的问题,一个长度大于15(也就是长度无法用4bit表示)的string是这么表示的:用指定字节0xD9表示后面的内容是一个长度用8bit表示的string,比如一个160个字符长度的字符串,它的头信息就可以表示为D9A0。
举一个长字符串的例子:
83 A4 6E 61 6D 65 DA 03 06 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 66 61 74 68 65 72 A3 61 67 65 0A AB 63 68 69 6C 64 65 72 4E 61 6D 65 A7 63 68 69 6C 64 65 72
一起解析一下看看
83:这个大家都已经知道了,一个固定的map,长度为3
A4:fixstr(长度4),然后找到后面四位
6E 61 6D 65:16进制转为字符串:name
DA:str 16 ,后面两个字节为长度
03 06:16进制转化为10进制:774
后面774个字节转化为字符串:
A3: fixstr(长度3),然后找到后面三位
61 67 65 :16进制转为字符串:age
0A :16进制转10进制:10
AB :fixstr(长度11),然后找到后面11位
63 68 69 6C 64 65 72 4E 61 6D 65 :16进制转为字符串:childerName
A7 : fixstr(长度7),然后找到后面七位
63 68 69 6C 64 65 72 :16进制转为字符串:childer
问题原因解析
先还原事件过程,我们在父类的最后添加一个字段,然后创建一个子类继承父类,然后进行模拟序列化和反序化,查找问题
第一步:模拟父子类,输出16进制数据
先声明一个父子类,然后进行序列化
父类:
public class FatherPojo implements Serializable { /** * name */ private String name;}
子类:
public class ChilderPojo extends FatherPojo implements Serializable { private String childerName;}
使用官方的序列化包进行序列化
org.msgpack jackson-dataformat-msgpack (version)
测试代码如下:
public class Demo { public static void main(String[] args) throws JsonProcessingException { ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory()); ChilderPojo pojo = new ChilderPojo(); pojo.setName("father"); pojo.setChilderName("childer"); System.out.println(JSON.toJSON(pojo)); byte[] bytes = objectMapper.writeValueAsBytes(pojo); //输出16进制 System.out.println(byteToArray(bytes)); } /** * byte数组转化为16进制数据 */ public static String byteToArray(byte[]data) { StringBuilder result = new StringBuilder(); for (int i = 0; i < data.length; i++) { result.append(Integer.toHexString((data[i] & 0xFF) | 0x100).toUpperCase().substring(1, 3)).append(" "); } return result.toString(); } }
输入结果如下:
82 A4 6E 61 6D 65 A6 66 61 74 68 65 72 AB 63 68 69 6C 64 65 72 4E 61 6D 65 A7 63 68 69 6C 64 65 72
拿着json数据去messagepack官网也获取一下16进制数据,跟如上代码输出的结果是一样的。
第二步:在父类的结尾增加一个字段,然后输出16进制数组
修改父类,增加一个age字段
public class FatherPojo implements Serializable { /** * name */ private String name; /*** * age */ private Integer age;}
修改测试代码,给父类的age赋值
public class Demo { public static void main(String[] args) throws JsonProcessingException { ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory()); ChilderPojo pojo = new ChilderPojo(); pojo.setName("father"); pojo.setChilderName("childer"); pojo.setAge(10); System.out.println(JSON.toJSON(pojo)); byte[] bytes = objectMapper.writeValueAsBytes(pojo); //输出16进制 System.out.println(byteToArray(bytes)); } /** * byte数组转化为16进制数据 */ public static String byteToArray(byte[]data) { StringBuilder result = new StringBuilder(); for (int i = 0; i < data.length; i++) { result.append(Integer.toHexString((data[i] & 0xFF) | 0x100).toUpperCase().substring(1, 3)).append(" "); } return result.toString(); } }
输入结果如下:
83 A4 6E 61 6D 65 A6 66 61 74 68 65 72 A3 61 67 65 0A AB 63 68 69 6C 64 65 72 4E 61 6D 65 A7 63 68 69 6C 64 65 72
拿着json数据去messagepack官网也获取一下16进制数据,跟如上代码输出的结果是一样的。
先对比json数据
父类没加字段之前:
父类加字段之后:
对比一下前后两次16进制数组,我们进行对齐后进行对比一下
82 A4 6E 61 6D 65 A6 66 61 74 68 65 72 AB 63 68 69 6C 64 65 72 4E 61 6D 65 A7 63 68 69 6C 64 65 72
83 A4 6E 61 6D 65 A6 66 61 74 68 65 72 A3 61 67 65 0A AB 63 68 69 6C 64 65 72 4E 61 6D 65 A7 63 68 69 6C 64 65 72
对比发现在红色部分是多出来的一部分数据应该就是我们添加的age字段,现在我们进行解析对比一下。
拼装一下
拼装一下
第三步:直接对二进制数据解包
1、先用正确的顺序解包
public static void analyze(byte[] bytes) throws IOException { MessageUnpacker unpacker = MessagePack.newDefaultUnpacker(bytes); int length = unpacker.unpackMapHeader(); String name = unpacker.unpackString(); String nameValue = unpacker.unpackString(); String age = unpacker.unpackString(); Integer ageValue = unpacker.unpackInt(); String childerName = unpacker.unpackString(); String childerNameValue = unpacker.unpackString(); System.out.println("{""+name+"":""+nameValue+"",""+age+"":"+ageValue+",""+childerName+"":""+childerNameValue+""}");}
输出结果为:
2、如果我们客户端没有升级client包版本,使用了错误的解包顺序
public static void analyze(byte[] bytes) throws IOException { MessageUnpacker unpacker = MessagePack.newDefaultUnpacker(bytes); int length = unpacker.unpackMapHeader(); String name = unpacker.unpackString(); String nameValue = unpacker.unpackString(); String childerName = unpacker.unpackString(); String childerNameValue = unpacker.unpackString(); System.out.println("{""+name+"":""+nameValue+"",""+childerName+"":""+childerNameValue+""}"); }
解析报错:反序列化失败
从上述案例中发现在父类中增加数据,相当于在子类中间增加数据导致子嘞反序列化失败。需要注意的是解包顺序必须与打包顺序一致,否则会出错。也就是说协议格式的维护要靠两端手写代码进行保证,而这是很不安全的。
JSF为什么选择MsgPack以及官方FAQ解释
为什么JSF会选择MsgPack作为默认的序列化
JDer的开发们用的RPC基本上都是JSF,在远程调用的过程中字节越少传输越快越安全(产生丢包的可能性更小), 咱们回过头去看看MsgPack; 我们了解了MsgPack的压缩传输可以看到,MsgPack序列化后占用的字节更小,这样传输的更快更安全;所以这应该就是JSF选择Msgpack作为默认序列化的原因了。我理解MsgPack是采用一种空间换时间的策略,减少了在网络传输中的字节数,使其更安全,然后在接到序列化后的数据后按照压缩规范进行反序列化(这部分增加了cpu和内存的使用,但是减少了网络传输中时间且提高了传输安全性)。
JSF对父子类序列化的FQA解释
是时候进行总结和说再见了
总结:
1、MessagePack 是一种高效的二进制序列化格式。 它允许您在多种语言(如 JSON)之间交换数据。 但是速度更快,体积更小。
此去经年,江湖再见
-
全球观点:(笔记)【NTP系列:05】NTP时间同步失败:Windows(W32Time)作为NTP时钟源服务端,Linux作为客户端
一、问题现象使用windows(W32Time)作NTP时钟源服务端,控制板端Linux作为客户端,使用ntpd服务无法同...
来源: 一次JSF上线问题引发的MsgPack深入理解,保证对你有收获
全球快看点丨springboot实战——总结
全球观点:(笔记)【NTP系列:05】NTP时间同步失败:Windows(W32Time)作为NTP时钟源服务端,Linux作为客户端
[概率论与数理统计]笔记:5.4 假设检验概述
西门子手机怎么样?西门子手机哪年进入中国?
联想y470双显卡驱动怎么装?联想y470双显卡怎么切换?
dota2怎么改成国服?DOTA2配置要求是什么?
世界新动态:传奇大佬、联想PC全球第一的功臣蒋凡可·兰奇去世 享年69岁
不叫003 极氪第三款车型ZEEKR X官图发布:20万买不
世界观焦点:智商碾压 新养的边牧把养5年金毛拐跑丢弃
当前滚动:办公党等到了!小米笔记本12.4二合一发布:2.5K触屏 2999元
荣耀Magic5通过3C认证:1/1.1英寸主摄、标配66W充电头
世界关注:非常强大的gsap动画
2023年值得收藏的开源或免费的web应用防火墙
keycloak~JWT各字段说明及扩展字段的方法
苹果业绩暴雷:iPhone卖不动了!库克感谢国人支持 要降价刺激销量?
《巫师3:狩猎》4.01版更新上线:光追性能更强 帧率又高了
美国新造车告急:造一辆亏23万 CEO深感抱歉
极氪009被吐槽像灵车、棺材 车主亲身评测:死人躺并不舒适
比亚迪又一大杀器 全新海鸥出街被拍:超个性涂装上身
快看:iPhone 12/13/14灵魂设计师离职 苹果直接取消工业设计总监职位
动态焦点:男孩为网游充值4万 家长控诉腾讯监控不力未尽义务:该不该退钱?
全球微动态丨国内油价今晚调整 或迎兔年“第一涨”:加满一箱预计多花8.5元
环球滚动:20个小猫身上笑死人的奇葩花纹:只有你想不到!
萌萌哒的兔子竟是“头号杀手”!澳大利亚曾研制病毒专杀兔兔
全球新资讯:澳大利亚搞丢一枚剧毒放射性胶囊 相关单位仅被罚款1000块:下不为例?
专家称年轻人工资低可能是能力不够引争议:企业点赞 打铁还应自身硬
世界今热点:触控体验碾压iPhone 14 Pro Max!一加Ace 2做到了
火箭弹电子版领取处>>(密码博主昵称 全部小写)
天天观点:Pandas分析泰坦尼克号生还比例
天天新资讯:图卷积的演变-从谱图卷积到GCN
.NET Core 3.1 通过 Web Service 读写 Salesforce 数据
【全球新要闻】打开它 游戏性能飙升46%!NVIDIA为啥不要呢?
每日资讯:麦当劳赢了:世界第一美食APP
即时看!地球最稀有矿石就一个标本!已知6000多种矿石就它特殊
【天天速看料】《流浪地球2》票房破30亿!下一部或两年后上映
最新消息:这两年大家都在吃瘪 结果微软闷声发大财了!全靠它
视焦点讯!Spring中Bean的生命周期
一名老了的普通程序员的未来在哪里
元宵节将至:北京周五晚高峰将达严重拥堵
焦点报道:334个小核心反超AMD!Intel下代至强“增肥”70%
出厂安卓13 三星Galaxy S23承诺四次大版本迭代:包你升级Android 17
世界热点!在欧洲大陆上奔跑的中国新能源车正越来越多!当地人慌了
当前热讯:编写干净代码的 9 条必须知道的规则
有钱玩家真多!越来越多Steam用户配置RTX 4090显卡:已超2万人
Python教程:OS与sys模块用法教程
世界看点:mybatis-plus代码生成器
女子误用八千元一斤茶叶煮茶叶蛋 以为过期:网友称这茶叶蛋真吃不起
天天观天下!专家:年轻人工资低是因为能力不够 很少有人反思这问题
全球微速讯:爱奇艺回应3台设备登录账号被封:改密码能解封 不用充值更贵会员
全球滚动:PS游戏启动失败?PS日本教你如何进行问题排查
剧版一集就被砍之后 DC电影版《沼泽怪物》物色导演
订单破5万!比亚迪腾势D9登35万以上新能源豪华MPV销量第一
环球微动态丨导演评价《狂飙》:可能是可以刻在自己墓碑上的一部戏
每日快报!12.4万的保时捷带来诸多疑问 故意营销质疑越来越多!
造车新势力第一!广汽埃安1月交付10206辆 今年冲击60万辆
天天观热点:CSS 清除浮动
今日快讯:蔚来开启降价 内部员工回应:像小鹏那样直接降太没面子
彻底不冒黑烟!沃尔沃天然气重卡发布:发动机最大500马力
世界速讯:30岁中国女子在日本买70万平小岛成岛主:永久使用权
天天资讯:体育纳入高考、鲨鱼咬人?朋友圈十大谣言出炉
环球速看:800W核弹 老外猜测RTX Titan Ada售价:2.5万元都是良心价
每日信息:程序员应该专注技术,还是优雅转管理?
环球今日报丨超越三星 中国电视品牌出货量首次登顶全球第一
天天看热讯:33款砍掉一半多!奔驰大刀阔斧改革旗下车型:不赚钱的都扔掉
环球短讯!上海动物园小老虎意外溺亡 回应:因外界人员干扰致应激反应
河南一地发现大型石墨矿:自然界最软的矿物 估算超100万吨
95比92更耐烧吗、中石化和中石油能混加吗?官方科普
当前焦点![JavaSript]闭包
即时焦点:element-ui表格展开行每次只能展开一行
阿里二面:千万级、亿级数据,如何性能优化? 教科书级 答案来了
热推荐:MyBatis的使用一(框架的搭建)
环球要闻:数字孪生|可视化图表之散点图
焦点报道:视网膜能秒击穿!网友用小米12实测新能源车激光雷达威力:相机被烧坏
天天速讯:可口可乐定制版真我10 Pro外观首曝:最具辨识度的千元机
世界滚动:《狂飙》落幕后 《三体》剧版上线超前点播:18元提前看大结局
安卓之光归来 三星对Galaxy S23系列很自信:最好的相机及游戏性能
世界今日报丨小米汽车设计泄密供应商被处罚100万!雷军:泄密员工正在处理
自动化运维:如何构建和部署前端应用
cpp简单总结
你只会用 xxl-job?一款更强大、新一代分布式任务调度框架来了,太强大了!
微动态丨可口可乐定制版真我10 Pro官宣:LCD屏 边框比iPhone 14 Pro还窄
天天快资讯丨英特尔锐炫显卡驱动更新:DirectX 9游戏性能提升超过40%
环球速递!连赢友商两代的CPU功臣退位 AMD确认5nm Zen4今年成为主力
【天天热闻】吃鱼或将再也不用挑刺了!中国科学家取得新突破:基因突变搞定
《狂飙》大结局口碑崩了!豆瓣评分跌至8.8:网友吐槽结尾仓促
多功能游戏工具箱 - Watt Toolkit V4.4
每日视讯:IOS逆向--恢复Dyld的内存加载方式
世界快讯:智能学习灯赛道竞争日趋激烈 火山引擎 VeDI 用数据技术助力打造新优势
全球微资讯!Java里面为什么搞了双重检查锁,写完这篇文章终于真相大白了
抄袭、偷票房、成本1千万争端不断!张艺谋:《满江红》是正能量传承
网易暴雪游戏退款服务爆火!排队人数超100万 你退了多少?
恒大恒驰上海公司被强执409万:累计被执行2.8亿
天天热头条丨微信多开工具,微信消息防撤回、QQ消息防撤回、Tim消息防撤回,不错过每一条消息
京东PLUS会员与爱奇艺、喜马拉雅联名卡宣布调价:都涨了
视焦点讯!能怎样?韩数万用户上诉苹果:故意降低旧款iPhone性能让换新败诉
每日观察!马斯克测试推特“仅粉丝可见”遭群嘲:懂的工程师都被裁了?
每日消息!董明珠造车路又遭一击!海南三亚67辆格力钛新能源大巴起火被烧
焦点简讯:限制480P投屏被7年老粉起诉:律师称爱奇艺大概率会败诉
网友囤1000片退烧药全砸手里了被点赞:囤N95口罩血氧仪价格也都惨了