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

一个土木工程专业背景的开发者,讲述开源带给他的力量

在前段时间我们举办的“TDengine Open Day”第一季技术沙龙中,TDengine 应用研发高级工程师谭雪峰进行的“开源之路:程序员的成长与探索”主题分享获得了众多参会者的好评。谭雪峰从自身独特的职业发展经历出发,分享了自己在开源领域的种种收获以及在进行职业转换过程中面临的挑战及应对。本篇文章基于此次演讲整理而成,给到有需要的开发者参考。

从土木工程到软件开发,开源是我的“老师”

我并不是科班出身,大学学的是土木工程专业,最后转来转去,就成为了一名开发者,过程中所有的编程知识我都是自学的。从土木工程到软件开发,这一转变几句话可能就概括完了,但我在其中付出的精力和努力不是能简单用文字概括的,现在想想,幸好坚持了下来,最终也结出了一个不错的成果。

最开始就是因为对游戏的热爱,引发了我对游戏逆向工程的兴趣。我开始使用工具如金山游侠、Cheat Engine(CE)、OllyDbg(OD)、IDA 等,来探索游戏的内部工作原理。这一过程让我熟悉了汇编语言和伪 C 代码,进而激发了我对底层编程的兴趣。通过参与 Capture The Flag(CTF)比赛,我进一步锻炼了我的技术能力,并在解决复杂问题中找到了乐趣。

之后,我从逆向工程转向了更广泛的编程领域,开始自学 JavaScript、Python、PHP、Lua 和 Go 等语言。在刚开始工作时由于编程知识的基础不足,工作上还是非常困难的,我就边实践边学习。这一路上,我的知识几乎都是通过网络学习来的——通过百度和谷歌,我能够搜索到几乎任何我需要的学习资源;同时,技术社区如 CSDN 和 Stack Overflow 成为了我解决编程难题和学习新技能的宝贵平台。这些资源对我帮助巨大,让我能在编程的世界里越走越远。

还有一个很重要的学习途径就是参与开源项目。刚开始我就是在 GitHub 上学习别人写的开源代码,等有了成长之后就不单是学习了,我自己也开始贡献代码,成为了一名 Contributor。我参与的第一个开源项目是关于寻路算法的优化,在从 ActionScript 到 TypeScript 的转换过程中,我发现了一些算法的 Bug,并开始尝试修复,最终成功修正了源算法的狄洛尼三角网生成错误以及包围盒调用错误。这是我第一次向开源社区贡献代码,感觉自己真的是从使用工具到改进工具的一个转变。

之后我印象比较深刻的一个项目是关于 H265 视频流。在某次工作中,我在一个项目中需要处理 H265 格式的视频流,要优化延迟时间。我花了一些时间进行改进,后端取到 H265 裸流进行处理之后用 Websocket 实时推送 Web 端,然后在 Web 端我将 ffmpeg 编译成 webassembly,之后在浏览器里用 Worker 实现多线程软解,最终通过 Canvas 进行实时监控,并成功实现了毫秒级延迟。这个项目让我学到了很多关于视频处理和浏览器性能优化的知识。后来,我把这个前端解决方案开源了,希望能帮助到其他面临相同挑战的开发者。

最具戏剧化的一次开源经历就是参与 TDengine HiveMQ 挑战赛,这次经历也让我与 TDengine 真正连接在了一起。在这场比赛中,我最终以第一名的成绩获得了“优胜奖”,结果还是很不错的。这也是我第一次参与开源社区活动,感觉能展示自己还能回馈社区,这正是我想做的事情。接着我就收到了涛思数据抛出的“橄榄枝”,最后很幸运地成为其中一员,目前我主要负责 TDengine 的应用研发和一些周边生态建设。

其实在这之前我就在研究 TDengine 了,我之前所在领域是工业物联网,对各种时序数据库都需要了解一些,国产的时序数据库数量比较少,其中开源的就更少了,在这些开源数据库里面 TDengine 性能又是其中非常高的,当时要将TDengine 引入到平台里面,就认识了涛思数据的人。后来因为一些开发任务我开始研究 TDengine 的源码,为了能在 Windows 上应用便用 GCC 编译做了一些修改,这也是我首次参与大型开源项目。

通过这些经历,我从一个简单使用工具的程序员,变成了能够自己“造轮子”的开发者。现在,我不仅能解决问题,还能创造工具帮助他人解决问题。这就是开源给我的最大礼物—成长和自由。

开源让用户、项目、开发者多方共赢

发展至今,开源社区已经演变为一个日益壮大的全球性多元化舞台,开发者可以在社区中分享经验、解决问题、合作开发,共同推动项目的发展。越来越多的企业意识到开源的重要性,积极支持开源项目,并且在自己的产品和服务中采用开源技术。许多大型企业也积极参与到开源项目中,贡献代码、资源和经验,推动了开源社区的发展和创新。

上图是 GitHub 2023 年年度报告,从其中我们可以看到,2023 全年一共有 4.2 亿个项目、2.84 亿个公共仓库、6.5 万个公开的生成式 AI 项目、总共做出了 45 亿次贡献。可见开源项目数量不断增长,涵盖了各个领域,包括操作系统、编程语言、框架、工具、应用程序等。

开源产品无疑是当今技术发展的一大趋势。通过开源,产品可以吸收来自不同使用者的广泛反馈,不合理之处可以通过提交问题(issue)来指出,而社区的开发者则能贡献自己的代码改进。这种模式促使使用者、开发团队和社区三者之间形成协作,共同丰富和完善项目内容,确保了项目的持续健康发展,而不是闭门造车式地过早终结。

以 TDengine 为例,不同于许多时序数据库采用的是单机版免费而集群版收费的模式,TDengine 提供的集群版同样是开源的。这不仅使得开发者能够深入学习数据库集群的解决方案,还为使用者提供了更优质的集群版时序数据库选择,实现了多方共赢的局面。

当下的“开源盛景”无疑也为每个开发者提供了很大的机会。开源让开发者展现自己的同时还能帮助到其他人,分享越多得到的就越多,你可能觉得自己掌握的知识很简单,但也有很多人还不懂,他们得到了你的帮助也会诚心的去感谢你。以我自身参与开源的经历来说,我认为通过开源项目主要能让我们获得以下四个维度的能力提升:

  • 提升代码质量

我们可以选择一些优质的开源项目,多看多学习这些开源代码。但想要成长还需要多写,不光要写代码还要把优化的过程写出来,最简单的办法就是写完一段代码之后半个月再去看,如果觉得当时的写的非常 low 那就说明有成长了。最好就是自己写东西开源出来,帮助别人的同时与开源项目一起成长。

而且开源代码还会促使开发者保持高标准,因为知道自己的代码将被公开展示,我们便会更加注重代码的整洁和清晰。Linus's Law 曾说过一句经典名言“Given enough eyeballs, all bugs are shallow”,这句话的意思是如果有足够多的人检查代码,那么所有的 Bug 都将无处藏身。

  • 获得实战项目经验

参与开源项目为程序员提供了接触和探索各种规模代码库的机会,这些代码库的规模从几十行的小型脚本到多达数百万行的复杂系统不等。通过研究和实践这些现有的代码,程序员不仅可以学习到如何构建简洁、高效且易于维护的代码结构,还能深入理解多种设计模式和算法的实际应用。此外,参与这些项目还可以帮助他们在实际开发中更好地理解代码的性能优化、错误处理和用户体验改进等关键方面。

  • 技术视野拓展

当一项新技术开始引起关注时,开源项目往往是最早采用和实验这些技术的平台之一。参与这些项目不仅可以使程序员在早期阶段就接触并掌握这些前沿技术,还能深入了解其背后的原理和实际应用场景。这种直接的实践经验不仅能够提升个人的技术能力,还有助于帮助我们形成对未来技术趋势的敏锐洞察,在不断变化的职业市场中保持竞争优势。

  • 建立个人品牌

随着开源技术的深入和广泛应用,开源社区的影响力日益增强,越来越多的企业开始认识到开源项目中隐藏的人才价值。企业不仅在技术创新上依赖这些开源解决方案,同时也倾向于招募那些在开源社区中积极贡献的程序员。那些在开源社区中有所贡献的程序员,往往更容易获得企业的青睐,从而获得更好的职业发展机会。

但相应的,拥有“Contributor”的头衔不仅是一种荣誉,更是一种责任。作为开源社区的一员,我们需要从内心深处发挥回馈社区的责任感。开源项目的成功不仅仅依赖于代码的质量,更重要的是依赖于社区成员的积极参与和持续贡献。这包括对项目的负责,关注并推动项目的长期发展,维护社区的健康生态,以及确保软件的高质量和稳定性,为用户提供卓越的使用体验。通过这种全面的投入,我们不仅提升个人技术水平,还为整个开源生态系统的繁荣做出贡献。

程序员与工程师

在软件开发中,程序员和工程师虽共同致力于软件的创建与完善,但他们的角色和职责各有侧重。程序员主要专注于编写、测试和维护代码,解决特定的技术问题。他们是代码实现和逻辑的专家,通过精确的编程确保软件功能的实现。

而软件工程师的职责更为广泛,不仅包括编程,还涵盖项目的整体规划、设计、测试、部署与维护。工程师需要在整个软件开发周期中进行综合考虑和资源协调,以确保项目的顺利执行和质量标准的达成。因此,每位工程师都应具备扎实的编程能力,而成为一名合格的程序员仅是迈向全面软件工程师之路的起点。通过积极参与开源,程序员可以逐步扩展自身的技术和管理视野,最终成长为能够在更广泛领域内作出影响的软件工程师。


 

相关文章:

一个土木工程专业背景的开发者,讲述开源带给他的力量

在前段时间我们举办的“TDengine Open Day”第一季技术沙龙中,TDengine 应用研发高级工程师谭雪峰进行的“开源之路:程序员的成长与探索”主题分享获得了众多参会者的好评。谭雪峰从自身独特的职业发展经历出发,分享了自己在开源领域的种种收…...

express+vue在线im实现【四】

往期内容 expressvue在线im实现【一】 expressvue在线im实现【二】 expressvue在线im实现【三】 本期示例 本期总结 支持了音频的录制和发送&#xff0c;如果觉得对你有用&#xff0c;还请点个免费的收藏与关注 下期安排 在线语音 具体实现 <template><kl-dial…...

【Qt 实现3D按钮】

要在Qt中实现3D按钮&#xff0c;你可以使用QML和Qt 3D模块。这是一个简单的例子&#xff0c;展示了如何在Qt中创建一个3D按钮&#xff1a; 首先&#xff0c;确保你的系统中已经安装了Qt 3D模块。在命令行中输入以下命令检查&#xff1a; qmlscene --version如果没有安装&…...

8.每日LeetCode-笔试题,交替打印数字和字母

代码地址&#xff1a;interview-go: Go高级面试总结 问题描述 ​​​交替打印数字和字母 使用两个 goroutine 交替打印序列&#xff0c;一个 goroutine 打印数字&#xff0c; 另外一个 goroutine 打印字母&#xff0c; 最终效果如下&#xff1a; 12AB34CD56EF78GH910IJ1112KL…...

UE5近战对抗系统Tutorial

文章目录 BP_Character 组合攻击Notify State 检测攻击BP_Character 攻击反馈BP_Character 生命系统BP_Character 死亡效果BP_Character 武器系统BP_Enemy 初始化和行为树 BP_Character 组合攻击 首先我们获取攻击动画&#xff0c;在这里使用的是 Easy Combo Buffering 的攻击…...

Typescript: declear

问: const book: string 这样就可以声明而且赋值为什么还用declear去分成好几步骤走呢? 同时即使不赋值只需要使用const book: string;难道不也行吗? 为什么要加上一个declear呢? 回答: 在 TypeScript 中&#xff0c;声明变量和使用 declare 声明类型信息是两个不同的概念…...

Linux内核编译流程

删除之前编译生成的文件和配置文件 make mrproper生成.config文件 make menuconfig编译 make -j41. No rule to make target ‘debian/canonical-certs.pem‘, needed by ‘certs/x509_certificate_list‘ vim .config 修改CONFIG_SYSTEM_TRUSTED_KEYS为"" 修改C…...

昇思25天学习打卡营第2天 | 张量Tensor

张量Tensor 张量&#xff08;Tensor&#xff09;基础 张量是MindSpore中的基本数据结构的一种&#xff0c;类似于NumPy中数组和矩阵非常相似。它具有以下重要属性&#xff1a; 形状&#xff08;shape&#xff09;和数据类型&#xff08;dtype&#xff09;&#xff1a;每个张量…...

时间安排 |规划

计算机网络&#xff08;记得完成作业本上的习题&#xff09; 先看王道知识点讲解 然后不懂得看 计算机网络微课堂&#xff08;有字幕无背景音乐版&#xff09;_哔哩哔哩_bilibili 最后做本章习题 【乱讲的】《计算机网络》&#xff08;第8版&#xff09;课后习题讲解_哔哩…...

PS系统教程28

Alpha通道&#xff08;透明通道&#xff09; 8位的灰度通道&#xff0c;也有256个位置记录图片当中的透明度信息 作用&#xff1a;定义透明、半透明、不透明通道信息。保存、存储选区。 白色不透明区域黑色透明区域灰色半透明区域 案例 为了将我们抠出来的人物方便下次修改…...

如何在web页面下做自动化测试?

自动化测试是在软件开发中非常重要的一环&#xff0c;它可以提高测试效率并减少错误率。在web页面下进行自动化测试&#xff0c;可以帮助我们验证网页的功能和交互&#xff0c;并确保它们在不同浏览器和平台上的一致性。本文将从零开始&#xff0c;详细介绍如何在web页面下进行…...

spring源码环境的搭建

为什么要编译spring源码 为了高效调试Spring源码、验证个人猜想&#xff0c;并从开发者的视角深化理解&#xff0c;编译自定义的Spring源码版本显得尤为重要。这样可以避免因缺乏预编译版本而带来的不便&#xff0c;并允许直接在源码上进行注释或修改&#xff0c;以记录学习心…...

小山菌_代码随想录算法训练营第三十四天| 56. 合并区间、

56. 合并区间 文档讲解&#xff1a;代码随想录.合并区间 视频讲解&#xff1a;贪心算法&#xff0c;合并区间有细节&#xff01;LeetCode&#xff1a;56.合并区间 状态&#xff1a;已完成 代码实现 class Solution { public:vector<vector<int>> merge(vector<…...

让工厂像手机一样更“聪明”

手机&#xff0c;作为我们日常生活中不可或缺的一部分&#xff0c;以其智能、便捷、高效的特点&#xff0c;彻底改变了我们的沟通、娱乐和工作方式。那么&#xff0c;想象一下&#xff0c;如果工厂能像手机一样便捷&#xff0c;那么生产过程中的每一个环节都将变得触手可及。通…...

vue2与vue3数据响应式对比之检测变化

vue2 由于javascript限制&#xff0c;vue不能检测数组和对象的变化 什么意思呢&#xff0c;举例子来说吧 深入响应式原理 对象 比如说我们在data里面定义了一个info的对象 <template><div id"app"><div>姓名: {{ info.name }}</div><…...

Spring Cloud - 开发环境搭建

1、JDK环境安装 1、下载jdk17&#xff1a;下载地址&#xff0c;在下图中红色框部分进行下载 2、双击安装&#xff0c;基本都是下一步直到完成。 3、设置系统环境变量&#xff1a;参考 4、设置JAVA_HOME环境变量 5、在PATH中添加%JAVA_HOME%/bin 6、在命令行中执行&#xff1a;j…...

绘制图形

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 在前3节的实例中&#xff0c;我们一直绘制的都是直线&#xff0c;实际上&#xff0c;海龟绘图还可以绘制其他形状的图形&#xff0c;如圆形、多边形等…...

SpringAop实战(xml文件/纯注解两种方式)

AOP的概述 什么是AOP&#xff1f; 在软件业&#xff0c;AOP为Aspect Oriented Programming的缩写&#xff0c;意为&#xff1a;面向切面编程 • AOP是一种编程范式&#xff0c;隶属于软工范畴&#xff0c;指导开发者如何组织程序结构 • AOP最早由AOP联盟的组织提出的,制定了…...

(八)Linux的进程与线程

多任务处理是指用户可以在同一时间内运行多个应用程序,每个正在执行的程序被称为一个任务。一个任务包含一个或多个完成独立功能的子任务,其中子任务可以是进程或线程。Linux就是一个支持多任务的操作系统,比起单任务系统它的功能增强许多。 一.进程 进程:一个具有独立功…...

Map-JAVA面试常问

1.HashMap底层实现 底层实现在jdk1.7和jdk1.8是不一样的 jdk1.7采用数组加链表的方式实现 jdk1.8采用数组加链表或者红黑树实现 HashMap中每个元素称之为一个哈希桶(bucket),哈希桶包含的内容有以下4项 hash值&#xff08;哈希函数计算出来的值&#xff09; Key value next(…...

TDengine 快速体验(Docker 镜像方式)

简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能&#xff0c;本节首先介绍如何通过 Docker 快速体验 TDengine&#xff0c;然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker&#xff0c;请使用 安装包的方式快…...

应用升级/灾备测试时使用guarantee 闪回点迅速回退

1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间&#xff0c; 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点&#xff0c;不需要开启数据库闪回。…...

Leetcode 3576. Transform Array to All Equal Elements

Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接&#xff1a;3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到&#xf…...

遍历 Map 类型集合的方法汇总

1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...

React Native在HarmonyOS 5.0阅读类应用开发中的实践

一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强&#xff0c;React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 &#xff08;1&#xff09;使用React Native…...

React19源码系列之 事件插件系统

事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...

Psychopy音频的使用

Psychopy音频的使用 本文主要解决以下问题&#xff1a; 指定音频引擎与设备&#xff1b;播放音频文件 本文所使用的环境&#xff1a; Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南

&#x1f680; C extern 关键字深度解析&#xff1a;跨文件编程的终极指南 &#x1f4c5; 更新时间&#xff1a;2025年6月5日 &#x1f3f7;️ 标签&#xff1a;C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言&#x1f525;一、extern 是什么&#xff1f;&…...

Python Ovito统计金刚石结构数量

大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...

MinIO Docker 部署:仅开放一个端口

MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...