avatar
文章
92
标签
122
分类
5

首页
合集
  • 归档
  • 标签
  • 分类
专栏
  • 开发笔记
  • 日常记录
友链
关于
首页
合集
  • 归档
  • 标签
  • 分类
专栏
  • 开发笔记
  • 日常记录
友链
关于

CYK's Blog

GPR 数据到底长什么样:A-scan、B-scan 与采样定理
发表于2026-06-24|开发笔记|GPR•雷达•信号处理•采样定理
探地雷达往地下打一束高频电磁脉冲,遇到材料变了的地方,一部分反射回来,剩下的继续往下走。仪器只记录两个数:什么时候回来,回来有多强。所有 GPR 数据说到底就是这个。 反射和深度反射强弱看界面两边材料差多少: $$R = \frac{\sqrt{\varepsilon_1}-\sqrt{\varepsilon_2}}{\sqrt{\varepsilon_1}+\sqrt{\varepsilon_2}}$$ 混凝土介电常数大概 6~9,空气接近 1。衬砌背后出现空洞时,两边差得大,反射就强。空洞、脱空能被探到,原因就在这里。 深度从回波时间换算: $$d = \frac{v \cdot t}{2}, \qquad v = \frac{c}{\sqrt{\varepsilon_r}}$$ $t$ 是电磁波下去再上来的双程时间,所以除以 2。光速 $c=0.3,\text{m/ns}$,混凝土里波速大概 $0.10\sim0.12,\text{m/ns}$。回波时间对应深度,回波强弱对应界面差异——这两句话是后面所有算法的基础。 A ...
零线刷新幂等去重 缓存数组逐元素比较
发表于2026-06-17|开发笔记|踩坑•性能优化•Kotlin•幂等
现象零线对齐初始化那阵,发现磁盘被频繁读、初始化很慢。profile 了一下,看到 reloadBuffer 被反复触发了很多次。 原因初始化时有好几个事件源(不同组件的状态变更)都会触发 reloadBuffer——也就是重新从磁盘读雷达数据再刷新。这些事件短时间里密集到达,虽然最后零线的状态其实没变,但每次都老老实实重读一遍磁盘,做了大量重复 IO。 去重要让刷新幂等,说白了就是相同的输入只处理一次。把上一次的 zeroPositions 数组缓存下来,新事件来了先比一比新旧: fun onZeroLineUpdate(newPositions: DoubleArray) { if (newPositions contentEquals lastPositions) return // 没变,跳过 lastPositions = newPositions.copyOf() reloadBuffer()} 为什么不算哈希第一反应可能是算个哈希比一下,快。但哈希会碰撞:两个内容不同的数组哈希恰好一样,就会被当成”没变”漏掉刷新,雷达图就错位了 ...
雷达采样直方图从 O(N×M) 优化到 O(N) 单遍桶计数
发表于2026-06-15|开发笔记|性能优化•Kotlin•算法•直方图
背景雷达图渲染前要统计采样值的分布——算百分位、做增益和对比度映射,这步一般叫”采样直方图”。打开一个多文件的测线时,每打开一个文件都得算一遍。 原来的 O(N×M)最早的做法是”对每个待统计的输出桶,把所有采样点扫一遍,数有多少落进这个桶”。N 个采样点 × M 个桶,复杂度 O(N×M)。单文件几百万采样点的时候,光这一步就把打开速度拖慢一大截,多文件叠在一起更明显。 改成 O(N) 单遍桶计数其实直方图没必要每个桶都扫一遍数据。一趟遍历,把每个采样点直接扔进它对应的桶就行了: fun histogram(samples: IntArray, min: Int, max: Int, bucketCount: Int): IntArray { val buckets = IntArray(bucketCount) val range = (max - min).coerceAtLeast(1) for (v in samples) { val idx = ((v - min).toLong() * bucketCount / ran ...
Kotlin 协程生命周期 SupervisorJob 与 Mutex 超时保护
发表于2026-05-22|开发笔记|Kotlin•协程•并发•生命周期
SupervisorJob默认情况下,协程作用域用的是 Job(),父子关系就像一根绳上的蚂蚱——任意一个子协程抛异常,整个作用域(包括其他正常跑着的兄弟协程)都会被取消。对于”加载多条测线、其中一条失败不该拖累其他”的场景,这就太脆了。 换成 SupervisorJob(),子协程的失败不会往上传播,其他兄弟照常跑: class RadarViewModel { private val scope = CoroutineScope(SupervisorJob() + Dispatchers.Main)} @PreDestroy协程要是不主动取消,它会一直挂着,引用着 ViewModel / UI,造成内存泄漏,甚至组件都销毁了还跑回来刷新一个已经失效的 UI。把 scope 的取消绑到生命周期上: @PreDestroyfun onDestroy() { scope.cancel() // 取消所有子协程} Mutex 加超时共有 / 复合病害的计算可能短时间里被触发好几次(连续编辑),不加锁的话,两个并 ...
JavaFX Canvas 踩 GPU 纹理上限 视口裁剪方案
发表于2026-05-20|开发笔记|JavaFX•Canvas•性能优化•渲染
现象有条超长的层位线(20000+ 道)在雷达图上只显示了一截,甚至整段空白;短一点的层位线倒是正常。 原因原来的渲染是把整段层位线一口气画到一个 Canvas 上,Canvas 的宽度就等于这段的道数。一条 20000 道的层位线,Canvas 宽度起步就是 20000 像素,缩放之后还更高。 而 GPU 纹理是有尺寸上限的,一般在 16384 ~ 32768 像素之间,看显卡。Canvas 宽度一旦超过这个上限,渲染就直接失败——而且是静默失败,表现就是空白或者只画了一截,啥报错都没有,排查起来很费劲。 视口裁剪办法就是只画当前能看见的那一截,整段别都画。Canvas 宽度始终差不多等于视口宽度(屏幕上能看到的范围),内容跟着滚动、缩放重绘: 根据当前的滚动位置和缩放,算出视口覆盖的道号区间 [from, to]。 只把这个区间里的层位线点画到 Canvas 上。 Canvas 宽度固定成视口宽度,永远不会越过 GPU 的纹理上限。 用户一滚动或者缩放,就重新算区间、重绘。 附带的优化视口裁剪顺带把性能问题也解决了:以前不管你看哪,都在画 20000 个点,现在只画视口里那几百 ...
SQLite 批量更新 CASE WHEN 与 999 变量上限
发表于2026-05-14|开发笔记|SQLite•SQL优化•数据库•批量更新
痛点病害的”共有 / 复合”状态算完得持久化。几百上千条病害,最开始是逐条 UPDATE,两个毛病:一是慢,每次 UPDATE 都是一次磁盘事务;二是没有整体事务保护,中途一旦失败,就留下一堆半新半旧的数据。 CASE WHEN 批量更新把 N 条逐条 UPDATE 合成一条,用 CASE WHEN 给每行不同的值: UPDATE defectSET compound_level = CASE id WHEN 101 THEN 'AA' WHEN 102 THEN 'A1' WHEN 103 THEN 'B' END, is_compound = CASE id WHEN 101 THEN 1 WHEN 102 THEN 1 WHEN 103 THEN 0 ENDWHERE id IN (101, 102, 103) 一趟往返就更新了多行多列,磁盘事务次数从 N 次降到 1 次。外面再用 TransactionTe ...
用事件总线解耦模块 零线变更的级联重算
发表于2026-05-12|开发笔记|Kotlin•架构设计•事件总线•解耦
问题用户调一下”零线”,后面会牵一发动全身:受影响的文件得重算厚度不足段、层位段平均深度、病害深度,层位识别和病害标注那边的雷达图、列表也都得跟着刷新。 要是让零线模块直接去调各模块的刷新方法,耦合就焊死了——零线模块得记着谁要刷新、调谁的哪个方法,以后多加个模块还得回来改零线的代码。 事件总线加一个轻量的事件总线,零线模块只管”发事件”,谁在意谁自己”订阅”: // 发布方:零线模块,不关心谁来处理eventBus.publish(ZeroLineChangedEvent(affectedFileIds))// 订阅方:层位识别模块,自己决定怎么响应@Subscribefun onZeroLineChanged(e: ZeroLineChangedEvent) = scope.launch { recalcLayerSegments(e.affectedFileIds) refreshChart()} 好处其实就是几件事搅一块儿:发布方和订阅方互相不认识,以后加模块订阅一下就行,零线代码不用动;重算(耗时)和刷新(UI)各跑各的协程,互不卡;零线模块 ...
用并查集识别隧道相邻测线的共有病害
发表于2026-05-09|开发笔记|Kotlin•算法•并查集•数据结构
业务场景隧道里有多条平行的测线,相邻两条(编号差 1)上要是各有一个病害、里程范围还重叠,那很可能就是同一个病害在两条测线上各露了一面——这种得标成”共有病害”。 难点在传递性判断这事不能光看两两配对,因为重叠是会传递的:A 和 B 重叠、B 又和 C 重叠,那 A、B、C 其实是同一组,该归到一块儿。要是只两两标记,A-B 一组、B-C 一组,C 跟 A 之间的关系就丢了,分出来的组是碎的。 并查集(Union-Find)这种”沾边就连、要整体分组”的活,正好是并查集擅长的: class UnionFind(n: Int) { val parent = IntArray(n) { it } val rank = IntArray(n) fun find(x: Int): Int { if (parent[x] != x) parent[x] = find(parent[x]) // 路径压缩 return parent[x] } fun union(a: Int, b: I ...
Excel 导入的两个坑 字段截断与 32767 字符限制
发表于2026-04-30|开发笔记|踩坑•Excel•SQLite•POI
背景做历史层位 / 病害的 Excel 导入导出的时候,连踩了两个”长度上限”的坑,一个在数据库,一个在 Excel 本身,记一下。 坑一:SQLite 字段截断导入历史层位线以后,滚到中间位置,长段的层位线突然变成了一条水平直线。排查发现,存深度数据的 depth_index_array 列定义成了 VARCHAR(5000),超长段的数据被静默截断了——SQLite 写入的时候不报错,读出来就是一截残缺数据,渲染自然就错了。 解决办法:把这列改成 TEXT,不限长度。SQLite 的 TEXT 本身不限长,VARCHAR(N) 里的 N 只是个 hint、并不会真限制(SQLite 弱类型),但有些驱动 / ORM 层会按声明长度截断,所以声明成 TEXT 最保险。 教训就是:别拿 VARCHAR 存可能很长的内容,长文本一律 TEXT,免得被中间某一层按声明长度给截了。 坑二:Excel 单元格字符上限层位导出的时候,原始数据那列把整个深度数组塞进了一个单元格,结果导出直接失败。原因是 Excel 对单个单元格的字符数有硬上限:32767 个字符。深度数组动不 ...
JavaFX 截图卡死 UI 的根治 Java2D 纯数据渲染
发表于2026-04-16|开发笔记|JavaFX•性能优化•Java2D•MVVM
痛点病害导出的时候,每条病害要生成一张雷达图截图。原来的做法是直接对着界面上那个 JavaFX 节点调 snapshot() 截图。问题来了:snapshot() 必须在 FX Application Thread 上跑,导出几十上百张图的时候,主线程被这些截图任务占得死死的,整个 UI 完全卡住,进度条都不带动的。 思路卡死的根子在于渲染绑死在 UI 线程上了。要彻底解决,就得让渲染脱离 JavaFX 节点,变成在随便哪个线程上都能跑的纯计算。所以我把截图渲染从”拍 UI”改成了”用 Java2D 拿纯数据画”。 改造按 MVVM 三层切开: View 层只管从 UI 组件里抠出纯数据(当前视口的里程范围、采样值数组、增益、颜色映射这些),不掺和画图。 ViewModel 层负责渲染的调度和参数拼装,把 View 抠出来的数据组装成绘图参数。 Service 层是纯绘图,用 BufferedImage + Graphics2D 画雷达图、层位线、病害框、信息面板,完全不碰 JavaFX。 // Service 层,任意线程可跑fun render(params: RenderPa ...
1…345…10
avatar
CYK
CYK 的个人技术博客,记录 Docker、Linux、Java、网络运维等后端与运维实践,以及日常折腾和踩坑笔记。
文章
92
标签
122
分类
5
公告

怎么这么难!
我真服了!

最新文章
评论区加载不出来?把 Twikoo 从 Vercel 搬回自己服务器2026-10-27
静态博客的传输层优化:HTTP/2、gzip 和缓存头2026-10-27
重装只是开始:把公网服务器从裸奔状态拉回来2026-10-27
服务器被拿去当肉鸡:一次入侵的完整复盘2026-10-26
oh-my-posh:一个好看的终端提示符怎么装2026-08-05
分类
  • 学习笔记1 篇
  • 工具笔记1 篇
  • 开发笔记84 篇
  • 生活记录1 篇
  • 运维笔记4 篇
标签
并查集 性能优化 DOCX 安全 Gradle Nginx 逆向 Shell JAVA SCRIPT Hexo Kotlin协程 算法 打包 Butterfly BIG 渲染 JDK25 属性绑定 踩坑 Java JavaFX MySQL 入侵复盘 数据处理 Algolia MQ 工具 回调 协程 hexo 命令行 增益 批量更新 SQL优化 二进制 SVN MongoDb 采样定理 图像处理 基础
归档
  • 十月 20264 篇
  • 八月 20261 篇
  • 七月 202622 篇
  • 六月 20266 篇
  • 五月 20265 篇
  • 四月 20264 篇
  • 三月 20262 篇
  • 二月 20264 篇
网站资讯
©2024 - 2026 By CYK

HEXO Butterfly GitHub
鲁ICP备2024065423号-2

搜索