当前位置: 首页 > news >正文

工程师是怎样对待开源 qt

工程师如何对待开源

本文是笔者作为一个在知名科技企业内从事开源相关工作超过 20 年的工程师,亲身经历或者亲眼目睹很多工程师对待开源软件的优秀实践,也看到了很多 Bad Cases,所以想把自己的一些心得体会写在这里,供工程师进行参考,希望能帮助工程师更好的成长。

概述

作为一个在科技企业内部进行技术工作的工程师,工作任务就是用技术手段支持和实现公司所关注的商业目标。 实际工作过程中,需要主动或者被动的使用和维护大量的开源软件。 据统计,每个工程师在企业内部进行研发和运维等工作的时候,每年会接触到上千款开源软件, 如果是以 Java 或 JavaSciprt 为主要程序开发语言的工程师,则接触到的开源软件数量更多,在万级别甚至十万级别。 (数据来源:《2020 State of the Software Supply Chain》由 Sonatype 发布)

那么如何选择开源软件? 这么多开源软件中,如何根据个人需求和业务需要来选择合适的开源项目来进行投入,是需要综合考虑的。

选择了开源软件之后又如何进行定制和长期维护? 这也是一个很大的问题。因为在企业内部开发软件,跟个人开发软件不一样的是,维护一个计算机软件系统的成本远远大于开发该系统或软件的成本。选择开源软件之后,如何从长期的视角进行定制和修改,后续的长期维护如何进行,才能做到高效和节省成本,业内有很多很好的经验,也有不少不太成功的案例成为教训。

最后回到个人,工程师的成长是在不断的学习和实践中进行的。如何来利用开源来提升自己能力,扩大自己的眼界,提高自己技术口碑和业内影响力,对于工程师本人也是非常重要的。

本文将从如下三个部分来分别阐述:

工程师如何选择开源软件

工程师如何定制和维护开源软件

工程师个人成长如何利用开源

1. 如何选择开源软件

首先要明确对开源软件的态度,在现阶段是不可能离开对开源软件的使用的。 使用开源软件有各种各样的风险,包括开源合规、安全、效率的问题。 简化为一句:在企业内部使用开源软件,需要遵守该企业对开源软件的内部规定,包括如何引入和如何维护,以便达到高效、安全、合规的使用。

回到具体如何选择特定的开源软件的问题上,有如下几个纬度可以进行参考。

根据需求

根据技术发展趋势

根据软件采纳周期的不同阶段

根据开源软件的成熟度情况

根据项目的质量指标

根据项目的治理模式

1.1 根据需求来选择开源软件

选择开源软件,首先要明确需求,即选择这个开源软件的目的究竟是什么。 工程师选择一个开源软件,究竟是它用来做什么的,是用来进行个人学习的; 还是用来满足 ToB 客户的需求的;还是用来满足内部服务开发的需求的。 这三个不同的目的下,选择开源软件的导向完全不一样。 (注意:后两个场景是需要先考虑企业开源合规的需求的,参见第三章)

先说说选择开源软件来进行个人学习,那么需要看看个人学习的具体目的究竟是什么。 是想学习一种比较流行的技术来完善个人的技术知识结构扩大个人技术视野;还是想看看相应的开源技术项目的具体实现,来作为内部项目技术开发的参考;还是想为了下一份工作进行有针对性的技术准备。不同的目的会导致不同的选择。针对前者,显然是什么技术最流行选什么,自己缺什么选什么;针对第二种目的,一般是对该技术领域的知名开源软件或者创新性软件进行有针对性的选择,即某个特性是我当前需要的,或者是我当前项目实现不好的,我需要看看别人是如何实现的。最后一种,显然是按照下一份工作的职位需要和技术栈要求进行准备,并根据技术栈要求的门槛高低进行选择。但是注意,从个人需求出发选择开源软件,一般都需要写个小项目练练手,比如一个 Demo 程序或者一个测试服务,因为不用考虑后续的长期维护,所以尽可以按照个人的想法和个人研发习惯进行各种练习,不用遵循企业内部的开发流程和质量要求,也不用考虑该开源软件的稳定性和社区成熟度等情况,只需要尽情的学习和参考代码就好了。

然后看下一个需求,选择开源软件进行研发的软件是需要提供给客户的,往往可能还是以私有云的方式进行交付。基于此类需求来选择开源软件,注意作好平衡,即客户的需求和企业自身技术规划或产品的长期规划需要。以私有云方式进入客户的 IDC 环境,是需要跟客户开发和运行环境的上下游项目进行集成的。这时候要看客户的需要,可能某些客户对开源软件有特定的要求,例如要求使用 HDFS 而且是某个特定版本。对这类指定软件名字和指定版本的要求,有可能是因为客户当前比较熟悉这个版本,也有可能是因为之前其他软硬件供应商提供的软件和版本,指定的目的是方便集成和后续的使用与维护。如果这种需求是符合企业项目或者产品的长期发展需求的,则是可以完全满足的。如果甲方非常强势,除了满足他的要求之外没有别的办法,那就选择客户所指定的软件和版本好了。但是如果跟自身项目或产品的长期发展需求不一致,而且具体项目或者版本是可以跟甲方进行协商的,那么需要跟客户协商出一个双方都能接受的结果出来,即选择特定的开源软件和版本既要做到客户满意并买单,又要做到自身的交付成本可控,还要做到符合自身项目或者产品的长期发展需要。例如客户使用 Java 的某个老版本,但是企业的 toB 交付的软件要求使用 Java 的较高版本。那么需要跟客户协商,要么切换到企业希望的版本上,还需要帮助客户完成已有系统的升级工作;要么只能降低自身软件的 Java 版本需求,可能还需要对某些自身代码进行修改,还可能对软件中的某些依赖组件进行修改。这个场景下是带有很多客观约束条件下的选择,是需要跟客户,自身的产品经理和架构师一起协商的。

最后,如果场景是为了满足内部服务的需求,即选择开源软件来搭建的服务是给内部业务或者最终用户来使用的,常见于国内各大互联网公司的互联网服务系统和各种手机上的 App。这时候项目的开发和维护方有较大的自主权,跟 toB 的交付业务完全不一样。此时选择开源软件,就一定要综合考虑开发和维护成本,还要考虑使用该服务的业务所处的阶段。

(1)如果提供的服务是给创新业务使用的,创新业务一般都是试错业务,随时需要根据市场情况的变化和当前执行的状态进行调整,很可能三个月后这个项目没了,即被取消了。这种情况下 “糙快猛” 的开发方式是比较合适的,不用太多考虑系统的可维护性和可扩展性,就用研发团队最熟悉的软件技术栈,然后用底层技术支撑团队比如基础架构团队提供的成熟而且经过验证后的底层基础技术平台就可以,最重要是尽快把系统搭建出来,然后随着产品进行快速的迭代。这个时候需要尽量降低现有研发运维团队的学习成本和开发成本,不用太多考虑可维护成本,因为需要糙快猛的把系统堆出来,验证产品需求和商业模式是最重要的,时间最重要。如果发现有市场机会,就快速跟进,站稳脚跟之后可以采用省时间但是费资源的方式(俗称 “堆机器”)来进行扩展,或者采用 “边开飞机边换引擎” 的模式进行重写都是比较划算的。对于处于创业阶段的企业或者项目来说,速度胜过一切。

(2)但是如果选择开源软件搭建出来的计算机软件系统或者服务,是需要长期维护的,比如是给公司内成熟业务使用的,或者是针对公司内成熟平台的缺点进行系统升级并要替代原有产品的,那么在满足业务需求的前提下,考虑系统的可维护性变成最重要的事情。选择对应的开源软件,它是否成熟,是否稳定;二次开发是否友好;运维成本是否比较合算即比较省机器和带宽;运维操作是否方便,例如常见的扩容和缩容操作是否可以高效、自动、无损的完成;Upstream 到上游开源社区是否容易等等,这些都成为需要重点考虑的事情。这种情况下,开发一个系统的成本,可能只占整个系统生命周期内的成本的 1/10 不到。所以在满足需求的前提下,重点考虑可维护性。

1.2 根据技术发展趋势来选择开源软件

如上图所示,现代计算机软件或者服务的研发,是一个不断运行的循环和迭代过程。从市场分析开始,然后进入到创意阶段,再到编码阶段,最后到上线阶段完成应用的部署和生效,上线之后根据得到的数据反馈,继续进行分析。这个循环迭代的过程,显然对于一个身处竞争激烈的行业的企业来说,迭代的速度越快越好,同时也需要具备快速弹性、低成本伸缩的能力,即产品方向对了,那么赶紧进行系统扩容,承接快速增长的流量,做到快速增长;如果产品方向不对,需要赶紧缩容,把相关硬件和人力资源节省出来,投入到新的试错方向上去。身处同一个行业内的企业,如果企业 A 能以更低的成本,更快的速度的进行各种产品和策略的迭代,显然它是能比迭代速度慢,成本高的企业 B 是有更好的竞争优势的。

现在的开源软件数量非常多,几乎每一个分类下面都有很多的开源项目。针对某一个具体的需求,如何进行选择?一个建议是根据技术趋势进行选择。即现在的计算机系统迭代的方式是 Agile(敏捷) + Scale(扩展)。显然,能够支持计算机系统进行快速迭代,并能够很方便进行低成本弹性伸缩的开源软件是值得进行长期投入的。而对一个新的开源软件的学习和使用,学习者是希望该软件的学习门槛越低越好。一个流行的开源软件,内部实现可以尽可能的复杂,但是对于用户来说一定是需要用户友好的。不然即使创新度再好,易用性不好,只有极客才能学习和掌握,创新的鸿沟是很难跨越的。

例如 Docker 的出现之后,以极快的速度风靡全球,非常多的工程师喜欢上了 Docker。就是因为 Docker 的特性,在传统的容器系统之上增加了新特性,包括把应用程序和底层依赖库封装为一个容器镜像,容器镜像有版本,而且可以通过集中的镜像仓库进行存储和大批量分发。Docker 首先解决了长期困扰工程师的开发、测试、上线环境标准化的问题,能够支持开发者进行快速的迭代。同时使用了统一的镜像仓库来进行镜像的分发,而且底层采用了轻量级虚拟机即容器的技术,可以非常快的被拉起,所以采用 Docker 的系统可以很方便的进行弹性扩展。同时,因为把应用 App 封装在一个镜像里面,可以在逻辑上根据 Domain Model 的设计原则进行更好的抽象和复用。显然,这样的技术是值得每一个开发计算机系统的工程师学习和掌握的。因为他能带来极大的方便。相反,在 Docker 产生之前,虽然 Control Group(简称 cgroup) + Namespace 的技术早就已经出现,并早就集成在 Linux 内核中,Google 的 borg 相关的论文早就已经发表,但是一般的技术研发团队不是很容易就能驾驭容器并把容器系统在公司内部大规模进行部署的。印象中 borg 论文出现后,国内只有 BAT 级别的互联网公司,才有一小撮精英研发团队来研发和使用容器管理系统,例如百度负责 Matrix 系统研发的团队,阿里负责 Pounch 系统研发的团队,腾讯也有一个小团队负责容器系统的研究。但是除了那一小部分团队,更多的工程师因为相对较难的学习难度而没有把容器大批的用起来。而 Docker 这种技术,就是非常好的顺应了敏捷和弹性扩展的技术趋势,而且提供了非常好的用户易用性,然后一出场就被非常多的工程师迅速使用上了,而且成为市场的默认标准。

这些顺应潮流的开源软件是值得选择和投入的。

另外一个例子是 Spark,Spark 的出现解决了 MapReduce 在分布式计算过程中因为需要频繁进行 IO 操作导致的性能比较低下的问题,同时在易用性上有较大的提升,所以才取代了 MapReduce 在分布式计算领域内的主流地位。

1.3 根据开源软件采纳周期的不同阶段进行选择

软件作为智力活动的产物,他有他的生命周期,一般用软件的技术采纳曲线表示。

开源软件也是软件的一种,也都是遵循软件的技术采纳规律的。

一个开源软件从创建到衰亡一般会经过 5 个阶段。 从创新期(Innovators,占比 2.5%),到早期采纳期(Early Adopters,占比 13.5%),然后跨越鸿沟(chasm),进入到早期大众期(Early Majority,占比 34%),再进入后期大众期(Late Majority,占比 34%),最后进入衰退期(Laggards,占比 16%)。绝大部分的开源创新项目,没有能成功的跨域鸿沟,即从早期采纳阶段进入到早期大众阶段,就消亡掉了。 所以,如果是选择一个需要长期使用并维护的开源项目,选择处于早期大众或者后期大众状态的项目是比较理智和科学的。

当然如果只是个人想学习一个新的东西,可以看看处于创新者状态的开源项目,或者看看处于 “早期采纳者” 状态的项目。

注意不管是从长期研发系统的角度,还是从个人学习的角度,都不要再去看处于衰退期(Laggards)的项目了。 例如现阶段即 2022 年,是不用再去选择 Mesos,Docker Swarm 之类的项目了。自从 Kubernetes 成为容器调度技术分类的默认标准,这两个项目就已经处于衰退期,他们的母公司都已经放弃了。这个阶段如果还投入较多精力来开发和维护,除非真的是非常强势的甲方要求,把钱砸在工程师面前逼的不得不用才会选择。

相关文章:

工程师是怎样对待开源 qt

工程师如何对待开源 本文是笔者作为一个在知名科技企业内从事开源相关工作超过 20 年的工程师,亲身经历或者亲眼目睹很多工程师对待开源软件的优秀实践,也看到了很多 Bad Cases,所以想把自己的一些心得体会写在这里,供工程师进行…...

Maven中Servlet的坐标为什么要添加<scope>provided</scope>

Maven中Servlet的坐标 在Maven中,我们使用坐标(Coordinates)来唯一标识一个依赖库。对于Servlet,其坐标通常是指定servlet-api包。在使用Servlet时,我们需要将其添加到项目的依赖中,以便在编译、运行和测试…...

联发科CEO:未获准向华为供货,换机潮已过去,手机需求不会更差

据钜亨网报道,联发科近期召开了业绩说明会。蔡力行,该公司副董事长兼首席执行官,表明当前手机市场需求保持稳定,并且随着过去两年用户更换潮的过去,对手机市场明年有一定期望。 根据蔡力行的指示,联发科正在…...

2023年DevOps和云趋势报告!

要点 ●云创新已从革命性阶段转变为演进性阶段,重点是迁移和重新架构工作负载。云空间已发展为提供对可扩展资源和托管服务的按需访问,强调简化交互并减少团队的认知负担。 ●人工智能 (AI) 和大型语言模型 (LLM) 可以通过解决认知过载问题并支持即时管…...

怎么学习CSS相关技术知识? - 易智编译EaseEditing

学习CSS技术是前端开发中的重要一环,它用于控制网页的样式和布局,使网页更加美观和易于使用。以下是学习CSS技术的几个方面: 基本语法和选择器: 了解CSS的基本语法,学习如何使用选择器来选择HTML元素并应用样式。 样…...

Qt 2. QSerialPortInfo显示串口信息

在ex2.pro 添加&#xff1a; QT serialport//main.cpp #include "ex2.h" #include <QtSerialPort/QtSerialPort> #include <QApplication>int main(int argc, char *argv[]) {QApplication a(argc, argv);Ex2 w;w.show();QList<QSerialPortInfo>…...

linux or mac 查看进程的pid和占有的端口

1.查看谁占有了什么端口&#xff1f; lsof -i:<占用端口> [rootgit-lab gitlab]# lsof -i:8929 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME docker-pr 25090 root 4u IPv4 140059875 0t0 TCP *:8929 (LISTEN) docker-pr 25096 root …...

8.2Jmeter5.1:察看结果树的响应结果乱码

【问题描述】 Jmeter察看结果树的响应结果乱码 原因&#xff1a;jmeter.properties未设置语言 【解决方案】 修改jmeter.properties的属性&#xff0c;然后重启Jmeter # The encoding to be used if none is provided (default ISO-8859-1) sampleresult.default.encodingut…...

vscode 快捷键

今天好闲 就记一些学的东西吧~ vscode 快捷键 快速生成头文件注释&#xff1a;Ctrlalti 快速生成方法注释&#xff1a;Ctrlaltt 新建窗口&#xff1a;CtrlShiftn 查找&#xff1a;Ctrlf 替换&#xff1a;Ctrlh 替换所有&#xff1a;CtrlAltEnter 打开上一个编辑器&#xff1a;…...

Python pillow扩展库图像编程

...

【Antv G6】导出图片

需求 将Antv G6生成的树形图导出成图片 代码 <div style"height: calc(100% - 50px);"><div id"miniMap" class"minimap"></div><div id"containerG6" ref"containerG6" class"containerWrap&…...

shared_ptr

源码路径&#xff1a; /opt/rh/devtoolset-10/root/usr/include/c/10/bits/shared_ptr_base.h D:\wsl-ubuntu20.04\rootfs\usr\include\c\9\bits\shared_ptr_base.h 类原型&#xff1a; template<typename _Tp, _Lock_policy _Lp>class __shared_ptr: public __shared_pt…...

ChatGPT + Stable Diffusion + 百度AI + MoviePy 实现文字生成视频,小说转视频,自媒体神器!(二)

ChatGPT Stable Diffusion 百度AI MoviePy 实现文字生成视频&#xff0c;小说转视频&#xff0c;自媒体神器&#xff01;(二) 前言 最近大模型频出&#xff0c;但是对于我们普通人来说&#xff0c;如何使用这些AI工具来辅助我们的工作呢&#xff0c;或者参与进入我们的生活…...

git提交的时候Changes not staged for commit

git删除和修改一些文件之后&#xff0c;git add -A之后就使用git commit -m "提交最新代码"后报错 On branch master Your branch is up to date with origin/master.Changes not staged for commit:但是使用git push origin master怎么都提交不上去&#xff0c;解决…...

03_使用execle表生成甘特图

背景 每次排期都需要话很多时间 很可能排期还不对头 这时候需要一个表能看到 1.什么时候项目结束 开始 转阶段 2.当前手上的活能不能做完 当前阶段手上有多少活 3.产品经理每次修改完计划迅速排期 甘特图生成 execle表生成 1.需要使用亿图创建甘特图 2.把当前的甘特图数据进…...

linux基础命令-ls

“ls” 命令是 Linux 系统中用来列出目录内容的常用命令。它显示当前工作目录中的文件和子目录列表。下面将详细解释 “ls” 命令的用法以及示例&#xff1a; 命令语法&#xff1a; ls [选项] [目录] 常用选项&#xff1a; -l&#xff1a; 以长格式&#xff08;long format&a…...

Chrome浏览器中的vue插件devtools的下载方式(使用Chrome应用商店/科学上网情况下)

目录 devtools对前端来说的好处——开发预览、远程调试、性能调优、Bug跟踪、断点调试等 下载步骤&#xff1a; 测试阶段&#xff1a; 最近做项目要使用devtools这个vue插件。 devtools对前端来说的好处——开发预览、远程调试、性能调优、Bug跟踪、断点调试等 下载步骤…...

7、Kubernetes核心技术 - Secret

目录 一、Secret概述 二、Secret 三种类型 2.1、Opaque 2..2、kubernetes.io/dockerconfigjson 2.3、kubernetes.io/service-account-token 三、Secret创建 3.1、命令行方式创建 Secret 3.2、yaml方式创建 Secret 四、Secret解码 五、Secret使用 5.1、将 Secret 挂载…...

MATLAB算法实战应用案例精讲-【自动驾驶】路径规划(补充篇)

目录 前言 几个高频面试题目 无人车运动规划,路径规划,轨迹规划的区别和联系?...

农业与太阳能的互利共生

不断增长的人口需要更多的食物和能源&#xff0c;而这些都在争夺有限的空间……除非能改变这样的竞争局面。 农业光伏装置将农业和太阳能生产结合起来。 农业光伏 (AV) 是 20 世纪 80 年代提出的概念&#xff0c;它在同一块土地上将农业和太阳能生产结合起来。 从业者在太阳能…...

每日一题(822. 翻转卡片游戏)-集合set

题目 822. 翻转卡片游戏 题解思路 简述为&#xff1a;找到桌面卡片中 不重复的最小值&#xff0c;卡片可以来回反转 如果 卡片前面后面的数字相同 则抛弃不用在剩下的卡片中 找到最小值&#xff08;前后可以反转 卡片不分前后&#xff09; 代码 C class Solution { pub…...

windows服务器iis PHP套件出现FastCGI等错误解决方法汇总

如果您的服务器安装了PHP套件&#xff0c;出现了无法打开的情况&#xff0c;请参照如下办法解决&#xff1a; 首先&#xff0c;需要设置IIS允许输出详细的错误信息到浏览器&#xff0c;才好具体分析 错误一&#xff1a; 处理程序“FastCGI”在其模块列表中有一个错误模块“Fast…...

Qt Creator 11 开放源码集成开发环境新增集成终端和 GitHub Copilot 支持

导读Qt 项目今天发布了 Qt Creator 11&#xff0c;这是一款开源、免费、跨平台 IDE&#xff08;集成开发环境&#xff09;软件的最新稳定版本&#xff0c;适用于 GNU/Linux、macOS 和 Windows 平台。 Qt Creator 11 的亮点包括支持标签、多外壳、颜色和字体的集成终端模拟器&am…...

Collections工具类(java)

文章目录 7.1 常用方法 参考操作数组的工具类&#xff1a;Arrays&#xff0c;Collections 是一个操作 Set、List 和 Map 等集合的工具类。 7.1 常用方法 Collections 中提供了一系列静态的方法对集合元素进行排序、查询和修改等操作&#xff0c;还提供了对集合对象设置不可变、…...

C++ 第六弹 STL

目录 1.什么是stl 2.六大组件-容器-序列式容器-C98 string 3.六大组件-容器-序列式容器-C98 vector 4.六大组件-容器-序列式容器-C98 list 5.六大组件-容器-序列式容器-C98 deque 6.六大组件-容器-序列式容器-C11 array 7.六大组件-容器-序列式容器-C11 forward_list 8…...

蓝桥杯上岸每日N题 第四期(最少刷题数)!!!

蓝桥杯上岸每日N题第四期 ❗️ ❗️ ❗️ 最少刷题数 同步收录 &#x1f447; 蓝桥杯上岸必背&#xff01;&#xff01;&#xff01;(持续更新中~) 大家好 我是寸铁&#x1f4aa; 冲刺蓝桥杯省一模板大全来啦 &#x1f525; 蓝桥杯4月8号就要开始了 &#x1f64f; 距离蓝…...

STM32 LWIP UDP 一对一 一对多发送

STM32 LWIP UDP通信 前言设置 IP 地址UDP函数配置实验结果单播发送&#xff0c;一对一发送广播发送&#xff0c;一对多发送 可能遇到的问题总结 前言 之前没有接触过网络的通信&#xff0c;工作需要 UDP 接收和发送通信&#xff0c;在网上没有找到一对一、一对多的相关例程&am…...

【有趣的设计模式】23 种设计模式详解和场景分析

前言 七大设计原则 1、单一原则&#xff1a;一个类只负责一个职责 2、开闭原则&#xff1a;对修改关闭&#xff0c;对扩展开放 3、里氏替换原则&#xff1a;不要破坏继承关系 4、接口隔离原则&#xff1a;暴露最小接口&#xff0c;避免接口过于臃肿 5、依赖倒置原则&#xff1…...

【数据结构与算法】TypeScript 实现图结构

class Grapg<T> {// 用于存储所有的顶点verteces: T[] [];// 用于存储所有的边 采用邻接表的形式adjList: Map<T, T[]> new Map();// 添加顶点addVertex(v: T) {this.verteces.push(v);// 初始化顶点的邻接表this.adjList.set(v, []);}// 添加边addEdge(v: T, w:…...

《golang设计模式》第一部分·创建型模式-04-抽象工厂模式(Abstract Factory)

文章目录 1. 概述1.1 角色1.2 类图 2. 代码示例2.1 设计2.2 代码2.3 类图 1. 概述 1.1 角色 AbstractFactory&#xff08;抽象工厂&#xff09;&#xff1a;它声明了一组用于创建产品的方法&#xff0c;每一个方法对应一种产品。ConcreteFactory&#xff08;具体工厂&#xf…...