Text
Why time zone is hard (for some people)
At the end of 2022, I left Square and made yet another move to a new company.
Square is a great company. We shared the same mission, build the best ecosystem for merchants (and later became economy empowering).
My team helped build tools to save millions for merchants from fraud, and bad charge-backs, and I am proud to be a part of it.
However, I had one big thing that pulled me back from contributing more to the company: Time-zone.
My team has less than 10 members distributed across 3 time zones PST, EST, and JST. Square has most of its employees located in either PST or EST. To give you a sense of why it’s problematic:
8am (JST) == 3pm (PST) == 6pm (ETS). Monday in JST is Sunday in both EST and PST (which means I can’t collaborate with anyone on Monday)
I’m 100% not a morning person
Look at (1), JST has only 2 or 3 hours of overlap with PST, and almost zero overlaps with EST. This caused the first problem, we need to organize our syncs in the very early morning or very late night of JST (since JST is a minor branch, prioritizing over US time zone which has more people, is a requirement). We picked the “early morning” option, which is bad for me obviously lol.
As a good friend of mine, you suggested a few improvements:
Just become a morning person! Exercise every morning! Problem solved, yay!
Work smarter, use asynchronous communication, read Rework and Remote (books by DHH / Jason)
(1) sounds easy. I did wake up early (to be honest, I must since my kid wakes up early as well to go to daycare). But waking up early, is not necessarily the same as “waking up early and doing tons of work at full speed, using full energy in the morning”.
Imagine every morning
You wake up and a thread of hundred Slack messages is waiting for you.
You take 10 minutes to read through ALL of them to make sure you didn’t miss any important things while helping your kid to go to daycare (of course he doesn’t cooperate).
You eat a break first in 5 minutes and join early Google Meet to discuss things that you just read from Slack.
It takes 2, 3 hours for all the meetings and finally you have some time for yourself, try to write some codes but find that it’s already lunchtime.
You eat lunch, take a break and you find that you’re already out of energy. But you know that you need to work hard, and you try to write some code. But you found that the code that you need to write needs some confirmation from you co-workers who already took off 🤦♂️.
Not all of my days happen like that, but most.
For (2), my team and I did try a lot to address those issues. I feel grateful to my manager as well as my co-workers for being supportive and aligning their schedules to follow our timezone (having meetings at 6 pm everyday is not a pleasant experience).
We also wrote a lot. Square’s culture is obsessed with documents. I wrote much more documents than code. Every discussion of our team started with “where is your design doc”.
I had a list of “blockers” in my notion, which I used to put in Slack scheduler to be sent at the midnight to all stakeholders so that I could check their responses the next day’s morning.
We also had a following-the-sun on-call rotation, with a complex model of primary and sub so that the workload is fairly shared between members, but not so biased that could block our customers who are mostly based in the US.
So what was wrong?
The problem is, my team, and myself is not everything. The company is everything. Dealing with time zones requires the whole company's effort. Many important company meetings happen at our midnight. My role requires a lot of communication across organizations, but communication with other teams is just laggy (every single ping-pong cost us at least a day). Also, our on-call rotation model wasn’t worked well since most customer supports and outages happen in US time zone, which puts more burden on our team there.
Time zone is hard, but time zone with full remote work (and Covid) is much harder. It’s very hard for me to feel being a part of the company. Until I left the company, I still wasn’t able to meet all of my peers who were based in the US, face to face.
I tried to understand the reasons why my company wasn’t the best fit for multi time zones model:
We built the company from the ground up with most of the workforce and customers who are based in a single time zone (or closed time zone).
Our Japan engineer team wasn’t doing Japan-related work, with Japan-based stakeholders, but mostly US-based projects, which just caused a lot of blockers.
Covid blocked us from being more “social”, and prevent us to have offline team all-hands.
Well, I’m not trying to complain or blame anything or anyone. I was just trying to say that remote work, while sounds very fancy and could be awesome for some teams or companies, could just be super hard for others, especially with multiple time zones.
0 notes
Text
Wrap up 2021
Bài viết gần nhất trên blog của tôi là wrap up 2020, thật là trùng hợp!
Trong 1 năm qua tôi đã nhận ra một điều tương đối quan trọng, là đôi khi không làm gì cả cũng là một việc nên làm.
Công việc trong năm qua có thể tóm gọn lại trong 3 từ là “đủ sống sót”. Remote, khác biệt về timezone là những rào cản lớn hơn tôi nghĩ khá nhiều để đem lại được những thành quả trong công việc mà mình có thể tự hào được. Tuy nhiên, mặt tốt ngược lại là tôi cũng học được nhiều về cách communicate với team, về các công việc thiên về chiến lược (strategy), kế hoạch (planning), và giao tiếp (lobbying) nhiều hơn. Nhìn từ ngoài thì có lẽ những công việc trên khá nhàm chán, nhưng nó lại là bắt buộc nếu bạn ở staff level ở các công nghệ Mĩ, và thật sự nó cũng không quá nhàm chán nếu coi những công việc đó là tiền đề cho những project mang lại nhiều impact hơn trong năm sau.
Ngoài công việc, ngược lại tôi thấy mình khá thành công trong năm nay khi lấy được thêm khá nhiều skills.
Lái xe: vốn bị say xe khá nặng, tôi cũng không có nhu cầu lái xe, và từng nghĩ đi tàu và taxi là thừa đủ ở Tokyo rồi. Tuy nhiên sau khi lấy hết dũng khí (+ thời gian) để lấy bằng lái xong, thì việc lái xe đi vòng quanh thật sự rất phê. Xung quanh vùng kanto của Nhật có rất nhiều cung đường đẹp, một bên là núi bên kia là biển, xa xa là núi Phú Sĩ phủ trắng tuyết, mà nếu không có xe thì sẽ không bao giờ thấy được.
Nấu ăn: Rảnh rỗi sinh nông nổi, cũng như việc thích ăn ngon đã làm tôi dành khá nhiều thời gian vào đọc sách nấu ăn, xem youtube cũng như xem anime về nấu ăn. Sau một thời gian thì tôi nhận thấy nấu ăn cũng khá giống lập trình, cũng có một vài nguyên lý, và để có món ăn ngon thì về cơ bản là “mix” các nguyên lý lại với nhau. Bạn nào có hứng thú về nấu ăn thì có thể xem cuốn Cooking For Geeks của Oreilly, hay xem bộ anime Shokugeki No Shoma.
DIY: Cũng giống với lý do tại sao tôi bắt đầu nấu ăn, rảnh rỗi sinh nông nổi, cộng với việc muốn có một ngôi nhà gọn gàng hơn, tôi đã bỏ một chút thời gian để học làm đồ gỗ. Kết quả là một loạt rack treo tường, hộp sạc điện thoại, rack để đồ đã được sinh ra. Về cost performance thì việc tự làm đồ gỗ đắt hơn khá nhiều so với mua đồ làm sẵn (đặc biệt nếu tính cả cost đầu tư ban đầu cho workbench, jigsaw, drill..), tuy nhiên điểm lợi là tôi có thể customize cho bất kì vị trí, hay khoảng trống nào trong nhà, đáp ứng được nhu cầu về “gọn” mà tôi đặt ra ban đầu.
Trading: Mặc dù cũng có biết cũng như có bắt đầu mua index từ 2020, đầu năm 2021 tôi mới bỏ thời gian nhiều hơn để tập tành active trading hơn. Kết luận là active trading sẽ khó có thể mang lại lợi nhuận nhiều hơn các index tốt như SP500 hay VTI. Tuy nhiên cá nhân tôi khá thích thú với việc học được chút gì từ mỗi lần lỗ, cũng như lãi, cũng như có thêm nhiều kiến thức về kinh tế nên việc cố gắng day trade cũng đêm lại nhiều điểm cộng.
Vậy là tôi đã kết thúc 2021 với toàn các thành quả chả liên quan đến công việc :v.
Sau 2 năm không đạt được mục tiêu gì, và biết mình bản tính vốn nhanh chán, năm nay tôi quyết định không đặt mục tiêu gì cả! Hy vọng sẽ đem lại hiệu quả tốt trong năm 2022.
Chúc mừng năm mới cả nhà!
1 note
·
View note
Text
Wrap up, 2020 was a strange year
Năm 2020 quả là một năm kì lạ.
Vì (nhờ) có Covid 19 mà cả thế giới thay đổi, nhiều giá trị cũ bị phá đi, và nhiều giá trị mới được sinh ra.
Bên cạnh covid thì bầu cử tổng thống Mĩ, cháy rừng, BLM, biểu tình HongKong, bitcoin đạt đỉnh 20k$, sự ra đời của kipacast, cũng đem lại một năm 2020 mà tôi nghĩ chương trình táo quân chắc phải kéo dài 7 ngày mới hết chuyện để nói.
Với bản thân tôi thì năm 2020 cũng đem lại nhiều thay đổi. Con trai tôi được 1 tuổi, giờ nó đã biết đi, biết đánh bố nó. Nhờ có Covid mà kế hoạch lúc đầu tôi định nghỉ không lương để ở nhà chơi với nó, thì tôi đã có thì vừa chơi với nó, vừa nhận lương.
Khoảng thời gian từ 0 đến 1 tuổi là khoảng thời gian mà trẻ con thay đổi theo ngày. Vậy nên được quan sát con mình trong khoảng thời gian này với tôi là hết sức quan trọng, ít ra để về sau nó có gấu thì tôi cũng không thể trách mẹ nó được, lỗi tất cả là do tôi...
Năm 2020 cũng là năm tôi chuyển sang công ty mới, sau gần 5 năm gắn bó với LINE. Nếu bạn nào đã đọc kế hoạch 2019 của tôi thì sẽ biết tôi có rất nhiều kế hoạch với LINE, và tràn đầy nhiệt huyết. Vậy nên việc tôi chuyển việc chẳng qua do Covid, tôi không có lỗi.
Mà đọc kĩ lại đống '2020 goals' thì tôi chả làm được gì ngoài việc 'dành nhiều thời gian cho con'. Đúng là hứa thật nhiều thì sẽ thất hứa thật nhiều.
LINE đã cho tôi rất nhiều thứ. Tôi được làm việc cùng nhiều người giỏi hơn tôi rất nhiều. Tôi được có team riêng của bản thân, đủ tự do để tự mình bắt đầu và kết thúc nhiều dự án hay ho. Tôi được đi du lịch đến các trụ sở khác nhau của công ty miễn phí (Seoul, Fukuoka, Kyoto..). Tôi được hiểu thêm về văn hoá, tính cách của người Hàn Quốc (LINE xuất thân là 1 công ty Hàn Quốc). Tôi được đồng hành với một công ty trước khi nó IPO và trải qua thời điểm nó IPO, cho đến khi nó reverse IPO...
Tất nhiên có nhiều điều tôi nghĩ LINE có thể cải thiện, tuy nhiên tôi nghĩ LINE vẫn là một công ty đáng để vào với bất kì engineer nào ở Nhật nói riêng (hay Châu Á nói chung).
Khi tôi bỏ LINE, rất nhiều bạn bè hỏi là tôi "khởi nghiệp à".Bộ trông cái mặt tôi có tướng khởi nghiệp lắm sao. Tôi không chắc tương lai sẽ có ngày đó không, nhưng có một điều tôi chắc chắn, là khởi nghiệp sẽ phải hy sinh rất nhiều thứ. Hy sinh thời gian với gia đình, với bạn bè, hy sinh sức khoẻ, và tùy theo lĩnh vực tôi có thể phải hy sinh cả những giá trị mà từ trước đến nay tôi tôn trọng. Xung quanh bạn bè tôi có những người xây dựng những công ty đến cả nghìn người, tôi nghĩ là họ đã hy sinh rất nhiều thứ và thực sự đáng nể.
Quá trình chuyển việc đến với tôi khá ngẫu nhiên. Tôi nghĩ Covid đã đóng góp lớn vào sự ngẫu nhiên đó khi cho tôi nhiều thời gian rảnh.
Từ trước đến giờ tôi làm chủ yếu ở mấy công ty Nhật bổn với Hàn xẻng, vậy nên lần này tôi nghĩ là làm thử ở công ty Mĩ tho xem các bạn Tây lông có gì hơn các bạn Châu Á da vàng. Động lực đó đã đưa tôi đến với Square.
Có thể không nhiều người ở Việt Nam hay Nhật biết đến Square. Giới thiệu qua một vài đặc điểm nổi bật của Square thì:
Giám đốc của Square là Jack Dorsey, cũng là giám đốc của Twitter. Ấn tượng của tôi với Jack khi vào công ty thì Jack là người thông minh, dễ gần, và nhiều râu.
Square là công ty tiên phong về giải pháp thanh toán offline và gần đây là online (cashapp). Cơ mà thôi cứ gọi là công ty Fintech hàng đầu nghe cho gớm.
Có nhiều lý do tôi chọn Square.
Square làm về Fintech, là lĩnh vực tôi chả biết gì cả. Ngoài thì Fintech nghe nó rất sang mồm, nó kiểu khi nghe bạn làm ngân hàng thì kể cả công việc của bạn có là đi bán thẻ thì người ta cũng tưởng là bạn giàu.
Square qui mô vừa đủ nhỏ (~5000 người), và còn nhiều khoảng trống để phát triển.
Tôi là nhân viên thứ 3 của Square ở Tokyo, nghe nói khi team nhỏ thì bạn sẽ khó bị layoff hơn (ủa hay ngược lại ấy nhỉ...)
Cuối cùng là quá trình phỏng vấn cho tôi thấy tôi muốn làm việc ở đây, cùng những con người đã phỏng vấn tôi.
Vào Square được 3 tháng, tôi thấy măn mắn là hầu hết những gì tôi thấy ở công ty đều không đi trái với tưởng tượng ban đầu.
Vào công ty mới thì kiến thức về lĩnh vực mới + độ phức tạp của business logic cao hơn khá nhiều những gì tôi từng làm. Với cá nhân tôi thì có 2 loại sản phẩm chính là: (1) thiên về kĩ thuật nhưng business logic đơn giản, và (2) thiên về business logic và kĩ thuật không quá khó. Công việc ở LINE thiên về (1), còn công việc mới ở Square thì thiên về (2). Tôi nghĩ mình sẽ học được nhiều ở đây.
Bên cạnh công việc thì năm 2020 cũng là một năm tôi có xuất phát vài dự án mới.
Kipacast là một dự án podcast nhỏ mà tôi hy vọng sẽ đem lại những góc nhìn mới cho những người xung quanh.
Gần đây tôi có suy nghĩ về việc mình muốn trở thành người thế nào. Suy nghĩ một hồi thì tôi muốn trở thành một người buồn cười, hay nói cách khác là một người thú vị. Để làm mọi người cười được quả thực là rất khó. Bởi vậy kipacast thực ra là một dự án để tôi trở thành người thú vị hơn, bằng cách học từ những người thú vị xung quanh, xem họ đọc gì, xem gì, biết gì.
Tuy vậy sau vài số thì tôi nghĩ kipacast có thể trở thành một thứ gì đó lớn hơn là một dự án cá nhân, hy vọng mọi người sẽ tiếp tục ủng hộ về sau.
Bên cạnh kipacast thì tôi cũng có một dự án siêu nhỏ khác, là start paper reading research group cùng với Grokking. Group sau tầm 2 tháng thì đã đọc được tầm 10 paper, chủ yếu từ các hội thảo con của usenix như NSDI, FAST. Tôi nghĩ hình thức hoạt động hiện tại là sustainable và hy vọng năm sau nhóm sẽ có nhiều hoạt động + output hơn.
Vậy là năm 2020 của tôi đã kết thúc vậy đó. Tôi nghĩ mình đã có nhiều măy mắn trong năm nay, trong cái rủi (Covid) thì lại sinh ra những may mắn khác.
Tôi thấy mình may mắn được làm việc trong ngành ít bị ảnh hưởng bởi Covid nhất. Tôi thấy mình may mắn có được ủng hộ nhiều từ gia đình. Tôi may mắn có nhiều bạn bè giỏi xung quanh.
Hy vong năm sau tôi vẫn sẽ có nhiều may mắn như thế, và các bạn cũng vậy.
0 notes
Text
Escaping the build trap (book reading)
Building internal product, a build trap's rabbit hole
I'm an engineer which mostly worked on internal product. In my previous job I built internal observability systems for thousands of LINE's engineers. In my current job I'm building internal platform for thousands of ops member, risk supports.
The hard thing of building internal product is, most people don't see internal product as a "product". Many people think internal product as a "simple tool" which do not need roadmap or proper management, which is just simply wrong. Even many senior managers think internal product as "cost center" (which mostly "spend money" instead of generating revenue), which make the situation even worse.
At the time, lacking of product management knowledge is our team most painful point (failed find 'true' Product Manager role is one of the cause, but finding Product Manager for internal product is mostly impossible in Japan market).
Recently I read a book called Escaping the Build Trap from Mellissa Perri. Reading the book made me feel that I should have read it sooner. The book had some very intuitive and simple guide for people that don't have much experience in Product Management field, to escape from what she called 'build trap', which is a rabbit hole of shipping feature that nobody use, while can't get enough sponsorship from upper manager.
There were many things that I learnt from the book, to name the few:
Product Manager role is to explore the 'what' and the 'why', while the Engineering team (Engineer Manager, Engineer, Project Manager) focus on the 'how' and the 'when'
Any company should know about strategic thinking, how to define vision, goal, and communicate those visions across the company
Any product company should be outcome centric instead of output centric, and know how to measure those outcomes (metrics) is also very important
Book detail
Output centric confusion
Many companies focused on 'output' culture, not 'outcome'. Our previous team did the same.
But the culture came with trade off, we so focused on shipping features, we celebrated big releases, but we mostly forgot to follow up the question Are those features being used??
It’s about confusing output-centric measures of progress with real measures of value.
Product vs Project
The book has a very concise definition of 'product' and 'project'. Confusing between those 2 concepts may easily lead to an organization which just keep creating new project which deliver nothing to users.
A Product is something needed to be nurtured and grown to maturity, this takes a long time. Product are vehicles of value, which deliver value repeatedly to customers and users, without requiring the company to build something new every time
A project is a discrete scope of work that has a particular aim
What product manager do?
In the book Mellissa wrote few things about 'Product Manager' role that I feel very important
One of the biggest misconceptions about the role of a product manager is that they own the entire product and therefore can tell everyone what to build.
Product managers really own the 'why' of what they're building
The title 'Product Manager' is misleading in itself. An effective product manager is not a manager
Those facts are indeed very reasonable. For small team like my previous team, we didn't have a luxury of a dedicated 'Product Manager'. We had only one role 'Engineering Manager' that did almost everything, from Product Roadmap, User Investigation, Mentoring to Technical Architecture.. Wearing many hat is obviously bad so I don't have to explain why it's bad here.
But we have to admit that, NOT many team has resource for a dedicate Product Manager. But even you have to wear many hats with limit team resource, know the boundary of the role is very important to guide you to do correct practice.
Strategy is NOT a plan
When the company pay hundreds of thousands of Dollars for their employees, the biggest expectation from the company is 'Autonomousity'. Autonomy is what allows organizations to scale (which limit to company that build their own product, not outsource company).
But even with high autonomous employees, they can't just sit there and doing things on their own, without any direction. They need framework and vision, which could be translated into 'strategy'
A good product needs a good strategy, not one-time plan.
Good strategy isn’t a detailed plan. It’s a framework that helps you make decisions. Thinking of strategy as a plan is what gets us into the build trap.
So what is strategy, and how to create strategic framework?
A good company strategy should be made up of two parts: the operational framework, or how to keep the day-to-day activities of a company moving; and the strategic framework, or how the company realizes the vision through product and service development in the market
To make up detail strategies, we need something call 'Strategy deployment'
Strategy deployment
Strategies are interconnecting stories told throughout the organization that explain the objective and outcomes, tailored to a specific time frame. We call this act of communicating and aligning those narratives strategy deployment.
Strategy deployment has different appearance across company layers:
The first two are at the company level, whereas the last two are specific to the products or services of the company. Strategy deployment and strategy creation, though, are two different things
Strategy creation
Strategy creation is the process of figuring out which direction the company should act upon and of developing the framework in which people make decisions. Strategies are created at each level and then deployed across the organization.
It's pretty cryptic definition, so I think we could understand strategy creation is
(1) Process of figure out 'what to do' to full fill visions / and resolve intent
(2) A framework of 'how' people iterate their product, make it better
There is well known improvement framework (2) practiced at Toyota called Product Kata
Build and optimize your product
There are multiple steps to optimize your product, starting with Problem
Problem Exploration → Solution Exploration → Building and Optimizing Solution
It’s easy to fall into the trap of solving problems before you find their root causes. We’re all prone to problem solve, even if we don’t know what the problem is
Engineers, since their nature is curiosity, easily fall into building things which solve nothing, just to satisfy their curiosity. So explore the 'why' carefully is one important job of product manager to escape from building trap.
When you know possible 'why', the next important things is explore solution. The word explore has uncertainty inside it, the book suggest few methods:
Concierge: could be understood as a 'manual' solution. Especially useful for B2B product since you don't have to do many things at scale.
Wizard of Oz: could be understood as a 'mock' solution, which 'looks and feels' like real product but behind the scene is all manual. This method is famously employed by Zappos, to build their only shop entirely on WordPress.
Concept Testing: just straight forward as its name, you demonstrate the concepts to the user to gauge their feedback
Despite any method you choose, the most important concept behind the 'Solution Exploration' is its uncertainty, which means that you need to persuade the upper manager to give you enough space to 'explore', to learn and fail.
Product managers need a certain amount of trust from the organization to have room to explore different options.Learning should be at the core of every product-led organization. It should be what drives us as an organization. It’s far wiser to look at funding product development like a venture capitalist (VC). Startups must pitch investors on their vision and on the data they collect to prove that the vision will be viable and profitable in the market
1 note
·
View note
Text
Phim tài liệu "Long Time No See, WuHan"
youtube
Hôm nay tôi vừa được xem một bộ phim tài liệu khá thú vị về thành phố Vũ Hán, nơi được coi là nơi khởi điểm virus Covid19.
Nếu bạn thử tìm kiếm về Vũ Hán trên Internet hay xem trên các trang tin tức thì sẽ thấy hầu hết các tin tiêu cực hoặc liên quan đến chính trị.
Bộ phim tài liệu này là của một đạo diễn người Nhật sống ở Trung Quốc. Cá nhân tôi thì thấy bộ phim này thú vị ở 2 điểm
Cung cấp góc nhìn không thành kiến về Vũ Hán
Các báo chính thống hiện tại, hay đặc biệt là mạng xã hội (Facebook), để tìm được nguồn tin mà không có mục đích chính trị chắc khó hơn tìm kim đáy biển.
Đặc biệt khi nói về Trung Quốc, khi bạn sống ở phương tây hay các nước thân Mĩ, chắc chắn kênh tin của bạn sẽ tràn ngập tin kiểu "Trung Quốc không tôn trọng nhân quyền", "Virus Trung Quốc" blah blah.
Cá nhân tôi nghĩ là để tập thói quen không có thành kiến với bất kì thứ gì, tập không có thành kiến với Trung Quốc có lẽ là bài tập đơn giản và hiệu quả nhất.
Cho góc nhìn về những "con người" cụ thể
Nhìn vào những con người cụ thể đêm đến cho chúng ta một góc nhìn mới hơn, gần gũi hơn và khó có thành kiến.
Bộ phim tài liệu này nói về rất nhiều những con người khác nhau
Một chủ quán trà sữa xinh đẹp bị phá sản vì Covid
Một cặp vợ chồng sắp cưới 6 tháng không được gặp nhau vì Covid
Một nữ y tá thay đổi cuộc sống hoàn toàn sau Covid
Một cô gái bị mất ông, bà cũng như các thành viên thân thiết khác vì Covid
Một người công nhân tham gia vào dự án bệnh viện thần tốc Lôi Thần Sơn (mà anh tham gia vì lương quá cao (6tr VND / ngày)) ...
Cá nhân tôi khi đi du lịch nước ngoài thì cũng hay có thói quen đi xem cuộc sống thường nhật của người dân ở đó thay vì đi tham quan các điểm du lịch nổi tiếng, vậy nên việc được nhìn những con người cụ thể đem lại cho tôi nhiều đồng cảm hơn với thành phố này.
Lời nói cuối
Khi xem xong bộ phim tài liệu này tôi càng thấy rõ quan điểm là con người, vùng đất nào cũng đẹp đẽ cả, chỉ là góc nhìn của chúng ta bị bẻ méo đi bởi "real" fake news, cũng như shitty politians thôi.
3 notes
·
View notes
Text
Note about Eclipse MAT (Memory Analyzer)
MAT is one of most useful tool to analyze Java (or any JVM language heap). Recently I met memory leak in on of my application. If you think GC language like Java should "never" caused memory leak, read this
MAT could be downloaded here.
MAT usage is pretty straight forward so I didn't try to cover details here but simply:
You take a heap dump (using -XX:HeapDumpOnOutOfMemoryError option, or using bundle Hotspot tool like jmap or jconsole)
You download the heapdump to local and open it with MAT
Interestingly in my case my app didn't OOM but just hang and fullGC happen like forever. Here is the GC graph for the case (memory leak cause hang application) if you're interested in:
The graph shows that in the viewpoint of JVM, application required much java heap size over than Xmx somehow, so JVM attempts to create Java heap space by Full GC as last resort, but there were not freed objects. Eventually, frequent FullGC hangs Java application because Java application cannot free objects due to STW.
So in short, jmap just not works in my case, it will just crashed with weird error like:
java.lang.RuntimeException: field "_bmStartWord" not found in type CMSBitMap
So I have to work around by:
Generate core dump using gcore
Using jmap to generate heap dump from core file (see document).jmap is pretty cool huh.
MAT mechanism
It's all about graph traverse
MAT will analyze java heap only, it doesn't care about the native heap which are managed by VM itself.
Basically Java heap is directed graph (digraph) of references. Each ref may heave primitives (integers, longs, bytes..).
There 2 types of reference:
Incoming references can be thought as "parents"
Outgoing references can be thought as "children"
Reason they use incoming and outgoing because children could point back to parent and vice versa.
So basically MAT is a visualize tool help us traverse the heap graph easier, and find the part of the graph which is consuming big portion of memory.
Some other concepts
Shallow heap : the heap of object and its primitive itself (could call it "base" heap may be?)
Retained heap : Shallow heap + lifetime-dependenct outgoing references. The retained heap is just more important, because when you say that, I have 10G heap contains strings, it's just meaningless. We need to know "what point to those strings", and why it keeps those strings so long in the heap.
Dominator tree : We know that heap == graph that we talked about. Dominitor tree is a part of the graph which stand alone and consumes the most memory of the entire heap (so the name "dominator" says it all).
Final words and some tips
So that's all, I think MAT UX is simple enough for you to explore its feature, and below is some of my personal notes about the usage, hope it helpful for you:
Normally the default heap size of MAT (512Mb) will not help you to open big heapdump, to increase it go to app location and edit MemoryAnalyzer.ini (-Xmx option)
cd /Applications/mat.app/Contents/Eclipse sed 's/Xmx512/Xmx4096/g' MemoryAnalyzer.ini
If you try to open 64G heap or 128G heap, I think even your local PC can't afford such a big memory to open the file, you could do the cool trick of MAT is to use its headless mode, and run in your server which has enough DRAM. See link
When you open the heapdump and show its histogram, it show only the basic size of the objects. If you want to see the retained heap size as well, click the calculator icon. The retained heap size as well will help you find which is the real "holder" of big memory chunk.
0 notes
Text
Khảo sát nhỏ về thu nhập engineer tại Nhật
Cách đây khá lâu tôi có nhờ các bạn sinh viên chương trình Việt Nhật làm một khảo sát nhỏ về kĩ sư phần mềm đang làm việc tại Nhật
Lý do sau mãi bao lâu tôi mới publish kết quả này thì lý do lớn nhất là do lười :(
Một lý do khác nữa là bộ câu hỏi ban đầu của tôi khá tồi (tôi nhận ra việc đó sau khi đã khá đông bạn làm nên không thể sửa được), dẫn đến kết quả cuối cùng thiếu nhiều thông tin có thể làm kết quả dễ bị hiểu nhầm.
Vì vậy hy vọng các bạn nào đọc bộ kết quả này thì cần hiểu rằng có những yếu tố có thể ảnh hưởng đến thu nhập mà chưa được hỏi trong bộ câu hỏi này gồm có:
Địa điểm làm việc
Sector công ty ngoài sản phẩm + outsource còn có consultant hay viện nghiên cứu
Số năm làm việc (nhóm người làm khảo sát này là các bạn còn khá trẻ nên các con số có thể bị ảnh hưởng khá lớn bởi yếu tố này)
Vị trí trong công ty
Sau đây là một vài tổng kết cơ bản:
Có 69 bạn tham gia khảo sát
Phân bổ công ty
42% các bạn làm trong các công ty gia công phần mềm (outsource)
58% các bạn làm trong các công ty sản phẩm (trong đó 27% là công ty lớn (đã IPO)) và 31 % là các công ty venture (chưa IPO)
Phân bổ mức lương
43.3% có thu nhập < 500 man
41.8% có thu nhập 500 ~ 800 man
9% có thu nhập 800 ~ 1000 man
6% có thu nhập > 1000 man
Phân bổ mức lương theo sector công ty
Gia công phần mềm:
55% có thu nhập < 500 man
37% có thu nhập 500 ~ 800 man
3 % có thu nhập 800 ~ 1000 man (1 người)
3 % có thu nhập > 1000 man (1 người)
Làm sản phẩm:
34% có thu nhập < 500 man
41% có thu nhập 500 ~ 800 man
12% có thu nhập 800 ~ 1000 man (5 người)
12% có thu nhập > 1000 man (5 người)
Ý định chuyển việc
Gần 48% các bạn không có ý định chuyển việc và 52 % có
Trong 52% các bạn muốn chuyển việc chỉ có 11% các bạn muốn chuyển trong năm nay
Mục tiêu chuyển việc
70% là nhu cầu tăng lương tuy nhiên ngoài lương ra thì mục đích muốn học hỏi cái mới được đề cập khá nhiều
Một vài cảm tưởng cá nhân
Do tôi đã nói ở trên thì việc đối tượng tham gia làm khảo sát có xu hướng
Còn khá trẻ
Không có các bạn làm trong ban giám đốc của các công ty làm gia công
nên con số sẽ có xu hướng thâp hơn thực tế (là người Việt nói chung đang làm trong ngành phần mềm ở Nhật)
Mức lương dưới 500 man, tuy không gọi là quá thấp so với thu nhập của các ngành nghề nói chung ở Nhật (mức median hiện tại là 300 ~ 360man), nhưng trong ngành phần mềm bạn có thể tăng mức lương lên trên 500man một cách khá dễ dàng (dựa vào việc thu mức 500~800 chiếm tỉ lệ xấp xỉ trong bản khảo sát này), chỉ với một chút cố gắng, cộng thêm mong muốn chuyển việc.
Bản khảo sát hiện tại mức trần mới chỉ là > 1000man, tuy nhiên tôi nghĩ là các con số trên mức trần (vd 1500, 2000, 3000) có thể sẽ mang lại nhiều insights hơn, nên tôi thấy khá tiếc khi đã không thêm các con số cho mức trần.
Có một điểm thú vị là trái ngược với suy nghĩ của tôi thì có tới 50% các bạn làm khảo sát không có nhu cầu chuyển việc, nếu có dịp tôi rất muốn làm một khảo sát nữa để xem motivation của mọi người đối với công việc hiện tại là gì.
Anw, hy vọng bạn đọc đã có được thêm một số thông tin hữu ích từ bản khảo sát. Con số cụ thể từ bản khảo sát được công khai tại https://docs.google.com/spreadsheets/d/1HEGY-dN93pjuvLKdxawbOx-9NHnNa9oZuNxhomCgWDA/edit?usp=sharing . Các bạn có thể tuỳ ý sử dụng cho các mục đích cá nhân.
1 note
·
View note
Text
The manager path, book reading #2
It's roughly one year since I became engineer manager of my team.
There are few good things of being of an engineering manager:
You have broader view of the company. The view is indeed useful, even you decide to become back to individual contributor later.
You will enjoy experience of make people do their best for what you aim for the team. The good feeling when your member that you mentored did a superb job could not be explained easily.
Became manager is a good chance for you to "manage" yourself better (by better schedule, better work flow etc)
But beyond all the good things, being an engineering manager for the first time is not a fruitful experience for most people, since you have to "manage" the other "human-being". And things even worse since those "human-being" are engineers, who has strong opinion for "everything", lazy and easy to fed up almost "everything". You'll soon find that the daily job of an engineer manager is nothing except adjustment and setup coordination between members and external teams.
When feeling stress, what i always do is to find some guide through books. I read plenty of books about productivity, and one book really help me to feel less stressful, called The Manager's Path: A Guide for Tech Leaders Navigating Growth and Change.
This book is so good since it written from the view of a person who origin from engineer, and I learn a lot from the book because it has a lot "truths" as well as solution that indeed so true for myself.
It's hard to summary the whole book within this short blog. Just a few short take aways that you may find it's so obvious, but I think reading those take aways will at least make you feel you're doing the right things:
Never be "The people pleaser": the manager who always try to make everyone please, avoid mistake, overpromises and underdelivers, say yes to everyone.
Instead of being "Micromagement", try to delegate effectively, using the team goal to guide people, and establish standards for code and system at early stage.
Become a manager is not a promotion. "New manager" job is just an entry-level job with no seniority on any front.
Try hard to do 1-1 with your member, build connection and trust, give them frequently feedback to get them know that they're doing the right thing.
If there is employee who lack respects you or her/his peers, you may want ask if she/he want to work on your team, if yes, layout what you expect clearly and calmly, if doesn't, process to move her to another team or another company as it's win-win relationship.
Above are just few advices that i randomly picked, there are much more good advices out there in the book, so let's take your own and becoming better engineering manager.
1 note
·
View note
Text
Understand about how to implement (fast) queue (#1)
Background
(I tried to write this blog post in Vietnamese, but after write half of the blog, I realized that half of written text is in english (ノ゚0゚)ノ~ ..)
Recently I wanted to understand better about queue, and how to make a better "unbounded, thread safe queue". If you don't know about queue, you could understand queue as a main data structure to share "work load" or "task" (in another word, producer consumer problem).
My system is written mostly in go. As a go user, the very obvious way to implement unbounded, thread safe is to use go channel
Go channel will serve us very well in most cases and workload, it's not very fast. The problem of slow throughput is pretty obvious since go channel using many centralize lock object, which cause much contention to happen. There is one way to resolve the problem (we're using this method), is to batch the workload into bigger one, to reduce queue contention.
However, since we're still happy with batched workload and go channel, the problem here is very interesting, so I'm realize that thread safe, bounded queue implementation is indeed very interesting topic because it touches many interesting fields in computer science. So that is, that's why I tried to write this blog series.
Implement a queue, why it's hard?
Some simple googling how to implement high performance queue bring me to go github discussion of whether to add decent implementation of unbounded queue to std (container/queue) or not.
The discussion could be summarized into few ideas of why making a queue is hard?:
Variation of situation we would want to use the queue (MPMC, SPMC, MPSC, SPSC)
Variation of features we would the queue to support (push-front or not (dequeue vs queue)? lock-free or not? performance requirement?)
Since we don't want a slow queue, let's presume we want to make it as fast as possible. There are multiple ways to implement a queue:
Linked list
Flat slice or Ring buffer (both could be implemented using array)
Linked-list implementation bring some advantages:
Better lock contention (since the lock contention is only high on tail or head (not both)
Dynamic resizing (since add / remove node require alloc/dealloc a single node only)
However it come in disadvantages:
Memory usage (need 64 bit pointer memory for singly linked-list and 128 bit pointer for doubly linked list per node)
Memory fragment (since alloc happen in realtime, the memory of nodes will not be continuous obviously)
GC pressure (since we will have a lot of pointers to manage, more pointers, more pressure for GC language (java/go))
In opposite, array-backed implementation has totally opposite advantage / disadvantage
Bad: Harder lock method (since we may need to lock the whole array for each enqueue / dequeue ))
Bad: Resizing cost. Most decent resizing method is to double array every time we short of memory, but that will cause high memcopy cost (which is linear to element count).
Good: Contiguous array make a very well performance tradeoff utilizing CPU cache line characteristic. And using array reduce GC pressure a lot, since we only have to manage single pointer of array head.
Grasp some ideas from the giants
Find the optimized implementation that could minimize above disadvantages is hard. Let's see how de-facto implementations of few major languages are doing it. TL;DR most of standard libs don't fancy trick, they just try to do very decent implementation that is bug free and fast enough for most of the cases.
Java's LinkedBlockingQueue
In my daily job, the most queue implementation i've been using is java std LinkedBlockingQueue.
As explained in source code, the queue implementation based on a technique called "two lock queue" with LinkedList backed queue.
https://github.com/openjdk-mirror/jdk7u-jdk/blob/master/src/share/classes/java/util/concurrent/LinkedBlockingQueue.java#L83-L93
A variant of the "two lock queue" algorithm. The putLock gates entry to put (and offer), and has an associated condition for waiting puts. Similarly for the takeLock.
The comment explain it all, we use 2 lock to control the the queue. putlock used to control write (enqueue) path, and takeLock used to control read (dequeue) path. The origin paper is here: Simple, Fast, and Practical Non-Blocking and Blocking Concurrent Queue Algorithms .
public boolean offer(E e) { ..... putLock.lock(); try { if (count.get() < capacity) { enqueue(node); .... } } finally { putLock.unlock(); } } public E take() throws InterruptedException { takeLock.lockInterruptibly(); try { x = dequeue(); ... } finally { takeLock.unlock(); } return x; }
The good thing of queue (compare to stack) is that the concern for read and write is separated, we have 2 different object head and last to control read and write path, we could just easily separate lock for those.
Beside the two-lock technique, the implementation also has some fine-grain control method to reduce lock time. One of the method is to control number of remain items so when producer side call offer (or put), it could signal on-waiting take (or poll) right away. The idea is written in source code as below:
to minimize need for puts to get takeLock and vice-versa, cascading notifies are used. When a put notices that it has enabled at least one take, it signals taker. That taker in turn signals others if more items have been entered since the signal. And symmetrically for takes signalling puts.
private final Condition notEmpty = takeLock.newCondition(); public boolean offer(E e) { ..... if (c == 0) notEmpty.signal(); ..... } public E take() throws InterruptedException { ..... try { while (count.get() == 0) { notEmpty.await(); } x = dequeue(); .... } .... }
So that is, LinkedBlockingQueue idea is so simple. To use the queue as MPMC task queue, LinkedBlockingQueue is definitely better than other implementation like ArrayBlockingQueue, since ArrayBlockingQueue try to lock the whole queue for every single put or take.
LinkedBlockingQueue serves us very well for years, even for now. LinkedBlockingQueue is also very convenient in term of specification, since it block consumer or producer when the queue is empty or full, which reduce cost for us to implement to spin wait ourself. However the question still remain, do we have better idea or implementation, which will be talked at next part of this serie, so stay tune :).
1 note
·
View note
Text
Book reading #1
Recently I read 2 books
One is The Subtle Art of Not Giving a F*ck: A Counterintuitive Approach to Living a Good Life and the other is The Denial of Death.
Boths are interesting as it somehow give us some "rules" which could make us live a better life, as well as understand a little bit about the implicit motivation which drives our every day action.
Some short take away / quotes come from The Subtle Art of Not Giving a F*ck: A Counterintuitive Approach to Living a Good Life that may be helpful for some people
A true and accurate measurement of one’s elf-worth is how people feel about the negative aspects of themselves
Happiness comes from solving problems
Wanting positive experience is a negative experience; accepting negative experience is a positive experience
You're not special. The rare people who do become truly exceptional at something do so not because they believe they’re exceptional. They become amazing because they’re obsessed with improvement
We can be truly successful only at something we’re willing to fail at. If we’re unwilling to fail, then we’re unwilling to succeed
In other side, The Denial of Death give us some insight of how people control the fear of the dead, is to pursuit of “immortality projects” (or causa sui), "projects that allow our conceptual self to live on way past the point of our physical death.".
In doing so, we feel that we become heroic and part of something eternal that will never die, compared to the physical body that will eventually die.
But the book said that, “immortality projects” are not the solution, but indeed the problem, which may lead to mental illness when your "immotarlity projects" failed. In common sense we're care too much about your "identity" as well as how people evaluate us.
Instead answer questions
"What is your legacy?" "How will the world be different and better when you’re gone?"
seems like a better help instead of trying to do "immortality projects"
Last word, I realize one practical use of how to not giving a f*ck, that is when you don't care about are people gonna click "like" your blog or not ¯_(ツ)_/¯, it helps your become better blogger by able to write more and faster.
1 note
·
View note
Text
May mắn
Chị Thuỷ (muối), cô gái được ví là "nữ hoàng khởi nghiệp Việt" đã qua đời sau 3 năm chống chọi kiên cường với căn bệnh ung thư phổi giai đoạn cuối.
Báo chí đã nói hết những gì tôi có thể nói về chị.
Chị xinh đẹp, chị dũng cảm, chị là nguồn cảm hứng của hàng triệu người người, chị giúp hàng ngàn người sống tốt hơn.
Tuy nhiên, tạm gác các cảm xúc về buồn hay tiếc nuối, tôi muốn nói một chút về "may mắn".
May mắn không có gì hơn là cảm nhận cá nhân.
Một người bán vé số dạo "cảm thấy" họ may mắn khi họ bán được nhiều vé hơn ngày thường.
M���t cô bé học sinh "cảm thấy" may mắn khi mình được điểm cao ở một môn mà mình không hề giỏi
Cách dễ dàng nhất để bạn cảm thấy may mắn chính là trải qua những trải nghiệm tồi tệ.
Với một gia đình, việc có con đầu lòng có thể là một niềm vui, và chỉ dừng lại ở đó. Tuy nhiên với một gia dình đã từng trải qua việc xảy thai (gia đình tôi là một ví dụ), thì việc con của họ được sinh ra khoẻ mạnh thì họ sẽ cảm thấy họ thật sự may mắn, khiến họ trân trọng đứa con của mình hơn gấp nhiều lần.
Khi bạn được ngồi trong phòng điều hoà, đọc được blog này, thì bạn đã là một người may mắn lắm rồi. Bạn may có mắt để đọc. Bạn có internet để sử dụng. Bạn may mắn vì không có ai thả bom vào giữa nhà bạn vào ban đêm (như ở Trung Đông).
Việc chị Thuỷ ra đi làm tôi cảm thấy rằng mình quá may mắn, vì tôi vẫn còn được sống, tôi còn thời gian để làm làm những gì mình muốn, cũng như những gì mình thấy có ích. Tôi may mắn vì được biết về chị, để thấy rằng chỉ với khoảng thời gian hữu hạn, con người ta có thể làm được những điều to lớn đến thế nào.
Tôi thấy rằng những điều tiêu cực xẩy ra xung quanh, thường là do con người có xu hướng cảm thấy mình kém may, thay vì ngược lại. Bạn cãi lôn với sếp vì bạn nghĩ bạn không được đánh giá cao bằng đồng nghiệp. Bạn nổi cáu vì trong một ngày trời mưa vì bạn muốn trời nắng để được đi công viên.
Chỉ cần bạn thấy rằng mình đã quá may mắn với tất cả mọi thứ bạn có được, thì cuộc sống của bạn, và cả những người xung quanh cũng sẽ trở nên tích cực và vui vẻ hơn nhiều lần.
Nghĩ lại thì việc tôi viết được blog này đến dòng cuối này, cũng đã là quá may mắn rồi, vì thằng cu nhà tôi đêm nay không quấy khóc :P.
2 notes
·
View notes
Text
# Load average, again
Do you have experience operate a linux server? If yes, you must already heard about a metrics called "load average". Along with CPU Usage, Load Average pretty much being used as de-facto standard metrics to answer a question: How busy CPUs of a server is.
When we mention "busy", there are 2 aspects:
Utilization: how much the CPUs are being used
Saturation: how much the CPUs are being "over used"
Those 2 aspects included in a method called USE (http://www.brendangregg.com/usemethod.html) which is widely adopted in performance analyzing methodology. Load Average represent the second aspect: Saturation.
Why I used the word "again" in the title? My friend already wrote a pretty good article explained about the concept in Vietnamese. https://kipalog.com/posts/Tai-trung-binh
Reading above article, you could summary few things:
Load average could be checked using top or uptime command in linux
Load average is represented as 3 number : 1min, 5min and 15min
Load average represent the saturation in ALL cores.
Load average / number of cores represent the average saturation in each core, we call it ratio. In many case, the ratio > 1.5 say that: your server is overloaded, and it will cause degration in performance very soon.
I understood the concept very well, so what?
I maintain a pretty large scale service at my company, which serves a magnitude of millions write per second. When you service is big, you may want to utilize the hardware as much as possible. Utilizing, means that you want the CPU being "as busy as possible". To do that, we tried to parallel tasks as possible (we're using golang , and luckily golang do the parallel job very good).
We were success to utilize our CPUs, some how
Utilizing CPUs means that your system load average always in high watermark
$lscpu Architecture: x86_64 CPU op-mode(s): 32-bit, 64-bit Byte Order: Little Endian CPU(s): 40 On-line CPU(s) list: 0-39 Thread(s) per core: 2 Core(s) per socket: 10 Socket(s): 2
Taking that my server CPU has 40 cores, so above graph means that Load Average Ratio is just around 1. 1 < 1.5, so it should be totally fine? right? right? right..
So here is my problem, I could not tell with confident that, it is totally fine.
Looking around the internet could not answer my question: what is the real DANGEROUS line of my system.
The DANGEROUS line means that, if my system go above the line, I need to add more servers, or somebody need to take CPU profile to see what's going on. In another word, I need a number bind to load average to set alert.
After searching for a while, Brendan gave me an answer in his awesome blog: http://www.brendangregg.com/blog/2017-08-08/linux-load-averages.html
The answer is even simpler than a concrete number:
There is no number!
You could read the above blog for details, but here is the summary:
Load Average in Linux system is NOT only about the CPU, but also anothe resources (DiskIO...)
LoadAvg source code include a comment from its maintainer
This file contains the magic bits required to compute the global loadavg figure. Its a silly number but people think its important. We go through great pains to make it work on big machines and tickless kernels.
So how could we decide the DANGEROUS line?
Brendan suggested some alternative tools:
per-CPU utilization: eg, using mpstat -P ALL 1
per-process CPU utilization: eg, top, pidstat 1, etc.
per-thread run queue (scheduler) latency: eg, in /proc/PID/schedstats, delaystats, perf sched
CPU run queue latency: eg, in /proc/schedstat, perf sched, my runqlat bcc tool.
CPU run queue length: eg, using vmstat 1 and the 'r' column, or my runqlen bcc tool.
In my usecase, /proc/schedstat and vmstat's r column give me pretty much what I want which is: Is my CPUs are being overloaded?
1 note
·
View note
Text
2019 summary
Highlight
Together with linxgnu we successfully built and released our in house Time Series Database called Flash (slide below), which serving ~ 300 millions datapoints per minute currently.
My son (Minh Duong) was born! (big love to my wife and my families).
Became LINE JP's company wide observability team's manager.
Public speaking
LINE.go tokyo slide
Fukuoka go conference: slide
Go 1.13 release event: slide
Architecture night: slide
LINE Dev day: slide
2020 goals
More opensource (public some internal tools as well as being main contributor for big impact OSS).
More blogs + reading
More time with my son
More impacts with LINE's observability team (we have a lot of big plans this year)
0 notes
Text
Tìm đồng nghiệp thật khó
Gần đây tôi tham gia phỏng vấn tuyển dụng cho team mình (lẫn cho công ty) khá nhiếu. Càng làm tôi càng thấy tìm được một đồng nghiệp tốt đã khó, tìm ra một đồng nghiệp hoàn hảo gần như là không thể.
Phỏng vấn tuyển dụng là một qui trình khá căng thẳng, cho cả hai phía. Bạn có thể coi tuyển dụng cũng như kết hôn, khi hai người không hợp nhau nằm chung giường, thì dĩ nhiên sẽ khó có đứa trẻ nào được sinh ra.
Để tìm được bạn đồng nghiệp đáng yêu mà bạn muốn làm việc cùng hàng ngày, tương tự như tìm vợ, yếu tố lớn nhất là “may mắn”. Tuy nhiên khi đã may mắn, để gặp được người phù hợp, bạn nên làm thế nào để họ về chung một nhà, cũng như ngược lại khi gặp một người cố tình tán bạn nhưng lại thực sự không phù hợp, làm thế nào để không bị nhìn nhầm.
Nếu so sánh 2 nguy cơ: loại mất đồng nghiệp tốt (false positive), và phải làm việc cùng đồng nghiệp tồi (false negative) thì nguy cơ thứ hai gây ra hậu quả trầm trọng hơn rất nhiều.
Vậy làm thế nào để giảm nguy cơ thứ hai xuống tối thiểu?
Câu trả lời là không có câu trả lời! Ah mà thực ra là có câu trả lời nhưng nó giống như NP problem vậy. Tuy nhiên cá nhân tôi có đúc rút được một số cách để giảm thiểu nguy cơ thứ 2 (loại đồng nghiệp xấu).
Cách 1: Structured interview
Tôi biết khá nhiều công ty, có khi phải lên đến 90% các công ty tôi biết là phỏng vấn theo phong cách giáo sư xoay, hay còn gọi là ngẫu hứng. Riêng định nghĩa của từ “ngẫu hứng” đã có tính chất bất định. Structured interview đơn giản là một bộ câu hỏi có chuẩn bị trước. Độ sâu của câu hỏi tất nhiên sẽ tuỳ vào kiến thức của ứng viên, nhưng việc nó có cấu trúc sẽ giúp rất nhiều vào việc không bỏ sót nhưng điểm nhỏ mà đến lúc làm việc cùng bạn mới nhận ra.
Ngoài ra có một ưu điểm quan trọng của cách này là, nó giúp tránh các thiên kiến. Là engineer bạn sẽ có rất nhiều sở thích, nhưng không có nghĩa bạn đem sở thích đó vào phỏng vấn. Việc bạn thích compiler hay low level programming rất dễ dẫn đến xu hương đem các vấn đề đó vào phỏng vấn, cũng như dễ làm bạn có thiện cảm với người có kiến thức sâu về các mảng này, mặc dù không chắc mảng đó có liên quan đến công việc hiện tại.
Cách 2: Chú trọng system design test hơn algorithm test
Tôi nghĩ algorithm test là một qui trình rất quan trọng để kiểm chứng 2 điểm: một là bạn có “biết code” hay không, hai là bạn có biết cách giải thích các suy nghĩ của mình một cách dễ hiểu không. Cả 2 điểm đều quan trọng, với tôi thì điểm thứ 2 (communication) quan trọng hơn.
Tuy nhiên algorithm test không khó để luyện tập, có rất nhiều tài liệu trên mạng mà bạn có thể dễ dàng tìm thấy. Ở một số nước như India hày US thì các practice về algorithm test hầu như ai cũng nắm rõ. Tất cả những ứng viên tôi phỏng vấn đến từ 2 nước này đều dễ dàng pass algorithm test với các câu trả lời “đẹp như sách” (tất nhiên lý do có thể bao gồm algorithm test của công ty tôi chưa đủ khó nữa).
Vì vậy cá nhân tôi thấy algorithm test chỉ nên chiếm tỉ trọng 10~15% trong việc quyết định hire/no hire. Thay vào đó các câu hỏi liên quan đến system design nên được tăng tỉ trọng thêm. Các câu hỏi liên quan đến system design nên gần gũi với các project hàng ngày của team bạn, thay vì dùng các mẫu câu hỏi tìm được trên mạng. Nếu bạn đang làm ecommerce thì nên hỏi cách thiết kế payment gateway, nếu bạn đang làm storage team thì nên hỏi về cách làm một database đơn giản.
Cách 3: Tìm người có thể thay đổi tình trạng hiện tại thay vì tìm người để giao việc
Tuỳ vào từng giai đoạn của công ty bạn có thể có nhu cầu tìm người khác nhau. Khi công ty ở giai đoạn prototyping có thể bạn sẽ nghĩ rằng chỉ cần một lập trình viên làng nhàng có thể hoàn thành feature sớm nhất có thể. Cách nghĩ đó là hoàn toàn sai lầm. Bạn có thể tuyển một bạn sinh viên mới ra trường, chưa có kĩ năng nhưng có tiềm năng lớn hơn là tuyển một bạn “senior” kinh nghiệm 10x1 năm. (10 năm làm cùng 1 công việc).
Nói thì dễ nhưng việc nhìn ra “tiềm năng” từ một người khó vô cùng. Cá nhân tôi, định nghĩa “tiềm năng” chính là việc người đó có khả năng “thay đổi”. Dù tình trạng hiện tại có tồi tệ đến đâu, luôn luôn có những thứ có thể làm cho tốt hơn. Khả năng thay đổi mọi thứ có thể ví giống như “Midas gold touch”. Một người không thoả mãn với hiện tại, và có khả năng thực thi để thay đổi hiện tại luôn là một người bạn muốn có mặt trong team mình. Chính vì vậy một câu hỏi ưa thích của tôi khi phỏng vấn là “bạn đã làm gì để cải tiến team của mình” và “bạn tự hào nhất với project nào của mình”.
Cách 4: Xoá bỏ các định kiến (bias)
Con gái không biết code đc, ứng viên đến từ Sillicon Valley là hoàn hảo… là hàng loạt các định kiến mà hầu hết các công ty công nghệ đếu có. Bạn có thể không nói rõ các định kiến đó ra miệng, nhưng chắc hẳn nó sẽ vẫn đâu đó có trong đầu bạn. Structure Interview chính là cách tốt nhất để xoá bỏ định kiến. Ngoài ra việc bạn biết là bạn đang mang các định kiến cũng là một bước đầu tiên rất tốt. Hãy lập một list những điều bạn cảm thấy vừa lòng với đồng nghiệp hiện tại, và tạo nên một bộ câu hỏi dựa trên đó.
TL;DR
Tìm đồng nghiệp rất khó, thậm chí nhiều team còn chả có cơ hội thử thực hiện những điều tôi nói ở trên vì họ còn chả có hồ sơ đến! Tuy nhiên cá nhân tôi thấy nếu bạn đang ở vị trí ngược lại (người đi tìm việc chứ không phải nhà tuyển dụng), có một vài điểm có thể có ích với bạn:
Luôn cố gắng thay đổi tình trạng hiện tại. Bạn đang vướng trong một đống shit code, shit architecture, hãy vẽ nên một bức tranh mới tốt đẹp hơn và vẽ ra từng bước để thay đổi nó. Cá nhân tôi là một người ám ảnh bởi việc luôn làm mọi thứ tốt hơn, và tôi nghĩ cách nghĩ đó đã giúp tôi rất nhiều, kể cả việc thăng tiến trong công ty lẫn cả ngoài xã hội.
Tìm dự án nào mà khiến bạn tự hào là đã từng làm nó để ghi vào CV. Kĩ năng "tìm dự án ngon" là một kĩ năng thiết yếu mà tôi nghĩ bạn sẽ lãng phí thời gian lẫn năng lực cá nhân nếu không có kĩ năng này.
Khi không làm được hai điều trên ở team hiện tại (có thể vì chính trị công ty, vì công ty quá ... lởm), hãy tìm việc mới ngay khi có thể.
6 notes
·
View notes
Text
Livelock
Livelock (so với deadlock) là một khái niệm khó nhớ, vì đơn giản bạn chả có cơ hội gặp nó trong thực tế mấy (ngay cả deadlock cũng vậy).
Hôm nay tình cờ đi thang máy tôi gặp một bạn nữ rất xinh. Tôi và bạn ấy cùng tiến vào thang máy, khi tôi đi chậm lại để nhương bạn ấy đi trước thì bạn đó cũng đi chậm lại. Khi tôi đi nhanh lên thì bạn nữ cũng đi nhanh lên. Rốt cục cả 2 đều bước vào thang máy với một khe cửa rất hẹp.
Đó chính là một ví dụ tôi nghĩ là dễ nhớ về livelock, là khi bạn tưởng là đang tiến lên, nhưng thực ra là không tiến bước nào.
3 notes
·
View notes
Text
UUID cho cách mạng 4.0
Một ngày đẹp trời, bạn quyết định viết một dịch vụ web dự định sẽ làm thay đổi cả thế giới. Dịch vụ của bạn sẽ kết nối tất cả các thiết bị di động trên thế giới lại thành một mạng lưới khổng lồ nói chuyện với nhau. Tất nhiên, bạn không muốn mạng lưới đó chạy trên blockchain, bạn muốn kiểm soát mọi thứ. Vì vậy mà bạn quyết định lưu toàn bộ dữ liệu về các thiết bị trên cơ sở dữ liệu của bạn. Code băng băng prototype, bất giác bạn băn khoan về việc làm thế nào để lưu ID cho mỗi thiết bị đó, và nhận ra việc, thiết kế một hoàn hảo là không hề dễ dàng.
Đầu tiên bạn nghĩ là sẽ lưu ID mỗi thiết bị dưới dạng tuần tự, đơn giản là 1, 2, 3, .. , N. Việc dùng ID tuần tự có những điểm lợi như, dễ lưu, ai đọc cũng hiểu (human readable), cũng như có thể sắp xếp được theo thời gian tạo (sortable). Việc sortable rất có lợi khi bạn có thêm thông tin mà không phải làm gì, vì vậy bạn có thể hiển thị bảng list thiết bị, mà không cần phải lấy thêm bảng timestamp từ cơ sở dữ liệu, tiết kiệm được khơ khớ công sức.
Tuy nhiên việc dùng id tuần tự lại có rất nhiều điểm trừ:
Trạng thái tuần tự là một trạng thái tập trung, bởi vậy bắt buộc phải có một chiếc máy làm nhiệm vụ lưu trạng thái, cũng như trả lời trạng thái, cập nhật trangj thái hiện tại (counter). Nói một cách khác, bạn không thể sinh id trên nhiều máy khác nhau, hay chính là “không scale"
ID tuần tự sẽ “tiết lộ” cho người ngoài rằng bạn có bao nhiêu thiết bị trên dịch vụ của bạn. Giả sử bạn có một api là /deviceId/:id/detail, thì người ngoài sẽ dễ dàng lần mò ra thông tin thiết bị không phải của họ (tạm bỏ qua yếu tố bảo mật ở đây)
Vậy ID tuần tự có vẻ không tốt về nhiều mặt :-?. Bạn nghĩ rằng, vậy nên qui định rõ một số tính chất của việc sinh ID, mà bạn cho rằng là tốt:
Đầu tiên, ID sinh ra phải có tính ngẫu nhiên, bạn không muốn người ngoài có thể mò mẫm hệ thống của bạn giống như ID tuần tự
Việc sinh ID, phải nhanh, và để nó nhanh một cách ổn định, nó nên diễn ra trên nhiều máy được (sinh tuần tự không làm được việc này).
Càng nhỏ càng tốt, càng dễ đọc càng tốt.
Bạn chợt nghĩ ra, vậy chỉ cần cho ID ngẫu nhiên (random) là được nhỉ. Sinh chuỗi ngẫu nhiên (Random Generator) là một lĩnh vực phức tạp, tôi sẽ đi qua một chút lý thuyết đơn giản trước để làm nền tảng cho đoạn sau. Đầu tiên thử suy nghĩ trong vòng 10 giây, thế nào là ngẫu nhiên. …… (hết 10 giây) Khó phết nhỉ.
Ngẫu nhiên, một cách trực quan, có thể định nghĩa là một thứ mà chúng ta không thể đoán được qui luật. Ví dụ chuỗi tăng tuần tự 1,2,3.. N không phải là ngẫu nhiên vì nó có qui luật. Định nghĩa trên wikipedia cũng cho ta:
Randomness is the lack of pattern or predictability in events
Tuy nhiên việc “dự đoán” ở đây cũng có thể hoàn toàn là cảm tính. Mặc dù trong toán học hay xác suất, cũng khó có thể định nghĩa một cách rõ ràng và dễ hiểu được. Khi bạn tung đồng xu, bạn tự coi việc xấp hay ngửa là ngẫu nhiên, đơn giản vì có quá nhiều thứ phức tạp có thể tác động vào việc đồng xu xấp hay ngửa, nên ngay cả máy tính cũng không thể tính toán chính xác được việc đó. Vậy những thứ “thật sự” ngẫu nhiên sẽ là những thứ bị tác động bởi nhiều yếu tố vật lý, làm cho kết quả không thể dự đoán được.
Trong khoa học máy tính, khi bạn nói: tôi muốn một chuỗi ngẫu nhiên, sẽ có 2 cách:
Sử dụng tính chất vật lý thật sự, để đem lại giá trị ngẫu nhiên thật sự theo như định nghĩa ở trên. Cách này chính là cách mà hệ điều hành UNIX sử dụng cho /dev/random bằng cách thu thập các nhiễu (noise) từ cacs thiết bị ngoại vi. Chính vì thế một đặc điểm mà bạn cần lưu ý khi sử dụng /dev/random là: đây là một nguồn tài nguyên CÓ HẠN. Quên đi đặc điểm này nhiều khi sẽ dẫn đến lỗi hệ thống mà bạn không mong muốn.
Sử dụng “trick”, là cho chuỗi sinh ra “nhìn có vẻ giống random”. Cách này chính là pseudorandom number generators (PRNGs). Về ý tưởng , bạn có một số X gọi là “seed”, và một công thức toán học kì diệu sẽ sinh ra X’ từ X mà nhìn khác hẳn X. Lặp lại việc này N lần (sinh X’’ từ X’)… sẽ cho chúng ta một con số kì lạ, mà bạn có thể “coi" như nó là ngẫu nhiên. Công thức toán học hay được dùng nhất chính là phép module.
Xn+1 = (a * Xn + b) % m
Trong thực tế thì người ta sẽ dùng một cách phức tạp hơn một chút để có phân phối tốt hơn trong một khoảng cố định, tuy nhiên idea thì vẫn tương tự.
Quá dài dòng cho anh bạn ngẫu nhiên! Quay lại bài toán chính, sinh ID, bạn đang nghĩ tại sao lại không sinh ID một cách ngẫu nhiên thay vì tuần tự. Bingo! Bạn đã có một ý tưởng không hề tồi. Tuy nhiên khi đi vào cụ thể bạn sẽ có rất nhiều cái phải suy nghĩ. Đầu tiên, giá trị ID của bạn nên là bao nhiêu bit? Ít bit thì tốt, nhưng nó sẽ tăng khả năng ID bị trùng, điều này thì không thể xảy ra. Tuy nhiên nhiều quá thì lại .. tốn chỗ. Hãy thử làm một vài phép tính toán đơn giản, điều kiện là để xác suất 2 ID trùng nhau càng thấp càng tốt. Đây chính là bài toán sinh nhật nổi tiếng (Birthday Problem). Bài toán này nghĩa là, sau một hồi các ông giáo sư toán đầu mưng mủ nghiên cứu, thì các ông ấy đã có công thức là xác suất trùng ID khi ta muốn generate n ID, với không gian x (X là tổng số ID có thể có, ví dụ bạn có 16 bit thì X sẽ là 2^16), sẽ là
P(n) ~ 1 - 2 ^ (-n^2 / 2x)
Giả sử chúng ta có không gian x là 122 bit , và chúng ta chỉ có tầm 100 triệu thiết bị, khi đó xác suất trùng ID sẽ là 9.4 * 10^-26. Tức là nếu bạn sinh 10^25 (1 tỉ là 9 số 0, đây sẽ là 1 trăm triệu tỉ tỉ ) lần 1 triệu ID thì khả năng sẽ có một lần mà trong 100 triệu ID đó có 2 ID bị trùng. Con số này lớn hơn 78 tỉ tỉ lần khả năng bạn bị sét đánh. Khiếp nhiều chữ tỉ quá! Đây chính là idea của UUID V4 khi chúng ta có 122 bits dành cho việc cho sinh số ngẫu nhiên trong tổng số 128 bit. Chúng ta sẽ đi sâu về cái gọi là UUID ở phần dưới. Thử đọc phần cài đặt UUID V4 trên một thư viện khá nổi tiếng của golang chúng ta sẽ hiểu idea của thuật toán đơn giản là, lấy một chuỗi random sau đó set các bit cần thiết như version bit và variant bit.
// NewV4 returns random generated UUID. func (g *rfc4122Generator) NewV4() (UUID, error) { u := UUID{} if _, err := g.rand.Read(u[:]); err != nil { return Nil, err } u.SetVersion(V4) u.SetVariant(VariantRFC4122) return u, nil }
Với UUID V4, cái vài điểm trừ bạn cần suy nghĩ chính là cái tôi đã nói ở trên về việc: tài nguyên để sinh số ngẫu nhiên trên máy tính (qua /dev/random) là hữu hạn. Khi nguồn tài nguyên này hết, đơn giản là việc đọc số ngẫu nhiên sẽ bị blocking, và chương trình của bạn sẽ bị "đứng hình" cho đến khi nó có trở lại. Ngoài ra một điểm trừ nữa là ... nó tốn quá nhiều bit. 1 tỉ ID với 128 bit sẽ là tầm 14GB, có lẽ không là gì nếu bạn lưu trên đĩa cứng, tuy nhiên nếu bạn cần cache đống ID đó lại trên NAND memory thì 14GB cũng không phải là một con số nhỏ.
Trước khi đi tiếp về việc, liệu chúng ta có cần đến 128 bit, đi sâu một chút về cái gọi là UUID trước nhỉ. UUID là một dạng ID "dùng cho mọi thứ (universal), và độc nhất (unique)", được qui định trong RFC4122. Tại sao lại cần một qui định thống nhất về UUID ? Theo như RFC thì chúng ta cần một chuẩn thống nhất để miêu tả mọi thứ, đủ lớn để mô tả hết, và đủ tốt để có thể tự động hoá quá trình sinh ID bởi một bên thứ 3 (completely automated).
Có nhiều biến thể của UUID, hiện tại bao gồm từ V1 đến V5. Các biến thể có đặc điểm chung là, cùng có 128 bit và biến thể nào sẽ được qui định ở vài bit đầu tiên tại octet thứ 8 (hay bit thứ 57 trở đi). Mỗi biến thể có một mục đích khác nhau nhưng về ý tưởng thì nó được chia làm 3 nhóm:
V1 là biến thể đầu tiên, cũng là biến thể hay được sử dụng nhất. V1 có đặc điểm là dùng các yếu tố mang tính cục bộ (local properties) như là : địa chỉ MAC của máy đang sử dụng và clock sequence (bạn có thể hiểu clock sequence giống như timestamp, nhưng lại được bổ sung một số tính toán nhằm tránh trường hợp clock bị sai). Version1, ngoài việc gúp tính “ngẫu nhiên” của chuỗi sinh ra thông qua clocksequence, còn nhằm mục đích là việc sinh chuỗi có thể diễn ra trên nhiều máy khác nhau (nhờ MAC address).
V2 về ý tưởng cũng tương tự V1, tuy nhiên lại có thêm 8 bit gọi là "local domain" nằm trong clock sequence. Nghe thiên hạ đồn đại local domain phục vụ cho mục đích security trên hệ thống phân tán (DCE security), cơ mà cụ thể qui định về localdomain này không ghi rõ trong RFC!!! Thế nên rất nhiều cài đặt của UUID bỏ qua V2. Các cụ đã nói, không có RFC đố mày làm nên quả không sai.
V3 và V5 sử dụng một khái niệm gọi là “name space”. Nôm na là bạn sẽ có thể chia ra ID cho thiết bị và ID cho người dùng khác nhau. Khác nhau ở V3 với V5 là V3 dùng MD5 để hash “name space” (ví dụ tên loại thiết bị / tên thành phố user ở) thì V5 dùng SHA1 (an toàn hơn MD5). Mặc dù ý tưởng có vẻ thú vị, nhưng bạn nghĩ, chả có lý do gì phải tách namespace cả, bạn đoán là trong thực tế chắc cũng chả có nhiều người dùng V3 hay V5.
V4 tôi đã nói ở trên, ý tưởng chỉ đơn thuần là 1 chuỗi ngẫu nhiên! Tuy nhiên ngẫu nhiên quá cũng có cái hại, là nó làm dữ liệu của bạn bị phân mảnh (fragmentation) trong nhiều hoàn cảnh.
Chắc bạn thấy đã quá mệt, bạn chỉ muốn sinh ID thôi mà nhiều thứ loằng ngoằng quá :-? Tuy nhiên tôi phải thông báo cho bạn một tin buồn mà sẽ không có báo chí nào nhắc đến là, nếu mới vậy bạn đã mệt thì bạn vẫn chưa sẵn sàng cho cách mạng 4.0 ...
RFC4122 cung cấp cho bạn rất nhiều lựa chọn tốt. V1 giúp bạn vừa có một ID đủ tốt (không bị trùng), vừa có thể sinh trên nhiều máy khác nhau. Tuy nhiên hãy thử nhìn một ID sinh ra bởi UUID V1
6639aa25-de02-4d7c-86a2-01ee0e01fd73
Bạn có thấy nó dài vãi 4.0 không? Ngoài ra sử dụng V1 đòi hỏi chúng ta phải có máy tính vật lý với MAC address cố định.
Quay lại một chút cái tôi đã nói ở trên:
Liệu chúng ta có cần đến 128 bit???
Liệu có một cách nào đó mô tả ID vừa ngắn gọn, lại vừa dễ đọc, vừa dễ nhìn không??
Trong thực tế, có rất nhiều người đã nghĩ ra những cách sinh ID không theo chuẩn, nhưng lại vừa đủ để giải quyết bài toán của họ.
Twitter SnowFlake là một ví dụ. Tại twitter thì họ cần ID cho user, và quan trọng hơn là cho tweet. Tweet có một thuộc tính vô cùng cần thiết để hiển thị là tính tuần tự theo thời gian. Và tweet ID, để cho dễ đọc thì twitter nghĩ họ muốn một con số, hơn là một chuỗi kí tự dài cả cây số như UUID. Twitter Snowflake, hay còn gọi là twitter id, là 64bit unsigned integer. Chuỗi này được sinh bằng cách nhét timestamp, machine id (quản lý trung tâm thông qua zookeeper) và một chút ngẫu nhiên vào 64bit. Bằng cách nhét timestamp vào họ đã có một id mà có thể sắp xếp được. Nhờ cách dùng machine id (1,2,3..N) mà họ có thể sinh ID trên nhiều máy khác nhau, qua đó scale xử lý lên đến hàng triệu ID mỗi giây.
Một ví dụ khác là ULID (Universally Unique Lexicographically Sortable Identifier). Ví dụ này khác SnowFlake ở chỗ thuật toán sinh này hướng đến số đông hơn (thay vì SnowFlake được thiết kế để phù hợp với hoàn cảnh twitter). ULID cũng có 128 bit, để dễ dàng thay thế cho UUID khi bạn đã lỡ thiết kế mất rồi. Có 2 đặc điểm khiến cho ULID đặc biệt:
Được nhét 48 bit timestamp vào đầu chuỗi bit, cho độ chính xác lên đến millisec
Thay vì sử dụng hex để encode chuỗi bit thành string như UUID, ULID sử dụng Crockford Base32, là một cách encode đơn giản hơn, và loại bỏ các kí tự dễ gây nhầm lẫn như I (nhìn giống 1) hay 0 (nhìn giống O) và chỉ dùng chữ hoa (uppercase) Cách sinh ULID vô cùng đơn giản, 48 bit đầu cho timestamp từ EPOCH, và 80 bit còn lại là ... ngẫu nhiên. ULID không có yếu tố cục bộ như MAC address hay machine ID, bởi vậy sẽ không dễ dàng để sử dụng trong môi trường phân tán, nhưng chắc không phải ai cũng là twitter để phải sinh ra hàng triệu ID mỗi giây nhỉ. Ngoài ra ngay cả sử dụng ULID trên môi trường phân tán, 80 bit ngẫu nhiên cũng quá đủ tốt để cho bạn không phải lo lắng quá nhiều về việc xung đột (collision).
Phù! Có lẽ bạn đã mệt vì có quá nhiều lựa chọn. Sau khi sản phẩm của bạn ra thị trường, bạn nhận thấy bạn chỉ có nhiều nhất 100 người dùng, vì vậy bạn quyết định, sử dụng 8 bit ID ngẫu nhiên, va chỉ tốn 1 byte để lưu trong bộ nhớ, và bạn nghĩ thầm, không hiểu với 100 người dùng thì bạn sẽ làm cách mạng ra sao đây....
Tuy nhiên bạn cũng đã học cho mình được một bài học:
Không phải lúc nào bạn cũng cần đến những chuẩn có sẵn. UUID và các biến thể của nó cũng vậy. Bạn có thể tự chế cho mình một thuật toán sinh ID sử dụng các ý tưởng có sẵn kết hợp với nhu cầu bản thân.
Mỗi một thuật toán sinh ID sẽ có những điểm yếu cũng như điểm mạnh riêng. Trong bài blog của mình, Lemire tác giả của lucene đã tìm hiểu xem các loại ID sẽ có ảnh hưởng khác nhau đến performance thế nào.
Quả thật làm cách mạng không phải dễ dàng nhỉ.
8 notes
·
View notes
Text
Đi làm cách mạng 2.0^2 (phần 3)
Cách mạng đã lên đến cao trào khi sau 2 ngày tôi chỉ được ngủ có tầm 5 giờ mỗi ngày, bằng một nửa so với mức bình thường của tôi.
Ngày thứ 3 của chuỗi sự kiện là ngày cuối cùng tôi được ở Hà Nội, khi mà hôm sau cả đoàn sẽ phải đi Quảng Ninh và từ đó bay thẳng vào Sài Gòn. Ngày thứ 3 bắt đầu bằng cuộc họp tại UBND TP Hà Nội. Cuộc họp đã được tường thuật khá chi tiết trong blog của anh T nên tôi sẽ không nhắc lại nhiều. Trong cuộc họp thì hầu hết mọi người đều ấn tượng với trí nhớ của chủ tịch Chung, tôi cũng vậy. Tuy nhiên do thời gian khá ngắn nên buổi gặp mặt diễn ra khá một chiều, khi bên thành phố chỉ có thời gian lắng nghe ý kiến của bên chuyên gia mà không có thời gian phản hồi, khiến cho cá nhân tôi không hy vọng nhiều lắm về việc các ý kiến này sẽ được thực hiện hay ghi nhớ một cách đầy đủ.
Trong các ý kiến chuyên gia thì tôi thấy đồng tình và thấy thú vị nhất với ý kiến của chị Tuyết bên BCG về việc, phải tuyên truyền những gì mà thành phố đã làm tốt nhiều hơn nữa. Mặt trái của mạng internet là những gì xấu về chính quyền sẽ dễ lan truyền với tốc độ chóng mặt, trong khi những gì tốt thường vô ý hay cố ý, sẽ bị lờ đi. Thành phố đã và đang làm những điều tốt, và tôi thấy những điều đó cần được lan truyền rộng hơn nữa, để ít nhất đem lại cho dân thường như tôi thêm hy vọng, mà khi có hy vọng thì người ta sẽ muốn đóng góp. Trong việc tuyên truyền bao gồm việc tạo nên mascot cho thành phố (không biết tôi nhớ đúng không). Ở Nhật thì người ta rất hay tận dụng các hình ảnh đáng yêu để mô tả về những gì vốn cứng nhắc như chính quyền, công an hay bộ đội. Tôi nghĩ nếu Hà Nội thuê một đội branding desing để xây dựng một nhân vật tượng trưng cho thành phố (kiểu như nhân vật bộ truyện thần đồng đất Việt chẳng hạn) thì sẽ rất hay.
Chiều cùng ngày chúng tôi đến thăm trung tâm CNC Láng Hoà Lạc, đây là lần đầu tiên tôi đến đây. Cảm nhận cá nhân khi đến là khu vực vẫn khá hoang vắng, nhiều chỗ vẫn xây dựng ngổn ngang, cộng thêm quãng đường cũng xa, không hiểu ai sẽ có động lực lên đây nữa. Cuộc gặp giữa đoàn và lãnh đạo FPT diễn ra tại văn phòng FPT tại Hoà Lạc. Văn phòng của FPT rất đẹp. Tuy nhiên khi nghe bài phát biểu của các lãnh đạo của FPT thì tôi càng thêm củng cố niềm tin về việc FPT sẽ khó làm nên gì đặc biệt cả khi anh Bình cố nhấn mạnh về cái chuyển dịch số (aka: các dự án outsource về migration, theo tôi hiểu) và AI (không hiểu anh có hiểu rõ cái anh nói không). Hy vọng niềm tin của tôi là sai. Kể thêm là mấy hôm sau tôi có ngồi ăn cũng như nói chuyện khá nhiều với thành viên bên ban công nghệ tập đoàn của FPT, tôi thấy họ là những người có ước mơ, muốn làm những điều lớn lao. Tuy nhiên tôi không tin vào ban lãnh đạo của FPT, cũng như văn hoá của FPT, tôi không nghĩ họ muốn làm, có quyết tâm, và có khả năng làm những sản phẩm thực sự tốt. Những cá nhân có tài năng của FPT tôi hy vọng họ sẽ tìm được bến đỗ ở VNG hay VinGroup để đóng góp được nhiều hơn cho cộng đồng cũng như cho bản thân họ.
Tối hôm đó chúng tôi được hẹn gặp Vin group tại almaz, tuy nhiên do đã có hẹn trước với bạn nên tôi không tham dự được. Nghe nói Almaz đẹp lắm và anh Vượng cũng nói nhiều thứ ở tầm vĩ mô. (còn tiếp)
3 notes
·
View notes