软件开发故事 - 我对 CTO 撒谎并挽救了项目

在这里插入图片描述

原文:GrumpyOldDev - 2024.04.18

这是几年前的事情了。还记得在我职业生涯的初期,父亲曾告诉我,做好工作往往意味着要在上司的阻碍下做好需要做的事情。他的意思是,你可以让上司成功并感到快乐;也可以让上司做每一个决定,在这种情况下,没有人会成功或快乐。

当时,我在一家财富 500 强公司工作,我们的 CTO 承诺要为一个重要的客户交付一个大项目,他与该客户有私人关系。他还决定将其中的一个关键部分外包给一家大型技术服务公司,该公司声称他们有一款产品可以为我们完成大部分繁重的工作。

在我的职业生涯中,这种情况很常见,当供应商说他们有一款产品时,真正的意思是他们一个隐约类似于产品的东西,在某种程度上符合我们的需求,并且通过大量的定制,他们可以把它改造成我们需要的样子。当然,通过定制他们的“产品”,我们巧妙地结合了供应商软件的所有缺点和定制软件的所有缺点。我们同时实现了“坏主意”中的“圣杯”:一个不灵活的供应商软件包,必须被强迫去做它并未设计去做的事情,还要从他们的主产品代码库中分叉出来 – 一旦供应商意识到维护它的成本有多高,它就会被淘汰。我们彼此抱怨这是一个多么可怕的馊主意,尤其是考虑到供应商在不按时交付产品方面的“良好记录”。

由于 CTO 每年都会更换他的直接下属,每次关于项目的状态都会是一些“老板,这是个好主意”,尽管根本没有人认为这是个好主意。

甚至连一般的主意都算不上。这是一个坏主意。

在这里插入图片描述

项目的其他部分都需要在公司内部进行大量开发,所以我们也有自己的挑战,忙得不可开交。但即便如此,随着整个夏天项目日期的推迟,供应商承诺他们的产品随时都可以集成到 10 月份的发布日期,除了 CTO 之外,其他人都越来越明显地感觉到项目遇到了麻烦。终于在 8 月份,供应商交付了他们的“产品”,我们开始了与之集成的死亡之旅。

9 月份,我们遇到了一个令人沮丧的错误。供应商的产品将每笔客户交易以 json 记录的形式存储在一个巨大的 json 文档中(注:此处的 json 文档存储在 MongoDB Collection)。因此,随着测试数据的积累,产品的性能变得越来越慢。添加一个新的交易需要从数据库中读取整个 json 文档,然后将新记录添加到文档末尾。供应商声称,他们可以通过索引交易字段来解决这个问题,这似乎有点帮助,直到我们遇到了第二个问题。

他们选择的数据库是 MongoDB,而当时 Mongo 的记录限制是每个文档 16MB。因此,到了 10 月份,当实施团队开始将真实的客户数据放入其中时,我们遇到了 16MB 的限制。事情开始变得有趣了起来,我们决定向客户隐瞒这一限制,并推迟一个月上线,但同时启动了一个小型项目来替换供应商集成,而且也没有告诉供应商。因此,我们同时欺骗了客户和重要的技术合作伙伴。

当时的“暴躁老开发者”更像是一个“热情的年轻开发者”,于是他组建了自己的团队来开发替代产品。供应商有 70 多人参与了这个项目,团队只分配了 3 个人来替换它。一个负责设计数据库,一个负责构建与数据库接口的后端,还有一个负责构建业务逻辑/网络服务。

客户被告知,我们将在 1 月份推出新版本供他们测试。新版本将修复他们在最初上线时遇到的最严重缺陷。但他们并不知道我们正在重写整个核心系统。这只用了不到两个月的时间,而原始的项目启动用了一年多的时间。只有 3 个人,还是在假期里(你看这是怎么回事)。

于是,大约在 12 月中旬,所有参与项目的人都被告知(不是要求)要在假期中工作。

要知道,在过去的 6 个月里,我们中的大多数人已经每周工作 60-80 个小时,只为赶上原定(大约)的发布日期。

每个人都累坏了。

此时此刻,如果你正在阅读这篇文章,而且你不是一个以交付为导向的技术人员,可能会觉得这太疯狂了,是时候辞职了。你是对的,但是,我们中的许多人真的很喜欢软件开发,感觉有点像摇滚明星。你花了几个月甚至几年的时间来准备这场“演出”,然后发布日期就像一场表演,你想在发布日期一炮而红。部分原因就像剧院里的人:演出必须继续。但你也想在自己的辛勤工作第一次与真正的用户见面时,感觉自己像个摇滚明星,感受到“我做到了”的快感。人们喜欢我做的事情,我战胜了不可能。对于内向的人来说,软件发布就像是现场表演。

在这里插入图片描述

所以,到这个时候,已经快到圣诞节了。团队基本上用一个月的时间就完成了替代软件的开发,还有一些功能有待完善。但这些开发人员都很聪明,他们一直在按部就班地工作,我知道,如果他们不精疲力竭,我们一定能赶上测试日期。

所以,当 CTO 来找我,说假期被取消时,我说“好吧”…

然后,在我一生中最自豪的时刻,回想起父亲关于不顾上司阻碍完成工作的建议…

我告诉团队中的那三个人,“休息一周,我来搞定。”

每天早上,我都会参加 CTO 强制性的死亡进度电话会议,然后我撒谎:

  • “团队正在努力工作,今天我们达到了第 73 个集成点。”
  • “团队昨天进展顺利,我们又完成了一项网络服务”

每天我都会出现在大老板面前,告诉他我们正在努力工作,而这些工作已经在上个月完成了。

一周后,伙伴们回来了,他们精神焕发。

我们在一月份准时完成了任务,上线后取得了很好的效果,短暂的时间里我们成了“摇滚明星”。也许更像是 Herman’s Hermits,而不是 The Beatles。但是,感觉仍然很好。

这就是我向 CTO 撒谎的经历。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/610926.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux的编译器

程序编译的过程 程序的编译过程是将源代码转换为可执行文件的一系列步骤。这个过程涉及多个阶段,主要包括预处理、编译、汇编和链接。下面详细介绍每个阶段: 1. 预处理(Preprocessing) 在实际编译之前,源代码文件首…

让云上用户拥有安全感 可信或成云服务器标配安全能力之一!

什么是虚拟主机 虚拟主机就是利用网络空间技术,把一台服务器分成许多的“虚拟”的主机,每一台网络空间都具有独立的域名和IP地址,具有完整的Internet服务器功能。网络空间之间完全独立,在外界看来,每一台网络空间和一台…

gpustat 不能使用问题

突然间就不能用了,可能是环境出了问题,如果GPU没问题的话,那么换个环境重新安装试一下(pip install gpustat),目前是换个环境就可以了(做个笔记)

【神器来袭】快速解放双手,朋友圈自动转发工具,告别繁琐操作!

朋友圈作为一个重要的营销推广渠道,如果能实现自动转发,那对于很多企业或个人来说,是极好的。下面,就给大家分享一个实用且便捷的朋友圈运营工具——个微管理系统,让大家都能快速推广。 1、多账号登录,定时…

企业如何有效做好源代码防泄密工作之九种干货分享

企业为解决源码泄密风险问题,许多单位采取拆除光驱软驱、封掉USB接口、限制上网等方法来进行限制;或者安装一些监控软件,监控员工的日常工作,使其不敢轻举妄动;或者安装各种网络信息安全防护产品,如防火墙&…

“幽灵“再临!新型攻击瞄准英特尔CPU;微软Outlook漏洞被俄利用,网络间谍攻击捷克德国实体 | 安全周报0510

1. 微软Outlook漏洞被俄罗斯APT28利用,捷克德国实体遭网络间谍攻击! 捷克和德国于周五透露,他们成为与俄罗斯有关的APT28组织进行的长期网络间谍活动的目标,此举遭到欧洲联盟(E.U.)、北大西洋公约组织&…

深度技术解读AlphaFold3: 谷歌第三代AI工具精准预测生物大分子四级结构

自然界每一种植物、动物和人类细胞内部,都包含有数以亿计的分子机器。这些分子机器由蛋白质、DNA、RNA及其他配体分子组成。正是这些由生物大分子组成的小型机器,维持着生命的运转和延续。从本质上来讲,生命就是建立在分子层面的结构支撑&…

Qt——信号 和 槽

目录 概述 信号和槽的使用 自定义信号和槽 带参数的信号和槽 概述 在Linux系统中,我们也介绍了信号的产生、信号的检测以及信号的处理机制,它就是系统内部的通知机制,也可以是一种进程间通信的方式。在系统中有很多信号,我们可…

探索 Joomla! CMS:打造个性化网站的利器

上周我们的Hostease客户咨询建站服务。他想要用Joomla建站。Hostease提供免费安装Joomla CMS服务。这可以让客户搭建网站变得更加简单和高效。下面是针对Joomla建站的一些使用心得。 Joomla CMS是一款开放自由的软件,为用户提供了创建和维护网站的自由度。它经过全…

MemoryModule - exp - test

文章目录 MemoryModule - exp - test概述笔记测试环境GetModuleFileName不能正常执行GetModuleFileNameWntdll_LdrGetDllFullName猜测原因用LoadLibrary载入的DLL中功能是正常的 gLog可以正常使用内存载入DLL无法支持的功能的折中方法COM操作正常调用方代码接口代码 接口入参测…

AI图书推荐:使用FastAPI框架构建AI服务

《使用FastAPI构建生成式AI服务》(Building Generative AI Services with FastAPI (Early Release) )是一本由Ali Parandeh编写的书籍,计划于2025年3月首次出版,该书以实践为导向,指导读者如何开发具备丰富上下文信息的…

LeetCode 513.找树左下角的值

LeetCode 513.找树左下角的值 1、题目 题目链接:513. 找树左下角的值 给定一个二叉树的 根节点 root,请找出该二叉树的 最底层 最左边 节点的值。 假设二叉树中至少有一个节点。 示例 1: 输入: root [2,1,3] 输出: 1示例 2: 输入: [1,2,3,4,null…

React - Input框绑定动态State和监听onChange事件,输入时失去焦点

React - Input框绑定动态State和监听onChange事件,输入时失去焦点 一. 案例复现二. 解决方案 一. 案例复现 案例代码如下: import React, { useState } from react; import { Table, Input } from antd; const Column Table.Column; const mockData …

5.2 Java全栈开发前端+后端(全栈工程师进阶之路)-服务端框架-Spring框架-相信我看这一篇足够

1.Spring框架 1.1.Spring框架简介 Spring是一个基于java的轻量级的、一站式框架。 虽然Spring是一个轻量级框架,但并不表示它的功能少。实际上,spring是一个庞然大物,包罗万象。 时至今日,Spring已经成为java世界中事实上的标准…

邻域注意力Transformer

邻域注意力(NA),这是第一个高效且可扩展的视觉滑动窗口注意力机制,NA是一种逐像素操作,将自注意力(SA)定位到最近的相邻像素,因此与SA的二次复杂度相比,具有线性时间和空…

QT day5 作业

服务器头文件 #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTcpServer> //服务器类 #include <QTcpSocket> //客户端类 #include <QList> //链表类 #include <QMessageBox> //消息对话框类 #include <QDebu…

Hadoop3:HDFS的架构组成

一、官方文档 我这里学习的是Hadoop3.1.3版本&#xff0c;所以&#xff0c;查看的也是3.1.3版本的文档 Architecture模块最下面 二、HDFS架构介绍 HDFS架构的主要组成部分&#xff0c;是一下四个部分 1、NameNode(NN) 就是Master节点&#xff0c;它是集群管理者。 1、管…

QT+MYSQL数据库处理

1、打印Qt支持的数据库驱动&#xff0c;看是否有MYSQL数据库驱动 qDebug() << QSqlDatabase::drivers(); 有打印结果可知&#xff0c;没有MYSQL数据库的驱动 2、下载MYSQL数据库驱动&#xff0c;查看下面的文章配置&#xff0c;亲测&#xff0c;可以成功 Qt6 配置MySQL…

【教程向】从零开始创建浏览器插件(二)深入理解 Chrome 扩展的 manifest.json 配置文件

第二步&#xff1a;深入理解 Chrome 扩展的 manifest.json 配置文件 上一次我们已经着手完成了一个自己的浏览器插件&#xff0c;链接在这里&#xff1a;我是链接 在本篇博客中&#xff0c;我们将更详细地探讨 Chrome 扩展中的 manifest.json 文件。这个文件是每个浏览器扩展…

UBOOT介绍

一、UBOOT简介 U-boot全称 Universal Boot Loader&#xff0c;是遵循GPL条款的开放源码项目&#xff0c;uboot 是一个裸机代码&#xff0c;可以看作是一个裸机综合例程&#xff0c;执行启动内核的功能。 补充&#xff1a;GPL条款&#xff08;GNU General Public License&…