美团一面:项目中有 10000 个 if else 如何优化?想了半天,被问懵了!

news/2024/11/14 13:17:49/文章来源:https://www.cnblogs.com/javastack/p/18203306

大家好,我是R哥。

最近做 Java 面试辅导,有个兄弟面试美团,遇到一个特别有意思的问题:

一万个 if else 如何优化,有好的解决方案吗?

我看到这问题都有点懵逼,现实项目中怎么可能会有 10000 个 if else 的代码,至少我工作 10 余年没见过样的代码。

关键要写完这 10000 行的 if else 代码,如果每天写 100 个,是不是意味着也要 100 天才能写完,并且每次请求都要执行几千上万次的判断,代码难以维护不说,还会严重影响系统性能

很显然,面试官考察的不是一般的八股文,这个问题可以看作是一道场景题,它考察一个程序员在面对复杂逻辑判断时的优化能力,也是在考察一个程序员临场发挥技术能力

这兄弟虽然说上了策略模式,但显然不是完美和唯一的解决方案,另外像责任链模式等其他设计模式都会存在这样的问题,所以具体的问题还得具体分析。

所以这题可以这样回答:

  • 如果这 1 万个 if else 是在同一个代码块流程里面,这就要考虑这 1 万 if else 存在的意义了,因为这么量极的 if else 会很难维护,也会极其影响性能,需要具体分析然后再去分析如何去分解和优化。
  • 如果这 1 万个 if else 分散在同一个项目里面,那么优化 if else 的方式有很多种,包括.……

下面我说说几种方案,欢迎大家拍砖。

if else 优化方案

方案1:策略模式

这个兄弟也说到了策略模式,策略模式介绍及实战看这篇:

别在再满屏的 if/ else 了,试试策略模式,真香!!

使用策略模式确实可以提升代码的优雅性,但也会存在以下问题:

  • 如果是大量的 if else 分支,比如这 1 万个,那就会有 1 万个策略类,此时就会造成类膨胀,并且随着时间的推移逐渐变得更加庞大而复杂
  • 如果是多层的 if else 嵌套,策略模式可能也无法派上用场了。

策略模式的优点是可以很方便的解耦,适用于有多种不同逻辑和算法的 if 场景,但不适用于大量的 if else 场景。

方案2:策略模式变体

这是策略模式的一种变体:

Map<Integer, Runnable> actionMap = new HashMap<>();
actionMap.put("condition1", () -> { /* 分支1的执行逻辑 */ });
actionMap.put("condition2", () -> { /* 分支2的执行逻辑 */ });
actionMap.put("conditionN", () -> { /* 分支N的执行逻辑 */ });// 根据条件获取执行逻辑
Runnable action = actionMap.get("condition1");
if (action != null) {action.run();
}

这种把业务逻辑代码分离出去了,简化了单个类的代码,也省去了策略实现类,让策略类不会得到膨胀,但如果有大量的条件映射,依然会造成单个类的膨胀和难以维护。

这里使用的是线程异步执行的案例,还可以把要执行的逻辑代码存储在其他类、数据库中,然后再用反射或者动态编译的方式加载进去并执行。

方案3:多级嵌套优化

上面说的两种方案嵌套可能无法解决,如果是这种带层级的判断是可以优化的:

/*
* 来源公众号:Java技术栈 
*/
if(xxxOrder != null){if(xxxOrder.getXxxShippingInfo() != null){if(xxxOrder.getXxxShippingInfo().getXxxShipmentDetails() != null){if(xxxOrder.getXxxShippingInfo().getXxxShipmentDetails().getXxxTrackingInfo() != null){...}}}
}

这种 if 嵌套层级太多,极不优雅,怎么优化见我之前写的这篇:

if else 太多?看我用 Java 8 轻松干掉!

方案4:使用三目运算符

如果判断条件不多,只有 2、3 个的情况下可以使用三目运算符简化 if else 分支。

比如以下代码:

String desc;
if (condition1) {desc = "XX1";
} else if (condition2) {desc = "XX2";
} else {desc = "XX3";
}

使用三目运算符一行搞定:

String desc = condition1 ? "XX1" : (condition2 ? "XX2" : "XX3");

超过 3 个条件就不建议使用了,不然代码可读性会大大降低。

方案5:使用枚举

枚举类型可以用来表示一组固定的值,例如星期几、月份、颜色等,它提供了一种更简洁、可读性更高的方式来表示一组相关的常量。

如以下示例代码:

/*** 公众号:Java技术栈*/
public class Test {public static void main(String[] args) {Day today = Day.MONDAY;System.out.println("Today is " + today);System.out.println("Today is " + today.getChineseName());}enum Day {MONDAY("星期一"),TUESDAY("星期二"),WEDNESDAY("星期三"),THURSDAY("星期四"),FRIDAY("星期五"),SATURDAY("星期六"),SUNDAY("星期日");private String chineseName;Day(String chineseName) {this.chineseName = chineseName;}public String getChineseName() {return chineseName;}}}

这里我只写了一个字段,我们可以在枚举属性里面定义多个字段,这样就无需大量的 if else 判断,直接通过枚举来获取某个某一组固定的值了。

方案6:使用 Optional

Java 8 提供了一个 Optional 新特性,它是一个可以包含 null 值的容器对象,可以用来代替 xx != null 的判断。

参考我之前写的这篇:

JDK 8 新特性之 Optional

如果项目中存在大量 xx != null 的判断,可以使用 Optional 来优化。

方案7:尽快返回

分析业务,根据 if else 的执行次数按降序排,把执行次数较多的 if 放在最前面,如果符合条件,就使用 return 返回,如下面代码:

if (条件1) {return
}if (条件2) {return
}...

这样改可能是比较简单的方式,在很大程度上可以提升系统的性能,但是还存在以下问题:

  • 有的条件不能按执行次数排序,存在先后或者互斥关系。
  • 如果新增一个条件,可能无法马上判定它的执行次数,如果放在后面可能也还会影响性能。
  • 对类的继续膨胀和代码维护没有任何帮助。

方案8:去除没必要的 if else

比如这种:

if (condition) {...
} else {return;
}

优化后:

if(!condition){return;
}

或者是这样:

return !condition

方案9:合并条件

考虑这 1 万 if else 是不是真的每个都有必要,是不是可以合并归类,比如是不是可以把几百、几千个相似逻辑的归为一类,这样也能大大简化 if else 数量。

比如以下代码:

double calculateShipping() {if (orderAmount > 1000) {return 0.5;}if (customerLoyaltyLevel > 5) {return 0.5;}if (promotionIsActive) {return 0.5;}
}

优化后:

double calculateShipping() {if (orderAmount > 1000 || customerLoyaltyLevel > 5 || promotionIsActive) {return 0.5;}
}

这样就把返回相同值的 if 归为一类了,如果 if 较大就能大大简化代码量。

方案10:规则引擎

对于复杂的业务逻辑,业务规则经常变化,规则制定不依赖于技术团队,需要实现可配置的逻辑处理,此时可以考虑使用规则引擎来处理,比如 Drools。

规则引擎系统可用于执行一组规则,在许多业务应用程序中,业务决策可以通过一系列的逻辑规则来定义,规则引擎允许这些规则在运行时执行,而无需硬编码在应用程序之中。

规则引擎的好处是:

  • 业务逻辑可以和程序代码解耦;
  • 提高业务逻辑的可管理性;
  • 提高系统的灵活性和可扩展性;
  • 业务人员可参与决策过程;

总结

掌握优化 if else 的方法很重要,有时候面试官可能会换着法子问你,比如我们面试辅导这位兄弟遇到的这个面试官,你可以问清楚这一万个 if else 是在一个代码块中,还是在一个项目中,然后再去解答,如果不了解清楚业务场景,盲目回答又会被面试官绕进去。

本文我也总结了 10 种优化 if else 的方法,其实还不止,根据不同的场景还可以使用多态、责任链模式、模板方法模式等更多方法来消除 if else。

总之,消除 if else 并没有万能的方法,也不可能全部优化掉,在实际开发中需要根据实际场景使用不同的方法,以及多种方法组合使用,这样才是正确的方式。

像这样的面试题,我的小程序「Java面试库」还有许多,比如:

  • 如果把线程池 corePoolSize 设置为 0,会出现什么情况?
  • 线程池中的线程抛出了异常,如何处理?
  • MySQL 索引为什么选用 B+Tree 作为数据结构?
  • MySQL 的自增 ID 如果用完了,会怎么样?
  • 有了多线程,为什么还要消息队列?
  • ......

共 2800+,都是平时我面试别人,或者学员面试复盘积累下来的真题,不要在网上找乱七八糟的面试题了,浪费时间还容易被误导。

最后,推荐一波我们的「面试辅导」,有在看机会的,离职的、迷茫的,都可以加入,大厂导师 1 v 1 辅导,帮你全面提升面试综合实力,少走很多弯路,最大化提升职场收益。

版权声明: 本文系公众号 "Java技术栈" 原创,转载、引用本文内容请注明出处,抄袭、洗稿一律投诉侵权,后果自负,并保留追究其法律责任的权利。

更多文章推荐:

1.Spring Boot 3.x 教程,太全了!

2.2,000+ 道 Java面试题及答案整理(2024最新版)

3.免费获取 IDEA 激活码的 7 种方式(2024最新版)

觉得不错,别忘了随手点赞+转发哦!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/709887.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何通过数据下发平台,实现总分支机构间数据安全流转?

随着企业业务的快速发展,不少大型企业会在全国乃至全球,设立总部-分部-办事处/网点等多层级的结构。在日常经营中,总部与分支之间存在着较为频繁的数据互动关系,经常会存在文件数据下发的场景。数据下发平台是专门设计管理和下发大量文件的系统,它能够将文件从中心服务器传…

radioGroup.check()有两次事件

解决方法 :使用radioBotton.setChecked()方法来解决 参考:https://www.jianshu.com/p/f69cd82cd85a

聊聊如何利用spring实现服务隔离

前言 假设我们有个场景,我们需要实现服务之间的数据隔离、配置隔离、依赖的spring bean之间隔离。大家会有什么实现思路?今天给大家介绍spring-cloud-context里面有个NamedContextFactory可以达到上面的效果 NamedContextFactory简介 NamedContextFactory可以实现子容器,通过…

让机台数据传输更高效可靠,一文了解!

在汽车制造业中,机台数据传输和管理是一个关键环节,它涉及到生产效率、产品质量和企业运营的多个方面。以下是一些机台数据传输和管理的关键点:车载通信技术:随着汽车智能化的提升,车载通信技术变得尤为重要。车内总线通信与车载无线通信技术的提升,使得智能电动汽车成为…

openpyxl styles 模块

styles 模块说明 styles 模块提供了许多用于设置和控制单元格样式的类和方法。这些类和方法可以帮助你定制 Excel 工作表中单元格的外观,包括字体样式、边框、填充颜色等。 styles 模块主要功能 Font(字体):Font 类用于定义和修改单元格中文本的字体样式,如字体名称、大小…

dotnet 命令行工具解决方案 PomeloCli

目录PomeloCli 是什么为什么实现太多的工具太少的规范基于二进制拷贝分发难以为继快速开始1. 引用 PomeloCli 开发命令行应用2. 引用 PomeloCli 开发命令行插件开发命令行插件搭建私有 nuget 服务发布命令行插件3. 使用 PomeloCli 集成已发布插件安装命令行宿主集成命令行插件…

华为云CodeArts 12大安全防护机制,端到端全面保障软件供应链安全!

华为云CodeArts推出软件供应链安全解决方案,对软件作业流12个安全威胁点加对应防护机制。全球网络安全事件频发不断,企业纷纷损失惨重。2021年11月,知名logo4j漏洞波及全球多达6万款开源软件,70%以上企业受影响。2022年3月,大型加油站服务商遭到勒索软件攻击,要求其支付2…

MLOps 学习之旅「GitHub 热点速览」

又是 AI 神仙打架的一周,上周 OpenAI 发布了最新的 GPT-4o 模型,而谷歌也紧跟着开源了 Gemma 2 模型。随着 AI 大模型不断地变强,各大科技巨头正利用它们重塑自家的产品,这也让大模型算法工程师变得炙手可热,相关岗位需求正旺。 对于普通程序员来说,想要转型成为大模型算…

【博客园发文技巧】不离开编辑页面,批量添加图片链接和设置图片大小

参考文档:https://www.cnblogs.com/sanshi/p/3794796.html 起因 在博客园写文章,有时需要上传好多大图片,如果这些图片过大,则会导致页面变形。 因此有一个实际的需求,能够在博客园的编辑页面,直接批量修改所有图片的大小,然后给这些图片添加链接,以便点击时转到大图。…

video2blog 视频转图文AI小工具正式开源啦

前言 最近对一些小细节做了很多处理,但是其实还是有非常多的问题,没办法时间毕竟时间有限。为什么在这个时候开源,因为主要功能可以全部跑通了,分支暂时没开发的功能也可以通过其他的工具来替代。 这个工具开发初衷(想法来源),我之前有一篇文章有详细的说明,有兴趣的可…

组策略和bginfo

简介 很多的IT管理员都希望终端操作用户达到一个计算机脱盲的水平,但是理想很丰满,现实很骨感。人生不如事十之八九。 终端用户真的一言难尽。 简单的帮我们看一下CPU,内存,IP地址,这些基础信息,他们做不到。 好在微软发布了bginfo这个软件,BgInfo - Sysinternals | Mic…