Monday, July 11, 2022

V2EX - 技术

V2EX - 技术


前端和后端中间的部分一般习惯叫做什么

Posted: 11 Jul 2022 03:43 PM PDT

如图:

前端和后端比较好理解,但一般为了还会在中间增加一层。

用于将后端的映射为页面直接可以使用的接口。

这部分叫做什么呢

修改后的 EVA 初号机 VS Code 主题 各位提点意见

Posted: 11 Jul 2022 03:07 PM PDT

在预算有限的情况下,服务器放在哪里能兼顾全球用户啊?

Posted: 11 Jul 2022 02:54 PM PDT

请问各位牛人,想建立一个小型电商网站,请问,应该把服务器放在哪里,能兼顾全球用户在做下订单这样的动态操作时,都会有不错的体验啊?刚刚创业,资金有限,希望能在起步的时候尽量省钱。大家有具体的服务商和服务器地区推荐吗?谢谢!

微信聊天记录导出,这个需求大吗?

Posted: 11 Jul 2022 02:45 PM PDT

目前,做了一个安卓端的微信聊天记录导出的 APP ,能够导出聊天记录(文本、网页、数据库等格式)和联系人,支持文件、图片、视频、音频等多媒体资源。目前已经发布在了酷安网,但是好像没什么人气。是因为 Root 的门槛过高,还是没什么需求呢?我做这个之前,调研到不少用户好像有这个需求,结果做出来无人问津,有点悲观。 如果 V 友们有需求,有能力,欢迎支持一下。

c++20 coroutine 实现的 generator 可以被优化成常数

Posted: 11 Jul 2022 02:04 PM PDT

JDK17 都出来了,感觉现在很多资深程序员 Stream 不会, Lambda 不会, Java .time 包不会

Posted: 11 Jul 2022 01:27 PM PDT

不少资深人士写代码的时候还是各种 for 循环。

Lambda 也不用,还用各种匿名内部类。

还有 JDK8 的时期时间库,很多人还是在用 Date ,Calender 。现在的 LocalDate, LocalDateTime, YearMonth, ZonedDateTime 做时间计算真的特别直观简单,但是他们就喜欢用 Date ,简单的计算就用毫秒加减,复杂点的计算就先换成 Calender ,完事后再转换回 Date 。

甚至 JDK7 的 try-with-resources 语法我都感觉不少人都不知道。

所以,现在"JDK8 是主流"这句话是不对的,而是"JVM8 是主流"才是对的。语法的主流应该是 J2SE 1.5 。

有一个 Redis 通知的问题想问一下大家

Posted: 11 Jul 2022 01:20 PM PDT

最近需要做一个订单超时未支付自动取消的功能
研究一下方案后,暂时决定用监听 Redis 失效 Key 来实现
简单测试了一下可以用,但有一个小问题
网络搜的实现过程 第一步大部分都是打开 redis.conf 里的键事件的通知
即这样设置 notify-keyspace-events Ex
但是我没按这个来 默认的设置没改动 仍然可用
即 notify-keyspace-events ""
有没有大佬可以解释一下这种情况
感谢

分布式环境下,不借助任何第三方存储的前提下,是不是必须要自己实现一个“存储”

Posted: 11 Jul 2022 11:28 AM PDT

不借助 redis 、mysql 等第三方存储。

想维护一个集群的当前连接,是不是只能靠 raft 等机制实现自己的一个存储,而且一定是依靠主从的?

比如一个 websocket 集群环境。我想知道当前整个集群中一共有多少连接活跃和连接详情(假设是 map[uid:string]server-ip )而不借助第三方存储(比如 redis 计数)是不是只能自己把每个节点的连接信息上报到当前集群的 leader 中(所谓 metadata )同时所有节点除了维护自身连接外,同样也接受备份存储。

12 代 cpu 做 nas 现在合适吗?

Posted: 11 Jul 2022 10:31 AM PDT

想升级一下家里的 nas, 本着能省则省,能跑满 2.5G 下载的原则(没有板载 2.5G 网卡的话,就自己加 usb 或者 pcie 2.5G 网卡。或者板载 1G+我闲置的 1G usb 网卡组链路聚合?),打算用铭瑄 H610 itx(500 多)或者精粤 H610 itx ( 300 多)+ g6900(200 多)组黑裙。前面都是 pdd 价格。不知道黑裙目前对 12 代 cpu 支持情况怎么样,大家有什么意见吗?

xdm,接了个外包,对面是公司,要求签合同开发票咋整?我是个人开发的阿,没有公司

Posted: 11 Jul 2022 10:07 AM PDT

咋弄 第一次搞 整个网站

请教如何打 log,性能最好

Posted: 11 Jul 2022 08:31 AM PDT

如果每打一句 log ,就阻塞住,通过 filestream 往文件中写入一句 log ,写入很多次(比如 10000 次),多少会影响程序性能。

想请教各位大佬,性能最好的 log 方案是什么样的?

有道云笔记新版已不支持导出功能,有永久丢失数据的隐患

Posted: 11 Jul 2022 08:31 AM PDT

以前导出有两种:

1.导出全部数据为一个有道云笔记的专用文件。这种功能用于用户自行备份数据。

2.导出全部数据为 PDF 文件,具体做法是,每篇日志,导出为一个单独的 PDF 文件。

这两个功能,新版本都已经取消。也就是说:

1.新版本没有导出功能,只有导入功能。

2.新版本,用户再也没办法自行备份,只能买会员恢复数据,而且限次数。

3.如果云端数据丢失,那就真的永久丢失。

看了站内很多不小心把数据库清空或误删数据的

Posted: 11 Jul 2022 08:26 AM PDT

提个醒:

1.一定要做数据库自动备份,至少每日一备份。 就是个脚本的事情,搜一下就完事了。

2.除了查询外,做增删改之前,一定要备份一次。不要怕麻烦,不要怕耽误时间。 性能不够上固态,固态不够上内存盘。

以上两点,没做好,是有可能吃牢饭的,没开玩笑。

码农想入手个游戏主机 PS 还是 XBOX

Posted: 11 Jul 2022 08:18 AM PDT

个人喜欢玩单机游戏 之前有台 XBOX360 玩也都是 鬼泣 古墓丽影 孤单惊魂 三国无双之类的

对赛车类的游戏无感,喜欢玩古墓丽影 孤单惊魂 刷子类游戏 还是 RPG 。 射击类的也比较喜欢,不过尝试用手柄完了几次之后放弃了,操作实在是适应不了。 我这种适合 XBOX 还是 PS 呢。 国行还是非国行。我对联机需求不高能玩单机就行。

haskell 菜鸟的问题

Posted: 11 Jul 2022 07:48 AM PDT

quicksort :: (Ord a) => [a] -> [a] quicksort [] = [] quicksort (x:xs) =         let smallerOrEqual = [a | a <- xs, a <= x]                 larger = [a | a <- xs, a > x]         in quicksort smallerOrEqual ++ [x] ++ quicksort larger 

初学菜鸟。请问这个示例程序,迭代是怎么停止的?

公司数据库数据被我更新成 null 了,救命!

Posted: 11 Jul 2022 07:47 AM PDT

数据库有些数据值为: "保密"

前面我在用 regex_replace 函数更新一些不规范数据

我顺手就用 update lawyers set working_years=regexp_replace(working_years, "保密", null); 把 "保密" 更新为 null

结果 working_years 字段全部被更新为 null !!!

有办法恢复吗,大佬救命!!!

容器化环境中有什么办法可以把日志文件同步到其他存储介质上?

Posted: 11 Jul 2022 07:16 AM PDT

Java 服务,部署在一个容器化环境中,容器镜像是部署平台构建好的,使用方只能丢一个 jar 包上去按照平台预设的命令启动(这个命令可以进行调整),有什么办法可以自动化把日志文件或者日志内容传输到其他的存储介质上吗?比如对象存储等等

请问大佬们一个数据迁移问题

Posted: 11 Jul 2022 07:02 AM PDT

db2 历史表数据导入到 es 里面去大家有什么推荐的方法没?目前考虑的有传统的 select db 然后 bulk insert 到 es.还有 datax 这种实现方式。flink cdc 貌似不支持 db2 。最求速度快!

Seenvoy: 一个 envoy 配置的可视化面板,欢迎试用

Posted: 11 Jul 2022 06:48 AM PDT

最近都在做 istio 相关的工作,istio 的数据面使用的是 envoy 。envoy 的配置是一个大 JSON ,每次看 envoy 的配置我都很头大,所以做了这个工具。

主要就是把配置通过前端的方式展现出来,然后增加一些交互。比如可以直接通过 Listener 跳去 Route 或者 Cluster 。

然后我还做了一个关系图,点击某一个 Listener 可以查看从这个入口进来的流量经过哪些配置最终走到了哪里。

地址: https://github.com/saltbo/seenvoy

求关注,求 star

ffmpeg.wasm 关于 rtsp 推流

Posted: 11 Jul 2022 06:18 AM PDT

需求:rtsp 协议 ip 摄像头转码 webrtc 协议在线播放。


疑问:本地的 ffmpeg 可以解析 rtsp 通过端口推流并转发出去,这个方案非常灵活,但局限于 cs 模式,在浏览器上偶然发现 ffmpeg 的 wasm 版本,了解后发现 github 上打包出来的解析库并不全,其次看 demo ,输入输出都是以文件的形式放在内存访问,并没有流的形式输入输出。所以想问下 wasm 解析 rtsp 的可行性。

一种优化的 JPEG 剪裁、缩小图片的解码方法

Posted: 11 Jul 2022 06:16 AM PDT

libjpeg-turbo 是一个优秀的,JPEG 解码加速库。但是在程序使用上其实可以更进一步优化。具体为:

# 图片剪裁

JPEG 图片是逐个 MCU(Minimum Coded Unit) 从左到右,从上到下地编码出来的,因此解码可以只解码感兴趣的部分而不用解码整个图片,JPEG 库提供了相对应的操作,`jpeg_skip_scanlines` 可以跳过行,`jpeg_crop_scanline` 可以只解码感兴趣的像素列所在的 MCU ,经过上层封装后能减少 MCU 解码的个数,对于只剪裁很小一部分像素的程序来说会有很大的性能提升。

# 图片缩小

同上,基于 JEPG 的 MCU 特性,每个 MCU 涉及重采样。简单且一般来说,抽样一般是 4:2:0 ,这意味着 16x16 像素大小的 MCU ,Y 通道会被编码成 16x16 ,而 Cb 和 Cr 通道会被编码成 8x8 大小(实际没有这么简单,但先可以这么理解)。在解码时,明显地 Cb 、Cr 通道需要升采样。这时候如果进行图片缩小操作就很浪费 CPU 和内存了,因为 Cb 和 Cr 通道进行了升采样,然后再被缩小,实际上可以不升采样。在 libjepg 里面也提供了这样的接口,只需要在解码时传入 `scale_num` 和 `scale_denom` 就可以控制解码时升降采样大小了。

下面是安利时间,这是我 Golang 上已实现的库,已经实现了主流格式的兼容了,附上 benchmark 。
https://github.com/picone/gojpegturbo

兄弟们听说过自愈嘛?

Posted: 11 Jul 2022 06:10 AM PDT

是这样的,最近有人告诉我说,为了避免消息丢失,状态不更新的问题,然后啥都搞个一直轮询的逻辑。比如 redis 的消息订阅,kafka 的消息等,大家都是这样设计的嘛?是不是太自愈。

在公司发表发明专利有什么好处?

Posted: 11 Jul 2022 06:02 AM PDT

本人在一家互联网大厂,部门都有发明专利的指标,我最近也发了几个专利。现在发表一个专利公司会补贴 5000 以上,除了这个对个人来说还有什么好处么?

问下前端大佬们 京东到家的分类侧边栏如何实现

Posted: 11 Jul 2022 05:28 AM PDT

问一下下面的侧边栏如何实现的

京东到家

有人知道电子合同需要接入什么认证才有法律效益嘛

Posted: 11 Jul 2022 05:01 AM PDT

像腾讯云的电子签,需要接入什么司法或者证书中心

感谢回复~

没想到 clickhouse 这么牛逼,比 es 强太多了,搞 quant 适合吗

Posted: 11 Jul 2022 04:35 AM PDT

最近跟朋友讨论一起搞搞 quant ,技术面是看了某 git ( https://github.com/thuquant/awesome-quant

数据库和硬件层面不知道用 clickhouse 作为数据库,p5510 ,pm9a3 作为存储,适不适合? 拿 clickhouse 的 500w 数据试验了一下,结合 metabase 牛逼极了,没想到超越了 es 这么多

当然目前正处于脑暴 bb 阶段,离最后去创业还差得远

现在互联网不容易,年纪大了随时毕业, 我是搞数据算法的,朋友是搞金融风控的, 君子不器,如果被行业淘汰,总得找找新出路

请问怎么能提高页面或者应用的布局设计及美化水平

Posted: 11 Jul 2022 03:45 AM PDT

后端开发一枚,最近总是想自己高点小程序或者插件或者网页等东西 后端实现都很容易,但是页面就画的贼丑,大家有啥学习的路线或者渠道么

冲动买了个二奶 NAS 万由 HN-200

Posted: 11 Jul 2022 03:15 AM PDT

为什么要买

  1. PDD 500-75 券 315 一块的价格一时冲动买了两块 4T 紫盘。
  2. 家里有一台蜗牛 B 壳 + G6500T + 16G + 8T * 4 的黑裙,在跑 PT ,目前是半洗白状态,考虑黑裙的不稳定性,所以想搞个白的。
  3. 闲的蛋疼,整个白的双盘位给自己家人备份照片、文件使用。

对比

威联通 212p3 极空间 z2s 万由 HN-200
ARM ARM X86
1G RAM 不可更换 2G RAM 不可更换 2G RAM 可更换
系统较完善 系统一般 系统一般
\ 可做机顶盒 \
不可刷机 不可刷机 可刷黑裙
pdd 615 1000+ 天猫 685

思索

经过一系列的思考,首先排除极空间 z2s ,家里电视、手机、平板都是 PLEX ,有 PLEX PASS 会员,不需要机顶盒,价格的确有点贵了。比较纠结的就是 212p3 和 hn-200 ,价格也差不多,后来考虑到 212p3 毕竟是古董级产品,无拓展性,1G RAM 估计不够用,如果万由系统用不习惯还可以再装一个黑裙,综合考虑,选择了万由。

微服务架构下 MDM(主数据管理)和业务表数据有什么最佳实践

Posted: 11 Jul 2022 03:07 AM PDT

比如存在 2 个微服务,MDM 和 Order 。

MDM 中维护了仓库,会员,运输商,等数据。

Order 中的业务表如何维护基础信息?

  1. 存 Id ,Code 和 Name, n 个关联对象,就会有 3n 个列
  2. 只存 Id, 查询时再 call MDM 去做关联
  3. CQRS, 感觉没必要上
  4. shared-database,或者走表订阅,和 MDM 共享 db 感觉有点怪

大公司一般如何处理这种问题?

关于自己对 Go web 的包结构理解

Posted: 11 Jul 2022 03:03 AM PDT

不同语言的项目结构都不太一样的,就像 MVC 并不是 Java 的专属,但是现在提到 MVC 大家都会提到 Java ,从而到 spring/spring Boot 。

这里推荐一个项目结构,它并不是 golang 官方的标准,再加上阿里的 Java 开发手册,如下所示:

  • cmd: 主要是各种功能的入口,简单来说像 main.go 就可以放到这里。
  • internal(内包是不希望其他人在其应用程序或库中导入代码)
    • db: 数据库相关的配置。
    • dao: 和数据库交互的都可以放在这里,我把 CRUD 之类的都放在这里了。
    • model: 和数据库表对应。
    • service: 具体逻辑实现。
    • dto: 放一些和前端交互的参数
    • controller: 做一些校验。
  • pkg: 外部应用程序可以使用的库代码,其他项目会导入这些库。
  • vendor: 这里就根据版本来了,一些老的 golang 项目还会有,存放一些第三方库,到后来 go mod 的出现这个就不需要有了。

像 internal 这种就可以根据自己的需求来,我是参考了阿里的 Java 开发手册还有之前在上海实习的时候的项目结构。

这是我写的博客中一部分,附上博客链接( https://shuimo03.github.io/)

请教一个 Linux 问题,光盘救援模式下,如何 fsck 原有系统的根目录

Posted: 11 Jul 2022 02:43 AM PDT

我进入光盘模式,其它分区,我都可以先 umount ,然后 fsck 检查修复。但是原系统的根目录无法卸载,提示 /mnt/sysimage:target is busy 。

因为在图书馆笔记本连不上网络,没有截图,只有手打文字。系统是虚拟机下的 centos7.9

nslookup 返回应答不对,但是能访问.

Posted: 11 Jul 2022 02:42 AM PDT

https://ibb.co/vjjxvNW 见图片上 这莫名的应答都带了这个地址 soho3q.com 好奇怪啊

vscode remote ssh 是如何实现 notty 登录的?

Posted: 11 Jul 2022 02:40 AM PDT

在使用 vscode-remote ssh 连接服务器时发现登录信息并不会记录在 /var/log/wtmp 、/var/log/utmp ,也就是 last 和 w 命令都看不到登录信息,使用 ps aux 查用户进程发现是以 notty 模式登录的。但实际上在 vscode 的终端中是有正常的 shell ,也可以正常执行命令的。

很好奇 vscode 是如何实现这种效果的?

Jprofiler 内存概览怎么看,内存有空闲大小,使用大小,提交大小三部分组成,生产上真正消耗的内存是以哪个为准。

Posted: 11 Jul 2022 02:23 AM PDT

如何改变一个方法里的常量

Posted: 11 Jul 2022 01:51 AM PDT

一个 config 里的常量,想在执行另一个方法时能改变这个常量,是否可以

有人用 gitlab 极狐吗,体验如何

Posted: 11 Jul 2022 01:43 AM PDT

github 国内速度太慢了

创业公司如何做好产品业务的安全合规?

Posted: 11 Jul 2022 01:29 AM PDT

最近安全故障比较多,主要是想请讲师来分享下如何避坑,如何在早期就做好安全合规,技术中立的干货分享,欢迎大家来交流~点击链接立即报名或者扫码报名即可!

报名链接:http://www.huodongxing.com/event/3656847952423?qd=v2ex

扫码报名:

CKA 考试

Posted: 11 Jul 2022 01:02 AM PDT

公司最近要求去考这个证书,大家有没有考过。证书实际价值有多少,考试难度大不大,需要多长时间准备,考试有哪些注意点,或者有考试资料的也可以分享一下

各位大佬请教一下, win10 重置删除的文件可以恢复吗

Posted: 11 Jul 2022 12:57 AM PDT

帮朋友装系统,就想着简单重装一下,他说他把重要的资料都放在一个盘里了,我就想着直接重置就好了 然后我还百度了一下,重置是否会删除系统盘以外的磁盘文件,结果说是不会 我为了弄干净点就都选的删除个人数据什么的,结果第二天起来晴天霹雳 大佬们有遇到这样的问题吗,我试着用数据恢复软件好像没用 马上想找淘宝看能不能花钱修复 大佬们支支招啊 QAQ

VS Code 插件可以过滤 Terminal 的输入和输出吗?输入经过插件再发到服务器,输出经过插件再显示。

Posted: 11 Jul 2022 12:39 AM PDT

有 V 友提出是否可以在 VS Code 中使用 trzsz ( trz / tsz ) 上传和下载文件。

如果是本地开发的,可以使用 trzsz-go,在 Terminal 中使用 trzsz ssh xxx 登录服务器,就可以用 trz 上传文件,用 tsz xxx 下载文件了。

如果是远程开发的,那 Terminal 已经登录到远程服务器,集成 trzsz.js 也可以做。

有大佬知道如何开发一个 VS Code 的插件,"过滤" Terminal 的输入和输出吗?

当键盘输入时,先经过插件,再由插件发送到服务器。当服务器输出时,先经过插件,再由插件输出到 xterm 进行显示。

大佬们, windows 下有什么劫持 DNS 的软件吗?

Posted: 11 Jul 2022 12:02 AM PDT

搞了 mosdns 解析, 要改网卡 dns 地址才能用, 但是笔记本总会搬到各地地方用, 有些时候不方便开 mosdns, 然后又要重新改网卡 DNS. 想找个劫持软件, 开启就劫持到 mosdns 解析, 关闭就恢复原貌, 请问有这样的软件或者命令行命令吗? 谢谢大佬们

账户验证详细过程

Posted: 10 Jul 2022 11:26 PM PDT

/t/865306 没人能看懂?确实我包含愤怒情绪可能没说清楚,现在我详细讲讲验证过程,还不明白你们也该自己反思了。

首先,我有三台设备,IOS (长期开机),android (已经关机半月)、Windows chrome (经常用,半年没注销过了),登录了谷歌账户。

昨天我想查看某一天的历史记录,chrome 那个你们懂的,一直无限下滑,当时没考虑用扩展,因为不知道哪些安全。 我登录谷歌账户的活动记录( https://myactivity.google.com/ ),提示要安全验证,首先输入密码,弹出需要 2FA ,"谷歌提示"那个它指定要安卓机点是,我不想开机,选择"谷歌身份验证器"也就是 TOTP 验证,验证通过,再次弹出"谷歌提示"要安卓机验证,此时没有其他验证手段了。

问题是:我的 IOS 也登陆了账户,却不能选择,而且 TOTP 不能作为验证,那还有什么用处?

为什么说 Typescript 是必学语言以及如何学会 TS 全栈开发

Posted: 10 Jul 2022 10:54 PM PDT

TS 的全面性

目前来说前端基本是 React,Vue,Angular 这三框架占据主流。而现在这三个框架对 TS 基本是默认支持与推荐的。接着我们再来说说移动方面。虽然 Flutter 目前的流行度非常高,但是需要学习 Dart 语言,这就多了一个学习成本,而 React Native+TS 的流行度依然跟 Flutter 不相上下,在性能方面对比 Flutter 有所差距,不过既然使用这种跨平台开发,那么基本都是社交,电商等或者展示类的 APP ,一般不会是系统型或者超大型 APP 的话,这个方面 RN 也足够应付,如果是游戏或者系统型 APP 的话,我相信你也不会去选择 Flutter 而会直接使用原生了。接着说说桌面应用方面,Electron 框架一直在低性能要求的跨平台桌面应用这块占据主流,如果你的桌面应用是以 web 页面为主或者对性能要求不是非常高的话,Electron 足够应付,如果对性能要求比较高的话,那么同样可以使用原生的 c#,swift 去开发。在小程序方面毋庸置疑,无论是原生的微信小程序,还是跨平台的 Taro,Uniapp,肯定使用 JS/TS 来编写的。在开发网站方面,拥有大量的 SSR 框架,最为占据主流的就是基于 React 的 Nextjs 和基于 Vue 的 Nuxtjs 。而在编写后端 API 这部分,Node.js 的性能并不比传统的 PHP,Python,Ruby 这类动态语言差,尤其在 IO 和高并发方面因为异步机制和自带 Cluster 集群功能,性能表现非常优秀,再加上 Nestjs 这种企业级的开发框架和越来越完善的生态,完全可以作为和其它动态后端语言平分秋色。当然与 Java,C#尤其是 Go 这种编译型的语言还是有一定差距,不过与 RN,Electron 一样在性能要求并不是非常高的情况下完全可以应付,而 99%的应用或网站是不需要这么高的性能的。在 CLI 构建方面,一个 Yargs 基本可以扛起所有,不用多做解释。并且目前 Node 已经在区块链,嵌入式甚至人工智能方面的生态也已经遍地开花,以前区块链基本是 go 的天下,而嵌入式则是 C,Rust 这类占据主流,人工智能一般都是用 Python 。而现在大量的区块链,嵌入式的招聘中开始出现 Node.js 的身影。就连人工智能也出现支持 Node 的框架。

综合来说,TS 目前在前端,网站,小程序中的位置基本无可替代,同时也可以构建完美的 CLI 应用。在移动,桌面,后端方面,性能不是要求很高的情况下完全可以胜任,并且在区块链,嵌入式,人工智能方面也开始茁壮成长。

TS 的必学性

现在来说,Typescript 已经成为一门必学的编程语言。

如果你是编程入门者,建议第一门语言就选择 TS ,后面打算往职业后端发展可以增加学习一下 Go 或者 Java Spring 全家桶,或者往职业移动开发者方向发展,可以学习一下 Swift 或者 Java ,如果长期从事 C/S 系统开发,则可以尝试一下 C#。

如果你已经对另一种技术栈掌握的比较深入,那么多学一门 TS 语言是非常有帮助的。比如说你是职业的 Java Spring 开发者,那么学习一下 React+TS ,瞬间可以成为一名全栈开发者,一个人可以把小程序,前端,APP 客户端,桌面应用等通通搞定

TS 目前可以做这些事

  • 使用 React 等框架可以编写 Spa 应用,比如中后台,数据可视化等
  • 使用 Nextjs 等框架可以编写 SSR 网站
  • 使用 Electron 可以开发 C/S 类的桌面应用
  • 使用 React Native 可以开发跨平台的移动 APP
  • 使用 Taro 等框架可以编写跨平台的小程序
  • 使用 Nestjs 可以编写企业级高性能的后端 API
  • 使用 Yargs 可以开发 CLI 工具
  • 并且目前已经开始在区块链,嵌入式,人工智能方面出现一些高可用的框架

如何学习 TS

我个人建议的入门方法是从 ES6 入手先学习 ES6+,这是 TS 的基石,必须理解了这些底层的东西,再学习 JS 的超集语言 TS 才会事半功倍。否则如果你会感觉有些东西会很难理解,比如 TS 的类在底层 JS 上本身是一个对象,函数也是一个对象,万物皆为对象。但是你像 Java 一样去使用就很不灵活,类其实可以手动使用对象描述构建一个。又比如把装饰器当成 Java 注解去理解,那么代码又变得很生硬了,其实装饰器本质上只是一个函数。还有像this,apply等,在 ts 中没有直接学习的方案,必须从 JS 开始

那么如果一步步把 TS 全部学会呢?

小编提供一下自己的学习路径供参考。

我的学习经历

首先小编简单介绍一下自己,我是从 08 年开始入手的 php ,前面学过 delphi ,从 08-17 年一直用的 php,从 18 年开始转的 TS ,在学习 TS 前,JS 方面只会一些简单的 Jquery 。我的学习路径是这样的

第一步学习 ES6 ,看的是《阮一峰的 ECMAScript6 入门》这本电子书。大概浏览一遍做到心中有数后,接着学习了这本《 Typescript 入门教程》的电子书。

学习 React

接下来就开始学习 React ,看的是官方文档,因为当时的官方文档默认是没有 Ts 示例的,所以边对着《深入理解 Typescript 》这本电子书查阅,边写 React 。期间学习了各种库,比如 Redux,Mobx,React-DND,Antd,React-Spring,Echarts 等等,也爬了无数的坑,谷歌了无数次,看了无数次的 StackoverFlow 的问答和各种库的 Issue ,这期间遇到的最老大难的问题就是配置 vscode+eslint+prettier+stylelint ,光这套学了很长一段时间。后来技术慢慢的开始熟练起来,以至于现在拿起 React 就变成一把利剑一样好用了,比如对于状态管理,可以直接自己写或者使用一些轻量级的Zustand等,又比如说 React 默认没有的keepalive功能,也是几行代码就能轻松实现。作为成果,我开发了一个比较完善的开源后台管理面板荼蘼(目前正在升级成 React 18)

学习 Electron

在掌握了 React 后,又开始爬坑 Electron ,当然也有许许多多的问题,小编花了无数的时间和精力去解决,一开始使用的是 webpack 作为打包工具去编写桌面应用,后面出来了一个极好的构建工具--vite 。尝试了使用 vite+ts+electron+react 的方式去构建,虽然当时的 vite 还不成熟,坑非常多,也把一个个问题通过自己思索或谷歌去解决了,随着 vite 的不断成熟,坑越来越少,这套技术栈也变得坚实,现在使用这套技术栈开发桌面应用已经非常熟练,足可以应付一般的业务需求。

学习 Taro 和 React Native

因为小编家中一些原因,一段时期一直在自由职业的缘故,所以接到了一些各种各样的单子。有一次客户要求做一个 SEO 友好的电商网站,本来小编打算直接用熟练的 jquery+laravel 搞定,但是后来在各种反复考量下,小编决定采用一些新的技术栈。因为那时候,Remix 还没有出来,甚至同作者的 React Router v6 也没发布,于是小编当时唯一的选择就是 Nextjs(Gatsby 太过复杂,因为我不会 vue 所以直接排除 Nuxtjs).然后开始尝试使用 Nextjs 去构建这个网站,当然后端因为还没学习 Node ,所以依旧使用擅长的 PHP 去编写,没想到竟然全程基本无坑,一气呵成,可见 React 的基础技能对于其生态是有多重要了。。。

后面随着一个新的客户需要开发一个小程序加 APP ,这并不在小编的技术栈范围内,但是给出的报酬和支付订金的爽快程度前所未见,所以没办法,为了生活也只能硬着头皮上。

一开始去学微信的官方文档,但是后来客户说最好能支持某宝,小编没有精力去学习两套 SDK 。这时候我就开始各种搜索跨平台小程序的开发框架,找到了两个比较成熟的,一个是 Uniapp ,但是没有 Vue 开发经验再加上不喜欢他官网各种营销式的文档样式和自带的 IDE ,那么只能选择另一个京东出的 Taro 。没想到使用 Taro 构建小程序非常顺利,除了官方的 UI 丑一点外(现在 Taro 已经有很多好看的生态库了),基本无坑。这时,看到 Taro 也支持 RN ,于是乎抱着试一试的方式,边学习 React Native ,边使用 Taro 去构建 APP ,那么结果大家都知道了,坑是有多多。。。后面只能裸用 React Native 去写 APP ,坑的确少了很多,APP 也开发成功了,但是唯一的缺憾是 UI 方面无法和小程序统一了。毕竟瑕不掩瑜,希望 Taro 对 RN 的支持会越来越好吧,后面有 APP 开发还是会去尝试 Taro ,而不是把它仅用于小程序开发。

学习 Nestjs

这几年,接到的后端业务越来越多,但是因为 PHP 的口碑扑街(其实个人认为 PHP 并没这么差),很多客户也是人云亦云直接来一句 PHP 的不要。。。那么没办法,要么学习 Java 这个巨无霸体系,要么入手生态很差的 Golang 。一次在逛某乎的时候,看到有一名作者在布道一个 node 框架--Nestjs 。凭我对 10 来年前,node 刚出现时尝试过的 express 框架的记忆,想着 node 不就是 slim 这种微框架吗?这些项目得多累。但是鉴于当时也没有更好的选择,并且 TS 语言也熟悉,然后抱着试一试的心态去尝试 Nestjs ,没想到没试不知道,试了就知道捡到宝了。这个框架生态非常健全,ORM ,消息列队,websockets ,微服务等通通完美支持,然后测试了一下性能,对比 swoole+symfony/laravel 也不遑多让。立马拿来构建第一个项目。因为当时的 nestjs 还是 5.0 版本,问题颇多,大多集中在 Typeorm 方面,再加上 Nestjs 本身一大堆概念,比如 DTO ,验证器,拦截器,过滤器等等,在开发第一个 CRM 项目的时候还是踩了非常多的坑,导致项目延期无数次,过了半年终于把项目开发好,当然报酬也少了许多。。。但是个人认为这一切是值得的,后面就可以使用一种语言打遍天下了。

等到第二个项目来临时,Nestjs 已经使用地非常成熟了,这时候遇到一个老客户,他需要一个带后台的小程序,这是我发现了一个比较好的库--lerna ,可以用一种叫做 monorepo 的方式,把所有前后端的 TS 包放在一个仓库里,接口能相互调用,还能一键发布一些主应用之外的包到 npm 的仓库里,甚至能按照依赖顺序对 TS 进行编译,非常实用,所以直接使用 lerna 构建起了整个应用。

学习 CLI 构建

后面发现了更加轻量的 pnpm ,然后 pnpm 不支持 lerna ,但是它本身没有发布功能,并且无法按依赖顺序执行编译命令,所以在空余时间我慢慢的尝试自己编写一个命令行工具去使 pnpm 可以自己按顺序执行编译和一键发布。于是发现了一个好用的 node 的命令行工具--yargs 。当然围绕 yargs 还发现了 execa,ora 等好用 CLI 生态库。并且同时深入整个 Node 重新学习了一遍,比如在使用 CLI 构建长时间命令式,使用 fork 开子进程等。同时发觉在开发时 nestjs 的重启速度实在太慢,于是在我的工具库里添加了一个 nodemon+swc 热更新 nestjs 的命令。

后面发现客户部署上去的 Nestjs 应用总是在进程出现错误后就挂掉,于是乎学习了一下 cluster ,使用 PM2+Cluster 的方式去部署应用,当然目前基本使用 docker 来部署了。

推荐给大家

小编以上的学习过程是非常痛苦且漫长的,花了大概 2 年多,因为都是普通人,并非天赋异禀。但是这么长的学习和爬坑过程,甚至还是全职的情况下,是并不是谁都有时间和精力去做的。尤其有些库遇到的各种问题去查官网文档,不仅只有英文文档,甚至大量还是语焉不详的情况下,只能不停地去查询 stackoverflow 以及那些库的 issue,去 github 的 discussions 或者 discord 用英语提交问题。这会浪费大量的学习和工作时间。然后去各种 QQ 群提问基本就是答非所问,各种灌水,去一些问答社区提问则大概率得不到想要的答案。

所以为了帮助大家能更快的解决开发与工作中遇到的问题。小编开始做一套TS 全系列的视频教程并包含各个技术栈,qq 群: 455820533 。目前以 React18 和 Nestjs 开始制作,慢慢地涵盖所有 TS 的技术栈,在学习和开发过程中遇到问题也可以让小编帮助解决。但是视频教程只针对已经有一定基础的同学来进阶学习。

如果没有任何基础,可以找小编进行基础性学习,帮助你尽快地掌握这个 TS 开发体系。

掌握 TS 的优势

学会 TS 全栈开发不仅有助于提升求职竞争力,同时也可以成为一名完全自由的开发者,比起需要长期 996 的一端开发者来说优势不可为不大。尤其在某些编程语言和框架非常内卷的情况下,还是非常有帮助的。同时希望我个人能帮助到一些同学快速掌握这套技术栈。

新成为 helmfile 项目核心维护者,声明式管理 helm chart,求志同道合的小伙伴一起参与

Posted: 10 Jul 2022 08:34 PM PDT

helmfile

github: https://github.com/helmfile/helmfile

声明式地部署您的 Kubernetes 清单,Kustomize 配置和图表

目前该项目的使用者很多,原始 star 为 3k, 当前由 helmfile 社区维护,使用者包括 gitlab 公司等。

自我介绍

github 地址: github.com/yxxhero

  • k8s 成员
  • helm 分支维护者
  • harbor-operter 维护者
  • dragonfly 维护者
  • helmfile 核心维护者
  • 等其他 cncf 项目贡献者

Nestjs 最佳实践教程:5 自动验证,序列化与异常处理

Posted: 10 Jul 2022 03:18 PM PDT

注意: 此处文档只起配合作用,为了您的身心愉悦,请看 B 站视频教程,不要直接略过视频直接看这个文档,这样你将什么都看不到😄

另,本人在找工作中,希望能有远程工作匹配(无法去外地),有需要的老板可以看一下我的个人介绍: https://pincman.com/about

学习目标

  • 全局自动数据验证管道
  • 全局数据序列化拦截器
  • 全局异常处理过滤器

文件结构

本节内容主要聚焦于CoreModule

src/core ├── constants.ts ├── core.module.ts ├── decorators │   ├── dto-validation.decorator.ts │   └── index.ts ├── helpers.ts ├── index.ts ├── providers │   ├── app.filter.ts │   ├── app.interceptor.ts │   ├── app.pipe.ts │   └── index.ts └── types.ts 

应用编码

本节中用到一个新的Typescript知识点-自定义装饰器和matedata,详细使用请查看我写的一篇相关文章

装饰器

添加一个用于为Dto构造metadata数据的装饰器

// src/core/decorators/dto-validation.decorator.ts export const DtoValidation = (     options?: ValidatorOptions & {         transformOptions?: ClassTransformOptions;     } & { type?: Paramtype }, ) => SetMetadata(DTO_VALIDATION_OPTIONS, options ?? {}); 

验证管道

自定义一个全局的验证管道(继承自Nestjs自带的ValidationPipe管道)

代码: src/core/providers/app.pipe.ts

大致验证流程如下

  1. 获取要验证的 dto 类
  2. 获取Dto自定义的matadata数据(通过上面的装饰器定义)
  3. 合并默认验证选项(通过在CoreModule注册管道时定义)与matadata
  4. 根据 DTO 类上设置的 type 来设置当前的 DTO 请求类型('body' | 'query' | 'param' | 'custom')
  5. 如果被验证的 DTO 设置的请求类型与被验证的数据的请求类型不是同一种类型则跳过此管道
  6. 合并当前 transform 选项和自定义选项(验证后的数据使用 class-transfomer`序列化)
  7. 如果 dto 类的中存在 transform 静态方法,则返回调用进一步 transform 之后的结果
  8. 重置验证选项和 transform 选项为默认

序列化拦截器

默认的序列化拦截器是无法对分页数据进行处理的,所以自定义的全局序列化拦截器类重写serialize方法,以便对分页数据进行拦截并序列化

// src/core/providers/app.interceptor.ts serialize(         response: PlainLiteralObject | Array<PlainLiteralObject>,         options: ClassTransformOptions,     ): PlainLiteralObject | PlainLiteralObject[] {         const isArray = Array.isArray(response);         if (!isObject(response) && !isArray) return response;         // 如果是响应数据是数组,则遍历对每一项进行序列化         if (isArray) {             return (response as PlainLiteralObject[]).map((item) =>                 this.transformToPlain(item, options),             );         }         // 如果是分页数据,则对 items 中的每一项进行序列化         if (             'meta' in response &&             'items' in response &&             Array.isArray(response.items)         ) {             return {                 ...response,                 items: (response.items as PlainLiteralObject[]).map((item) =>                     this.transformToPlain(item, options),                 ),             };         }         // 如果响应是个对象则直接序列化         return this.transformToPlain(response, options);     } 

异常处理过滤器

Typeorm 在找不到模型数据时会抛出EntityNotFound的异常,而此异常不会被捕获进行处理,以至于直接抛出500错误,一般在数据找不到时我们需要抛出的是404异常,所以需要定义一个全局异常处理的过滤器来进行捕获并处理.

全局的异常处理过滤器继承自 Nestjs 自带的BaseExceptionFilter,在自定义的类中定义一个对象属性,并复写catch方法以根据此属性中不同的异常进行判断处理

// src/core/providers/app.filter.ts protected resExceptions: Array<         { class: Type<Error>; status?: number } | Type<Error>     > = [{ class: EntityNotFoundError, status: HttpStatus.NOT_FOUND }]; catch(exception: T, host: ArgumentsHost) {...}  

注册全局

CoreModule中分别为全局的验证管道,序列化拦截器和异常处理过滤器进行注册

在注册全局管道验证时传入默认参数

// src/core/core.module.ts providers: [         {             provide: APP_PIPE,             useFactory: () =>                 new AppPipe({                     transform: true,                     forbidUnknownValues: true,                     validationError: { target: false },                 }),         },         {             provide: APP_FILTER,             useClass: AppFilter,         },         {             provide: APP_INTERCEPTOR,             useClass: AppIntercepter,         },     ], }) 

逻辑代码

  • 对于验证器需要修改DtoController
  • 对于拦截器需要修改EntityController
  • 对于过滤器需要修改Service

自动序列化

PostEntity为例,比如在显示文章列表数据的时候为了减少数据量不需要显示body内容,而单独访问一篇文章的时候则需要,这时候可以添加添加一个序列化组post-detail,而为了确定每个模型的字段在读取数据时只显示我们需要的,所以在类前添加一个@Exclude装饰器

对于对象类型需要通过@Type装饰器的字段转义

示例

// src/modules/content/entities/post.entity.ts     ...     @Expose()     @Type(() => Date)     @CreateDateColumn({         comment: '创建时间',     })     createdAt!: Date;     @Expose()     @Type(() => CategoryEntity)     @ManyToMany((type) => CategoryEntity, (category) => category.posts, {         cascade: true,     })     @JoinTable()     categories!: CategoryEntity[];     @Expose({ groups: ['post-detail'] })     @Column({ comment: '文章内容', type: 'longtext' })     body!: string; 

然后可以在在控制器中针对有特殊配置的序列化添加@SerializeOptions装饰器,如序列化组

示例

// src/modules/content/controllers/post.controller.ts     ...     @Get(':post')     @SerializeOptions({ groups: ['post-detail'] })     async show(         @Param('post', new ParseUUIDEntityPipe(PostEntity))         post: string,     ) {         return this.postService.detail(post);     }  

自动验证

为了代码简洁,把所有针对同一模型的DTO类全部放入一个文件,于是有了以下 2 个dto文件

  • src/modules/content/dtos/category.dto.ts
  • src/modules/content/dtos/post.dto.ts

dto文件中需要传入自定义验证参数的类添加@DtoValidation装饰器,比如@DtoValidation({ groups: ['create'] })

注意的是默认的paramTypebody,所以对于query,需要额外加上type: 'query'

示例

// src/modules/content/dtos/category.dto.ts @Injectable() @DtoValidation({ type: 'query' }) export class QueryCategoryDto implements PaginateDto { ... } 

现在可以在控制器中删除所有的new ValidatePipe(...)代码了,因为全局验证管道会自行处理

自动处理异常

现在把服务中的findOne等查询全部改成findOneOrFail等,把抛出的NotFoundError这些异常去除就可以在 typeorm 抛出默认的EntityNotFound异常时就会响应404

示例

// src/modules/content/services/post.service.ts     async findOne(id: string) {         const query = await this.getItemQuery();         const item = await query.where('post.id = :id', { id }).getOne();         if (!item)             throw new EntityNotFoundError(PostEntity, `Post ${id} not exists!`);         return item;     } 

No comments:

Post a Comment