What are your parameters or mindset or mental model to figure out a technical debt?<p>How do you deal with the tech debt? How do you prioritize the tech debt severity?<p>In general, not restricted only to the computer science field, how is the technical debt described for a particular field?<p>To me, field: computer science - software, any denormalized database object is technical debt, with a severity directly proportional to the amount of additional code being written to manage denormalization.
Tech debt is something that saves time/resources now, at the cost of even more time/resources later.<p>This could include not writing tests, spaghetti code, poorly planned or poorly defined features, and so on.<p>I treat it much like financial debt. The best ones are the ones you might not have to pay off - experimental features that may not be used or that could be replaced.<p>There are some cases where the amount you save vs future cost is really poor, e.g. denormalized database or spaghetti architecture. It's quite a senior/specialist skill to get the right balance.
Technical debt is debt. It provides leverage but accrues interest. Technical debt is wiped away in bankruptcy.<p>The last is important. Technical debt accrued in pursuit of a bad idea goes away when the project is abandoned. For a startup that is scaling rapidly, technical debt goes away because the problems of scale require rewriting even the best tuned small scale code.<p>Even in ordinary business cases, the cost of carrying technical debt is very often lower than the cost of eliminating it. One extra engineer to deal with it, is less expensive and lower risk than rewriting the code base on moral grounds. Carrying it contributes more to the bottom line and cash flow than an effort to eliminate it.
Field: software development<p>A technical debt is anything that slows down either performance and development.<p>It could be:<p>- memory leaks<p>- zombie routines<p>- variable/function/type/endpoints misnomer<p>- out of date comments<p>- unhandled errors<p>- technological goldplates<p>- readability-hindering and overly-strict conventions<p>- non-forward compatibility<p>- unnecessary side effects / mutability<p>- god objects<p>- improper architecture<p>- unclear separation of concern<p>- flow dead-ends<p>- non-scalable storage access strategy<p>- unused data created in memory (seriously, this is annoying. Imagine reading codes like these like this:<p>fn renderSomeHeavyStuff(errorKind: string) {<p><pre><code> let renderables = {
"kindA": someHeavyProcedureA(),
"kindB": someHeavyProcedureB(),
"kindC": someHeavyProcedureC(),
}
return renderables[errorKind]
</code></pre>
}<p>)<p>- structure written imperatively<p>- stories written declaratively<p>- premature abstraction<p>- leaky abstraction<p>- overprotective abstraction<p>- over-complex resource endpoint<p>- under-complex procedure endpoint
IMO there are two types of tech debt.<p>The first is "techincal" debt - which is stuff that gets ignored for the sake of faster delivery but slows down development in the long run. Missing tests, spaghetti code, weird hacks, poor documentation.<p>The second type is "product techincal" debt - stuff that purposely half baked / half delivered for the sake of meeting deadlines. Features that are delivered or bugs that are fixed in less-than optimal ways.<p>I'm much more sympathetic to the second kind. At a certain point you always have to negotiate quality with speed. As long as there is a shared understanding that "this isn't perfect, but we're agreeing to move forward", it can generally be corrected eventually.<p>The first kind is usually the kind that gets piled up though. It's the stuff that causes engineers to want to burn down everything and rebuild, and eventually leads people to quit. Nothing is worse than being forced under time constraints and then realizing you can't implement a new feature without being forced into a major refactor, or spending a week on adding tests that should have been there in the first place. It's this stuff that causes the most stress IMO, because management usually sees it as unnecessary.
Basically, when I look at something and think "ugh". Code which is usually much too long for what it's doing, is hard to follow, or will otherwise likely limit our team's ability to change the product in the future.<p>Due to our small team size and low test coverage, we will almost always leave such code alone until such time that we have the chance to work on the product in earnest (e.g. changing or adding a feature that touches the affected code in some way).
Search for TODO, HACK, etc in the code base to uncover the obvious technical debt.<p>The hidden ones are those undocumented code, workaround, config settings etc that no one understands what it does.