Admin▫ 骑着驴儿去编程
操了
关注数: 20 粉丝数: 250 发帖数: 18,768 关注贴吧数: 9
失望,就这么处理了 欧皇活动处理说明 亲爱的车友们: 由于“燃擎之夜寻庆典欧皇”抽奖活动出现异常,严重影响了车友们的活动体验,目前异常问题已经修复,经过慎重考虑,我们最终决定按照以下方案对本次活动异常情况进行处理: 1、原定于7月2日20:00举行的幸运车友宠物抽奖,将在7月7日20:00重新举行,为了感谢车友们对活动的热情,同时也为了向车友们表示我们的歉意,我们决定在7日额外抽取100位幸运车友,即共计抽取200位幸运车友,可有机会在奖池内全部传说级宠物中任选1个宠物;7月8日、7月9日的抽奖规则不变,仍按照初始活动规则,即每日分别抽取100位幸运车友获得自选车手及赛车,还请车友们后续关注活动开奖; 2、由于7月3日20:00的车手抽奖延期,我们将对7月3日20:00前邀请满3个车友且获得活动抽奖资格的车友作出延期补偿!补偿奖励为酷币*1888,补偿奖励将于3个工作日内邮件发放至各位车友,请注意查收; 3、针对7月2日20:00已获奖的车友,考虑到这部分车友并非主观刻意利用活动异常而获利,且确认满足参与抽奖的资格,因此,我们对7月2日获奖的车友,所获奖励不作回收,但该部分车友将无法重新参与7月7日20:00的宠物抽奖(可继续参与7月8日及7月9日的抽奖),同时不包含在抽奖延期补偿名单内; 给车友们带来的不便,我们深表歉意,感谢您的理解与支持,祝您游戏愉快~ 跑跑手游运营团队 2021年7月5日
如何优化代码中大量的if/else,switch/case? 前言 随着项目的迭代,代码中存在的分支判断可能会越来越多,当里面涉及到的逻辑比较复杂或者分支数量实在是多的难以维护的时候,我们就要考虑下,有办法能让这些代码变得更优雅吗? 正文 使用枚举 这里我们简单的定义一个表示状态的枚举。 public enum Status { NEW(0),RUNNABLE(1),RUNNING(2),BLOCKED(3),DEAD(4); public int statusCode; Status(int statusCode){ this.statusCode = statusCode; } } 那么我们在使用的时候就可以直接通过枚举调用了。 int statusCode = Status.valueOf("NEW").statusCode; 优雅的解决了下面代码赋值的方式 if(param.equals("NEW")){ statusCode = 0; }else if(param.equals("RUNNABLE")){ statusCode = 1; } ... 善用 Optional 在项目中,总少不了一些非空的判断,可能大部分人还是如下的用法 if(null == user){ //action2 }else{ //action1 } 这时候该掏出Optional这个秘密武器了,它可以让非空校验更加优雅,间接的减少if操作。没了解过Optional的同学可自行Google,这里就不再赘述。 Optional<User> userOptional = Optional.ofNullable(user); userOptional.map(action1).orElse(action2); 上面的代码跟第一段是等效的,通过一些新特性让代码更加紧凑。 表驱动法 来自Google的解释:表驱动法是一种编程模式,它的本质是,从表里查询信息来代替逻辑语句(if,case)。下面看一个案例,通过月份来获取当月的天数(仅作为案例演示,获取2月份的数据不严谨),普通做法: int getMonthDays(int month){ switch(month){ case 1:return 31;break; case 2:return 29;break; case 3:return 31;break; case 4:return 30;break; case 5:return 31;break; case 6:return 30;break; case 7:return 31;break; case 8:return 31;break; case 9:return 30;break; case 10:return 31;break; case 11:return 30;break; case 12:return 31;break; default:return 0; } } 表驱动法实现方式 int monthDays[12] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; int getMonthDays(int month){ return monthDays[--month]; } 其实这里的表就是数组而已,通过直接查询数组来获得需要的数据,那么同理,Map之类的容器也可以成为我们编程概念中的表。 Map<?, Function<?> action> actionsMap = new HashMap<>(); // 初试配置对应动作 actionsMap.put(value1, (someParams) -> { doAction1(someParams)}); actionsMap.put(value2, (someParams) -> { doAction2(someParams)}); actionsMap.put(value3, (someParams) -> { doAction3(someParams)}); // 省略 null 判断 actionsMap.get(param).apply(someParams); 通过Java8的lambda表达式,我们把需要执行东西存进value中,调用的时候通过匹配key的方式进行。 提前判断返回 在之前的文章《优化代码中的“坏味道”》里也有提过,如下语句 if(condition){ //dost }else{ return ; } 改为 if(!condition){ return ; } //dost 避免一些不必要的分支,让代码更精炼。 其他方法 除了上面提到的方法,我们还可以通过一些设计模式,例如策略模式,责任链模式等来优化存在大量if,case的情况,其原理会和表驱动的模式比较相似,大家可以自己动手实现一下,例如我们在Netty的使用过程中,可能会出现需要大量判断不同的命令去执行对应动作的场景。 ServerHandler.java if(command.equals("login")){ //执行登录 }else if(command.equals("chat")){ //聊天 }else if(command.equals("broadcast")){ //广播信息 } .... 该如何处理呢?这里先卖个关子,大家可以先思考一下,笔记后续会写一些关于Netty实现IM的文章,到时候会详细介绍。 结语 最后要明确一点,不是所有的if/else,switch/case都需要优化,当我们发现有“痛点”或者“闻到代码有坏味道”再来优化才是最好的,不然你可能会写了一个从不扩展的可扩展代码,所有的优化都是为了更好的迭代项目,更好的服务于业务,而不是为了优化而优化。
大白话搞懂什么是同步/异步/阻塞/非阻塞 前言 在最近的一些面试中,跟应聘者聊了比较多关于“同步/异步,阻塞/非阻塞”相关的话题,发现大家对于这些概念的理解都比较模糊,甚至有的同学会反问“他们不就是同一个东西吗?”。所以借着这么一个机会,我想用一些尽量简单的例子,尽量简洁的语言来聊聊自己对于这些概念的看法。 正文 这篇文章想通过一个老王“候车”的案例来解释这些概念。 同步阻塞 放假了,老王回到了乡下,由于乡下的基础设施比较差,当他在车站候车的时候,只能一直在干等着,直到公交车的到站。 这时候对于公交车(被调用着者)来说,它是“同步“的。老王(调用者)被公交车(被调用者)“阻塞”在站台上。 异步阻塞 放完假了,老王回到了大城市开始上班,同样在车站候车,一样在车站干等着,但是大城市的基础设施建设得比较好,当公交车到站的时候,会有广播提示提醒乘客。 那么这时候对于公交车(被调用着者)来说,它是“异步“的,到站后会通知调用者。但是此时老王(调用者)还是被公交车(被调用者)“阻塞”在站台上。 同步非阻塞 过年了,老王放假回来了乡下,又要开始候车了,这时候他变聪明了,没有一直在车站上干等着,而是去找隔壁的小花叙叙旧。但是又害怕车到站了自己会错过,就只能隔一段时间过来看看车到了没。 那么这时候对于公交车(被调用着者)来说,它是“同步“的。但是此时老王(调用者)可以在候车的时候去干其他的的事情,所以他是“非阻塞”的。 异步非阻塞 春风吹满地,新农村建设正在火热进行中,此时的乡下,公交车里面也安装了车辆到站的提醒广播。现在老王在候车的时候,可以安心的跟小花叙旧了,当听到自己需要乘坐的车辆到站广播时,才过去车站上车。 这时候对于公交车(被调用着者)来说,它是“异步“的,到站后会广播提醒,此时老王(调用者)可以在候车的时候去干其他的的事情,所以他是“非阻塞”的 概念总结 从上面的示例中,我们可以明白一件事情,同步异步,阻塞非阻塞他们针对的对象是不一样的。对于调用者来说是阻塞跟非阻塞,被调用者是同步跟异步。 同步:A调用B,此时只有等B有结果了才返回。 异步: A调用B,B立即返回,无须等待。当B处理完之后会通过通知或者回调函数的方式来告诉A结果。 阻塞:A调用B,A会被被挂起,一直在等待B的结果,什么事都不能干。 非阻塞:A调用B,自己用被挂起等待B的结果,可以去干其他的事情。 Java中相关概念 在Java中的IO模型有三种,分别是BIO(同步阻塞IO),NIO(同步非阻塞IO),AIO(异步非阻塞IO)。这时候我们会发现,异步阻塞的模型是不存在的。 NIO跟AIO的出现解决了很多在BIO使用过程遇到的难题,所以我们在选择使用何种IO的时候需要根据业务场景来做决定,没必要一味追求NIO跟AIO,不仅加大了编码的难度也提高的出错的概率,技术的出现是为了更好的解决问题。 结语 这篇文章主要是想通过大家熟悉的场景来描述这些概念的含义以及区别,如果想更深入的去钻研的话,大家可以去查阅Linux IO模型相关资料,Java的IO API也是基于这些基础模型来封装的。
大白话搞懂什么是同步/异步/阻塞/非阻塞 前言 在最近的一些面试中,跟应聘者聊了比较多关于“同步/异步,阻塞/非阻塞”相关的话题,发现大家对于这些概念的理解都比较模糊,甚至有的同学会反问“他们不就是同一个东西吗?”。所以借着这么一个机会,我想用一些尽量简单的例子,尽量简洁的语言来聊聊自己对于这些概念的看法。 正文 这篇文章想通过一个老王“候车”的案例来解释这些概念。 同步阻塞 放假了,老王回到了乡下,由于乡下的基础设施比较差,当他在车站候车的时候,只能一直在干等着,直到公交车的到站。 这时候对于公交车(被调用着者)来说,它是“同步“的。老王(调用者)被公交车(被调用者)“阻塞”在站台上。 异步阻塞 放完假了,老王回到了大城市开始上班,同样在车站候车,一样在车站干等着,但是大城市的基础设施建设得比较好,当公交车到站的时候,会有广播提示提醒乘客。 那么这时候对于公交车(被调用着者)来说,它是“异步“的,到站后会通知调用者。但是此时老王(调用者)还是被公交车(被调用者)“阻塞”在站台上。 同步非阻塞 过年了,老王放假回来了乡下,又要开始候车了,这时候他变聪明了,没有一直在车站上干等着,而是去找隔壁的小花叙叙旧。但是又害怕车到站了自己会错过,就只能隔一段时间过来看看车到了没。 那么这时候对于公交车(被调用着者)来说,它是“同步“的。但是此时老王(调用者)可以在候车的时候去干其他的的事情,所以他是“非阻塞”的。 异步非阻塞 改革春风吹满地,新农村建设正在火热进行中,此时的乡下,公交车里面也安装了车辆到站的提醒广播。现在老王在候车的时候,可以安心的跟小花叙旧了,当听到自己需要乘坐的车辆到站广播时,才过去车站上车。 这时候对于公交车(被调用着者)来说,它是“异步“的,到站后会广播提醒,此时老王(调用者)可以在候车的时候去干其他的的事情,所以他是“非阻塞”的 概念总结 从上面的示例中,我们可以明白一件事情,同步异步,阻塞非阻塞他们针对的对象是不一样的。对于调用者来说是阻塞跟非阻塞,被调用者是同步跟异步。 同步:A调用B,此时只有等B有结果了才返回。 异步: A调用B,B立即返回,无须等待。当B处理完之后会通过通知或者回调函数的方式来告诉A结果。 阻塞:A调用B,A会被被挂起,一直在等待B的结果,什么事都不能干。 非阻塞:A调用B,自己用被挂起等待B的结果,可以去干其他的事情。 Java中相关概念 在Java中的IO模型有三种,分别是BIO(同步阻塞IO),NIO(同步非阻塞IO),AIO(异步非阻塞IO)。这时候我们会发现,异步阻塞的模型是不存在的。 NIO跟AIO的出现解决了很多在BIO使用过程遇到的难题,所以我们在选择使用何种IO的时候需要根据业务场景来做决定,没必要一味追求NIO跟AIO,不仅加大了编码的难度也提高的出错的概率,技术的出现是为了更好的解决问题。 结语 这篇文章主要是想通过大家熟悉的场景来描述这些概念的含义以及区别,如果想更深入的去钻研的话,大家可以去查阅Linux IO模型相关资料,Java的IO API也是基于这些基础模型来封装的。
1 下一页