47 điểm bởi xguru 2023-03-20 | 2 bình luận | Chia sẻ qua WhatsApp
  • Những điều cần có để nhìn nhận nợ kỹ thuật như một công cụ chiến lược
    • Nhận diện và giải quyết các giả định tiêu cực về nợ kỹ thuật
    • Phân loại 6 kiểu nợ kỹ thuật và ứng phó khác nhau với từng loại
    • Xác định quy mô nợ kỹ thuật
    • Cách quyết định mức độ ưu tiên của nợ kỹ thuật

How to Not Manage Tech Debt

  • 4 giả định khiến nợ kỹ thuật bị quản lý sai cách

Giả định #1: nợ kỹ thuật = điều xấu

  • Không nên phân loại mọi khoản nợ kỹ thuật là “xấu”
  • Tốt hơn nhiều là đặt tên cho từng loại, đo mức độ đau đớn và phân loại các khoản nợ kỹ thuật
  • Có những khoản nợ kỹ thuật là điều tốt, và mọi đội ngũ đều nên có nợ kỹ thuật
  • Ví dụ của Twitter về việc “từng có nợ kỹ thuật tốt”: dùng storage công khai rồi sau đó phát triển Manhattan, DB phân tán của riêng mình
  • Những câu hỏi để đối phó với giả định “nợ kỹ thuật = điều xấu”
    • Nếu tích lũy khoản nợ kỹ thuật này bây giờ và xử lý vào tháng sau, ta sẽ đạt được điều gì?
    • Trong tình huống nào ban lãnh đạo sẽ quan tâm đến khoản nợ kỹ thuật này? Cần truyền đạt thông tin gì để giúp CTO thuyết trình với ban lãnh đạo?
    • Sáng kiến này có thể dẫn tới tầm nhìn lớn hơn hay định hướng chiến lược của công ty như thế nào?

Giả định #2: mọi nợ kỹ thuật = công việc phức tạp

  • Cũng như mọi công việc khó khác, có nhiều cách để xử lý công việc phức tạp, không chỉ riêng nợ kỹ thuật
  • Đặc biệt với nợ kỹ thuật, có cách tiếp cận theo công việc Defined/Undefined (đã xác định/chưa xác định)
    • Defined = công việc có điểm bắt đầu và điểm kết thúc
    • Undefined = công việc có điểm bắt đầu nhưng điểm kết thúc không rõ ràng
  • Để đối phó với giả định “nợ kỹ thuật = phức tạp”
    • Hãy làm rõ khoản nợ kỹ thuật trước mắt là Defined hay Undefined
      • Với Defined, cần hiểu thời gian dự kiến để hoàn thành và chừa thêm một chút buffer
      • Với Undefined, hãy liệt kê các điểm chưa rõ để hiểu vì sao việc này phức tạp và không có ngày kết thúc rõ ràng, rồi truyền đạt cho các bên liên quan để xin ý kiến về cách tốt nhất để tiến lên
    • Chia nợ kỹ thuật Undefined thành những phần việc dễ xử lý hơn để giảm độ phức tạp
      • Khi chuyển từ công việc lớn, phức tạp sang những phần việc nhỏ hơn vẫn phức tạp nhưng khả thi, đội ngũ sẽ có thêm động lực để giải quyết từng phần nợ kỹ thuật trong sprint hoặc quý đã định
  • Những câu hỏi để đối phó với giả định “nợ kỹ thuật = công việc phức tạp”
    • Chúng ta đang có những giả định sai nào về hệ thống?
    • Nếu mời một người có kinh nghiệm hoặc quen thuộc với lĩnh vực này vào, những câu hỏi bắt buộc phải hỏi là gì?
    • Đội ngũ của chúng ta có đủ nhân lực và kiến thức phù hợp để làm việc này không? Nếu không thì nên cân nhắc tái phân bổ thông tin/nguồn lực như thế nào, và khi nào là thời điểm lý tưởng nhất để giải quyết vấn đề này?
    • Cách tốt nhất để giải thích độ phức tạp của khoản nợ kỹ thuật này cho một người hoàn toàn không hiểu nó là gì?

Giả định #3: nợ kỹ thuật ≠ công việc sản phẩm

  • Các tổ chức thường rất rõ ràng về việc công việc sản phẩm sẽ cải thiện metric của công ty như thế nào
  • Nhưng nợ kỹ thuật thường bị bỏ sót khỏi đó
  • Giải quyết nợ kỹ thuật đúng lúc có thể rất quan trọng để thúc đẩy tăng trưởng công ty, ngay cả khi chưa thể định lượng ngay lập tức
  • Để đối phó với giả định “nợ kỹ thuật ≠ công việc sản phẩm”
    • Ngay cả khi một khu vực nợ kỹ thuật cụ thể không gắn trực tiếp với metric, hãy suy nghĩ rộng hơn xem nó có thể giúp ích cho trải nghiệm người dùng/sản phẩm nào
    • Thay vì chỉ nhấn mạnh lợi ích kỹ thuật, nếu nhấn mạnh ngang nhau cả lợi ích cho người dùng và sản phẩm thì người khác sẽ dễ hiểu hơn vì sao đội ngũ cần quan tâm tới công việc này
    • Hãy dành thời gian để chắc chắn business lead và technical lead đang on the same page
  • Những câu hỏi để đối phó với giả định “nợ kỹ thuật ≠ công việc sản phẩm”
    • Lý do quan trọng nhất khiến phải làm việc này ngay bây giờ là gì?
    • Những ai cần hiểu tác động của việc này? Vì sao họ nên quan tâm?
    • Điều tôi muốn nói là gì? Nó có khớp với điều stakeholder muốn nghe không? Nếu không thì tôi có thể giải quyết vấn đề của họ như thế nào?
    • Tôi hoặc đội ngũ xem đâu là kết quả hợp lý so với kết quả xuất sắc?
    • Liệu tôi có đang hứa hẹn quá mức về kết quả không? Có thể chia mức kỳ vọng thành “xuất sắc” và “tốt” để cân bằng kỳ vọng không?

Giả định #4: nỗi đau của cá nhân = nỗi đau của tổ chức

  • Các kỹ sư ở gần nợ kỹ thuật thường lặp đi lặp lại rằng việc xử lý nợ kỹ thuật gây đau đớn cho cá nhân họ
  • Với nhân viên, điều đó có thể giống như tận thế, nhưng phần còn lại của tổ chức lại không cảm nhận cùng mức đau đớn đó
  • Điều này thường gặp ở những người ở giai đoạn đầu sự nghiệp, và thường bắt nguồn từ việc thiếu bối cảnh chiến lược rộng hơn
  • Để đối phó với giả định “nỗi đau của cá nhân = nỗi đau của tổ chức”
    • Khi chạm đến một khu vực nợ kỹ thuật có mức ưu tiên cao, hãy dừng lại xem đây là pain point ở cấp cá nhân hay cấp tổ chức
      Thông thường, vấn đề ở cấp tổ chức sẽ tác động trực tiếp đến khách hàng hoặc doanh nghiệp theo một cách nào đó
    • Hãy thử suy nghĩ từ góc nhìn của người có nhiều bối cảnh tổ chức hơn bạn. Cũng có thể giải thích việc này cho người ở đội khác
  • Những câu hỏi để đối phó với giả định “nỗi đau của cá nhân = nỗi đau của tổ chức”
    • Có bao nhiêu đội ngũ được hưởng lợi từ việc phân loại và giải quyết khoản nợ kỹ thuật này?
    • Khi nào công ty từng ghi nhận hoặc thưởng cho người đảm nhận công việc liên quan đến nợ kỹ thuật? Đó là loại nợ kỹ thuật nào và tại sao khi đó nó cần thiết? Có thể nói về cách người đó định vị công việc ấy không?
    • Engineering manager của tôi có hiểu giá trị của công việc nợ kỹ thuật không? Họ có advocate cho đóng góp của tôi trong công việc này khi review hiệu suất không?

6 loại nợ kỹ thuật

  • Maintenance debt (nợ bảo trì)
    • Khi đội ngũ không theo kịp các cập nhật của công nghệ
    • Bao gồm cả việc không xóa dead code sau khi bắt đầu thử nghiệm / rollout tính năng / hủy triển khai, cũng như không cập nhật thư viện, không thêm chú thích cho mã thiếu ngữ cảnh, không tài liệu hóa các quyết định triển khai
    • Ví dụ) thử nghiệm tính năng “log in with Spotify”, sau đó hủy nhưng không xóa phần mã liên quan
  • Developer efficiency debt (nợ hiệu suất của lập trình viên)
    • Khi công ty không có hệ thống test, monitoring, cảnh báo phù hợp cho sản phẩm
    • Đây là loại nợ phổ biến khi workflow kỹ thuật cực kỳ kém hiệu quả, deploy/build mất hàng giờ hoặc hàng ngày, và lập trình viên không phát hiện được vấn đề kỹ thuật trước khi lên production
    • Ví dụ) tổ chức tăng từ 15 lên 50 người trong một năm, khiến quá nhiều thử nghiệm được tiến hành. Các bản phát hành sửa bug phát hiện trên production bị chậm 2-3 đợt. Các bài test mới cho trải nghiệm mua hàng tiếp tục bị đẩy lùi
  • Stability debt (nợ ổn định)
    • Khi nhiều loại nợ kỹ thuật tích lũy trong tổ chức bắt đầu ảnh hưởng đến độ ổn định của hạ tầng
    • Thay vì quản lý on-call từ trước, tổ chức rơi vào kịch bản chỉ gọi chuyên gia vào sau khi sự cố xảy ra, hoặc cả đội đều phải on-call
    • Đây là cơn đau đầu lớn với kỹ sư và đội xoay vòng on-call, nhưng với phần còn lại của công ty thì gần như không thể nắm được hay giải thích vấn đề
    • Nợ ổn định cũng ảnh hưởng đến độ tin cậy của sản phẩm, tạo ra các vấn đề mà khách hàng phải đối mặt
    • Ví dụ) đội mobile có nhiều lập trình viên iOS hơn nên ưu tiên iOS hơn ứng dụng Android. Kết quả là app Android thiếu product guideline cho các luồng quan trọng với doanh nghiệp, đồng thời vẫn còn đoạn mã yếu kém (Kryptonite) do bên thứ ba phát triển từ đầu. Vì vậy người dùng Android bị crash khi truy cập tính năng cũ, làm đánh giá trên Google Play đi xuống
  • Security debt (nợ bảo mật)
    • Khi sử dụng tech stack có lỗ hổng bảo mật như brute-force mật khẩu, rò rỉ dữ liệu, v.v.
    • Vì con người khó lên kế hoạch và đánh giá những việc có thể xảy ra (hoặc có thể không xảy ra), nên nhiều tổ chức phát sinh nợ bảo mật
    • Ví dụ) do vấn đề trong quy trình nội bộ của công ty nên không thể cập nhật kịp thời, không vá được lỗ hổng đã biết và làm lộ dữ liệu cá nhân của khách hàng (từ công ty nhỏ cho đến các công ty như Equifax với 140 triệu người bị ảnh hưởng)
  • Technical product debt (nợ kỹ thuật của sản phẩm)
    • Khi tác động tiêu cực lên sản phẩm trở nên rõ ràng
    • Đây là loại nợ dễ thấy và dễ xử lý nhất vì nó ảnh hưởng đến cả người dùng, và mọi đội trong tổ chức đều nhìn thấy tác động tới bán hàng/doanh thu
    • Ví dụ) người dùng mất vài giây để thực hiện một thao tác cụ thể trong sản phẩm. Điều này có thể do nhiều loại nợ gây ra, nhưng nó ảnh hưởng trực tiếp tới trải nghiệm cốt lõi của người dùng
  • Decision debt (nợ quyết định)
    • Khi phải trả giá cho một quyết định kỹ thuật trong quá khứ vì nó sai X% hoặc vì đã đánh đổi về phạm vi, thời gian hay tài nguyên
    • Đây là hình thức nợ kỹ thuật phổ biến nhất
    • Ví dụ) dùng giải pháp bên thứ ba cho một thử nghiệm cụ thể trên website. Sau vài năm tăng trưởng mạnh, nay website có hàng triệu người dùng ghé thăm. Kết quả là đội kỹ thuật, dữ liệu và sản phẩm đều gặp khó khăn mỗi khi muốn thực hiện thí nghiệm phức tạp.
      Điều này tạo ra nợ quyết định vì đội ngũ đã đưa ra quyết định đánh đổi giữa bên thứ ba và tự phát triển. Khi đó có thể là đúng, nhưng giờ đã bắt đầu gây tác động

Xác định quy mô nợ kỹ thuật: Acute vs Systemic

  • Sau khi hiểu các loại nợ kỹ thuật, cần xác định quy mô chi phí để so sánh với giá trị sẽ nhận được
  • Khi đội ngũ hỏi “bao giờ chúng ta mới có thời gian làm nợ kỹ thuật?”, thường rất khó biết xét theo thời gian, suy nghĩ và công sức thì đó là việc nhỏ hay lớn
  • Nợ kỹ thuật Acute (cấp tính)
    • Nợ kỹ thuật tương đối nhỏ
    • Ví dụ) để phát hành tính năng mới, đội ngũ bỏ qua phần việc cho một nền tảng/trình duyệt có quy mô sử dụng nhỏ. Nếu không có việc khác, có thể bổ sung dễ dàng trong vòng 1 ngày
  • Nợ kỹ thuật Systemic (mang tính hệ thống)
    • Nợ kỹ thuật từ lớn đến cực lớn
    • Ví dụ) CTO/nhà sáng lập đã đưa ra quyết định về sản phẩm (gián tiếp là về kỹ thuật) từ 5 năm trước và cả công ty đã xây dựng dựa trên đó. Nếu thay đổi, rất nhiều thứ sẽ bị ảnh hưởng.
      Khoản nợ kỹ thuật này không thể xử lý dễ dàng, và có thể mất từ vài tháng đến vài năm để thay đổi

Ưu tiên nợ kỹ thuật một cách chiến lược

  • Cách cân nhắc và đánh giá linh hoạt
    • Confidence: khả năng cao việc này sẽ dẫn đến vấn đề nghiêm trọng không? thấp/cao
    • Time: khi nào nó sẽ trở thành vấn đề? chưa gấp/gấp
    • Impact to User: nếu không làm, có phát sinh vấn đề về tốc độ/chất lượng làm hại trải nghiệm người dùng không? thấp/cao
    • Sequence: nó có cản trở việc đạt tới milestone quan trọng không? ảnh hưởng nhỏ/chặn hẳn
    • Accumulated debt: chúng ta đã quyết định tích lũy bao nhiêu nợ rồi? ít/nhiều

Danh mục nợ kỹ thuật chiến lược theo giai đoạn tăng trưởng của công ty

  • Traction:
    • Trước Product-Market fit
    • Cần đưa ra quyết định kỹ thuật ưu tiên tốc độ hơn là độ chính xác, ổn định và quy trình. Nợ hiệu suất của lập trình viên ở quy mô lớn
    • Thường có nghĩa là chọn các full-stack framework như Django, Rails, PHP để phát triển nhanh
  • Inflection:
    • Giai đoạn xuất hiện dấu hiệu PMF và sản phẩm chuyển sang vòng lặp có thể mở rộng
    • Đội ngũ nhận ra cần có một số quy trình (nợ hiệu suất của lập trình viên bắt đầu được giải quyết), nhưng vẫn đang cân bằng giữa quy trình nội bộ và trải nghiệm người dùng nên nợ kỹ thuật của sản phẩm tăng lên
  • Scale:
    • Giai đoạn hyper-growth của doanh nghiệp
    • Trong lúc tìm sự cân bằng giữa thực hành/quy trình nội bộ và trải nghiệm người dùng, nợ kỹ thuật của sản phẩm và nợ hiệu suất của lập trình viên bắt đầu giảm và ổn định
    • Do tăng trưởng quá nhanh, nợ bảo mật, nợ bảo trì và nợ quyết định tăng lên
    • Có rất nhiều thay đổi và điều chỉnh trong test automation, hệ thống deploy, monitoring và cảnh báo, logging và instrumentation, test và staging, ETL, v.v.
  • Expansion:
    • Bắt đầu bước vào Saturation. Doanh nghiệp trưởng thành hơn
    • Do lượng lớn mã cũ và các quyết định cũ, nợ bảo trì và nợ quyết định tiếp tục tăng
    • Khi đội ngũ tìm kiếm cơ hội tăng trưởng mới, nợ hiệu suất của lập trình viên lại bắt đầu tăng
    • Nợ kỹ thuật của sản phẩm, nợ bảo mật và nợ ổn định đang dần được cân bằng sau giai đoạn trước

Mẹo quản lý danh mục nợ kỹ thuật

  • Quy trình để giảm lượng nợ kỹ thuật được tạo ra
    • Dù tích lũy nợ kỹ thuật có thể mang tính chiến lược, đôi khi đúng hơn là triển khai quy trình từ sớm để ngăn nợ kỹ thuật phát sinh ngay từ đầu
    • Điều này đặc biệt đúng ở giai đoạn Inflection và Scale, khi nợ hiệu suất của lập trình viên cần giảm dần khi có thêm nhiều kỹ sư gia nhập
    • Khi nợ hiệu suất của lập trình viên giảm, nó có thể được thay thế bằng việc nợ quyết định và nợ bảo trì tăng lên
    • Ví dụ về các quy trình này: review code/PR, tiêu chuẩn monitoring, phê duyệt QA, review kỹ thuật/thiết kế
  • Công cụ để ngăn hình thành một số loại nợ cụ thể
    • Đầu tư vào công cụ nền tảng có thể giúp một số loại nợ không hình thành
    • Đặc biệt quan trọng ở giai đoạn Scale để ngăn vấn đề bảo mật (nợ bảo mật), bug ảnh hưởng đến trải nghiệm người dùng (nợ kỹ thuật của sản phẩm), và sự nhất quán của mã nguồn (nợ hiệu suất của lập trình viên)
    • Ví dụ về các công cụ này: linter và pipeline CI/CD
  • Công việc sprint cho nợ kỹ thuật Reactive & Acute
    • Khi tổ chức đạt tới quy mô cần on-call, sprint on-call nên được dùng để xử lý các sự cố đang cháy hoặc các công việc phản ứng liên quan đến nợ kỹ thuật
    • Bằng cách này, tổ chức có thể xử lý các hạng mục nợ kỹ thuật cấp bách, và đội on-call có thể thật sự hành động với các vấn đề hiện tại/trong quá khứ
    • Việc để on-call xử lý công việc phản ứng đặc biệt quan trọng ở giai đoạn Scale/Expansion của tăng trưởng. Giải quyết nợ kỹ thuật cấp bách sẽ giúp các đội khác tiếp tục xây tính năng/sản phẩm mới và xử lý thêm các khoản nợ khác
  • Công việc roadmap cho nợ kỹ thuật chủ động và mang tính hệ thống
    • Đưa nợ kỹ thuật vào roadmap đòi hỏi nhiều công việc căn chỉnh giữa các đội
    • Ví dụ đưa nợ kỹ thuật vào roadmap: rewrite quy mô lớn, tái cấu trúc hệ thống dữ liệu cho tính năng khách hàng dùng nhiều nhất, định nghĩa và triển khai cảnh báo cho critical path, chuyển đổi hệ thống thanh toán, v.v.

Cách biến nợ kỹ thuật từ gánh nặng thành công cụ chiến lược

  • Thông qua lượng nợ kỹ thuật đã tích lũy, đội ngũ có thể đưa ra các quyết định chiến lược tổng thể về việc sẽ theo đuổi sáng kiến nào
  • Hãy nghĩ về các giả định phổ biến về nợ kỹ thuật mà đội của bạn sẽ gặp. Bạn có phản đối “nợ kỹ thuật = điều xấu” hay “nợ kỹ thuật ≠ công việc sản phẩm” không? Bạn có đang nghe đồng nghiệp nói theo kiểu “nỗi đau của cá nhân = nỗi đau của tổ chức” không?
  • Đừng dùng cụm từ bao quát “nợ kỹ thuật”. Hãy gọi tên là nợ bảo trì, nợ hiệu suất của lập trình viên, nợ ổn định, nợ bảo mật, nợ kỹ thuật của sản phẩm, nợ quyết định
  • Xác định quy mô nợ kỹ thuật để giảm sự mơ hồ. Nó là Acute hay Systemic?
  • Ưu tiên nợ kỹ thuật một cách chiến lược bằng cách so sánh với các lĩnh vực khác trong công ty. Xếp hạng ưu tiên dựa trên các vector như độ chắc chắn, thời gian, tác động tới người dùng, v.v.
  • Hãy tiếp tục tiến hóa và giữ cân bằng danh mục nợ kỹ thuật theo những thay đổi và nhu cầu đi kèm sự tăng trưởng của công ty

2 bình luận

 
roxie 2023-03-24

Tôi nghĩ điều cơ bản nhưng quan trọng nhất là phải chỉ ra thật rõ ràng rằng "đây là nỗi đau của bạn". Dù là bằng con số hay bằng cách nào khác.

Nếu không làm được điều đó thì thực ra, có lẽ, cũng có thể đi đến kết luận rằng đó ngay từ đầu không phải là nợ kỹ thuật.

 
[Bình luận này đã bị ẩn.]