AI 能写代码,但工程架构还是应该由人来定
做 Android 车载开发这些年,我越来越觉得,有些问题并不是代码写出来就算解决了。
尤其是在维护项目里。
有时候只是改一个功能,顺着代码往下看,才发现它还牵涉到另外一个 Service,某个广播又会影响设备状态,状态变化之后还要通知其他模块。改到最后,原本想解决的问题还没处理完,反而发现了几个之前没注意到的隐患。
最近使用 AI 编程工具比较多,我也开始思考一个问题:
既然 AI 已经能够帮我们写代码、分析问题,甚至参与方案设计,那工程师应该把哪些工作交给 AI,哪些事情又应该自己把握?
我的想法是,具体工作可以让 AI 多参与,但工程架构、整体方向和关键决策,还是应该由人来确定。
01. 一个看起来很小的需求,背后可能牵涉好几个模块
普通 Android 开发中,很多需求相对独立。修改一个页面、增加一个按钮,或者调整某个业务逻辑,通常沿着当前模块就能找到入口。
车载项目有时候不太一样。
以设备管理为例,从蓝牙扫描、设备发现、配对,到后续连接和投屏,中间涉及多个状态和模块之间的配合。
一个设备被发现了,不代表它已经配对;配对成功了,也不代表连接已经建立。不同阶段的状态变化,还可能通过广播、回调或者服务接口通知其他模块。
如果只盯着某一个方法,很容易觉得问题已经解决了。
但实际运行时,可能还有另外一个模块没有收到预期的状态,或者某个异常分支没有被处理。
这类问题在维护项目中并不少见。
有些代码单独看没有问题,放到整个业务流程里,就不一定了。
所以我现在接到一个需求时,通常不会马上考虑怎么改代码,而是先弄清楚它涉及哪些模块,现有流程是怎么走的,修改之后会影响哪些地方。
这一步如果没有想清楚,后面写得再快,也可能是在错误的方向上做事情。
02. AI 确实提高了开发效率,但它需要工程上下文
这段时间使用 AI 编程工具,我最大的感受就是效率确实提高了。
以前遇到一个不熟悉的类,需要自己查调用关系、看接口、翻日志。现在可以让 AI 帮忙分析调用流程,解释异常,甚至给出修改建议。
一些重复性的代码,也不需要再完全从头写起。
但我发现一个问题:AI 给出的答案,往往取决于它拿到了多少有效的上下文。
比如一个 Service,单独拿出来看,AI 可以很快理解它的功能。但如果它还依赖另外两个服务,其中一个服务负责设备状态,另一个负责连接管理,那么只看当前类,就很难判断一次修改会不会影响其他模块。
更麻烦的是维护项目中的历史逻辑。
有些判断看起来多余,实际上是为了兼容某些设备;有些接口看起来可以合并,却可能已经被其他模块依赖。
如果这些背景没有交代清楚,AI 很可能会按照当前代码的表面逻辑给出修改建议。
所以我现在越来越重视给 AI 提供工程上下文。
让它先了解模块职责、接口关系、状态流转和现有约束,再去分析具体问题。
AI 可以帮助我们理解项目,但不能因为它给出了一个完整答案,就认为它已经考虑了整个项目的所有情况。
03. 真正麻烦的问题,往往不是代码本身
之前做过一次蓝牙扫描相关的长时间压测。
刚开始运行时一切正常,扫描回调也一直在正常返回。日志里不断打印设备名称、设备 ID 等信息,页面也会跟着刷新。
短时间运行似乎没有什么异常,但测试时间拉长之后,最终还是出现了 OOM。
后来排查发现,高频回调带来的日志输出和刷新操作,也是需要关注的地方。频繁打印日志、反复进行字符串拼接,以及不必要的刷新,都会增加额外开销。
最后通过减少高频日志、降低刷新频率,解决了这次问题。
这件事让我意识到,有些问题不能只从一个方法判断。
代码能不能运行,只是一个方面。长时间运行是否稳定、资源是否持续增长、异常情况下状态能不能恢复,这些同样需要考虑。
AI 可以帮忙检查代码、分析日志,也可以提供性能优化建议。
但如果没有真实的运行数据、压测结果和现场信息,很多判断都只能停留在推测阶段。
这也是为什么我认为,AI 应该参与工程分析,但不能替代工程师对最终结果的判断。
04. 方案可以让 AI 推演,但方向不能完全交给 AI
前段时间和同事一起讨论一个技术方案,遇到过一个比较纠结的问题。
按照其中一个方案处理,会引出另外一个问题;如果优先解决另一个问题,又可能破坏当前的处理逻辑。
当时也让 AI 推演了好几个方向。
它给出的方案并不是完全没有道理,单独看每一种处理方式,都能找到一定的依据。
但把它们放到一起,就发现有些地方根本衔接不上。甚至某些修改还可能让之前修复过的问题重新出现。
后来我逐渐意识到,我们当时缺少的可能不是更多方案,而是一个明确的整体设计。
例如:
- 当前问题的边界到底在哪里?
- 哪个模块负责处理设备状态?
- 服务之间的调用关系应该怎么组织?
- 异常发生之后,状态如何恢复?
- 修改之后,之前的功能会不会受到影响?
这些问题没有弄清楚之前,让 AI 不断生成新方案,其实很难真正解决问题。
我的习惯是先把整体流程理清楚,确定模块职责和接口关系,再让 AI 参与具体实现。
AI 可以提供不同思路,也可以指出设计中的遗漏,但最终选择哪种方案,还是要结合项目现状来决定。
05. 工程架构应该由人来定,AI 负责把事情做得更快
我现在对 AI 编程的理解,越来越接近一种分工。
工程师负责确定方向,AI 负责辅助执行。
比如一个设备管理功能,在开始开发之前,应该先明确设备状态由谁维护,哪些服务负责处理连接,模块之间通过什么接口通信,状态变化如何通知其他模块。
这些属于工程设计,需要结合整个项目来考虑。
确定好之后,AI 就有很多事情可以做了。
它可以帮忙梳理现有代码,分析接口调用关系,补充具体实现,检查异常分支,编写测试代码,甚至从不同角度审查方案。
如果发现现有设计存在问题,也可以让它提供几种调整思路,帮助我们比较不同方案的影响。
但这里有一个前提:我们必须知道自己要解决什么问题。
否则 AI 给出的代码越多,可能只是让一个没有确定方向的方案变得越来越复杂。
我并不认为架构设计就完全不能交给 AI 参与。相反,AI 可以成为一个很好的方案讨论对象。
只是讨论归讨论,最终的架构决策和取舍,应该由了解项目的人来负责。
06. 维护项目尤其不能只看眼前的代码
新项目和维护项目,使用 AI 的方式应该有所区别。
新项目有一定的设计空间,架构、接口和模块职责都可以提前规划。
维护项目则有很多历史包袱。
现有代码可能已经运行了很长时间,有些实现虽然看起来不够漂亮,却承担着兼容和稳定运行的责任。
AI 可能会建议你把某段代码抽象出来,重新设计状态管理,甚至调整整个调用结构。
从代码质量的角度看,这些建议未必有问题。
但对于一个正在维护的项目来说,改动越大,影响范围也越难控制。
我更愿意先明确本次需求的边界,尽量控制修改范围。确实有必要调整架构的地方,再评估依赖关系、兼容性和回归场景。
AI 可以帮助我们完成修改,也可以提醒我们哪些地方值得关注。
但哪些地方可以改,哪些地方不能动,还是需要工程师结合项目实际情况来判断。
毕竟,维护项目最怕的不是代码写得不够漂亮,而是解决了一个问题,又带来了另一个问题。
07. AI 编程之后,工程师需要保留自己的判断能力
最近使用 AI 编程工具越来越多,我也有一个比较明显的感受。
有时候 AI 给出的代码很完整,解释也很清楚,甚至看起来比自己写的还规范。
但如果自己没有真正理解它的实现过程,后续出了问题,还是得重新回来梳理。
这让我觉得,使用 AI 的过程中,有一件事不能丢:自己分析和判断问题的能力。
Android 开发中的 Framework、Binder、Service、Handler、线程、生命周期等基础知识,仍然有必要掌握。
不一定每次开发都要从底层原理开始,但至少应该知道系统为什么这样运行,模块之间为什么这样设计。
特别是车载项目,很多问题并不是单纯修改几行代码就能解决的。
我们需要知道设备状态怎么变化,服务什么时候启动,异常发生之后如何恢复,以及一个模块的修改会不会影响其他模块。
这些能力决定了我们能不能看懂 AI 写出来的代码,也决定了我们能不能判断它给出的方案是否适合当前项目。
写在最后
我并不排斥 AI 编程。
相反,我觉得它确实改变了很多日常开发方式。一些重复性工作、代码实现和问题排查,现在都可以借助 AI 提高效率。
但我不希望自己逐渐变成一个只负责给 AI 提需求、复制代码、检查运行结果的人。
我更愿意把 AI 当成一个可以协作的工具。
具体实现可以交给它,代码分析可以让它参与,方案设计也可以一起讨论。
但项目要往哪个方向走,整体架构怎么组织,模块之间的边界怎么划分,以及最终方案是否符合项目实际情况,这些事情还是应该由工程师来决定。
架构由人定,细节让 AI 做,最终结果由人来把关。
至少在我看来,这才是 AI 编程更合理的使用方式。
本文由 AI图鉴自动抓取并翻译,版权归原作者所有;如需查看原文请点下方链接。
AI can write code, but the structure should still be determined by people.
I've been working on Android all these years, and I'm getting the feeling that some of the problems are not coded and solved.
Especially in maintenance projects.
Sometimes it is only by changing a function, looking down through the code, that it is also found to involve another Service, that one broadcast affects the state of the equipment and that other modules are notified after the change in status. In the end, the problem that was intended to be solved has not yet been resolved, but rather has identified a number of risks that had not been noticed before.
I've been using a lot of AI programming tools lately, and I'm starting to think about one question:
Now that AI has been able to help us write codes, analyse problems, and even participate in programme design, what should the engineer hand over to AI and what should he take care of himself?
My idea is that concrete work can involve AI more, but the structure of the project, the overall direction and the key decision-making should be determined by people.
A demand that looks small and may involve several modules.
In general Android development, many needs are relatively independent. Modifys a page, adds a button, or adjusts a business logic, which usually leads to an entry along the current module.
Car-loading projects are sometimes different.
In the case of equipment management, from bluetooth scanning, equipment discovery, matchmaking, to subsequent connections and screens, there are multiple state and module interfaces.
The fact that a device has been discovered does not mean that it has been paired; it has been paired and the connection has been established. Changes in status at different stages may also result in other modules being notified by broadcast, callback or service interface.
If you look at only one method, it is easy to feel that the problem has been solved.
However, at the time of actual operation, there may be another module that does not receive the expected status or that an abnormal branch is not being processed.
Such issues are not uncommon in maintenance projects.
Some codes can be seen in isolation and placed throughout the business process, which is not necessarily the case.
So when I get a demand, I usually do not immediately consider how to change the code, but first to find out which modules it involves, how the current process goes, and where the changes will affect.
If this step is not clearly thought out, then it may be written as quickly as possible and in the wrong direction.
AI does improve development efficiency, but it requires engineering context
I used the AI programming tool during this time, and my biggest feeling was that it was actually more efficient.
Previously, an unfamiliar category had to check its own call relationships, look at interfaces and turn over logs. Now you can get AI to help analyze the call process, explain anomalies, and even suggest changes.
Some repetitive codes do not need to be written entirely from the beginning.
But I found a question: AI's answer often depends on how much it's got.
Like a Service, look at it alone, and AI can quickly understand its functions. But if it also relies on two other services, one for the state of the equipment and the other for connection management, it is difficult to judge whether a change will affect other modules, depending on the current category.
More troublesome is the historical logic of maintaining the project.
Some of the judgements appear redundant and are actually intended to be compatible with some of the equipment; some of the interfaces appear to be consolidated but may already be relied upon by other modules.
If these contexts are not clear, AI is likely to suggest changes based on the apparent logic of the current code.
So I'm now increasingly focusing on providing AI with engineering context.
It will first understand the functions of the modules, interfaces, state flow and existing constraints before analysing specific issues.
AI can help us understand the project, but it cannot be assumed that it has taken into account all the circumstances of the project as a whole because it gives a complete answer.
The real problem is often not the code itself.
A long-term pressure test associated with a bluetooth scan had previously been performed.
Everything was normal at the beginning of the operation, and the scanned loops had been returning normally. The log keeps printing information about the name of the device, the device ID, and the page is refreshed.
Short run seems to be no anomaly, but after the test has been lengthened, OOM eventually appears.
Subsequent check-ups have found that log output and refreshing operations resulting from HF back-up are also areas of concern. Frequent printing of logs, repeated stringing and unnecessary updating add additional costs.
Finally, the problem was resolved by reducing HF logs and updating frequencies.
This has made me realize that some issues cannot be judged in one way or another.
The code can't run, just one side. The stability of long-term operations, the continued growth of resources and the restoration of the state of affairs in exceptional circumstances also need to be considered.
AI can help check codes, analyze logs and provide recommendations for performance optimization.
However, in the absence of real operational data, pressure measurements and on-site information, many judgements can only remain speculative.
And that's why I think AI should be involved in the engineering analysis, but it's not a substitute for the engineers' judgment of the end result.
The scheme allows AI to advance, but does not give full direction to AI
During the previous period, a technical programme was discussed with colleagues, and a more topical issue was encountered.
Dealing with one of the options raises another problem; if the other were to be addressed as a matter of priority, it could undermine the current logic of treatment.
It also gave AI several directions.
It offers programmes that are not completely unreasonable, and each treatment alone can find a certain basis.
But by putting them together, it turns out that there are places that are simply not connected. Even some of the modifications may lead to the recurrence of problems previously repaired.
Then I became aware that the possibility that we were missing at the time was not more programmes, but a clear overall design.
For example:
- Where are the boundaries of the current problem?
- Which module handles the equipment?
- How should the connection between services be organized?
- After the anomaly, how is the situation restored?
- Will the previous function be affected after the modification?
It's hard to really solve these problems until they're clear, so AI is constantly generating new solutions.
It's my habit to get the whole process clear, to define the modular responsibilities and interfaces, and to involve AI in actual implementation.
AI may provide different ideas or point to gaps in the design, but the final choice is to be made in relation to the status of the project.
The structure of the project should be defined by people, and AI is responsible for doing things faster.
My understanding of AI programming is getting closer and closer to a division of labour.
Engineers are responsible for determining direction and AI for supporting implementation.
For example, a device management function should be developed with clarity as to who maintains the equipment, which services handle connections, what interfaces between modules communicate, and how other modules are notified of changes in status.
These are engineering designs that need to be considered in conjunction with the project as a whole.
Once it's done, AI has a lot to do.
It helps to combo existing codes, analyze interface calls, complement practical realization, check unusual branches, prepare test codes and even review programmes from different angles.
If there are problems with existing design, it can also provide several adjustment ideas that will help us compare the impact of different programmes.
But here's the premise: we have to know what we want to solve.
Otherwise, the more codes AI gives, the more complex it may be to make an unorthodox programme more complex.
I don't think the architecture design can go to AI at all. Instead, AI could be a good target for discussion.
It is only up to the discussion, and the ultimate structural decision-making and trade-offs should be the responsibility of those who know the project.
In particular, maintenance projects should not focus on immediate code
New projects and maintenance projects, using AI, should be different.
There is some design space for the new project, and architecture, interfaces and modular responsibilities can be planned in advance.
The maintenance project has many historical burdens.
Existing codes may have been in operation for a long time, and some of their realization, while not looking good enough, carries the responsibility of compatible and stable operation.
AI might suggest that you abstract a certain code, redesign state management or even adjust the entire call structure.
These recommendations are not necessarily problematic in terms of code quality.
For a project that is being maintained, however, the greater the changes, the greater the scope of the impact.
I would prefer to first clarify the boundaries of this need and try to control the scope of the modification. There is a real need to adapt the structure to assess dependency, compatibility and return scenarios.
AI can help us make the changes, and it can also remind us of what deserves attention.
However, where changes can be made, where no movement can be made, will need to be judged by engineers in relation to the actual circumstances of the project.
After all, it is not the code that is not good enough for the maintenance project, but the solution of one problem and the creation of another.
After AI programming, engineers need to retain their judgement capabilities
I've been using more and more of the AI programming tools recently, and I've had a more obvious feeling.
Sometimes AI gives a complete code, a clear explanation, and even looks more prescriptive than it does.
But if you do not really understand the process of its realization, then there is a problem, and you have to go back and clean up.
And it makes me feel like there's one thing I can't lose in using AI: my ability to analyse and judge problems.
Basic knowledge such as Framework, Binder, Service, Handler, wiring, life cycle, etc., is still needed.
It is not always necessary to start at the bottom of each development, but at least it should be known why the system operates as such and why it is designed between modules.
In particular, in the case of vehicle-borne projects, many of the problems were not solved by simple changes to several lines of codes.
We need to know how the state of the equipment changes, when the service starts, how it recovers after the anomaly, and whether the modification of one module will affect other modules.
These capabilities determine whether we can read the codes that AI wrote, and whether we can judge whether the programs it offers are suitable for the current project.
At the end.
I do not exclude AI programming.
On the contrary, I think it does change a lot of routine development. Some repetitive work, code realization and problem mapping can now be used to improve efficiency through AI.
But I don't want to become a person who's only responsible for asking for AI, copying the code, checking the results.
I prefer to use AI as a tool for collaboration.
Realization can be entrusted to it, code analysis can involve it and programme design can be discussed together.
However, it is up to the engineers to determine which direction the project will go, how the overall structure will be organized, how the boundary between modules will be divided, and whether the final programme will be in line with the project.
The structure is set by people, the details are done by AI, and the end result is closed by people.
At least in my opinion, this is how AI programming works.
Auto-fetched and translated by AI Atlas. All rights belong to the original author.