深度网营销型网站建设公司怎么样,汶上网站建设哪家好,邢台发广告的平台有哪些,哪个公司的管理咨询公司前面我们一起回顾了第九期 Scala Java Meetup 中最受关注的话题 —— jdk 并发编程的终极解决方案#xff1a;虚拟线程#xff0c;探讨了这一新特性对包括 Scala 在内的响应式编程语言的影响。
本次 Meetup 的首位分享者 Chunsen#xff0c;在加入 Tubi 成为 Scala 开…前面我们一起回顾了第九期 Scala Java Meetup 中最受关注的话题 —— jdk 并发编程的终极解决方案虚拟线程探讨了这一新特性对包括 Scala 在内的响应式编程语言的影响。
本次 Meetup 的首位分享者 Chunsen在加入 Tubi 成为 Scala 开发者之前曾在 Java 开发领域深耕多年。他分享了从 Java 转向 Scala 的一些体验以及“回头再写 Java 一定会想念 Scala 的那些点”也欢迎观看直播回放。
欢迎关注比图科技公众号了解 Scala 最新资讯及活动。也欢迎你在后台留言申请加入 Scala 开发交流群
话题回顾
Java 语言的发展是非常成功的尤其是在 Web 后台领域。自 1995 年诞生以来Java 凭借网络服务的兴起成为了互联网行业最常用的编程语言之一。Java 最初设计为一种面向对象的编程语言旨在简化跨平台开发具有可移植性和安全性比 C 更简单易用因此 Java 的很多特性与 C 比较类似。Scala 是一门在 2003 年始源于研究项目旨在为 JVM 平台提供一种更具表达力和灵活性的编程语言融合了面向对象和函数式编程的特性。
如果用一句话来总结 Java 和 Scala 的差异那就是 Scala 作为一个相对于 Java 历史包袱更小的编程语言可以更多地尝试融合更多现代化的优秀编程思想进一步简化编程过程同时Scala 最初的设计者也在观察到 Java 语言发展过程中相对落后 / 冗余的方面后借鉴了函数式编程等其他编程语言的优点形成了编程风格简洁的多范式编程语言。!
Java 开发者非常适合了解学习 Scala 的原因
从宏观上来说由于 Java 与 Scala 在渊源上的联系Java 开发者学习 Scala 具有明显的优势。比如 Scala 和 Java 都是运行在 JVMJava 虚拟机上的编程语言两者之间可以互相调用有时也会存在不容易兼容的情况并利用包括跨平台和成熟的生态系统在内的 JVM 优势以及 JVM 升级带来的性能提升等。
Scala 和 Java 各自都有很多优秀的库可以比较容易地互相调用这意味着 Scala 和 Java 代码可以混合编译并共存于同一个项目中。
另外学习一门新的编程语言不一定是为工作所用也可以给开发者带来新的编程思想并有可能进一步改变其编程思维。
Scala 相比 Java 在某些特性上有着更出色的表现
不是所有场景下 Scala 都比 Java 更好但它有一些特性是将来再写 Java 一定会特别想念的比如那些使代码表达力更强、更安全、更高效的特性。
第一代码表达力更强
Scala 的代码表达力通过它的类型推导、模式匹配、命名参数与默认值、集合处理、隐式参数或隐式转换来体现。
类型推断
在创建变量时如果编译器能确定变量的类型就不需要手动声明了而这样的操作确实让代码更简洁了。 模式匹配
Scala 模式匹配是一种强大的特性可以用于检查数据类型、数据结构和数值的匹配并根据匹配的结果执行相应的代码块。如下图所示通过模式匹配我们可以非常简单明了地实现一个获取所有叶子节点值的方法。 下图展示了一些模式匹配的常见用法。模式匹配不仅可以匹配类型还可以匹配正则表达式提高正则表达式代码的可读性。同时我们还可以通过定义 unapply 和 unapplySeq 的方式自定义模式匹配的行为。 命名参数 默认值
通过下图所呈现的代码我们可以看到 Scala 可以在一个函数内实现函数参数有默认值也就是多个函数的重载而在 Java 开发中实现同样的功能我们往往需要写多个函数。 集合处理
如图中代码所示通过对比 Java 和 Scala 计算平均工资的方法差异我们可以容易地发现 Scala 在 Lambda 函数的使用和集合函数的处理上都是更加精简好用的。 隐式参数 / 隐式转换
隐式参数是一种特殊的参数允许我们在调用函数时不显式地传递参数而是让编译器根据上下文自动查找并传入相应的参数值。这种功能可以帮助简化代码提高灵活性并且常用于依赖注入、类型类和其它模式中。下图展示了隐式参数的使用。 第二更安全
空指针安全
Java 编程获取 User 列表中最长的名字需要注意判断空容易出错。而在 Scala 中我们可以使用函数式编程方式避免出现没有判空的错误。 类型安全
Java 编译器允许把 String 数组赋值给 Object 数组但在运行时当我们尝试给这个 Object 数组插入一个非 String 对象时就会产生错误。这是 Java 编译器在类型安全上的一个问题。同时Java 编译器不允许把一个 String 列表赋值给 Object 列表但是从逻辑上来说我们希望这个这个赋值是可以发生的。而 Scala 编译器则能够解决了这两个问题它不允许把一个 Sting 数组赋值给一个 Object 数组但是允许把一个 String 列表赋值给一个 Object 列表。 如下图我们定义了特质 AnimalDog 继承 AnimalHusk 继承 Dog。Scala 中 Dog 继承了 Animal的特质可以当作 Animal 的类型不能当作 Husky 的类型但在 Java 中都是不可以的并不符合常理。 Scala 编译器通过协变Covariance和逆变Contravariance来实现上述例子中的的类型安全这也是为什么 Scala 比 Java 类型系统强大的一个原因。
协变表示类型参数的子类型关系与泛型类型之间的子类型关系是一致的。简而言之如果类型 A 是类型 B 的子类型那么 F[A] 也是 F[B] 的子类型。其中F 表示一个泛型类型。
逆变表示类型参数的子类型关系与泛型类型之间的子类型关系是相反的。简而言之如果类型 A 是类型 B 的子类型那么 F[B] 是 F[A] 的子类型。与协变相反逆变使用逆变符号 - 来表示。 模式匹配检查
Scala 编译器会检查我们的模式匹配代码是否穷举完了所有的 case当我们忽略了一些 case编译器会认为代码可能存在逻辑漏洞。这一特性可以很好地帮助我们发现逻辑中的漏洞让代码更可靠。 第三更高效
尾递归
Java 中使用递归函数可能会造成栈溢出某些 Java 编译器在某些情况下会进行尾递归优化而在 Scala 中尾递归Tail Recursion是指递归函数中的递归调用发生在函数体的最后一个位置。当函数满足尾递归的条件时编译器可以对其进行尾递归优化。
尾递归优化是一种编译器优化技术它可以将尾递归函数转化为迭代形式从而避免在递归过程中产生大量的函数调用栈。这样可以减少内存消耗并提高性能因为不再需要保存每次递归调用的上下文信息。
如下图最后一个调用不是该递归函数则会发生栈溢出不会进行尾递归的优化。 当稍加修改在函数中保留一个变量尾递归优化就可以实现了。 异步编程
在 Scala 中Future 是表示异步计算结果的一种抽象类型。它允许在一个独立的执行上下文中进行并发计算并在计算完成后获取结果。Future 通常用于处理异步操作例如从远程服务器获取数据、执行耗时的计算或 IO 操作等。 宏
在 Scala 中宏Macros是一种元编程机制允许在编译时对代码进行操作和生成。通过宏开发人员可以在编译时期以及语法树级别上扩展和改变代码从而实现更高级的抽象、优化和代码生成。
宏在 Scala 中被广泛应用于各种框架和库中用于生成重复代码、优化性能、实现领域特定语言DSL等方面。然而宏也是一种强大而复杂的元编程工具需要谨慎使用以避免引入难以理解和维护的代码。需要注意的是自 Scala 2.13 版本起宏已经被标记为“实验性功能”而且在 Scala 3 中已经不再推荐使用宏而是推荐使用新的“引用透明宏”inline meta功能。—— 以上总结来自现场观众谷国伟
热门话题讨论
提问Scala 在实际生产中的应用怎么样
Chunsen大家对 Scala 在国内的情况应该比较了解一直处于不温不火的状态在国外相对更好。但其实Scala 依然有很多忠实爱好者包括我自己。
虽然随着 Java 的发展语言本身存在缺陷的部分也在逐步弥补。Scala 刚发行时Java 版本是 1.5Java 确实存在很多问题影响编程体验比如泛型尚不成熟、也没有 Lamda那时 Scala 相对更有优势而如今 Java 有 Recall /Lamda也可以支持 Pental Match这会导致大家对于 Scala 的需求没有那么强了更何况还存在 Kotlin 这样一款更能抓住 Java 开发者心的、介于 Java 和 Scala 之间的一门编程语言。
但是在我看来 Scala 依然具备一定的优势尤其是在你对 Scala 有了更好的掌握和驾驭能力之后。在我使用 Scala 开发的体验中Scala 确实使我们的代码更高效业务逻辑更清晰了。
Guobin如果你的团队相对于技术追求更看重业务本身那么没有必要一定从 Java 转向 Scala。但是我们个人学习一门技术或编程语言并非为了在实际生产环境中使用而是为了了解 Java 之外的编程思想。比如作为 Java 开发者你可能会认为 Lamda 就应该是这样的但是当你去学习了 Rust、Kotlin、Scala 等函数式编程语言后你肯定会问自己“为什么 Java 的 Lamda 这样难用” 在我看来这是学习和使用另外一门编程语言所应该实现的效果。
如果你是为了在实际生产环境中使用一门新的编程语言那么一定要考虑这一选择所带来的代价与收益。比如当 Java 面对并发这一技术问题时你可以考虑使用 Scala Akka 这一相对于 Java 非常不同的处理方式。在我看来最关键的还是要找到“硬需求是什么”。我使用 Scala 的时间比 Java 更长我有一些个人体验可以分享给大家。面向过程的 Java 开发很容易让人陷入细节的思考中比如我们通过 Java 实现的算子、折叠方法可能不如标准部件实现得更好。而在 Scala 开发中我们可以通过充分使用标准部件避免投入过多的时间在细节的实现上而将关注点放在更重要更根本的业务实现上。
QiwenTubi 是我第一份写 Scala 的工作之前我是 Java 开发者。在我看来了解一门新的语言是为了学习它的写法和思想而非是为了完全将一种服务从一门语言迁移到另一门语言上。我在 Amazon 工作时做的是Java 开发虽然当时我们使用的版本是 1.8但依然保持了一些更老的 Java 习惯。在我开始熟练使用 1.8 的 Lamda 时会发现很多流程就是一个链会带来更加清晰简洁的流程描述。当我来到 Tubi 开始写 Scala 时我发现这竟然是 Scala 天生带有的一种能力这也给了我机会反观 Java 开发经历。当我了解了 Scala 语言设计的初衷和思想再回头理解 Java 相对应的一些实现时我会更理解 Java 这门语言的一些特性也更会在写代码时遵循那些最佳实践。
Chunsen我很赞同 Guobin 提到的“在没有硬需求的情况下没有必要硬转一门新的编程语言”但我也想补充一点了解和使用 Scala 一段时间究竟会给开发者带来什么虽然我们都知道没有什么是 Scala 能实现而 Java 实现不了的只不过在代码行数和美观性上存在差异但是使用 Scala 的过程确实改变了我们思考问题的方式。Java 是面向过程的语言面对一个问题的解决思路是一步一步地找到解决方案如我在分享中提到的这个例子一样当你需要在列表中找到用户名最长的用户Java 的解决思路是使用 loop 循环并在中间加入定义一步步找到。Scala 的解决思路是首先需要将用户名拿出来根据用户名的长度排序找到最大的。这是两种完全不同的思维方式。在写了一段时间 Scala 后我在回顾 Java 代码时会发现有很多可以被优化的地方。对我个人而言这是我转写 Scala 后的最大收获之一。
欢迎加入 Tubi
Tubi Data Team 目前正在寻找一位大数据平台开发 Lead他 / 她将领导数据开发团队创建高质量、可扩展的流数据管道与所有用户建立联系将在开放创新的环境中与机器学习团队、产品经理、DevOps 团队和数据科学家合作推动用户增长对系统架构设计全面负责解决性能、可扩展性、可重用性和灵活性等问题并倡导工程最佳实践培养与保持团队内的工程师文化负责技术招聘和指导团队成员的职业发展建立一支高效的开发团队。
首选编码语言为 Scala、Python 或 Java。
Scala Meetup 往期推荐
Tubi 秉承开放和回馈的心态自 2019 年 8 月开始赞助并举办 Scala Meetup如今已成功完成九期线上线下活动。
从 Scala 编程入门学习到职业发展Scala 函数式编程语言的研究还有 Scala 的生产实践你所关心的 Scala 话题在往期 Meetup 中都有所涉及这些共创交流也正在以某种方式回馈着社区中的每个人让我们反复思考和精进“为什么选择 Scala如何可以更好地发挥 Scala 的优势Scala 怎样可以发展得更好”
欢迎阅读往期回顾
【活动回顾】2023年1月
【活动回顾】2022年6月
【活动回顾】2021年1月
【活动回顾】2020年9月
【活动回顾】2020年4月