Câu hỏi rất hay. Bạn cứ hình dung sự phối hợp của tụi nó như cách xử lý kẹt xe vậy ==> Khi hashCode() bị trùng, các key phải chui chung vào 1 bucket. Lúc này equals() sẽ đi soi từng thằng để lấy đúng data. Ban đầu tụi nó chỉ xếp hàng dọc (LinkedList), nhưng nếu kẹt đông quá (từ 8 phần tử) thì hàng tự "biến hình" thành Red-Black Tree để tốc độ quét vẫn mượt (O(logn) thay vì O(n)). Vậy nên dù có collision liên tiếp tại một chỗ, hiệu năng vẫn được bảo kê.Tuy nhiên, Tree chỉ là "cấp cứu cục bộ". Khi tổng số phần tử trong map quá đông (đạt 75% sức chứa), HashMap tung chiêu cuối là Rehashing — mở rộng gấp đôi "mặt đường" (số bucket) và tính toán phân bổ lại toàn bộ. Các phần tử trong Tree lúc nãy sẽ được tản mát ra các bucket mới. Vui cái là nếu chia xong mà bucket mới thưa thớt (<= 6 phần tử), nó lại tự thoái hóa ngược về LinkedList để tiết kiệm bộ nhớ.Túm cái váy lại: Red-Black Tree lo giữ tốc độ khi ùn tắc cục bộ, còn Rehashing là để mở rộng đường, giải tỏa traffic triệt để. Cảm ơn bác đã góp một comment cực chất lượng cho bài nhé!
Cảm ơn b nhiều nhé, đồng cảm ghê. Hồi trước mình cũng y hệt vậy, xem video thì gật gù mà lúc mở IDE lên là đầu óc trống trơn. Cứ bóp nát bài toán ra rồi mạnh dạn gõ bừa, dính bug tự fix dần là quen tay ngay đúng không b! 😁
Mình có thắc mắc, trong HashMap, nếu xảy ra nhiều collision liên tục dẫn đến rehashing, thì cơ chế hashCode(), equals(), bucket, và việc chuyển từ LinkedList sang Red-Black Tree sẽ phối hợp với nhau như thế nào để vẫn đảm bảo hiệu năng truy xuất?
Đọc xong bài này thấy đúng với bản thân mình thật 😄 Nhiều lúc xem tutorial thì hiểu hết, nhưng tự mở IDE lên lại không biết bắt đầu từ đâu. Cách tác giả phân tích mindset học lập trình rất thực tế và dễ ngộ ra vấn đề, cảm ơn tác gỉa vì bài viết chất lượng!
This article is exactly what I've been researching. Previously, I only used geo_point for simple distance searches around a location, so when faced with the requirement to draw a polygon to filter data by area, I was quite confused. After switching to geo_shape, I realized how powerful it is, especially for tracking or route mapping problems. I once tried building a system to store movement paths similar to the map movement in the game PolyTrack , needing to check if an object was within a defined area. That's when geo_shape with polygons and multi-polygons proved extremely useful. It's true that ES isn't just powerful for full-text search; its geo querying capabilities are also well worth exploring.
When I first started making small games, separating update() and draw() really helped me keep things organized and avoid weird bugs. It reminds me of how smooth timing feels in the FNF game, where the logic and visuals stay in sync even when performance drops a bit.
Vẫn chưa thực sự hiểu rõ lý do của bác khi không dùng Eloquent. Việc tránh withoutGlobalScope thực ra cũng rất đơn giản. Dùng query thuần giống như bác đang trở về thời kì đồ đá vậy @@ Không đáng để đánh đổi.
Cảm ơn bạn đã góp ý 😁
Mình khá đồng ý với quan điểm AI nên là công cụ hỗ trợ hơn là thay thế hoàn toàn con người. Sau thời gian dùng đủ lâu, mình cũng thấy AI mạnh nhất khi được dùng như một trợ lý hỗ trợ, chứ không phải giao hoàn toàn công việc cho nó.
Có lẽ ý mình trong bài không phải là AI tệ, mà là nhiều người đang kỳ vọng nó ở những phần cần judgement, context và trách nhiệm thực tế — trong khi đó lại là phần con người vẫn phải đứng ra gánh nhiều nhất.
Haha cảm ơn bác @duchai2k đã kéo em về mặt đất nhé 😅 Chắc tại đọc cuốn quá nên em hơi hưng phấn dùng từ 'master' nghe hơi đao to búa lớn.
Ý em ở đây là bài viết hệ thống lại bản chất rất tốt để anh em có cái gốc vững. Đúng như bác nói, thực tế phần lớn dự án bây giờ đều qua Spring hay các lib Async bọc hết rồi, mấy khi tự tay gõ synchronized hay dùng Lock. Nhưng cá nhân em thấy có những case hệ thống bị nghẽn Thread Pool hoặc dính Concurrency Bug ngầm, nếu không có cái nền tảng này thì đọc log hay thread dump đúng là như nhìn bức vách.
Dù sao cũng cảm ơn góc nhìn thực chiến rất hay của bác, lý thuyết kết hợp với tư duy design thực tế như bác nói mới là chuẩn bài!
Bài viết tâm huyết quá. Nhưng mình nghĩ quan điểm của bạn đã sai ngay từ đầu: AI nên là thứ hỗ trợ, chứ không phải thứ thay thế con người. Bạn kì vọng quá cao và giao vai trò sai cho nó dẫn đến kết luận là AI tệ. Trong khi với vai trò là công cụ hỗ trợ, mình thấy AI làm rất tốt.
Mình thấy hơi “overhype” một chút 😅
Đúng là Concurrency trong Java quan trọng thật, nhưng nói đọc một bài là có thể “nắm vững bản chất” để tránh Race Condition hay Deadlock thì hơi lý tưởng hóa. Mấy vấn đề này trong thực tế thường đến từ design sai hoặc thiếu kinh nghiệm debug hơn là chỉ thiếu kiến thức lý thuyết.
Ngoài ra, cũng không phải dự án nào cũng cần “master” concurrency. Nhiều case business bình thường, dùng framework (Spring, thread pool, async abstractions, reactive lib…) đúng cách là đã handle được phần lớn rồi, không cần tự mình “đụng chạm” sâu đến low-level synchronization.
Bài viết tốt thì vẫn đáng đọc, nhưng mình nghĩ nên nhìn nhận nó như một tài liệu tham khảo nền tảng thôi, chứ chưa đủ để “tự tin chiến đấu” trong production đâu @bullpig
Cảm ơn tác giả đã có 1 bài viết đáng đọc! @ngocbach99
THẢO LUẬN
tôi thiết kế ban đầu để mọi thứ tường minh nhất có thể.
Câu hỏi rất hay. Bạn cứ hình dung sự phối hợp của tụi nó như cách xử lý kẹt xe vậy ==> Khi hashCode() bị trùng, các key phải chui chung vào 1 bucket. Lúc này equals() sẽ đi soi từng thằng để lấy đúng data. Ban đầu tụi nó chỉ xếp hàng dọc (LinkedList), nhưng nếu kẹt đông quá (từ 8 phần tử) thì hàng tự "biến hình" thành Red-Black Tree để tốc độ quét vẫn mượt (O(logn) thay vì O(n)). Vậy nên dù có collision liên tiếp tại một chỗ, hiệu năng vẫn được bảo kê.Tuy nhiên, Tree chỉ là "cấp cứu cục bộ". Khi tổng số phần tử trong map quá đông (đạt 75% sức chứa), HashMap tung chiêu cuối là Rehashing — mở rộng gấp đôi "mặt đường" (số bucket) và tính toán phân bổ lại toàn bộ. Các phần tử trong Tree lúc nãy sẽ được tản mát ra các bucket mới. Vui cái là nếu chia xong mà bucket mới thưa thớt (<= 6 phần tử), nó lại tự thoái hóa ngược về LinkedList để tiết kiệm bộ nhớ.Túm cái váy lại: Red-Black Tree lo giữ tốc độ khi ùn tắc cục bộ, còn Rehashing là để mở rộng đường, giải tỏa traffic triệt để. Cảm ơn bác đã góp một comment cực chất lượng cho bài nhé!
Cảm ơn b nhiều nhé, đồng cảm ghê. Hồi trước mình cũng y hệt vậy, xem video thì gật gù mà lúc mở IDE lên là đầu óc trống trơn. Cứ bóp nát bài toán ra rồi mạnh dạn gõ bừa, dính bug tự fix dần là quen tay ngay đúng không b! 😁
Mình có thắc mắc, trong HashMap, nếu xảy ra nhiều collision liên tục dẫn đến rehashing, thì cơ chế hashCode(), equals(), bucket, và việc chuyển từ LinkedList sang Red-Black Tree sẽ phối hợp với nhau như thế nào để vẫn đảm bảo hiệu năng truy xuất?
Đọc xong bài này thấy đúng với bản thân mình thật 😄 Nhiều lúc xem tutorial thì hiểu hết, nhưng tự mở IDE lên lại không biết bắt đầu từ đâu. Cách tác giả phân tích mindset học lập trình rất thực tế và dễ ngộ ra vấn đề, cảm ơn tác gỉa vì bài viết chất lượng!
😁😁cảm ơn bạn đã đọc và góp ý 😋
@nqubao1312 về điều này mình hoàn toàn đồng ý.
bài viết dài nhưng lan man quá
cảm ơn nhé!!!
This article is exactly what I've been researching. Previously, I only used geo_point for simple distance searches around a location, so when faced with the requirement to draw a polygon to filter data by area, I was quite confused. After switching to geo_shape, I realized how powerful it is, especially for tracking or route mapping problems. I once tried building a system to store movement paths similar to the map movement in the game PolyTrack , needing to check if an object was within a defined area. That's when geo_shape with polygons and multi-polygons proved extremely useful. It's true that ES isn't just powerful for full-text search; its geo querying capabilities are also well worth exploring.
When I first started making small games, separating update() and draw() really helped me keep things organized and avoid weird bugs. It reminds me of how smooth timing feels in the FNF game, where the logic and visuals stay in sync even when performance drops a bit.
Vẫn chưa thực sự hiểu rõ lý do của bác khi không dùng Eloquent. Việc tránh withoutGlobalScope thực ra cũng rất đơn giản. Dùng query thuần giống như bác đang trở về thời kì đồ đá vậy @@ Không đáng để đánh đổi.
Cảm ơn bạn đã góp ý 😁 Mình khá đồng ý với quan điểm AI nên là công cụ hỗ trợ hơn là thay thế hoàn toàn con người. Sau thời gian dùng đủ lâu, mình cũng thấy AI mạnh nhất khi được dùng như một trợ lý hỗ trợ, chứ không phải giao hoàn toàn công việc cho nó. Có lẽ ý mình trong bài không phải là AI tệ, mà là nhiều người đang kỳ vọng nó ở những phần cần judgement, context và trách nhiệm thực tế — trong khi đó lại là phần con người vẫn phải đứng ra gánh nhiều nhất.
Haha cảm ơn bác @duchai2k đã kéo em về mặt đất nhé 😅 Chắc tại đọc cuốn quá nên em hơi hưng phấn dùng từ 'master' nghe hơi đao to búa lớn.
Ý em ở đây là bài viết hệ thống lại bản chất rất tốt để anh em có cái gốc vững. Đúng như bác nói, thực tế phần lớn dự án bây giờ đều qua Spring hay các lib Async bọc hết rồi, mấy khi tự tay gõ synchronized hay dùng Lock. Nhưng cá nhân em thấy có những case hệ thống bị nghẽn Thread Pool hoặc dính Concurrency Bug ngầm, nếu không có cái nền tảng này thì đọc log hay thread dump đúng là như nhìn bức vách.
Dù sao cũng cảm ơn góc nhìn thực chiến rất hay của bác, lý thuyết kết hợp với tư duy design thực tế như bác nói mới là chuẩn bài!
Bài viết tâm huyết quá. Nhưng mình nghĩ quan điểm của bạn đã sai ngay từ đầu: AI nên là thứ hỗ trợ, chứ không phải thứ thay thế con người. Bạn kì vọng quá cao và giao vai trò sai cho nó dẫn đến kết luận là AI tệ. Trong khi với vai trò là công cụ hỗ trợ, mình thấy AI làm rất tốt.
@huydev007 ráng đi em =))
bài viết hay, respect tác giả
@hhoang a viet bai bang ai ak sao a viet nhanh the e ko doc kip=))
Mình thấy hơi “overhype” một chút 😅 Đúng là Concurrency trong Java quan trọng thật, nhưng nói đọc một bài là có thể “nắm vững bản chất” để tránh Race Condition hay Deadlock thì hơi lý tưởng hóa. Mấy vấn đề này trong thực tế thường đến từ design sai hoặc thiếu kinh nghiệm debug hơn là chỉ thiếu kiến thức lý thuyết. Ngoài ra, cũng không phải dự án nào cũng cần “master” concurrency. Nhiều case business bình thường, dùng framework (Spring, thread pool, async abstractions, reactive lib…) đúng cách là đã handle được phần lớn rồi, không cần tự mình “đụng chạm” sâu đến low-level synchronization. Bài viết tốt thì vẫn đáng đọc, nhưng mình nghĩ nên nhìn nhận nó như một tài liệu tham khảo nền tảng thôi, chứ chưa đủ để “tự tin chiến đấu” trong production đâu @bullpig Cảm ơn tác giả đã có 1 bài viết đáng đọc! @ngocbach99
Bài viết hữu ích