我是怎么把一个项目带崩的

我是一名项目经理,在过去的四个月里,我把一个项目带崩了(上线后频出问题,用户无法使用)。在最近的几天,我每天都在反思自己,我都在问自己以下几个问题:
1.我做错了什么?
2.我在其中占有多重的因素?

以下内容,我将回答以上问题,并在最后说一下我的补救措施。

项目和团队背景

首先给大家说明一下项目背景,以便各位对此项目有更清晰的了解:
1.该项目是一个二次开发项目,第一个基础版本(打印申报系统)也由我带领开发。
2.系统是需要和国家系统对接,有三条主流程。
3.需求频繁变化,由于系统需要对接国家系统,需求方对需求也不甚了解。曾在5月份一个月内需求变更超过8次,都是主流程变更。
4.项目大小按照最初需求估算,约在100人天左右。
5.项目两条主流程无法测试,依赖于外部U盾,但开发过程中并没有U盾。
6.客户现场使用U盾调试和开发时间约为20天左右。
7.我当时同时负责大大小小4个项目,没有进入开发,仅管控进度。
8.团队成员共3名,其中两名是当时开发基础版本的项目成员,他们对此项目较为熟悉。
9.项目推进过程中,需要多次去现场调试测试,由团队中的两名工程师共同前去。

我做错了什么

除了监控进度,还要管理质量

在项目的开发初期,我制定了一份详细的开发计划,用于指导整个开发过程。开发计划交付与了客户,而答应了的事情就要做到,所以在整个项目过程中,我对进度管控很严。我定期检查功能是否完成,定期和客户汇报情况,保证了开发进度顺利推进。但也由此埋下了祸根,仅仅看需求是否完成,而未关注完成的质量如何。

项目质量出现了许多细节性问题。比如:
1.上线后,客户那边发现其中一条主流程都走不下去
2.其中申报功能,系统提示成功。但实际上并没有真的申报成功,申报后在国家系统无法查询到
3.打印功能小问题较多,打印获取的数据错误
4.同步数据的功能无法同步或者同步的数据错误
5.执行时间过长的功能,数据库会强制断开连接
等等问题,就不一一列举

反思:

1.进度和开发速度固然重要,但以质量换速度不可取
2.如果开发时间和质量冲突,优先保质量,毕竟你埋下的坑,总是要坑你自己的
3.再困难的情况下,也要保证基本测试
4.时间极其不允许的情况下,也要保证主线功能顺利执行

既要给予信任,也要保持警惕

项目中的三名成员,都是合格的开发,对使用的框架非常熟悉。其中两名还是基础版本开发成员,对需求也很熟悉。所以项目中,我放心的把整个项目交给了他们。基于对他们的放心,加上其他项目事情繁杂,对此项目关注度,对他们的关注度就不够了。

我在项目中给予了他们非常充分的信任,信任他们可以把一切事情都做好。但我没有在正确的时候给予他们正确的指引,项目中出现的困难点,我也没有帮助他们解决,甚至于没有给出思路。所有的一切,都靠他们自己完成。我在这个项目里做的,就是对接客户,催进度。再无第三件事。

反思:

1.不论什么原因,都要关注到项目成员的状态
2.给予信任没错,但也要适当保持警惕,他们多少会因为经验问题疏忽遗漏一些问题
3.给予信任,也要给予帮助,不以时间为理由推脱你应该对他们进行的指点和帮助。毕竟现在剩下来一分钟,以后要花一个小时去弥补

若无法全局掌控,就指派专人负责

这是我在项目中做的最错误的地方。

由于种种原因,我无法掌握到项目的每个要点和细节。而项目中有三个开发。我并没指明其中某一个来负责整个项目,所有事情都让他们自己商量。从客户对接来的问题,我也是仅告知对应的开发。整个项目中,没有一个人对项目中的每个要点了如指掌。

反思:

1.手里捏着管理的权利,却没有做到管理的事情。是我在这个项目里最大的问题
2.授权!授权!授权!如果自己无法亲力亲为投入项目管理工作,就授权给团队某个成员管理权限,让他代替你去做管理工作
3.管理一人,总比管理多个人轻松,也更有效

要控制需求,更要控制流程

项目是二次开发、成员对项目很熟悉、项目工作量不大、时间紧。

基于以上原因,我掉以轻心,没有在项目初期进行项目的设计和规划,未指定任何开发规范。仅仅告诉开发的同事要多复用,也未检查他们是否真的复用了。

项目开发中的需求变更,客户反馈意见,我我都仅仅是告知他们一声,未做详细的修改规划,所有事情都靠嘴说,所有变动都放在了我和他们的脑子里。

对项目上心程度不够,未对客户的需求变更做控制和管理。所有变更都压给了开发的同事。

整个项目以及其不规范的方式在运行,我也未在其中起到控制作用,项目开发一团乱麻。

反思:

1.不做设计,不进开发
2.以管理工具指导开发进行,开发过程中所有变更、反馈做记录
3.控制需求变更,拒绝不合理的需求
4.需求变更规范化操作,统一变更,而不是直接压给开发

无论什么情况下,都要进行code review

整个项目过去了几乎四个月,我仅仅花了两个多小时简单看了下代码,未指出代码的任何问题。这也导致出问题后来我花了成倍的时间来处理code review的工作,并且项目成型后的代码修改困难。

项目开发过程中,也未让开发间互相进行代码review,也没有进行代码评审会。

其实代码中出现了很多问题,最后检查代码的时候,发现各种命名不规范、代码复用不到位、简单逻辑复杂写等等。而这些问题,很大一部分都是早期未做规定,未指定人负责项目、未进行早期code review造成的。开发各自为战,难免造成代码问题。

代码质量的问题,淋漓尽致的体现的在项目中,项目中的诸多bug,都是因为代码不规范引起的。甚至于开发人员自己对自己写过的东西,都有些拎不清了。

反思:

1.代码质量非常重要,代码越规范bug越少
2.代码互评能让开发更注重自己代码的质量
3.code review非常有必要,越早期的code review越能有效的节省后期的时间

我在其中占有多重的因素

100%

我怎么填坑的

项目上线,问题频出,用户不满。花了8天时间来处理这个问题。幸亏项目不大,我一个人也能够挽回。

目前暂时解决完毕,我简单说一下我是怎么填坑的:
1.和开发主流程的同事详细熟悉了所有需求要点
2.基于我对项目需求的熟悉,我花了三天把所有主流程的所有代码分析完毕,做出了我认为应该的修改,并实施部署到生产环境测试(这是在给开着的飞机换引擎,但需要U盾才能测试,仅有生产环境的机器有U盾,别无他法)
3.每天花超过12个小时来进行code review 和修改,几乎每天code review + 修改到凌晨2点多(仅修改了问题较大且影响较小的地方。小问题未修改、牵涉面较广的地方未修改)
4.每次上班时间的修改让开发同事坐在旁边和我一起进行,我进行修改,开发同事在一旁监督。确保我不出错
5.优化功能点,把我发现的提示问题,和优化点都同步修改进代码中,确保用户体验不要太糟,以期能挽回一些用户心态

我所吸取的教训总结

1.先设计,后开发
2.管理权下放,项目中必须有人全身心负责
3.无论什么情况都要进行code review
4.压缩质量得到的进度保证不可取,开发周期不合理决不答应客户。否则坑了自己坑了同事,更坑了客户


转载于:https://juejin.im/post/5c0672e7e51d451db202c5ba

<think>好的,用户想在Unity 2022中自定义一个名为“即可运行”的功能,可能与Shader ALU统计相关。首先,我需要明确用户的需求到底是什么。根据用户之前的提问,他们之前询问了如何获取Shader的ALU统计信息,现在想进一步自定义一个功能,可能涉及性能监控和自动化处理。 “即可运行”这个名称听起来像是希望在溃或性能问题出现时能够快速恢复或自动处理。结合用户提到的Shader ALU统计,可能用户希望实时监控Shader的性能指标,如ALU指令数,当超过某个阈值时触发某种操作,比如停止渲染或切换简化Shader,防止溃。 接下来,我需要考虑Unity 2022的相关工具和API。之前提到的Shader Variant Collector和Graphics Profiler可能不够,用户需要的是自定义的自动化解决方案。可能需要编写编辑器脚本,利用Unity的Profiler API和ShaderUtil类来获取实时数据。 用户可能希望这个功能在编辑器模式下运行,自动收集数据并做出响应。例如,当检测到某个Shader的ALU指令数过高时,自动记录日志或弹出警告,甚至替换材质。需要确保脚本在编辑模式下无需进入Play模式即可运行,这可以通过EditorApplication.update事件来实现。 另外,需要考虑如何持久化监控配置,比如允许用户设置阈值和监控对象。可能需要创建自定义的EditorWindow,让用户可以配置监控的参数,并保存这些设置。 还需要注意不同平台下的兼容性,以及性能开销,避免监控本身导致编辑器卡顿。可能需要优化数据采集频率,或者使用异步方法来处理。 最后,测试这个功能是否在Unity 2022中有效,确保使用的API在该版本中没有被废弃或更改。例如,ShaderUtil的方法是否有变化,Profiler的数据获取方式是否需要调整。 总结,用户需要的是一个实时监控Shader ALU指令数的工具,能够在超过阈值时触发自定义操作,防止溃,并提高运行效率。需要结合编辑器脚本、性能分析API和用户界面设计来实现。</think>### 在Unity 2022中实现“即可运行”功能(基于Shader ALU统计的自定义性能监控) --- #### 核心需求分析 1. **功能目标** - 实时监控Shader的ALU指令数,若超过预设阈值,触发保护机制(如自动切换低复杂度Shader、停止渲染特定对象或弹出警告)。 - 无需进入Play Mode即可在Editor模式下运行,且支持动态配置监控参数。 2. **技术依赖** - **Unity Editor API**:通过`ShaderUtil`类获取Shader指令数[^1]。 - **性能监控**:结合`Profiler`或自定义编辑器脚本实现实时数据采集。 - **动态配置**:利用`ScriptableObject`或`EditorPrefs`存储监控配置。 --- #### 分步实现方案 ##### 1. 创建Shader ALU监控脚本 通过`ShaderUtil`读取Shader的ALU指令数,并封装为可调用的静态方法: ```csharp using UnityEditor; using UnityEngine; public static class ShaderALUChecker { // 获取指定Shader的ALU指令数(Vertex + Fragment) public static int GetShaderALUCount(Shader shader) { int totalALU = 0; for (int subshader = 0; subshader < ShaderUtil.GetSubshaderCount(shader); subshader++) { int passCount = ShaderUtil.GetPassCount(shader, subshader); for (int pass = 0; pass < passCount; pass++) { totalALU += ShaderUtil.GetShaderPassFragmentInstructionCount(shader, subshader, pass); totalALU += ShaderUtil.GetShaderPassVertexInstructionCount(shader, subshader, pass); } } return totalALU; } } ``` ##### 2. 实现实时监控与保护逻辑 在Editor模式下通过`EditorApplication.update`事件循环检测当前活跃Shader的ALU指令数: ```csharp using UnityEditor; using UnityEngine; public class ALUMonitor : EditorWindow { private static int aluThreshold = 500; // 默认阈值 private static bool isMonitoring = false; [MenuItem("Tools/即可运行/启动监控")] public static void StartMonitoring() { isMonitoring = true; EditorApplication.update += OnUpdate; } [MenuItem("Tools/即可运行/停止监控")] public static void StopMonitoring() { isMonitoring = false; EditorApplication.update -= OnUpdate; } private static void OnUpdate() { if (!isMonitoring) return; // 获取当前场景中所有材质关联的Shader var materials = Resources.FindObjectsOfTypeAll<Material>(); foreach (var mat in materials) { if (mat.shader == null) continue; int aluCount = ShaderALUChecker.GetShaderALUCount(mat.shader); if (aluCount > aluThreshold) { Debug.LogError($"Shader {mat.shader.name} ALU超标: {aluCount} (阈值: {aluThreshold})"); // 触发保护机制(示例:禁用材质) mat.DisableKeyword("_EMISSION"); EditorUtility.SetDirty(mat); } } } } ``` ##### 3. 添加动态配置界面 通过`EditorWindow`提供阈值设置和监控目标筛选: ```csharp public class ALUMonitorConfigWindow : EditorWindow { [MenuItem("Tools/即可运行/配置")] public static void ShowWindow() { GetWindow<ALUMonitorConfigWindow>("监控配置"); } void OnGUI() { aluThreshold = EditorGUILayout.IntField("ALU阈值", aluThreshold); if (GUILayout.Button("保存配置")) { EditorPrefs.SetInt("ALU_Threshold", aluThreshold); } } } ``` ##### 4. 优化与扩展 - **性能优化**:限制检测频率(如每0.5秒检测一次),避免Editor卡顿: ```csharp private static double lastCheckTime; private static void OnUpdate() { if (EditorApplication.timeSinceStartup - lastCheckTime < 0.5) return; lastCheckTime = EditorApplication.timeSinceStartup; // ...原有逻辑 } ``` - **保护机制扩展**:支持自动切换为低性能消耗的Fallback Shader: ```csharp public Shader fallbackShader; if (aluCount > threshold) { mat.shader = fallbackShader; } ``` --- #### 验证与调试 1. **测试场景搭建** - 创建包含不同复杂度Shader的测试材质,手动触发ALU超限条件。 2. **日志与警告系统** - 当检测到超标时,通过`Debug.LogError`输出日志,并高亮相关材质(使用`EditorGUIUtility.PingObject`)。 --- #### 注意事项 1. **平台兼容性** - 不同图形API(如Vulkan、OpenGL)的Shader编译结果可能影响ALU指令数统计,需在目标平台验证[^2]。 2. **Editor性能影响** - 高频检测可能导致Editor卡顿,建议在非开发阶段关闭监控。 --- ### 相关问题 1. 如何通过Unity Profiler的API实现自定义性能指标的实时监控? 2. 在URP/HDRP中,Shader复杂度限制是否有官方推荐的最佳实践? 3. 如何将此类自定义工具打包为Unity Package供团队共享使用? [^1]: Unity 2022中`ShaderUtil`类提供了对Shader指令数的直接访问,但需注意不同版本API差异。 [^2]: 跨平台Shader编译差异可能导致ALU统计波动,建议在目标设备上校准阈值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值