小菜鸟

java菜鸟号正在起航

Scala 类和对象:面向对象的简洁实现

Scala 作为一门纯粹的面向对象语言,其类和对象的设计既保留了面向对象的核心思想,又通过语法糖简化了代码编写,相比 Java 更加简洁灵活。本文将深入解析 Scala 类和对象的定义、属性访问机制及底层实现。

类的定义与特性

基本语法

Scala 中类的定义无需显式声明 public(默认即为公有),一个源文件可包含多个类,所有类均具有公有可见性。

// 语法格式
[修饰符] class 类名 {
  // 类体(属性、方法等)
}

示例:定义一个简单的类

class Cat {
  // 用var声明可变属性(会生成getter和setter)
  var name: String = _  // _表示赋默认值(需指定类型)
  var color: String = _
  
  // 用val声明不可变属性(仅生成getter)
  val life: Int = 10  // val必须显式赋值,且不可修改
}
代码解析:
  • 属性初始化:Scala 要求类的属性必须显式初始化。若暂时不想赋值,可用 _ 赋默认值(需指定类型),默认值规则与 Java 基本类型一致(如字符串默认 null,整数默认 0)。
  • varval 的区别:
    • var:可变属性,编译后会生成 getter(获取值)和 setter(修改值)方法。
    • val:不可变属性,编译后仅生成 getter 方法(无 setter,因为值不可修改)。

对象的实例化与使用

实例化对象

阅读全文 »

Scala 异常处理:基于模式匹配的灵活机制

异常处理是程序健壮性的重要保障,Scala 的异常处理机制在保留 Java 核心思想(try...catch...finally)的基础上,通过模式匹配简化了异常捕获逻辑,同时取消了编译期检查,让代码更灵活。本文将详细解析 Scala 异常处理的语法、特性及最佳实践。

异常处理的基本语法

Scala 使用 try...catch...finally 结构处理异常,核心差异在于 catch 块采用模式匹配case)捕获不同类型的异常,而非 Java 的 catch (Exception e) 语法。

基础示例

try {
  // 可能抛出异常的代码
  val result = 10 / 0  // 触发算术异常(除数为0)
} catch {
  // 模式匹配:按异常类型捕获
  case e: ArithmeticException => 
    println(s"算术异常:${e.getMessage}")  // 处理特定异常
  case e: Exception => 
    println(s"通用异常:${e.getMessage}")   // 处理其他异常
} finally {
  // 无论是否异常,都会执行的代码(如资源释放)
  println("异常处理结束,执行清理操作")
}

执行结果

算术异常:/ by zero
异常处理结束,执行清理操作

核心特性解析

模式匹配捕获异常

  • catch 块中只能有一个代码块,通过多个 case 分支匹配不同类型的异常。
  • 匹配顺序为从上到下,一旦匹配成功则不再执行后续分支,因此需将具体异常放在前面,通用异常(如 Exception)放在后面。
阅读全文 »

Scala 惰性函数:延迟执行的高效机制

在编程中,“延迟执行” 是一种优化策略 —— 将计算推迟到真正需要结果时再执行,从而避免不必要的资源消耗。Scala 中的惰性函数(Lazy Function)正是这一思想的体现,通过 lazy 关键字实现,与 Hibernate 的 “懒加载” 机制异曲同工。本文将详细解析惰性函数的用法、原理及适用场景。

惰性函数的基本概念

定义

当函数的返回值被 lazy 修饰时,该函数的执行会被推迟,直到首次使用返回值时才真正执行。这种 “按需执行” 的特性,称为 “惰性求值”(Lazy Evaluation)。

语法

lazy val 变量名 = 函数调用  // 用lazy修饰函数返回值的变量

注意

  • lazy 只能修饰 val(不可变变量),不能修饰 var(可变变量)。
  • lazy 修饰的变量,其值的分配也会延迟到首次使用时。

惰性函数的示例与执行流程

基础示例

阅读全文 »

Scala 函数:灵活高效的代码块封装

在 Scala 中,函数是代码复用和逻辑封装的核心单位,其灵活性远超 Java 中的方法 —— 不仅可以独立定义,还能像变量一样赋值、传递,甚至作为参数或返回值。本文将深入解析 Scala 函数的定义、参数特性及使用技巧。

函数与方法的关系

Scala 中 “函数”(Function)和 “方法”(Method)概念相近,但存在细微区别:

  • 方法:定义在类、对象或特质中的函数,依赖于宿主结构。
  • 函数:可独立存在的代码块,本质是 FunctionN 特质的实例(如 Function2 对应两个参数的函数)。

日常使用中,两者常被混用,因为 Scala 会自动在方法和函数间转换(通过 “eta 展开”:方法名 _ 将方法转为函数)。

函数的基本定义

Scala 函数通过 def 关键字声明,语法灵活,支持多种返回值形式。

基本语法

def 函数名([参数名: 参数类型], ...)[[: 返回值类型] =] {
  函数体
  [return 返回值]
}

三种返回值形式

1. 显式指定返回值类型

通过 : 返回值类型 = 明确声明返回值类型,可使用 return 关键字。

阅读全文 »

HBase 配置优化:读多写少、写多读少,参数调法不一样

HBase 的默认配置能跑,但不一定适合你的业务。

  • 写多读少(日志采集、实时写入)→ MemStore 要大、刷盘要少
  • 读多写少(用户画像、历史查询)→ BlockCache 要大、Scanner 缓存要调大
  • 混合负载 → 平衡 MemStore 和 BlockCache 的内存配比

HDFS 层配置——HBase 的”地基”

HBase 的数据最终存在 HDFS 上,HDFS 配置不对,HBase 再调也白搭。

参数 推荐值 为什么调 调大了有风险吗
dfs.support.append true HBase 的 WAL 需要追加写,不开这个 HBase 起不来 必须开,没得选
dfs.datanode.max.transfer.threads 4096 HBase 刷盘、合并、读取同时进行,默认 4096 够用但高并发时可调大 设太大占用内存
dfs.image.transfer.timeout 60000(60s) HBase 的 StoreFile 可能很大,传输慢会超时 设太大可能掩盖网络问题

写入性能优化——“写得多”怎么调

场景特征: 日志采集、实时数据写入、IoT 数据上报。写入 QPS 高,读少。

参数 默认值 推荐值(写入密集) 为什么调 风险
hbase.client.write.buffer 2MB 5-10MB 客户端攒一批再写,减少 RPC 次数 设太大客户端 OOM
hbase.regionserver.handler.count 10 30-50 处理写请求的线程数,高并发写需要更多线程 设太大 CPU 上下文切换开销
hbase.hregion.memstore.flush.size 128MB 256MB(写密集) 大 MemStore 减少刷盘频率,降低小文件产生 设太大单个 Region 内存压力大
hbase.regionserver.global.memstore.upperLimit 0.4 0.45 允许更多内存给 MemStore,减少刷盘触发 调太高挤占 BlockCache

写入密集场景配置示例(hbase-site.xml):

阅读全文 »
0%