Thursday, December 2, 2021

V2EX - 技术

V2EX - 技术


想问下 Windows 平台有什么好用的 xliff 编辑器么?

Posted: 02 Dec 2021 07:31 AM PST

京东没有 robots.txt 是怎样防止爬虫抓取的

Posted: 02 Dec 2021 07:27 AM PST

试了下京东 www.jd.com/robots.txt 跳首页了。这中间是有什么故事让其它搜索引擎没有抓取他家数据。

有关自建图床类服务 ( 10TB 左右 )有什么坑或者现成的选择吗? 主要避免重复上传文件名哈希

Posted: 02 Dec 2021 07:26 AM PST

总体大约 3000 万文件吧, 包括图片视频等不同文件, S3 或其他对象存储

有没有既定方案或者开源项目的, 不知道该搜什么关键词, 找不到就只好自己搭了

  1. 记录原始图片地址转存储路径打算 mongodb 上查, 平时并发不会很高
  2. 存储路径是否存在打算使用带计数器的布隆过滤器(为了可以删除), 有没有坑呢
  3. 用文件内容整个哈希做文件名哈希表, xxhash 怎么样, xxh3_128 作为长度 32 的文件名还能接受, 碰撞应该也安全, 性能比 md5 什么的靠谱

感谢帮助

Paw Cloud 免费送兑换, 新注册或者老用户都能领

Posted: 02 Dec 2021 07:23 AM PST

原推正文,到 12 月 5 号截止

otHCdI.png

领取地址: https://paw.cloud/redeem/vWd706vfEOwQL8OLJ2rPlnAxhNNdWXWc

想要一个可视化的像 omv 或者群晖那种的 web 管理面板

Posted: 02 Dec 2021 07:16 AM PST

如题。

主要是 smb 权限配置太麻烦了,宝塔面板不行

不知道大家有没有什么推荐的

小组长让我一小时提交一次代码

Posted: 02 Dec 2021 07:09 AM PST

小组长过一会儿(大约一小时)就对我说,你把你代码提交一下,我蚌埠住了

有没有办法防止通过发送邮件验证码的接口乱发邮件

Posted: 02 Dec 2021 07:07 AM PST

想来想去只想到通过限制 ip 访问接口次数,但是如果只限制 ip 的话开代理照样可以绕过,各位有什么好点的解决方案

关于 1password 保险库备份问题有坑莫踩

Posted: 02 Dec 2021 06:59 AM PST

开车的人很多,为了应对账号未来可能出现的问题,大家都开始另外备份保险库,这里面有个坑,有人备份保险库的时候,考虑到安全问题,选择了备份 1password 自加密的保险库,这其实等于没备份,因为 1password 开车可能出现的最大问题是可能账号被删掉,如果账号删掉了,那么你备份的保险库就没法用了,不要想你再注册个账号,然后保险库就能导入进去,密钥变了,是不可能让你导入的。
所以还是建议导出未加密的保险库,然后自己加密,这样才是最保险的。

一个完整的项目需要有哪些文件

Posted: 02 Dec 2021 06:51 AM PST

楼主每次完成期末项目的时候,都是只把项目源代码,一份 report ,一份 readme 文档。 不知道还是学生的 v 友提交代码的时候会交哪些文件? 还有不知道工作的时候,需要和上级交哪些文件吗

h5 canvas 插件开发 web 渲染框架求推荐

Posted: 02 Dec 2021 06:05 AM PST

尝试过不少 h5 canvas 的游戏引擎,画面需求是满足了,但调研后发现同页面都只支持单个 canvas ,如果是插件化 那么同页面势必要存在很多个 canvas 组件。
有一个方案是通过离屏 canvas 引擎统一渲染完 然后再把数据源复制到多个组件 canvas 内,这样的结果就是效率极其低下,不太可行。
现在寻找一个轻量级 2d 渲染框架,实现一些与业务能互动的动画效果展示,并且能够插件化。比较像 Chart.js 那样的图表工具包。

gtx1650 能硬解 8K 吗?

Posted: 02 Dec 2021 05:56 AM PST

试了一下,硬解 4K 完全没有问题,但是同样的设置,8K 貌似不行。

是不是这个系列的无法硬解 8K ?

那些 Python 语言设计上的重大失误

Posted: 02 Dec 2021 05:54 AM PST

python 系统性的限制了代码的灵活执行,不管是 lambda 还是 eval 都只能运行表达式,应用场景十分有限,极大的限制了 python 语言的表现力。

本来能够很容易就写出来的代码,需要绕弯子。

这种限制在当前没有任何站得住脚的合理解释,非要说就只能扯 pythnoic 意识形态大旗。

python 还有个更糟糕的设计是用缩进当做语法,也许在 30 年前能少敲几下键盘,或者让缩进看起来更一致和美观,但是现在的各种 IDE 全都能自动解决这些问题,根本就不需要人操心。

不过这些设计上的问题总会有些争论的,毕竟大家对自己常用的工具都挺有感情的。

设计是好的还是坏的,到现在是否还合时宜,有个更客观的评价标准,就是那个设计是否影响到了最近才出现的主流语言,如果那个设计是后继无人的,那么必定是坏的。

就拿缩进敏感来说吧,算是典型的后继无人,Swift ? Go ? Rust ? Kotlin ?这种糟糕的设计已经被后人全面抛弃。

python 还有哪些糟糕的设计?

以设计的传承性来看,你可能会发现更多败笔,它们已经被历史无情地扔到垃圾堆中了。

毕竟很多东西都有其时代局限性。

机器学习哪款 gpu 可以胜任

Posted: 02 Dec 2021 05:48 AM PST

怎么获取到 telegram、discord、twitter 的自己的账号的关注人数?

Posted: 02 Dec 2021 04:49 AM PST

倒是找到了三个渠道的 api , 但是看着让我难受过去了,完全看不懂

Telegram: https://core.telegram.org/method/channels.getFullChannel Twitter: https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/get-lists-members Discord: https://discord.com/developers/docs/resources/channel#get-channel

有没有大佬之前做过,赐教一下

《Effective Java 》读后感

Posted: 02 Dec 2021 04:41 AM PST

有读过这本书的小伙伴 可以分享读后感,也可以分享下读之前需要注意什么?哪些是重点?

有没有熟悉 node 的朋友, Linux 上编译 node16 快 12 小时了,咋这么慢。。。

Posted: 02 Dec 2021 04:35 AM PST

如题,从开始的时候感觉正常到现在怀疑自己是否哪里搞错了,一直编译,cpu 一直占用 100%(单核虚拟机)

具体安装方法就是从官网上下个源码,然后解压,configure ,make && make install.

编译过程中除了 CPU 占用高,内存占用也挺高的,不过 1G+swap 应该还扛得住,问题就是编译咋这么慢。而且编译之前也没要求装啥依赖之类的,像 python 编译起码还要装个 build-essential ,我是不是哪里做错了?

今日学到一个东西,基于 https 的 dns 解析

Posted: 02 Dec 2021 03:49 AM PST

今天抓手机包,怎么都抓不到手机的一些 dns 包,排除了缓存问题,访问的都是新网址。。。 后来筛选发现有一些对 dns 服务器的 tcp 包,还是加密的 然后请教了大佬,说有基于 https 的 dns 解析。 学到老,学到老。。。。

请问你们有用 liquibase 框架工具吗?请教一个问题

Posted: 02 Dec 2021 03:32 AM PST

我们在现有的项目上引进了 liquibase,但是数据库中目前已经有表,线上也在运行,如何将之前 SQL 脚本引到 liquibase 中,这样项目在新环境部署的时候 让他先执行原有的 sql ,然后再执行后期在 liquibase 上维护的脚本,而不会影响线上正在运行的项目

多数据源最佳实践是什么?

Posted: 02 Dec 2021 03:20 AM PST

有了 k8s,还有必要学习 docker compose 吗

Posted: 02 Dec 2021 02:32 AM PST

大佬们 问个问题

Posted: 02 Dec 2021 02:27 AM PST

1638440779(1).png

像这种如何通过在控制台输入 js 来切换呀 有 iframe 引入的东西 top 里面没有 手动切换到那儿可以 但是因为我要写脚本 想通过 js 切换

求一个 go 中的 aes 加密方法

Posted: 02 Dec 2021 01:56 AM PST

要求如下:

str = `406BF0AD11310101220213481000320000` key := `ER2Fb6ts3ECX` 通过 AES 加密(加解密算法 AES/工作模式 ECB /填充方式 NoPadding)并根据 base64 转码后字符串位: rebZn7aj61hD3lfsUrhwFgVzPg4yYo9aseP/a4sNTRIh/Vtb0mziFfoHdOZBZ5uj 

试过了论坛中一位大老的方法,出来的结果貌似不一样呀~

package xaes  import ( 	"bytes" 	"crypto/aes" 	"crypto/cipher" 	"crypto/rand" 	"crypto/sha256" 	"encoding/base64" 	"errors" )  type Aes struct { 	key []byte }  func NewAes(key string) (*Aes) { 	if key == "" { 		panic("aes key empty") 	} 	sum := sha256.Sum256([]byte(key)) 	return &Aes{ 		key:sum[:], 	} }  func (a *Aes) Encrypt(encodeBytes []byte) (val string, err error) { 	block, err := aes.NewCipher(a.key) 	if err != nil { 		return 	} 	blockSize := block.BlockSize() 	encodeBytes = zeroPadding(encodeBytes, blockSize)  	iv := make([]byte, blockSize) 	_,err = rand.Read(iv) 	if err != nil { 		return 	}  	blockMode := cipher.NewCBCEncrypter(block, iv) 	crypted := make([]byte, len(encodeBytes)) 	blockMode.CryptBlocks(crypted, encodeBytes)  	iv = append(iv,crypted...) 	val = base64.StdEncoding.EncodeToString(iv) 	return }   func (a *Aes) pkCS5Padding(ciphertext []byte, blockSize int) []byte { 	padding := blockSize - len(ciphertext)%blockSize 	padtext := bytes.Repeat([]byte{byte(padding)}, padding) 	return append(ciphertext, padtext...) }  func (a *Aes) Decrypt(decodeBytes []byte) (origData []byte,err error) { 	//decodeBytes, err := base64.StdEncoding.DecodeString(decodeStr) 	//if err != nil { 	//	return 	//} 	block, err := aes.NewCipher(a.key) 	if err != nil { 		return nil, err 	} 	if len(decodeBytes) < block.BlockSize() { 		err = errors.New("decodeBytes 长度不足") 		return 	} 	iv := decodeBytes[:block.BlockSize()] 	decodeBytes = decodeBytes[block.BlockSize():]  	blockMode := cipher.NewCBCDecrypter(block, iv) 	origData = make([]byte, len(decodeBytes)) 	blockMode.CryptBlocks(origData, decodeBytes) 	origData = zeroUnPadding(origData) 	return }  func (a *Aes) pkCS5UnPadding(origData []byte) []byte { 	length := len(origData) 	unpadding := int(origData[length-1]) 	return origData[:(length - unpadding)] }  func zeroPadding(ciphertext []byte, blockSize int) []byte { 	padding := blockSize - len(ciphertext)%blockSize 	padText := bytes.Repeat([]byte{0}, padding) 	return append(ciphertext, padText...) }  func zeroUnPadding(origData []byte) []byte { 	return bytes.TrimFunc(origData, 		func(r rune) bool { 			return r == rune(0) 		}) } 

调用方式

package main  import ( 	"awesomeProject/xaes" 	"fmt" )  func main()  { 	str := []byte("406BF0AD11310101220213481000320000") 	xa := xaes.NewAes("ER2Fb6ts3ECX") 	b,e:=xa.Encrypt(str) 	if e != nil{ 		fmt.Println(e.Error()) 		return 	} 	fmt.Println(b) } 

起点国际站移动端 css 响应式代码,能说明下计算原理吗

Posted: 02 Dec 2021 01:38 AM PST

html {   background-color: #fff;   font-size: 16px;   font-size: calc(100% + 2 * (100vw - 360px) / 39);   font-size: calc(16px + 2 * (100vw - 360px) / 39);   line-height: 1.5 }  @media screen and (min-width: 414px) {     html {         font-size:calc(112.5% + 4 * (100vw - 414px) / 586);         font-size: calc(18px + 4 * (100vw - 414px) / 586)     } }  @media screen and (min-width: 750px) {     html {         font-size:calc(137.5% + 6 * (100vw - 1000px) / 1000);         font-size: calc(22px + 6 * (100vw - 1000px) / 1000)     } } 

MongoDB 时间戳和当前时间比较

Posted: 02 Dec 2021 01:08 AM PST

需求:用户在前端使用 DatePicker 选定一个时间,返回给后端,并存储到 MongoDB 里(假设这个字段是 startTime ),在之后的请求操作中需要判断 startTime 与 Date.now() 的差值是否小于 30 * 60 * 1000 (也就是 30 min )

问题:MongoDB 存储的时间是不带时区的,Date.now() 可以正确返回当前时间(比如北京时间),有时区,这个时候就很难比较了

求求大佬们了

有人了解 QuickPy 嘛? 在知乎看到介绍, 想尝试一下, 但是只找到了 Chrome 插件?

Posted: 02 Dec 2021 01:04 AM PST

在知乎看到一篇关于 QuickPy 的介绍.

https://zhuanlan.zhihu.com/p/436049215

想尝试一下, 但是只找到一个 Google Chrome 的插件... 有人了解嘛?

产品对比: TeamCode DCS 与 Docker Dev Environment

Posted: 02 Dec 2021 12:53 AM PST

随着云计算技术的出现和普及,线上算力越来越强,极大降低了企业的生产成本。同时人们对越来越多的软件公司开始进行数字化创新,探求更加高效的远程开发和工作模式。微软在 2019 年发布了 VS Code Remote ,支持远程开发功能, 开启了远程开发新时代。根据 2019 年度的一份 StackOverflow 的调研,VS Code 已经在当时成为了开发者首选的开发环境。之后,Coder 开源了 code-server ,让 VS Code 可以在任何平台上运行并通过浏览器访问,解决了跨设备的环境一致性问题。满足了人们对自由、便捷、高效的工作和协作模式的需求,打造了远程开发的基础架构,不少公司也纷纷推出远程开发工具,例如 TeamCode( https://www.teamcode.com) 的 DCS( https://www.teamcode.com/products/dcs) 与 Docker( https://www.docker.com)推出的 Development Environments( https://docs.docker.com/desktop/dev-environments/)。

用户价值分析 项目开发者-配置环境困难症 开发者开发一个项目的时候,第一步要做的就是配置本地开发环境。通常我们会边阅读项目的文档根据教程配置开发环境,然而恰恰是在这看似最基础的事情上,会出现各类问题困扰开发者:

  1. 安装环境报错导致无法继续;
  2. 要求的环境依赖与本地环境冲突;
  3. 好不容易把项目成功了,但项目启动不了;
  4. 系统不同导致无法安装成功,比如有一部分开发者使用的是 Windows 操作系统。

以上这些问题都让开发者抓狂。接下来就让我们看看两款工具是如何解决环境部署及安装问题的呢?

TeamCode 为了解决以上的开发痛点,TeamCode 推出了 DCS ,它是一款快速自动构建可扩缩的云端开发环境的产品。 它的能力

  1. 通过 Git 仓库地址快速搭建开发环境;
  2. 标准化的开发环境;
  3. 支持主流 IDE 和浏览器,支持客户端 IDE 接入,可与 TeamCode Cloud-IDE 无缝连接;
  4. 支持多种语言,已支持 Java 、Python 、Go 、Typescript 等。 它的用途
  5. 开发环境云端自动化管理,降低人力及研发成本;
  6. 代码及研发数据云端存储,加强研发数据安全性;
  7. 研发过程云端管理,数据透明化,提升管理效率。 产品结构分析 产品的主要目标人群为开发者,因此需要重点满足开发者的需求,解决开发流程中的繁琐问题。

场景一:如何满足开发者安装环境的需求 DCS 支持从 Git 仓库创建一个开发环境,自动检测并创建环境,可以选择 VS Code 与 Cloud IDE 连接环境与开发

Dev Environment 支持以下方式创建一个开发环境:

  1. Git 仓库地址
  2. 本地文件夹
  3. Docker 镜像地址 环境会被自动创建,打开 VS Code 连接环境,开始开发

场景二:如何满足开发者与业务团队的预览发布需求 DCS 可以通过 URL 直接预览项目改动,无需通过 CICD 流程。

Dev Environment 需要通过 Git 推送代码并走 CICD 部署至预览服务器。

对 TeamCode DCS 的未来展望与优化建议 优势: 我认为 DCS 这款产品除了解决安装环境这一痛点之外,还能够成为一个在线的预览测试服务,这能够提升开发团队与业务团队合作时候的效率,让业务团队可以及时预览改动。Docker 的 Dev Environment 则还是走传统的 CICD 路径,在此场景下较为低效。 建议: 建议能够在本地创建一个开发环境,因为如果强制用户使用云开发环境,就代表用户所有的开发基础架构都需要上云,相对于本地开发来说成本较高,这一点 Docker 的 Dev Environment 有优势。

问个按揭相关问题,各位老哥按揭时选本金还是本息?

Posted: 02 Dec 2021 12:53 AM PST

准备买房了,在网上看了一些相关知识。按 30 年贷款的话感觉本金跟本息各有各的好处。

等额本金

  1. 提前还款有优势;
  2. 总体利息比等额本息少;

等额本息

  1. 压力没有等额本金前期那么大;
  2. 平均到每个月的话,对于通货膨胀来说是友好的;

所以问问各位老哥,你们是选的等额本息还是等额本金呢?

今天突然很多国外客户苹果手机与服务器通信提示"发生了 SSL 错误,无法建立与该服务器的安全连接。"

Posted: 02 Dec 2021 12:25 AM PST

大部分都是移动网络,有一个运营商是 SoftBank 的。部分人有线网络也无法访问。

请问大家遇到过类似的问题吗,如何排查了?感觉像是网络问题,其他的时间设置,还有服务器配置应该没啥问题

无时无刻不在用“闭包”

Posted: 02 Dec 2021 12:22 AM PST

global 是开包,大家都可以访问; local 是闭包,只有函数内部可以访问。

只要你使用函数,你就在用闭包。

在正常的情况下,闭包会随着任务的结束而被销毁,它没有什么存在感。

但是!如果将闭包的引用抛到外面,那么就可以在任何地方持续访问它。

这是个很神奇的情景,如果在现实生活中你有个闭包,就意味着有个这个世界上只有你才能进去的私人空间,你完全可以报复自己的仇人,然后溜进自己的闭包当中,别人只能干瞪眼,他们挖地三尺也找不到你。

普通的闭包太过寻常,太过短暂,以至于大家都忘记它的名字,现在"闭包"特指那些没被销毁的。

群晖 Driver 下的文件夹,能否同步到 dropbox

Posted: 01 Dec 2021 11:24 PM PST

群晖 Driver 下的文件,能否同步到 dropbox

试验了下,只可以同步 Driver 下的文件夹,同步到 dropbox 。但是 Driver 下的文件是同步不到 dropbox 的。

有解吗?

经常蓝屏,看 dump 提示报错还不一样,请大佬们指点下

Posted: 01 Dec 2021 10:28 PM PST

今天是 ATTEMPTED_WRITE_TO_READONLY_MEMORY (be)
上次是 MEMORY_MANAGEMENT (1a)

这是今天的:

image.png image.png

这是前几天的:

image.png image.png

这种情形该怎么处理?

Posted: 01 Dec 2021 10:19 PM PST

child.vue

<template>   <div class="child">     <h4>这里是子组件</h4>     <el-input v-model="data"></el-input>     <el-button type="primary" @click="onClick">add</el-button>     <!-- <grand-child></grand-child> -->   </div> </template> <script>  export default {   name: 'Child',   props: {   // 1 、用 v-model 绑定     value: {       type: [String, Number]     }   },   data() {     return {       data: ''     };   },   watch: {   // 2 、监听 value 的变化,并做一些处理     value: {       handler(val) {         console.log(val);         this.data = val + 'parent';       },       immediate: true     }   },   methods: {     onClick() {       this.data += 'child';       // 3 、更新值       this.$emit('input', this.data);     }   } }; </script>  

parent.vue

<template>   <div class="father">     <h3>这里是父组件</h3>     <child v-model="data"> </child>   </div> </template> <script> import Child from '@/views/Child';  export default {   name: 'Parent',   components: {     Child   },   data() {     return {       data: '888'     };   } }; </script> 

就是子组件要监听父组件传过来的 prop ,并做一些操作(步骤 2 )。当子组件更新值的时候(步骤 3 ),又会再次触发 watcher 且又执行一次步骤 2 ,此时我并不想再触发步骤 2 的操作 ,除了加一个类似锁的变量之外还有什么别的办法吗? 谢谢。

和 .project 文件说“再见”—— VS Code Java 1.1.0 背后的故事

Posted: 01 Dec 2021 10:08 PM PST

Language Support for Java 1.1.0 版本包含了一项重要更新:现在插件在导入新的 Java 项目时,项目元数据文件(.project ,.classpath ,settings 等)默认将不再生成于项目路径下。这一问题 自 2018 年被记录至今已有超过三年的时间。本文旨在记录并分享我们解决这一问题的过程和最后的解决方案。

悬在头顶的"达摩克利斯之剑"

随着 VS Code Java 的功能逐渐丰富,用户数量也在稳步上升。但是由于 Java 插件在导入项目时,会在项目目录下生成元数据文件的问题,我们得到了不少的 1 星差评。可以预见,随着用户基数增加,因这一问题而造成的差评数量也会增加。这就如同一把悬在我们头顶的"达摩克利斯之剑",如果不及时解决,问题随时都有可能爆发。

其实这并不是我们产品组不想彻底修复这一问题,根本原因需要从 Java 语言服务的架构说起:

JDT Java Language Server 架构示意图

VS Code Java 项目背后所采用的 Java 语言服务的正式项目名称是 Eclipse JDT Language Server™,由微软和红帽联手开发。在上面的项目架构图中可以看到,我们在实现中复用了 Eclipse 的一些模块,而这些自动生成的元数据文件也正是由其中一些上游模块所产生。在 Eclipse 的讨论区中可以找到一条相关的讨论帖子。这条帖子的创建时间甚至可以追溯到 2004 年。由于在实现时,这些元数据文件的路径就已经作为常量被硬编码在了代码里,这些常量又被各个不同的 Eclipse 模块甚至是插件引用,经年累月下来这一问题从某种意义上已经成为了"历史包袱"。

考虑到改变上游模块的行为包含了太多的未知和不确定性,在过去我们尝试给用户提供一些变通方法,比如让这些元数据文件在 VS Code 的文件浏览器中隐藏,并引导用户将他们添加至 .gitignore 当中。但从用户的反馈来看,这些方式并没有让用户感到满意。为了能够彻底解决这个已经困扰了我们以及用户三年多之久的"顽疾",我们在今年下半年决定再做一次尝试,希望能将其"根治"。

方案一:使用 Symbolic Link (失败)

我们最先想到的方法是使用 Symbolic Link。在导入项目时,可以将被导入的项目通过 Symbolic Link 的方式链接到一个用户看不到的地方,从而让元数据文件生成在链接后的路径下。但很快这一方案就遇到了问题——在某些操作系统下创建 Symbolic Link 需要特定的权限,否则会抛出 FileSystemException ,这显然不是我们想要的效果,因此这个方案马上被否决了。

方案二:使用 Eclipse Linked Resources (放弃)

和 Symbolic Link 的思路类似地,我们还可以选择使用 Eclipse Linked Resources:

Linked Resources : Linked resources are files and folders that are stored in locations in the file system outside of the project's location.

上文是 Linked Resources 的一段官方定义,它可以作为项目的一部分,但又允许存储在项目路径之外的其他位置。在 VS Code Java 中,我们对于 Unmanaged Folder (无构建系统的项目),就是通过 Linked Resources 机制将这些元数据文件隐藏的,它的实现原理如下图所示:

Unmanaged Folder 实现原理

可以看到项目的实际路径放在了 Language Server workspace storage 中,用户通常并不知晓这一路径,同时在 .project 文件里我们定义了 Linked Resources 的目标路径,也就是用户在 VS Code 打开的文件夹位置,它作为项目的一部分,会像其他项目一样参与到构建过程当中,其开发体验是类似的。

相同的原理可以应用到 Maven 项目和 Gradle 项目的导入过程当中来解决这一问题,因此,我们在 M2E 模块上进行了一些实验。M2E 模块在 Java 语言服务中负责 Maven 项目的导入,通过改动模块中的相关代码,并利用 Linked Resources 机制就可以将元数据文件生成到项目路径之外的地方。

最终的实验结果是可行的,但是这套方案的缺点也非常明显:

  • 改动较大 :需要改动的代码散落在整个模块的不同文件中(大约十几处),同时因为代码规模较大,没有办法在短时间内确定这些改动是否是完备的。
  • 对下游模块不透明 :因为多了一层 Linked Folder ,这会让 Java 项目视图在展示项目结构时,多出一层代表了 Linked Folder 的目录结构。在 Java 项目视图的实现中需要增加一些额外的控制逻辑,让项目结构的展示和正常项目一样。
  • 可行性未知 :对于 Maven 和 Gradle 构建系统的支持模块 M2E 和 Buildship 都是上游项目,这一概念能否被采纳接受是个未知数。
  • 扩展性差 :如果要支持一套新的构建系统,需要将类似的逻辑再实现一遍。

考虑到上述原因,团队在经过讨论之后决定暂时放弃 Eclipse Linked Resources 方案,并继续寻找更优的解决办法。

发现"银弹"

放弃第二套方案还有另一个原因:Eclipse 自发布至今二十载,在保证稳定运行的同时,可以不断地增加新的功能且提供了出色的拓展能力,在这背后一定蕴含了优秀的架构设计和可拓展性。直觉上让我们觉得应该还会有更优雅的解决办法。

因此,这一次我们直接从 Eclipse 底层文件系统入手分析,并最终发现了一枚解决问题的"银弹":File System Provider 和 FileStore (注:虽然在软件工程领域,人们的共识是没有银弹,不过对于这一特定的问题,我们确实找到了一种比较"奇巧"的解决办法)。

Eclipse 工作空间结构与 FileStore

Eclipse 在运行过程中会为整个工作空间维护一颗树形结构,树的节点代表了文件系统中的文件或目录,同时还保存了文件的一些重要信息,如修改时间等。

Eclipse 底层通过 FileStore 类将这些节点和文件系统中的文件进行关联。FileStore 类还有一个重要特性:如果映射的对象是单个文件,那么 FileStore 还会负责提供这一文件的输入输出流。

这一特性为问题的解决带来了非常重要的思路:只要能够将元数据文件的输入输出流重定向到项目目录之外的位置,问题也许就能得以解决。带着这个假设,我们又发现了另一个关键线索:File System Provider 。

方案三:File System Provider

File System Provider 是 Eclipse 平台对外开放的一个扩展点,它允许开发人员实现一个 Eclipse 文件系统接口( org.eclipse.core.filesystem.IFileSystem ),并将其注册到扩展点上,用以处理具有特定 URI scheme 的文件请求。

于是我们从 File System Provider 这一拓展点入手,继承并覆盖了 Eclipse 默认处理 URI scheme 为 file 的文件系统,通过覆写其中的一些方法,让文件系统在处理元数据文件时,将文件路径重定向到项目路径之外的地方进行读写。相比于方案二,这一套方案的优点在于:

  • 对其他模块完全透明 ,基本不需要进行修改就能正常工作,这同时还意味着较好的 拓展性
  • 代码量很小 ,最终的实现,算上 JavaDoc 和注释,一共只有 300 行左右。

当然这个方案也并非完美,因为它要求其他模块通过 Eclipse 提供的 API 进行对元数据文件的读写操作。我们在实现过程中就发现上游 Buildship 在处理元数据文件时直接通过JDK中的文件 I/O API 进行读写,为此我们提交了一份变更请求将相关操作迁移到了 Eclipse API 上。

总结

在权衡了利弊之后,我们最终选取了第三套方案并解决了这一困扰了 VS Code Java 用户三年多时间的问题。虽然最终的实现并不复杂,但探寻答案的过程却非常具有戏剧性。

最后特别感谢 Eclipse Platform 项目成员 Mickael Istria 以及 Alexander Fedorov 。在问题讨论的过程中他们给予了非常有用的建议,对问题的解决起到了非常关键的作用。

使用 vim 中文问题,网上所有方法都是切换到 abc 之后切回来? 这种用起来也是麻烦切换微信还需要切换下输入法?求能不能比如 搜狗 不用切输入法 仅仅是切 中英文就可以完成?

Posted: 01 Dec 2021 10:06 PM PST

使用 vim 中文问题,网上所有方法都是切换到 abc 之后切回来? 这种用起来也是麻烦切换微信还需要切换下输入法?求能不能比如 搜狗 不用切输入法 仅仅是切 中英文就可以完成???

做个开发者调查

Posted: 01 Dec 2021 08:56 PM PST

在点开这个帖子之前,有多少同学是知道"信创"这两个词的含义 or 是从事相关工作的?

很好奇到底这个产业有多么引人注目。

如果你是从事相关行业的,不妨在下方留言你所在的企业 or 正在做的领域。

求问 Everything 怎么才能默认搜索某一文件夹下的文件

Posted: 01 Dec 2021 05:28 PM PST

everything 在哪里设置才能在每次用快捷键打开的搜索窗口中**默认**仅搜索某一路径下的文件?
在以前的电脑上设置过,现在换了电脑在设置中没有找到……

关于量子教程与平台(已经知道的大牛请忽略)

Posted: 01 Dec 2021 04:21 PM PST

Hello, Excuse me.

Please take time to google 百度贴吧( you can copy it ) on your computer or mobile phone, and search in 百度贴吧 : "有好奇心的工程师" (吧 bar), and pay attention to post (comments).

Thank you. Goodbye.

It has the IBM Quantum Platform and tutorials

如果懂中文,也可以看看本源量子

No comments:

Post a Comment