BurningBright

  • Home

  • Tags

  • Categories

  • Archives

  • Search

关于数据异步导出

Posted on 2022-05-18 | Edited on 2022-05-23 | In java

上周开始做大量数据导出需求,今天记录些思路。

分析

  1. 原系统使用同步导出,文件流形式响应前端。
  2. 前端页面一直卡住无提示体验不佳,且数据量有限制以避免请求超时。
  3. POI导出工具类使用XSSFworkbook,如果数据量巨大可能会内存溢出。

基于现状需要改造系统导出,采用异步导出。
异步导出可以做成统一界面、前端轮询或是邮件通知的形式。
异步导出文件对象,采用上传云存储返回用户URL的形式下载。

思路

asychronous _export.png
不开发界面查询导出任务,用户提交导出请求后,以同参数轮询接口。
应用系统兼顾后台系统和导出系统。

聊一聊数据导出那些事 这篇文章中聊到的导出过程相当有范

  1. 提交导出申请:接口实现
  2. 生成导出批次:参数实现
  3. 发送导出批次到中间件
  4. 提交申请成功
  5. 读取导出批次信息:异步线程池传参
  6. 查询/生成/加密文件
  7. 上传到云存储
  8. 组装下载地址
  9. 回填信息:前端轮询
  10. 查询导出申请并下载:前端轮询

总体看来思路相同,包括第六步对旧文件的处理
主要区别来自需求和架构,在用户交互和第五步对导出任务执行上的区别

实现

  1. 改造工具类使用SXSSFWorkbook导出excel
  2. 设计导出任务数据结构
  3. 同进程异步线程池执行导出任务;更新进度
  4. 管道流在异步线程池中上传文件对象;更新进度
  5. 列举云存储文件,删除旧导出文件
  6. 返回轮询目标任务文件URL,导出完成

聊一聊数据导出那些事
使用SXSSFWorkbook来导出excel
HSSFworkbook,XSSFworkbook,SXSSFworkbook区别总结
Java中怎么将OutputStream 转换成InputStream
对象存储 OSS

macOS 上安装 STM32CubeProgrammer

Posted on 2022-03-22 | In 漫步键圈

看了一段时间QMK主控,想找IO口多一点的板子,考虑过tensy2.0++,找了一下价格感人。
就算是tensy2.0,虽说IO口符合需求,但价格也有点贵,而且还是上古mini-usb接口,果断放弃。
想过自制type-c pro micro,考虑到没什么贴片元件焊接经验,手头又没焊接工具,也就不折腾了。
https://docs.qmk.fm/#/compatible_microcontrollers

最后选了一款stm32的板子。
STM32F411 “BlackPill” Development Board

安装

https://www.st.com/zh/development-tools/stm32cubeprog.html
从官网下载macOS安装包,对怎么安装使用两眼一抹黑,看见解压包里竟然有jre文件夹就有种不详预感。
果然双击带图标的文件,图标一闪而过,下意识以为是jre版本不对,毕竟压缩包里附赠jre,一通环境变量修改,把JAVA_HOME指向附赠的jre,依旧闪退。。。只好上网找答案。

万能的『栈溢出』

最后是在 stackoverflow 找到了答案Installing STM32CubeProgrammer on macOS Big Sur
没想到这玩意需要用命令行来打开,只能说很符合用户群风格。。。

1
./SetupSTM32CubeProgrammerx.y.z.app/Contents/MacOs/SetupSTM32CubeProgrammer-x_y_z_macos

20220318_231934
20220318_232001

测试

从qmk编译了 handwired/onekey/blackpill_f411,烧录顺利,测试成功。
有意思是这玩意儿对烧录的温度有要求,上周末降温尝试烧录别的固件一直报错,一度以为是空间超了,结果放电脑上热一会再烧录就好了。

log4j2 lookups issues

Posted on 2021-12-20 | In java

2021-12-10 上上周五,log4j2爆出一个严重的代码注入漏洞。
突发!Log4j 爆“核弹级”漏洞,Flink、Kafka等至少十多个项目受影响

看完报道,感觉挺严重,抱着试试看的心态打开intellij想复现表达式注入,结果失败了。
表达式并没有被执行,而是字符串打印了出来,当时下意识感觉和jdk版本有关联,后边证实了我的想法。

1
logger.info("hello {}", "${java:os}");
Read more »

探索httpClient 4.5.13 源码

Posted on 2021-10-28 | Edited on 2021-11-07 | In java

客户端创建

1
2
3
4
5
6
CloseableHttpClient httpClient = HttpClientBuilder.create()
.setDefaultSocketConfig(socketConfig)
.setDefaultRequestConfig(requestConfig)
.setMaxConnTotal(totalNum)
.setMaxConnPerRoute(routeNum)
.build();

连接池

连接池建造者

建造者模式在创建HttpClient时如果没设置自定义连接池,会默认创建池化连接管理器
Registry用于创建套接字上下文,dnsResolver用于域名解析

HttpClientBuilder::build()

1
2
3
4
5
6
7
8
9
10
11
// line: 984
final PoolingHttpClientConnectionManager poolingmgr = new PoolingHttpClientConnectionManager(
RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.getSocketFactory())
.register("https", sslSocketFactoryCopy)
.build(),
null,
null,
dnsResolver,
connTimeToLive,
connTimeToLiveTimeUnit != null ? connTimeToLiveTimeUnit : TimeUnit.MILLISECONDS);

Read more »

tapip的工程框架

Posted on 2021-09-18 | In network

工程目录

目录 文件 Description
app 内嵌shell的网络命令
ping.c 网络请求命令
snc.c 网络监听命令
arp arp_cache.c 地址数据缓存
arp.c 地址解析处理逻辑
doc 工程文档
… …
include 头文件
… …
ip 网络层
icmp.c 网际控制报文协议
ip_forward.c 报文重定向
ip_in.c 收到ip数据报,交给运输层
ip_out.c 发送ip数据报,从运输层来
raw.c 读取链路层数据
route.c 路由寻找下一跳
lib 静态库文件
cbuf.c 环型缓冲数据结构
checksum.c 加和检查完整性
lib.c 打印、内存分配方法等
net 物理层、数据链路层
loop.c 事件轮询
net.c 数据链路层
netdev.c 网络设备相关
pkb.c 数据报相关
tap.c 操作tap设备
veth.c 虚拟网络,用户态处理的起点
shell 交互界面
main.c 程序启动入口
net_command.c 网络命令交互
ping_command.c ping命令交互
shell.c
socket
inet.c 绑定上层运输层协议
raw_sock.c 默认网络帧处理
sock.c 底层套接字
socket.c 上层套接字
tcp 模拟传输控制协议
tcp_in.c tcp报文接收处理
tcp_out.c tcp报文发送处理
tcp_reass.c 分配数据段?
tcp_sock.c tcp套接字相关
tcp_state.c 状态处理 RFC 793
tcp_text.c 滑动窗口收发数据
tcp_timer.c 超时计时器
udp 模拟用户数据报协议
udp_sock.c udp套接字相关
udp.c udp报文接收处理

编译过程

外层Makefile 配置调试选项、网络拓扑选项
执行make命令时,先用下层Makefile构建各个模块.o文件
各模块.o文件链接为目标文件xxx_obj.o
各模块目标文件,构建为可执行文件tapip

1
2
3
4
5
6
7
8
9
LD = ld
CC = gcc
CFLAGS = -Wall -I../include
LFLAGS = -pthread
export LD CC CFLAGS

ifeq ($(CONFIG_DEBUG), y)
CFLAGS += -g
endif
  • ld 链接器
  • gcc 编译器
  • -Wall 选项可以打印出编译时所有的错误或者警告信息
  • -I 选项指定寻找头文件的路径
  • -pthread 执行多线程选项
  • -g 选项是指可以用gdb调试

CMake中使用pthread实践

tapip的网络拓扑

Posted on 2021-09-13 | Edited on 2021-09-18 | In network

网络拓扑一:替换内核网络协议栈

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
+----------+
| internet | (10.20.133.20)
+----|-----+ |
+----|-----+ |
| eth0 | (0.0.0.0)
+----|-----+ |
+----|-----+ |
| bridge | (0.0.0.0)
+----|-----+ |
+----|---------+ |
| tap0 | (0.0.0.0)
|--------------|
| /dev/net/tun | /dev/net/tun
+--|----|---|--+ |
poll | | |
| read | |
| | write |
+--|----|---|--+ |
| my netstack | (10.20.133.21)
+--------------+

通过网桥连通本地网络eth0和虚拟网络tap0

区别

  1. 本地网络作为网关
  2. 不支持重定向
  3. 路由初始化,下一跳为TAP的IP
  4. 如果下一跳不可达,需要返回Code 0 (Network Unreachable) ICMP报文(RFC 1812)
  5. 虚拟网络设备额外初始化过程
  6. ifconfig 命令特殊提示

脚本

  1. 创建网络设备tap0 简要输出接口名到垃圾桶
  2. 创建网桥设备br0
  3. 配置网桥通过 br0 连通 eth0 tap0
  4. 将eth0 tap0 br0加入本地网络并启动

WARNING

谨慎使用该模式,内核协议栈会被挂起,网络由用户态接管。
如果是远程登录使用TOP1可能会导致断连,无法继续使用。
建议直接使用串口同真实机器交互,以方便恢复原网络拓扑。

网络拓扑二:虚拟设备与核心交互

1
2
3
4
5
6
7
8
localhost                     outside network
kernel stack usermode stack [ ./tapip ]
| (10.0.0.1)
| (write) | .
| \|/ /|\
| ' | (read)
tap0 <------ netif_rx() -----/dev/net/tun
(10.0.0.2) `-- tun_net_xmit() -----------^

local -> tap0(10.0.0.2) -> veth0(10.0.0.1)

交互

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
                  +-------------------[Linux kernel TCP/IP stack]---------------------+
| |
arping 10.0.0.1 -----> socket send --> route --> tap0 --> tap0::dev_hard_xmit |
| ( arp packet: | |
| 10.0.0.2 request | |
| hwaddr of 10.0.0.1) | _tap0 (10.0.0.2)_ |
| | |
arping received <----- socket recv <-- tap0(netif_rx) <----. | |
| | | |
+-----------------------------------------|--|----------------------+
| |
/dev/net/tun
| |
(write) | | (read)
| |
.--------> reply --> netdev_tx-' | _veth (10.0.0.1)_
| \|/
| '
'- arp_in <-- netif_in <----- process
update arp cache <------' { usermode network stack }
  1. arping 命令进程向内核发起寻址请求
  2. 内核将请求包路由至tap0设备
  3. 经虚拟网络设备交换至用户态协议栈tapip处理
  4. 寻址结果返回设备tap0,经内核返回arping命令进程显示

Linux虚拟网络设备之tun/tap
user-mode TCP/IP stack based on linux tap device

尝试分析UDP

Posted on 2021-07-16 | Edited on 2021-09-18 | In network

Host

准备环境
Server

1
2
3
4
5
6
7
8
ens3      Link encap:Ethernet  HWaddr 02:42:ac:11:00:36  
inet addr:172.17.0.54 Bcast:172.17.255.255 Mask:255.255.0.0
inet6 addr: fe80::42:acff:fe11:36/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:3733 errors:0 dropped:0 overruns:0 frame:0
TX packets:1723 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:1216408 (1.2 MB) TX bytes:678036 (678.0 KB)

Client

1
2
3
4
5
6
7
8
ens3      Link encap:Ethernet  HWaddr 02:42:ac:11:00:18  
inet addr:172.17.0.24 Bcast:172.17.255.255 Mask:255.255.0.0
inet6 addr: fe80::42:acff:fe11:18/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:1717 errors:0 dropped:0 overruns:0 frame:0
TX packets:904 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:1021151 (1.0 MB) TX bytes:301129 (301.1 KB)

Read more »

大教堂,集市和镇议会【译】

Posted on 2021-06-07 | Edited on 2021-06-10 | In blog

作者:艾伦•考克斯

这些是我认为值得分享的,我对’集市模式’的一些想法。它同时也是一个如何彻底搞砸一个自由软件项目的指南。我选择了一个我认为最好的,被称之为“城镇议会”效应的经典例子(尽管镇议员们可能不这么认为)。

对于软件开发人员,您必须了解一些特定的事情。首先要理解的是,真正优秀的开发者相对来说并不常见。不仅如此,一个真正的“真实开发者”和“普通开发者”之间的差异,相比其他职业“优秀”和“普通”之间的差异要大得多。研究表明,最好的开发者和其他开发者在工作效率上的差异是30比1。

其次,你需要明白,许多想成为真正开发者的人非常擅长发表意见。他们中的许多人还染上了噜苏病,或被一些专业人士认为这是“唯一正确的道路”。要知道在以太网上夸夸其谈很廉价。

任何软件项目的第三方就是我们所说的“群众”。他们中有些人不编程,但在其他领域做出了巨大贡献——文档、用户帮助和美术作品,这类人通常认为你需要一个许可证才能连接到互联网。

我将以Linux 8086项目为例来说明如何彻底搞砸。总的来说,将Linux的一个子集移植到8086是世界上最没有意义的练习之一,一开始只是个玩笑,后来就失控了。

只有极少数真正的开发者有足够的时间和正确的(或者是错误的)精神状态来为项目做出贡献,而这个项目的唯一真正价值就是“Hack Value”。因此,在任何给定的时间,项目都有两个或三个核心贡献人员。

不幸的是,有很多人认为在8086上运行Linux会很好,他们觉得有义务“参与”。在这种情况下,他们中的大多数人都停留在“想成为开发者”这一类人,因为他们从安全距离发现了这个项目的“愚蠢”因素。

开始出现的问题是,许多(大部分意义很好)危险的半线索人带着意见的到来,不是代码而是意见!他们完全清楚应该怎么写,但大多数人不会用C语言写“hello world”。因此在项目使用了一年适用的编译器后,他们为用什么编译器亦或是重写一个争论了几周。他们忙于讨论如何生成大型模型二进制文件,而忽略了内核交换器设计。

Linux 8086继续开发,真正的开发人员在他们的kill文件(黑名单)中有很多其他列表成员,这样他们就可以通过列表进行通信,而这仅仅是因为有太多的半线索人在乱发邮件。它不再是一个集市模式,它变成了一个核心团队,对许多人来说,这是一个礼貌的用词。在这种情况下,这是不可避免的防御阵地。

在Linux的模式中,用户/开发者基础增长缓慢,它的成长背景是从一群贡献代码的人员中成长起来的,他们要么是在最初的Minix黑客社区中有基础,要么是通过一次次启动的艰难方式学会了一些东西。随着项目的发展,那些原本应该成为“Linux内核结构规划管理委员会”的人反而被抛弃在一个期望他们交付的环境中,在那里失败不被视为问题。用莱纳斯的话来说,“给我看看源码”。

如果有人被卡住了,他们就会发布问题,通常会有一个基数足够大的,有时间和相应知识的人来回答。在Linux8086的案例中,开发人员早就把自己隔离起来了。如果有一个更好的活跃开发者与潜在有用的开发者的比例,就能迅速将一些噪音转化为生产力。这个项目可以获得更多有用的开发者,他们反过来也可以教其他人。与任何学习练习一样,你最好只有几个学徒。

有些人认为你不能把“低级开发者”变成真正的开发者。从个人在Linux项目中的经验来看,有很多人提供了一点帮助,并增加了一点他人的信心,他们将成为最好的开发者。有很多人不会,但足够多的人会。

作为这个声明的一个例子,Linux IPv6源代码的作者曾经在葡萄牙的irc(Internet Relay Chat)上提出一些基础的想法和问题。在我们帮助他解决一些内核内部问题后,他编写了大约75%的Linux IPv6协议代码,而最后一次见到他是在美国为思科工作。

Linux 8086项目基本上已经从它的“侵扰”中恢复过来,现在是一个小的安静的项目,使用CVS树,由Alastair Riddoch领导,他一直在做出色的工作。随着镇议员的解散,现在可以自由的提出问题,加入和帮助这个项目。

从这个项目以及其他类似项目(有时会失败——还记得早期的Linux文字处理项目)中得到的教训非常清楚:

  • 从一开始就发布代码。如果不是很有用也没关系。对镇议会进行分类的最好方法就是简单地完成工作,然后告诉他们已经完成了。Linux、KDE和GNOME都采取了这种态度,并且都做得很好。你可以为正确的编程方式争论一辈子。一旦有了代码,人们(不管他们的技能如何)就可以使用它。
  • 感谢那些给你一点帮助,却能为项目做出巨大贡献的人。如果他们的第一个补丁有问题,不要忽略它们,解释为什么会有问题,并提出解决方案或是指出能寻找到解决方案的地方。每一分钟花在回答真正的问题上,帮助别人在一个项目上工作,将会得到十倍于项目的回报,对社会的回报将是不可估量的。
  • 不要忘记非开发者。我发现很可悲的是,当被问及“最重要的五名Linux内核人员”时,大多很少说出一些最重要的人的名字——所有那些维护网站、更改日志、邮件列表和文档的人都同样重要。莱纳斯说“给我看看代码”,这是对一个真实项目的狭隘看法。当你听到“我很想帮忙,但我不会编程”,你听到的是一个文档管理员。当他们说“但英语不是我的母语”时,你就有了另一种语言的文档和翻译人员。
  • 试着把有用的人从噪音中分离出来。试图把人们从大量无意义的讨论中分离出来很难,在Linux 8086的案例中,我放弃这个目标绝对是错误的。如何排除那些只说不做的人是一个研究课题。

所以下次有人想要对一个项目投票,或者讨论一个月的问题,然后执行它——请注意。他们有可能最终能找到正确的解决方案。但不管怎样,你还是有较大可能性继续开发下去。只要在项目推进时,让他们给你发个补丁就行了。

要小心“我们应该”,而是着手于“我该怎么”……

——1998

Cathedrals, Bazaars and the Town Council
Feature:Cathedrals, Bazaars and the Town Council
Alan Cox

均方误差的偏方差分解

Posted on 2021-05-14 | In ml
  • 均方误差期望 = 偏差 + 方差 + 噪音

  • 偏差显示了,预估模型和“真实”函数 $f(x)$ 之间的数值差别。

  • 方差显示了预估函数 $\hat{f}(x)$ 值与其均值的分散程度

https://en.wikipedia.org/wiki/Bias%E2%80%93variance_tradeoff
https://datawhalechina.github.io/pumpkin-book/#/chapter2/chapter2

usb 转 usb 转换器

Posted on 2021-04-18 | Edited on 2021-04-23 | In 漫步键圈

489871548.jpg

19年初看到老莱频道剪辑师介绍的 Hasu u2u 转换器非常心动,可惜已售罄。
在geekhack上找到 Hasu 的帖子USB to USB keyboard converter build log,但完全不知道怎么制作。
这是第一次了解到 Hasu 和他的 TMK,后来在看Yang的HHKB蓝牙双模改装方案时发现也有 Hasu 的贡献。

20年8月看到50元成本自制转换器,正好ERGO88进展不顺,打算试试QMK换换心情。
结果是反复尝试进DFU都失败,一度以为运气不好,买到的 Arduino pro micro 板子没法刷固件。
纠结半天,曾打算买ISP工具重新烧录bootloader,最后担心花费太多时间精力还是放弃了。

21年初完成ERGO88后,重买 pro micro,这次以防万一,买了16MHz-5V版本。
16MHz u2u运行正常,换到8MHz发现去年买的板子竟然烧录正常。
问题应该是出在第一次进DFU上,尝试在插入USB前就短接,插入后放开再短接一次就能顺利进入。

原理图

20210421155504.png
如果买的是3.3V版本的pro micro,就不用再接U2线性稳压元件

50元成本自制转换器 里面包板线序没有很清晰的标注出来,原理图参考 USB Host Shield Library, For Connecing Other USB Devices。

Shield

20210421163704.jpg
usb hub的外接设备供电,需要和板子断开,如图中红圈所示断开线路。
飞线shield的raw针至图中箭头所示焊盘,使用 pro micro 的raw针为设备供电。

20210421163804.jpg
外接设备供电飞线,3.3V和RST针飞线。

线路参考: 在 Arduino Min (3.3V,8MHz) 上使用 Usb Host Shield Mini

130850.jpg

Arduino

20210422153200.jpg
旋转180度,层叠在一起。
右上第三针如果插接会短接VCC,这里我掰掉了 pro micro 的第三针GND脚。

固件

解决好供电,晶振频率的问题可以通过固件适配。

8Mhz https://config.qmk.fm/#/converter/usb_usb/pro_micro/LAYOUT_all

16MHz https://config.qmk.fm/#/converter/usb_usb/hasu/LAYOUT_all

如果键盘是非标键盘,或是有宏定义的需求,可以自行编译。
https://github.com/qmk/qmk_firmware/tree/master/keyboards/converter/usb_usb

在 keymaps 下新增映射表,并编译
./bin/qmk compile -kb converter/usb_usb/pro_micro -km default

烧录

  1. 下载hex固件文件
  2. 下载 qmk_toolbox,注意安装驱动
  3. 短接两次RST脚和GND脚,进入bootloader,该状态会维持8秒。
  4. 选择好hex固件文件,在DFU状态点击烧录按钮,等待界面升级日志提示成功。
  • 如果arduino插入toolbox没反应,检查驱动是否安装
  • 如果arduino两次短接没法进入DFU,尝试先短接RST、GND再连接电脑,放开再短接一次。

在 Arduino Min (3.3V,8MHz) 上使用 Usb Host Shield Mini
我修我自己——Arduino充当ISP烧录器修复Arduino记录
【HIDuino】 — 超迷你的USB-HID开发板
https://www.arduino.cn/thread-6001-1-1.html
Arduino串口调试助手(2013.12.28更新)


https://1upkeyboards.com/shop/controllers/usb-to-usb-converter/
USB Host Shield Library, For Connecing Other USB Devices
USB to USB keyboard converter build log(Pro Micro 3.3v with mini host shield)
50元成本自制转换器——普通键盘变全键可编程键盘键盘什么值得买
【官方双语】打鸡血的键盘-Hasu USB到USB键盘控制器转换器#linus谈科技

12…28

Leon

278 posts
20 categories
57 tags
GitHub
Links
  • clock
  • typing-cn
  • mathjax
  • katex
  • cron
  • dos
  • keyboard
  • regex
  • sql
  • toy
© 2017 – 2022 Leon
Powered by Hexo v3.9.0
|
Theme – NexT.Muse v7.1.2