作者:微信小助手
<section style="box-sizing: border-box;"> <section class="V5" style="box-sizing: border-box;" powered-by="xiumi.us"> <section style="margin-top: 10px;margin-bottom: 10px;box-sizing: border-box;"> <section style="padding-top: 10px;padding-right: 10px;padding-left: 10px;box-sizing: border-box;background-color: rgb(239, 239, 239);"> <span style="display: inline-block;width: 5%;line-height: 0.8;font-weight: bolder;font-size: 48px;box-sizing: border-box;"> <section style="box-sizing: border-box;"> “ </section></span> <section style="display: inline-block;vertical-align: top;float: right;width: 90%;line-height: 1.5;font-size: 15px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="box-sizing: border-box;"><span style="letter-spacing: 1px;">对于锁大家肯定不会陌生,在 Java 中 synchronized 关键字和 ReentrantLock 可重入锁在我们的代码中是经常见的,一般我们用其在多线程环境中控制对资源的并发访问。</span></p> </section> <section style="clear: both;box-sizing: border-box;"></section> </section> </section> </section> </section> <p style="line-height: 1.75em;"><br></p> <p style="text-align: center;margin-left: 8px;margin-right: 8px;margin-bottom: 5px;"><img class="" data-copyright="0" data-ratio="0.5038639876352395" data-s="300,640" src="/upload/1382e2d2be59a4d1d456404e5a642ad3.png" data-type="png" data-w="647" style=""></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">但是随着分布式的快速发展,本地的加锁往往不能满足我们的需要,在我们的分布式环境中上面加锁的方法就会失去作用。</span></p> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">于是人们为了在分布式环境中也能实现本地锁的效果,也是纷纷各出其招,今天让我们来聊一聊一般分布式锁实现的套路。</span></p> <p style="line-height: normal;"><br></p> <section style="box-sizing: border-box;"> <section class="V5" style="box-sizing: border-box;" powered-by="xiumi.us"> <section style="border-bottom-width: 1px;border-bottom-style: solid;border-bottom-color: black;margin-top: 0.5em;margin-bottom: 0.5em;line-height: 1.2;box-sizing: border-box;"> <section style="display: inline-block;border-bottom-width: 6px;border-bottom-style: solid;border-color: rgb(89, 89, 89);margin-bottom: -1px;font-size: 20px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="box-sizing: border-box;">为何需要分布式锁</p> </section> </section> </section> </section> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">Martin Kleppmann 是英国剑桥大学的分布式系统的研究员,之前和 Redis 之父 Antirez 进行过关于 RedLock(红锁,后续有讲到)是否安全的激烈讨论。</span></p> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">Martin 认为一般我们使用分布式锁有两个场景:</span></p> <ul class=" list-paddingleft-2" style="margin-left: 8px;margin-right: 8px;"> <li><p style="text-align: justify;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">效率:</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">使用分布式锁可以避免不同节点重复相同的工作,这些工作会浪费资源。比如用户付了钱之后有可能不同节点会发出多封短信。</span></p></li> <li><p style="text-align: justify;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">正确性:</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">加分布式锁同样可以避免破坏正确性的发生,如果两个节点在同一条数据上面操作,比如多个节点机器对同一个订单操作不同的流程有可能会导致该笔订单最后状态出现错误,造成损失。</span></p></li> </ul> <h2 style="line-height: normal;"><br></h2> <section style="box-sizing: border-box;"> <section class="V5" style="box-sizing: border-box;" powered-by="xiumi.us"> <section style="border-bottom-width: 1px;border-bottom-style: solid;border-bottom-color: black;margin-top: 0.5em;margin-bottom: 0.5em;line-height: 1.2;box-sizing: border-box;"> <section style="display: inline-block;border-bottom-width: 6px;border-bottom-style: solid;border-color: rgb(89, 89, 89);margin-bottom: -1px;font-size: 20px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="box-sizing: border-box;">分布式锁的一些特点</p> </section> </section> </section> </section> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">当我们确定了在不同节点上需要分布式锁,那么我们需要了解分布式锁到底应该有哪些特点?</span></p> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">分布式锁的特点如下:</span></p> <ul class=" list-paddingleft-2" style="margin-left: 8px;margin-right: 8px;"> <li><p style="text-align: justify;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">互斥性:</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">和我们本地锁一样互斥性是最基本,但是分布式锁需要保证在不同节点的不同线程的互斥。</span></p></li> <li><p style="text-align: justify;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">可重入性:</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">同一个节点上的同一个线程如果获取了锁之后那么也可以再次获取这个锁。</span></p></li> <li><p style="text-align: justify;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">锁超时:</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">和本地锁一样支持锁超时,防止死锁。</span></p></li> <li><p style="text-align: justify;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">高效,高可用:</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">加锁和解锁需要高效,同时也需要保证高可用防止分布式锁失效,可以增加降级。</span></p></li> <li><p style="text-align: justify;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">支持阻塞和非阻塞:</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">和 ReentrantLock 一样支持 lock 和 trylock 以及 tryLock(long timeOut)。</span></p></li> <li><p style="text-align: justify;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">支持公平锁和非公平锁(可选):</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">公平锁的意思是按照请求加锁的顺序获得锁,非公平锁就相反是无序的。这个一般来说实现的比较少。</span></p></li> </ul> <h2 style="line-height: normal;"><br></h2> <section style="box-sizing: border-box;"> <section class="V5" style="box-sizing: border-box;" powered-by="xiumi.us"> <section style="border-bottom-width: 1px;border-bottom-style: solid;border-bottom-color: black;margin-top: 0.5em;margin-bottom: 0.5em;line-height: 1.2;box-sizing: border-box;"> <section style="display: inline-block;border-bottom-width: 6px;border-bottom-style: solid;border-color: rgb(89, 89, 89);margin-bottom: -1px;font-size: 20px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="box-sizing: border-box;">常见的分布式锁</p> </section> </section> </section> </section> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">我们了解了一些特点之后,我们一般实现分布式锁有以下几个方式:</span></p> <ul class=" list-paddingleft-2" style="margin-left: 8px;margin-right: 8px;"> <li><p style="text-align: justify;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">MySQL</span></strong></p></li> <li><p style="text-align: justify;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">ZK</span></strong></p></li> <li><p style="text-align: justify;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">Redis</span></strong></p></li> <li><p style="text-align: justify;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">自研分布式锁:如谷歌的 Chubby。</span></strong></p></li> </ul> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">下面分开介绍一下这些分布式锁的实现原理。</span></p> <p style="line-height: normal;"><br></p> <section style="box-sizing: border-box;"> <section class="V5" style="box-sizing: border-box;" powered-by="xiumi.us"> <section style="margin-top: 10px;margin-bottom: 10px;box-sizing: border-box;"> <section style="width: 0.6em;display: inline-block;vertical-align: middle;box-sizing: border-box;"> <span style="width: 0.6em;height: 0.6em;display: block;opacity: 0.2;box-sizing: border-box;background-color: rgb(89, 89, 89);"></span> <strong><span style="width: 0.6em;height: 0.6em;display: block;opacity: 0.6;margin-top: 2px;margin-bottom: 2px;box-sizing: border-box;background-color: rgb(89, 89, 89);"></span> <span style="width: 0.6em;height: 0.6em;display: block;opacity: 1;box-sizing: border-box;background-color: rgb(89, 89, 89);"></span> </strong> </section> <section style="display: inline-block;vertical-align: middle;font-size: 18px;padding-left: 5px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="box-sizing: border-box;"><strong>MySQL </strong></p> </section> </section> </section> </section> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">首先来说一下 MySQL 分布式锁的实现原理,相对来说这个比较容易理解,毕竟数据库和我们开发人员在平时的开发中息息相关。</span></p> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">对于分布式锁我们可以创建一个锁表:</span></p> <p style="text-align: center;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><img class="" data-copyright="0" data-ratio="0.3832046332046332" data-s="300,640" src="/upload/c813eb5f4c73cc98e7dc9a1400bac6a8.png" data-type="png" data-w="1036" style=""></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">前面我们所说的 lock(),trylock(long timeout),trylock() 这几个方法可以用下面的伪代码实现。</span></p> <p style="line-height: normal;"><br></p> <h2 style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 16px;"><strong><span style="color: rgb(89, 89, 89);letter-spacing: 1px;">lock()</span></strong></span></h2> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">lock 一般是阻塞式的获取锁,意思就是不获取到锁誓不罢休,那么我们可以写一个死循环来执行其操作
作者:じ☆ve宝贝
##11.组合模式(Composite) 组合模式有时又叫部分-整体模式,在处理类似树形结构的问题时比较方便,看看关系图:  直接来看代码: ``` public class TreeNode { private String name; private TreeNode parent; private Vector<TreeNode> children = new Vector<TreeNode>(); public TreeNode(String name){ this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } public TreeNode getParent() { return parent; } public void setParent(TreeNode parent) { this.parent = parent; } //添加孩子节点 public void add(TreeNode node){ children.add(node); } //删除孩子节点 public void remove(TreeNode node){ children.remove(node); } //取得孩子节点 public Enumeration<TreeNode> getChildren(){ return children.elements(); } } ``` 测试类: ``` public class Tree { TreeNode root = null; public Tree(String name) { root = new TreeNode(name); } public static void main(String[] args) { Tree tree = new Tree("A"); TreeNode nodeB = new TreeNode("B"); TreeNode nodeC = new TreeNode("C"); nodeB.add(nodeC); tree.root.add(nodeB); System.out.println("build the tree finished!"); } } ``` 使用场景:将多个对象组合在一起进行操作,常用于表示树形结构中,例如二叉树等。
作者:微信小助手
<section style="box-sizing: border-box;"> <section class="V5" style="box-sizing: border-box;" powered-by="xiumi.us"> <section style="margin-top: 10px;margin-bottom: 10px;box-sizing: border-box;"> <section style="padding-top: 10px;padding-right: 10px;padding-left: 10px;box-sizing: border-box;background-color: rgb(239, 239, 239);"> <span style="display: inline-block;width: 5%;line-height: 0.8;font-weight: bolder;font-size: 48px;box-sizing: border-box;"> <section style="box-sizing: border-box;"> “ </section></span> <section style="display: inline-block;vertical-align: top;float: right;width: 90%;line-height: 1.5;font-size: 15px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="box-sizing: border-box;"><span style="letter-spacing: 1px;">现在面试,一般都会聊聊分布式系统这块的东西。通常面试官都会从服务框架(Spring Cloud、Dubbo)聊起,一路聊到分布式事务、分布式锁、ZooKeeper 等知识。</span></p> </section> <section style="clear: both;box-sizing: border-box;"></section> </section> </section> </section> </section> <p style="line-height: 1.75em;"><br></p> <p style="text-align: center;margin-left: 8px;margin-right: 8px;margin-bottom: 5px;"><img class="" data-copyright="0" data-ratio="0.5631399317406144" data-s="300,640" src="/upload/ce3534c84ec8dc81d7c6b2d429f6d49.png" data-type="png" data-w="586" style=""></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">所以咱们就来聊聊分布式锁这块的知识,先具体的来看看 Redis 分布式锁的实现原理。</span></p> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">说实话,如果在公司里落地生产环境用分布式锁的时候,一定是会用开源类库的,比如 Redis 分布式锁,一般就是用 Redisson 框架就好了,非常的简便易用。</span></p> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">大家如果有兴趣,可以去 Redisson 的官网,看看如何在项目中引入 Redisson 的依赖,然后基于 Redis 实现分布式锁的加锁与释放锁。</span></p> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">下面给大家看一段简单的使用代码片段,先直观的感受一下:</span></p> <p style="text-align: center;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><img class="" data-copyright="0" data-ratio="0.21476510067114093" data-s="300,640" src="/upload/ddb2da3be2555d75aac1ff2ec248cc65.png" data-type="png" data-w="447" style=""></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">怎么样,上面那段代码,是不是感觉简单的不行!此外,人家还支持 Redis 单实例、Redis 哨兵、Redis Cluster、redis master-slave 等各种部署架构,都可以给你完美实现。</span></p> <p style="line-height: normal;"><br></p> <section style="box-sizing: border-box;"> <section class="V5" style="box-sizing: border-box;" powered-by="xiumi.us"> <section style="border-bottom-width: 1px;border-bottom-style: solid;border-bottom-color: black;margin-top: 0.5em;margin-bottom: 0.5em;line-height: 1.2;box-sizing: border-box;"> <section style="display: inline-block;border-bottom-width: 6px;border-bottom-style: solid;border-color: rgb(89, 89, 89);margin-bottom: -1px;font-size: 20px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="box-sizing: border-box;">Redisson 实现 Redis 分布式锁的底层原理</p> </section> </section> </section> </section> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">好的,接下来就通过一张手绘图,给大家说说 Redisson 这个开源框架对 Redis 分布式锁的实现原理。</span></p> <p style="text-align: center;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><img class="" data-copyright="0" data-ratio="0.5182815356489945" data-s="300,640" src="/upload/a930e2c4f0ddeeaf2a58b432c1a48c9d.png" data-type="png" data-w="1094" style=""></p> <section style="box-sizing: border-box;"> <section class="V5" style="box-sizing: border-box;" powered-by="xiumi.us"> <section style="margin-top: 10px;margin-bottom: 10px;box-sizing: border-box;"> <section style="width: 0.6em;display: inline-block;vertical-align: middle;box-sizing: border-box;"> <span style="width: 0.6em;height: 0.6em;display: block;opacity: 0.2;box-sizing: border-box;background-color: rgb(89, 89, 89);"></span> <span style="width: 0.6em;height: 0.6em;display: block;opacity: 0.6;margin-top: 2px;margin-bottom: 2px;box-sizing: border-box;background-color: rgb(89, 89, 89);"></span> <span style="width: 0.6em;height: 0.6em;display: block;opacity: 1;box-sizing: border-box;background-color: rgb(89, 89, 89);"></span> </section> <section style="display: inline-block;vertical-align: middle;font-size: 18px;padding-left: 5px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="box-sizing: border-box;"><strong>加锁机制</strong></p> </section> </section> </section> </section> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">咱们来看上面那张图,现在某个客户端要加锁。如果该客户端面对的是一个 Redis Cluster 集群,他首先会根据 Hash 节点选择一台机器。</span></p> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">这里注意,仅仅只是选择一台机器!这点很关键!紧接着,就会发送一段 Lua 脚本到 Redis 上,那段 Lua 脚本如下所示:</span></p> <p style="text-align: center;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><img class="" data-copyright="0" data-ratio="0.5086071987480438" data-s="300,640" src="/upload/5a017e82b8d92fb8ddf09209e67bc501.png" data-type="png" data-w="639" style=""></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">为啥要用 Lua 脚本呢?因为一大坨复杂的业务逻辑,可以通过封装在 Lua 脚本中发送给 Redis,保证这段复杂业务逻辑执行的原子性。</span></p> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">那么,这段 Lua 脚本是什么意思呢?这里 KEYS[1] 代表的是你加锁的那个 Key,比如说:RLock lock = redisson.getLock("myLock");这里你自己设置了加锁的那个锁 Key 就是“myLock”。</span></p> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">ARGV[1] 代表的就是锁 Key 的默认生存时间,默认 30 秒。ARGV[2] 代表的是加锁的客户端的 ID,类似于下面这样:8743c9c0-0795-4907-87fd-6c719a6b4586:1。</span></p> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">给大家解释一下,第一段 if 判断语句,就是用“exists myLock”命令判断一下,如果你要加锁的那个锁 Key 不存在的话,你就进行加锁。如何加锁呢?很简单,用下面的命令:hset myLock。</span></p> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">8743c9c0-0795-4907-87fd-6c719a6b4586:1 1,通过这个命令设置一个 Hash 数据结构,这行命令执行后,会出现一个类似下面的数据结构:</span></p> <p style="text-align: center;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><img class="" data-copyright="0" data-ratio="0.23552123552123552" data-s="300,640" src="/upload/46785937774248196117514696c01fe.png" data-type="png" data-w="518" style=""></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">上述就代表“8743c9c0-0795-4907-87fd-6c719a6b4586:1”这个客户端对“myLock”这个锁 Key 完成了加锁。</span></p> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">接着会执行“pexpire myLock 30000”命令,设置 myLock 这个锁 Key 的生存时间是 30 秒。好了,到此为止,加锁完成了。</span></p> <p style="line-height: normal;"><br></p> <section style="box-sizing: border-box;"> <section class="V5" style="box-sizing: border-box;" powered-by="xiumi.us"> <section style="margin-top: 10px;margin-bottom: 10px;box-sizing: border-box;"> <section style="width: 0.6em;display: inline-block;vertical-align: middle;box-sizing: border-box;"> <span style="width: 0.6em;height: 0.6em;display: block;opacity: 0.2;box-sizing: border-box;background-color: rgb(89, 89, 89);"></span> <span style="width: 0.6em;height: 0.6em;display: block;opacity: 0.6;margin-top: 2px;margin-bottom: 2px;box-sizing: border-box;background-color: rgb(89, 89, 89);"></span> <span style="width: 0.6em;height: 0.6em;display: block;opacity: 1;box-sizing: border-box;background-color: rgb(89, 89, 89);"></span> </section> <section style="display: inline-block;vertical-align: middle;font-size: 18px;padding-left: 5px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="box-sizing: border-box;"><strong>锁互斥机制</strong></p> </section> </section> </section> </section> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">那么在这个时候,如果客户端 2 来尝试加锁,执行了同样的一段 Lua 脚本,会咋样呢?</span></p> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">很简单,第一个 if 判断会执行“exists myLock”,发现 myLock 这个锁 Key 已经存在了。</span></p> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">接着第二个 if 判断,判断一下,myLock 锁 Key 的 Hash 数据结构中,是否包含客户端 2 的 ID,但是明显不是的,因为那里包含的是客户端 1 的 ID。</span></p> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">所以,客户端 2 会获取到 pttl myLock 返回的一个数字,这个数字代表了 myLock 这个锁 Key 的剩余生存时间。</span></p> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">比如还剩 15000 毫秒的生存时间。此时客户端 2 会进入一个 while 循环,不停的尝试加锁。</span></p> <p style="line-height: normal;"><br></p> <section style="box-sizing: border-box;"> <section class="V5" style="box-sizing: border-box;" powered-by="xiumi.us"> <section style="margin-top: 10px;margin-bottom: 10px;box-sizing: border-box;"> <section style="width: 0.6em;display: inline-block;vertical-align: middle;box-sizing: border-box;"> <span style="width: 0.6em;height: 0.6em;display: block;opacity: 0.2;box-sizing: border-box;background-color: rgb(89, 89, 89);"></span> <strong><span style="width: 0.6em;height: 0.6em;display: block;opacity: 0.6;margin-top: 2px;margin-bottom: 2px;box-sizing: border-box;background-color: rgb(89, 89, 89);"></span> <span style="width: 0.6em;height: 0.6em;display: block;opacity: 1;box-sizing: border-box;background-color: rgb(89, 89, 89);"></span> </strong> </section> <section style="display: inline-block;vertical-align: middle;font-size: 18px;padding-left: 5px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="box-sizing: border-box;"><strong>watch dog 自动延期机制</strong></p> </section> </section> </section> </section> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">客户端 1 加锁的锁 Key 默认生存时间才 30 秒,如果超过了 30 秒,客户端 1 还想一直持有这把锁,怎么办呢?</span></p> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">简单!只要客户端 1 一旦加锁成功,就会启动一个 watch dog 看门狗,他是一个后台线程,会每隔 10 秒检查一下,如果客户端 1 还持有锁 Key,那么就会不断的延长锁 Key 的生存时间。</span></p> <p style="line-height: normal;"><br></p> <section style="box-sizing: border-box;"> <section class="V5" style="box-sizing: border-box;" powered-by="xiumi.us"> <section style="margin-top: 10px;margin-bottom: 10px;box-sizing: border-box;"> <section style="width: 0.6em;display: inline-block;vertical-align: middle;box-sizing: border-box;"> <span style="width: 0.6em;height: 0.6em;display: block;opacity: 0.2;box-sizing: border-box;background-color: rgb(89, 89, 89);"></span> <strong><span style="width: 0.6em;height: 0.6em;display: block;opacity: 0.6;margin-top: 2px;margin-bottom: 2px;box-sizing: border-box;background-color: rgb(89, 89, 89);"></span> <span style="width: 0.6em;height: 0.6em;display: block;opacity: 1;box-sizing: border-box;background-color: rgb(89, 89, 89);"></span> </strong> </section> <section style="display: inline-block;vertical-align: middle;font-size: 18px;padding-left: 5px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="box-sizing: border-box;"><strong>可重入加锁机制</strong></p> </section> </section> </section> </section> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">那如果客户端 1 都已经持有了这把锁了,结果可重入的加锁会怎么样呢?比如下面这种代码:</span></p> <p style="text-align: center;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><img class="" data-copyright="0" data-ratio="0.6801801801801802" data-s="300,640" src="/upload/c6a07949839edfed3658b361c71ef749.png" data-type="png" data-w="444" style=""></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">这时我们来分析一下上面那段 Lua 脚本。第一个if判断肯定不成立,“exists myLock”会显示锁 Key 已经存在了。</span></p> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">第二个 if 判断会成立,因为 myLock 的 Hash 数据结构中包含的那个 ID,就是客户端 1 的那个 ID,也就是“8743c9c0-0795-4907-87fd-6c719a6b4586:1”。</span></p> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">此时就会执行可重入加锁的逻辑,他会用:</span><span style="color: rgb(89, 89, 89);font-size: 15px;letter-spacing: 1px;line-height: 1.75em;">incrby myLock 8743c
作者:微信小助手
<section class="xmtedi
作者:微信小助手
<section style="box-sizing: border-box;"> <section class="Powered-by-XIUMI V5" style="box-sizing: border-box;" powered-by="xiumi.us"> <section class="" style="margin-top: 10px;margin-bottom: 10px;box-sizing: border-box;"> <section class="" style="padding-top: 10px;padding-right: 10px;padding-left: 10px;box-sizing: border-box;background-color: rgb(239, 239, 239);"> <span style="display: inline-block;width: 5%;line-height: 0.8;font-weight: bolder;font-size: 48px;box-sizing: border-box;" class=""> <section style="box-sizing: border-box;"> “ </section></span> <section class="" style="display: inline-block;vertical-align: top;float: right;width: 90%;line-height: 1.5;font-size: 15px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="box-sizing: border-box;"><span style="letter-spacing: 1px;">在前面的两篇文章中,分别介绍了 <a href="http://mp.weixin.qq.com/s?__biz=MjM5ODI5Njc2MA==&mid=2655816024&idx=1&sn=f4ee4afce1055d9f34c61a8a9d95918a&chksm=bd74c48f8a034d99ffb4291e78a6b0c6654a8ab74d83bbf6739bc4ec20ce7ae1165d19e79d44&scene=21#wechat_redirect" target="_blank">Redis 的内存模型</a>和 <a href="http://mp.weixin.qq.com/s?__biz=MjM5ODI5Njc2MA==&mid=2655817009&idx=1&sn=1b28414b42179d506d4216112dfc36c7&chksm=bd74c0e68a0349f0506ea75dccad96e4c302764b45e2b5c6869d5d1e5d1fd3bb5c4931caf2a6&scene=21#wechat_redirect" target="_blank">Redis 的持久化</a>,今天我们来深入学习 Redis 的主从复制。</span></p> </section> <section style="clear: both;box-sizing: border-box;"></section> </section> </section> </section> </section> <p style="line-height: 1.75em;"><br></p> <p style="text-align: center;margin-left: 8px;margin-right: 8px;margin-bottom: 5px;"><img class="" data-copyright="0" data-ratio="0.554006968641115" data-s="300,640" src="/upload/5ac61f5b294a85f5ea587740c0f925b3.png" data-type="png" data-w="574" style=""></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">在 Redis 的持久化中曾提到,Redis 高可用的方案包括持久化、主从复制(及读写分离)、哨兵和集群。</span></p> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">其中持久化侧重解决的是 Redis 数据的单机备份问题(从内存到硬盘的备份);而主从复制则侧重解决数据的多机热备。此外,主从复制还可以实现负载均衡和故障恢复。</span></p> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">我将从以下几个部分详细介绍 Redis 主从复制的方方面面:</span></p> <ul class=" list-paddingleft-2" style="list-style-type: disc;"> <li><p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">主从复制概述</span></strong></p></li> <li><p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">如何使用主从复制</span></strong></p></li> <li><p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">主从复制的实现原理</span></strong></p></li> <li><p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">应用中的问题</span></strong></p></li> <li><p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">总结</span></strong></p></li> </ul> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;"></span></p> <section style="box-sizing: border-box;"> <section class="Powered-by-XIUMI V5" style="box-sizing: border-box;" powered-by="xiumi.us"> <section class="" style="border-bottom-width: 1px;border-bottom-style: solid;border-bottom-color: black;margin-top: 0.5em;margin-bottom: 0.5em;line-height: 1.2;box-sizing: border-box;"> <section class="" style="display: inline-block;border-bottom-width: 6px;border-bottom-style: solid;border-color: rgb(89, 89, 89);margin-bottom: -1px;font-size: 20px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="box-sizing: border-box;">主从复制概述</p> </section> </section> </section> </section> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">主从复制,是指将一台 Redis 服务器的数据,复制到其他的 Redis 服务器。前者称为主节点(master),后者称为从节点(slave);数据的复制是单向的,只能由主节点到从节点。</span></p> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">默认情况下,每台 Redis 服务器都是主节点;且一个主节点可以有多个从节点(或没有从节点),但一个从节点只能有一个主节点。</span></p> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="color: rgb(71, 193, 168);"><span style="font-size: 15px;letter-spacing: 1px;">主从复制的作用</span><span style="font-size: 15px;letter-spacing: 1px;line-height: 1.75em;">主要包括:</span></span></p> <ul class=" list-paddingleft-2" style="list-style-type: disc;"> <li><p style="text-align: justify;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">数据冗余:</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式。</span></p></li> <li><p style="text-align: justify;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">故障恢复:</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复;实际上是一种服务的冗余。</span></p></li> <li><p style="text-align: justify;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">负载均衡:</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">在主从复制的基础上,配合读写分离,可以由主节点提供写服务,由从节点提供读服务(即写 Redis 数据时应用连接主节点,读 Redis 数据时应用连接从节点),分担服务器负载;尤其是在写少读多的场景下,通过多个从节点分担读负载,可以大大提高 Redis 服务器的并发量。</span></p></li> <li><p style="text-align: justify;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">高可用基石:</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">除了上述作用以外,主从复制还是哨兵和集群能够实施的基础,因此说主从复制是 Redis 高可用的基础。</span></p></li> </ul> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;"></span></p> <section style="box-sizing: border-box;"> <section class="Powered-by-XIUMI V5" style="box-sizing: border-box;" powered-by="xiumi.us"> <section class="" style="border-bottom-width: 1px;border-bottom-style: solid;border-bottom-color: black;margin-top: 0.5em;margin-bottom: 0.5em;line-height: 1.2;box-sizing: border-box;"> <section class="" style="display: inline-block;border-bottom-width: 6px;border-bottom-style: solid;border-color: rgb(89, 89, 89);margin-bottom: -1px;font-size: 20px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="box-sizing: border-box;">如何使用主从复制</p> </section> </section> </section> </section> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">为了更直观的理解主从复制,在介绍其内部原理之前,先说明我们需要如何操作才能开启主从复制。</span></p> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;"></span></p> <section style="box-sizing: border-box;"> <section class="Powered-by-XIUMI V5" style="box-sizing: border-box;" powered-by="xiumi.us"> <section class="" style="margin-top: 10px;margin-bottom: 10px;box-sizing: border-box;"> <section class="" style="width: 0.6em;display: inline-block;vertical-align: middle;box-sizing: border-box;"> <span style="width: 0.6em;height: 0.6em;display: block;opacity: 0.2;box-sizing: border-box;background-color: rgb(89, 89, 89);"></span> <strong><span style="width: 0.6em;height: 0.6em;display: block;opacity: 0.6;margin-top: 2px;margin-bottom: 2px;box-sizing: border-box;background-color: rgb(89, 89, 89);"></span> <span style="width: 0.6em;height: 0.6em;display: block;opacity: 1;box-sizing: border-box;background-color: rgb(89, 89, 89);"></span> </strong> </section> <section class="" style="display: inline-block;vertical-align: middle;font-size: 18px;padding-left: 5px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="box-sizing: border-box;"><strong>建立复制</strong></p> </section> </section> </section> </section> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">需要注意,主从复制的开启,完全是在从节点发起的;不需要我们在主节点做任何事情。</span></p> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">从节点开启主从复制,有 3 种方式:</span></p> <ul class=" list-paddingleft-2" style="list-style-type: disc;"> <li><p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="color: rgb(89, 89, 89);font-size: 15px;letter-spacing: 1px;line-height: 1.75em;">在从服务器的配置文件中加入:slaveof <masterip> <masterport>。</span></p></li> <li><p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="color: rgb(89, 89, 89);font-size: 15px;letter-spacing: 1px;line-height: 1.75em;">redis-server 启动命令后加入 --slaveof <masterip> <masterport>。</span></p></li> <li><p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="color: rgb(89, 89, 89);font-size: 15px;letter-spacing: 1px;line-height: 1.75em;">Redis 服务器启动后,直接通过客户端执行命令:slaveof <masterip> <masterport>,则该 Redis 实例成为从节点。</span></p></li> </ul> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">上述 3 种方式是等效的,下面以客户端命令的方式为例,看一下当执行了 slaveof 后,Redis 主节点和从节点的变化。</span></p> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;"></span></p> <section style="box-sizing: border-box;"> <section class="Powered-by-XIUMI V5" style="box-sizing: border-box;" powered-by="xiumi.us"> <section class="" style="margin-top: 10px;margin-bottom: 10px;box-sizing: border-box;"> <section class="" style="width: 0.6em;display: inline-block;vertical-align: middle;box-sizing: border-box;"> <span style="width: 0.6em;height: 0.6em;display: block;opacity: 0.2;box-sizing: border-box;background-color: rgb(89, 89, 89);"></span> <strong><span style="width: 0.6em;height: 0.6em;display: block;opacity: 0.6;margin-top: 2px;margin-bottom: 2px;box-sizing: border-box;background-color: rgb(89, 89, 89);"></span> <span style="width: 0.6em;height: 0.6em;display: block;opacity: 1;box-sizing: border-box;background-color: rgb(89, 89, 89);"></span> </strong> </section> <section class="" style="display: inline-block;vertical-align: middle;font-size: 18px;padding-left: 5px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="box-sizing: border-box;"><strong>实例</strong></p> </section> </section> </section> </section> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">准备工作:</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">启动两个节点。为了</span><span style="color: rgb(89, 89, 89);font-size: 15px;letter-spacing: 1px;line-height: 1.75em;">方便起见,实验所使用的主从节点是在一台机器上的不同 Redis 实例。</span></p> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><span style="color: rgb(89, 89, 89);font-size: 15px;letter-spacing: 1px;line-height: 1.75em;">其中主节点监听 6379 端口,从节点监听 6380 端口;从节点监听的端口号可以在配置文件中修改:</span></p> <p style="text-align: center;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><img class="" data-ratio="0.10492505353319058" src="/upload/60f6f62bee2f89618fd36bfbcaf6c6f0.png" data-type="png" data-w="467" style="box-sizing: border-box !important;word-wrap: break-word !important;width: auto !important;visibility: visible !important;"></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">启动后可以看到:</span></p> <p style="text-align: center;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><img class="" data-ratio="0.10830324909747292" src="/upload/8a691b375f0d337babe23e6367b94045.png" data-type="png" data-w="554" style="box-sizing: border-box !important;word-wrap: break-word !important;width: auto !important;visibility: visible !important;"></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">两个 Redis 节点启动后(分别称为6379节点和6380节点),默认都是主节点。</span></p> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">建立复制:</span></strong><span style="color: rgb(89, 89, 89);font-size: 15px;letter-spacing: 1px;line-height: 1.75em;">此时在 6380 节点执行 slaveof 命令,使之变为从节点。</span></p> <p style="text-align: center;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><img class="" data-ratio="0.16666666666666666" src="/upload/ded51e25d51a53669b146ee9d609d4ac.png" data-type="png" data-w="312" style="box-sizing: border-box !important;word-wrap: break-word !important;width: auto !important;visibility: visible !important;"></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">观察效果:</span></strong><span style="color: rgb(89, 89, 89);font-size: 15px;letter-spacing: 1px;line-height: 1.75em;">下面验证一下,在主从复制建立后,主节点的数据会复制到从节点中。</span></p> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">首先在从节点查询一个不存在的 key:</span></p> <p style="text-align: center;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><img class="" data-ratio="0.17117117117117117" src="/upload/54f94c4f7634408fc16c8869328a1f1b.png" data-type="png" data-w="222" style="box-sizing: border-box !important;word-wrap: break-word !important;width: auto !important;visibility: visible !important;"></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">然后在主节点中增加这个 key:</span></p> <p style="text-align: center;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><img class="" data-ratio="0.1282051282051282" src="/upload/39403ea927bbcf3bfb92aab4f8114a44.png" data-type="png" data-w="273" style="box-sizing: border-box !important;word-wrap: break-word !important;width: auto !important;visibility: visible !important;"></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><span style="font-size: 15px;letter-spacing: 1px;color: rgb(89, 89, 89);">此时在从节点中再次查询这个 key,会发现主节点的操作已经同步至从节点:</span></p> <p style="text-align: center;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><img class="" data-ratio="0.17289719626168223" src="/upload/44a517aa67992b9a03afb47d393672d7.png" data-type="png" data-w="214" style="box-sizing: border-box !important;word-wrap: break-word !important;width: auto !important;visibility: visible !important;"></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">然后在主节点删除这个 key:</span></p> <p style="text-align: center;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><img class="" data-ratio="0.18226600985221675" src="/upload/3e468e1e160051b3298c4e9cb22b885c.png" data-type="png" data-w="203" style="box-sizing: border-box !important;word-wrap: break-word !important;width: auto !important;visibility: visible !important;"></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><span style="font-size: 15px;letter-spacing: 1px;color: rgb(89, 89, 89);">此时在从节点中再次查询这个 key,会发现主节点的操作已经同步至从节点:</span></p> <p style="text-align: center;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><img class="" data-ratio="0.17703349282296652" src="/upload/5fa7d4d028d55d90ece6c65ca8ab452e.png" data-type="png" data-w="209" style="box-sizing: border-box !important;word-wrap: break-word !important;width: auto !important;visibility: visible !important;"></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;"></span></p> <section style="box-sizing: border-box;"> <section class="Powered-by-XIUMI V5" style="box-sizing: border-box;" powered-by="xiumi.us"> <section class="" style="margin-top: 10px;margin-bottom: 10px;box-sizing: border-box;"> <section class="" style="width: 0.6em;display: inline-block;vertical-align: middle;box-sizing: border-box;"> <span style="width: 0.6em;height: 0.6em;display: block;opacity: 0.2;box-sizing: border-box;background-color: rgb(89, 89, 89);"></span> <strong><span style="width: 0.6em;height: 0.6em;display: block;opacity: 0.6;margin-top: 2px;margin-bottom: 2px;box-sizing: border-box;background-color: rgb(89, 89, 89);"></span> <span style="width: 0.6em;height: 0.6em;display: block;opacity: 1;box-sizing: border-box;background-color: rgb(89, 89, 89);"></span> </strong> </section> <section class="" style="display: inline-block;vertical-align: middle;font-size: 18px;padding-left: 5px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="box-sizing: border-box;"><strong>断开复制</strong></p> </section> </section> </section> </section> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">通过 slaveof <masterip> <masterport> 命令建立主从复制关系以后,可以通过 slaveof no one 断开。</span></p> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">需要注意的是,从节点断开复制后,不会删除已有的数据,只是不再接受主节点新的数据变化。</span></p> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">从节点执行 slaveof no one 后,打印日志如下图所示;可以看出断开复制后,从节点又变回为主节点。</span></p> <p style="text-align: center;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><img class="" data-ratio="0.148014440433213" src="/upload/447af8486e631ecd7650d9d130228359.png" data-type="png" data-w="554" style="box-sizing: border-box !important;word-wrap: break-word !important;width: auto !important;visibility: visible !important;"></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">主节点打印日志如下:</span></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><img class="" data-ratio="0.039711191335740074" src="/upload/645f0d603a209104413e81757b67f345.png" data-type="png" data-w="554" style="box-sizing: border-box !important;word-wrap: break-word !important;width: auto !important;visibility: visible !important;"></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;"></span></p> <section style="box-sizing: border-box;"> <section class="Powered-by-XIUMI V5" style="box-sizing: border-box;" powered-by="xiumi.us"> <section class="" style="border-bottom-width: 1px;border-bottom-style: solid;border-bottom-color: black;margin-top: 0.5em;margin-bottom: 0.5em;line-height: 1.2;box-sizing: border-box;"> <section class="" style="display: inline-block;border-bottom-width: 6px;border-bottom-style: solid;border-color: rgb(89, 89, 89);margin-bottom: -1px;font-size: 20px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="box-sizing: border-box;">主从复制的实现原理</p> </section> </section> </section> </section> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">上面一节中,我们介绍了如何操作可以建立主从关系;本小节将介绍主从复制的实现原理。</span></p> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">主从复制过程大体可以分为 3 个阶段:</span></p> <ul class=" list-paddingleft-2" style="list-style-type: disc;"> <li><p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">连接建立阶段(即准备阶段)</span></strong></p></li> <li><p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">数据同步阶段</span></strong></p></li> <li><p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">命令传播阶段</span></strong></p></li> </ul> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;"></span></p> <section style="box-sizing: border-box;"> <section class="Powered-by-XIUMI V5" style="box-sizing: border-box;" powered-by="xiumi.us"> <section class="" style="margin-top: 10px;margin-bottom: 10px;box-sizing: border-box;"> <section class="" style="width: 0.6em;display: inline-block;vertical-align: middle;box-sizing: border-box;"> <span style="width: 0.6em;height: 0.6em;display: block;opacity: 0.2;box-sizing: border-box;background-color: rgb(89, 89, 89);"></span> <strong><span style="width: 0.6em;height: 0.6em;display: block;opacity: 0.6;margin-top: 2px;margin-bottom: 2px;box-sizing: border-box;background-color: rgb(89, 89, 89);"></span> <span style="width: 0.6em;height: 0.6em;display: block;opacity: 1;box-sizing: border-box;background-color: rgb(89, 89, 89);"></span> </strong> </section> <section class="" style="display: inline-block;vertical-align: middle;font-size: 18px;padding-left: 5px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="box-sizing: border-box;"><strong>连接建立阶段</strong></p> </section> </section> </section> </section> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">该阶段的主要作用是在主从节点之间建立连接,为数据同步做好准备。</span></p> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 16px;"><strong><span style="color: rgb(89, 89, 89);letter-spacing: 1px;">步骤 1:保存主节点信息</span></strong></span></p> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">从节点服务器内部维护了两个字段,即 masterhost 和 masterport 字段,用于存储主节点的 ip 和 port 信息。</span></p> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">需要注意的是,slaveof 是异步命令,从节点完成主节点 ip 和 port 的保存后,向发送 slaveof 命令的客户端直接返回 OK,实际的复制操作在这之后才开始进行。</span></p> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">这个过程中,可以看到从节点打印日志如下:</span></p> <p style="text-align: center;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><img class="" data-ratio="0.08303249097472924" src="/upload/5f993ac4edb00ec8052d36e33766f476.png" data-type="png" data-w="554" style="box-sizing: border-box !important;word-wrap: break-word !important;width: auto !important;visibility: visible !important;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 16px;"><strong><span style="color: rgb(89, 89, 89);letter-spacing: 1px;">步骤 2:建立 Socket 连接</span></strong></span></p> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">从节点每秒 1 次调用复制定时函数 replicationCron(),如果发现了有主节点可以连接,便会根据主节点的 ip 和 port,创建 socket 连接。</span></p> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">如果连接成功,则:</span></p> <ul class=" list-paddingleft-2" style="list-style-type: disc;"> <li><p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">从节点:</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">为该 socket 建立一个专门处理复制工作的文件事件处理器,负责后续的复制工作,如接收 RDB 文件、接收命令传播等。</span></p></li> <li><p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">主节点:</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">接收到从节点的 socket 连接后(即 accept 之后),为该 socket 创建相应的客户端状态,并将从节点看做是连接到主节点
作者:别丢下我不管
今天在使用PowerDesigner,要导入MySQL的表结构到PowerDesginer里,顺路记录一下步骤,给后续的同学学习。 1、安装MySQL的ODBC驱动 http://dev.mysql.com/downloads/connector/odbc/5.1.html 下载MSI Installer 2、打开Windows的**控制面板**——>**管理工具**——>**ODBC 数据源(32 位)**——>**文件DSN**——>添加——>**选择MySQL ODBC 5.1 Driver**,并输入ip端口等信息,保存为文件 3、在PowerDesigner里,菜单File——>Reverse Engineer——>Database——>DBMS选择MySQL5.0 确定 4、弹出的Database Reverse Engineering Options窗口的Selection里,选择Using a data source,点击右边的小数据库图标 在弹窗里,选择ODBC file data source,查找到第2步创建的DSN文件,然后在下面输入User ID和Password,点击Connect 5、点击确定就可以弹出数据库的表选择窗口,选择对应的需要导入的数据库表点击ok就行了  ## 常见问题: 1、如果安装64为ODBC,可能会提示SQLSTATE=IM002[Microsoft][ODBC驱动程序 管理器未发现数据源名称并且未指定默认驱动程序。 解决:更换为32为的ODBC,因为PowerDesigner是32位的。
作者:じ☆ve宝贝
按照官方文档在json中定义好了Tabbar后,在模拟器上显示没问题,而在真机上不显示Tabar文字。 原因是: 在app.json定义Tabbar文字选中态和非选中态颜色时我用了英文例如black、orange。在模拟器没事,但是在真机一定要用色值,例如#050505 此类问题是由于模拟器环境与真机环境的差异造成的。
作者:微信小助手
<p style="max-width: 100%;min-height: 1em;color: rgb(51, 51, 51);font-family: -apple-system-font, system-ui, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 17px;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);text-align: center;box-sizing: border-box !important;word-wrap: break-word !important;"><span style="max-width: 100%;color: rgb(255, 0, 0);font-size: 14px;box-sizing: border-box !important;word-wrap: break-word !important;"><span style="max-width: 100%;color: rgb(255, 41, 65);line-height: 22.4px;box-sizing: border-box !important;word-wrap: break-word !important;">(点击</span><span style="max-width: 100%;line-height: 22.4px;color: rgb(0, 128, 255);box-sizing: border-box !important;word-wrap: break-word !important;">上方公众号</span><span style="max-width: 100%;color: rgb(255, 41, 65);line-height: 22.4px;box-sizing: border-box !important;word-wrap: break-word !important;">,可快速关注)</span></span></p> <p style="max-width: 100%;min-height: 1em;color: rgb(51, 51, 51);font-family: -apple-system-font, system-ui, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 17px;letter-spacing: 0.544px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;word-wrap: break-word !important;"><br style="max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;"></p> <blockquote style="max-width: 100%;color: rgb(51, 51, 51);font-family: -apple-system-font, system-ui, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 17px;letter-spacing: 0.544px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;word-wrap: break-word !important;"> <p style="max-width: 100%;min-height: 1em;text-align: left;box-sizing: border-box !important;word-wrap: break-word !important;"><span style="max-width: 100%;font-size: 14px;box-sizing: border-box !important;word-wrap: break-word !important;">来源:</span><span style="font-size: 14px;letter-spacing: 0.544px;">ImportNew - 朱伟杰</span></p> </blockquote> <p><br></p> <p>在开发和设计的时候,我们需要考虑编译时,运行时以及构建时这三个概念。理解这几个概念可以更好地帮助你去了解一些基本的原理。下面是初学者晋级中级水平需要知道的一些问题。</p> <p><br></p> <p>Q.下面的代码片段中,行A和行B所标识的代码有什么区别呢?</p> <p><br></p> <blockquote> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">public class ConstantFolding {</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> </span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> static final int number1 = 5;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> static final int number2 = 6;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> static int number3 = 5;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> static int number4= 6;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> public static void main(String[ ] args) {</span></p> <p><span style="color: rgb(136, 136, 136);font-size: 12px;"> int product1 = number1 * number2; //line A</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> int product2 = number3 * number4; //line B</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> }</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">}</span></p> </blockquote> <p><br></p> <p>A.在行A的代码中,product的值是在编译期计算的,行B则是在运行时计算的。如果你使用Java反编译器(例如,jd-gui)来反编译ConstantFolding.class文件的话,那么你就会从下面的结果里得到答案。</p> <p><br></p> <blockquote> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">public class ConstantFolding<br></span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">{</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> static final int number1 = 5;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> static final int number2 = 6;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> static int number3 = 5;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> static int number4 = 6;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> </span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> public static void main(String[ ] args)</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> {</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> int product1 = 30;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> int product2 = number3 * number4;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> }</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">}</span></p> </blockquote> <p><br></p> <p>常量折叠是一种Java编译器使用的优化技术。由于final变量的值不会改变,因此就可以对它们优化。Java反编译器和javap命令都是查看编译后的代码(例如,字节码)的利器。</p> <p><br></p> <p>Q.你能想出除了代码优化外,在什么情况下,查看编译过的代码是很有帮助的?</p> <p><br></p> <p>A.Java里的泛型是在编译时构造的,可以通过查看编译后的class文件来理解泛型,也可以通过查看它来解决泛型相关的问题。</p> <p><br></p> <p>Q.下面哪些是发生在编译时,运行时,或者两者都有?</p> <p><br></p> <p style="text-align: center;"><strong style="text-align: center;white-space: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 14px;font-family: "Microsoft YaHei", 宋体, "Myriad Pro", Lato, "Helvetica Neue", Helvetica, Arial, sans-serif;background-color: rgb(255, 255, 255);"><img class="aligncenter size-full wp-image-1798" data-ratio="1.0947955390334572" src="/upload/9f51fd079a06ab9dd1d85f72a0ad12f0.jpg" data-type="jpeg" data-w="538" height="589" title="compile-vs-run-time" width="538" style="border-width: 0px;border-style: initial;border-color: initial;font-size: 0px;color: transparent;vertical-align: middle;top: 0px;left: 0px;right: 0px;bottom: 0px;"></strong></p> <p><br></p> <p>A.</p> <p><br></p> <p><strong>方法重载</strong>:这个是发生在编译时的。方法重载也被称为编译时多态,因为编译器可以根据参数的类型来选择使用哪个方法。</p> <p><br></p> <blockquote> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">public class {</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> public static void evaluate(String param1); // method #1</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> public static void evaluate(int param1); // method #2</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">}</span></p> </blockquote> <p><br></p> <p>如果编译器要编译下面的语句的话:</p> <p><br></p> <blockquote> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">evaluate(“My Test Argument passed to param1”);</span></p> </blockquote> <p><br></p> <p>它会根据传入的参数是字符串常量,生成调用#1方法的字节码</p> <p><br></p> <p><strong>方法覆盖</strong>:这个是在运行时发生的。方法重载被称为运行时多态,因为在编译期编译器不知道并且没法知道该去调用哪个方法。JVM会在代码运行的时候做出决定。</p> <p><br></p> <blockquote> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">public class A {</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> public int compute(int input) { //method #3</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> return 3 * input;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> } </span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">}</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> </span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">public class B extends A {</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> @Override</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> public int compute(int input) { //method #4</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> return 4 * input;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> } </span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">}</span></p> </blockquote> <p><br></p> <p>子类B中的compute(..)方法重写了父类的compute(..)方法。如果编译器遇到下面的代码:</p> <p><br></p> <blockquote> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">public int evaluate(A reference, int arg2) {</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> int result = reference.compute(arg2);</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">}</span></p> </blockquote> <p><br></p> <p>编译器是没法知道传入的参数reference的类型是A还是B。因此,只能够在运行时,根据赋给输入变量“reference”的对象的类型(例如,A或者B的实例)来决定调用方法#3还是方法#4.</p> <p><br></p> <p><strong>泛型(又称类型检验)</strong>:这个是发生在编译期的。编译器负责检查程序中类型的正确性,然后把使用了泛型的代码翻译或者重写成可以执行在当前JVM上的非泛型代码。这个技术被称为“类型擦除“。换句话来说,编译器会擦除所有在尖括号里的类型信息,来保证和版本1.4.0或者更早版本的JRE的兼容性。</p> <p><br></p> <blockquote> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">List<String> myList = new ArrayList<String>(10);</span></p> </blockquote> <p><br></p> <p>编译后成为了:</p> <p><br></p> <blockquote> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">List myList = new ArrayList(10);</span></p> </blockquote> <p><br></p> <p>注解(Annotation):你可以使用运行时或者编译时的注解。</p> <p><br></p> <blockquote> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">public class B extends A {</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> @Override</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> public int compute(int input){ //method #4</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> return 4 * input;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> } </span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">}</span></p> </blockquote> <p><br></p> <p>@Override是一个简单的编译时注解,它可以用来捕获类似于在子类中把toString()写成tostring()这样的错误。在Java 5中,用户自定义的注解可以用注解处理工具(Anotation Process Tool ——APT)在编译时进行处理。到了Java 6,这个功能已经是编译器的一部分了。</p> <p><br></p> <blockquote> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">public class MyTest{</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> @Test</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> public void testEmptyness( ){</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> org.junit.Assert.assertTrue(getList( ).isEmpty( ));</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> }</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> </span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> private List getList( ){</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> //implemenation goes here</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> }</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">}</span></p> </blockquote> <p><br></p> <p>@Test是JUnit框架用来在运行时通过反射来决定调用测试类的哪个(些)方法的注解。</p> <p><br></p> <blockquote> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">@Test (timeout=100)</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">public void testTimeout( ) {</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> while(true); //infinite loop</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">}</span></p> </blockquote> <p><br></p> <p>如果运行时间超过100ms的话,上面的测试用例就会失败。</p> <p><br></p> <blockquote> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">@Test (expected=IndexOutOfBoundsException.class)</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">public void testOutOfBounds( ) {</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> new ArrayList<Object>( ).get(1);</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">}</span></p> </blockquote> <p><br></p> <p>如果上面的代码在运行时没有抛出IndexOutOfBoundsException或者抛出的是其他的异常的话,那么这个用例就会失败。用户自定义的注解可以在运行时通过Java反射API里新增的AnnotatedElement和”Annotation”元素接口来处理。</p> <p><br></p> <p><strong>异常(Exception)</strong>:你可以使用运行时异常或者编译时异常。</p> <p><br></p> <p><strong>运行时异常(RuntimeException)</strong>也称作未检测的异常(unchecked exception),这表示这种异常不需要编译器来检测。RuntimeException是所有可以在运行时抛出的异常的父类。一个方法除要捕获异常外,如果它执行的时候可能会抛出RuntimeException的子类,那么它就不需要用throw语句来声明抛出的异常。</p> <p><br></p> <p>例如:NullPointerException,ArrayIndexOutOfBoundsException,等等</p> <p><br></p> <p><strong>受检查异常(checked exception)</strong>都是编译器在编译时进行校验的,通过throws语句或者try{}cathch{} 语句块来处理检测异常。编译器会分析哪些异常会在执行一个方法或者构造函数的时候抛出。</p> <p><br></p> <p><strong>面向切面的编程(Aspect Oriented Programming-AOP)</strong>:切面可以在编译时,运行时或,加载时或者运行时织入。</p> <p><br></p> <ul class=" list-paddingleft-2" style="list-style-type: disc;"> <li><p><strong>编译期</strong>:编译期织入是最简单的方式。如果你拥有应用的代码,你可以使用AOP编译器(例如,ajc – AspectJ编译器)对源码进行编译,然后输出织入完成的class文件。AOP编译的过程包含了waver的调用。切面的形式可以是源码的形式也可以是二进制的形式。如果切面需要针对受影响的类进行编译,那么你就需要在编译期织入了。</p><p><br></p></li> <li><p><strong>编译后</strong>:这种方式有时候也被称为二进制织入,它被用来织入已有的class文件和jar文件。和编译时织入方式相同,用来织入的切面可以是源码也可以是二进制的形式,并且它们自己也可以被织入切面。</p><p><br></p></li> <li><p><strong>装载期</strong>:这种织入是一种二进制织入,它被延迟到JVM加载class文件和定义类的时候。为了支持这种织入方式,需要显式地由运行时环境或者通过一种“织入代理(weaving agent)“来提供一个或者多个“织入类加载器(weaving class loader)”。</p><p><br></p></li> <li><p><strong>运行时</strong>:对已经加载到JVM里的类进行织入</p></li> </ul> <p> </p> <p><strong>继承</strong> – 发生在编译时,因为它是静态的</p> <p><br></p> <p><strong>代理或者组合 </strong>– 发生在运行时,因为它更加具有动态性和灵活性。</p> <p><br></p> <p>Q.你有没有听说过“组合优于继承”这样的说法呢?如果听说过的话,那么你是怎么理解的呢?</p> <p><br></p> <p>A.继承是一种多态工具,而不是一种代码复用工具。有些开发者喜欢用继承的方式来实现代码复用,即使是在没有多态关系的情况下。是否使用继承的规则是继承只能用在类之间有“父子”关系的情况下。</p> <p><br></p> <ul class=" list-paddingleft-2" style="list-style-type: disc;"> <li><p>不要仅仅为了代码复用而继承。当你使用组合来实现代码复用的时候,是不会产生继承关系的。过度使用继承(通过“extends”关键字)的话,如果修改了父类,会损坏所有的子类。这是因为子类和父类的紧耦合关系是在编译期产生的。</p></li> <li><p>不要仅仅为了多态而继承。如果你的类之间没有继承关系,并且你想要实现多态,那么你可以通过接口和组合的方式来实现,这样不仅可以实现代码重用,同时也可以实现运行时的灵活性。</p></li> </ul> <p><br></p> <p>这就是为什么四人帮(Gang of Four)的设计模式里更倾向于使用组合而不是继承的原因。面试者会在你的答案里着重关注这几个词语——“耦合”,“静态还是动态”,以及“发生在编译期还是运行时”。运行时的灵活性可以通过组合来实现,因为类可以在运行时动态地根据一个结果有条件或者无条件地进行组合。但是继承却是静态的。</p> <p><br></p> <p>Q.你能够通过实例来区别编译期继承和运行时继承,以及指出Java支持哪种吗?</p> <p><br></p> <p>A.“继承”表示动作和属性从一个对象传递到另外一个对象的场景。Java语言本身只支持编译期继承,它是通过“extends”关键字来产生子类的方式实现的,如下所示:</p> <p><br></p> <blockquote> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">public class Parent {</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> public String saySomething( ) {</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> return “Parent is called”;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> }</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">}</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> </span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">public class Child extends Parent {</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> @Override</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> public String saySomething( ) {</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> return super.saySomething( ) + “, Child is called”;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> }</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">}</span></p> </blockquote> <p><br></p> <p>“Child”类的saySomething()方法的调用会返回“Parent is called,Child is Called”,因为,子类的调用继承了父类的“Parenet is called”。关键字“super”是用来调用“Parent”类的方法。运行时继承表示在运行时构建父/子类关系。Java语言本身不支持运行时继承,但是有一种替代的方案叫做“代理”或者“组合”,它表示在运行时组件一个层次对象的子类。这样可以模拟运行时继承的实现。在Java里,代理的典型实现方式如下:</p> <p><br></p> <blockquote> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">public class Parent {</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> public String saySomething( ) {</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> return “Parent is called”;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> }</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">}</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> </span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">public class Child {</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> public String saySomething( ) {</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> return new Parent( ).saySomething( ) + “, Child is called”;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> }</span></p> </blockquote> <blockquote> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">}</span></p> </blockquote> <p><br></p> <p>子类代理了父类的调用。组合可以按照下面的方式来实现:</p> <p><br></p> <blockquote> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">public class Child {</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> private Parent parent = null;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> </span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> public Child( ){</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> this.parent = new Parent( );</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> }</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> </span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> public String saySomething( ) {</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> return this.parent.saySomething( ) + “, Child is called”;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"> }</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">}</span></p> </blockquote> <p><br></p> <section class="" powered-by="xiumi.us" style="max-width: 100%;box-sizing: border-box;color: rgb(51, 51, 51);font-family: -apple-system-font, system-ui, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 17px;letter-spacing: 0.544px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);word-wrap: break-word !important;"> <section class="" style="margin-top: 10px;margin-bottom: 10px;max-width: 100%;box-sizing: border-box;text-align: left;word-wrap: break-word !important;"> <section class="" style="padding: 10px;max-width: 100%;box-sizing: border-box;display: inline-block;width: 668px;border-width: 1px;border-style: solid;border-color: rgb(226, 226, 226);box-shadow: rgb(226, 226, 226) 0px 16px 1px -13px;word-wrap: break-word !important;"> <section class="" powered-by="xiumi.us" style="max-width: 100%;box-sizing: border-box;word-wrap: break-word !important;"> <section class="" style="max-width: 100%;box-sizing: border-box;word-wrap: break-word !important;"> <section class="" style="max-width: 100%;box-sizing: border-box;color: rgb(93, 93, 93);word-wrap: break-word !important;"> <p class="" style="max-width: 100%;box-sizing: border-box;min-height: 1em;font-size: 13px;word-wrap: break-word !important;">【关于投稿】</p> <p class="" style="max-width: 100%;box-sizing: border-box;min-height: 1em;font-size: 13px;word-wrap: break-word !important;"><br style="max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;"></p> <p class="" style="max-width: 100%;box-sizing: border-box;min-height: 1em;font-size: 13px;word-wrap: break-word !important;">如果大家有原创好文投稿,请直接给公号发送留言。</p> <p class="" style="max-width: 100%;box-sizing: border-box;min-height: 1em;font-size: 13px;word-wrap: break-word !important;"><br style="max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;"></p> <p class="" style="max-width: 100%;box-sizing: border-box;min-height: 1em;font-size: 13px;word-wrap: break-word !important;"><span style="max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;"><span style="max-width: 100%;color: rgb(53, 53, 53);box-sizing: border-box !important;word-wrap: break-word !important;">① 留言格式:</span><br style="max-width: 100%;color: rgb(53, 53, 53);box-sizing: border-box !important;word-wrap: break-word !important;"><span style="max-width: 100%;color: rgb(53, 53, 53);box-sizing: border-box !important;word-wrap: break-word !important;">【投稿】+《 文章标题》+ 文章链接</span><br style="max-width: 100%;color: rgb(53, 53, 53);box-sizing: border-box !important;word-wrap: break-word !important;"><br style="max-width: 100%;color: rgb(53, 53, 53);box-sizing: border-box !important;word-wrap: break-word !important;"><span style="max-width: 100%;color: rgb(53, 53, 53);box-sizing: border-box !important;word-wrap: break-word !important;">② 示例:</span><br style="max-width: 100%;color: rgb(53, 53, 53);box-sizing: border-box !important;word-wrap: break-word !important;"><span style="max-width: 100%;color: rgb(53, 53, 53);box-sizing: border-box !important;word-wrap: break-word !important;">【投稿】《不要自称是程序员,我十多年的 IT 职场总结》:http://blog.jobbole.com/94148/</span><br style="max-width: 100%;color: rgb(53, 53, 53);box-sizing: border-box !important;word-wrap: break-word !important;"><br style="max-width: 100%;color: rgb(53, 53, 53);box-sizing: border-box !important;word-wrap: break-word !important;"><span style="max-width: 100%;color: rgb(53, 53, 53);box-sizing: border-box !important;word-wrap: break-word !important;">③ 最后请附上您的个人简介哈~</span></span></p> <p style="max-width: 100%;min-height: 1em;box-sizing: border-box !important;word-wrap: break-word !important;"><br style="max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;"></p> </section> </section> </section> </section> </section> </section> <p style="max-width: 100%;min-height: 1em;color: rgb(51, 51, 51);font-family: -apple-system-font, system-ui, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 17px;letter-spacing: 0.544px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;word-wrap: break-word !important;"><br style="max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;"></p> <p style="max-width: 100%;min-height: 1em;color: rgb(51, 51, 51);font-family: -apple-system-font, system-ui, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 17px;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);text-align: center;box-sizing: border-box !important;word-wrap: break-word !important;"><span style="max-width: 100%;font-size: 14px;color: rgb(255, 169, 0);box-sizing: border-box !important;word-wrap: break-word !important;overflow-wrap: break-word !important;">看完本文有收获?请转发分享给更多人</span></p> <p style="max-width: 100%;min-height: 1em;color: rgb(51, 51, 51);font-family: -apple-system-font, system-ui, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 17px;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);text-align: center;box-sizing: border-box !important;word-wrap: break-word !important;"><strong style="max-width: 100%;color: rgb(255, 169, 0);box-sizing: border-box !important;word-wrap: break-word !important;overflow-wrap: break-word !important;">关注「ImportNew」,提升Java技能</strong></p> <p style="max-width: 100%;min-height: 1em;color: rgb(51, 51, 51);font-family: -apple-system-font, system-ui, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 17px;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);text-align: center;box-sizing: border-box !important;word-wrap: break-word !important;"><img class="" data-ratio="0.9166666666666666" data-s="300,640" data-type="png" data-w="600" width="auto" src="/upload/899866149276fa5fddb73c61ae04be64.png" style="box-sizing: border-box !important;word-wrap: break-word !important;overflow-wrap: break-word !important;visibility: visible !important;width: 600px !important;"></p>
作者:微信小助手
<p style="text-align: center;"><img class="" data-copyright="0" data-ratio="0.11875" src="/upload/7e46361941675db393b2b98242f4fa7d.gif" data-type="gif" data-w="640" style=""></p> <section data-role="outer" label="Powered by 135editor.com" style="font-size: 16px;font-family: 微软雅黑;"> <section data-role="outer" label="Powered by 135editor.com" style="font-size: 16px;"> <section style="white-space: normal;box-sizing: border-box;"> <section data-role="paragraph" class="_135editor" style="border-width: 0px;border-style: none;border-color: currentcolor;-moz-border-top-colors: none;-moz-border-right-colors: none;-moz-border-bottom-colors: none;-moz-border-left-colors: none;box-sizing: border-box;"> <p style="text-align: justify;letter-spacing: 2px;line-height: 1.75em;"><span style="font-size: 13px;">有多少90后,每天都活在人生崩溃的边缘?</span></p> <p style="text-align: justify;letter-spacing: 2px;line-height: 1.75em;"><span style="font-size: 13px;"><br></span></p> <p style="text-align: justify;letter-spacing: 2px;line-height: 1.75em;"><span style="font-size: 13px;"><span style="font-size: 13px;">为了<span style="font-size: 13px;">捡拾日常生活里的美好细节</span>,那些被我们忽略的平凡,需要被重新装点。</span></span></p> <p style="text-align: justify;letter-spacing: 2px;line-height: 1.75em;"><br></p> <p style="text-align: justify;letter-spacing: 2px;line-height: 1.75em;"><span style="font-size: 13px;">在这本<strong>《我只是对人生过敏》里,</strong>有<strong><span style="color: rgb(192, 0, 0);font-size: 17px;">105</span></strong>条涂鸦作品,在观赏作者呆萌画风的同时,也是一本集合了无厘头的世界观、古怪的冷笑话以及诡异的名词解释的英文段子书。</span></p> <p style="text-align: justify;letter-spacing: 2px;line-height: 1.75em;"><span style="font-size: 13px;"><br></span></p> <p style="text-align: justify;letter-spacing: 2px;line-height: 1.75em;"><span style="font-size: 13px;"><span style="font-size: 13px;">它们也许不能帮你解决什么难题,但却能为你无聊烦躁的生活带来快乐。</span></span></p> <p style="text-align: justify;letter-spacing: 2px;line-height: 1.75em;"><br></p> <p style="text-align: justify;letter-spacing: 2px;line-height: 1.75em;"><span style="font-size: 15px;"><strong>或许,你的日常就在这本《我只是对人生过敏》里↓</strong></span><span style="font-size: 13px;"><br></span></p> <p><br></p> </section> <section class="_135editor" style="box-sizing: border-box;border-width: 0px;border-style: none;border-color: currentcolor;-moz-border-top-colors: none;-moz-border-right-colors: none;-moz-border-bottom-colors: none;-moz-border-left-colors: none;"> <section class="" style="margin-top: 3px;margin-bottom: 3px;text-align: center;box-sizing: border-box;"> <section class="" style="margin-right: auto;margin-left: auto;display: inline-block;border-width: 1px;border-style: solid;border-color: rgb(190, 182, 145);width: 1.8em;height: 1.8em;line-height: 1.8em;border-radius: 100%;font-size: 18px;box-sizing: border-box;background-color: rgb(190, 182, 145);"> <p style="box-sizing: border-box;"><strong style="box-sizing: border-box;">1</strong></p> </section> </section> </section> <section class="_135editor" style="box-sizing: border-box;border-width: 0px;border-style: none;border-color: currentcolor;-moz-border-top-colors: none;-moz-border-right-colors: none;-moz-border-bottom-colors: none;-moz-border-left-colors: none;"> <section class="" style="margin-top: 30px;margin-bottom: 5px;text-align: center;box-sizing: border-box;"> <section class="" style="padding: 10px 10px 5px;display: inline-block;width: 530.094px;vertical-align: top;box-shadow: 1.41421px 1.41421px 6px rgb(185, 185, 185);box-sizing: border-box;"> <section style="box-sizing: border-box;"> <section class="" style="margin-bottom: 15px;box-sizing: border-box;"> <section class="" style="max-width: 100%;vertical-align: middle;display: inline-block;box-shadow: 0px 0px 0px rgb(0, 0, 0);box-sizing: border-box;overflow: hidden ! important;"> <img class="" data-ratio="1.0094876660341556" src="/upload/e7c67344f66e45f2cfb57e089e64ca59.jpg" data-type="jpeg" data-w="527" style="vertical-align: middle;box-sizing: border-box;"> </section> </section> </section> </section> </section> </section> <section class="_135editor" style="box-sizing: border-box;border-width: 0px;border-style: none;border-color: currentcolor;-moz-border-top-colors: none;-moz-border-right-colors: none;-moz-border-bottom-colors: none;-moz-border-left-colors: none;"> <section class="" style="margin-top: 5px;margin-bottom: 10px;text-align: center;box-sizing: border-box;"> <section class="" style="padding: 10px 10px 15px;display: inline-block;width: 530.094px;vertical-align: top;box-shadow: 1.41421px 1.41421px 6px rgb(185, 185, 185);box-sizing: border-box;"> <section style="box-sizing: border-box;"> <section class="" style="margin-top: -30px;box-sizing: border-box;"> <section class="" style="display: inline-block;vertical-align: top;width: 255.047px;box-sizing: border-box;"> <section style="box-sizing: border-box;"> <section class="" style="box-sizing: border-box;"> <section class="" style="max-width: 100%;vertical-align: middle;display: inline-block;box-shadow: 0px 0px 0px rgb(0, 0, 0);width: 242.281px;box-sizing: border-box;overflow: hidden ! important;"> <img class="" data-ratio="0.2196078431372549" src="/upload/7cf3089e8987dfc7edc1bc29fe8411bd.png" data-type="png" data-w="255" style="vertical-align: middle;width: 242.281px;box-sizing: border-box;"> </section> </section> </section> </section> <section class="" style="display: inline-block;vertical-align: top;width: 255.047px;box-shadow: 0px 0px 0px rgb(0, 0, 0);box-sizing: border-box;"> <section style="box-sizing: border-box;"> <section class="" style="box-sizing: border-box;"> <section class="" style="max-width: 100%;vertical-align: middle;display: inline-block;width: 242.281px;box-sizing: border-box;overflow: hidden ! important;"> <img class="" data-ratio="0.2196078431372549" src="/upload/7cf3089e8987dfc7edc1bc29fe8411bd.png" data-type="png" data-w="255" style="vertical-align: middle;width: 242.281px;box-sizing: border-box;"> </section> </section> </section> </section> </section> </section> <section style="box-sizing: border-box;"> <section class="" style="box-sizing: border-box;"> <section class="" style="text-align: left;box-sizing: border-box;"> <p style="box-sizing: border-box;"><br></p> </section> </section> </section> <section style="box-sizing: border-box;"> <section class="" style="box-sizing: border-box;"> <section class="" style="padding-right: 5px;padding-left: 5px;text-align: justify;font-size: 15px;box-sizing: border-box;"> <p style="box-sizing: border-box;">I fail to understand the “good” part of<strong> “good morning”.</strong></p> </section> </section> </section> <section style="box-sizing: border-box;"> <section class="" style="margin-top: 8px;margin-bottom: 18px;box-sizing: border-box;"> <section class="" style="border-top: 1px dashed rgb(185, 185, 185);box-sizing: border-box;"></section> </section> </section> <section style="box-sizing: border-box;"> <section class="" style="text-align: left;box-sizing: border-box;"> <section class="" style="padding-right: 5px;padding-left: 5px;text-align: justify;font-size: 15px;letter-spacing: 2px;box-sizing: border-box;"> <p style="box-sizing: border-box;">我就不明白了,<strong>“早上好”</strong>到底好在哪里。</p> </section> </section> </section> </section> </section> </section> <section class="_135editor" style="box-sizing: border-box;border-width: 0px;border-style: none;border-color: currentcolor;-moz-border-top-colors: none;-moz-border-right-colors: none;-moz-border-bottom-colors: none;-moz-border-left-colors: none;"> <section class="" style="box-sizing: border-box;"> <section class="" style="box-sizing: border-box;"> <p style="box-sizing: border-box;"><br></p> </section> </section> </section> <section class="_135editor" style="box-sizing: border-box;border-width: 0px;border-style: none;border-color: currentcolor;-moz-border-top-colors: none;-moz-border-right-colors: none;-moz-border-bottom-colors: none;-moz-border-left-colors: none;"> <section class="" style="box-sizing: border-box;"> <section class="" style="box-sizing: border-box;"> <p style="box-sizing: border-box;"><br></p> </section> </section> </section> <section class="_135editor" style="box-sizing: border-box;border-width: 0px;border-style: none;border-color: currentcolor;-moz-border-top-colors: none;-moz-border-right-colors: none;-moz-border-bottom-colors: none;-moz-border-left-colors: none;"> <section class="" style="margin-top: 3px;margin-bottom: 3px;text-align: center;box-sizing: border-box;"> <section class="" style="margin-right: auto;margin-left: auto;display: inline-block;border-width: 1px;border-style: solid;border-color: rgb(190, 182, 145);width: 1.8em;height: 1.8em;line-height: 1.8em;border-radius: 100%;font-size: 18px;box-sizing: border-box;background-color: rgb(190, 182, 145);"> <p style="box-sizing: border-box;"><strong style="box-sizing: border-box;">2</strong></p> </section> </section> </section> <section class="_135editor" style="box-sizing: border-box;border-width: 0px;border-style: none;border-color: currentcolor;-moz-border-top-colors: none;-moz-border-right-colors: none;-moz-border-bottom-colors: none;-moz-border-left-colors: none;"> <section class="" style="margin-top: 30px;margin-bottom: 5px;text-align: center;box-sizing: border-box;"> <section class="" style="padding: 10px 10px 5px;display: inline-block;width: 530.094px;vertical-align: top;box-shadow: 1.41421px 1.41421px 6px rgb(185, 185, 185);box-sizing: border-box;"> <section style="box-sizing: border-box;"> <section class="" style="margin-bottom: 15px;box-sizing: border-box;"> <section class="" style="max-width: 100%;vertical-align: middle;display: inline-block;box-shadow: 0px 0px 0px rgb(0, 0, 0);box-sizing: border-box;overflow: hidden ! important;"> <img class="" data-ratio="1.0094876660341556" src="/upload/b2e8e8f49d4343831b68ccf80672e0f9.jpg" data-type="jpeg" data-w="527" style="vertical-align: middle;box-sizing: border-box;"> </section> </section> </section> </section> </section> </section> <section class="_135editor" style="box-sizing: border-box;border-width: 0px;border-style: none;border-color: currentcolor;-moz-border-top-colors: none;-moz-border-right-colors: none;-moz-border-bottom-colors: none;-moz-border-left-colors: none;"> <section class="" style="margin-top: 5px;margin-bottom: 10px;text-align: center;box-sizing: border-box;"> <section class="" style="padding: 10px 10px 15px;display: inline-block;width: 530.094px;vertical-align: top;box-shadow: 1.41421px 1.41421px 6px rgb(185, 185, 185);box-sizing: border-box;"> <section style="box-sizing: border-box;"> <section class="" style="margin-top: -30px;box-sizing: border-box;"> <section class="" style="display: inline-block;vertical-align: top;width: 255.047px;box-sizing: border-box;"> <section style="box-sizing: border-box;"> <section class="" style="box-sizing: border-box;"> <section class="" style="max-width: 100%;vertical-align: middle;display: inline-block;box-shadow: 0px 0px 0px rgb(0, 0, 0);width: 242.281px;box-sizing: border-box;overflow: hidden ! important;"> <img class="" data-ratio="0.2196078431372549" src="/upload/7cf3089e8987dfc7edc1bc29fe8411bd.png" data-type="png" data-w="255" style="vertical-align: middle;width: 242.281px;box-sizing: border-box;"> </section> </section> </section> </section> <section class="" style="display: inline-block;vertical-align: top;width: 255.047px;box-shadow: 0px 0px 0px rgb(0, 0, 0);box-sizing: border-box;"> <section style="box-sizing: border-box;"> <section class="" style="box-sizing: border-box;"> <section class="" style="max-width: 100%;vertical-align: middle;display: inline-block;width: 242.281px;box-sizing: border-box;overflow: hidden ! important;"> <img class="" data-ratio="0.2196078431372549" src="/upload/7cf3089e8987dfc7edc1bc29fe8411bd.png" data-type="png" data-w="255" style="vertical-align: middle;width: 242.281px;box-sizing: border-box;"> </section> </section> </section> </section> </section> </section> <section style="box-sizing: border-box;"> <section class="" style="box-sizing: border-box;"> <section class="" style="text-align: left;box-sizing: border-box;"> <p style="box-sizing: border-box;"><br></p> </section> </section> </section> <section style="box-sizing: border-box;"> <section class="" style="box-sizing: border-box;"> <section class="" style="padding-right: 5px;padding-left: 5px;text-align: justify;font-size: 15px;letter-spacing: 0px;box-sizing: border-box;"> <p style="box-sizing: border-box;">If robbers even broke into my house and searched for money, I’d just laugh and search with them.</p> </section> </section> </section> <section style="box-sizing: border-box;"> <section class="" style="margin-top: 8px;margin-bottom: 18px;box-sizing: border-box;"> <section class="" style="border-top: 1px dashed rgb(185, 185, 185);box-sizing: border-box;"></section> </section> </section> <section style="box-sizing: border-box;"> <section class="" style="text-align: left;box-sizing: border-box;"> <section class="" style="padding-right: 5px;padding-left: 5px;text-align: justify;font-size: 15px;letter-spacing: 2px;box-sizing: border-box;"> <p style="box-sizing: border-box;">要是有劫匪闯入我的屋子里找钱,我只会大笑着和他们一起找。</p> </section> </section> </section> </section> </section> </section> <section class="_135editor" style="box-sizing: border-box;border-width: 0px;border-style: none;border-color: currentcolor;-moz-border-top-colors: none;-moz-border-right-colors: none;-moz-border-bottom-colors: none;-moz-border-left-colors: none;"> <section class="" style="box-sizing: border-box;"> <section class="" style="box-sizing: border-box;"> <p style="box-sizing: border-box;"><br></p> </section> </section> </section> <section class="_135editor" style="box-sizing: border-box;border-width: 0px;border-style: none;border-color: currentcolor;-moz-border-top-colors: none;-moz-border-right-colors: none;-moz-border-bottom-colors: none;-moz-border-left-colors: none;"> <section class="" style="box-sizing: border-box;"> <section class="" style="box-sizing: border-box;"> <p style="box-sizing: border-box;"><br></p> </section> </section> </section> <section class="_135editor" style="box-sizing: border-box;border-width: 0px;border-style: none;border-color: currentcolor;-moz-border-top-colors: none;-moz-border-right-colors: none;-moz-border-bottom-colors: none;-moz-border-left-colors: none;"> <section class="" style="margin-top: 3px;margin-bottom: 3px;text-align: center;box-sizing: border-box;"> <section class="" style="margin-right: auto;margin-left: auto;display: inline-block;border-width: 1px;border-style: solid;border-color: rgb(190, 182, 145);width: 1.8em;height: 1.8em;line-height: 1.8em;border-radius: 100%;font-size: 18px;box-sizing: border-box;background-color: rgb(190, 182, 145);"> <p style="box-sizing: border-box;"><strong style="box-sizing: border-box;">3</strong></p> </section> </section> </section> <section class="_135editor" style="box-sizing: border-box;border-width: 0px;border-style: none;border-color: currentcolor;-moz-border-top-colors: none;-moz-border-right-colors: none;-moz-border-bottom-colors: none;-moz-border-left-colors: none;"> <section class="" style="margin-top: 30px;margin-bottom: 5px;text-align: center;box-sizing: border-box;"> <section class="" style="padding: 10px 10px 5px;display: inline-block;width: 530.094px;vertical-align: top;box-shadow: 1.41421px 1.41421px 6px rgb(185, 185, 185);box-sizing: border-box;"> <section style="box-sizing: border-box;"> <section class="" style="margin-bottom: 15px;box-sizing: border-box;"> <section class="" style="max-width: 100%;vertical-align: middle;display: inline-block;box-shadow: 0px 0px 0px rgb(0, 0, 0);box-sizing: border-box;overflow: hidden ! important;"> <img class="" data-ratio="1.0094876660341556" src="/upload/2e41aff9e578b4f03a154b8fe804f08c.jpg" data-type="jpeg" data-w="527" style="vertical-align: middle;box-sizing: border-box;"> </section> </section> </section> </section> </section> </section> <section class="_135editor" style="box-sizing: border-box;border-width: 0px;border-style: none;border-color: currentcolor;-moz-border-top-colors: none;-moz-border-right-colors: none;-moz-border-bottom-colors: none;-moz-border-left-colors: none;"> <section class="" style="margin-top: 5px;margin-bottom: 10px;text-align: center;box-sizing: border-box;"> <section class="" style="padding: 10px 10px 15px;display: inline-block;width: 530.094px;vertical-align: top;box-shadow: 1.41421px 1.41421px 6px rgb(185, 185, 185);box-sizing: border-box;"> <section style="box-sizing: border-box;"> <section class="" style="margin-top: -30px;box-sizing: border-box;"> <section class="" style="display: inline-block;vertical-align: top;width: 255.047px;box-sizing: border-box;"> <section style="box-sizing: border-box;"> <section class="" style="box-sizing: border-box;"> <section class="" style="max-width: 100%;vertical-align: middle;display: inline-block;box-shadow: 0px 0px 0px rgb(0, 0, 0);width: 242.281px;box-sizing: border-box;overflow: hidden ! important;"> <img class="" data-ratio="0.2196078431372549" src="/upload/7cf3089e8987dfc7edc1bc29fe8411bd.png" data-type="png" data-w="255" style="vertical-align: middle;width: 242.281px;box-sizing: border-box;"> </section> </section> </section> </section> <section class="" style="display: inline-block;vertical-align: top;width: 255.047px;box-shadow: 0px 0px 0px rgb(0, 0, 0);box-sizing: border-box;"> <section style="box-sizing: border-box;"> <section class="" style="box-sizing: border-box;"> <section class="" style="max-width: 100%;vertical-align: middle;display: inline-block;width: 242.281px;box-sizing: border-box;overflow: hidden ! important;"> <img class="" data-ratio="0.2196078431372549" src="/upload/7cf3089e8987dfc7edc1bc29fe8411bd.png" data-type="png" data-w="255" style="vertical-align: middle;width: 242.281px;box-sizing: border-box;"> </section> </section> </section> </section> </section> </section> <section style="box-sizing: border-box;"> <section class="" style="box-sizing: border-box;"> <section class="" style="text-align: left;box-sizing: border-box;"> <p style="box-sizing: border-box;"><br></p> </section> </section> </section> <section style="box-sizing: border-box;"> <section class="" style="box-sizing: border-box;"> <section class="" style="padding-right: 5px;padding-left: 5px;text-align: justify;font-size: 15px;box-sizing: border-box;"> <p style="box-sizing: border-box;">Every once in a while I check up on people I hate to <strong>make sure I still hate them.</strong></p> </section> </section> </section> <section style="box-sizing: border-box;"> <section class="" style="margin-top: 8px;margin-bottom: 18px;box-sizing: border-box;"> <section class="" style="border-top: 1px dashed rgb(185, 185, 185);box-sizing: border-box;"></section> </section> </section> <section style="box-sizing: border-box;"> <section class="" style="text-align: left;box-sizing: border-box;"> <section class="" style="padding-right: 5px;padding-left: 5px;text-align: justify;font-size: 15px;letter-spacing: 2px;box-sizing: border-box;"> <p style="box-sizing: border-box;">每隔一段时间,我就会核对一遍我讨厌的人,<strong>确保我仍然恨着他们</strong>。</p> </section> </section> </section> </section> </section> </section> <section class="_135editor" style="box-sizing: border-box;border-width: 0px;border-style: none;border-color: currentcolor;-moz-border-top-colors: none;-moz-border-right-colors: none;-moz-border-bottom-colors: none;-moz-border-left-colors: none;"> <section class="" style="box-sizing: border-box;"> <section class="" style="box-sizing: border-box;"> <p style="box-sizing: border-box;"><br></p> </section> </section> </section> <section class="_135editor" style="box-sizing: border-box;border-width: 0px;border-style: none;border-color: currentcolor;-moz-border-top-colors: none;-moz-border-right-colors: none;-moz-border-bottom-colors: none;-moz-border-left-colors: none;"> <section class="" style="box-sizing: border-box;"> <section class="" style="box-sizing: border-box;"> <p style="box-sizing: border-box;"><br></p> </section> </section> </section> <section class="_135editor" style="box-sizing: border-box;border-width: 0px;border-style: none;border-color: currentcolor;-moz-border-top-colors: none;-moz-border-right-colors: none;-moz-border-bottom-colors: none;-moz-border-left-colors: none;"> <section class="" style="margin-top: 3px;margin-bottom: 3px;text-align: center;box-sizing: border-box;"> <section class="" style="margin-right: auto;margin-left: auto;display: inline-block;border-width: 1px;border-style: solid;border-color: rgb(190, 182, 145);width: 1.8em;height: 1.8em;line-height: 1.8em;border-radius: 100%;font-size: 18px;box-sizing: border-box;background-color: rgb(190, 182, 145);"> <p style="box-sizing: border-box;"><strong style="box-sizing: border-box;">4</strong></p> </section> </section> </section> <section class="_135editor" style="box-sizing: border-box;border-width: 0px;border-style: none;border-color: currentcolor;-moz-border-top-colors: none;-moz-border-right-colors: none;-moz-border-bottom-colors: none;-moz-border-left-colors: none;"> <section class="" style="margin-top: 30px;margin-bottom: 5px;text-align: center;box-sizing: border-box;"> <section class="" style="padding: 10px 10px 5px;display: inline-block;width: 530.094px;vertical-align: top;box-shadow: 1.41421px 1.41421px 6px rgb(185, 185, 185);box-sizing: border-box;"> <section style="box-sizing: border-box;"> <section class="" style="margin-bottom: 15px;box-sizing: border-box;"> <section class="" style="max-width: 100%;vertical-align: middle;display: inline-block;box-shadow: 0px 0px 0px rgb(0, 0, 0);box-sizing: border-box;overflow: hidden ! important;"> <img class="" data-ratio="1.0094876660341556" src="/upload/8489fa13bea08d614fec4b2a2795da1e.jpg" data-type="jpeg" data-w="527" style="vertical-align: middle;box-sizing: border-box;"> </section> </section> </section> </section> </section> </section> <section class="_135editor" style="box-sizing: border-box;border-width: 0px;border-style: none;border-color: currentcolor;-moz-border-top-colors: none;-moz-border-right-colors: none;-moz-border-bottom-colors: none;-moz-border-left-colors: none;"> <section class="" style="margin-top: 5px;margin-bottom: 10px;text-align: center;box-sizing: border-box;"> <section class="" style="padding: 10px 10px 15px;display: inline-block;width: 530.094px;vertical-align: top;box-shadow: 1.41421px 1.41421px 6px rgb(185, 185, 185);box-sizing: border-box;"> <section style="box-sizing: border-box;"> <section class="" style="margin-top: -30px;box-sizing: border-box;"> <section class="" style="display: inline-block;vertical-align: top;width: 255.047px;box-sizing: border-box;"> <section style="box-sizing: border-box;"> <section class="" style="box-sizing: border-box;"> <section class="" style="max-width: 100%;vertical-align: middle;display: inline-block;box-shadow: 0px 0px 0px rgb(0, 0, 0);width: 242.281px;box-sizing: border-box;overflow: hidden ! important;"> <img class="" data-ratio="0.2196078431372549" src="/upload/7cf3089e8987dfc7edc1bc29fe8411bd.png" data-type="png" data-w="255" style="vertical-align: middle;width: 242.281px;box-sizing: border-box;"> </section> </section> </section> </section> <section class="" style="display: inline-block;vertical-align: top;width: 255.047px;box-shadow: 0px 0px 0px rgb(0, 0, 0);box-sizing: border-box;"> <section style="box-sizing: border-box;"> <section class="" style="box-sizing: border-box;"> <section class="" style="max-width: 100%;vertical-align: middle;display: inline-block;width: 242.281px;box-sizing: border-box;overflow: hidden ! important;"> <img class="" data-ratio="0.2196078431372549" src="/upload/7cf3089e8987dfc7edc1bc29fe8411bd.png" data-type="png" data-w="255" style="vertical-align: middle;width: 242.281px;box-sizing: border-box;"> </section> </section> </section> </section> </section> </section> <section style="box-sizing: border-box;"> <section class="" style="box-sizing: border-box;"> <section class="" style="text-align: left;box-sizing: border-box;"> <p style="box-sizing: border-box;"><br></p> </section> </section> </section> <section style="box-sizing: border-box;"> <section class="" style="box-sizing: border-box;"> <section class="" style="padding-right: 5px;padding-left: 5px;text-align: justify;font-size: 15px;box-sizing: border-box;"> <p style="box-sizing: border-box;">I’m waiting for the day that scientists discover a cure for <strong>Natural Causes</strong>.</p> </section> </section> </section> <section style="box-sizing: border-box;"> <section class="" style="margin-top: 8px;margin-bottom: 18px;box-sizing: border-box;"> <section class="" style="border-top: 1px dashed rgb(185, 185, 185);box-sizing: border-box;"></section> </section> </section> <section style="box-sizing: border-box;"> <section class="" style="text-align: left;box-sizing: border-box;"> <section class="" style="padding-right: 5px;padding-left: 5px;text-align: justify;font-size: 15px;letter-spacing: 2px;box-sizing: border-box;"> <p style="box-sizing: border-box;">我等待着科学家成功治愈<strong>“顺其自然综合征”</strong>的那一天。</p> </section> </section> </section> </section> </section> </section> <section class="_135editor" style="box-sizing: border-box;border-width: 0px;border-style: none;border-color: currentcolor;-moz-border-top-colors: none;-moz-border-right-colors: none;-moz-border-bottom-colors: none;-moz-border-left-colors: none;"> <section class="" style="box-sizing: border-box;"> <section class="" style="box-sizing: border-box;"> <p style="box-sizing: border-box;"><br></p> </section> </section> </section> <section class="_135editor" style="box-sizing: border-box;border-width: 0px;border-style: none;border-color: currentcolor;-moz-border-top-colors: none;-moz-border-right-colors: none;-moz-border-bottom-colors: none;-moz-border-left-colors: none;"> <section class="" style="box-sizing: border-box;"> <section class="" style="box-sizing: border-box;"> <p style="box-sizing: border-box;"><br></p> </section> </section> </section> <section class="_135editor" style="box-sizing: border-box;border-width: 0px;border-style: none;border-color: currentcolor;-moz-border-top-colors: none;-moz-border-right-colors: none;-moz-border-bottom-colors: none;-moz-border-left-colors: none;"> <section class="" style="margin-top: 3px;margin-bottom: 3px;text-align: center;box-sizing: border-box;"> <section class="" style="margin-right: auto;margin-left: auto;display: inline-block;border-width: 1px;border-style: solid;border-color: rgb(190, 182, 145);width: 1.8em;height: 1.8em;line-height: 1.8em;border-radius: 100%;font-size: 18px;box-sizing: border-box;background-color: rgb(190, 182, 145);"> <p style="box-sizing: border-box;"><strong style="box-sizing: border-box;">5</strong></p> </section> </section> </section> <section class="_135editor" style="box-sizing: border-box;border-width: 0px;border-style: none;border-color: currentcolor;-moz-border-top-colors: none;-moz-border-right-colors: none;-moz-border-bottom-colors: none;-moz-border-left-colors: none;"> <section class="" style="margin-top: 30px;margin-bottom: 5px;text-align: center;box-sizing: border-box;"> <section class="" style="padding: 10px 10px 5px;display: inline-block;width: 530.094px;vertical-align: top;box-shadow: 1.41421px 1.41421px 6px rgb(185, 185, 185);box-sizing: border-box;"> <section style="box-sizing: border-box;"> <section class="" style="margin-bottom: 15px;box-sizing: border-box;"> <section class="" style="max-width: 100%;vertical-align: middle;display: inline-block;box-shadow: 0px 0px 0px rgb(0, 0, 0);box-sizing: border-box;overflow: hidden ! important;"> <img class="" data-ratio="1.0094876660341556" src="/upload/eb121f2593e91769cae446baba9c8cf3.jpg" data-type="jpeg" data-w="527" style="vertical-align: middle;box-sizing: border-box;"> </section> </section> </section> </section> </section> </section> <section class="_135editor" style="box-sizing: border-box;border-width: 0px;border-style: none;border-color: currentcolor;-moz-border-top-colors: none;-moz-border-right-colors: none;-moz-border-bottom-colors: none;-moz-border-left-colors: none;"> <section class="" style="margin-top: 5px;margin-bottom: 10px;text-align: center;box-sizing: border-box;"> <section class="" style="padding: 10px 10px 15px;display: inline-block;width: 530.094px;vertical-align: top;box-shadow: 1.41421px 1.41421px 6px rgb(185, 185, 185);box-sizing: border-box;"> <section style="box-sizing: border-box;"> <section class="" style="margin-top: -30px;box-sizing: border-box;"> <section class="" style="display: inline-block;vertical-align: top;width: 255.047px;box-sizing: border-box;"> <section style="box-sizing: border-box;"> <section class="" style="box-sizing: border-box;"> <section class="" style="max-width: 100%;vertical-align: middle;display: inline-block;box-shadow: 0px 0px 0px rgb(0, 0, 0);width: 242.281px;box-sizing: border-box;overflow: hidden ! important;"> <img class="" data-ratio="0.2196078431372549" src="/upload/7cf3089e8987dfc7edc1bc29fe8411bd.png" data-type="png" data-w="255" style="vertical-align: middle;width: 242.281px;box-sizing: border-box;"> </section> </section> </section> </section> <section class="" style="display: inline-block;vertical-align: top;width: 255.047px;box-shadow: 0px 0px 0px rgb(0, 0, 0);box-sizing: border-box;"> <section style="box-sizing: border-box;"> <section class="" style="box-sizing: border-box;"> <section class="" style="max-width: 100%;vertical-align: middle;display: inline-block;width: 242.281px;box-sizing: border-box;overflow: hidden ! important;"> <img class="" data-ratio="0.2196078431372549" src="/upload/7cf3089e8987dfc7edc1bc29fe8411bd.png" data-type="png" data-w="255" style="vertical-align: middle;width: 242.281px;box-sizing: border-box;"> </section> </section> </section> </section> </section> </section> <section style="box-sizing: border-box;"> <section class="" style="box-sizing: border-box;"> <section class="" style="text-align: left;box-sizing: border-box;"> <p style="box-sizing: border-box;"><br></p> </section> </section> </section> <section style="box-sizing: border-box;"> <section class="" style="box-sizing: border-box;"> <section class="" style="padding-right: 5px;padding-left: 5px;font-size: 15px;box-sizing: border-box;"> <p style="text-align: justify;box-sizing: border-box;">Old people at weddings always poke me and say <strong style="box-sizing: border-box;">“you’re next.”</strong> So, I started doing the same thing to them at funerals.</p> </section> </section> </section> <section style="box-sizing: border-box;"> <section class="" style="margin-top: 8px;margin-bottom: 18px;box-sizing: border-box;"> <section class="" style="border-top: 1px dashed rgb(185, 185, 185);box-sizing: border-box;"></section> </section> </section> <section style="box-sizing: border-box;"> <section class="" style="text-align: left;box-sizing: border-box;"> <section class="" style="padding-right: 5px;padding-left: 5px;text-align: justify;font-size: 15px;letter-spacing: 2px;box-sizing: border-box;"> <p style="box-sizing: border-box;">老人们喜欢在婚礼上戳戳我,并对我说:“<strong>下一个就是你啦</strong>。”所以,我开始在葬礼上以牙还牙。</p> </section> </section> </section> </section> </section> </section> <section class="_135editor" style="box-sizing: border-box;border-width: 0px;border-style: none;border-color: currentcolor;-moz-border-top-colors: none;-moz-border-right-colors: none;-moz-border-bottom-colors: none;-moz-border-left-colors: none;"> <section class="" style="box-sizing: border-box;"> <section class="" style="box-sizing: border-box;"> <p style="box-sizing: border-box;"><br></p> </section> </section> </section> <section class="_135editor" style="box-sizing: border-box;border-width: 0px;border-style: none;border-color: currentcolor;-moz-border-top-colors: none;-moz-border-right-colors: none;-moz-border-bottom-colors: none;-moz-border-left-colors: none;"> <section class="" style="box-sizing: border-box;"> <section class="" style="box-sizing: border-box;"> <p style="box-sizing: border-box;"><br></p> </section> </section> </section> <section class="_135editor" style="box-sizing: border-box;border-width: 0px;border-style: none;border-color: currentcolor;-moz-border-top-colors: none;-moz-border-right-colors: none;-moz-border-bottom-colors: none;-moz-border-left-colors: none;"> <section class="" style="margin-top: 3px;margin-bottom: 3px;text-align: center;box-sizing: border-box;"> <section class="" style="margin-right: auto;margin-left: auto;display: inline-block;border-width: 1px;border-style: solid;border-color: rgb(190, 182, 145);width: 1.8em;height: 1.8em;line-height: 1.8em;border-radius: 100%;font-size: 18px;box-sizing: border-box;background-color: rgb(190, 182, 145);"> <p style="box-sizing: border-box;"><strong style="box-sizing: border-box;">6</strong></p> </section> </section> </section> <section class="_135editor" style="box-sizing: border-box;border-width: 0px;border-style: none;border-color: currentcolor;-moz-border-top-colors: none;-moz-border-right-colors: none;-moz-border-bottom-colors: none;-moz-border-left-colors: none;"> <section class="" style="margin-top: 30px;margin-bottom: 5px;text-align: center;box-sizing: border-box;"> <section class="" style="padding: 10px 10px 5px;display: inline-block;width: 530.094px;vertical-align: top;box-shadow: 1.41421px 1.41421px 6px rgb(185, 185, 185);box-sizing: border-box;"> <section style="box-sizing: border-box;"> <section class="" style="margin-bottom: 15px;box-sizing: border-box;"> <section class="" style="max-width: 100%;vertical-align: middle;display: inline-block;box-shadow: 0px 0px 0px rgb(0, 0, 0);box-sizing: border-box;overflow: hidden ! important;"> <img class="" data-ratio="1.0094876660341556" src="/upload/58eda238170ec7ecc3c0b8045402cb0a.jpg" data-type="jpeg" data-w="527" style="vertical-align: middle;box-sizing: border-box;"> </section> </section> </section> </section> </section> </section> <section class="_135editor" style="box-sizing: border-box;border-width: 0px;border-style: none;border-color: currentcolor;-moz-border-top-colors: none;-moz-border-right-colors: none;-moz-border-bottom-colors: none;-moz-border-left-colors: none;"> <section class="" style="margin-top: 5px;margin-bottom: 10px;text-align: center;box-sizing: border-box;"> <section class="" style="padding: 10px 10px 15px;display: inline-block;width: 530.094px;vertical-align: top;box-shadow: 1.41421px 1.41421px 6px rgb(185, 185, 185);box-sizing: border-box;"> <section style="box-sizing: border-box;"> <section class="" style="margin-top: -30px;box-sizing: border-box;"> <section class="" style="display: inline-block;vertical-align: top;width: 255.047px;box-sizing: border-box;"> <section style="box-sizing: border-box;"> <section class="" style="box-sizing: border-box;"> <section class="" style="max-width: 100%;vertical-align: middle;display: inline-block;box-shadow: 0px 0px 0px rgb(0, 0, 0);width: 242.281px;box-sizing: border-box;overflow: hidden ! important;"> <img class="" data-ratio="0.2196078431372549" src="/upload/7cf3089e8987dfc7edc1bc29fe8411bd.png" data-type="png" data-w="255" style="vertical-align: middle;width: 242.281px;box-sizing: border-box;"> </section> </section> </section> </section> <section class="" style="display: inline-block;vertical-align: top;width: 255.047px;box-shadow: 0px 0px 0px rgb(0, 0, 0);box-sizing: border-box;"> <section style="box-sizing: border-box;"> <section class="" style="box-sizing: border-box;"> <section class="" style="max-width: 100%;vertical-align: middle;display: inline-block;width: 242.281px;box-sizing: border-box;overflow: hidden ! important;"> <img class="" data-ratio="0.2196078431372549" src="/upload/7cf3089e8987dfc7edc1bc29fe8411bd.png" data-type="png" data-w="255" style="vertical-align: middle;width: 242.281px;box-sizing: border-box;"> </section> </section> </section> </section> </section> </section> <section style="box-sizing: border-box;"> <section class="" style="box-sizing: border-box;"> <section class="" style="text-align: left;box-sizing: border-box;"> <p style="box-sizing: border-box;"><br></p> </section> </section> </section> <section style="box-sizing: border-box;"> <section class="" style="box-sizing: border-box;"> <section class="" style="padding-right: 5px;padding-left: 5px;font-size: 15px;box-sizing: border-box;"> <p style="text-align: justify;box-sizing: border-box;">If I knew I wasn’t going to fall asleep in the last 2 hours, I could have been using the Internet! </p> </section> </section> </section> <section style="box-sizing: border-box;"> <section class="" style="margin-top: 8px;margin-bottom: 18px;box-sizing: border-box;"> <section class="" style="border-top: 1px dashed rgb(185, 185, 185);box-sizing: border-box;"></section> </section> </section> <section style="box-sizing: border-box;"> <section class="" style="text-align: left;box-sizing: border-box;"> <section class="" style="padding-right: 5px;padding-left: 5px;text-align: justify;font-size: 15px;letter-spacing: 2px;box-sizing: border-box;"> <p style="box-sizing: border-box;">早知道花了两个小时都没睡着,我本可以好好上上网的。</p> </section> </section> </section> </section> </section> </section> <section class="_135editor" style="box-sizing: border-box;border-width: 0px;border-style: none;border-color: currentcolor;-moz-border-top-colors: none;-moz-border-right-colors: none;-moz-border-bottom-colors: none;-moz-border-left-colors: none;"> <section class="" style="box-sizing: border-box;"> <section class="" style="box-sizing: border-box;"> <p style="box-sizing: border-box;"><br></p> </section> </section> </section> <section class="_135editor" style="box-sizing: border-box;border-width: 0px;border-style: none;border-color: currentcolor;-moz-border-top-colors: none;-moz-border-right-colors: none;-moz-border-bottom-colors: none;-moz-border-left-colors: none;"> <section class="" style="box-sizing: border-box;"> <section class="" style="box-sizing: border-box;"> <p style="box-sizing: border-box;"><br></p> </section> </section> </section> <section class="_135editor" style="box-sizing: border-box;border-width: 0px;border-style: none;border-color: currentcolor;-moz-border-top-colors: none;-moz-border-right-colors: none;-moz-border-bottom-colors: none;-moz-border-left-colors: none;"> <section class="" style="margin-top: 3px;margin-bottom: 3px;text-align: center;box-sizing: border-box;"> <section class="" style="margin-right: auto;margin-left: auto;display: inline-block;border-width: 1px;border-style: solid;border-color: rgb(190, 182, 145);width: 1.8em;height: 1.8em;line-height: 1.8em;border-radius: 100%;font-size: 18px;box-sizing: border-box;background-color: rgb(190, 182, 145);"> <p style="box-sizing: border-box;"><strong style="box-sizing: border-box;">7</strong></p> </section> </section> </section> <section class="_135editor" style="box-sizing: border-box;border-width: 0px;border-style: none;border-color: currentcolor;-moz-border-top-colors: none;-moz-border-right-colors: none;-moz-border-bottom-colors: none;-moz-border-left-colors: none;"> <section class="" style="margin-top: 30px;margin-bottom: 5px;text-align: center;box-sizing: border-box;"> <section class="" style="padding: 10px 10px 5px;display: inline-block;width: 530.094px;vertical-align: top;box-shadow: 1.41421px 1.41421px 6px rgb(185, 185, 185);box-sizing: border-box;"> <section style="box-sizing: border-box;"> <section class="" style="margin-bottom: 15px;box-sizing: border-box;"> <section class="" style="max-width: 100%;vertical-align: middle;display: inline-block;box-shadow: 0px 0px 0px rgb(0, 0, 0);box-sizing: border-box;overflow: hidden ! important;"> <img class="" data-ratio="1.0114068441064639" src="/upload/c69ca7aefc8b4c7cf787f46e63c1b275.jpg" data-type="jpeg" data-w="526" style="vertical-align: middle;box-sizing: border-box;"> </section> </section> </section> </section> </section> </section> <section class="_135editor" style="box-sizing: border-box;border-width: 0px;border-style: none;border-color: currentcolor;-moz-border-top-colors: none;-moz-border-right-colors: none;-moz-border-bottom-colors: none;-moz-border-left-colors: none;"> <section class="" style="margin-top: 5px;margin-bottom: 10px;text-align: center;box-sizing: border-box;"> <section class="" style="padding: 10px 10px 15px;display: inline-block;width: 530.094px;vertical-align: top;box-shadow: 1.41421px 1.41421px 6px rgb(185, 185, 185);box-sizing: border-box;"> <section style="box-sizing: border-box;"> <section class="" style="margin-top: -30px;box-sizing: border-box;"> <section class="" style="display: inline-block;vertical-align: top;width: 255.047px;box-sizing: border-box;"> <section style="box-sizing: border-box;"> <section class="" style="box-sizing: border-box;"> <section class="" style="max-width: 100%;vertical-align: middle;display: inline-block;box-shadow: 0px 0px 0px rgb(0, 0, 0);width: 242.281px;box-sizing: border-box;overflow: hidden ! important;"> <img class="" data-ratio="0.2196078431372549" src="/upload/7cf3089e8987dfc7edc1bc29fe8411bd.png" data-type="png" data-w="255" style="vertical-align: middle;width: 242.281px;box-sizing: border-box;"> </section> </section> </section> </section> <section class="" style="display: inline-block;vertical-align: top;width: 255.047px;box-shadow: 0px 0px 0px rgb(0, 0, 0);box-sizing: border-box;"> <section style="box-sizing: border-box;"> <section class="" style="box-sizing: border-box;"> <section class="" style="max-width: 100%;vertical-align: middle;display: inline-block;width: 242.281px;box-sizing: border-box;overflow: hidden ! important;"> <img class="" data-ratio="0.2196078431372549" src="/upload/7cf3089e8987dfc7edc1bc29fe8411bd.png" data-type="png" data-w="255" style="vertical-align: middle;width: 242.281px;box-sizing: border-box;"> </section> </section> </section> </section> </section> </section> <section style="box-sizing: border-box;"> <section class="" style="box-sizing: border-box;"> <section class="" style="text-align: left;box-sizing: border-box;"> <p style="box-sizing: border-box;"><br></p> </section> </section> </section> <section style="box-sizing: border-box;"> <section class="" style="box-sizing: border-box;"> <section class="" style="padding-right: 5px;padding-left: 5px;text-align: justify;font-size: 15px;box-sizing: border-box;"> <p style="box-sizing: border-box;">Person is tying…</p> <p style="box-sizing: border-box;">Person is tying…</p> <p style="box-sizing: border-box;">Person is tying…</p> <p style="box-sizing: border-box;">Person is tying…</p> <p style="box-sizing: border-box;">Person is tying…</p> <p style="box-sizing: border-box;">Person says:<strong style="box-sizing: border-box;">hi</strong></p> </section> </section> </section> <section style="box-sizing: border-box;"> <section class="" style="margin-top: 8px;margin-bottom: 18px;box-sizing: border-box;"> <section class="" style="border-top: 1px dashed rgb(185, 185, 185);box-sizing: border-box;"></section> </section> </section> <section style="box-sizing: border-box;"> <section class="" style="text-align: left;box-sizing: border-box;"> <section class="" style="padding-right: 5px;padding-left: 5px;font-size: 15px;letter-spacing: 2px;box-sizing: border-box;"> <p style="box-sizing: border-box;">对方正在输入……</p> <p style="box-sizing: border-box;">对方正在输入……</p> <p style="box-sizing: border-box;">对方正在输入……</p> <p style="box-sizing: border-box;">对方正在输入……</p> <p style="box-sizing: border-box;">对方正在输入……</p> <p style="box-sizing: border-box;">对方说:<strong style="box-sizing: border-box;">嗨</strong>。</p> </section> </section> </section> </section> </section> </section> <section class="_135editor" style="box-sizing: border-box;border-width: 0px;border-style: none;border-color: currentcolor;-moz-border-top-colors: none;-moz-border-right-colors: none;-moz-border-bottom-colors: none;-moz-border-left-colors: none;"> <section class="" style="box-sizing: border-box;"> <section class="" style="box-sizing: border-box;"> <p style="box-sizing: border-box;"><br></p> </section> </section> </section> <section class="_135editor" style="box-sizing: border-box;border-width: 0px;border-style: none;border-color: currentcolor;-moz-border-top-colors: none;-moz-border-right-colors: none;-moz-border-bottom-colors: none;-moz-border-left-colors: none;"> <section class="" style="box-sizing: border-box;"> <section class="" style="box-sizing: border-box;"> <p style="box-sizing: border-box;"><br></p> </section> </section> </section> <section class="_135editor" style="box-sizing: border-box;border-width: 0px;border-style: none;border-color: currentcolor;-moz-border-top-colors: none;-moz-border-right-colors: none;-moz-border-bottom-colors: none;-moz-border-left-colors: none;"> <section class="" style="margin-top: 3px;margin-bottom: 3px;text-align: center;box-sizing: border-box;"> <section class="" style="margin-right: auto;margin-left: auto;display: inline-block;border-width: 1px;border-style: solid;border-color: rgb(190, 182, 145);width: 1.8em;height: 1.8em;line-height: 1.8em;border-radius: 100%;font-size: 18px;box-sizing: border-box;background-color: rgb(190, 182, 145);"> <p style="box-sizing: border-box;"><strong style="box-sizing: border-box;">8</strong></p> </section> </section> </section> <section class="_135editor" style="box-sizing: border-box;border-width: 0px;border-style: none;border-color: currentcolor;-moz-border-top-colors: none;-moz-border-right-colors: none;-moz-border-bottom-colors: none;-moz-border-left-colors: none;"> <section class="" style="margin-top: 30px;margin-bottom: 5px;text-align: center;box-sizing: border-box;"> <section class="" style="padding: 10px 10px 5px;display: inline-block;width: 5
作者:微信小助手
<p style="text-align: center;margin-bottom: 10px;" data-mpa-powered-by="yiban.io"><span style="color: rgb(51, 51, 51);letter-spacing: 0.544px;text-align: center;background-color: rgb(255, 255, 255);font-family: CourierNewPS-ItalicMT;font-size: 13px;">【公众号回复“</span><strong style="color: rgb(51, 51, 51);letter-spacing: 0.544px;text-align: center;white-space: normal;background-color: rgb(255, 255, 255);font-family: CourierNewPS-ItalicMT;font-size: 13px;"><span style="color: rgb(0, 82, 255);">1024</span></strong><span style="color: rgb(51, 51, 51);letter-spacing: 0.544px;text-align: center;background-color: rgb(255, 255, 255);font-family: CourierNewPS-ItalicMT;font-size: 13px;">”,送你一个特别推送】</span></p> <p style="text-align: center;"><img class="" data-backh="314" data-backw="498" data-before-oversubscription-url="https://mmbiz.qpic.cn/mmbiz_jpg/CvQa8Yf8vq3wwribUdUxuEEc9vIz7EHtibtjXDb19QxHax8ic8ruUY1vWdxKJRdPH8LUv9yqagS1EPYaNLRyGickWQ/0?wx_fmt=jpeg" data-copyright="0" data-oversubscription-url="http://mmbiz.qpic.cn/mmbiz_jpg/CvQa8Yf8vq3wwribUdUxuEEc9vIz7EHtibB7SpHrqhqnVQuswoJFS0rC3aYG1dJG4fLXVwAVE9ic34q2Rz98IlrMw/0?wx_fmt=jpeg" data-ratio="0.6292585170340681" data-s="300,640" src="/upload/9803b13e5d56b89580f5a7c9ffc6411a.jpg" data-type="jpeg" data-w="499" style="width: 100%;height: auto;"></p> <h3 style="margin-top: 20px;margin-bottom: 10px;font-size: 18px;letter-spacing: 1.4px;white-space: normal;color: rgb(0, 150, 136) !important;">判空灾难</h3> <p style="font-size: 14px;letter-spacing: 1.4px;white-space: normal;margin: 1.5em 5px !important;"><img class="" data-ratio="0.215" src="/upload/d116859653b25b1597bfdeae48129713.png" data-type="png" data-w="1000"></p> <p style="font-size: 14px;letter-spacing: 1.4px;white-space: normal;margin: 1.5em 5px !important;">作为搬砖党的一族们,我们对判空一定再熟悉不过了,不要跟我说你很少进行判空,除非你喜欢NullPointerException。</p> <p style="font-size: 14px;letter-spacing: 1.4px;white-space: normal;margin: 1.5em 5px !important;">不过NullPointerException对于很多猿们来说,也是Exception家族中最亲近的一员了。</p> <p style="font-size: 14px;letter-spacing: 1.4px;white-space: normal;margin: 1.5em 5px !important;text-align: center;"><img class="" data-ratio="0.6654545454545454" src="/upload/73df1eea2116386a9df9b55ed5078e15.png" data-type="png" data-w="275"></p> <p style="font-size: 14px;letter-spacing: 1.4px;white-space: normal;margin: 1.5em 5px !important;">为了避免NullPointerException来找我们,我们经常会进行如下操作。</p> <section data-mpa-preserve-tpl-color="t" data-mpa-template="t" class="mpa-template" mpa-preserve="t"> <pre style="margin:0;padding:0;border-radius:none;background:none;"><code style="border-radius: 4px;font-size: 0.85em;margin: 0px 0.15em;background: rgb(40, 44, 52);color: rgb(171, 178, 191);display: block;padding: 5.95px;overflow-x: auto;white-space: nowrap;" class="hljs-default"><span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 14px;text-decoration: none solid rgb(198, 120, 221);font-weight: 400;font-style: normal;">if</span> (data != <span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 26px;text-decoration: none solid rgb(198, 120, 221);font-weight: 400;font-style: normal;">null</span>) {<br> <span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 14px;text-decoration: none solid rgb(198, 120, 221);font-weight: 400;font-style: normal;">do</span> sth.<br>}</code></pre> </section> <p style="font-size: 14px;letter-spacing: 1.4px;white-space: normal;margin: 1.5em 5px !important;">如果一个类中多次使用某个对象,那你可能要一顿操作,so:<br></p> <p style="font-size: 14px;letter-spacing: 1.4px;white-space: normal;margin: 1.5em 5px !important;text-align: center;"><img class="" data-ratio="2.2931596091205213" src="/upload/c4b7a239fbac66a8b2699d1525a0afa4.png" data-type="png" data-w="307"></p> <p style="font-size: 14px;letter-spacing: 1.4px;white-space: normal;margin: 1.5em 5px !important;">“世界第九大奇迹”就这样诞生了。Maybe你会想,项目中肯定不止你一个人会这样一顿操作,然后按下Command+Shift+F,真相就在眼前:</p> <p style="font-size: 14px;letter-spacing: 1.4px;white-space: normal;margin: 1.5em 5px !important;text-align: center;"><img class="" data-ratio="0.21584699453551912" src="/upload/d35654d21845f0ec43b2a042132a0086.png" data-type="png" data-w="366"></p> <p style="font-size: 14px;letter-spacing: 1.4px;white-space: normal;margin: 1.5em 5px !important;">What,我们有接近一万行的代码都是在判空?</p> <p style="font-size: 14px;letter-spacing: 1.4px;white-space: normal;margin: 1.5em 5px !important;text-align: center;"><img class="" data-ratio="0.75" src="/upload/79df88a5fe8be0a8f595eb61f66366e7.png" data-type="png" data-w="480"></p> <p style="font-size: 14px;letter-spacing: 1.4px;white-space: normal;margin: 1.5em 5px !important;">好了,接下来,要进入正题了。</p> <h3 style="margin-top: 20px;margin-bottom: 10px;font-size: 18px;letter-spacing: 1.4px;white-space: normal;color: rgb(0, 150, 136) !important;">NullObject模式</h3> <p style="font-size: 14px;letter-spacing: 1.4px;white-space: normal;margin: 1.5em 5px !important;">对于项目中无数次的判空,对代码质量整洁度产生了十分之恶劣的影响,对于这种现象,我们称之为“判空灾难”。</p> <p style="font-size: 14px;letter-spacing: 1.4px;white-space: normal;margin: 1.5em 5px !important;">那么,这种现象如何治理呢,你可能听说过NullObject模式,不过这不是我们今天的武器,但是还是需要介绍一下NullObject模式。</p> <p style="font-size: 14px;letter-spacing: 1.4px;white-space: normal;margin: 1.5em 5px !important;">什么是NullObject模式呢?</p> <blockquote style="margin: 10px 5px 10px 1em;padding-right: 10px;border-left-width: 2px;border-left-color: rgb(0, 150, 136);font-size: 14px;letter-spacing: 1.4px;white-space: normal;color: rgb(119, 119, 119);quotes: none;"> <p style="margin: 1.5em 5px !important;">In object-oriented computer programming, a null object is an object with no referenced value or with defined neutral (“null”) behavior. The null object design pattern describes the uses of such objects and their behavior (or lack thereof).</p> </blockquote> <p style="font-size: 14px;letter-spacing: 1.4px;white-space: normal;margin: 1.5em 5px !important;">以上解析来自Wikipedia。</p> <p style="font-size: 14px;letter-spacing: 1.4px;white-space: normal;margin: 1.5em 5px !important;">NullObject模式首次发表在“ 程序设计模式语言 ”系列丛书中。一般的,在面向对象语言中,对对象的调用前需要使用判空检查,来判断这些对象是否为空,因为在空引用上无法调用所需方法。</p> <p style="font-size: 14px;letter-spacing: 1.4px;white-space: normal;margin: 1.5em 5px !important;">空对象模式的一种典型实现方式如下图所示(图片来自网络):</p> <p style="font-size: 14px;letter-spacing: 1.4px;white-space: normal;margin: 1.5em 5px !important;text-align: center;"><img class="" data-ratio="0.45481927710843373" src="/upload/9c4719b1232f813dd8edddcc0f80375b.png" data-type="png" data-w="332"></p> <p style="font-size: 14px;letter-spacing: 1.4px;white-space: normal;margin: 1.5em 5px !important;">示例代码如下(命名来自网络,哈哈到底是有多懒):</p> <p style="font-size: 14px;letter-spacing: 1.4px;white-space: normal;margin: 1.5em 5px !important;">Nullable是空对象的相关操作接口,用于确定对象是否为空,因为在空对象模式中,对象为空会被包装成一个Object,成为Null Object,该对象会对原有对象的所有方法进行空实现。</p> <section data-mpa-preserve-tpl-color="t" data-mpa-template="t" class="mpa-template" mpa-preserve="t"> <pre style="margin:0;paddi