📰Những bài viết hay
You Are Not Google
(quangle80)
Là một kỹ sư phần mềm, chúng ta luôn mong muốn áp dụng những công nghệ tối tân, tốt nhất khi bắt tay vào xây dựng một hệ thống. Nhưng chậm lại một nhịp, liệu các công nghệ mà bạn dự định áp dụng (ví dụ như MapReduce, Kafka học từ các Big Tech Google, LinkedIn, v.v…) có thực sự phù hợp với use-case của bạn.
Với góc nhìn “don’t cargo cult” (không tôn sùng bất kì công nghệ nào), tác giả Oz Nova muốn chỉ ra các bước đánh giá UNPHAT để giúp bạn đọc đưa ra quyết định tốt hơn:
Understand the problem: Hiểu vấn đề mà hệ thống đang gặp phải
Numerate multiple candidate solutions: Đánh giá nhiều giải pháp chứ không chọn theo sở thích
Read the Paper: sau khi chọn được giải pháp phù hợp, nghiên cứu thêm các paper, document của công nghệ, giải pháp đã chọn.
Determine the Historical context: đánh giá công nghệ này sinh ra để giải quyết bài toán gì cho doanh nghiệp (Ví dụ LinkedIn xây dựng Kafka để giải quyết hàng tỷ events 1 ngày, chục triệu messages 1 giây, liệu doanh nghiệp của chúng ta có cần thiết phải áp dụng Kafka hay chỉ cần sử dụng công nghệ nào khác)
Weigh Advantages against disadvantages: Cân nhắc ưu và nhược điểm của công nghệ
Think!: cuối cùng tác giả vẫn lặp lại tiêu chí khuyên bạn đọc hãy tỉnh táo và suy ngẫm khách quan xem giải pháp này phù hợp với vấn đề mà bạn đang gặp phải như thế nào
Cùng với một loạt những phân tích cụ thể với các use-case tại Amazon, LinkedIn, mời bạn đọc cùng tham khảo chi tiết tại bài viết.
Protecting Reddit Users in Real Time at Scale
(Steven.do87)
Reddit là một cộng đồng mạng xã hội với hơn 57 triệu người dùng tương tác, đăng tải nội dung và trò chuyện với nhau mỗi ngày. Việc giữ cho nền tảng hoạt động an toàn, ổn định và vẫn có thể kiểm soát một lượng lớn nội dung đăng tải là một thách thức đối với đội ngũ kỹ sư tại Reddit nhằm ngăn chặn, phát hiện và hành động đối với nội dung đăng tải vi phạm chính sách theo thời gian thực.
Vào năm 2016, Reddit đã phát triển một bộ quy tắc (Rule-engine) với tên gọi , Rule-Executor-V1 (REV1), để hạn chế nội dung vi phạm chính sách đăng tải trên nền tảng Reddit theo thời gian thực. Ở cấp độ quản lý, REV1 cho phép nhóm điều hành Hoạt động An toàn của Reddit dễ dàng khởi chạy các quy tắc thực thi áp dụng cho các luồng sự kiện phát sinh trên Reddit, chẳng hạn như khi người dùng tạo bài đăng hoặc nhận xét. Với tiêu chí quan trọng nhất là phải loại bỏ sự phức tạp về kỹ thuật để người dùng cuối có thể tập trung vào việc xây dựng quy tắc. Mặc dù REV1 đã chứng minh hiệu quả trong một khoảng thời gian hoạt động, tuy nhiên theo thời gian dần phát sinh một vài vấn đề mà đội ngũ kỹ sư tại Reddit muốn cải thiện như:
Chạy trên cơ sở hạ tầng kế thừa của các phiên bản EC2 raw thay vì Kubernetes (K8s) vốn đã được áp dụng triển khai làm nền tảng hoạt động cho các dịch vụ hiện tại của Reddit.
Mỗi quy tắc chạy như một quy trình riêng biệt trong một node REV1, dẫn đến cần phải mở rộng theo chiều dọc (vertical scaling) khi nhiều quy tắc được đưa ra, điều này hóa ra là tốn kém và thiếu ổn định.
Chạy trên Python 2.7, một phiên bản Python đã lỗi thời.
Lịch sử thay đổi của một quy tắc rất khó hiển thị vì các quy tắc không được kiểm soát phiên bản.
Thiếu môi trường thử nghiệm (staging) trong đó các quy tắc có thể được chạy thử nghiệm trên dữ liệu thực tế trên môi trường product mà không ảnh hưởng đến người dùng thực tế.
Năm 2021, các kỹ sư tại Reddit đã phát triển một cơ sở hạ tầng streaming mới, với tên gọi là Snooron, được xây dựng dựa trên Flink Stateful Functions để hiện đại hóa kiến trúc của REV1 cũng như hỗ trợ số lượng ngày càng tăng các nhu cầu đảm bảo đáp ứng yêu cầu xử lý luồng dữ liệu. Cùng tham khảo phương án kỹ thuật mà các kỹ sư tại Reddit đã áp dụng tại bài viết.
Designing & Building Metrics
(n^4)
Metric là một trong các khái niệm quan trọng Business Intelligent. Giống như con người có khỏe mạnh hay không có thể được phản ánh thông qua nhiều chỉ số như huyết áp, nhịp tim, đường huyết, oxy, ... Một công ty có phát triển tốt hay không cũng sẽ được thể hiện thông qua những chỉ số đo lường (metric).
Trong thời đại Big data ngày nay, việc tính toán và tổ chức metric cũng sẽ càng ngày càng phức tạp khi quy mô công ty và thị trường ngày càng lớn. Nhiều dữ liệu, nhiều chỉ số phát sinh, vậy thì nên tổ chức và thiết kế hệ thống metrics này như thế nào để giúp trả lời được những câu hỏi nền tảng xoay quanh hoạt động doanh nghiệp một cách nhanh chóng và hiệu quả?
Trong bài techtalk này, chúng ta sẽ cùng tìm hiểu cách các nhóm dữ liệu có thể hỗ trợ tốt nhất cho vòng đời của metrics từ đầu đến cuối:
1. Thiết kế các metrics hữu ích như một phần của cây metrics.
2. Phát triển các metrics này dựa trên hợp đồng dữ liệu tiêu chuẩn và ổn định.
3. Vận hành các metrics để thúc đẩy giá trị.
💭Góc bạn đọc- Một tuần làm việc của EM (p5)
Thứ năm - OKR và lối tư duy impact-oriented
Một hoạt động khác cũng hay diễn ra trong ngày thứ 5 là họp cross platform và OKR review.
Team mình đang phụ trách đang phát triển và vận hành một platform nội bộ. Trong công ty mình có khá nhiều platform như vậy, mỗi platform sẽ chịu trách nhiệm giải quyết một bài toán nào đó cho người dùng nội bộ như gửi message, tạo campaign, tạo data pipeline, ... Một số team platform có liên quan với nhau sẽ gom lại thành một tổ chức lớn hơn. Làm sao để các platform này planning tốt với nhau?
Đối với từng platform thì mỗi 6 tháng, platform đó sẽ phải tự review và đặt ra OKR cho platform của mình để định hình những thứ ưu tiên mà platform muốn xây dựng và đạt được trong 6 tháng tới. OKR là viết tắt cho Objective-Key Result. Việc lập kế hoạch sử dụng OKR thay vì “danh sách tính năng” sẽ giúp platform tập trung vào khía cạnh impact hơn là output của những thứ team platform làm trong 6 tháng tới. Một ví dụ về sự khác biệt này:
Platform A, theo mô hình tính năng, sẽ plan là trong 6 tháng tới sẽ phát triển tính năng cho người dùng schedule những campaign A/B testing song song thay vì tuần tự.
Nhưng khi plan bằng OKR, team platform A sẽ đặt ra mục tiêu là làm sao để tăng được lượng A/B testing campaign diễn ra trong 1 tháng từ 8 campaign lên đến 40 campaign. Key result lúc này là tỉ lệ campaign thực hiện tăng lên 500%. Và giải pháp là xây dựng tính năng như đã nói ở trên.
Việc planning theo OKR như thế này sẽ mang đến nhiều sự thay đổi về mặt tư duy:
Team tập trung vào impact và problem statement hơn. Tránh tình trạng phát triển nhiều tính năng hay, nhưng hóa ra lại không giải quyết được vấn đề cần giải quyết.
Công nghệ đóng vai trò công cụ. Nếu trong quá trình planning team tìm ra được giải pháp khác để đạt được cùng mục tiêu kể trên thì team sẽ cân nhắc thay đổi phương án thay vì bám vào solution ban đầu. Quan trọng là mục tiêu và problem ko đổi, solution có thể đổi. Giống ví dụ trên, nếu team thay đổi góc nhìn, thay vì xây dựng tính năng mới thì lại tìm cách điều chỉnh thiết kế để mỗi campaign A/B testing chạy ngắn hơn chẳng hạn.
Giữa các platform có thể có joint-OKR, gọi là mục tiêu chung cần sự cộng tác của nhiều team. Đặt ra joint-OKR này là một cách để các team commit thời gian và có sự thỏa hiệp tương ứng.
Thứ sáu - Growth day
Công việc hàng ngày của một bạn kỹ sư phần mềm có thể chia thành hai nhóm chính sau:
- Xây dựng phần mềm
- Vận hành phần mềm
Xây dựng phần mềm, bản chất là sử dụng kiến thức và kỹ năng lập trình để tạo ra những dòng mã giúp giải quyết một vấn đề nào đó có trong tổ chức. Vấn đề đó có thể là vấn đề thiên về hướng business ví dụ như xây dựng một tính năng trên app giúp định hướng người dùng, hoặc một vấn đề về vận hành hệ thống ví dụ như xây dựng thuật toán điều hướng background job để tăng throughput....
Để tạo ra được phần mềm đúng thì phải hiểu bản chất nhu cầu tại sao lại cần phần mềm đó để từ đó đưa ra được giải pháp phù hợp. Và để hiểu bản chất của vấn đề mà bản thân đang cần giải quyết, người kỹ sư cần có một lượng kiến thức nhất định trong lĩnh vực tương ứng. Từ đó sẽ phát sinh nhu cầu học hỏi thêm về lĩnh vực mà bản thân đang làm. Ví dụ như làm một hệ thống thiên về marketing thì cũng cần bổ sung kiến thức về marketing để có thể hiểu rõ hơn người dùng và xây phần mềm hữu ích hơn.
Vận hành phần mềm, là theo dõi, kiểm tra, giám sát phần mềm mà bản thân xây dựng để có những can thiệp cần thiết, đảm bảo hệ thống vận hành được thông suốt. Giống như một người kỹ sư điện có thể tham gia thiết kế hệ thống điện trong một tòa nhà, họ cũng có thể tham gia vào quá trình bảo trì, kiểm tra để đảm bảo không có sự cố điện xảy ra.
Công việc hàng ngày của software engineer là phải ra quyết định rất nhiều. Từ những quyết định cơ bản từ việc chọn cấu trúc dữ liệu nào, thiết kế model như thế nào, dùng while hay dùng for, … đến những quyết định dần lớn hơn như phải thiết kế hệ thống gồm những thành phần nào, phải triển khai thành phần nào trước nào sau, … cho đến những quyết định mang tính chiến lược hơn nữa như nên thay đổi những platform nào, những platform nào nên xóa bỏ, những platform nào cần xây mới, … Cấp bậc càng cao trong tổ chức, dù là IC hay manager thì việc ra quyết định càng khó và phức tạp. Tương ứng với việc đó là chi phí phải bỏ ra cho mỗi sai lầm cũng lớn hơn.
Tổng hợp cả ba tình huống trên lại, theo mình người kỹ sư cần không ngừng học hỏi về chuyên môn kỹ thuật, về kiến thức domain của lĩnh vực đang làm, kỹ năng mềm như ra quyết định, ... để hoàn thiện mình hơn. Và ngày thứ 6 sẽ tạm gọi là ngày growth day để bản thân và team có thể dành thêm thời gian để đọc tài liệu nội bộ, post mortem, wiki, product design docs, ...
👨💻Góc lập trình
(by ndaadn and phucnh)
Đề ra tuần này: Rotate Image
Cho mảng 2 chiều n x n. Thực hiện xoay mảng này 90 độ theo chiều kim đồng hồ mà không sử dụng mảng phụ.
Ví dụ:
Input: matrix = [[1,2,3],[4,5,6],[7,8,9]]
Output: [[7,4,1],[8,5,2],[9,6,3]]
Lời giải tuần trước: Split Array Largest Sum
Gọi f(i,j) là giá trị tối ưu thỏa mãn đề bài khi chia mảng con từ vị trí `i` đến cuối mảng thành `j` phần.
Sử dụng đệ quy để tính toán các giá trị này bằng cách thử tất cả các khả năng chia mảng con, tìm giá trị tối ưu nhất sao cho tổng lớn nhất trong số các mảng con là nhỏ nhất khi chia mảng con bắt đầu từ i thành j phần.
Sau đó lưu trữ các giá trị tối ưu đã tính trước đó để tránh tính toán lặp lại trong các lần gọi đệ quy sau. (kỹ thuật này gọi là memoization, thường sử dụng để tối ưu một giải thuật đệ quy thành giải thuật quy hoạch động top down).
Giải thuật cụ thể mời bạn đọc tham khảo lời giải bằng bằng ngôn ngữ Java sau đây.
class Solution {
public int splitArray(int[] nums, int m) {
int n = nums.length;
int[][] memo = new int[n][m + 1];
for (int i = 0; i < n; i++) {
Arrays.fill(memo[i], -1);
}
return splitArrayHelper(nums, 0, m, memo);
}
private int splitArrayHelper(int[] nums, int i, int j, int[][] memo) {
if (j == 1) { // Nếu j = 1, trả về tổng của mảng con đó
int sum = 0;
for (int k = i; k < nums.length; k++) {
sum += nums[k];
}
return sum;
}
if (memo[i][j] != -1) { // Trả về giá trị tối ưu đã tính toán trước đó
return memo[i][j];
}
int minMaxSum = Integer.MAX_VALUE;
int currentSum = 0;
for (int k = i; k <= nums.length - j; k++) {
// Tính toán giá trị currentSum cho cách chia hiện tại
currentSum += nums[k];
// Gọi đệ quy cho cách chia mảng tiếp theo
int maxSumInPartition = Math.max(currentSum, splitArrayHelper(nums, k+1, j-1, memo));
// Trả về giá trị tối ưu nhất (tổng lớn nhất trong số các mảng con là nhỏ nhất khi chia mảng con bắt đầu từ i thành j phần)
minMaxSum = Math.min(minMaxSum, maxSumInPartition);
}
memo[i][j] = minMaxSum;
return minMaxSum;
}
}
Độ phức tạp thuật toán của lời giải trên là O(n^2 m)*, trong đó:
n là số lượng phần tử trong mảng nums.
m là số lượng phân đoạn cần tạo.
Trong hàm splitArrayHelper, chúng ta duyệt qua tất cả các vị trí có thể để chia mảng con và gọi đệ quy cho từng trường hợp. Do đó, chúng ta có O(n) lần lặp, và trong mỗi lần lặp, chúng ta thực hiện O(n) lần đệ quy (vì trong trường hợp xấu nhất, có thể phải chia mảng con từ i đến n). Ngoài ra, chúng ta cũng có O(m) mảng con cần tạo. Vì vậy, tổng độ phức tạp là O(n^2 * m).
Quotes
"Science is a way of thinking more clearly about the world around us."
- Carl Sagan, astronomer and cosmologist -
"Split Array Largest Sum" có thể giải quyết bằng kỹ thuật Chặt Nhị Phân + Tham Lam (Binary Search + Greedy). Độ phức tạp tối ưu chỉ có O(N log M), trong đó N là độ dài của mảng, M là tổng các giá trị.