这应该是全网讲解JAVA 异常处理最全的文章了
专注于Java领域优质技术,欢迎关注
作者:allen4tech 慕课网
JAVA 异常类型结构
Throwable 是所有异常类型的基类,Throwable 下一层分为两个分支,Error 和 Exception.
Error 和 Exeption
- Error
Error 描述了 JAVA 程序运行时系统的内部错误,通常比较严重,除了通知用户和尽力使应用程序安全地终止之外,无能为力,应用程序不应该尝试去捕获这种异常。通常为一些虚拟机异常,如 StackOverflowError 等。
- Exception
Exception 类型下面又分为两个分支,一个分支派生自 RuntimeException,这种异常通常为程序错误导致的异常;另一个分支为非派生自 RuntimeException 的异常,这种异常通常是程序本身没有问题,由于像 I/O 错误等问题导致的异常,每个异常类用逗号隔开。
受查异常和非受查异常
- 受查异常
受查异常会在编译时被检测。如果一个方法中的代码会抛出受查异常,则该方法必须包含异常处理,即 try-catch 代码块,或在方法签名中用 throws 关键字声明该方法可能会抛出的受查异常,否则编译无法通过。如果一个方法可能抛出多个受查异常类型,就必须在方法的签名处列出所有的异常类。
通过 throws 关键字声明可能抛出的异常
try-catch 处理异常
- 非受查异常
非受查异常不会在编译时被检测。JAVA 中 Error 和 RuntimeException 类的子类属于非受查异常,除此之外继承自 Exception 的类型为受查异常。
异常的抛出与捕获
直接抛出异常
通常,应该捕获那些知道如何处理的异常,将不知道如何处理的异常继续传递下去。传递异常可以在方法签名处使用 throws 关键字声明可能会抛出的异常。
封装异常再抛出
有时我们会从 catch 中抛出一个异常,目的是为了改变异常的类型。多用于在多系统集成时,当某个子系统故障,异常类型可能有多种,可以用统一的异常类型向外暴露,不需暴露太多内部异常细节。
捕获异常
在一个 try-catch 语句块中可以捕获多个异常类型,并对不同类型的异常做出不同的处理
同一个 catch 也可以捕获多种类型异常,用 | 隔开
自定义异常
习惯上,定义一个异常类应包含两个构造函数,一个无参构造函数和一个带有详细描述信息的构造函数(Throwable 的 toString 方法会打印这些详细信息,调试时很有用)
try-catch-finally
当方法中发生异常,异常处之后的代码不会再执行,如果之前获取了一些本地资源需要释放,则需要在方法正常结束时和 catch 语句中都调用释放本地资源的代码,显得代码比较繁琐,finally 语句可以解决这个问题。
调用该方法时,读取文件时若发生异常,代码会进入 catch 代码块,之后进入 finally 代码块;若读取文件时未发生异常,则会跳过 catch 代码块直接进入 finally 代码块。所以无论代码中是否发生异常,fianlly 中的代码都会执行。
若 catch 代码块中包含 return 语句,finally 中的代码还会执行吗?将以上代码中的 catch 子句修改如下:
调用 readFile 方法,观察当 catch 子句中调用 return 语句时,finally 子句是否执行
可见,即使 catch 中包含了 return 语句,finally 子句依然会执行。若 finally 中也包含 return 语句,finally 中的 return 会覆盖前面的 return.
try-with-resource
上面例子中,finally 中的 close 方法也可能抛出 IOException, 从而覆盖了原始异常。JAVA 7 提供了更优雅的方式来实现资源的自动释放,自动释放的资源需要是实现了 AutoCloseable 接口的类。
try 代码块退出时,会自动调用 scanner.close 方法,和把 scanner.close 方法放在 finally 代码块中不同的是,若 scanner.close 抛出异常,则会被抑制,抛出的仍然为原始异常。被抑制的异常会由 addSusppressed 方法添加到原来的异常,如果想要获取被抑制的异常列表,可以调用 getSuppressed 方法来获取。
阿里巴巴异常处理规约
1、【强制】 Java 类库中定义的可以通过预检查方式规避的 RuntimeException 异常不应该通过catch 的方式来处理,比如:NullPointerException, IndexOutOfBoundsException 等等。
说明:无法通过预检查的异常除外,比如,在解析字符串形式的数字时,不得不通过 catch NumberFormatException 来实现。
正例:if (obj != null) {…}
反例:try { obj.method(); } catch (NullPointerException e) {…}
2、【强制】 异常不要用来做流程控制,条件控制。
说明: 异常设计的初衷是解决程序运行中的各种意外情况,且异常的处理效率比条件判断方式要低很多
3、【强制】 catch 时请分清稳定代码和非稳定代码,稳定代码指的是无论如何不会出错的代码。对于非稳定代码的 catch 尽可能进行区分异常类型,再做对应的异常处理。
说明: 对大段代码进行 try-catch,使程序无法根据不同的异常做出正确的应激反应,也不利于定位问题,这是一种不负责任的表现。
正例: 用户注册的场景中,如果用户输入非法字符, 或用户名称已存在, 或用户输入密码过于简单,在程序上作出分门别类的判断,并提示给用户。
4、【强制】 捕获异常是为了处理它,不要捕获了却什么都不处理而抛弃之,如果不想处理它,请将该异常抛给它的调用者。最外层的业务使用者,必须处理异常,将其转化为用户可以理解的内容。
5、【强制】 有 try 块放到了事务代码中, catch 异常后,如果需要回滚事务,一定要注意手动回滚事务。
6、【强制】 finally 块必须对资源对象、流对象进行关闭,有异常也要做 try-catch。
说明: 如果 JDK7 及以上,可以使用 try-with-resources 方式。
7、【强制】 不要在 finally 块中使用 return。
说明:finally 块中的 return 返回后方法结束执行,不会再执行 try 块中的 return 语句。
8、【强制】 捕获异常与抛异常,必须是完全匹配,或者捕获异常是抛异常的父类。
说明: 如果预期对方抛的是绣球,实际接到的是铅球,就会产生意外情况。
9、【推荐】 方法的返回值可以为 null,不强制返回空集合,或者空对象等,必须添加注释充分说明什么情况下会返回 null 值。
说明: 本手册明确防止 NPE 是调用者的责任。即使被调用方法返回空集合或者空对象,对调用者来说,也并非高枕无忧,必须考虑到远程调用失败、 序列化失败、 运行时异常等场景返回null 的情况。
10、【推荐】 防止 NPE,是程序员的基本修养,注意 NPE 产生的场景:
1)返回类型为基本数据类型, return 包装数据类型的对象时,自动拆箱有可能产生 NPE。
反例:public int f() { return Integer 对象}, 如果为 null,自动解箱抛 NPE。
2) 数据库的查询结果可能为 null。
3) 集合里的元素即使 isNotEmpty,取出的数据元素也可能为 null。
4) 远程调用返回对象时,一律要求进行空指针判断,防止 NPE。
5) 对于 Session 中获取的数据,建议 NPE 检查,避免空指针。
6) 级联调用 obj.getA().getB().getC(); 一连串调用,易产生 NPE。
正例: 使用 JDK8 的 Optional 类来防止 NPE 问题。
11、【推荐】 定义时区分 unchecked / checked 异常,避免直接抛出 new RuntimeException(),更不允许抛出 Exception 或者 Throwable,应使用有业务含义的自定义异常。
推荐业界已定义过的自定义异常,如:DAOException / ServiceException 等。
12、【参考】 对于公司外的 http/api 开放接口必须使用“错误码”; 而应用内部推荐异常抛出;跨应用间 RPC 调用优先考虑使用 Result 方式,封装 isSuccess()方法、 “错误码”、 “错误简短信息”。
说明: 关于 RPC 方法返回方式使用 Result 方式的理由:
1) 使用抛异常返回方式,调用方如果没有捕获到就会产生运行时错误。
2) 如果不加栈信息,只是 new 自定义异常,加入自己的理解的 error message,对于调用端解决问题的帮助不会太多。如果加了栈信息,在频繁调用出错的情况下,数据序列化和传输的性能损耗也是问题。
13、【参考】 避免出现重复的代码(Don’t Repeat Yourself) ,即 DRY 原则。
说明: 随意复制和粘贴代码,必然会导致代码的重复,在以后需要修改时,需要修改所有的副本,容易遗漏。必要时抽取共性方法,或者抽象公共类,甚至是组件化。
正例: 一个类中有多个 public 方法,都需要进行数行相同的参数校验操作,这个时候请抽取:private boolean checkParam(DTO dto) {…}
常见面试题
1. Error 和 Exception 区别是什么?
Error 类型的错误通常为虚拟机相关错误,如系统崩溃,内存不足,堆栈溢出等,编译器不会对这类错误进行检测,JAVA 应用程序也不应对这类错误进行捕获,一旦这类错误发生,通常应用程序会被终止,仅靠应用程序本身无法恢复;
Exception 类的错误是可以在应用程序中进行捕获并处理的,通常遇到这种错误,应对其进行处理,使应用程序可以继续正常运行。
2. 运行时异常和一般异常区别是什么?
编译器不会对运行时异常进行检测,没有 try-catch,方法签名中也没有 throws 关键字声明,编译依然可以通过。如果出现了 RuntimeException, 那一定是程序员的错误。
一般一场如果没有 try-catch,且方法签名中也没有用 throws 关键字声明可能抛出的异常,则编译无法通过。这类异常通常为应用环境中的错误,即外部错误,非应用程序本身错误,如文件找不到等。
3.NoClassDefFoundError 和 ClassNotFoundException 区别?
NoClassDefFoundError 是一个 Error 类型的异常,是由 JVM 引起的,不应该尝试捕获这个异常。
引起该异常的原因是 JVM 或 ClassLoader 尝试加载某类时在内存中找不到该类的定义,该动作发生在运行期间,即编译时该类存在,但是在运行时却找不到了,可能是变异后被删除了等原因导致;
ClassNotFoundException 是一个受查异常,需要显式地使用 try-catch 对其进行捕获和处理,或在方法签名中用 throws 关键字进行声明。当使用 Class.forName, ClassLoader.loadClass 或 ClassLoader.findSystemClass 动态加载类到内存的时候,通过传入的类路径参数没有找到该类,就会抛出该异常;另一种抛出该异常的可能原因是某个类已经由一个类加载器加载至内存中,另一个加载器又尝试去加载它。
4. JVM 是如何处理异常的?
在一个方法中如果发生异常,这个方法会创建一个一场对象,并转交给 JVM,该异常对象包含异常名称,异常描述以及异常发生时应用程序的状态。创建异常对象并转交给 JVM 的过程称为抛出异常。可能有一系列的方法调用,最终才进入抛出异常的方法,这一系列方法调用的有序列表叫做调用栈。
JVM 会顺着调用栈去查找看是否有可以处理异常的代码,如果有,则调用异常处理代码。当 JVM 发现可以处理异常的代码时,会把发生的异常传递给它。如果 JVM 没有找到可以处理该异常的代码块,JVM 就会将该异常转交给默认的异常处理器(默认处理器为 JVM 的一部分),默认异常处理器打印出异常信息并终止应用程序。
5. throw 和 throws 的区别是什么?
throw 关键字用来抛出方法或代码块中的异常,受查异常和非受查异常都可以被抛出。
throws 关键字用在方法签名处,用来标识该方法可能抛出的异常列表。一个方法用 throws 标识了可能抛出的异常列表,调用该方法的方法中必须包含可处理异常的代码,否则也要在方法签名中用 throws 关键字声明相应的异常。
6. 常见的 RuntimeException 有哪些?
- ClassCastException(类转换异常)
- IndexOutOfBoundsException(数组越界)
- NullPointerException(空指针)
- ArrayStoreException(数据存储异常,操作数组时类型不一致)
- 还有IO操作的BufferOverflowException异常
iPhone上轻松搭建V2Ray:从零开始的安全上网指南
在数字化时代,网络安全和个人隐私保护变得前所未有的重要。对于iPhone用户而言,V2Ray作为一款高效、安全的代理工具,能够帮助我们在享受移动互联网便利的同时,有效保护个人数据安全。本文将为您提供一份详尽的iPhone版V2Ray配置指南,从基础概念到实际操作,手把手带您进入安全上网的新世界。
V2Ray技术解析:为何它成为隐私保护的首选?
V2Ray(Project V)是一款开源的网络代理工具,由一群关注网络自由的开发者共同维护。与传统的VPN或SS/SSR相比,V2Ray采用了更先进的架构设计,其核心优势在于:
多协议支持:V2Ray原生支持VMess、Shadowsocks、Socks、HTTP等多种协议,并能通过配置实现协议间的自动切换,有效规避网络封锁。
强大的混淆能力:内置的TLS加密和WebSocket传输可以伪装成正常的HTTPS流量,使代理流量与普通网页浏览难以区分。
动态端口分配:支持mKCP协议,能够在单一连接中使用多个端口,大幅提高稳定性和抗干扰能力。
路由分流功能:可以智能判断哪些流量需要代理,哪些可以直接连接,既保证了访问速度又节省了服务器资源。
对于iPhone用户而言,V2Ray的这些特性意味着: - 在公共WiFi下浏览网页时,个人信息不会被窃取 - 出差旅行时能够稳定访问企业内网资源 - 学术研究者可以无障碍获取全球知识资源 - 商务人士能够安全地进行跨国通讯
前期准备:搭建V2Ray的必要条件
在开始配置之前,我们需要做好以下准备工作:
硬件与系统要求
- iPhone设备:建议使用iPhone 7及以上型号,确保处理器性能足够
- iOS版本:iOS 12.0及以上,推荐升级到最新版本以获得最佳兼容性
- 存储空间:至少预留50MB空间用于客户端安装和缓存
网络环境评估
- 家庭/办公网络:检查路由器是否设置了特殊限制
- 移动数据网络:确认运营商没有屏蔽常用代理端口
- 备用网络方案:准备至少两种不同的网络接入方式(如WiFi+蜂窝数据)
服务器信息获取
一个典型的V2Ray服务器配置包含以下关键信息: { "address": "your_server_ip_or_domain", "port": 443, "id": "b831381d-6324-4d53-ad4f-8cda48b30811", "alterId": 64, "security": "auto", "network": "tcp", "headerType": "none", "type": "vmess", "tls": "tls" }
专业建议:初次使用者可以通过以下途径获取服务器配置: 1. 自建服务器:租用VPS并按照官方文档搭建(技术要求较高) 2. 付费服务:选择信誉良好的V2Ray服务提供商 3. 社区分享:技术论坛中寻找测试节点(需谨慎验证安全性)
客户端选择:iPhone上的V2Ray最佳伴侣
App Store中有多款支持V2Ray协议的客户端应用,我们重点推荐三款各具特色的选择:
1. Shadowrocket(小火箭)
- 价格:$2.99(美区账号购买)
- 优势:
- 界面直观,新手友好
- 支持订阅功能,可自动更新节点列表
- 内置多种规则模式,可实现分应用代理
- 适用人群:追求简单易用的普通用户
2. Quantumult X
- 价格:$7.99(美区账号购买)
- 优势:
- 支持复杂的策略组配置
- 提供精细的流量统计功能
- 可自定义重写规则和MITM解密
- 适用人群:有进阶需求的技术爱好者
3. Streisand(免费开源方案)
- 获取方式:通过TestFlight安装
- 优势:
- 完全开源透明,隐私有保障
- 支持最新的VLESS协议
- 无内购和广告
- 适用人群:注重隐私保护的技术用户
下载技巧: - 中国区App Store可能无法直接搜索到这些应用,需要切换至美区/港区等海外账号 - 注册海外Apple ID时无需绑定信用卡,选择"None"作为支付方式即可 - 下载完成后建议开启应用的自动更新功能
详细配置指南:以Shadowrocket为例
下面我们以Shadowrocket为例,展示完整的配置流程:
步骤1:基础设置
- 打开Shadowrocket应用,点击右下角"+"按钮
- 选择"类型"为VMess(这是V2Ray最常用的协议)
- 填写服务器基本信息:
- 别名:自定义名称(如"东京节点1")
- 地址:服务器IP或域名
- 端口:通常为443或8443
- 用户ID:UUID格式的字符串
步骤2:高级参数配置
- 加密方式:推荐选择"auto"或"aes-128-gcm"
- 传输协议:
- TCP:兼容性最好
- WebSocket:适合严格网络环境
- mKCP:抗丢包能力强
- TLS设置:
- 启用TLS(重要安全选项)
- 跳过证书验证(仅测试时使用)
- 混淆设置:
- 类型选择"none"或"http"
- 主机名填写常见域名(如cloudflare.com)
步骤3:路由规则配置
- 进入"配置"→"本地文件"
- 选择适合的规则集:
- DIRECT规则:国内网站直连
- PROXY规则:国外网站代理
- REJECT规则:屏蔽广告域名
- 启用"智能路由"功能,实现自动分流
步骤4:连接测试
- 返回主界面,选择刚配置的服务器
- 点击顶部开关启动连接
- 通过以下方式验证:
- 查看左上角VPN图标是否出现
- 访问ip.sb检查IP是否变更
- 使用Ping工具测试延迟
专家提示:配置完成后,建议: - 导出配置备份(通过iCloud或AirDrop) - 设置快捷指令实现一键切换 - 启用"按需连接"节省电量
使用技巧与优化建议
要让V2Ray发挥最佳性能,还需要掌握以下进阶技巧:
网络性能优化
- 协议选择策略:
- 网络稳定时:TCP+TLS
- 网络限制严格:WebSocket+TLS
- 移动场景:mKCP+伪装
- MTU调整:在高级设置中将MTU值设为1400左右可改善某些网络下的稳定性
- 多节点负载均衡:配置多个服务器并启用自动切换
隐私增强措施
- DNS设置:
- 使用DOH(DNS over HTTPS)
- 推荐DNS:1.1.1.1或8.8.4.4
- 防止DNS泄漏:
- 启用"处理DNS请求"选项
- 禁用系统级DNS设置
- 流量混淆:定期更换伪装域名和路径
日常维护要点
- 订阅管理:
- 设置自动更新频率(建议每天)
- 手动刷新前检查订阅源安全性
- 日志监控:
- 定期检查连接日志
- 关注异常断开和重连记录
- 客户端更新:
- 关注开发者Twitter获取更新信息
- 重大版本更新后重置配置
常见问题深度解决方案
连接失败排查流程
基础检查:
- 确认设备网络正常
- 尝试切换WiFi/4G/5G
- 重启客户端应用
服务器端验证:
- 通过电脑端工具测试同一配置
- 联系服务商确认服务器状态
- 检查账号是否过期或被限速
客户端调试:
- 尝试关闭TLS或更换传输协议
- 临时禁用防火墙和杀毒软件
- 重置网络设置(设置→通用→传输或还原)
速度优化专项方案
服务器选择策略:
- 使用延迟测试工具筛选最优节点
- 避免高峰时段拥挤的服务器
- 选择支持BBR加速的服务器
客户端参数调优:
- 调整concurrency参数(通常设为2-4)
- 启用"fast-open"选项
- 限制上传带宽减轻缓冲影响
系统级优化:
- 关闭后台应用刷新
- 禁用自动备份和iCloud同步
- 使用低电量模式减少后台干扰
法律与道德使用指南
在使用V2Ray等代理工具时,我们必须明确:
合法用途包括:
- 企业远程办公接入
- 学术研究资料获取
- 跨国商务通讯保护
- 个人隐私安全防护
绝对禁止行为:
- 访问违法内容
- 进行网络攻击
- 侵犯他人隐私
- 绕过版权限制
风险防范建议:
- 避免使用不明来源的免费节点
- 不在代理环境下进行金融操作
- 定期更换服务器和配置
- 了解当地相关法律法规
未来展望:V2Ray技术演进
随着网络环境的不断变化,V2Ray也在持续进化:
协议创新:
- VLESS协议简化了VMess的复杂性
- Trojan协议提供了更好的隐蔽性
- QUIC支持提升了移动端体验
客户端发展:
- 与iOS系统深度整合
- 支持Apple Silicon原生优化
- 更智能的AI自动配置
生态系统完善:
- 可视化配置工具涌现
- 一站式服务平台出现
- 专业的技术支持社区
结语:掌握数字时代的自主权
通过本文的详细指导,您已经掌握了在iPhone上配置和使用V2Ray的完整知识体系。从基础概念到高级技巧,从工具选择到法律边界,我们希望为您提供了一站式的解决方案。在数字化生存成为常态的今天,技术工具的使用能力正在成为现代公民的基本素养。V2Ray这样的隐私保护工具,本质上是我们捍卫数字自主权的武器。但请永远记住:技术是中性的,关键在于使用者的目的和方式。愿您既能享受技术带来的便利,又能成为负责任的数字公民。
精彩点评: 这篇文章以专业而不失通俗的语言,系统性地解构了iPhone上使用V2Ray的完整知识图谱。其亮点在于: 1. 结构严谨:从理论到实践,从基础到进阶,形成完整闭环 2. 内容深度:不仅告诉读者"怎么做",更解释了"为什么这样做" 3. 实用性强:包含大量经过验证的实操技巧和故障排查方法 4. 视野开阔:将技术使用置于法律伦理框架下讨论,体现社会责任感 5. 前瞻思维:不仅解决当下问题,还引导读者关注技术发展趋势
文章语言流畅自然,技术术语解释得当,在保持专业性的同时具有良好的可读性。特别是将枯燥的技术配置转化为提升数字生活质量的实用方案,展现了作者深厚的技术功底和人文关怀。
版权声明:
作者: freeclashnode
链接: https://www.freeclashnode.com/news/article-3888.htm
来源: FreeClashNode
文章版权归作者所有,未经允许请勿转载。
热门文章
- 12月6日|19.8M/S,V2ray节点/Clash节点/SSR节点/Singbox节点|免费订阅机场|每天更新免费梯子
- 11月22日|20.2M/S,Shadowrocket节点/V2ray节点/Clash节点/Singbox节点|免费订阅机场|每天更新免费梯子
- 12月5日|23M/S,Singbox节点/V2ray节点/Clash节点/SSR节点|免费订阅机场|每天更新免费梯子
- 12月11日|23M/S,Singbox节点/V2ray节点/Clash节点/Shadowrocket节点|免费订阅机场|每天更新免费梯子
- 11月25日|20.3M/S,Clash节点/V2ray节点/Singbox节点/SSR节点|免费订阅机场|每天更新免费梯子
- 12月9日|20M/S,Singbox节点/V2ray节点/Clash节点/SSR节点|免费订阅机场|每天更新免费梯子
- 12月12日|18.6M/S,Singbox节点/Clash节点/Shadowrocket节点/V2ray节点|免费订阅机场|每天更新免费梯子
- 12月8日|21.6M/S,Singbox节点/SSR节点/V2ray节点/Clash节点|免费订阅机场|每天更新免费梯子
- 12月13日|18.1M/S,V2ray节点/SSR节点/Clash节点/Singbox节点|免费订阅机场|每天更新免费梯子
- 11月20日|19.3M/S,Singbox节点/Shadowrocket节点/V2ray节点/Clash节点|免费订阅机场|每天更新免费梯子
最新文章
- 12月17日|20.7M/S,Singbox节点/V2ray节点/Shadowrocket节点/Clash节点|免费订阅机场|每天更新免费梯子
- 12月16日|21M/S,SSR节点/Singbox节点/Clash节点/V2ray节点|免费订阅机场|每天更新免费梯子
- 12月15日|20.8M/S,SSR节点/Singbox节点/Clash节点/V2ray节点|免费订阅机场|每天更新免费梯子
- 12月14日|21.5M/S,V2ray节点/Shadowrocket节点/Singbox节点/Clash节点|免费订阅机场|每天更新免费梯子
- 12月13日|18.1M/S,V2ray节点/SSR节点/Clash节点/Singbox节点|免费订阅机场|每天更新免费梯子
- 12月12日|18.6M/S,Singbox节点/Clash节点/Shadowrocket节点/V2ray节点|免费订阅机场|每天更新免费梯子
- 12月11日|23M/S,Singbox节点/V2ray节点/Clash节点/Shadowrocket节点|免费订阅机场|每天更新免费梯子
- 12月10日|19.9M/S,Clash节点/V2ray节点/Singbox节点/SSR节点|免费订阅机场|每天更新免费梯子
- 12月9日|20M/S,Singbox节点/V2ray节点/Clash节点/SSR节点|免费订阅机场|每天更新免费梯子
- 12月8日|21.6M/S,Singbox节点/SSR节点/V2ray节点/Clash节点|免费订阅机场|每天更新免费梯子
归档
- 2025-12 29
- 2025-11 55
- 2025-10 56
- 2025-09 55
- 2025-08 49
- 2025-07 31
- 2025-06 30
- 2025-05 31
- 2025-04 31
- 2025-03 383
- 2025-02 360
- 2025-01 403
- 2024-12 403
- 2024-11 390
- 2024-10 403
- 2024-09 388
- 2024-08 402
- 2024-07 424
- 2024-06 446
- 2024-05 184
- 2024-04 33
- 2024-03 32
- 2024-02 29
- 2024-01 50
- 2023-12 53
- 2023-11 32
- 2023-10 32
- 2023-09 3