Bài viết được sự cho phép của tác giả Trần Anh Tuấn
Hey ya. Tình hình là mới đi du lịch Đà Nẵng zìa hôm kia nên hôm nay tranh thủ viết bài chia sẻ tiếp kiến thức cho anh em. Và chủ đề hôm nay đó là một trong những pseudo class mà nhiều bạn học và làm vẫn chưa hiểu rõ cũng như áp dụng hết sự hiệu quả của nó mang lại đó chính là :before và :after.
Hiểu đơn giản thì before thì thêm vào trước và after là thêm vào sau thế thôi nhưng để hiểu sâu và làm được với nó thì cách tốt nhất đó là làm ví dụ thì mới mau hiểu được. Nào cùng chiến thôi.
Để sử dụng :before hay :after thì đơn giản các bạn chỉ cần dùng theo cú pháp element:before hoặc element:after. Như .home:before{} chẳng hạn. Và để before hay after hoạt động thì bắt buộc phải có thuộc tính content nha.
Thường thường các bạn hay thấy content: "" người ta để rỗng thế này là vì người ta muốn làm một cái gì đó khác mà không có nội dung bên trong. Còn bạn muốn thêm vào content: "noidung" thì vẫn được không sao cả. Ví dụ một thẻ p nào đó
<p>toi ten la</p>
Mình muốn thêm tên của mình vào phía sau thẻ p này thì mình sẽ sử dụng :after
p:after {content:" Tuan";}
Còn nếu mình muốn thêm vào trước thì dùng :before
p:before {content:"Xin chao ";}
Ta được kết quả như hình
Hoặc các bạn có thể thấy rõ khi các bạn sử dụng fontawesome, họ xài before hay after để hiển thị icon với thuộc tính content: "\ec06" gì đó để nó hiển thị icon tương ứng mà họ đã định dạng trong code của họ.
Còn nếu mà để trống content: "" như này thì các bạn cũng có thể làm nhiều kiểu style khác như làm background phủ toàn bộ layer nè, hiệu ứng background chạy qua chạy lại rồi animation các kiểu, tạo những kiểu phức tạp…. nhiều lắm.
Thường thường khi sử dụng before hoặc after thì phần tử mà chúng ta đang làm nên sử dụng position: relative hoặc position: absolute. Sau đó trong :before hay :after các bạn dùng position: absolute và các thuộc tính top, right, bottom, left để căn chỉnh vị trí cùng với các thuộc tính CSS khác để style theo ý muốn của bạn.
Nếu bạn không hiểu cách dùng position trong CSS như thế nào thì đừng quên quay lại bài trước mình có viết về tìm hiểu thuộc tính position trong CSS rất rõ ràng chi tiết luôn ấy. Các bạn có thể xem tại đây nha.
Giờ mình sẽ làm vài ví dụ kèm theo giải thích cho các bạn dễ hiểu và hình dung hơn. Chớ đọc chữ nãy giờ chắc chưa thông não đâu.
Giờ mình muốn khi rê chuột vào thì cái background-color nó sẽ chạy từ trái qua phải rồi sau khi đưa chuột ra thì background-color nó thu về lại. Mình sẽ code như sau
h2:hover:before {width:100%;}
Lúc đầu mình cho :before có thuộc tính content: "" rỗng, position: absolute để chạy theo phần tử cha(ở đây là thẻ h2 chính nó) và top: 0, left: 0 thì nó sẽ nằm góc bên trái trên cùng
Kèm theo là height: 100% nghĩa là nó sẽ chiếm chiều cao 100% của phần tử mà chúng ta đang làm là thẻ h2 và set độ rộng(width) là 0 để nó chưa có gì hết. Và kèm thêm transition để làm hiệu ứng nó mượt hơn khi :hover vào.
Sau đó mình dùng :hover để khi chúng ta rê chuột vào thì mình cho độ rộng(width: 100%) để cho cái background-color nó chạy ra từ trái qua phải. Bạn có thể xem demo Codepen này
Tuy nhiên các bạn sẽ thấy khi rê chuột vào background-color nó chạy đè lên chữ luôn. Như vậy là sai rồi. Vì thế đừng quên dùng thuộc tính z-index vào nhé. Ở trong Codepen các bạn check code CSS sẽ thấy mình có comment cái z-index: -1 lại đó.
Mình để số âm là vì muốn nó nằm dưới, z-index hoạt động như các lớp đè lên nhau lớp nào có z-index cao hơn sẽ nằm lên trên và ngược lại lớp nào có z-index thấp hơn sẽ nằm ở dưới.
Mặc định giá trị của z-index là auto và z-indexchỉ hoạt động khi đi kèm với thuộc tính position nhé. Cho nên mình set cho thẻ h2:before là -1 cho nó nằm dưới text. Các bạn nhớ bỏ comment để nó hiển thị ra kết quả như mong đợi nè.
Giờ mình muốn cải thiện hiệu ứng độc đáo hơn một chút với các thuộc tính left right các bạn có thể xem tham khảo nà. Mình muốn khi rê chuột vào background-color nó sẽ chạy từ trái qua phải(như lúc đầu) và sau khi bỏ chuột ra thay vì co background-color lại bên trái thì mình muốn nó chạy qua bên phải luôn.
Chỉ một chút thay đổi code CSS với thuộc tính left và right như thế này
Nhiều bạn khi code sẽ thấy có người dùng :before hoặc ::before thì mình note phát là hầu hết các trình duyệt đều hỗ trợ 2 dấu 2 chấm :: hay 1 dấu 2 chấm : cho cú pháp của CSS3 tuy nhiên trên một số trình duyệt cũ như IE8 chẳng hạn thì lại không hỗ trợ 2 dấu 2 chấm ::.
Cho nên nếu dự án bạn code không cần tới tận IE8 thì thoải mái dùng ::before hay ::after ok nhé. Còn làm việc với IE8 thì dùng :before hay :after cho an toàn.
# Tạo ribbon hình tam giác
Các bạn nhìn quen không? Chắc hẳn khi làm sẽ gặp nhiều trường hợp như thế này rồi. Và cách tốt nhất đó là dùng :before hoặc :after để làm nó. Để tạo hình tam giác bằng CSS hay hình gì khác thì các bạn có thể tham khảo code tại đây.
Việc tạo hình tam giác thì mình đã để link ở trên, còn ở đây mình có set bottom: -10px để nó nằm dưới cùng vì nó có độ cao là 10px của border và mình cho thêm left: 50px để nó cách ra so với bên trái 1 chút cho đẹp và màu border nó sẽ trùng với màu nền của thẻ div mà chúng ta đang làm cho đồng bộ.
# Lời kết
Bài viết đến đây là kết thúc. Hi vọng sẽ giúp được cho các bạn hiểu hơn được đôi chút. Vì mấy cái này cần làm nhiều thì mới biết nhiều, áp dụng được nhiều chứ không thể chỉ hết được vì nó còn rất nhiều cái mới mà trong khi làm chúng ta sẽ gặp phải.
Nếu có gì thắc mắc góp ý thì cứ bình luận bên dưới mình sẽ ráng giải đáp với kiến thức chuyên môn của mình nà. Chúc các bạn một ngày tốt lành.
Tại sao lại chọn kiểu này? Không cần quan tâm đến user, cảm giác rất quyền lực như có găng tay vô cực, chỉ với _. chúng ta có tất cả mọi thứ.
Điểm yếu, đây là cách tuyệt đối nghiêm cấm, vì gần như là load nguyên cái thư viện
Tổng 190 KB, Lodash ngốn hết 72.5kb
Cách 2
import{ map, each, get, set }from lodash;
Kiểu này ổn, dễ đọc, rất rõ ràng để thấy được những hàm nào cần sử dụng.
Tuy nhiên, nó lại không khác gì với cách 1. Tổng vẫn là 190kb
Cách 3
import map from'lodash/map';import each from'lodash/each';import get from'lodash/get';import set from'lodash/set';
Kết quả cho thấy đây là cách tiết kiệm nhất, mặc dù thực tế sử dụng cho thấy cách này hơi tốn công anh em dev của chúng ta và nhìn đoạn import có vẻ dài.
Một số ý kiến cho là dùng lodash-es, một phiên bản theo kiểu ES module sẽ tiết kiệm hơn, đây là kết quả đo được
Cách 1: 256.4 KB
Cách 1: 256.54 KB
Cách 1: 142.39 KB
Như vậy việc dùng lodash-es có vẻ là vô dụng
Dùng lodash babel plugin
Sử dụng lodash babel plugin chúng ta có kết quả 140kb trên tất cả các cách import
Dùng Lodash webpack plugin
Lodash webpack plugin không biết đã bùa chú kiểu gì mà kết quả cuối cùng rất ngon 121kb cho cách 1, các cách khác sẽ còn bé hơn nữa
Kết luận
Nếu ko siêng bạn nên dùng cách 3, còn nếu siêng bạn setup với babel-plugin-lodash và lodash-webpack-plugin để đạt hiệu quả cao nhất.
Lodash-es thì nên dẹp luôn đừng xài vì nó ko thay đổi gì tích cực cả.
Động lực thực sự rất quan trọng đối với nhân viên. Động lực được xem là thứ nuôi dưỡng; thúc đẩy nhân viên về nhiều khía cạnh, đặc biệt là khía cạnh tinh thần. Hiệu suất cao, phát huy tiềm năng, khả năng đồng hành và phát triển,… là những yếu tố bị chi phối bởi động lực. Để đảm bảo việc duy trì động lực cho nhân viên, nhà quản lý/lãnh đạo nhân sự cần có những chiến lược cụ thể. Cùng TopDev tìm hiểu xem đâu là chiến lược phù hợp nhất.
Thiếp lập chính sách tiếp cận
Hãy đảm bảo rằng nhân viên của bạn hiểu rõ về các quy tắc, (dựa trên các cơ sở pháp lý). Đồng thời, việc truyền đạt các chính sách phải diễn ra rõ ràng.
Nhà quản lý/lãnh đạo nhân sự cần xác định rõ nguyên nhân, kết quả và định hướng cho nhân viên những gì họ cần phải làm trong thời gian sắp tới.
Hơn thế nữa, nhân viên cần nhận thức được những ảnh hưởng phát sinh. Điều đó được phản ánh qua chính cách hành xử; thực hiện các nhiệm vụ của họ. Họ cần biết rằng khi họ đang hoạt động trong một tổ chức, việc giảm bớt cái tôi cá nhân và cân bằng hóa những mong muốn là ưu tiên hàng đầu. Hiểu được như vậy, mỗi nhân viên sẽ có được niềm tin từ doanh nghiệp. Đồng thời, hạn chế được những rủi tro phát sinh và có back-up phù hợp nhất cho tình hình hiện tại.
Chuẩn hóa quản lý vĩ mô (Macromanagement)
Quản lý vĩ mô là một hình thức được nhiều doanh nghiệp dành sự quan tâm. Chuẩn hóa quản lý vĩ mô sẽ giúp chính các nhân viên kiểm soát tốt các nhiệm vụ cần phải thực hiện. Tự chủ động theo dõi và báo cáo kết quả. Và đảm bảo đúng trách nhiệm với nhiệm vụ được giao. Những quy tắc riêng được đặt ra khiến họ phải thật sự để tâm đến công việc của mình.
Từ cơ sở đó, hình thành ở họ một tư duy độc lập. Đặc biệt là tinh thần luôn cầu tiến. Họ biết rõ mình cần làm gì, làm vì mục đích nào và đâu sẽ là những đích đến xa hơn. Chính điều đó tạo ra động lực thúc đẩy họ luôn phải cố gắng.
Phép loại trừ là yếu tố được các tổ chức thực hiện nhằm gia tăng tính cạnh tranh. Thực tế mục đích của việc này là tạo ra “lực đẩy” tác động tinh thần. Từ đó, nhân viên nhân thấy các thách thức và tự nỗ lực rèn luyện. Thế nhưng, lưu ý mọi thứ cần có giới hạn. Nếu không, định hướng dẫn dắt và mục tiêu thực hiện quản lý vĩ mô sẽ bị ảnh hưởng.
Khen thưởng luôn là chiến lược tối ưu
Không cần bàn cãi thì ai cũng thừa nhận rằng khen thưởng chính là cách tạo ra động lực tốt nhất dành cho nhân viên. Và tất nhiên, mỗi sự xem xét cần đảm bảo các tiêu. Mỗi quyết định đều dựa trên các hệ giá trị tnương ứng về khả năng, kinh nghiệm, hiệu suất công việc, tiềm năng phát triển,… Việc khen thưởng phải được diễn ra công bằng; đảm bảo tính hợp lý trong thị trường phát triển nghề nghiệp.
Động lực gắn liền với mục tiêu thăng tiến của mỗi nhân viên. Hãy mở ra nhiêu cơ hội để nhân viên thử sức. Họ sẽ cảm nhận được sự quan tâm nhiều hơn từ tổ chức. Đó là động lực lớn giúp họ cải thiện hiệu suất công việc.
Lời kết
Dưới góc nhìn của một chuyên gia, các nhà lãnh đạo nhân sự cần nhìn nhận những thay đổi cũng như mong muốn từ nhân viên. Họ cần một môi trường làm việc thoải mái và đảm bảo những nhu cầu về sự thăng tiến, tính hợp tác,… Rất nhiều thứ cần được nắm bắt qua chính lăng kính của người quản lý. TopDev hi vọng, nhà lãnh đạo sẽ giúp họ tiếp cận với các thách thức tạo ra động lực. Và cho họ niềm tin rằng tổ chức của bạn hoàn hoàn là nơi phù hợp giúp họ gia tăng động lực.
Tuyển Dụng Nhân Tài IT Cùng TopDev Đăng ký nhận ưu đãi & tư vấn về các giải pháp Tuyển dụng IT & Xây dựng Thương hiệu tuyển dụng ngay!
Hotline: 028.6273.3496 – Email: contact@topdev.vn
Dịch vụ: https://topdev.vn/page/products
Chúng ta thường nghĩ rằng mình quá già để học thêm kiến thức mới hay quá lớn tuổi để nhảy việc. Thật ra tuổi tác chưa bao giờ là giới hạn để ta đạt được thứ mình muốn hay tiếp thu thêm kiến thức, như một ngôn ngữ lập trình mới chẳng hạn?
Tôi đã chứng kiến nhiều người trên 30 tuổi mới bắt đầu học về Java. Sự thật là càng lớn tuổi bạn càng có nhiều kinh nghiệm và khôn ngoan hơn khi tiếp thu, chọn lọc những kiến thức mới. Thêm vào đó, IT là lĩnh vực ít bị tác động bởi tuổi tác vì ngành này quan trọng kinh nghiệm của lập trình viên hơn.
Học những điều mới khi lớn tuổi sẽ giúp bạn xử lý công việc tốt hơn
Các nghiên cứu y khoa gần đây của Cesar Quililan đã chứng minh được ảnh hưởng đáng kể của hoạt động não bộ đối với quá trình lão hóa và sức khỏe não bộ. Nghĩa là nếu bạn càng rèn luyện trí não nhiều đầu óc bạn sẽ càng minh mẫn hơn. Nghiên cứu cũng chỉ ra rằng những người ở độ tuổi 60 – 90 đã cải thiện sức khỏe não bộ của họ chỉ bằng cách làm đồ thủ công mỹ nghệ và một số sở thích chỉ vài giờ mỗi ngày. Vậy bạn có thể tưởng tượng xem bộ não của một người 30 tuổi sẽ còn làm được nhiều việc như thế nào?
Khi học một ngôn ngữ lập trình mới não bộ sẽ rèn luyện khả năng suy nghĩ và vận dụng đầu óc, từ đó tăng sự tập trung và chú ý của bạn. Một người đàn ông 32 tuổi chia sẻ trên Reddit rằng trước đây anh ấy không hề biết về lập trình hay kỹ năng nào, tuy nhiên hiện tại anh ấy đang học lập trình ở trường đại học. Dù bắt đầu có nhiều khó khăn nhưng giờ đây đầu óc anh ấy đã nhạy bén hơn rất nhiều. Và chẳng ai quan tâm xem anh ấy bao nhiêu tuổi cả!
Có rất nhiều khóa học và tài liệu học trực tuyến – ở đó chẳng ai quan tâm đến tuổi của bạn!
Học trực tuyến không còn là khái niệm mới và thậm chí nhiều người còn cảm thấy nó hiệu quả hơn cả học offline. Ngành IT coi trọng kiến thức và kỹ năng hơn là khả năng thể chất của bạn. Nếu thật sự muốn học hỏi bạn sẽ thành công và đạt được công việc mơ ước rất nhanh.
Dưới đây là những nền tảng trực tuyến mà bạn có thể sử dụng để học thêm Java:
CodeGym – cung cấp khóa học lập trình Java trực tuyến với 80% tiết học thực hành, được thiết kế cho các beginner.
CodeAcademy – chương trình này cung cấp các kỹ năng mang tính kỹ thuật rất hữu ích trong công việc tương lai của bạn.
Khi bạn bắt đầu học hay tìm hiểu ngành lập trình, bạn vẫn cần tham khảo thêm khá nhiều các nguồn kiến thức hay kinh nghiệm từ những dev đi trước. Đây là một số trang web cung cấp nhiều kiến thức về ngôn ngữ lập trình Java mà bạn có thể tham khảo:
Java subreddit là nền tảng chia sẻ các giải pháp và kinh nghiệm về các vấn đề liên quan đến Java.
Java world là nền tảng chứa rất nhiều tin tức, blog, chia sẻ của chuyên gia liên quan đến Java.
Programming subreddit là nền tảng cho phép bạn đặt câu hỏi hoặc được giải đáp các thắc mắc liên quan đến việc lập trình.
Java Forum là một diễn đàn quen thuộc của các dev có nhiều chủ đề và được chia thành từng phần để tìm kiếm nhanh hơn.
Java Geek là một chương trình mà bạn có thể tìm thấy những lời giải thích rõ ràng về một trường hợp hoặc một vấn đề cụ thể, ngoài ra nó còn được chia thành các danh mục tương tác với các lĩnh vực công nghệ khác nhau.
CodeGym Help là một cộng đồng dành cho những beginner, nơi họ có thể chia sẻ những khó khăn và được hỗ trợ kịp thời.
Bench Resources là nơi các tập hợp các vấn đề liên quan đến Java.
Ngoài ra còn có các khóa học video trực tuyến trên Coursera hoặc Udemy – đây là những nền tảng bao gồm các khóa học trực tuyến từ các trường đại học ở khắp nơi trên thế giới, dành cho nhiều đối tượng khác nhau.
Bên cạnh đó, còn có một nguồn kiến thức quan trọng khác mà bạn không nên bỏ qua đó là sách. Bạn có thể tham khảo một số cuốn như:
Head First Java by Kathy Sierra & Bert Bates: Các tác giả của sách này cố gắng truyền tải những kiến thức họ có bằng một ngôn ngữ đơn giản và nội dung trực quan cho người đọc tìm hiểu về Java.
Java: A Beginner’s Guide by Herbert Schildt: mô tả những điều cơ bản của ngôn ngữ lập trình Java theo thứ tự từ dễ đến khó, cho phép người dùng hiểu và đi sâu vào ngôn ngữ Java ngay từ đầu.
Đây chỉ là một ít trong số rất nhiều nguồn khác nhau về ngôn ngữ lập trình Java mà bạn có thể học. Hãy tìm hiểu về nó ngay khi có thể vì chẳng ai quan tâm đến tuổi tác của bạn cả mà họ chỉ quan tâm đến những gì bạn biết mà thôi.
Tuổi tác không liên quan
Tuổi tác chỉ là con số. Nhưng nhiều người lại có suy nghĩ sẽ gắn bó với một công việc cho đến cuối đời. Hãy thay đổi quan điểm này và bắt đầu làm mọi thứ mà bạn muốn, hãy bắt đầu học lập trình nếu bạn muốn trở thành lập trình viên.
Đừng so sánh với người khác. Bạn và người đó có xuất phát điểm và kinh nghiệm làm việc khác nhau. Thay vào đó, hãy tự so sánh mình của hiện tại với trước đây, nếu chăm chỉ luyện tập bạn sẽ thấy rõ sự tiến bộ của mình.
Và đừng bao giờ sợ code xấu hay thiếu kinh nghiệm vì dù ở độ tuổi nào chăng nữa chúng ta vẫn mắc lỗi khi mới bắt đầu công việc và sẽ dần cải thiện khi trau dồi kỹ năng nhiều hơn. Các công ty tuyển dụng đều yêu cầu ứng viên có kinh nghiệm ở mức tối thiểu và sẽ cải thiện thêm trong quá trình làm việc. Vì chúng ta không thể học tất cả mọi thứ chỉ trong một lần, thời gian là điều cần thiết để mọi người nâng cao “tay nghề” của mình.
Học Java cũng giống như học các kỹ năng khác mà thôi
Học Java cũng không khác gì tập đi xe đạp, chỉ là bạn sẽ lo lắng nhiều hơn khi học đi xe đạp ở tuổi trưởng thành. Ở tuổi trưởng thành bạn sẽ còn có nhiều kinh nghiệm hơn khi đối mặt với những khó khăn và biết cách vượt qua nó tốt hơn.
Không thời điểm nào học ngôn ngữ java tốt hơn ngay bây giờ
Đừng trì hoãn những dự định của bạn, hãy bắt tay vào thực hiện ngay khi có thể vì sẽ không bao giờ có thời gian thích hợp hơn ngay bây giờ cả. Bạn sẽ lãng phí thời gian nếu chờ đợi đến lúc thích hợp. Thậm chí khi càng lớn tuổi hơn bạn sẽ càng hoài nghi nhiều hơn với những thứ mình làm. Mạnh mẽ và dám đối mặt sẽ giúp bạn sớm đạt được thành công.
Kết luận
Không bao giờ là quá muộn để bắt đầu học ngôn ngữ lập trình Java hay bất cứ ngôn ngữ lập trình nào khác. Hãy bắt đầu càng sớm càng tốt vì IT là ngành rất coi trọng kiến thức và kĩ năng. Đủ bản lĩnh sẽ giúp bạn thành công trong công việc lập trình viên này.
Bài viết được sự cho phép của tác giả Nguyễn Việt Hưng
Django và Flask là hai web-framework phổ biến nhất – thành công nhất của Python. Ngày này, khi nhìn các bảng tuyển dụng, sẽ thường thấy yêu cầu Django để làm web nhưng Flask dần trở thành công cụ quen thuộc của giới làm data. Nếu ai có hỏi “nên học cái nào” thì câu trả lời chuẩn nhất chỉ có một: nên học cả hai.
Một framework là một bộ thư viện, thường gồm nhiều tính năng phục vụ đưa ra sản phẩm cuối cùng chạm tới người dùng. Ví dụ requests là một library, chỉ cung cấp tính năng HTTP client, hay bs4 chỉ cung cấp tính năng bóc tách/ truy cập dữ liệu HTML, hay sqlalchemy là library giúp truy cập và tương tác với database, thì Flask/Django cung cấp một bộ khung kèm các “thư viện” để làm ra một sản phẩm tới tay người dùng (trang web). Frame trong tiếng Anh có nghĩa là “khung”, framework cung cấp cái khung, lập trình viên điền những thứ mình muốn vào đó, framework sẽ tự lo chạy. Vì vậy khi dùng framework, sẽ có cảm giác như ta không biết nó hoạt động thế nào, chỉ biết là điền đúng những thứ yêu cầu thì nó sẽ hoạt động.
Django là framework đầy đủ (full-fledge), có đủ mọi thứ, nên sẽ càng có thêm cảm giác ta chỉ điền chút xíu là nó tự chạy, mọi thứ đều có khuôn mẫu sẫn rồi. Flask là micro-framework, chỉ có phần khung cơ bản, các phần còn lại cho phép người dùng tùy chọn mà đắp vào, vậy nên có phần dễ hiểu hơn, ít phép màu hơn.
Cũng vì sự khác biệt này, dẫn tới tài liệu trang chủ của 2 framework viết rất khác nhau. Flask vào đời bằng một website dùng 7 dòng code, khiến người dùng rất dễ học, dễ bắt đầu với sự đơn giản này. Còn Django lại dùng ví dụ phức tạp, mặc định người dùng sẽ cần làm thứ “phức tạp” như vậy nên học thế cho quen.
Thế nhưng nếu không dựa vào 2 cái tutorial đấy để đánh giá, liệu Django có phức tạp hơn Flask, hay thậm chí còn đơn giản hơn? Bài nầy sẽ dựa trên 2 yếu tố để so sánh: 1. số khái niệm bạn cần biết 2. số dòng code bạn cần viết.
Bắt đầu.
Cài đặt
Cài đặt Flask
pip install flask
Cài đặt Django
pip install django
Kết quả: hòa, dễ như nhau: Flask 1 - Django 1
Viết một website hello world và hello mình
Flask
Tạo 1 file tên bất kỳ nhưng tốt nhất đặt là hello.py (tuyệt đối không đặt là flask.py do trùng tên flask)
Điểm ấn tượng nhất ở đây là chỉ có 10 dòng, trong đúng 1 file, mà chạy thành trang web.
Tổng số thao tác phải làm: 3 – tạo 1 file, điền nội dung, gõ lệnh để chạy.
Django
Django không làm web trong 1 file, nó dùng các câu lệnh có sẵn để sinh ra các file, tức ta chỉ phải gõ lệnh, chứ không phải gõ nhiều code. Gõ 3 lệnh sau là chạy luôn trang web:
$ django-admin startproject project1
$ cd project1/
$ ./manage.py startapp hello
$ ./manage.py runserver
Starting development server at http://127.0.0.1:8000/
Ngay lập tức đã có trang web mẫu của Django – thậm chí chưa gõ tí code nào. Để có kết quả giống Flask ở trên, cần sửa 2 file:
File hello/views.py, viết các function tương tự flask:
fromhelloimportviewsurlpatterns=[# có sẵnpath('admin/',admin.site.urls),# có sẵnpath('',views.hello_world,name='hello_world'),path('hello/<str:name>',views.hello,name='hello'),]# có sẵn
Giờ chạy ./manage runserver sẽ có kết quả y hệt Flask.
So sánh thao tác
Tổng số dòng code phải thêm vào Django là 8 – cũng chính bằng số dòng Flask phải viết – không tính dòng trống. Django phải chạy nhiều hơn 2 lệnh – nhưng chỉ cần phải làm khi bắt đầu dự án. Flask viết code trong 1 file, còn Django phải sửa 2 file. ở đây có thể xem như hòa nhau không bên nào hơn/kém quá cả.
So sánh khái niệm
Phần khác nhau chủ đạo giữa Django và Flask là cách ghi URL. Người dùng Flask tạo một Flask object, đặt tên là app, sau đó sử dụng decorator
@app.route("/hello/<string:name>")
để gắn đường dẫn /hello/name cho function ngay dưới nó (function hello). Decorator không phải một khái niệm đơn giản ở đây, mặc dù người dùng có thể cứ nhắm mắt rồi gõ @ theo và hiểu nôm na là gắn đường dẫn cũng được.
Django chọn giải pháp ghép đường dẫn với function thông qua file urls.py, import module views từ thư mục hello/ (tạo lúc chạy “startapp hello”), sau đó gán đường dẫn bằng cách gọi function path:
Dài dòng hơn Flask một chút là phải ghi name="hello", không có / ở đầu URL, và kiểu str thì ghi là str chứ không ghi string như Flask.
Khi mới bắt đầu, khó có thể thấy lý do Django viết riêng file urls.py để làm gì, khi mà flask @ lên đầu rất gọn ghẽ. Thì tới lúc có 20 URL bạn sẽ hiểu tại sao. Làm thế nào để liệt kê tất cả URL trong app của mình? Các URL của Flask rải rác khắc nơi, mỗi cái nằm trên đầu 1 function, nếu như mỗi function dài 50 dòng, thì việc tìm sẽ khá vất vả – hoặc phải dùng chức năng tìm kiếm, hoặc phải có IDE để hỗ trợ. Còn với Django tất cả đều nằm gọn trong urls.py.
Không hiểu tại sao Flask lại chọn string để ám chỉ kiểu string trong Python, vốn viết là str, Django lại ghi thêm điểm ở đây.
Có thể bạn đã biết, rằng không nhất thiết phải dùng @ trong Flask, bởi decorator này chỉ làm đơn giản có 1 việc: giống Django. Thay vì viết hai dòng @app.route trên đầu function, viết hai dòng này SAU khi định nghĩa các function:
Đây chính làm điều mà @app.route làm, như mô tả trong tài liệu của nó:
A decorator that is used to register a view function for a given URL rule. This does the same thing as :meth:add_url_rule but is intended for decorator usage::
Chốt: Django gõ nhiều hơn 2 lệnh, sửa thêm 1 file, nhưng sử dụng ít khái niệm cao cấp hơn Flask. Nếu dễ tính, thì cho là hòa, còn không Django dành chiến thắng ở đây.
Tỉ số: 2 - 2
Thêm trang dùng template
Flask
Tạo 1 thư mục tên templates ngay cạnh file hello.py, rồi tạo file index.html chứa code HTML và Jinja2 template.
Tạo thư mục tên templates/hello trong thư mục hello, sau đó tạo index.html và nội dung copy y hệt phần template của Flask.
Thêm function sau vào hello/views.py
# chú ý render đã được import sẵn ở file view.py ngay khi tạo appdefframeworks(request):returnrender(request,"hello/index.html",{"frameworks":["Flask","Django"]})
Và thêm 1 dòng vào project1/urls.py:
path('web', views.frameworks, name='frameworks'),
Ngoài ra phải thêm 'hello' vào file project1/settings.py Trong list INSTALLED_APPS
INSTALLED_APPS=[...,'hello',]
Phần này lại hòa, template mặc định của Flask là jinja2 tương đương với Django template, kể cả cú pháp cũng rất giống nhau. Django phải thêm 1 dòng vào file settings.py nhưng việc này cũng chỉ phải làm một lần duy nhất (lẽ ra nên làm luôn sau khi createapp từ đầu).
Django app
Khi chạy lệnh startproject ban đầu, nó sinh ra các file cần thiết cho một dự án Django (urls.py, settings.py, manager.py …, và nó chỉ phải chạy duy nhất 1 lần trong 1 dự án. Với Flask, bạn tạo thư mục bằng tay.
Django đưa ra khái niệm có nhiều app trong một dự án. Flask cũng có khái niệm tương tự, gọi là Blueprint. Nó không cần thiết cho ví dụ 6-10 dòng, nhưng khi làm một website nhiều tính năng thì blueprint là cách tổ chức chính thức của Flask, ngay cả trong bài tutorial của Flask cũng dùng luôn khái niệm này. Như vậy chỉ khác nhau việc học trước hay học sau, chứ không phải Flask thì không dùng tới.
Flask không ép (không hướng dẫn) người dùng cách tổ chức code, khi dự án lớn dần lên, có 3-5000 dòng code, ắt phải sinh ra file mới, phải sắp xếp, tổ chức sao cho hợp lý – mà thế nào là hợp lý thì không phải ai cũng tìm ngay ra cách. Dự án Flask khi rơi vào tay lập trình viên chưa có nhiều kinh nghiệm làm web sẽ dẫn tới code mỗi thứ một nơi, đi tìm cũng thấy mệt. Flask không hướng dẫn người dùng ngay từ đầu, nếu gặp phải người chưa có kinh nghiệm tổ chức, sẽ trở thành vô tổ chức.
Django bắt đầu bằng việc đặt mỗi thứ vào một nơi quy định sẵn, ban đầu có vẻ hơi phiền phức, nhưng sự gọn gàng ngăn nắp sẽ trả lợi ích rõ ràng về sau. Bạn có thể xem 10 dự án Django, cấu trúc đều như nhau, như mẫu của Django, thì 10 dự án Flask mỗi cái một kiểu.
Tỉ số: Flask 2 – Django 3
Thêm Database, thêm tính năng đăng nhập, thêm trang admin
Đến đây, việc của người dùng Django là mở tài liệu ra, đọc phần model, đọc phần admin page rồi làm theo hướng dẫn, đầy đủ hàng trăm tính năng có sẵn, thì người dùng Flask lại phải lo đi tìm:
dùng database nào? nếu dùng MySQL thì dùng driver nào?
có dùng ORM không? nếu có thì phải học SQLAlchemy, tương đương với học Django ORM
dùng SQLAlchemy rồi có phải dùng flask-sqlalchemy không (có).
khi đổi schema table (thêm/bớt/sửa cột trong 1 SQL table) thì phải làm thế nào? MigrateDB thì dùng cái gì? (Flask-Migrate / alembic)
Viết trang admin (ví dụ website quản lý sinh viên thì đây là trang để thêm/bớt/sửa/xóa sinh viên) thì viết ra sao (có thể dùng flask-admin)
Đăng nhập thì làm thế nào? (flask-httpauth)
Nhập/validate form thì dùng cái chi? (WTForm)
… tiếp tục …
Tỉ số: Flask 2 – Django 4
Kết quả
Hòa.
Hành động của chúng ta
pip install django dùng ngay và luôn thôi.
Kết luận
Bài này không nói Django hoàn hảo, dùng cho mọi trường hợp. Ví dụ nếu website của bạn không dùng database, không cần trang admin (như web của data science) thì Flask nhanh, nhẹ hơn Django nhiều phần. Hay khi bạn biết mình đang làm gì, biết đủ những thư viện để dùng ghép lại xịn hơn cả những gì Django có sẵn, thì Flask là lựa chọn tuyệt hảo. Flask không phải đồ chơi, phần core của Uber đã từng được viết bằng Flask, Airflow – công cụ không thể thiếu trong các hệ thống data cũng chính là một sản phẩm dùng Flask. Vậy nên, hãy học cả 2, nhé. Và nhớ là, Django không hề khó như bạn tưởng.
Lập trình đa luồng (Multi-threading) là một kỹ thuật trong lập trình mà một ứng dụng có thể thực thi nhiều phần công việc (luồng – thread) một cách đồng thời. Trong Java, đa luồng là một tính năng mạnh mẽ và quan trọng, giúp các ứng dụng có thể tận dụng tối đa tài nguyên CPU và giảm thời gian xử lý bằng cách thực thi nhiều tác vụ cùng lúc.
Java cung cấp hỗ trợ sẵn có cho lập trình đa luồng thông qua lớp Thread và giao diện Runnable. Việc sử dụng đa luồng trong Java giúp tăng cường hiệu suất và cải thiện tính đáp ứng (responsiveness) của ứng dụng, đặc biệt trong các ứng dụng yêu cầu xử lý song song hoặc thời gian thực.
Khái niệm thread trong Java
Thread là gì?
Thread (luồng) về cơ bản là một tiến trình con (sub-process). Một đơn vị xử lý nhỏ nhất của máy tính có thể thực hiện một công việc riêng biệt. Trong Java, các luồng được quản lý bởi máy ảo Java (JVM).
Multi-thread là gì?
Multi-thread (đa luồng) là một tiến trình thực hiện nhiều luồng đồng thời. Một ứng dụng Java ngoài luồng chính có thể có các luồng khác thực thi đồng thời làm ứng dụng chạy nhanh và hiệu quả hơn.
VD: Trình duyệt web hay các chương trình chơi nhạc là 1 ví dụ điển hình về đa luồng.
+ Khi duyệt 1 trang web, có rất nhiều hình ảnh, CSS, javascript… được tải đồng thời bởi các luồng khác nhau.
+ Khi play nhạc, chúng ta vẫn có thể tương tác được với nút điều khiển như: Play, pause, next, back … vì luồng phát nhạc là luồng riêng biệt với luồng tiếp nhận tương tác của người dùng.
Multitasking: Là khả năng chạy đồng thời một hoặc nhiều chương trình cùng một lúc trên một hệ điều hành. Hệ điều hành quản lý việc này và sắp xếp lịch phù hợp cho các chương trình đó. Ví dụ, trên hệ điều hành Windows chúng ta có làm việc đồng thời với các chương trình khác nhau như: Microsoft Word, Excel, Media Player, …
Chúng ta sử dụng đa nhiệm để tận dụng tính năng của CPU.
Đa nhiệm có thể đạt được bằng hai cách:
Đa nhiệm dựa trên đơn tiến trình (Process) – Đa tiến trình (Multiprocessing).
Mỗi tiến trình có địa chỉ riêng trong bộ nhớ, tức là mỗi tiến trình phân bổ vùng nhớ riêng biệt.
Tiến trình là nặng.
Sự giao tiếp giữa các tiến trình có chi phí cao.
Chuyển đổi từ tiến trình này sang tiến trình khác đòi hỏi thời gian để đăng ký việc lưu và tải các bản đồ bộ nhớ, các danh sách cập nhật, …
Đa nhiệm dựa trên luồng (Thread) – Đa luồng (MultiThreading).
Các luồng chia sẻ không gian địa chỉ ô nhớ giống nhau.
Luồng là nhẹ.
Sự giao tiếp giữa các luồng có chi phí thấp.
Đa tiến trình (multiprocessing) và đa luồng (multithreading) cả hai được sử dụng để tạo ra hệ thống đa nhiệm (multitasking). Nhưng chúng ta sử dụng đa luồng nhiều hơn đa tiến trình bởi vì các luồng chia sẻ một vùng bộ nhớ chung. Chúng không phân bổ vùng bộ nhớ riêng biệt để tiết kiệm bộ nhớ, và chuyển đổi ngữ cảnh giữa các luồng mất ít thời gian hơn tiến trình.
Đầu tiên, đa luồng giúp tăng hiệu suất của ứng dụng bằng cách chạy song song nhiều tác vụ. Thay vì thực hiện tuần tự, các tác vụ có thể xử lý đồng thời, tận dụng tối đa CPU, đặc biệt trong môi trường đa lõi (multi-core). Mỗi luồng có thể dùng chung và chia sẻ nguồn tài nguyên trong quá trình chạy, nhưng có thể thực hiện một cách độc lập.
Đa luồng còn giúp cải thiện tính đáp ứng của ứng dụng. Trong các ứng dụng giao diện người dùng (UI), việc sử dụng đa luồng tránh tình trạng ứng dụng bị “treo” khi thực hiện các tác vụ dài, từ đó cải thiện trải nghiệm người dùng. Điều này rất quan trọng khi cần thực hiện các tác vụ nặng như tải dữ liệu hoặc xử lý I/O.
Ngoài ra, đa luồng hỗ trợ xử lý đồng thời nhiều yêu cầu. Đối với các hệ thống máy chủ hoặc ứng dụng web, đa luồng cho phép xử lý nhiều yêu cầu của người dùng cùng lúc, giảm thời gian chờ đợi và tăng khả năng phục vụ. Các luồng cũng chia sẻ tài nguyên bộ nhớ, giúp tiết kiệm tài nguyên so với việc tạo nhiều tiến trình riêng biệt.
Nhược điểm của đa luồng trong Java
Tuy nhiên, lập trình đa luồng có một số nhược điểm lớn. Độ phức tạp của nó là một trong những thách thức lớn nhất. Khi làm việc với nhiều luồng, lập trình viên phải xử lý đồng bộ hóa, phối hợp luồng và tránh các lỗi như deadlock (tình trạng chết) hoặc race condition (điều kiện cạnh tranh). Điều này đòi hỏi kỹ năng cao và kinh nghiệm.
Đồng bộ hóa dữ liệu giữa các luồng cũng là một vấn đề quan trọng. Khi nhiều luồng truy cập chung một tài nguyên, nếu không đồng bộ đúng cách, dữ liệu có thể bị thay đổi ngoài ý muốn, dẫn đến lỗi. Đồng bộ hóa giúp ngăn chặn tình trạng này, nhưng nó làm giảm hiệu suất vì các luồng phải chờ nhau. Đồng thời, nếu đồng bộ không chính xác, có thể gây ra tình trạng deadlock, khi các luồng bị khóa lẫn nhau và không thể tiếp tục thực thi.
Deadlock (Khoá chết) là gì? Deadlock xảy ra khi 2 tiến trình đợi nhau hoàn thành, trước khi chạy. Kết quả của quá trình là cả 2 tiến trình không bao giờ kết thúc
Một vấn đề khác là race condition, khi nhiều luồng cùng thao tác với một tài nguyên mà không kiểm soát đúng cách. Điều này có thể dẫn đến dữ liệu không chính xác hoặc bị hỏng.
Cuối cùng, lập trình đa luồng còn dẫn đến tăng sử dụng tài nguyên. Mỗi luồng yêu cầu bộ nhớ và CPU riêng, và khi có quá nhiều luồng, việc chuyển đổi giữa các luồng (context switching) làm giảm hiệu suất tổng thể của hệ thống.
Vòng đời (các trạng thái) của một Thread trong Java
Vòng đời của thread trong java được kiểm soát bởi JVM. Java định nghĩa các trạng thái của luồng trong các thuộc tính static của lớp Thread.State:
NEW : Đây là trạng thái khi luồng vừa được khởi tạo bằng phương thức khởi tạo của lớp Thread nhưng chưa được start(). Ở trạng thái này, luồng được tạo ra nhưng chưa được cấp phát tài nguyên và cũng chưa chạy. Nếu luồng đang ở trạng thái này mà ta gọi các phương thức ép buộc stop,resume,suspend … sẽ là nguyên nhân sảy ra ngoại lệ IllegalThreadStateException .
RUNNABLE : Sau khi gọi phương thức start() thì luồng test đã được cấp phát tài nguyên và các lịch điều phối CPU cho luồng test cũng bắt đầu có hiệu lực. Ở đây, chúng ta dùng trạng thái là Runnable chứ không phải Running, vì luồng không thực sự luôn chạy mà tùy vào hệ thống mà có sự điều phối CPU khác nhau.
WAITING : Thread chờ không giới hạn cho đến khi một luồng khác đánh thức nó.
TIMED_WAITING : Thread chờ trong một thời gian nhất định, hoặc là có một luồng khác đánh thức nó.
BLOCKED: Đây là 1 dạng của trạng thái “Not Runnable”, là trạng thái khi Thread vẫn còn sống, nhưng hiện tại không được chọn để chạy. Thread chờ một monitor để unlock một đối tượng mà nó cần.
TERMINATED : Một thread ở trong trạng thái terminated hoặc dead khi phương thức run() của nó bị thoát.
Cách tạo thread trong Java
Trong java ta có thể tạo ra một luồng bằng một trong hai cách sau: tạo 1 đối tượng của lớp được extend từ class Thread hoặc implements từ interface Runnable.
Tạo luồng bằng cách extend từ lớp Thread
Để tạo luồng bằng cách tạo lớp kế thừa từ lớp Thread, ta phải làm các công việc sau :
Khai báo 1 lớp mới kế thừa từ lớp Thread
Override lại phương thức run ở lớp này, những gì trong phương thức run sẽ được thực thi khi luồng bắt đầu chạy. Sau khi luồng chạy xong tất cả các câu lệnh trong phương thức run thì luồng cũng tự hủy.
Tạo 1 thể hiện (hay 1 đối tượng) của lớp ta vừa khai báo.
Sau đó gọi phương thức start() của đối tượng này để bắt đầu thực thi luồng.
package com.gpcoder.simple;
public class TheadSimple extends Thread {
public void run() {
System.out.println("thread is running...");
}
public static void main(String args[]) {
TheadSimple t1 = new TheadSimple();
t1.start();
}
}
Lưu ý :
Tuy ta khai báo những công việc cần làm của luồng trong phương thức run() nhưng khi thực thi luồng ta phải gọi phương thức start(). Vì đây là phương thức đặc biệt mà java xây dựng sẵn trong lớp Thread, phương thức này sẽ cấp phát tài nguyên cho luồng mới rồi chạy phương thức run() ở luồng này. Vì vậy, nếu ta gọi phương thức run() mà không gọi start() thì cũng tương đương với việc gọi 1 phương thức của 1 đối tượng bình thường và phương thức vẫn chạy trên luồng mà gọi phương thức chứ không chạy ở luồng mới tạo ra, nên vẫn chỉ có 1 luồng chính làm việc chứ ứng dụng vẫn không phải là đa luồng.
Sau khi start một thread, nó không bao giờ có thể được start lại. Nếu bạn làm như vậy, một ngoại lệ IllegalThreadStateException sẽ xảy ra.
Tạo luồng bằng cách implement từ Interface Runnable
Để tạo luồng bằng cách hiện thực từ Interface Runnable, ta phải làm các công việc sau :
Khai báo 1 lớp mới implements từ Interface Runnable
Hiện thực phương thức run() ở lớp này, những gì trong phương thức run() sẽ được thực thi khi luồng bắt đầu chạy. Sau khi luồng chạy xong tất cả các câu lệnh trong phương thức run thì luồng cũng tự hủy.
Tạo 1 thể hiện (hay 1 đối tượng) của lớp ta vừa khai báo. (VD : Tên đối tượng là r1)
Tạo 1 thể hiện của lớp Thread bằng phương thức khởi tạo : Thread(Runnable target)
Runnable target: Là 1 đối tượng thuốc lớp được implements từ giao diện Runnable.
Ví dụ: Thread t1 = new Thread(r1);
Gọi phương thức start() của đối tượng t1.
package com.gpcoder.simple;
public class RunnableSimple implements Runnable {
public void run() {
System.out.println("thread is running...");
}
public static void main(String args[]) {
RunnableSimple runable = new RunnableSimple();
Thread t1 = new Thread(runable);
t1.start();
}
}
Khi nào implements từ interface Runnable?
+ Cách hay được sử dụng và được yêu thích là dùng interface Runnable, bởi vì nó không yêu cầu phải tạo một lớp kế thừa từ lớp Thread. Trong trường hợp ứng dụng thiết kế yêu cầu sử dụng đa kế thừa, chỉ có interface mới có thể giúp giải quyết vấn đề. Ngoài ra, Thread Pool rất hiểu quả và có thể được cài đặt, sử dụng rất hơn giản.
+ Trong trường hợp còn lại ta có thể kế thừa từ lớp Thread.
Ví dụ minh họa sử dụng đa luồng
Ví dụ Tạo luồng bằng cách extend từ class Thread
Tạo luồng extend từ class Thead
package com.gpcoder.flow;
public class ThreadDemo extends Thread {
private Thread t;
private String threadName;
ThreadDemo(String name) {
threadName = name;
System.out.println("Creating " + threadName);
}
@Override
public void run() {
System.out.println("Running " + threadName);
try {
for (int i = 4; i > 0; i--) {
System.out.println("Thread: " + threadName + ", " + i);
// Let the thread sleep for a while.
Thread.sleep(50);
}
} catch (InterruptedException e) {
System.out.println("Thread " + threadName + " interrupted.");
}
System.out.println("Thread " + threadName + " exiting.");
}
public void start() {
System.out.println("Starting " + threadName);
if (t == null) {
t = new Thread(this, threadName);
t.start();
}
}
}
Chương trình sử dụng đa luồng:
package com.gpcoder.flow;
public class ThreadDemoTest {
public static void main(String args[]) {
System.out.println("Main thread running... ");
ThreadDemo T1 = new ThreadDemo("Thread-1-HR-Database");
T1.start();
ThreadDemo T2 = new ThreadDemo("Thread-2-Send-Email");
T2.start();
System.out.println("==> Main thread stopped!!! ");
}
}
Kết quả chương trình trên được giải thích thông qua hình bên dưới:
Các phương thức của lớp Thread thường hay sử dụng
suspend() : Đây là phương thức làm tạm dừng hoạt động của 1 luồng nào đó bằng các ngưng cung cấp CPU cho luồng này. Để cung cấp lại CPU cho luồng ta sử dụng phương thức resume(). Cần lưu ý 1 điều là ta không thể dừng ngay hoạt động của luồng bằng phương thức này. Phương thức suspend() không dừng ngay tức thì hoạt động của luồng mà sau khi luồng này trả CPU về cho hệ điều hành thì không cấp CPU cho luồng nữa.
resume() : Đây là phương thức làm cho luồng chạy lại khi luồng bị dừng do phương thức suspend() bên trên. Phương thức này sẽ đưa luồng vào lại lịch điều phối CPU để luồng được cấp CPU chạy lại bình thường.
stop() : Luồng này sẽ kết thúc phương thức run() bằng cách ném ra 1 ngoại lệ ThreadDeath, điều này cũng sẽ làm luồng kết thúc 1 cách ép buộc. Nếu giả sử, trước khi gọi stop() mà luồng đang nắm giữa 1 đối tượng nào đó hoặc 1 tài nguyên nào đó mà luồng khác đang chờ thì có thể dẫn tới việc sảy ra deadlock.
destroy() : dừng hẳn luồng.
isAlive() : Phương thức này kiểm tra xem luồng còn active hay không. Phương thức sẽ trả về true nếu luồng đã được start() và chưa rơi vào trạng thái dead. Nếu phương thức trả về false thì luồng đang ở trạng thái “New Thread” hoặc là đang ở trạng thái “Dead”
yeild() : Hệ điều hành đa nhiệm sẽ phân phối CPU cho các tiến trình, các luồng theo vòng xoay. Mỗi luồng sẽ được cấp CPU trong 1 khoảng thời gian nhất định, sau đó trả lại CPU cho hệ điều hành (HĐH), HĐH sẽ cấp CPU cho luồng khác. Các luồng sẽ nằm chờ trong hàng đợi Ready để nhận CPU theo thứ tự. Java có cung cấp cho chúng ta 1 phương thức khá đặc biệt là yeild(), khi gọi phương thức này luồng sẽ bị ngừng cấp CPU và nhường cho luồng tiếp theo trong hàng chờ Ready. Luồng không phải ngưng cấp CPU như suspend mà chỉ ngưng cấp trong lần nhận CPU đó mà thôi.
sleep(long) : tạm dừng luồng trong một khoảng thời gian millisecond.
join() : thông báo rằng hãy chờ thread này hoàn thành rồi thread cha mới được tiếp tục chạy.
join(long) : Thread cha cần phải đợi millisecond mới được tiếp tục chạy, kể từ lúc gọi join(long). Nếu tham số millis = 0 nghĩa là đợi cho tới khi luồng này kết thúc.
getName() : Trả về tên của thread.
setName(String name) : Thay đổi tên của thread.
getId() : Trả về id của thread.
getState(): trả về trạng thái của thread.
currentThread() : Trả về tham chiếu của thread đang được thi hành.
getPriority() : Trả về mức độ ưu tiên của thread.
setPriority(int) : Thay đổi mức độ ưu tiên của thread.
isDaemon() : Kiểm tra nếu thread là một luồng Daemon.
setDaemon(boolean): xác định thread là một luồng Daemon hay không.
interrupt() : làm gián đoạn một luồng trong java. Nếu thread nằm trong trạng thái sleep hoặc wait, nghĩa là sleep() hoặc wait() được gọi ra. Việc gọi phương thức interrupt() trên thread đó sẽ phá vỡ trạng thái sleep hoặc wait và ném ra ngoại lệ InterruptedException. Nếu thread không ở trong trạng thái sleep hoặc wait, việc gọi phương thức interrupt() thực hiện hành vi bình thường và không làm gián đoạn thread nhưng đặt cờ interrupt thành true.
isInterrupted() : kiểm tra nếu thread đã bị ngắt.
interrupted() : kiểm tra nếu thread hiện tại đã bị ngắt.
Một số thông tin liên quan đến luồng
Định danh của luồng (ThreadId)
ThreadId là định danh của luồng, nó dùng để phân biệt với các luồng khác cùng tiến trình hoặc cùng tập luồng. Đây là thông số mà máy ảo java tự tạo ra khi ta tạo luồng nên ta không thể sửa đổi cũng như áp đặt thông số này khi tạo luồng. Nhưng ta có thể lấy được nó thông qua phương thức getId() của lớp Thread
Tên của luồng (ThreadName)
ThreadName là tên của luồng, đây là thuộc tính mà ta có thể đặt hoặc không đặt cho luồng. Nếu ta không đặt cho luồng thì máy ảo java sẽ tự đặt với quy tắc sau: “Thread-” + Thứ tự luồng được tạo ra, bắt đầu từ 0.
Độ ưu tiên của luồng (Priority)
Như đã nói ở phần trước, mỗi luồng có 1 độ ưu tiên nhất định. Đây sẽ là thông số quyết định mức ưu tiên khi cấp phát CPU cho các luồng.
Trong java, đế đặt độ ưu tiên cho 1 luồng ta dùng phương thức: void setPriority(int newPriority)
int newPriority : Là giá trị từ 1 đến 10.
Java có định nghĩa sẵn 3 mức ưu tiên chuẩn như sau:
Thread.MIN_PRIORITY (giá trị 01)
hread.NORM_PRIORITY (giá trị 05)
Thread.MAX_PRIORITY (giá trị 10)
Để lấy độ ưu tiên của 1 luồng, ta dùng phương thức: int getPriority()
Ví dụ minh họa
WorkingThread.java
package com.gpcoder.info;
public class WorkingThread extends Thread {
public WorkingThread(String name) {
super(name);
}
public void run() {
for (int i = 0; i < 5; i++) {
System.out.printf("Luồng: %s có độ ưu tiên là %d \n", getName(), getPriority());
}
}
}
ThreadInfoExample.java
package com.gpcoder.info;
public class ThreadInfoExample {
public static void main(String[] args) {
Thread t1 = new WorkingThread("Luồng 1");
Thread t2 = new WorkingThread("Luồng 2");
Thread t3 = new WorkingThread("Luồng 3");
System.out.println("ID luồng 1: " + t1.getId());
System.out.println("ID luồng 2: " + t2.getId());
System.out.println("ID luồng 3: " + t3.getId());
t1.setPriority(1);
t2.setPriority(5);
t3.setPriority(10);
t1.start();
t2.start();
t3.start();
}
}
Kết quả thực thi chương trình trên:
ID luồng 1: 10
ID luồng 2: 11
ID luồng 3: 12
Luồng: Luồng 2 có độ ưu tiên là 5
Luồng: Luồng 2 có độ ưu tiên là 5
Luồng: Luồng 2 có độ ưu tiên là 5
Luồng: Luồng 2 có độ ưu tiên là 5
Luồng: Luồng 2 có độ ưu tiên là 5
Luồng: Luồng 1 có độ ưu tiên là 1
Luồng: Luồng 3 có độ ưu tiên là 10
Luồng: Luồng 3 có độ ưu tiên là 10
Luồng: Luồng 3 có độ ưu tiên là 10
Luồng: Luồng 3 có độ ưu tiên là 10
Luồng: Luồng 3 có độ ưu tiên là 10
Luồng: Luồng 1 có độ ưu tiên là 1
Luồng: Luồng 1 có độ ưu tiên là 1
Luồng: Luồng 1 có độ ưu tiên là 1
Luồng: Luồng 1 có độ ưu tiên là 1
Sử dụng phương thức sleep()
Phương thức sleep() của lớp Thread được sử dụng để tạm ngừng một thread cho một khoảng thời gian nhất định.
Ví dụ chương trình in ra số từ 1 – 5, tạm ngừng 500 ms trước khi in chữ số tiếp theo.
package com.gpcoder.sleep;
public class SleepMethodExample extends Thread {
public void run() {
for (int i = 1; i <= 5; i++) {
System.out.println(i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String args[]) {
SleepMethodExample t1 = new SleepMethodExample();
t1.start();
}
}
Sử dụng join() và join(long)
join() : thông báo rằng hãy chờ thread này hoàn thành rồi thread cha mới được tiếp tục chạy.
Ví dụ:
package com.gpcoder.join;
public class UsingJoinMethod extends Thread {
public UsingJoinMethod(String name) {
super(name);
}
@Override
public void run() {
System.out.println(getName());
for (int i = 1; i <= 5; i++) {
try {
System.out.print(i + " ");
Thread.sleep(300);
} catch (InterruptedException ie) {
System.out.println(ie.toString());
}
}
System.out.println();
}
public static void main(String[] args) throws InterruptedException {
UsingJoinMethod t1 = new UsingJoinMethod("Thread 1");
UsingJoinMethod t2 = new UsingJoinMethod("Thread 2");
t1.start();
t1.join();
t2.start();
System.out.println("Main Thread Finished");
}
}
join(long) : Thread cha cần phải đợi millisecond mới được tiếp tục chạy, kể từ lúc gọi join(long). Nếu tham số millis = 0 nghĩa là đợi cho tới khi luồng này kết thúc.
package com.gpcoder.join;
public class UsingJoinMethod2 extends Thread {
public UsingJoinMethod2(String name) {
super(name);
}
@Override
public void run() {
System.out.println(getName());
for (int i = 1; i <= 5; i++) {
try {
System.out.print(i + " ");
Thread.sleep(300);
} catch (InterruptedException ie) {
System.out.println(ie.toString());
}
}
System.out.println();
}
public static void main(String[] args) throws InterruptedException {
UsingJoinMethod2 t1 = new UsingJoinMethod2("Thread 1");
UsingJoinMethod2 t2 = new UsingJoinMethod2("Thread 2");
t1.start();
// Main Thread phải chờ 450ms mới được tiếp tục chạy.
// Không nhất thiết phải chờ Thread t1 kết thúc
t1.join(450);
t2.start();
System.out.println("Main Thread Finished");
}
}
Phương thức Thread.setDefaultUncaughtExceptionHandler() thiết lập mặc định xử lý khi luồng đột ngột chấm dứt do một ngoại lệ xảy ra mà không có xử lý khác đã được xác định cho luồng đó.
Ví dụ:
package com.gpcoder.exception;
import java.util.Random;
public class WorkingThread implements Runnable {
@Override
public void run() {
while (true) {
processSomething();
}
}
private void processSomething() {
try {
System.out.println("Processing working thread");
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
Random r = new Random();
int i = r.nextInt(100);
if (i > 70) {
throw new RuntimeException("Simulate an exception was not handled in the thread");
}
}
}
Chương trình minh họa xử lý Thread Exception
package com.gpcoder.exception;
public class ThreadExceptionDemo {
public static void main(String[] args) {
System.out.println("==> Main thread running...");
Thread thread = new Thread(new WorkingThread());
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println("#Thread: " + t);
System.out.println("#Thread exception message: " + e.getMessage());
}
});
thread.start();
System.out.println("==> Main thread end!!!");
}
}
Thực thi chương trình trên:
==> Main thread running...
==> Main thread end!!!
Processing working thread
Processing working thread
Processing working thread
Processing working thread
Processing working thread
Processing working thread
#Thread: Thread[Thread-0,5,main]
#Thread exception message: Have a problem...
Trên đây là những kiến thức cơ bản về luồng (thread) và đa luồng (Multi-thread) trong Java. Chúng ta sẽ tiếp tục tìm hiểu về các vấn đề khác của đa luồng trong Java ở các bài viết tiếp theo. Cám ơn các bạn đã quan tâm và theo dõi bài viết.
Bài viết được sự cho phép của BBT Tạp chí Lập trình
Khi nói đến việc chọn một ngôn ngữ lập trình để học, bạn hẳn sẽ đau đầu bởi số lượng không thể đo đếm được của chúng. Đó là chưa nói đến chuyện mỗi ngôn ngữ lập trình lại có những ứng dụng khác nhau trong đời sống công nghệ.
Chức năng chính của một chương trình máy tính là giải quyết một vấn đề bằng một bộ các tập lệnh (hay mã lệnh). Tuy nhiên, nếu mọi chương trình đều có thể giải quyết các vấn đề, thì tại sao chúng ta lại cần đến quá nhiều chương trình như vậy? Liệu một chương trình có thể làm được mọi thứ hay không? Để trả lời câu hỏi này, hãy cùng tìm hiểu về cách một chương trình máy tính được thực thi.
Phần cứng đảm nhiệm việc tính toán cho chương trình
Hầu như mọi quá trình tính toán dù dưới bất kỳ hình thức nào (với một số ít ngoại lệ) đều được thực hiện trong Bộ xử lý trung tâm (CPU). CPU hiện đại mà chúng ta sử dụng ngày nay có chứa nhiều thành phần vi điện tử. CPU có thể được chia ra thành nhiều đơn vị tính toán nhỏ hơn, gọi là Logical Transistor Gates, hay đơn giản hơn là logic gates (cổng logic). Chức năng chính của cổng logic là thực hiện ba toán tử chính: AND, OR và NOT.
Những toán tử logic nói trên hoạt động trên một hệ thống số là một nhị phân, vốn hoạt động trên một hệ thống số gồm các số 0 và 1. Số 0 báo hiệu không có dòng điện chạy qua bóng bán dẫn, và số 1 báo hiệu có một dòng điện chạy qua bóng bán dẫn.
Điều phi thường nhất ở đây là, chỉ cần kết hợp những toán tử logic nói trên với nhị phân, bạn sẽ có thể diễn tả tất cả các logic chúng ta từng biết, bao gồm các phép toán số học, số nguyên, và gần như mọi thứ khác bạn có thể hình dung ra. Một CPU hiện đại ngày nay có một thứ gọi là vi mã được cài đặt sẵn bên trong. Một vi mã chứa một bộ các tập lệnh cơ bản được dùng để thực hiện các tác vụ phức tạp hơn, gọi là mã máy.
Các cấp độ của phần mềm dùng để thực thi mã lệnh
Ở trên, chúng ta đã biết phần cứng đằng sau quá trình thực thi mã máy. Tiếp theo, hãy nói về các cấp độ của phần mềm cần thiết cho việc thực thi của phần mềm. Chương trình đầu tiên cần đến là Asembler (trình dịch hợp ngữ), có chức năng chuyển đổi ngôn ngữ asembly (hợp ngữ) thành mã máy. Một ngôn ngữ cấp độ assembly là một ngôn ngữ cấp thấp, đóng vai trò như một chương trình trung gian giữa một ngôn ngữ lập trình bậc cao (Python, C++, Java) và mã máy. Biểu đồ bên dưới sẽ cho thấy kiến trúc của bất kỳ phần mềm nào:
Chương trình quan trọng tiếp theo là Compiler (trình biên dịch). Compiler lấy ngôn ngữ bậc cao và chuyển nó thành hợp ngữ, và đôi lúc thành mã máy nữa. Chương trình cuối cùng (hay gói) gắn kết mọi thứ lại cùng nhau là hệ điều hành. Hệ điều hành về cơ bản là một chương trình khởi động khi máy tính khởi động và chạy cho đến khi máy tính tắt đi. Hệ điều hành còn đảm nhiệm việc quản lý các tác vụ phức tạp, như quản lý tập tin, quản lý đầu vào và đầu ra. Hệ điều hành hoạt động liên tục để mỗi khi bạn muốn thực thi một chương trình, bạn không phải gọi nó lên hết lần này đến lần khác. Nó còn giúp quá trình tương tác với các chức năng người dùng trở nên trực quan hơn, thay vì buộc bạn phải giao tiếp với máy tính dưới dạng những con số 0 và 1.
Một ngôn ngữ lập trình không thể đáp ứng được mọi nhu cầu
Như vậy, mọi ngôn ngữ lập trình dù khác nhau vẫn được thực thi theo một dạng giống nhau. Một chương trình chắc hẳn phải đáp ứng được mọi nhu cầu, đúng chứ? Không đâu. Trong một thế giới lý tưởng, chúng ta sẽ chỉ cần một chương trình cho bất kỳ thứ gì. Mọi ngôn ngữ lập trình đúng là đều phục vụ cho mục đích như nhau, dù nó là C++, Java, Python… nhưng tất cả chúng đều cần thiết vì nhiều lý do khác nhau.
Chúng ta cần các ngôn ngữ lập trình khác nhau là bởi mỗi ngôn ngữ lại có một chức năng khác nhau. Khi một ngôn ngữ lập trình được tạo ra, nó được thiết kế với dụng ý làm sao để có được nhiều chức năng nhất có thể, nhưng không một ngôn ngữ lập trình nào có thể làm được mọi thứ cả. Dưới đây là một số ngôn ngữ lập trình và chức năng cụ thể của chúng:
– Java: đây là một phần mềm đa năng chủ yếu được sử dụng cho phát triển Android. Nó đôi lúc còn được dùng để phát triển website và phần mềm nhúng. Nó được xem là một trong những ngôn ngữ lập trình phổ biến nhất.
– C++: một ngôn ngữ lập trình đa năng khác, hậu bối của ngôn ngữ lập trình C nổi tiếng. Nó hiện được sử dụng cho việc phát triển game máy tính với đồ hoạ cao cấp. C++ cực tốt trong khâu quản lý bộ nhớ và vận hành rất mượt mà. Nó còn được dùng để phát triển các hệ điều hành và các ứng dụng desktop.
– Python: lại một phần mềm đa năng khác. Nó không nhanh như các ngôn ngữ lập trình khác, nhưng lại cực kỳ xuất sắc cho phát triển website và xử lý dữ liệu. Thời gian xây dựng chương trình trong Python ngắn hơn nhiều so với các ngôn ngữ lập trình khác.
– HTML/CSS: đây không hẳn là một ngôn ngữ lập trình đa năng, mà chủ yếu được thiết kế để hướng tới việc phát triển website. Các ngôn ngữ như Python, vốn được dùng để tạo ra backend (phần tương tác với cơ sở dữ liệu) của các website, hoạt động bằng cách gửi HTML đến máy chủ. HTML cung cấp cấu trúc cho website, trong khi CSS được dùng để tạo kiểu và sắp xếp lại các thành phần trong website.
– PHP: được dùng để thêm chức năng cho một chương trình HTML. Nó cho phép bạn gọi dữ liệu và tạo HTML theo nhiều cách hữu dụng trước khi gửi đến trình duyệt của người dùng để hiển thị. Các công ty như Facebook sử dụng ngôn ngữ này rất nhiều.
– R: ngôn ngữ này trong vài năm qua đã trở nên khá nổi tiếng trong cộng đồng lập trình. Nó được sử dụng chủ yếu cho phân tích số liệu thống kê và những thứ liên quan mật thiết đến lĩnh vực này.
Như bạn đã thấy, dù mỗi ngôn ngữ lập trình đều được dùng để tính toán một số dạng dữ liệu, mỗi trong số chúng lại có chức năng và tình huống sử dụng riêng. Ngoài ra, việc lựa chọn một ngôn ngữ còn phụ thuộc vào nhu cầu của mỗi người và sự thuần thục của họ đối với những ngôn ngữ cụ thể.
Vì lý do nào đó mà bạn đã chọn Chrome là browser để develop và Developer Tools của trình duyệt này để debug code. Chrome được các lập trình viên yêu thích là nhờ extension chrome hỗ trợ đầy đủ các devtools của hầu hết các framework frontend hiện đại, không bị giới hạn các extension hữu ích như các trình duyệt khác . Thi thoảng bạn mở Console panel để kiểm tra output của program hay Elements panel để check CSS cho DOM.
Mở Developer ToolsConsole trong Chrome devtools
Nhưng bạn đã hiểu tường tận về Chrome DevTool chưa? Thật ra các function trong này khá đỉnh, chúng sẽ giúp bạn đẩy nhanh hiệu suất của mình.
Trước khi bắt đầu mình sẽ nói qua về Command menu. Command menu (trong Chrome) nó cũng tương đồng với Shell (trong Linux), nó cho phép gõ commands để điều khiển Chrome.
Đầu tiên mở Chrome Developer Tools lên sau đó mở Command menu với các phím tắt như sau:
Windows: Ctrl + Shift + P
macOS:Cmd + Shift + P
Hoặc là mở trên trình duyệt luôn cũng được:
Chạy command
Sau khi mở Command panel, mình sẽ có khá nhiều lệnh command để thực hiện các loại function khác nhau:
Command panel
Trước khi đi vào các chức năng ít được nhắc đến thì mình sẽ đề cập đến một tab panel rất nổi tiếng và thần thánh từ nhà Chrome mà các trình duyệt khác hiện chưa có, đó là Lighthouse. Panel này có chức năng kiểm tra được performance, SEO, tốc độ tải cho trang web một cách chi tiết được đánh giá từ Google.
Tính năng chụp màn hình – Screenshot trong Chrome DevTool
Cap một phần màn hình là lệnh khá quen thuộc mà hầu hết ai cũng có software của riêng mình rồi. Nhưng mà liệu nó có đảm bảo các task này không?
Cap màn hình mọi thứ trên web, bao gồm cả phần bị che, không xuất hiện hết trên visual window
Cap chính xác content của DOM elemet
Đây chỉ là 2 requirements cơ bản thường gặp nhất nhưng không dễ gì làm được nếu sử dụng tool screenshot thường, thay vào đó bạn có thể dùng Commands với các lệnh tương ứng:
Screenshot Capture full size screenshot
Screenshot Capture node screenshot
Ví dụ: Mình sẽ ví dụ trên trang https://medium.com/tag/javascript
Sau đó mở Command menu và thực hiện Screenshot Capture full size screenshot
screenshot
Sau đó mình đã có screenshot đầy đủ của trang hiện tại
full size screenshot
Tương tự như vậy nếu bạn muốn chụp screenshot DOM element, bạn có thể dùng tool riêng nhưng cũng không thể cap chính xác được hết, thay vào đó có thể dùng lệnh Capture node screenshot.
Đầu tiên cần chọn element và chạy lệnh.
Capture node screenshot
Và đây là kết quả:
exact screenshot
Tham chiếu kết quả tới phép tính gần nhất trong console
Chúng ta hay phải debug code trong console. Giả dụ bạn muốn biết cách đảo chuỗi JavaScript, sau đó search những thông tin liên quan và tìm thấy dòng code như sau:
'abcde'.split('').reverse().join('')
Tham chiếu kết quả
Dòng code trên đúng là có đảo chuỗi, nhưng bạn chưa hiểu method split()reverse()join() để làm cái gì và kết quả của các bước tiếp theo sẽ là như thế nào. Nếu muốn thực hiện dòng code này từng bước một thì nên viết như sau:
Tham chiếu kết quả
Sau từng đó bước thì chúng ta sẽ biết giá trị trả về của từng method. Trong Console, ta có thể dùng biến thần kỳ $_ để tham chiếu kết quả tới phép tính trước đó.
Tham chiếu kết quả
$_ là kiểu biến khá đặc biệt, giá trị của nó luôn bằng với phép tính liền trước, cách này rất tiện để debug.
Biến $
Gửi lại (Resend) request XHR trong Chrome DevTool
Đối với các dự án frontend vần cần dùng XHR để request tới backend lấy data. Trong trường hợp muốn gửi lại request XHR phải làm sao? Nếu refresh page thì khá cồng kềnh, thực chất mình chỉ cần debug trực tiếp trong Network panel.
[Nói qua về Network panel được coi là điều không thể thiếu đối với Frontend Dev hiện đại khi vấn đề tương tác với api là việc thường xuyên). Network panel của Chrome có nhiều option hữu ích như Mainfest, has blocked cookie, block request, throttling hỗ trợ thay đổi tốc độ mạng theo nhiều chế độ (Online, Mobile, 3G, Flow 3G, ….), ở header options có thể control việc show những option cần thiết.]
Resend XHR
Mở Network panel
chọn nút XHE
Chọn request bạn muốn gửi lại
Phát lại XHR
Resend XHR
Theo dõi tình trạng tải trang
Để tải trang hoàn tất từ đầu có thể mất đến hơn 10 giây, thì đây sẽ là cách monitor trang load như thế nào tại những thời điểm khác nhau. Trong Chrome DevTool có thể lưu lại ảnh screenshoot, chụp lại tốc độ tải trang với Capture Screenshots trong Network panel.
Tùy ý chọn ảnh screenshot sẽ hiển thị kết quả network request với thời điểm tương ứng.
Liệu bạn có thể copy giá trị của một cái biến JavaScript từ nơi khác không? Task này có vẻ bất khả thi nhưng trong Chrome nó có một function gọi là copy giúp bạn sao chép biến. Sau đó đã có thể paste ra bất kỳ đâu.
Copy biến
Copy hình dưới dạng data URL
Có 2 cách xử lý hình ảnh trên trang, một là tải từ link nguồn bên ngoài, và cách kia là mã hóa hình ảnh dưới dạng data URLs.
Khi ta code hình ảnh dưới dạng Data URLs và nhúng trực tiếp vào code sẽ làm giảm số lượng HTTP request cần tạo, từ đó giúp đẩy nhanh tốc độ tải trang. Vậy trong Chrome thì làm thế nào để chuyển từ ảnh sang data URL?
Mảng thế này thì hơi khó nhìn trong console, chưa kể nếu mảng dài hơn với các element phức tạp hơn thì sẽ càng khó hiểu hơn. Cũng may Chrome có tính năng table có thể lập bảng các object của mảng. Và nó cũng khá hữu ích.
Table object arrayTable object array
Kéo thả trong Elements panel
Đôi lúc bạn muốn thay đổi vị trí của các element DOM nào đó trên trang để test UI. Thì với Elements panel bạn có thể kéo thả bất kỳ element HTML nào và thay đổi vị trí của nó trong trang:
drag n drop in elements panel
Ngoài ra Elements còn cho phép edit trực tiếp element DOM, change element hoặc delete.
Truy cập element đang được chọn trong Console
$0 lại là cú pháp thần kỳ khác giúp gọi element đang được chọn trong Element panel.
Trigger CSS pseudo-class trong Chrome DevTool
Pseudo-class trong CSS được dùng để thêm các hiệu ứng đặc biệt lên các element không chỉ ở mặt nội dung mà còn những yếu tố khác như lịch sử của navigator (ví dụ như :visited), trạng thái content (như :check) hoặc vị trí của trỏ chuột (như :hover hiển thị nếu chuột đang rê lên element đó). Elements panel được cập nhật thêm tính năng khi hover kiểm tra phần từ có 1 tooltip hiển thị thông tin của phần tử bao gồm tên class, id, thuộc tính css …,
Ta có thể viết nhiều lớp pseudo-class cho 1 element, sau đó test các kiểu thì trigger trực tiếp trong Elements panel.
Bạn băn khoăn không biết làm gì để deal thương hiệu quả? Bạn e ngại vì thiếu tự tin? Và bạn khó khăn trong việc tìm ra cách thức để deal mức “lương thương lượng”. Đừng lo lắng, bài viết sau đây của TopDev sẽ bật mí với bạn 7 bí kíp chinh phục quá trình deal lương một cách “thần sầu”.
Thương lượng qua tin nhắn & Email – Đừng thiếu chuyên nghiệp như thế!
Bạn ngại phải đối mặt trực tiếp(face to face) với sếp/người quản lý khi muốn đề nghị một mức lương tốt. Tốt đó, vì hầu như ai cũng vậy.
Thế nhưng, việc nỗ lực thương lượng qua tin nhắn hay email là điều cần tránh. Dù bạn có thiếu tự tin cũng không nên hành xử như thế. Bạn sẽ vô tình biến mình thành một nhân viên thiếu chuyên nghiệp.
Thương lương qua tin nhắn hay email cơ bản đã là cách giải quyết kém tinh tế. Bạn sẽ dễ dàng tiếp cận sai cách. Thậm chí nếu kỹ năng chưa hoàn thiện, việc truyền tải mong muốn về lương dễ lệch sang các chiều hướng không tích cực. Ngôn ngữ bạn sử dụng, giọng điệu bạn truyền tải liệu có phù hợp với nhà quản lý? Nếu là một nhân viên thông minh, bạn cần có những cách thức khoa học hơn.
Cụ thể, bạn có thể nói chuyện trực tiếp hoặc thông qua điện thoại. Có rất nhiều công cụ có thể hỗ trợ bạn. Bạn hoàn toàn có thể điều tiết những cảm xúc cá nhân thông qua âm sắc giọng, các hình thức giao tiếp khác nhau như: giao tiếp bằng mắt, giao tiếp bằng ngôn ngữ cơ thể, tốc độ nói,…
Hãy luyện tập chúng trước khi quyết định bước vào cuộc đàm phán về lương.
Quan tâm đến yếu tố sự thật thay vì cảm xúc
Đừng đến gặp nhà quản lý với tâm thế vội vàng! “Tôi nhận thấy bản thân đã đóng góp nhiều thứ”.“Tôi nghĩ mình xứng đáng nhận được một mức lương tốt hơn”. Những cách nói ấy nó sẽ không hiệu quả vì chịu sự chi phối từ cảm xúc cá nhân quá nhiều. Và điều quan trọng, nhà quản lý/cấp trên của bạn dường như không ai quan tâm đến những cảm xúc đang rối loạn của bạn.
Thay vì để cảm xúc lấn át, bạn nên thảo luận với nhà quản lý bằng những minh chứng cụ thể. Hãy dành thời gian tổng hợp và phân tích các nguồn dữ liệu. Sau đó, trình bày với nhà quản lý. Bạn cần thể hiện được các số liệu ấy phản ánh chính xác những thay đổi về tốc độ tăng trưởng về doanh thu, số lượng khách hàng, traffic từ các kênh truyền thông xã hội (Social Media),…
Nếu doanh nghiệp của bạn đang có những dự án lớn, bạn có thể chỉ ra những lợi thế giúp bản thân có thể đảm nhận hoặc hỗ trợ dựa trên hiệu suất làm việc trước đó. Tất nhiên, bạn không nên nói: “Tôi có thể làm được”. Cho dù đó thể hiện sự quyết tâm nhưng nó rất mơ hồ. Thay vào đó, bạn hãy trình bày những nhiệm vụ cụ thể cần thực hiện, càng chi tiết càng hiệu quả. Một bản tóm tắt về kế hoạch hoặc những ý tưởng bất chợt bạn nghĩ ra, nó đều sẽ có ý nghĩa khi thể hiện đúng tầm nhìn chiến lược.
Đừng mãi đề cập đến tình hình hiện tại! Bạn cần đặt ra những câu hỏi thực tế đúng trọng tâm. Đó là cơ sở để bạn tìm ra những vấn đề, khía cạnh còn tồn động những rủi ro ảnh hưởng đến sự tiến độ phát triển của công ty. Hãy làm chủ cuộc hội thoại bằng việc khai thác các thông tin từ nhà quản lý.
Điều này chứng tỏ bạn đang quan tâm đến công ty. Chính lúc này, bạn dễ dàng thương lượng về một mức offer tốt hơn công ty quyết định gia tăng thêm số lương nhiệm vụ.
Hãy cẩn thận vì ranh giời giữa sự thương lượng và những cuộc tranh cãi rất suýt sao. Điều quan trọng là khi thương lượng, bạn cần thể hiện sự nỗ lực hợp tác và làm cách nào để thực hiện hiệu quả những điều này.
Chiến lược thương lương giao tiếp
Để deal lương, bạn cần phải có chiến lược. Và do vậy, việc thiết lập một kế hoạch và hiểu được mục đích của việc làm đó là rất quan trọng. Hãy thiết lập chiến lược và cố gắng hoàn thiện nó một cách tốt nhất.
Intro dạo đầu hãy thể hiện một chút cảm giác về sự hứng khởi. Bạn hãy chia sẻ rằng bạn cảm thấy vui và hào hứng vì có cơ hội trải nghiệm tại đây. Do vậy, bạn cực kỷ mong đợi đồng hành làm việc cùng một team với những đồng đội tuyệt vời. Tiếp đó, chính là thời điểm thích hợp để bạn dẫn dắt qua câu chuyện thương lương.
Cụ thể, bạn có thể áp dụng ý tưởng suy nghĩ dựa trên các thông tin tư duy như dưới đây:
“Vậy tôi có thể chia sẻ về những phúc lợi được không? Tôi nghĩ chắc chắn rằng những nhân viên hoặc một team nếu có nền tảng kiến thức và kỹ năng tốt hơn, họ sẽ nhận được một phúc lợi tốt hơn về lương”. Điều này là khả dĩ. Bởi lẽ, họ tạo ra nhiều giá trị hơn. Họ giúp khai thác và kết nối doanh nghiệp với nhiều thị trường tiềm năng hơn. Đó là sự công bằng dành cho họ.”
Khi chia sẻ với nhà quản lý về các cơ sở, bạn bắt đầu quan tâm đến mục đích chính. Hãy thảo luận về việc bạn đã nỗ lực thế nào với những thành tích cụ thể. Kèm theo đó là những phân tích chuyên sâu để gia tăng tính thuyết phục.
Đừng than vãn – phàn nàn, điều đó thật tệ!
Sẽ là trò cười nếu bạn chỉ mãi nói về những khó khăn của bản thân! Đó là cách thức sai lầm khi deal lương.
Thay vì nói ra những mong muốn cụ thể, bạn hãy dùng cách nói thể hiện bạn cần một sự phù hợp và xứng đáng hơn dựa trên các giá trị của mình.
“I would be more comfortable with”. Cách nói này thật tinh tế và mang giọng điệu tích cực. Đừng quá thẳng thắn! Một lời đề nghị sẽ mang lại hiệu quả; tạo ra sức mạnh đủ khiến đối phương suy nghĩ là một phát ngôn khôn ngoan.
“Tôi thích công việc. Tôi yêu những gì mình làm và thật sự đang nỗ lực cống hiến vì điều đó. Vì thế, tôi nghĩ mình sẽ nhận được một mức lương tốt hơn.”
Một bí quyết quan trọng chính là đảm bảo mức độ trung tính (neutral) trong phát ngôn deal lương của bạn. Hãy nhớ rằng bạn là người bày tỏ lời đề nghị. Chứ không phải là người tấn công cuộc trò chuyện với nhà quản lý.
Tôi muốn thể hiện mình thật giá trị!
Khi mong muốn một mức lương tốt hơn đồng nghĩa bạn phải tạo ra nhiều giá trị hơn cho, cống hiến nhiều hơn. Bạn sẽ chấp nhận làm những task khó hơn, đòi hỏi tính chuyên môn cao. Hãy nói về những gì bạn có thể mang lại cho tổ chức. Tất nhiên, nó phải dựa trên cơ sở là phạm vị khả năng và những thành quả cụ thể trước đó của bạn.
Song với đó, bạn phải thật sự quan tâm đến vấn đề nâng cao kỹ năng – trình độ. Hãy chuẩn bị kỹ lưỡng để đảm bảo rằng nhà quản lý không có quá nhiều sự do dự khi đưa ra quyết định về mức thu nhập tiếp theo của bạn. Bạn không phải là người duy nhất đưa ra lời đề nghị. Mà rất nhiều nhân viên khác cũng mong muốn thế. Do vậy, bạn phải đầu tư cho bản thân để sẵn sàng cho mọi sự cạnh tranh.
Ngoài ra, khi deal lương, bạn có thể hỏi về những điều bạn cần cải thiện để bản thân hoàn thiện hơn. Bạn hỏi không phải vì mục đích tạo thiện cảm, hay giả trân với nhà quản lý. Đó là cách bạn thật sự muốn tìm ra những điều giúp bạn trở nên giá trị hơn. Nắm vững những chiến lược này, bạn sẽ tự tin hơn trong việc thương lương với nhà quản lý.
Kết nối sự đồng điệu
Đây là cách thức bạn giao tiếp kết hợp với việc điều tiết cảm xúc qua những phát ngôn mô tả.
Cụ thể, bạn sẽ chia sẻ với nhà quản lý bằng chuỗi các phát ngôn có sự kết nối với nhau.
Hãy bắt đầu bằng việc bạn muốn trở thành một team có giá trị trong một tổ chức. Bạn ở đây vì công việc. Và cụ thể, chính là theo đuổi mục tiêu nghề nghiệp và phát triển nó. Bạn cần một mức offer tốt hơn để tạo ra động lực cho những nỗ lực tiếp theo. Bạn có thể đảm nhận những mục tiêu mà công ty đang lên kế hoạch thực hiện. Tuy đó là một quá trình dài nhưng bạn sẽ cố gắng. Hãy thể hiện rằng bạn cũng mong muốn nhận được sự cố vấn, hỗ trợ từ nhà quản lý.
Bạn chấp nhận việc tăng KPI và cam kết cho những thành tích tiếp theo trong một phạm vị khả năng có thể đảm nhận. Tất nhiên, bạn làm điều này không phải chỉ để được tăng lương. Mà lý do thật sự chính là tạo sự gắn kết với cấp trên – những người lãnh đạo. Và bạn nghĩ, bạn xứng đáng nhận được điều đó dựa trên quá trình phát triển của mình.
Lời kết
Deal lương – một mức lương thương lượng là điều không dễ dàng. Hơn hết. bạn cần tìm hiểu, bản thân mình đã làm tốt hay chưa? Đâu là những giá trị bản thân mình đang sở hữu? Và TopDev mong rằng, bạn sẽ hoàn thiện nó. Hãy cho nhà quản lý thấy rằng sự thể hiện (Performance) của bạn đang tiến bộ và phát triển hơn qua từng ngày. Nếu là người lãnh đạo đủ tốt, họ sẽ nhận ra bạn có xứng đáng nhận được một mức lương tốt hơn hay không? Vấn đề quan trọng vẫn nằm ở bạn. Nỗ lực và chứng minh bản thân mình nhiều hơn nhé!
ĐÓN ĐẦU XU THẾ & TỐI ĐA HÓA TIỆN ÍCH TRONG LĨNH VỰC NGÂN HÀNG VÀ CẤU TRÚC BACK-END LIÊN QUAN
Ngân hàng mở (Open Banking) đang trở thành một xu thế mới trong lĩnh vực ngân hàng. Năm 2018 được ghi nhận là năm của “cuộc cách mạng lặng lẽ” ngân hàng mở, đặc biệt tại châu Âu và châu Mỹ. Đến năm 2020, tại Việt Nam, ngân hàng mở đang là từ khóa được quan tâm trong lĩnh vực tài chính, nhất là sau khi Việt Nam đã trải qua 2 đợt chống đại dịch.
Xu thế về Open Banking được dự đoán sẽ ngày một phổ biến hơn ở các nước châu Mỹ và châu u, tuy nhiên, đối với Việt Nam và các nước châu Á thì vẫn chưa. Do đó, một trong những xu hướng mà các ngân hàng có thể lựa chọn vào thời điểm này là xây dựng các Platform Banking trên nền tảng công nghệ số.
Riêng tại Việt Nam, Techcombank chính là một cái tên tiêu biểu, đại diện tiên phong trong việc xây dựng và triển khai Open Banking & Platform Banking.
Trong sự kiện HOW THE BACK-END OF BANKS EMBRACING DIGITAL CHANGE? được thực hiện bởi TECHCOMBANK, đại diện nhóm kiến trúc của Techcombank, anh LÊ HUY PHƯƠNG – @ () sẽ chia sẻ về xu thế mới này trong công nghệ IT của TCB cũng như trong các ngân hàng trên thế giới.
Anh Phương sẽ phần trình bày về Open Banking, Platform Banking sử dụng nền tảng kiến trúc Microservices với những nội dung cụ thể gồm:
Các khái niệm về Open Banking & Platform Banking.
Trong hạ tầng Back-end, kiến trúc microservices trong việc ứng dụng và xây dựng Open Banking và Platform Banking.
Tìm hiểu về quá trình chuyển đổi giữa các mô hình kiến trúc hiện tại sang một nền tảng kiến trúc định hướng về microservices, áp dụng định hướng đến việc xây dựng các nền tảng về Open Banking, Platform Banking.
Những practices gần đây nhất trong việc phát triển các nền tảng microservices.
Ngoài ra, chương trình sẽ được kết thúc bởi một Panel Discussion với sự tham gia của ba vị chuyên gia đến từ Techcombank hiện đang nắm giữ chủ chốt các yếu trong hạ tầng back-end hiện tại của Techcombank:
Anh Trần Hà Thanh – Giám đốc Chuyển đổi kinh doanh Công nghệ
Anh Nguyễn Phạm Bách – Giám đốc dự án cao cấp
Anh Lê Huy Phương: Kiến trúc sư Doanh nghiệp Mảng, Quản lí kiến trúc Công nghệ
Trước sự thay đổi nhanh chóng trong hành vi của người tiêu dùng, lấy khách hàng làm trung tâm đã không còn là một sự lựa chọn. Hãy tìm hiểu ngay về xu thế mới này để không bị tuột lại phía sau trước những thay đổi của công nghệ!
Time: 9:00 – 11:00 ngày 14/11/2020 tại trang Meetup
LƯU Ý KHI THAM GIA:
Chương trình chỉ livestreams trực tiếp tại website chương trình. Trước sự kiện 1 ngày, BTC sẽ gửi hướng dẫn tham dự và link truy cập.
Ở bài trước tôi đã giới thiệu với các bạn các bạn Các nguyên tắc thiết kế hướng đối tượng – SOLID. Trong bài này, tôi sẽ giới thiệu với một số nguyên tắc, định luật trong lập trình mà các bạn nên biết để phát triển chương trình của bạn tốt hơn.
The Law of Demeter Principle – LoD
Giới thiệu
The Law of Demeter Principle – LoD, còn gọi khác là nguyên tắc Demeter hay nguyên tắc “càng biết ít càng tốt” hay nguyên tắc “Một dấu chấm”. Nó là một nguyên tắc thiết kế để phát triển phần mềm, đặc biệt là các chương trình hướng đối tượng.
LoD là một triết lý nền tảng của việc lập trình được sinh ra từ một aspect-oriented programming (AOP) project cùng tên, là một trường hợp cụ thể của khớp nối lỏng lẻo (loose coupling).
LoD còn được gọi là nguyên tắc “Một dấu chấm”, nghĩa là không nên gọi quá nhiều dấu chấm (lời gọi hàm), là 1 code smell và sẽ dẫn đến việc code rất dễ vỡ khi có thay đổi.
Quan điểm cơ bản của nguyên tắc này chính là : tối giản sự hiểu biết của 1 object về cấu trúc, thuộc tính của các object khác ngoài nó (bao gồm các thành phần con).
Như bạn thấy đoạn code trên không có vấn đề gì. Tuy nhiên, nó vi phạm LoD và có thể gây chút phiền phức cho chúng ta sau này:
store về sau có thể sẽ không truy cập BillingAddress qua Customer, Order nữa.
Phương thức getCity() trong BillingAddress có thể sẽ không còn tồn tại.
Có thể sẽ gặp lỗi: NullPointerException, MethodNotFoundException nếu bất kỳ object order, customer, hay BillingAddress bị null.
Khi đóng gói Store để tái sử dụng, cũng cần phải đóng gói cả Order, Customer, BillingAddress. Khi đó, sự phụ thuộc lẫn nhau giữa các thành phần trong hệ thống tăng cao (tightly coupled).
Ưu điểm và nhược điểm của LoD
Cái gì thì có cũng mặt tốt và mặt xấu của nó cả, việc tuân theo LoD cũng vậy. Tùy theo trường hợp thích hợp hãy áp dụng để có được kết quả tốt nhất.
Lợi ích:
Class sẽ loosely coupled hơn, những thành phần trong hệ thống sẽ ít phụ thuộc vào nhau hơn.
Dễ dàng đóng gói và tái sử dụng.
Việc test, bảo trì sẽ dễ dàng hơn.
Bất lợi:
Viết nhiều phương thức, class wrapper hơn để có thể gọi được phương thức cần sử dụng.
Thật khó để tuân theo các quy tắc thiết kế này, nhưng một khi hiểu chúng đúng cách, nó sẽ mang đến cho chúng ta lợi ích rất nhiều.
Trong trường hợp trên cùng 1 interface có 2 yếu tố hành xử mâu thuẫn với nhau, hoặc cách hành xử không rõ ràng thì cần phải chọn cách hành xử nào gây bất ngờ ít nhất cho người sử dụng.
Đây là 1 nguyên tắc về giao diện người dùng. Một ví dụ đơn giản :
Trên 1 interface có 2 chức năng :
Ấn ctrl+Q để thoát chương trình.
Nhập macro (lưu 1 tổ hợp phím mang 1 chức năng nào đó để tiện cho việc sử dụng về sau).
Sẽ có trường hợp user muốn dùng Ctrl+Q cho macro của mình, nên hành xử đúng với nguyên tắc bất ngờ nhỏ nhất chính là : trong khi nhập macro thì ctrl+Q được coi như là tổ hợp phím bình thường, không phải là lệnh tắt chương trình. Đây chính là điều gây bất ngờ ít nhất cho người dùng.
Nguyên tắc Boy Scout
Nguyên tắc của các tổ chức Boy scout chính là : lúc đi phải sạch đẹp hơn lúc đến.
Trong lĩnh vực lập trình thì nguyên tắc đó sẽ được hiểu là “Khi bạn check-in một module thì lúc đó nó phải đẹp hơn lúc bạn check-out.”
Nguyên tắc YAGNI
Viết tắt của “You aren’t gonna need it” – Cái (chức năng, phần) ấy rồi sẽ không cần thiết.
Đó là một câu khẩu ngữ nhắc nhở người lập trình rằng trong quy trình Extreme Programming (lập trình cực hạn) thì : “Chưa phải lúc cần thiết thì chưa được phép làm.”
Khi nguyên tắc này được áp dụng tốt, dù ta có thay đổi 1 phần thì những phần không liên quan cũng sẽ không bị thay đổi theo. Hơn nữa, những phần có liên quan sẽ được thay đổi cùng 1 lượt, giúp ích rất nhiều cho cả khâu estimate và khâu thực hiện.
Nguyên tắc KISS
Viết tắt của “Keep it simple, stupid” – “Cứ đơn giản thôi, đồ ngu!”. Đây là 1 triết lí của Hải quân Mỹ.
Phương châm dao cạo Okham (Okham’s razor) : Không đưa ra nhiều giả thiết nếu không cần thiết. Cái gì cần ít giả thiết để chứng minh sẽ không thể chứng minh được bằng nhiều giả thiết.
Albert Einstein : Làm cái gì cũng nên đơn giản nhất có thể, nhưng đơn giản quá thì không được.
Leonardo da Vinci : Đơn giản nhất chính là điêu luyện nhất.
Antoine de Saint- Exupéry : Hoàn hảo, không phải là không thêm vào được nữa, mà là không thể bớt đi được nữa.
Nguyên tắc SOLID
Tập hợp những nguyên tắc trong lập trình hướng đối tượng. Các chữ cái đầu hợp lại thành SOLID.
SRP (Single Responsibility Principle) : Một class chỉ nên giữ 1 trách nhiệm duy nhất, chỉ có thể sửa đổi class với 1 lý do duy nhất.
OCP (Open/closed principle) : Có thể thoải mái mở rộng 1 class, nhưng không được sửa đổi bên trong class đó.
LSP (Liskov substitution principle) : Trong một chương trình, các object của class con có thể thay thế class cha mà không làm thay đổi tính đúng đắn của chương trình.
ISP (Interface segregation principle) : Thay vì dùng 1 interface lớn, ta nên tách thành nhiều interface nhỏ, với nhiều mục đích cụ thể.
DIP (Dependency inversion principle) : Các module cấp cao không nên phụ thuộc vào các modules cấp thấp. Cả 2 nên phụ thuộc vào abstraction. Interface (abstraction) không nên phụ thuộc vào chi tiết, mà ngược lại. ( Các class giao tiếp với nhau thông qua interface, không phải thông qua implementation.)
Nguyên tắc này đã được tôi viết khá kỹ trong bài viết “Các nguyên lý thiết kế hướng đối tượng – SOLID“. Các bạn có thể tham khảo thêm ở đây.
Bài viết được sự cho phép của tác giả Trần Anh Tuấn
Khi các bạn bắt đầu với một dự án nào đó hay là tự học code đi chăng nữa thì chắn hẳn các bạn sẽ gặp rất nhiều vấn đề khác nhau, như lỗi này lỗi nọ… Thì trong bài viết này mình sẽ tổng hợp các lỗi mà các bạn có thể sẽ gặp cũng như các tips tricks hay mà chúng ta có thể biết thêm để nâng cao trình độ nhé. Bắt đầu thôi nào!
Center với text-align
Khi các bạn làm việc với các khối hay hình ảnh có HTML đơn giản như sau, thì các bạn muốn cho hình ra giữa các bạn sẽ dùng display: block cho tấm hình rồi sau đó dùng margin: 0 auto.
<div class="image"><img src="demo.jpg"></div>
.image img {display:block;margin:0auto;}
Tuy nhiên nếu tấm hình đó bắt buộc không dùng display: block mà là inline-block thì sao ? Lúc này margin: 0 auto cho thẻ inline sẽ không có tác dụng. Để xử lý trường hợp này các bạn sẽ dùng text-align: center cho class .image bao bên ngoài là sẽ được nhé.
Chắc hẳn các bạn không lạ với việc dùng gradient cho background, tuy nhiên nếu muốn dùng gradient cho chữ thì làm thế nào ? Các bạn có thể làm được điều đó với thuộc tính -webkit-background-clip: text nhé. Khi áp dụng vào một dự án nào đó thì các bạn nên kiểm tra xem các trình duyệt mình làm có hỗ trợ thuộc tính này không nhé.
Giả sử các bạn muốn dùng nó nhưng sợ gặp trình duyệt không hỗ trợ sẽ lỗi vì thuộc tính color các bạn đã thiết lập trong suốt rồi, lúc này ta sẽ sử dụng @supports để xử lý trường hợp này. @supports sẽ kiểm tra xem trình duyệt có hỗ trợ thuộc tính đó không, nếu có thì áp dụng một đoạn CSS nào đó
Với đoạn code trên thì mặc định class .text sẽ có chữ màu cam, nhưng gặp trình duyệt hỗ trợ thuộc tính -webkit-background-clip: text thì nó sẽ áp dụng gradient.
Thiết lập max-width cho hình ảnh
Đôi khi chúng ta code có sử dụng nhiều hình ảnh rất to, nhưng khung chứa thì rất nhỏ dù đã thiết lập chiều rộng hay độ cao mà hình ảnh không có thu vào mà vẫn to như ảnh gốc ban đầu. Thì lúc này các bạn nên xem lại hình ảnh có dùng max-width chưa nhé.
img{max-width:100%;}
Khi sử dụng hình nền đừng quên thiết lập độ rộng và chiều cao, nếu không hình nền sẽ không hiển thị. Và sử dụng :before hay :after thì đừng quên thuộc tính content.
Khi các bạn thiết lập dự án ban đầu, các bạn sẽ thường thiết lập font-family trên body chẳng hạn để áp dụng cho toàn trang, tuy nhiên các thẻ như input, textarea, select, button sẽ không nhận mà nó lấy dựa theo mặc định của trình duyệt. Để xử lý trường hợp này các bạn phải CSS thêm font-family cho các thẻ này
Khi các bạn dùng thẻ img trong một khung nào đó chẳng hạn có kích thước là 50×50 mà hình của bạn là 135×275 thì lúc này hình của bạn sẽ hiển thị không được đẹp vì thế đừng quên sử dụng thuộc tính object-fit: cover để xử lý trường hợp này nhé.
img{object-fit:cover;}
Thẻ label không phải để chưng
Khi các bạn dùng thẻ label thì sẽ có thuộc tính for="" đi kèm, ở trong for này giá trị truyền vào chính là id của một input nào đó ví dụ
Lúc này khi nhấn vào thẻ label thì input với id tương ứng chỗ for sẽ được focus.
Xử lý khi liên kết dài hoặc chữ dài
Chắc hẳn khi các bạn làm giao diện layout thì việc hiển thị nội dung ra là chuyện đương nhiên và nội dung này được nhập từ người dùng. Ví dụ họ nhập 1000 chữ a dính nhau thì lúc này giao diện của các bạn sẽ hiển thị scroll ngang và sẽ làm xấu giao diện chẳng hạn. Để xử lý trường hợp này các bạn chỉ cần dùng như sau, ví dụ là class .text.
.text{word-break:break-all;}
Đừng sử dụng space-between khi làm việc với dữ liệu động
Khi các bạn làm việc với flexbox và sử dụng thuộc tính này với dữ liệu được đổ ra linh động thì lúc này có thể layout của các bạn sẽ hiển thị như thế này
Để xử lý trường hợp này các bạn có thể nghiên cứu dùng CSS Grid hoặc thay vì dùng space-between thì các bạn để mặc định là flex-start, sau đó chia % cho các phần tử và dùng hàm calc để tính toán khoảng cách giữa chúng, ví dụ khoảng cách giữa chúng là 20px. Ta có
Mình có viết một bài về trường hợp này rồi. Các bạn có thể nhấn tại đây để đọc nhé.
Đừng quên flex-wrap
Khi các bạn làm việc với Flexbox và dùng chỉ display: flex thì lúc này flex-wrap được thiết lập mặc định là nowrap nghĩa là các phần tử sẽ luôn nằm cùng một hàng cho dù lớp bao ngoài không đủ chứa đi nữa và có khi xuống màn hình nhỏ như điện thoại sẽ xuất hiện scroll ngang. Lúc này đơn giản là thay nowrap thành wrap là xong.
Chú ý với button
Khi các bạn dùng thẻ button thì ở trình duyệt như Chrome thì hiển thị bình thường nhưng ở Safari thì có màu nền làm xám. Để xử lý trường hợp này các bạn thiết lập màu nền mặc định là transparent là ok.
button{background-color:transparent;}
Border bị mất 1 phần khi zoom
Khi làm việc với các thẻ như input chúng ta thường code border: 1px solid #eee chẳng hạn, thì trên trình duyệt Chrome hay Safari lâu lâu sẽ bị mất border ở dưới hoặc bên trái, để fix trường hợp này mình đã Google và thấy nếu dùng 1px thì chúng ta có thể thay bằng thin
.box{border:thinsolid#eee;}
Sử dụng :empty để ẩn thành phần trống
Khi code với dữ liệu động được đổ ra từ database thì sẽ có đôi lúc dữ liệu chưa có thì lúc này ví dụ bạn sẽ có HTML như này <p></p> và nó có margin thì giao diện chắc chắn sẽ bị trống 1 phần nào đó, lúc này bạn muốn ẩn những thẻ <p> mà không có nội dung thì đơn giản chúng ta có thể dùng pseudo :empty nhé
p:empty{display:none;}
Hiển thị dấu … khi nội dung quá dài
Khi các bạn chỉ muốn một tiêu đề nào đó chỉ hiển thị trên một dòng và nếu quá dài thì sẽ bị cắt đi và hiển thị dấu 3 chấm thì chúng ta có thể dùng như thế này
Tuy nhiên bạn không muốn hiển thị trên một dòng mà là 3 hoặc 4 dòng rồi mới có dấu 3 chấm thì ta cũng có một cách khác để xử lý trường hợp này
.title{display:-webkit-box;-webkit-line-clamp:3;// số dòng muốn hiển thị-webkit-box-orient:vertical;text-overflow:ellipse;overflow:hidden;}
Responsive iframe, video
Khi chèn các iframe video từ các bên thứ ba như Youtube hay Vimeo thì việc trình phát hiển thị không có responsive khi gặp các màn hình nhỏ như tablet hay mobile là chuyện bình thường. Để xử lý việc này thì mình có tìm hiểu và thấy người ta code về tỉ lệ là 16:9 để cho hiển thị video được responsive tốt trên tất cả các màn hình. Ví dụ ta có HTML như sau
<div class="video"><iframe src="youtube"></div>
Thì chúng ta sẽ dùng đoạn code này để làm cho chúng responsive
Bài viết được sự cho phép của tác giả Trần Hữu Cương
Các câu hỏi chung như giới thiệu về bản thân, trước đó em làm công ty nào, sao nghỉ việc, mức lương em mong muốn ra sao… tạm thời mình không đề cập tới vì cái này tùy từng trường hợp và năng lực mỗi người =)). Mình sẽ chỉ đề cập tới vấn đề kỹ thuật khi đi phỏng vấn thôi nhé.
Phỏng vấn thực tập, freshser
Với những bạn mới ra trường thì phỏng vấn sẽ nhẹ nhàng, chủ yếu đánh giá kiến thức nền tảng của các bạn.
1. Lập trình hướng đối tượng là gì?
Trả lời: lập trình hướng đối tượng là 1 kỹ thuật lập trình, cho phép lập trình viên trừu tượng hóa các đối tượng thực tế thành các đối tượng trong code
2. Các tính chất của lập trình hướng đối tượng trong Java?
Trả lời: Có 4 tính chất (tính trừu tượng, tính đóng gói, tính kế thừa, tính đa hình) https://stackjava.com/oop/cac-tinh-chat-huong-doi-tuong-cua-java.html
3. Hỏi về collection Framework (Cái này hầu như 100% ở đâu phỏng vấn cũng hỏi).
Sự khác nhau giữa Set với Map
Sự khác nhau giữa Linklist với Arraylist; Vector với Arraylist; HashTable với HashMap
(* Chú ý: Từ Java 8 và Java 9, có khá nhiều thay đổi đối với Interface)
7. Khái niệm DI là gì?
Phần này thường hỏi đối với người đã có kinh nghiệm đi làm.
Trả lời:
8. Hỏi về các design pattern (1 số design pattern quen thuộc).
Phần này thường hỏi đối với người đã có kinh nghiệm đi làm.
Trả lời:
9. Hỏi về thuật toán.
1 số thuật toán quen thuộc như DFS, BFS, các thuật toán đồ thị, tìm kiếm…, thường thì phần này sẽ rơi vào phần làm bài test nhưng đôi khi cũng sẽ hỏi miệng chủ yếu để xác định bạn có biết tới những thuật toán đó không.
10. Hỏi về các dự án bạn đã làm, nghiên cứu.
Dự án ở đây là các bài tập lớn bạn đã làm, đồ án tốt nghiệp.
Để tạo ấn tượng tốt bạn nên có 1 số project trên github đối với các bài tập lớn của mình hoặc tham gia viết bài trên một blog nào đó về lập trình.
11. Hỏi về khả năng tự học, tiếp cận/giải quyết vấn đề.
Cái này chủ yếu về cách mà bạn giải quyết vấn đề, tiếp cận cái mới. Thí dụ cách mà bạn search google cũng được đánh giá khá cao.
Ví dụ: nhà tuyển dụng hỏi bạn: “em làm chức năng Login” hết bao lâu thời gian thì đừng trả lời mà phải hỏi lại là chức năng login như nào, áp dụng công nghệ nào, các role, permission ra sao…
Hỏi về những kỹ thuật, ngôn ngữ nào mà bạn tự học, tìm hiểu?
Đặc biệt nếu bạn đọc nhiều sách về lập trình thì sẽ được đánh giá rất cao. Một số sách hay về Java như: Sun Certified Programmer for Java®Platform; Clean Code, Java Effective.
Đối với vị trí yêu cầu kinh nghiệm thì yêu cầu cao hơn, các nhà phỏng vấn sẽ đánh giá nhiều về những gì bạn đã làm được.
Giả sử bạn giỏi, kinh nghiệm 2,3 năm nhưng bạn chỉ xào đi xào lại 1 dự án, chẳng có công nghệ, framework gì mới thì sẽ bị đánh giá rất thấp do đó những năm đầu đi xin việc mọi người đừng quá quan tâm vào lương mà hãy để ý xem nơi mình vào làm sẽ giúp mình học được gì, phát triển được gì.
Và thông thường nếu chỉ tầm 3 năm kinh nghiệm trở xuống thì bạn sẽ vẫn gặp những câu hỏi cơ bản giống như lúc tuyển fresher
1. Bạn đã làm những dự án nào? dự án đó làm cái gì, kích thước dự án ra sao và đóng góp vào dự án của bạn là gì?
2. Bạn biết những kỹ thuật, công nghệ, framework gì?
Cái này chủ yếu để xác định xem bạn có phù hợp với vị trí ứng tuyển không.
Ví dụ công ty đang làm về JSF và đang rất cần người biết về JSF nhưng bạn lại chỉ biết Spring thì sẽ không được ưu tiên bằng các ứng viên khác. Một số ít công ty thì chủ yếu maintain các dự án cũ nên sẽ làm nhiều về Struts (cái này giờ ít dùng), thậm chí có lần mình phỏng vấn 1 công ty mà sản phẩm của họ không hề dùng các công nghệ mới chỉ vì sản phẩm của họ đang ổn định.
3. Hỏi sâu về kiến thức mà bạn bảo mình biết 🙂
Phần này sẽ là phần đánh giá chủ yếu về kỹ thuật, nó giúp nhà tuyển dụng đánh giá những gì bạn trình bày có đúng ko.
Ví dụ:
Bạn bảo mình làm về Spring thì sẽ hỏi đại loại như Spring có những module nào? DI trong Spring như nào;
Bạn bảo mình biết JSF thì sẽ hỏi JSF có những phase nào…
Về Hibernate thì hỏi hibernat khác gì JPA, save – saveOrUpdate – merge khác gì nhau…
Hỏi về REST, maven…
Nếu cái gì bạn không biết thì ko nên đề cập tới trong CV. Nếu có hỏi tới thì cứ thoải mái thừa nhận là phần đó em chưa làm nhiều.
4. Ở các vị trí cao hơn
Với người có kinh nghiệm làm leader, hoặc kinh nghiệm lâu năm 8,9 năm gì đó thì sẽ hỏi nhiều về kiến trúc, pattern, cách lead team.
Kết.
Chú ý lúc phỏng vấn cũng là lúc bạn phỏng vấn ngược lại để biết được mình sẽ làm việc với ai, làm về cái gì, khả năng phát triển/ học hỏi được ở công ty ra sao.
Và đừng ngại đi phỏng vấn, mình phỏng cũng có lần tạch, cũng nhận được khá nhiều lời mời. Sau mỗi lần như thế bạn sẽ thể hiện mình tốt hơn trước nhà phỏng vấn.
Chúc bạn tự tin khi đi phỏng vấn nha!
Bài viết được sự cho phép của tác giả Trần Khôi Nguyên Hoàng
Responsive ngày này gần như là yêu cầu bắt buộc phải có khi thiết kế Website. Tuy nhiên, mỗi khi truy cập vào https://facebook.com thì giao diện y như những trang Web năm 2000. Xấu không chịu được. Vì thế, Facebook tìm ra cách giải quyết là tạo một bản Mobile Version tại https://m.facebook.com. Facebook là một trong những công ty to nhất thế giới, nhưng tại sao họ lại không dùng responsive mà phải dùng một bản Mobile Version?
Photo by Austin Distel / Unsplash
Responsive là gì?
Trước khi đi vào chém gió về lý do tại sao, thì nhắc lại thế nào là responsive đã nhỉ.
Responsive Web Design is about using HTML and CSS to automatically resize, hide, shrink, or enlarge, a website, to make it look good on all devices (desktops, tablets, and phones) – W3Schools.
Hay nói đơn giản thì responsive là cách cách thiết kế giao diện thân thiện cho mobile hay tablet.
Vậy thì tại sao Facebook lại không sử dụng Responsive?
Responsive không phải là cách duy nhất để thiết kế “Giao diện thân thiện” cho Mobile và Tablet
Nhiều người nghĩ rằng chỉ có một cách để thiết kế Website chạy tốt trên các trình duyệt di động là responsive. Nhưng nghĩ lại một chút thì trước khi có responsive thì vẫn có một cách để các giao diện chạy tốt trên điện thoại mà? Đó là người ta sử dụng một Mobile Version để chạy các Website trên di động. Thường thì sẽ là http://m.domain.com. Và đây chính là cách Facebook hay một số Website khác như Twitter cũng đang làm.
Facebook không phụ thuộc hay liên quan gì đến với Google
Tại sao lại lôi Google vào đây? Google sỡ hữu một công cụ tìm kiếm mạnh nhất quả đất hiện tại. Chính vì thế, các Website sau này đều muốn được xuất hiện trong top 100 tìm kiếm của anh Gồ. Mà để muốn lọt được vào top 100 thì phải SEO. Mà muốn SEO được thì Website phải được responsive. Nhưng với Facebook thì hoàn toàn khác. Facebook là một mạng xã hội lớn nhất hiện tại. Chính vì thế Facebook vẫn sống tốt sống khỏe mà không cần phải xuất hiện quá nhiều vào trong kết quả tìm kiếm của Google. Cho nên Facebook cũng không cần phải responsive.
Facebook quá phức tạp để responsive
Nếu một Website đơn giản hơn, ít tính năng thôi thì việc responsive không phải là một vấn đề quá lớn, quá phức tạp. Nhưng Facebook lại là một mạng xã hội quá lớn, kèm theo đó là ngàn nghìn tính năng trong trang Web của họ. Vậy thì responsive là một phương án không hề tối ưu. Chính vì vậy, việc có một tên miền khác cho mobile sẽ giúp giải quyết triệt để vấn đề này. Một website khác sẽ đồng nghĩa với hiện HTML khác, CSS khác, và Javascript cũng viết lại. Nó sẽ tiện hơn cho việc tối ưu hóa hiển thị trên di động, ngay cả trên các thiết bị cũ đời Tống. Bản mobile của Facebook hoàn toàn được viết bằng HTML, CSS và Javascript. Không có bất cứ một Framework Front End xịn xò nào như React. Bạn hoàn toàn có thể Crawl dữ liệu từ phiên bản mobile này. Hơn nữa, việc làm bản Mobile Version cho Facebook sẽ giúp Facebook linh động hơn trong việc tối ưu hóa trải nghiệm người dùng. Chẳng hạn khi thêm một tính năng mới thì sẽ dễ implement vào bản Mobile hơn.
Giúp tải trang nhanh và ổn định hơn
Facebook Desktop thì nó nặng như thế nào thì các bạn biết rồi chứ? Các bạn cứ thử bật 20 tab Facebook đi thì thấy nó như nào. Mà khi sử dụng responsive, đồng nghĩa với việc nó sẽ phải tải toàn bộ HTML5 của bản Desktop ngay trên Mobile, mặc dù không hề dùng đến. Điều này sẽ làm trải nghiệm của người dùng ở bản responsive trở nên tệ hại. Chính vì việc này nên mình nghĩ đó là lý do tại sao giao diện mobile của Facebook xấu hoàn toàn. Ở trên mobile thì mình nghĩ ưu tiên cao nhất là tốc độ và độ ổn định, chứ không hẳn là phải đẹp, phải hoành tráng. Facebook đã đánh đổi cái đẹp của bản mobile để đổi lấy tốc độ và ổn định.
Bài học rút ra
Nếu như một trang Web có quá nhiều tính năng phức tạp, cộng với việc không cần SEO trên Google thì việc đơn giản hơn là hì hục ngồi responsive thì cứ làm một bản Mobile Version cho nó nhẹ đầu. Đỡ nghĩ ngợi lung tung, phức tạp.
Kết luận
Trên đây là một số ngụ ý cá nhân của mình về câu hỏi “Tạo sao Facebook không sử dụng responsive?” sau khi đọc một số bài về responsive cũng như lê la trên Quora chiều hôm nay. Hy vọng các bạn sẽ thích.
Game indie là dòng game được phát triển bởi cá nhân, hay tổ chức nhỏ mà không có sự hỗ trợ tài chính nào từ các ông lớn ngành Game. Cũng chính vì thế, game indie chủ yếu tập trung và cốt truyện, nhân vật hơn là đồ họa.
Một điểm khá hay ở game indie chính là mục đích tạo ra game không vì lợi nhuận như các game ở các hãng lớn. Nếu muốn thử sức với dòng game indie, hãy cân nhắc các ngôn ngữ lập trình sau:
Ngôn ngữ hướng đối tượng C++
C++ khá khó học, tuy nhiên lại rất phổ biến vì C++ cấp quyền kiểm soát hardware cũng như đồ họa cần thiết để thiết kế video game. Và vì nó là ngôn ngữ hướng đối tượng nên cấu trúc bên trong sắp xếp code thành các block có thể tái sử dụng lại các đoạn code sau này.
Ngôn ngữ C++ khá phù hợp với những bạn mới bắt đầu, bởi khi bạn đã thành thạo ngôn ngữ nền tảng như vậy thì quá trình tìm hiểu ngôn ngữ mới cũng sẽ đơn giản hơn. Game Starbound (kiểu game phiêu lưu hành động) cũng được phát triển bởi C++.
Ngôn ngữ Java được nhiều dev lựa chọn vì nó hỗ trợ đa luồng – multithreading nên ít tốn bộ nhớ hơn, đồng thời tối đa hóa CPU. Các game được phát triển trên nền Java rất dễ tương thích với nhiều device khác nhau vì chạy trên máy ảo (virtual machine). Tựa game nổi tiếng – Minecraft, trước khi bán cho Microsoft thì được tạo ra từ Java bởi Markus Persson và trở thành video game bán chạy nhất mọi thời đại.
Ngôn ngữ đánh dấu HTML5
HTML5 phát triển trên nền tảng HTML và được sử dụng để design, cấu trúc diện mạo của web, và hiển thị content web. Các content đa phương tiện có thể thêm vào mà không cần Flash hay plug-in từ bên thứ ba. Thậm chí có thể truy cập website mà không cần Internet, rất đáng để cân nhắc phát triển game. Tựa game rất classic – Bejeweled được viết bằng HTML5.
Ngôn ngữ kịch bản JavaScript
Là ngôn ngữ lập trình và ngôn ngữ script phổ biến nhất giới lập trình, JavaScript được dùng để cung cấp trải nghiệm mượt mà hơn, cùng với với các chức năng tự động update các trang web, cải tiến UI như hình ảnh, animation, video, .. Với sự hỗ trợ từ API, các chương trình khó và cao cấp hơn cũng hoàn toàn khả thi với JavaScript, Ví dụ như tựa game Angry Birds cũng chạy trên nền tảng JavaScript.
Tùy vào lựa chọn design mà bạn có thể chọn ngôn ngữ build game phù hợp cho bản thân. Sau khi chọn được rồi thì hãy bắt tay và tạo ra một chiếc game indie của riêng mình nhé.
Nhiều người vẫn nghĩ rằng xinh đẹp và thông minh sẽ không tồn tại trên cùng một người, nhưng bài đăng này sẽ khiến bạn thay đổi suy nghĩ. Như chúng ta đều biết rằng Hacking là một khía cạnh phức tạp thực sự đòi hỏi kỹ năng kỹ thuật rất lớn. Vì vậy, AnonyViet đã thống kê danh sách những nữ hacker xinh đẹp và khét tiếng nhất, những người đã giành được vị trí này và đạt được một số cột mốc về hacker mũ trắng. Bạn có thể thấy họ trong một số tổ chức blue-chip, cơ sở công nghiệp và các công ty lớn.
Adeanna Cooke
Adeanna Cooke là một cựu người mẫu Playboy, và thật thú vị làm sao sau khi được thuê cho một buổi chụp ảnh bình thường, một trong những người bạn cũ của anh ấy muốn kiếm tiền bằng cách đặt khuôn mặt của cô ấy lên một cơ thể khác mà không mặc quần áo bằng cách chụp ảnh.
Nhưng, khi nhìn thấy những bức ảnh trần trụi trên một số trang web trái phép ngẫu nhiên, cô ấy đã ngay lập tức tự tay mình hack trang web mà không hề thông báo hay nhờ đến chính quyền.
Về cơ bản, Adeanna Cooke nổi tiếng với kỹ năng hack có đạo đức và cô là một hacker tự đào tạo. Cô cũng hỗ trợ phụ nữ và những người mẫu khác trong những hoàn cảnh tương tự. Do đó, ngay sau khi tìm thấy thành công trong nỗ lực của mình, Adeanna Cooke đã trở thành “nàng tiên hacker”.
Xem thêm:PHÁ HỦY MÁY TÍNH CỦA BẠN VỚI “USB SÁT THỦ” THẾ HỆ THỨ 3
Xiao Tian
19 tuổi Xiao Tian là “tướng lĩnh” mới của đội quân nữ Hacker Trung Quốc. Chỉ mới cuối tuổi thiếu niên, cô đã trở nên nổi tiếng khi thành lập nhóm “China Girl Security Team”.
Cho những ai chưa biết, ‘China Girl Security Team’ là một nhóm tin tặc, đặc biệt là phụ nữ, lớn nhất ở Trung Quốc hiện tại, có hơn 3000 thành viên, và đang tiếp tục tăng lên.
Như Xiao Tian cảm thấy rằng không có tiếng nói riêng dành cho những cô gái tuổi teen như cô trong thế giới hack do nam giới thống trị.
Anna Chapman
Anna Chapman là một nữ hacker người Nga, sinh ngày 23 tháng 2 năm 1982 và bị bắt tại thành phố New York khi cô bị phát hiện cùng 9 người khác với tội danh làm việc cho tổ chức gián điệp Illegals Programme thuộc cơ quan tình báo đối ngoại của Liên bang Nga.
Anna Chapman bị cáo buộc phạm tội âm mưu hoạt động như một đặc vụ của chính phủ nước ngoài mà không thông báo cho Bộ trưởng Tư pháp Hoa Kỳ và bị trục xuất về Nga vào ngày 8 tháng 7 năm 2010, như một phần của hiệp ước trao đổi tù nhân giữa Hoa Kỳ và Nga.
Ying Cracker
Ying Cracker là một trong những nữ hacker xinh đẹp nhất thế giới và là giáo sư ở Thượng Hải, Trung Quốc, người dạy mọi người những kiến thức cơ bản về “Cách bắt đầu hack”, “Cách thay đổi địa chỉ IP của bạn” và “Cách xóa mật khẩu Office”…
Cô ấy trở nên nổi tiếng trong một Diễn đàn được gọi là “Những hacker hấp dẫn người Trung Quốc”, nơi cô ấy có một lượng lớn người hâm mộ. Hơn nữa, công việc của Ying Cracker rất đáng chú ý, là một chuyên gia trong các khóa học về hack, viết và kiếm tiền bằng các khóa học về các công cụ này, và cô ấy cũng giúp những người khác bẻ khóa (bẻ khóa) phần mềm.
Xem thêm:Avira Phantom VPN Pro V2.29 Full – Phần mềm VPN nhanh, an toàn
Nhưng, điều thú vị nhất là thành tích của cô đã đổi họ thành CRACKER.
Kristina Svechinskaya
Tên đầy đủ của Kristina Svechinskaya là “Kristina Vladimirovna Svechinskaya”, sinh ra tại thành phố Irkutsk, đây là trung tâm hành chính của Irkutsk Oblast, và là một trong những thành phố đông dân nhất ở Siberia, Nga. Vào ngày 16 tháng 2 năm 1989, cô đến Hoa Kỳ, nơi cô đang là sinh viên của Trường Kinh doanh Stern thuộc Đại học New York và làm phục vụ bàn.
Đôi mắt xanh nhạt và vẻ đẹp lai Nga nổi bật của cô đã khiến cô trở thành một trong những “Hacker xinh đẹp nhất”, khi cô bị bắt ở New York, Hoa Kỳ, vào đầu tháng 10 năm 2010, vì bị buộc tội tích hợp một mạng lưới lừa đảo Internet, nơi có phần mềm độc hại, virus và Trojan đã được sử dụng để đánh cắp 35 triệu USD từ một số tài khoản ngân hàng của Hoa Kỳ và sử dụng hộ chiếu giả.
Kim Vanvaeck
Cô còn được gọi là Gigabyte. Kim Vanvaeck đến từ Bỉ, và cô được biết đến với tác phẩm Virus. Một mình cô ấy đã tạo ra một số loại virus cao cấp có khả năng đánh cắp thông tin nhạy cảm từ bất kỳ hệ thống nào và cũng có thể phá hủy chúng. Cô ấy đã viết về một số loại virus như Quis, Coconut, Sahay và YahaSux.
Tất cả chúng ta đều biết rằng không phải tất cả hacker đều Xấu, Joanna Rutkowska là bằng chứng. Cô là một nhà nghiên cứu bảo mật máy tính người Ba Lan. Joanna Rutkowska đã gây chấn động toàn thế giới khi cô trình diễn hai phương pháp đơn giản để hack vào Windows Vista beta trước đám đông vào tháng 8 năm 2006.
Xem thêm:Microsoft đã xóa thư mục Download khỏi Disk Cleanup
Cô ấy thuyết trình tại một hội nghị và làm việc với một số hãng công nghiệp khổng lồ bao gồm Microsoft.
Raven Adler
Chà, Raven Adler là người phụ nữ đầu tiên có mặt tại hội nghị hacker của DefCon. Cô ấy hiện đang làm cố vấn bảo mật cấp cao cho một số công ty.
Raven Adler nổi tiếng với việc phát triển các hệ thống phát hiện hack. Cô cũng làm việc với một số công ty nổi tiếng để giúp họ bảo vệ dữ liệu trực tuyến của họ.
Jude Milhon
Chà, Jude Milhon bắt đầu sự nghiệp của mình với tư cách là một lập trình viên máy tính vào năm 1967. Tuy nhiên, sau đó cô đã thành lập một nhóm hack được gọi là Cypherpunks.
Trong suốt cuộc đời của mình, cô đã viết một số cuốn sách cũng như xuất bản một số tạp chí liên quan đến hack và lập trình máy tính. Cô qua đời năm 2003.
Natasha Grigori
Natasha Grigori bắt đầu sự nghiệp của mình với tư cách là một hacker. Tuy nhiên, cô ấy không quản lý để đạt được một số danh tiếng. Vào cuối những năm 1990, cô thành lập trang antichildporn.org, nơi cô bắt đầu tán công các website nội dung khiêu dâm trẻ em. Natasha Grigori qua đời vào tháng 11 năm 2005 do bệnh nặng.
Vợ tui
Vâng, bất cứ ai đã lập gia đình đều biết vợ mình có khả năng hack bất cứ Password nào của bạn, từ điện thoại di động, đến laptop, cũng như SMS. Chỉ cần một cái liếc mắt, lập tức Password sẽ được người chồng khai báo, mà người vợ không cần dùng tới chiếc máy tính hay kể cả bàn phím nào. Có thể nói đây là Hacker nguy hiểm nhất mọi thời đại.
Đây là 10 nữ hacker khét tiếng nhất thế giới. Bạn hãy cố gắng phấn đấu để bằng chị em phụ nữ đi nhé, ad đi lau nhà, rửa chén tiếp đây.
Bài viết được sự cho phép của tác giả Huỳnh Quán Cẩm
Có một thủ pháp thường hay được sử dụng khi deploy app là chạy database migration ngay khi deploy, nhưng liệu đó có phải là một good practice (tam dịch: cách làm tốt) hay không?
Tất nhiên, để đảm bảo tính khách quan, mình giữ lập trường “câu trả lời vẫn luôn là còn tùy”, nhưng 99.9999% trường hợp là KHÔNG.
# trước khi sửa
render_json({id: user.id, date_of_birth: user.dob})
# sau khi sửa
render_json({id: user.id, date_of_birth: user.date_of_birth})
Như đầu đề, ta sẽ chạy migration code cùng lúc với deploy. Có thể nó khá phức tạp tùy theo từng app nhưng chung quy lại gồm 3 bước: a) Kéo code mới từ SCM về b) chạy đoạn code migration ở trên và c) restart lại ứng dụng để áp dụng mã mới.
Vậy thì vấn đề của cách làm trên là ở đâu?
Vấn đề
Có thể bạn sẽ để ý được là ở khoảng thời gian sau b) cho tới khi c) kết thúc, phần API đọc và ghi users của bạn sẽ bị lỗi không ngừng nghỉ với rate là 100%, lý do là vì lúc đó cột dob đã bị gỡ khỏi database nhưng code mới thì chưa được release lên.
Đương nhiên bạn có thể đảo ngược thứ tự giữa b) và c) nhưng vấn đề không đổi, cột date_of_birth chưa được tạo.
Là một lập trình viên, đôi lúc bạn sẽ nghĩ là vài giây đó thì thấm tháp vào đâu, nhưng chắc chắn 99.99% đồng nghiệp của bạn đang làm cho bộ phận tiếp nhận phàn nàn từ khách hàng sẽ nghĩ khác, những phần tử trong 0.001% còn lại (ừ thì 1 + 1 = 3) chắc hết chiều hôm đó thôi việc.
Giải pháp
Không có một giải pháp chuẩn nào cho việc này cả nhưng nói một cách hàn lâm thì quy tắc chung là:
Đảm bảo bản deploy hiện tại tương thích với bản deploy trước ở bất kì thời điểm nào của deploy.
Vậy với vấn đề ở trên (định dùng chữ bài toán nhưng sợ bạn rule keeper ở #random phàn nàn) cách giải quyết là chia thành nhiều bản deploy nhỏ (chú ý mỗi bước sau đây là một bản deploy).
a) tạo ra cột date_of_birth trong bảng users.
b) sửa đoạn code ghi ngày sinh và đoạn code đọc ngày sinh.
c) Viết đoạn script migrate tất cả dữ liệu từ dob qua date_of_birth.
d) Xóa đoạn code đọc đi (đừng xóa đoạn viết nếu bạn không muốn đồng nghiệp quay qua hỏi thăm bằng tiếng Đan Mạch).
e) Tạo migration để xóa cột dob.
Kết luận
Quản lý database schema là một vấn đề khó và đòi hỏi sự cẩn thận, tốt nhất là bạn nên đùn công việc này cho người khác nếu có thể (troll đó cơ mà nếu đùn được thì tốt).
Các bước thực hiện có thể sẽ khác nhau tùy trường hợp nhưng ý tưởng cơ bản thì là như trên, bạn có thể xào nấu lại tùy thích.
Lời cuối: Chúc chúng ta không bị banh server và ngủ ngon mỗi đêm.
Bài viết được sự cho phép của tác giả Võ Quang Huy
Tình hình hôm vừa rồi có đi cafe với ông Anh, ổng hỏi sao chú không ở nhà làm cho khỏe, làm công ty làm chi cho mệt? WordPress thiếu chi dự án… Đúng là một câu hỏi cũng đáng phải suy nghĩ Làm ở nhà thì thời gian thoải mái hơn, tự do, nếu ổn định thì thu nhập cao hơn… Nhưng…
Suy nghĩ thế thôi chứ theo mình đi làm công ty mình được nhiều thứ hơn là tiền… Với hơn 4 năm theo nghiệp code trải qua hơn 4 công ty thì hôm nay mình xin được chia sẽ cho các bạn những lý do bạn nên đi làm công ty thay vì làm ở nhà (freelancer).
1. Sự ổn định
Cái này thì tất nhiên rồi làm công ty với một mức thu nhập ổn định thì sẽ mang đến cho bạn một sự yên tâm. Hằng tháng cứ đến ngày 5 (Ngày nhận lương của mình =)) ) là tiền tự vào tài khoản, ngày làm đủ 8h tối về chở vợ con đi siêu thị chơi chả lo gì. Còn làm freelancer tháng nào nhiều dự án thì thu nhập được, tháng này bận việc hoặc nhác làm thì tiền chả có, chưa tính đến chuyện khách hàng chơi lầy làm xong rồi mà không chịu trả tiền…
Ổn định ở đây không chỉ ảnh hưởng đến bản thân bạn và còn ảnh hưởng đến người chung quanh… Nếu bạn làm công ty người thân sẽ thấy yên tâm: “à con tui nó làm công ty nước ngoài… Chồng tao làm lead công ty ABC…” Còn nếu bạn làm ở nhà phụ huynh của bạn sẽ cảm thấy khá lo lắng không biết nó làm gì mà ngồi máy tính cả ngày…
2. Đi làm công ty sẽ giúp bạn bớt “hư hỏng” =))
Mình cũng có 1 khoảng thời gian làm ở nhà, cũng tầm 1 tháng. Trong một tháng đó lịch làm việc của mình là: Sáng 11h thức dậy ăn sáng kiêm ăn trưa -> Ngồi máy tính chơi game đến 5h -> Đi ăn tối kiêm đi chơi đến 10h tối về -> Làm việc đến 3h sáng rồi đi ngủ luôn.
Một lịch làm việc chả có cái qq gì là khoa học hết và nó ảnh hưởng trầm trọng đến sức khỏe. Mình nhận ra đây không phải là cuộc sống mình hướng tới, mình không thể control được bản thân khi tự do và không có áp lực :)) Và mình quyết định đi xin việc công ty lại.
Khi đi làm công ty thì mọi chuyện hoàn toàn khác. Tối phải lo ngủ sớm để mai làm cho đúng giờ, xem world cup thì xem tới trận 10h thôi, còn trận 1h sáng mai lên xem video là là oke rồi. Chăm sóc vệ sinh cá nhân tốt hơn, phong cách ăn mặc cũng lịch sự hơn….Vì công ty cũng làm việc tập thể mà, đặc biệt lại có mấy em nữa :)))
3. Làm công ty sẽ giúp skill của bạn tăng lên đáng kể
Làm ở nhà thì tất cả kiến thức hầu như bạn phải tự mày mò, tự tìm tại liệu. Để tìm hiểu một kiến thức nào đó bạn phải tự lên lộ trình học… Nhưng nếu vào công ty thì tất cả bạn sẽ được định hướng cái gì học trước, cái gì học sau nó sẽ giúp bạn tiết kiệm thời gian. Chưa kể một số công ty còn có riêng đội ngũ để train cho nhân viên mới… Có nghĩa bạn sẽ được học mà không bị tốn tiền
Một cái khá quan trong nữa là: Khi bạn viết ra những dòng code sẽ có đi review code cho bạn kaka. Lead hoặc những người có kinh nghiệm sẽ đi review code, chỉnh cho bạn từng dòng, code sao cho hợp lý, code sao cho tối ưu, code sao cho chuẩn… Tất nhiên lúc đầu bạn sẽ nghe chữi khá nhiều, nhưng chỉ cần 1 2 lần review oke thì bạn sẽ rất tự tin với những dòng code mình viết ra cũng nhưng đãm bảo chất lượng cho những dự án sau này….
Làm CNTT quan trọng nhất là thực hành nhiều mới lên trình được… Nếu bạn làm ở cty thì dự án rất nhiều nên bạn có cơ hội để thực hành trên dự án thực tế cao, chỉ cần qua 1 2 dự án thực tế thì bạn đã có kinh nghiệm đầy mình
Đa số dự án của công ty là dự án lớn. Những dự án lớn cần sự tối ưu cao thì sẽ sử dụng nhưng công nghệ mới và hiện đại. Nếu làm ở công ty bạn sẽ có nhiều cơ hội tiếp xúc với những công nghệ đó. Điều đó sẽ giúp bạn không bị tụt hậu bạn sẽ thấy có tương lai hơn Sẽ không có cảm giác nếu ko làm cái này thì không biết làm gì…
5. Nâng cao khả năng làm việc nhóm
Cái này thì hiển nhiên rồi, làm công ty chủ yếu là làm việc theo nhóm. Làm việc theo nhóm giúp bạn học hỏi dược cách phần chia công việc, học được cách phối hơn cùng đồng đội, nâng cao tình thần trách nhiệm của mỗi cá nhân. Bạn sẽ học được cách sử dụng các công cụ quản lý code theo phiên bản như git, svn …
5. Nâng cao khả năng chịu đựng =))
Công ty nào cũng có nội quy, quy định. Mình đã từng làm công ty có những quy định rất khắc nghiệt ví dụ như:
Đi làm phải cực kỳ đúng giờ – Đi chậm 10 phút là lên họp với sếp. Đi làm trễ là thấy sếp đang ngồi chổ làm việc của mình :)))
Trong lúc làm việc ko được để chuông điện thoại reo – Nếu để chuông reo là hàng trăm đôi mắt nhìn về mình.
Trong lúc làm việc ko được ra ngoài chỉ có giờ giải lao giữa giờ mới ra ngoài =)))
Tuyệt đối không được lượt facebook trong lúc làm việc – Nhớ đợt đó đang làm mình lướt fb mà lão sếp đứng sau lưng lúc nào ko biết =)) thế là mấy ngày sau lão cứ lượn sau lưng mình =))) Bạn có hiểu cảm giác làm việc mà có người đứng sau lưng mình xem ko =))
Làm việc trong môi trường như thế chắc bạn sẽ thấy khá là hãm :)). Có chi được đâu mà khỏe, nhưng nếu bạn nghĩ theo một hướng tích cực thì sẽ thấy nó cũng giúp được mình khác nhiều.
Trải qua những quy định khắc nghiệt như thế thì mình sẽ học được sự chuyên nghiệp, tập trung trong công việc… Đồng thời sau này có đi công ty khác thì cũng không thấy khó khăn gì vì mình đã từng làm trong môi trường kinh khủng hơn thế
6. Là hành trang cần thiết để sau này bạn làm startup hihi
Làm công ty bạn sẽ học được cách vận hành một bộ máy lớn, cách quản lý dự án, cách quản lý nhân sự, cách xử lý các vấn đề bất cập… Hay là cách ứng xử giữa sếp với nhân viên. Từ đó bạn sẽ có chút ít kinh nghiệm để sau này mở công ty hoặc làm startup.
Tóm lại:
Nếu bạn là sinh viên mới ra trường thì mình khuyên nên xin vào một công ty, đây là cách nhanh nhất để bạn có kinh nghiệm. Nếu ko xin được vào làm, thì có thể xin thực tập và học việc. Đa số công ty hiện tại cũng muốn đào tạo mấy bạn thực tập để vào làm luôn.
Những cái list đầu dòng phía trên chỉ là cảm nhận cá nhân mình nhé. Và tất nhiên cũng tùy theo công ty, không phải công ty nào bạn cũng được hưởng những quyền lợi như trên
Trên đây chỉ là tâm sự của một thằng ngày code công ty tối về code cho vợ :)))
Một bài viết ngắn tổng hợp các lệnh Python cơ bản nhất cho lập trình viên mới bắt đầu với Python. Cùng TopDev xem qua và lưu về cheatsheet Python này nhé.
Biến – Variables
Biến trong Python được tạo và hiển thị như sau: name = expression.
num = 11 # hiển thị 11
word = "Hello" # hiển thị "Hello"
logic = True # hiển thị True
my_list = [2, 3, 4] # hiển thị [2, 3, 4]
my_tuple = (5, 2) # hiển thị (5, 2)
my_dict = {} # hiển thị {}
my_set = {4, 5} # hiển thị {4, 5}
Chuỗi – Strings
Chuỗi trong Python là tập hợp các ký tự và có thể khai báo bởi dấu nháy đơn ‘ hay dấu nháy đôi “
name = "Jeremy" # hiển thị "Jeremy"
size = len(name) # hiển thị độ dài 6 ký tự của chuỗi
twice = name * 2 # hiển thị "JeremyJeremy"
concat = name + "'s" # hiển thị "Jeremy's"
check = "e" in name # hiển thị True
first = name[0] # hiển thị "J"
last = name[-1] # hiển thị "y"
subset = name[1:4] # hiển thị "ere"
lower = name.lower() # hiển thị "jeremy"
upper = name.upper() # hiển thị "JEREMY"
Toán tử số học – Arithmetic
Toán số có thể sử dụng các ký tự: +, -, /, //, *, **, và %.
add = 3 + 7 # hiển thị tổng là 10
sub = 5 - 3 # hiển thị hiệu là 2
mul = 3 * 3 # hiển thị tích là 9
div = 5 / 2 # hiển thị thương là of 2.5
idiv = 5 // 2 # hiển thị kết quả là 2
exp = 2 ** 4 # hiển thị 16
rem = 7 % 2 # hiển thị 1
paren = (3 + 2) / 5 # hiển thị 1.0
Toán tử quan hệ – Relational Operators
Phép so sánh có thể sử dụng: >, >=, ==, <=, và <.
less = 2 < 4 # hiển thị True
less_equals = 3 <= 3 # hiển thị True
equals = 4 == 7 # hiển thị False
greater_equals = 5 >= 2 # hiển thị True
greater = -4 > 5 # hiển thị False
Kiểu dữ liệu Boolean – Boolean Algebra
Hoàn thành câu lệnh Boolean với các keywords: and, or, và not
is_cold = True # hiển thị True
is_wet = True # hiển thị True
is_not_cold = not is_cold # hiển thị False
am_sad = is_cold and is_wet # hiển thị True
am_mad = is_cold or is_wet # hiển thị True
Dictionaries bao gồm các key và value, sử dụng cặp dấu ngoặc nhọn {} để khai báo:
my_map = {"x": 2} # hiển thị {"x": 2}
value = my_map["x"] # hiển thị 2
my_map["y"] = 5 # adds "y": 5 to dict
list(my_map.keys()) # trả về [x, y]
list(my_map.values()) # trả về [2, 5]
Danh sách – List
List trong Python cho phép lưu nhiều kiểu data, và sử dụng cặp dấu ngoặc vuông [] để khởi tạo list.
items = [1, 2, 3] # hiển thị [1, 2, 3]
length = len(items) # hiển thị 3
begin = items[0] # hiển thị 1
end = items[-1] # hiển thị 3
section = items[0:1] # hiển thị [1]
exists = 2 in items # hiển thị True
items.append(4) # adds 4 to end of list
items.extend([5, 6]) # appends 5 and 6
items.reverse() # đảo ngược thứ tự của list
items.clear() # làm trống list
Vòng lặp – Loops
Để lặp lại 1 section code, Python sẽ dùng cả vòng lặp while và for.
# prints "h\ni\n"
greet = "hi"
index = 0
while index < len(greet):
print(greet[index])
index += 1
#cùng code, nhưng lặp for
for index in range(len(greet)):
print(greet[index])
#cùng code, nhưng lặp for each
for char in greet:
print(char)
Điều kiện – Conditionals
Với Python, conditions sử dịng cú pháp if/elif/else.
# prints "Nice car!"
cars = ["Tesla", "Ford", "Toyota"]
if "Toyota" in cars:
print("Nice car!")
elif "Audi" in cars:
print("Not bad!")
else:
print("Mistakes were made.")
Ngoài ra còn có thể chèn if trong if
# removes "Toyota" from cars
# prints "We won't be needing that!"
if "Toyota" in cars:
if "Tesla" in cars:
cars.remove("Toyota")
print("We won't be needing that!"
Bao hàm – Comprehensions
Comprehension được coi là hàm kết hợp giữa list và dictionaries
# tạo list từ 0 đến 49
nums = [x for x in range(50)]
# tạo list các số nhân đôi
doubles = [x * 2 for x in nums]
# tạo list các số chẵn
evens = [x for x in nums if x % 2 == 0]
# tạo mapping cho số chẵn
map = {x: y for x, y in zip(nums, evens)}
Bài viết được sự cho phép của tác giả Võ Xuân Phong
Khi làm việc với ReactJS, chúng ta đã nghe khá nhiều về 2 cái tên Webpack với Create React App. Vậy Webpack với Create React App khác nhau như thế nào? Chúng ta sẽ cùng nhau tìm hiểu ở bài viết này nhé.
Webpack với mục đích chung nhất là để đóng gói, nó dùng để chuyển đổi code React + ES6 sang Javascript thuần (plan-vanilla JS), nó cực kỳ hữu ích và mềm dẻo, nó có thể được cấu hình để bao gồm những thứ mà khi xây dựng một ứng dụng React có thể cần, nhưng nó tốn nhiều thời gian để developer hiểu và cấu hình thiết lập. Webpack cũng hoạt động tốt với Angular, Vue, NodeJS và kể cả là Web Assembly.
Vì lý do trên, mà Facebook đã tạo ra Create React App, chứa Webpack ở bên trong. Mọi thứ đã được cấu hình sẵn, developer chỉ cần tập trung vào việc code, chứ không phải việc ngồi cấu hình cho dự án. Nhưng với Create React App, để cấu hình một cách linh hoạt như Webpack thì đó là một điệu cực kỳ khó khăn.
Bên dưới đây, là một số so sánh cụ thể hơn nữa về Create React App Và Webpack.
Webpack là một mô-đun đóng gói trong khi react-script là một npm package, nó chứa các dependency (gói thư viện) cần để khởi tạo nhanh một project ReactJS như “babel” và “webpack” cũng có trong danh sách các dependency của react-script.
Môi trường
Create React App không có file build cấu hình vì thế chúng ta không thể cấu hình cho nó. Nếu bạn muốn điều chỉnh một số thứ bạn phải sử dụng đến lệnh “npm run eject” để nó xuất ra cho bạn các file cấu hình để bạn điều chỉnh. Mà bạn biết rồi đấy code hay cấu hình của một ai đó sẽ khiến bạn khó hiểu và bối rối mỗi khi xem chúng.
Với Webpack bạn có toàn quyền cấu hình môi trường phát triển cho dự án của bạn, và cấu hình theo cái mà bạn mong muốn.
Server Side Rendering
Để cấu hình và thiết lập SSR với Create React App thì rất đau đầu, với Webpack thì mọi chuyện sẽ dễ dàng hơn.
Trong khi sử dụng Webpack, thì bạn sẽ hoàn toàn dễ dàng, thoải mái chỉnh sửa cấu hình của Webpack, khi có sự thay đổi hoặc bạn muốn nâng cấp dự án.
Với Create React App thì tất cả được quản lý bởi cộng đồng React.
Tổng kết
Create React App phù hợp nhất cho các dự án nhỏ, nó không phù hợp cho các dự án lớn và phức tạp.
Sử dụng Create React App, sẽ tiết kiệm được thời gian khởi tạo và thiết lập dự án cho các bạn mới học React. Các bạn có thể tập trung vào học cách code React mà không cần lo lắng hay quan tâm “babel” là gì hay các thiết lập phức tạp khác trong file cấu hình Webpack.