Hacker News là một nền tảng cho phép các dev chia sẻ link và cùng thảo luận về các link đó. Hầu hết các chia sẻ đó đều liên quan đến Silicon Valley, Entrepreneurship, and Tech.
Sử dụng Hacker News cho phép người dùng cập nhật sớm nhất hệ sinh thái công nghệ của Silicon Valley và Hoa Kỳ. Các cuộc thảo luận trên Hacker News đều đã trải qua kiểm duyệt nên đáng tin cậy hơn.
Udemy là một trong những trang web giảng dạy bằng video lớn nhất trên thế giới, với lượng video bài giảng về công nghệ cực kỳ lớn. Sử dụng Udemy sẽ giúp bạn học thêm các skill mới khi làm developer.
ProductHunt là website mà các dev và các công ty phát hành những trang web hoặc app mà họ đã build được. Khi sử dụng ProductHunt bạn sẽ biết có bao nhiêu website, bao nhiêu app được phát hành mỗi ngày cũng như có thể tự mình cho ra mắt web hoặc app mình đã build.
DigitalOcean cung cấp dịch vụ lưu trữ cho phép bạnlưu trữ servers, cơ sở dữ liệu,… Đây là nền tảng đã được nhiều dev sử dụng. Bạn nên sử dụng DigitalOcean khi: đang thực hiện các project cá nhân, muốn có giao diện dễ sử dụng.
diff.blog là công cụ tổng hợp các blog về engineering. Website này có hàng ngàn bài blog về engineering và dev được tổng hợp (kể cả các blog trên dev.to).
Nếu đang sở hữu một blog về software engineer, bạn có thể giới thiệu về nó trên website diff.blog để thu hút được lượng người theo dõi đổ về trang mình.
Leetcode giúp bạn tìm kiếm nhiều tips,lời khuyên cho cuộc phỏng vấn việc làm của mình. Trên nền tảng này, bạn có thể thực hành viết code trước khi đi phỏng vấn, kinh nghiệm thực tế của những người đi trước sẽ giúp bạn làm tốt hơn.
StackOverflow.com và AskUbuntu rất nổi tiếng trong cộng đồng dev, nhưng ít người biết rằng 2 trang này đều là thành viên trong network StackExchange. Và vẫn còn rất nhiều các trang web khác trong network của StackExchange mà mình vẫn hay theo dõi như:
TopDev Challenge lần đầu tiên khởi động vào tháng 10/2020 kết hợp cùng nền tảng HackerRank hứa hẹn một sân chơi chuyên nghiệp, công bằng, trực quan không cảm tính hay thiên vị dành riêng cho Tech Fresher sẵn sàng đương đầu thử thách!
Theo chân TopDev đến với HackerRank – nền tảng có đến 11M+ coder trên toàn thế giới tin tưởng chọn để kiểm tra năng lực của mình. Nếu đây từng là nơi “luyện code” nay đã trở thành một đấu trường cạnh tranh năng lực cùng những món quà hấp dẫn “dân công nghệ Việt” không tài nào bỏ qua.
Cơ chế cuộc thi
TopDev Challenge 2020 diễn ra trong tháng 10 gồm có 03 Round riêng lẻ:
Qualification Round 01
Thời lượng: 9:00 – 21:00 | ngày 10/10/2020
Tranh giải TOP 3 / 200 thí sinh
TOP 20 đặc cách vào vòng Final
2. Qualification Round 02
Thời lượng: 9:00 – 21:00 | ngày 17/10/2020
Tranh giải TOP 3 / 200 thí sinh
TOP 20 đặc cách vào vòng Final
3. Final Round
Thời lượng: 9:00 – 11:00 | ngày 29/10/2020
Tranh giải TOP 3 / 40 thí sinh chọn ra người thắng chung cuộc
[Bạn đã biết? “Đã làm Lập trình viên thì phải biết đến HackerRank để tập luyện.”]
HackerRank.com – nền tảng đã có đến 11M+ coder tài năng trên toàn thế giới tin tưởng lựa chọn để kiểm tra năng lực, thi đấu với nhau, nếu bạn còn chưa biết đến platform này, hẳn sẽ còn nhiều điều đang đợi bạn khai phá! Bởi hiện tại, nhiều công ty lớn trên thế giới đang sử dụng nền tảng HackerRank như một công cụ hỗ trợ tuyển dụng như Facebook, Quora, Shopify, Booking.com, WePay, VMware, Red Hat,…
TopDev – Việc Làm IT Hàng Đầu : được biết đến là đơn vị đầu tiên mang chương trình đánh giá ứng viên IT uy tín nhất thế giới đến Việt Nam cùng hệ thống trang tuyển dụng đã tích hợp HackerRank ngay trên nền tảng của TopDev.
Bài viết được sự cho phép của tác giả Trần Anh Tuấn
Có bao giờ các bạn code CSS cho một site nào đó của bạn bè hoặc dự án công ty. Nhưng code CSS xong rồi nó lại không nhận, mặc dù đã đúng đường dẫn, check thấy rõ ràng nhưng lại không được kết quả như mong muốn. Và bạn nhận ra rằng ah thì ra có 1 đoạn code CSS ai đã code trước đó sử dụng #id, inline style hoặc !important
Ai dè mình code hoài sửa hoài mà CSS của mình nó không có chạy. Lúc này bạn mới nhận ra rằng độ ưu tiên trong CSS nó rất là quan trọng. Vì thế hôm nay chúng ta sẽ cùng tìm hiểu tất tần tật về độ ưu tiên trong CSS nó như thế nào nhé
Các bạn đoán thử xem. Kết quả ra 10px hay là 14px ? Mình nghĩ hầu hết các bạn sẽ đoán đúng là 14px đúng không nào.
Thứ nhất là vì nó nằm dưới nên độ ưu tiên nó cao hơn, thứ hai là nó có thêm class .text kèm theo nữa. Chà dễ quá dễ, nếu như vậy thì cần gì phải học nhỉ. Đừng vội mừng. Tiếp tục xem ví dụ dưới đây nà.
div p.text {font-size:14px;}#header p {font-size:20px;}
Ấy chà chà khó hơn rồi đây. Không code chạy thử nhé vì chúng ta cần hiểu và làm chớ code ra thì dễ rồi. Chỗ này người nào đã từng làm nhiều thì sẽ biết ngay thôi tuy nhiên người mới sẽ nghĩ là chắc là font-size: 14px rồi vì nó có 3 cái luôn như là thẻ div bọc ngoài rồi đến thẻ p kèm theo class .text chắc chắn là ưu tiên hơn ở dưới rồi.
Nhưng kết quả lại không nghiêng về người mới. Kết quả là người có kinh nghiệm đúng là font-size: 20px .Tại sao ? Tại vì #id nó ưu tiên hơn thẻ bình thường hơn class nên nó sẽ lấy CSS đoạn ở dưới thôi. Vì sao lại thế thì bạn nên hỏi người tạo ra CSS nha kaka
# Câu chuyện nhỏ nho
Để rõ ràng hơn về độ ưu tiên này trong CSS thì mình làm câu chuyện nho nhỏ như sau cho các bạn dễ hình dung. Giả sử các bạn đang xếp hàng có 4 người mua bánh. A (anh bạn) B (Bạn) C (Chú bạn) D (Dì bạn) thì bây giờ theo thứ tự ưu tiên sẽ là A B C D hen.
Đầu tiên là các elements(thẻ) trong CSS như là thẻ p, div, section , header … thì độ ưu tiên trong CSS của nó nằm cuối ta có (0A, 0B, 0C, 1D)
Tiếp theo là các class,pseudo class như .home , .content , :hover , :before , :after hoặc các attribute(thuộc tính) như a[target="_blank"], input[type="text"], a[href^="http"]… thì độ ưu tiên của nó nằm kế cuối ta có (0A, 0B, 1C, 0D)
Tiếp đến là các id như #header, #banner nó có độ ưu tiên thứ nhì ta được (0A, 1B, 0C, 0D)
Và cuối cùng là inline-style. Nghĩa là code trực tiếp bên trong thẻ HTML luôn như này và nó có độ ưu tiên cao nhất ta được (1A, 0B, 0C, 0D)
<div style="color: red;">Hello friends</div>
Giờ nhìn lại vào đoạn code khi nãy thì thấy đoạn code ở dưới có độ ưu tiên cao hơn cho nên nó sẽ chạy đoạn code đó #header p đó. Vì sao vì lúc này thèn 1B(bạn) đứng trước ưu tiên nhất và đoạn code trên có 0B cho nên độ ưu tiên thấp hơn và bạn đừng quan tâm con số 2D hay 1D vì nó đã nằm cuối là độ ưu tiên thấp nhất ko quan trọng là bao nhiêu số nhé.
div p.text {/*2 elements và 1 class ta có (0A,0B,1C,2D)*/font-size:14px;}#header p {/*1 id và 1 element ta có (0A,1B,0C,1D)*/font-size:20px}
Cho dù bạn code như thế này thì cái số 5 đó không có nghĩa lý gì khi nó vẫn đứng cuối. Còn thằng đứng cao hơn nó là đoạn code ở dưới có #id đó vẫn ưu tiên hơn. Giống như lúc xếp hàng, bạn đã được xếp đứng đầu thì cho dù thằng đứng cuối cao hơn bạn 5m thì nó vẫn đứng chót và độ ưu tiên vẫn thua bạn mà thôi.
<div id="header"><div><div><div><pclass="text">Welcome my friends</p></div></div></div></div>
div div div div p.text {/*5 elements và 1 class ta có (0A,0B,1C,5D)*/font-size:14px;}#header p {/*1 id và 1 element ta có (0A,1B,0C,1D)*/font-size:20px}
À còn 1 điểm nữa nếu như mình muốn đoạn code div p.text đè được đoạn code ở dưới mà không muốn thêm elements hay id thì sao. Tức là Dì bạn muốn mua trước bạn đó. Tất nhiên là có cách và đó chính là !important. Kiểu như Dì bạn có ngôi sao hi vọng hay quyền ưu tiên vì lớn tuổi nên dì bạn sử dụng chúng để mua hàng trước bạn.
Cho nên khi sử dụng thêm !important(quan trọng) lúc này nó sẽ có độ ưu tiên cao nhất luôn cao hơn cả cái inline style
Cho nên lúc này đoạn code trên sửa lại như này và nó sẽ chạy đoạn code div p.text và dì bạn sẽ mua được bánh trước bạn. Nhưng bạn đứng trước mà bạn muốn mua trước nên vì thế bạn cũng có thể sử dụng !important
div p.text {font-size:14px!important;}#header p {font-size:20px!important;}
Thì lúc này nó ngang hàng về mặt !important coi như ta bỏ nó ra rồi so sánh như ở trên ban đầu thôi. Và tất nhiên là đoạn code ở dưới có thêm #header p (là bạn đó) sẽ đè đoạn ở trên rồi. Haha mua được bánh rồi nhóe.
# Lưu ý
Trước khi kết thì còn vài điểm nữa là nếu trường hợp cả 2 đoạn code đều có thẻ #id ưu tiên như nhau thì lúc này nó sẽ xét số lượng các thẻ còn lại như vầy. Đoạn code này nó sẽ ưu tiên đoạn ở trên nha. Lúc này độ ưu tiên về #id như nhau nên nó sẽ xem xét các số lượng thẻ còn lại(4D > 2D) nên nó ưu tiên hơn nà.
#header div div div p {/*4 elements và 1 id ta có (0A,1B,0C,4D)*/font-size:14px;}#header div p {/*1 id và 2 element ta có (0A,1B,0C,2D)*/font-size:25px;}
Trường hợp tất cả đều bằng nhau thì nó sẽ ưu tiên đoạn code ở dưới nhé. Vì độ ưu tiên trong CSS chạy từ dưới lên
#header div div div p {/*4 elements và 1 id ta có (0A,1B,0C,4D)*/font-size:14px;}#header div div div p {/*1 id và 4 element ta có (0A,1B,0C,4D)*/font-size:25px;}
Thế trường hợp như này các bạn nghĩ là cái nào nà. Rõ ràng là đoạn code trên ưu tiên hơn vì so sánh như sau: 0A = 0A, 1B = 1B, 1C > 0C, 4D = 4D. Làm lâu riết các bạn sẽ dễ dàng nhận ra luôn mà không cần phải tính toán nhiều.
#header div div div p.text {/*4 elements 1class và 1 id ta có (0A,1B,1C,4D)*/font-size:14px;}#header div div div p {/*1 id và 4 element ta có (0A,1B,0C,4D)*/font-size:25px;}
Đặc biệt là khi các bạn custom CSS cho WordPress. Code nó bao dài luôn. Đòi hỏi các bạn phải hiểu để dùng cho đúng chứ không nên lạm dụng !important nhé. Nó chỉ dùng trong trường hợp bắt buộc, không thể tìm được độ ưu tiên nào khác cao hơn cái gốc nữa mới dùng nha.
Đây là một đoạn code dài khủng hoảng bên WordPress cho các bạn xem ví dụ để hiểu được rằng độ ưu tiên trong CSS nó quan trọng như thế nào. Bạn muốn đè đoạn code này ư ? Hãy phân tích nó từ các thẻ HTML và Class trong trang web nhé.
Một điểm lưu ý cuối cùng đó là Internal CSS và External CSS cụ thể là CSS nằm trong cặp thẻ <style>.code{}</style> bên trong HTML so với <link href=”css/style.css”> đường dẫn tới file CSS trong thư mục nào đó nếu thẻ nào nằm sau thì thẻ đó có độ ưu tiên cao hơn nhé.
# Lời kết
Hi vọng với câu chuyện vui nhộn kèm theo giải thích chi tiết sẽ giúp bạn hiểu được rõ ràng hơn về thứ tự độ ưu tiên trong CSS. Nó rất là quan trọng nên các bạn chú ý học chứ đừng bỏ qua nhé. Nếu có gì thắc mắc góp ý hoặc cám ơn thì cứ comment mình sẽ trả lời. Chúc các bạn một ngày tốt lành nà
Ở những bài học trước, mình đã hướng dẫn bạn cách thiết kế bố cục trang web bằng cách sử dụng thuộc tính float, kỹ thuật clear float hay đặt các position lồng nhau. Tuy nhiên phương pháp này thường phải viết khá nhiều code CSS và kết quả thì thực sự là khó đoán trước, có thể như ý bạn, cũng có thể cực kì… tệ.
Nhưng thật may mắn, Flexbox Layout đã ra đời để cải thiện những nhược điểm này. Với Flexbox, bạn có thể giải quyết rất nhiều vấn đề về dàn trang trong CSS một cách linh hoạt, dễ dàng và tiết kiệm thời gian chỉ bằng một vài dòng code. Vậy chúng ta cùng tìm hiểu xem Flexbox là gì và lý do tại sao nó lại mạnh mẽ như vậy?
Flexbox là gì?
Flexbox Layout (còn gọi là Flexible Box hay CSS flexbox) là một kiểu bố cục trang có khả năng tự cân đối kích thước, thay đổi chiều rộng/chiều cao và thứ tự phần tử bên trong để phù hợp với tất cả các loại thiết bị hiển thị và kích thước màn hình.
Với bố cục thông thường, bạn cần phải thiết lập kích thước của phần tử, thiết lập hiển thị dạng block hay inline, cho nó float, còn với Flexbox bạn chỉ cần thiết lập phần hiển thị theo chiều ngang hay chiều dọc, lúc đó các phần tử bên trong có thể hiển thị theo ý muốn..
Lưu ý: Flexbox Layout phù hợp nhất để thiết lập bố cục ở quy mô nhỏ, còn thiết lập bố cục với phạm vi lớn hơn thì vẫn nên sử dụng kiểu thông thường là dàn trang theo dạng lưới (grid layout).
Các khái niệm cơ bản và thuật ngữ
Bố cục Flex được thiết lập từ một khung lớn (parent container) đóng vai trò là khung linh hoạt (flex containter) và các thẻ con ngay trong nó (immediate children) đóng vai trò các mục nhỏ linh hoạt (flex item).
Dưới đây là sơ đồ cấu trúc Flexbox:
Thành phần quan trọng nhất của Flexbox là
container: là thành phần lớn bao quanh các phần tử bên trong, các item bên trong sẽ hiển thị dựa trên thiết lập của container này.
item: là phần tử con của container, bạn có thể thiết lập nó sẽ sử dụng bao nhiêu cột trong một container, hoặc thiết lập thứ tự hiển thị của nó.
Các item sẽ được bố trí theo trục main axis (bắt đầu từ main-start, kết thúc ở main-end) hoặc theo trục cross axis (bắt đầu từ cross-start, kết thúc ở cross-end).
main axis: đây là trục chính để điều khiển hướng mà các item sẽ hiển thị. Lưu ý, main axis không phải lúc nào cũng nằm ngang như sơ đồ trên, bạn có thể sử dụng thuộc tính flex-direction để thay đổi hướng của trục và lúc đó các item sẽ hiển thị theo nó.
main-start | main-end: khi thiết lập flexbox, các item nằm trong container hiển thị từ điểm bắt đầu gọi là main-start tới điểm kết thúc gọi là main-end.
main size: kích thước (chiều rộng hoặc chiều cao) của các item, tùy thuộc vào hướng của main axis.
cross axis: cross axis luôn là trục vuông góc của main axis. Hướng của nó phụ thuộc vào hướng của main axis.
cross-start | cross-end: có ý nghĩa tương tự nhưng luôn vuông góc với main start, main end.
cross size: kích thước (chiều rộng hoặc chiều cao) của các item dựa trên trục cross axis, tùy thuộc vào hướng của main axis.
Theo mặc định, item sẽ tự động thay đổi kích thước phần tử để nó luôn hiển thị trên cùng một dòng dù bạn có resize trình duyệt theo kích thước nào, điều này dễ làm cho nội dung bên trong (nếu có) bị giãn hay ép nhỏ lại, có thể gây xấu giao diện.
Vì vậy, ta có thuộc tính flex-wrap cho phép item tự động xuống dòng khi kích thước container thay đổi.
Theo mặc định, các item bên trong sẽ bắt đầu từ main start đến main end, tuy nhiên, đôi khi container vẫn còn khoảng trống. Vì vậy, bạn có thể sử dụng thuộc tính justify-content để điều chỉnh vị trí bắt đầu và căn chỉnh các item bên trong container theo dọc theo trục main axis, chiều ngang hoặc chiều dọc tùy thuộc vào flex-direction.
flex-start: giá trị mặc định, item sẽ bắt đầu từ lề chính main-start của container.
flex-end: item sẽ bắt đầu từ lề chính main-end của container (khác với row-reverse là đổi hướng hiển thị).
center: item sẽ nằm giữa container.
space-between: các item sẽ có khoảng cách giữa các phần tử bằng nhau do container sẽ tự động căn khoảng cách, item đầu tiên sát lề chứa điểm main-start, item cuối cùng sát lề chứa điểm main-end.
space-around: tương tự space-between, nhưng khác ở chỗ là mỗi item có khoảng cách 2 bên cạnh và những khoảng cách này bằng nhau.
space-evenly: các item được phân phối sao cho khoảng cách giữa hai item bất kỳ, giữa item và các lề là bằng nhau.
Thuộc tính align-items sử dụng để điều chỉnh vị trí bắt đầu và căn chỉnh các item bên trong container theo dọc theo trục cross axis, chiều ngang hoặc chiều dọc tùy thuộc vào flex-direction.
stretch: giá trị mặc định, các phần tử sẽ được kéo dài để lấp đầy container chứa nó, nhưng sẽ ưu tiên giá trị height/width nếu có, khi đó item sẽ không cao full mà chỉ lấy giá trị height/width mà bạn set.
flex-end: item sẽ bắt đầu từ lề cross-end của container. Trường hợp mặc định với cross axis đứng dọc, flex-direction: row thì các item sẽ dồn xuống dưới.
baseline: item được căn chỉnh theo đường cơ sở của chúng.
Đường cơ sở là đường mà tất cả các chữ cái sẽ “ngồi lên”. Bạn có thể sử dụng kích thước font chữ khác nhau để thấy rằng các mục được căn chỉnh theo đường cơ sở baseline:
Thuộc tính align-content sử dụng để căn chỉnh khoảng cách các item bên trong container theo dọc theo trục cross axis, chiều ngang hoặc chiều dọc tùy thuộc vào flex-direction.
space-between: các item sẽ có khoảng cách giữa các phần tử bằng nhau do container tự động căn khoảng cách, item đầu tiên sát lề chứa cross-start, item cuối cùng sát lề chứa cross-end.
Thuộc tính flex-grow cho phép các phần tử giãn theo độ rộng của container.
Cú pháp:
.item { flex-grow:<number>;/* mặc định là 0 */}
Thuộc tính này hơi phức tạp, Quantrimang sẽ minh họa một số trường hợp hay gặp cho bạn dễ hình dung hơn. Ví dụ ta set các item có độ rộng là 100px.
Giá trị mặc định của thuộc tính flex-grow là 0, các item sẽ không tự động co giãn kích thước, để lại nhiều khoảng trống trong container.
Khi ta tăng flex-grow = 1, item sẽ tự động giãn ra đều nhau sao cho vừa với khung container.
Giá trị của flex-grow rất linh động, khi set thuộc tính này cho tất cả các item với cùng một giá trị thì các item sẽ có tỉ lệ như nhau và được dàn đều lấp đầy container. Ví dụ set tất cả các phần tử flex-grow là 1 thì tất cả đều như nhau tỉ lệ 1:1, mà set flex-grow là 100 thì kết qua vẫn sẽ ra tương tự với tỉ lệ 1:1.
Nhưng điều thú vị hơn ở flex-grow là áp dụng nó cho từng item. Ta có giá trị mặc định ở tất cả phần tử là flex-grow = 0, thay đổi riêng giá trị của item2 thành 1, kết quả như sau:
Vậy là ở đây, thiết lập flex-grow là 1 thì item2 sẽ lấy phần trống còn lại của container đắp vào chính nó.
Bây giờ hãy thử cho các phần tử đều là flex-grow: 1, nhưng set riêng phần tử thứ 3 giá trị khác:
Lúc này thì tất cả các item đều được giãn ra lấp đầy phần trống của container, nhưng item3 có flex-grow: 3 sẽ được thừa hưởng nhiều phần trống hơn các item còn lại chỉ có flex-grow: 1, cụ thể là hơn khoảng 3 lần. Và như đã đề cập ở trên, thuộc tính flex-grow làm cho các phần tử tỉ lệ với nhau. Giả sử các item đều có flex-grow: 4 và item3 có thuộc tính flex-grow: 12 thì nó cũng tương tự như là 1 với 3.
Thuộc tính flex-shrink ngược lại với thuộc tính flex-grow ở trên, nó không giãn ra mà lại co lại khi chúng ta thay đổi độ rộng của container.
Cú pháp:
.item { flex-shrink:<number>;/* mặc định là 1 */}
Giá trị mặc định trong flex-shrink là 1, cho phép các phần tử co lại bằng nhau khi độ rộng container giảm xuống. Nếu flex-shrink: 0 thì item sẽ không co giãn mà lấy nguyên giá trị của thuộc tính width/height.
Nếu muốn item3 nó co lại nhiều hơn so với các item khác thì tăng giá trị flex-shrink của nó lên.
Resize cửa sổ trình duyệt nhỏ lại thì item3 co lại nhiều hơn:
flex-basis
Thuộc tính flex-basis sử dụng để xác định độ dài ban đầu của một item.
Cú pháp:
.item { flex-basis:<length>|auto;/* mặc định là auto */}
Nếu bạn xác định độ dài chung của class item là 100px nhưng tùy chỉnh item3 với flex-basis: 250px thì ta sẽ được như sau:
flex
Thuộc tính flex sử dụng để gộp chung ba thuộc tính flex-grow, flex-shrink và flex-basis.
Thì bạn có thể sử dụng thuộc tính flex một cách ngắn gọn:
flex:13250px;
Giá trị mặc định của flex là:
flex:01auto;
Lưu ý:
Nếu thuộc tính chỉ có một tham số thế này: flex: 1; thì ta hiểu đó là flex-grow.
Nếu thuộc tính chỉ có một tham số có đơn vị độ dài như thế này: flex: 250px; thì ta hiểu đó là flex-basis.
Nếu thuộc tính có hai tham số thế này: flex: 1 250px; thì ta hiểu đó là flex-grow và flex-basis.
Nếu thuộc tính có hai tham số thế này: flex: 1 2; thì ta hiểu đó là flex-grow và flex-shrink.
align-self
Thuộc tính align-self có tác dụng tương tự như align-items của phần container nhưng sử dụng riêng cho từng item, bạn có thể dùng nó để đặt lại vị trí cho một số item mà align-items đã quy định.
.item { align-self: auto | flex-start | flex-end | center | baseline | stretch; }
Align-self cũng có các giá trị giống như align-items đó là: flex-start, flex-end, center, stretch và baseline.
Ví dụ: Ta có 5 item đã được căn ra giữa nhờ align-items:center như sau:
Bạn có thể căn chỉnh các item theo ý thích, item1 nằm ở trên cùng, item3 thì phải kéo giãn dài ra và item5 thì phải nằm dưới cùng, hãy dùng align-self để đặt lại các vị trí.
<!DOCTYPE html><html><head><title>Page Title</title><metacharset="UTF-8"><metaname="viewport"content="width=device-width, initial-scale=1"><style>*{ box-sizing: border-box;}/* Style the body */body { font-family:Arial; padding:10px; background:#e9d8f4; margin:0;}/* Header/logo Title */.header { padding:10px; text-align: center; background: white; color:#58257b;}.header h1 { font-size:40px;}.header p { font-size:20px;}/* Định dạng navigation bar */.navbar { display: flex; background-color:#58257b;}/* Định dạng link điều hướng */.navbar a { color:#f2f2f2; padding:14px20px; text-decoration: none; text-align: center;}/* Thay đổi màu liên kết khi di chuột qua */.navbar a:hover { background-color:#db7093; color: white;}/* Column container */.row { display: flex; flex-wrap: wrap;}/* Tạo hai cột không bằng nhau nằm cạnh nhau *//* Sidebar/Cột trái */.side { flex:30%; background-color:#f1f1f1; padding:20px;}/* Cột chính */.main { flex:70%; background-color: white; padding:20px;}/* Hình ảnh tượng trưng */.fakeimg { background-color:#baa1cc; width:100%; padding:20px;}/* Footer */.footer { padding:10px; text-align: center; background: white; margin-top:10px;}/* Bố cục linh hoạt: các cột xếp chồng lên nhau thay vì cạnh nhau khi màn hình có chiều rộng dưới 600px */@media screen and(max-width:600px){.row,.navbar { flex-direction: column;}}</style></head><body><!-- Header --><divclass="header"><h1>Website Quản Trị Mạng</h1><p>Kiến thức - Kinh nghiệm - Hỏi đáp</p><p>Sử dụng <b>flexible</b> layout.</p></div><!-- Navigation Bar --><divclass="navbar"><ahref="#">Làng Công nghệ</a><ahref="#">Công nghệ</a><ahref="#">Khoa học</a><ahref="#">Cuộc sống</a></div><!-- Nội dung --><divclass="row"><divclass="side"><h2>Giới thiệu</h2><divclass="fakeimg"style="height:200px;">Ảnh</div><p>Quantrimang.com là mạng xã hội về khoa học công nghệ.</p><h3>Nổi bật</h3><divclass="fakeimg"style="height:60px;">Ảnh</div><br><divclass="fakeimg"style="height:60px;">Ảnh</div><br><divclass="fakeimg"style="height:60px;">Ảnh</div><h3>Follow Me</h3><p>Facebook</p><p>YouTube</p></div><divclass="main"><h2>Form - Biểu mẫu trong CSS</h2><h5>Quách Tỉnh, 14/02/2019</h5><divclass="fakeimg"style="height:200px;">Ảnh</div><p>Form là một phần không thể thiếu trong bất kì loại website nào.</p><p>Ở bài viết này, Quantrimang.com sẽ hướng dẫn bạn cách xây dựng phần giao diện hiển thị của một biểu mẫu cơ bản. Giao diện này có thể được làm khá đẹp mắt với CSS</p><br><h2>Attribute Selector trong CSS</h2><h5>Quách Tỉnh, 14/02/2019</h5><divclass="fakeimg"style="height:200px;">Ảnh</div><p>Attribute selector là cách chọn các phần tử bạn muốn định kiểu trong tài liệu HTML dựa vào thuộc tính của một hay nhiều thẻ HTML nào đó.</p><p>Attribute selector có thể chọn được các đối tượng mà không cần phải khai báo thêm các Class hoặc ID vào trong thẻ HTML và vẫn có thể hướng được đến các thành phần đó, giúp code gọn gàng hơn và mạch lạc hơn.</p></div></div><!-- Footer --><divclass="footer"><h4>Giấy phép số 362/GP-BTTTT. Bộ TT&TT cấp ngày 30/06/2016.</h4></div></body></html>
Con người chúng ta sinh đã luôn thích cái đẹp: người đẹp, tâm hồn đẹp, nhà đẹp, xe đẹp, quần áo đẹp và… Code đẹp – một quan niệm về cái đẹp chỉ có ở các lập trình viên. Mình cũng vậy, mình cũng như các bạn, rất thích cái đẹp, và rất thích code đẹp.
Code thế nào được coi là code đẹp?
Mỗi người lại quan điểm về cái đẹp khác nhau, hơn nữa “code đẹp” lại là một khái niệm chưa có trong từ điển Tiếng Việt, thế nên phần này mình xin trình bày quan điểm của mình thế nào là code đẹp nha:
Code chạy đúng trong mọi trường hợp: Nghĩa là cho dù sản phẩm của bạn có phát triển lớn tới cỡ nào, thì cũng vẫn là đoạn code đấy chạy. Sản phẩm của bạn có 1 người dùng cũng chạy đúng mà 10 triệu người dùng cũng vẫn chạy đúng, vẫn đáp ứng được hiệu năng.
Code chuẩn Style Guide: Style Guide là những quy ước về cú pháp, cách đặt tên biến, tên hàm, tên hằng trong dự án. Code chuẩn style guide là code tuân theo các quy ước này.
Code áp dụng các design pattern phù hợp: Design Pattern hiểu nhanh nó là một mô hình giúp các bạn giải quyết vấn đề, áp dụng design pattern chuẩn sẽ giúp code của bạn trong sáng và dễ hiểu, dễ tái sử dụng.
Code áp dụng các công nghệ tiên tiến nhất: Tất cả những gì tiên tiến nhất sẽ phải hội tụ trong dự án của bạn.
Code không bị dư thừa: Không dư thừa các các hàm không dùng đến, không dư thừa các file, các thư mục không dùng đến.
Code an toàn và bảo mật: Code sao để hacker không thể tấn công được.
Các tiêu chí về code đẹp là do mình tự đặt ra như vậy, có bạn nào đã từng làm dự án nào mà chứa toàn code đẹp như vậy chưa?
Không thể phủ nhận, code đẹp có rất nhiều mặt lợi. Mình nhớ hồi còn là sinh viên, vì túng tiền nên nhận bảo trì một trang web bán hàng cho một doanh nghiệp nọ. Họ yêu cầu mình thay đổi một số giao diện website kèm phát triển thêm một số tính năng mới, và hứa sẽ thưởng thêm nếu làm tốt công việc. Lúc nhận yêu cầu, mình thấy công việc cũng không có gì khó khăn, nghĩ bụng phen này chắc sắp giàu rồi. Thế nhưng mọi thứ quay ngoắt 180 độ khi mình có trong tay source code của họ… Dự án không hề áp dụng MVC mà viết lẫn lộn cả 3 thành phần vào nhau, tên file và thư mục thì tùy ý đặt tên, code thì không tuân theo style nào cả, mọi thứ cứ lẫn lộn lên như ly chè thập cẩm. Mình chán ngán và hỏi tại sao code lại “thúi” như vậy, thì các anh ở đấy bảo code này được phát triển từ một đề tài của sinh viên từ khá lâu rồi, lại trải qua nhiều lần nâng cấp, mỗi người thêm thắp một tý thành ra source code mới rối rắm đến thế. Nghĩ mà chán, thế nên mình quyết định từ bỏ dự án này, cũng may là bên họ tốt không bắt mình đền bù dự án :'(.
Kể câu chuyện như vậy để bạn thấy rằng tầm quan trọng của việc code đẹp, nếu dự án được được áp dụng mô hình MVC thôi, là quá trình bảo trì đã đơn giản hơn rất nhiều rồi. Nhưng đằng này…
Bên cạnh những mặt lợi không thể chối cãi, thì khi code quá đẹp cũng gây ra một số tác dụng phụ ảnh hưởng xấu tới dự án và chính mình, vì cái gì quá cũng không tốt mà. Bản thân mình đã gặp và cảm nhận được một số ảnh hưởng tiêu cực của việc lúc nào cũng cố gắng code đẹp như sau:
Code nắn nót quá sẽ tốn nhiều thời gian
Quá nắn nót vào từng dòng code khiến mình mất nhiều thời gian để suy nghĩ hơn. Giả sử như nỗi khi muốn đặt tên biến, tên hàm, tên file, tên thư mục… Mình thường suy nghĩ kỹ xem có nên đặt tên như vậy không, nhiều khi lúc này thấy hợp lý rồi, nhưng ngày mai nghĩ lại thì lại thấy cái tên khác hợp lý hơn. Thế là quay ra sửa lại code ngày hôm qua, cứ như vậy tạo nên một vòng luẩn quẩn khiến mình mãi không hoàn thiện nổi một tính năng.
Suy nghĩ đến những trường hợp quá xa
Nghĩ quá xa, vượt quá phạm vi của bài toán khiến mình mãi không ưng với những dòng code mình viết ra. Ví dụ dự án của mình làm xong thì cùng lắm có 5000 người dùng, thế nhưng mình luôn nghĩ phải thiết kế hệ thống sao cho đáp ứng được 5 triệu người dùng. Dự án của mình không cần phải mở rộng, thế nhưng mình luôn code theo hướng có thể mở rộng. Điều này khiến mình tốn rất nhiều thời gian để tìm hiểu, để thay đổi, trong khi các trường hợp đấy không bao giờ xảy ra với dự án mình đang theo đuổi.
Tích hợp nhiều công nghệ mới, trong khi nó chưa phổ biến
Khi PHP vừa mới ra mắt phiên bản 7.0, mình hí hưởng triển khai ngay một dự án cho công ty trên nền tảng mới này. Sau khi làm xong, đến bước deploy thì không deploy nổi bởi vì hosting mà công ty mua chỉ chạy được PHP 5.x. Kết quả là công ty mình đã phải chuyển qua sử dụng VPS, để có thể tự cài PHP 7 lên và chạy.
Một câu chuyện khác nữa, thời mà vuejs nổi lên như một framework js tích hợp những thứ hay ho nhất của angularjs và reactjs. Mình có áp dụng vue vào một dự án outsource, thời gian đầu dự án chỉ có một mình mình làm thì không có đáng nói, chuyện chỉ đáng nói khi mình không làm dự án nữa và bàn giao lại cho team khác. Nhưng vì vue là một framework mới, nên team đó không ai biết gì về vue cả. Vậy là mình phải dành 1 tuần để training cho họ về vue. Thế nhưng cũng vì có dịp training này mà mình có thêm vài người bạn mới, và sau đó cũng nhận thêm được một vài dự án outsource của team đấy gửi về – đúng là cho đi thì sẽ được nhận lại mà.
Quá tập trung vào code mà quên mất mục đích chính của dự án
Có lần mình làm một dự án về rao vặt bất động sản, tính năng chính là cho khách có thể tạo tài khoản và đăng tin rao vặt lên website. Thế nhưng vì quá mải mê vào việc code sao cho đẹp mà mình cứ làm đi làm lại một tính năng phụ, trong khi tính năng chính cần tập trung thì không làm. Kết quả là sắp deadline, mình phải OT để làm cho kịp dự án.
Cứ tập trung vào các chi tiết phụ, còn chi tiết chính thì lại làm nham nhở :p
Mang dao mổ trâu đi giết gà
Một bài toán đơn giản thì hãy cứ giữ cho nó đơn giản – Mình chỉ ước là nhận ra điều này sớm hơn. Hồi mới đi làm, mình được giao cho một task là liệt kê danh sách các khách hàng dưới dạng bảng và có bộ lọc theo mã khách hàng, tên khách hàng, trạng thái,… Tính năng này không hề khó, thế nhưng vì muốn sản phẩm nhìn phải thật ngầu, thật đẹp nên mình đã tích hợp thư viện datatable để hiển thị danh sách này. Cứ nghĩ phen này chắc là được khen tấm tắc, nào ngờ phải đập đi làm lại vì lý do “mang dao mổ trâu đi giết gà”. Việc sử dụng datatable để hiển thị giao diện bảng nhìn thì đẹp thật nhưng nó không cần thiết trong trường hợp này, hơn nữa việc tích hợp thư viện bên thứ ba như vậy sẽ làm dự án khó bảo trì hơn.
Một câu chuyện khác nữa, mình có web có tính năng rút gọn link. Phiên bản đầu dự án được build bằng PHP thuần với html, css tự viết. Sau đó mình nghe nói đến framework Laravel tuyệt lắm, thế là mình sử dụng Laravel để làm backend thay cho PHP thuần trước đó. Tiếp đến, mình lại nghe nói đến Single Page App đem lại trải nghiệm mượt mà, thế là mình lại mày mò áp dụng Single Page App cho dự án này. Kết quả là sản phẩm có tốt hơn, nhưng không tốt hơn là mấy, trong khi mình lại tốn quá nhiều thời gian cho việc thay đổi này. Nếu như bỏ qua việc mình học được thêm 2 công nghệ mới ra, thì việc đánh đổi như vậy là không xứng đáng. Nhưng cũng may, đây chỉ là dự án cá nhân của mình, nên không ảnh hưởng tới ai cả.
Lời kết
Các cụ nói cấm có sai “cái gì cũng có hai mặt”, tốt quá cũng xấu, mà xấu quá thì… chắc chắn là xấu rồi. Qua bài viết này, mình muốn nhắn nhủ một vài điều như sau
Thứ nhất: Code đẹp, nhưng phải đẹp trong phạm vi của bài toán. Sản phẩm có 1 trăm người dùng, khác hoàn toàn với sản phẩm có 1 triệu người dùng, mặc dù hai sản phẩm có thể cùng tính năng.
Thứ hai: Code đừng quá thông minh, bởi không phải ai cũng đủ thông minh để có thể hiểu được những dòng code thông minh đó.
Thứ ba: Đôi khi phải đánh đổi sự tốt nhất, nhanh nhất bằng sự phổ biến nhất.
Thứ tư: Cân nhắc công sức bỏ ra để đánh đổi lấy code đẹp. Nếu có hai lựa chọn “Code đẹp 8 mất 1 giờ” và “Code đẹp 10 mất 100 giờ” thì hãy chọn Code đẹp 8.
Thứ năm: Những tính năng đã hoàn thiện thì hãy cứ để nó ở quá khứ, nếu muốn cải thiện thì phải có kế hoạch rõ ràng.
Thứ 6: Code đẹp chưa chắc tạo ra sản phẩm tốt, sản phẩm tốt chưa chắc đã là code đẹp
Bài viết trên là các kinh nghiệm mình rút ra được trong quá trình làm việc. Hy vọng sẽ giúp ích cho ai đó…
Hiện tại thì có rất nhiều các blog lập trình viết về việc làm sao để học lập trình tốt rồi, các phương pháp thì cũng hay và bổ ích. Nhưng hôm nay mình sẽ viết ngược lại, mình sẽ chỉ cho các bạn một số cách để học “dốt” lập trình, đảm bảo là bạn sẽ “dốt” mãi, “dốt” không ngóc lên được.
CÁCH 1: DÀNH CÀNG ÍT THỜI GIAN CÀNG TỐT
Cần cù thì bù siêng năng,… à nhầm bù thông minh. Nếu như bạn dành thời gian khoảng 30 phút mỗi ngày cho việc rèn luyện kỹ năng lập trình thì bạn sẽ không dốt được đâu. Thay vào đó bạn nên dành nhiều thời gian cho việc chơi game, lướt facebook vô bổ, xem phim, hoặc đi nhậu với bạn bè thì hơn. Trong trường hợp mà bạn không có việc gì để làm cả, thì mình khuyên bạn nên đi ngủ cho khỏe.
Bạn cũng phải lưu ý là đừng lên các diễn đàn, group facebook về lập trình, đừng subscribe các chanel youtube hay thường xuyên đọc blog về lập trình làm gì cả. Bởi như vậy bạn sẽ rất dễ dàng có kiến thức – không thể nào mà dốt nổi.
CÁCH 2: HÃY COI THƯỜNG CÁC KIẾN THỨC CƠ BẢN
Kiến thức cơ bản về lập trình như một số giải thuật tìm kiếm, giải thuật sắp xếp, cấu trúc dữ liệu, lập trình hướng đối tượng thì bạn đừng có học. Bởi đây đều là những kiến thức nền tảng giúp bạn trở thành một lập trình viên giỏi sau này.
Nếu có ai đó nói với bạn nên học thật chắc các kiến thức nền tảng này trước khi học các kiến thức cao siêu khác thì đừng nghe, tuyệt đối đừng nghe. Vì họ chỉ đang muốn bạn giỏi lập trình hơn thôi.
CÁCH 3: ĐỪNG NGHE LỜI KHUYÊN CỦA CÁC BẬC TIỀN BỐI
Lời khuyên mà mình nhắc tới ở đây là lời khuyên về cách phương pháp học lập trình hiệu quả.
Các bậc tiền bối (thầy cô, anh chị, bạn bè đi trước) là những người đã có kinh nghiệm thực tế, họ từng trải và thường biết cách làm sao để học tốt lập trình. Nếu như họ cho bạn lời khuyên chân thành thì… cứ làm ngược lại, hoặc ít nhất thì nên bỏ ngoài tai thì đảm bảo bạn sẽ không thể tiến bộ hơn trong lập trình.
CÁCH 4: HỌC LÝ THUYẾT LÀ QUÁ ĐỦ
Học thì phải đi đôi với hành, vì thế bạn đừng bao giờ thực hành cả. Việc thực hành làm các dự án nhỏ, làm các bài tập lớn sẽ khiến bạn củng cố kiến thức lập trình, khiến bạn giỏi lên khá nhanh. Vì thế đừng có thực hành, lý thuyết là quá đủ rồi, hoặc thậm chí bạn cũng chẳng cần học lý thuyết luôn nếu muốn trở thành người “dốt” nhất.
Mình thường có thói quen làm các dự án nho nhỏ để củng cố hoặc học thêm kiến thức mới, bạn tuyệt đối không nên học theo.
CÁCH 5: CÁC KHÓA HỌC MIỄN PHÍ ĐẦY TRÊN MẠNG, ĐỪNG BAO GIỜ TÌM KIẾM CHÚNG
Ngày nay quá dễ dàng để tìm thấy các khóa học lập trình miễn phí nhưng chất lượng trên mạng. Các từ khóa như học lập trình cơ bản, khóa học lập trình miễn phí là các từ khóa bạn nên tránh xa khi tìm kiếm nếu không muốn bị giỏi lên.
CÁCH 6: ĐỪNG CHỦ ĐỘNG
Nếu bạn có đang học mà gặp phải một vấn đề khó khăn thì đừng vội suy nghĩ làm gì cho mệt người, tìm ngay thằng bạn thân bênh cạnh mà hỏi. Hoặc được giao làm bài tập lớn để tuần sau báo cáo, thì cứ chơi đi, sát ngày báo cáo thì lên mạng tìm xem có bài nào tương tự thì mang về chỉnh sửa là được.
Nói tóm lại là bạn không nên chủ động tìm hiểu, không nên suy nghĩ trước khi hỏi.
CÁCH 7: ĐỪNG HỌC TIẾNG ANH
Có một điều bạn nên chú ý đó là các công nghệ mới thì đều bắt nguồn chủ yếu từ “trời Tây”. Vì vậy mà tài liệu công nghệ chuẩn và chính xác nhất thường được viết bằng Tiếng Anh. Bạn chỉ nên tìm hiểu các tài liệu được viết bằng Tiếng Việt, vì đa phần các công nghệ đó đều cũ hoặc không còn gì mới mẻ nữa, thậm chí còn không được sử dụng trong các dự án ngày nay.
Ngoài ra, nếu học tốt Tiếng Anh, bạn sẽ có nguy cơ bị tiếp xúc với một nguồn tài liệu vô cùng phong phú và đa dạng. Cái mà sẽ khiến bạn có thêm nhiều kiến thức, nhiều góc nhìn mà khiến bạn không thể nào dốt lập trình được.
CÁCH 8: ĐỪNG BAO GIỜ ĐAM MÊ
Sau cùng đây là yếu tố quan trọng nhất, bởi nếu đam mê thì trước sau gì bạn cũng sẽ giỏi lập trình à. Vậy nên hãy ghi nhớ “Muốn dốt lập trình, tuyệt đối không đam mê nó”.
Nếu như có bắt buộc phải học lập trình, thì cũng chỉ nên học dạng chống đối, như việc cố học để qua môn, hoặc nhờ người khác giải bài tập hộ chẳng hạn.
CUỐI CÙNG – KẾT LUẬN
Trên là một số điều mà mình cho rằng là cốt lõi nhất nếu bạn muốn học “dốt” lập trình. Vậy làm sao để học TỐT lập trình đây? Đơn giản thôi, cứ làm ngược lại những điều mình nói ở trên là được, hoặc ít nhất cũng tránh những điều đó ra.
Trong bài trước, mình đã bình luận tại sao chúng ta — những lập trình viên — nên bỏ thời gian để tìm hiểu về UI/UX. Hôm nay, mình xin chia sẻ một vài tip nhỏ để nhanh chóng cải thiện UI.
Những tip dưới đây mình lượm nhặt được dựa trên các bài viết của Marc Andrew. Đó là những điều không quá “vĩ mô” nhưng sẽ cải thiện nhiều cho thiết kế app của bạn.
1. Làm cho các thành phần tách biệt với nhau hơn
Các thành phần có thể tách biệt với nhau hơn bằng cách dùng đường viền (border) rất mảnh, đậm màu hơn một chút so với phần bóng đổ (shadow) của đối tượng.
2. Chỉ dùng một typeface
Có thể bạn đã nghe nhiều về lời khuyên dùng ít nhất 2 typeface. Tuy nhiên, bạn có thể đạt kết quả tốt nếu kết hợp những màu sắc, kích cỡ (font size), độ dày (font weight) khác nhau của cùng môt typeface. Trong khi đó, việc dùng một typeface duy nhất giúp cho thiết kế của phần mềm trở nên nhất quán hơn.
3. Dùng cỡ chữ 20pt cho bài viết dài
Với bài viết dài dằng dặc toàn chữ là chữ, việc dùng cỡ chữ 20pt sẽ giúp người dùng có trải nghiệm đọc tốt hơn. Tất nhiên, việc chọn cỡ chữ sẽ còn phụ thuộc vào việc bạn đang dùng typeface nào.
Cố gắng chỉ dùng căn giữa cho tiêu đề hoặc một đoạn văn bản ngắn. Trong hầu hết các trường hợp, việc căn lề trái sẽ cho trải nghiệm đọc tốt hơn.
5. Khoảng trắng
Việc dùng khoảng trắng trong thiết kế có lẽ đã không còn là một lời khuyên xa lạ. Đây có lẽ là cách nhanh nhất và đơn giản nhất để cải thiện UI của bạn.
6. Làm nhạt văn bản ở font chữ đậm
Nếu bạn có một bài viết dài và các chữ cái trông có vẻ hơi đậm (font weight lớn) thì việc đọc nó sẽ đôi chút khó chịu, thậm chí gây mỏi mắt. Điều này có thể được cải thiện bằng cách làm nhạt bớt màu của văn bản. Chẳng hạn, thay vì dùng màu đen, hãy chuyển sang dùng các sắc thái khác nhau của màu xám (dark grey), như #4F4F4F.
7. Cỡ chữ càng nhỏ, line height càng lớn
Cũng vì để tăng tính dễ đọc, mỗi khi bạn giảm cỡ chữ (font size) của văn bản, bạn nên tăng line height lên tương xứng, và ngược lại.
9. Các sắc thái khác nhau của cùng một màu
Tương tự như mục 2 đã nói về việc dùng một typeface, đôi khi, bạn không nhất thiết phải dùng nhiều màu. Nếu có thể, hãy giảm thiểu số màu trong bảng màu của bạn. Bằng cách nào? Hãy chọn lấy một màu cơ bản (base color) rồi chọn thêm các sắc thái khác nhau (tint và shade) cũng của màu đó. Đây có lẽ là một trong những cách dễ nhất để thiết kế trở nên nhất quán hơn.
10. Làm cho những đối tượng quan trọng trở nên nổi bật
Bạn hoàn toàn có thể làm điều này bằng cách kết hợp cỡ chữ (font size), độ dày (font weight) và màu sắc. Hãy so sánh hai hình dưới đây.
11. Đảm bảo “Call to Action” là đối tượng nổi bật nhất
Điều này quá dễ hiểu phải không? Ai cũng sẽ làm điều như một thói quen.
Chưa chắc đâu. Bạn hãy nhìn lại hai hình ở mục 10. Có khi nào, bắt tay vào làm, bạn sẽ để nút mua là một nút “mờ nhạt” không đáng chú ý như hình bên phải? Và bạn có nghĩ là thay vì chỉ có một icon giỏ hàng, nếu thêm từ “Mua ngay” thì sẽ kích thích người dùng nhấn vào không?
12. Báo lỗi rõ ràng
Người dùng quên nhập một trường bắt buộc trong form? Người dùng nhập sai định dạng của trường? Lúc ấy, bạn không nên chỉ nói một câu kiểu như “Đã có lỗi xảy ra”. Việc đơn thuần khoanh đỏ trường bị lỗi cũng là chưa đủ. Bạn hãy đưa ra một chỉ dẫn cụ thể hơn. Người dùng sẽ muốn biết họ sai gì và làm sao để sửa nó.
13. Làm nổi bật những tính năng hay dùng
Nếu bạn có một menu, trong đó hành động “Tải ảnh lên” chẳng hạn, được dùng nhiều nhất, bạn nên làm cho hành động ấy nổi bật hơn các hành động còn lại.
Mong những tip vừa rồi sẽ giúp ích cho bạn. Hãy tiếp tục theo dõi các bài viết khác của mình nhé!
Lập trình đang là ngành nghề hot hiện nay. Đua theo xu hướng này, là các trung tâm đào tạo lập trình ngày càng nhiều, các trường Đại Học cũng thi nhau bổ sung thêm các ngành, khoa liên quan tới CNTT. Việc có nhiều đơn vị đào tạo như vậy là rất tốt, các bạn muốn theo ngành IT sẽ có nhiều cơ hội học tập hơn. Nhưng các bạn cũng đừng quên rằng “Học lập trình thì tự học là chủ yếu”, đừng ỷ lại vào các trung tâm đào tạo, hay trường học, đừng gán cho họ cái trách nhiệm “phải biến bạn thành lập trình viên”.
Cũng như mình vừa viết “Học lập trình thì tự học là chủ yếu”, và dưới đây là 4 lý do để chứng minh điều này.
Lưu ý: Tự học không có nghĩa là không được học từ người khác, tự học nghĩa bạn phải chủ động tìm hiểu kiến thức, không đợi người khác phải dục, phải bắt ép, hay phải hướng dẫn một cách quá chi tiết như “cầm tay chỉ việc”.
Kiến thức lập trình rất rộng, bạn không thể đợi người khác dạy thì mới học
Tuy lập trình chỉ là một góc của Công nghệ thông tin, nhưng nó cũng đủ rộng để bạn “học mãi mà không hết”. Thực tế, cái “góc nhỏ” lập trình rộng tới nỗi không ai có thể biết hết được. Và mặc dù không ai có nhu cầu học hết mọi thứ, nhưng người ta vẫn luôn có xu hướng học thêm những kiến thức mới.
Mình đã theo đuổi nghề lập trình khá lâu rồi, mình chưa bao giờ đặt mục tiêu là phải học tất tần tật kiến thức lập trình. Nhưng mình vẫn phải nạp thêm kiến thức mới vì nó thật sự có ích cho công việc.
Điều đó cho thấy rằng dù không ai đặt mục tiêu là học hết, chỉ cần học một phần nhỏ để đáp ứng được công việc, nhưng như vậy thôi cũng đủ để người ta “học mãi mà không hết”.
Như vậy, nếu bạn cứ đợi ai đó dạy thì mới học, thì sớm muộn những kiến thức bạn có cũng sẽ bị lỗi thời, hoặc là nó quá cơ bản, không giúp bạn đạt được hiệu quả cao trong công việc.
Chi phí để học rất cao, bạn sẽ không đủ tiền và thời gian
Giả sử quan điểm của mình ở mục I không đúng với bạn, tức là bạn đều đặn tham gia một khóa học nào đó để tiếp thu kiến thức mới – đồng nghĩa là luôn có người dạy bạn. Thì mình cho rằng mỗi tháng bạn sẽ phải tham một khóa học khác nhau, với học phí giao động từ 1 – 10 triệu, và tiêu tốn khoảng 16 – 24 giờ học. Các kiến thức càng mới, càng khó thì học phí càng cao và thời gian học cũng càng nhiều. Liệu bạn có đủ tài chính và thời gian để “học lập trình” theo cách này.
Khi đi làm, biết các kiến thức căn bản có thể giúp bạn hoàn thành được 80% công việc, nhưng đó chỉ là các công việc đơn giản kiểu “ai cũng làm được nếu họ chịu làm”. 20% công việc còn lại, dù ít, nhưng nó lại là các công việc quan trọng, có độ khó nhất định, có tính quyết định đến toàn bộ tính năng của sản phẩm. Nhưng thật sự rất khó để tìm được nơi dạy bạn giải quyết các vấn đề khó đó.
Các kiến thức lập trình được dạy ở các trung tâm đào tạo, hoặc các trường Đại học đa phần đều là những kiến thức căn bản, hoặc dạng lý thuyết hàn lâm. Những kiến thức chuyên sâu, kiến thức khó thì lại chẳng có ai dạy, hoặc có người dạy nhưng không hiểu:
Người dạy giỏi thì thường không giỏi công nghệ: Mỗi người chỉ có 24h, nếu họ tập trung vào kỹ năng dạy, họ sẽ không có thời gian để tìm hiểu công nghệ chuyên sâu.
Người biết thì không truyền đạt được: Cũng như ý trên, nếu họ tập trung vào kỹ năng công nghệ, họ sẽ không có thời gian để rèn luyện khả năng trình bày, hoặc đơn giản là họ không có thời gian để truyền đạt cho người khác.
Ít người quan tâm tới các vấn đề khó: Mình cũng chỉ ra rồi, chỉ 20% công việc là khó, nên cũng ít người quan tâm. Việc khó đã chẳng ai dạy, đã thế lại còn chẳng ai học, cứ vậy nó tạo nên cái vòng luẩn quẩn.
Vậy nếu bạn muốn học các kiến thức khó, các kiến thức chuyên sâu, cách tốt nhất vẫn là tự học.
Mỗi lập trình viên luôn có “n” vấn đề
Mỗi lập trình viên luôn có các vấn đề của riêng họ, trong khi các trung tâm đào tạo hay trường học mở ra là để dạy cho nhiều người, nên sẽ có nhiều kiến thức buộc bạn phải tự học thì mới biết được, như cách dùng một thư viện (thư viện lập trình) nào đó, hoặc cách dùng một framework mới mẻ, hoặc đơn giản là chữa một lỗi khó hiểu.
Tất cả các vấn đề kể trên đều đòi hỏi đến khả năng tự học, tự tìm hiểu, bởi không có ai giống ai, vấn đề của bạn người khác chưa chắc đã quan tâm, nên khả năng cũng sẽ không có ai giúp bạn.
Bài viết này không có ý nói rằng “học lập trình thì bắt buộc phải tự học”, hay cũng không có ý nói rằng học lập trình tại các trung tâm hay trường Đại học là không hiệu quả. Cách tốt nhất vẫn là học theo cả hai cách này, dù không có một tỷ lệ nào giữa việc được người khác dạy và tự học, nhưng qua trải nghiệm của bản thân, mình có thể khẳng định Học lập trình thì tự học là chủ yếu.
Lập trình viên cần học những gì? Làm thế nào để trở thành một lập trình viên giỏi? Đây là câu hỏi mà những người bắt đầu học lập trình rất quan tâm. Tuy nhiên, đưa ra câu trả lời cho những câu hỏi này lại không hề đơn giản. Lập trình là một lĩnh vực rộng lớn, luôn thay đổi và phát triển liên tục, điều này khiến cho nhiều người mới bắt đầu học lập trình rất mông lung khi bước chân vào thế giới của công nghệ thông tin. Nếu bạn đang gặp phải vấn đề này và chưa biết bắt đầu từ đâu, thì bài viết này sẽ giúp cho bạn.
Lập trình viên cần học những gì?
Kiến thức về lập trình, chuyên môn kỹ thuật
Công nghệ thông tin là một lĩnh vực rất đa dạng và phức tạp, tuy nhiên, để trở thành [...]
Tự học là một yếu tố quan trọng giúp các lập trình viên phát triển kỹ năng và nâng cao hiệu suất làm việc. Tuy nhiên, tự học như thế nào cho đúng, cách học nào là hiệu quả nhất đối với bạn? Trong bài viết này, chúng ta sẽ khám phá các phương pháp tự học lập trình tốt nhất dành cho người mới, giúp bạn tận dụng tối đa tiềm năng của mình và trở thành một lập trình viên tài giỏi.
Đọc sách dạy lập trình
Đọc sách là một phương pháp tự học quan trọng cho lập trình viên. Nó mang lại nhiều lợi ích, bao gồm tiếp cận kiến thức chuyên sâu về lập trình, mở rộng phạm vi kiến thức và cập nhật với công nghệ mới.
Để tận dụng tối đa việc đọc sách, bạn có thể chọn những tựa sách [...]
Nhiều ứng dụng tích hợp công nghệ hỗ trợ rất nhiều trong công tác quản trị nhân sự. TopDev đã tổng hợp 5+ các công cụ hỗ trợ tốt cho việc cải thiện hiệu suất công việc và quản trị nhân sự. Cùng check xem đó là những công cụ nào nhé!
Với những tính năng thông minh, tương thích trên nhiều nền tảng khác nhau, skype cho phép người dùng tạo ra những cuộc giao tiếp cá nhân hoặc nhóm; kết kết nối qua video hoặc qua tin nhắn.
Ngoài ra, skype còn những tính năng khác trong công tác hỗ trợ nhân sự phát triển: gửi tập tin và chia sẻ màn hình. Thậm chí bạn có thể gọi được cả những số điện thoại không thuộc skype.
Trello được biết đến là một ứng dụng quản lý dự án. Đồng thời, nó còn hỗ trợ thực hiện các công việc, giúp thiết lập và phân bổ các task theo hệ thống thẻ.Giao diện trực quan là một điểm nhấn đặc biệt của Trello. Khi có thể khiến người dùng nắm bắt một cách tổng quát nhanh chóng quá trình thực hiện dự án.
Nếu muốn xem và đánh giá tình hình, bạn chỉ cần click vào để mở thẻ đó. Không những thế, Trello còn có tính năng thông báo đến các thành viên nhóm bằng cách gửi email cho họ. Điều này giải quyết được những thay đổi phát sinh trong suốt quá trình.
Evernote giúp bạn tối ưu hóa các danh mục ghi chú những mục quan trọng. Ngoài ra, nó còn giúp lưu trữ hình ảnh theo hệ thống quản lý thông minh.
Điểm nổi trội của Evernote nằm ở chỗ nó là công cụ tìm kiếm mạnh mẽ. Những tìm kiếm của bạn sẽ được ghi nhận và lưu lại. Do vậy, không bao giờ bạn bị mất đi các ghi chú quan trọng. Trello còn chia sẻ các ghi chú cho các thành viên hoặc đồng nghiệp cùng một nhóm. Đồng thời, cho phép bạn cài đặt nhắc nhở và thông báo, tránh tình trạng trễ deadline.
Xuất hiện không lâu nhưng tầm ảnh hưởng của dropbox không thể đùa được. Sứ mệnh của công cụ này chính là quản trị hiệu suất. Hơn thế nữa, dropbox còn giúp bạn lưu trữ các tập tin quan trọng. Nguồn dữ liệu sẽ được đảm bảo nếu bạn sử dụng dropbox.
Dropbox là dịch vụ lưu trữ đám mây. Do đó, bạn có thể truy cập các tập tin của bạn từ các thiết bị bất kỳ có kết nối internet. Dropbox còn giải quyết được vấn đề về không gian khi các thành viên nhóm làm việc từ xa. Hơn nữa, hiện tại ứng dụng này cũng đề cao tính hiệu quả tương tác cộng đồng do tính răng cho phép bình luận.
IFTTT là một ứng dụng giúp cải thiện hiệu suất khá hiệu quả. Nó sử dụng các trường hợp “If (nếu điều này xảy ra); Then (thì sau đó)” để tự động hóa các quy trình chung và tổ chức hợp lý hóa luồng công việc của bạn.
Bạn có thể bắt đầu bằng cách xác định điều kiện “If” , được gọi là điều kiện kích hoạt (trigger). Tiếp theo, bạn xác định “Then”, là hành động mà bạn muốn thực hiện. Lưu ý là điều kiện kích hoạt của quá trình đó phải giống nhau. Sự kết hợp tác vụ có điều kiện kích hoạt này được gọi là “Recipes (Công thức)”
Vì IFTTT tương thích với rất nhiều các ứng dụng phổ biến, bạn có thể cài đặt các Recipes để thực hiện rất nhiều tác vụ thường lệ một cách tự động.
Hootsuite được sử dụng để quản lý các công việc truyền thông xã hội một cách hiệu quả. Nó hỗ trợ việc xây dựng thời gian biểu cho các bài post truyền thông trên các nền tảng xã hội. Hơn nữa, Hootsuite còn đưa ra những phân tích truyền thông cho người dùng nắm bắt thông tin.
Bên cạnh đó, Hootsuite còn theo dõi các luồng truyền thông xã hội khác nhau tại cùng một thời điểm. Điều này thật tuyệt vời nếu bạn muốn xem sự tham gia của phương tiện truyền thông xã hội trong tích tắc mà không tốn quá nhiều thời gian.
Lời kết
Mỗi ứng dụng đều có những ảnh hưởng tích cực đến việc cải thiện hiệu suất trong công tác quản trị nhân sự. Và tất nhiên, tùy vào từng loại ứng dụng và chúng ta quyết định sử dụng nó trên các thiết bị khác nhau. Mấu chốt để tiết kiệm thời gian đó là sử dụng các ứng dụng cải thiện hiệu suất trong luồng công việc thường ngày của bạn thường xuyên. TopDev hy vọng rằng bạn sẽ tìm ra đâu là ứng dụng yêu thích của bạn và xác định cách sử dụng chúng một cách hiệu quả nhất?
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
Đâu là cách thức tốt nhất để học Python? Đây có lẽ là một trong những câu hỏi phổ biến nhất mà các “newbie” chân ướt chân ráo bước vào thế giới của Python thắc mắc và tìm hiểu.
Chúng tôi tin rằng bước đầu tiên trong việc học bất kỳ ngôn ngữ lập trình nào là đảm bảo rằng bạn hiểu cách học vì đây được cho là kỹ năng quan trọng nhất liên quan đến lập trình máy tính.
Tại sao biết cách học quan trọng như vậy? Câu trả lời rất đơn giản: khi ngôn ngữ ngày càng phát triển, các thư viện của ngôn ngữ và các công cụ cũng sẽ được nâng cấp. Biết cách học sẽ rất cần thiết để theo kịp những thay đổi này và trở thành một lập trình viên thành công.
Có thể khẳng định rằng Python là ngôn ngữ rất tuyệt vời. Nếu bạn vừa quyết định sẽ “dấn thân” vào cuộc hành trình với đích đến là trở thành một lập trình viên Python “đẳng cấp” thì đây sẽ là một số chiến lược học tập. Hãy cùng Quantrimang tìm hiểu xem nhé!
Hãy làm cho Python trở nên gắn bó với bạn
Tip #1: Viết code hằng ngày
Sự kiên trì là rất quan trọng khi bạn đang học một ngôn ngữ mới. Tip đầu tiên dành cho bạn là nên kiên trì tập viết code mỗi ngày. Khi bạn lặp đi lặp lại một hành động nào đó, bộ não sẽ dần ghi nhớ. Theo thời gian, bạn sẽ thực hiện ngày càng tốt hơn, nhanh hơn, giỏi hơn. Điều này gọi là “Ký ức cơ bắp”. Việc kiên trì viết code hằng ngày sẽ giúp bạn phát triển “cơ bắp” này đấy! Có thể lúc đầu sẽ làm bạn hơi chán, vì vậy hãy thử bắt đầu với khoảng 25 phút mỗi ngày và tăng dần thời gian.
Khi đã có những tiến bộ trên hành trình trở thành một lập trình viên, bạn sẽ tự hỏi liệu mình có cần viết code, viết note lại những gì cần lưu ý không? Câu trả lời là có, chắc chắn rồi! Trong thực tế, các nghiên cứu cho thấy rằng viết note bằng tay là có lợi nhất cho việc ghi nhớ và duy trì lâu dài công việc. Điều này sẽ đặc biệt có lợi cho những người làm việc hướng tới mục tiêu trở thành các nhà phát triển/lập trình viên full-time, vì nhiều cuộc phỏng vấn sẽ liên quan đến việc viết code trên bảng trắng.
Khi bạn bắt đầu làm việc trên các dự án và chương trình nhỏ, viết bằng tay có thể giúp bạn lập kế hoạch cho code trước khi bạn chuyển sang viết trên máy tính. Bạn có thể tiết kiệm rất nhiều thời gian nếu viết ra những hàm và lớp nào cần, cũng như cách chúng sẽ tương tác.
Tip #3: Code trực tiếp trên cửa sổ dòng lệnh của Python
Cho dù bạn đang bắt đầu tìm hiểu về cấu trúc dữ liệu cơ bản của Python hay bạn đã thông thạo để gỡ lỗi một ứng dụng thì cửa sổ dòng lệnh của Python – Python shell luôn là một trong những công cụ học tập tốt nhất của bạn.
Để sử dụng Python shell (đôi khi còn được gọi là Python REPL) thì trước tiên hãy đảm bảo rằng Python đã được cài đặt trên máy tính của bạn. Để kích hoạt cửa sổ dòng lệnh Python shell, chỉ cần mở terminal và chạy python hoặc python3 tùy thuộc vào cài đặt.
Tip #4: Có thời gian nghỉ giải lao hợp lý
Nghỉ giải lao là rất quan trọng để có một buổi học và làm việc hiệu quả, đặc biệt là khi bạn đang tiếp nhận nhiều thông tin mới. Khi phải đối mặt với một quy trình, bạn nên chia ra thành các nhiệm vụ nhỏ để làm trong một khoảng thời gian ngắn, xen giữa các khoảng làm việc ngắn sẽ là những khoảng break-time. Phương pháp này sẽ huấn luyện bộ não của bạn tập trung làm việc trong một thời gian ngắn, giúp bạn rơi vào tình thế luôn có những hạn chót để hoàn thành công việc và cũng thường xuyên được nạp lại năng lượng.
Những khoảng break-time này đặc biệt quan trọng khi bạn đang gỡ lỗi. Nếu bạn gặp phải một lỗi và không thể hiểu được nó nằm ở đâu, hãy nghỉ ngơi một lúc xem nhé. Bước ra khỏi máy tính của bạn, đi dạo hoặc trò chuyện với ai đó.
Trong lập trình, code của bạn luôn phải tuân theo chính xác các quy tắc và logic của ngôn ngữ, do đó có thể chỉ thiếu một dấu ngoặc kép thôi cũng có thể phá vỡ mọi thứ. Hãy luôn giữ đôi mắt mình thật sáng và tinh tường.
Tip #5: Trở thành Bug Bounty Hunter
Nói về vấn đề “nai lưng” sửa lỗi thì đây là việc không thể tránh khỏi khi bạn đã bắt đầu viết các chương trình phức tạp hơn. Ai cũng sẽ gặp phải tình trạng này thôi, đừng quá lo lắng nhé! Quan trọng, đừng để những lỗi này “hạ gục” và làm bạn thất vọng. Thay vào đó, khi tìm và sửa thành công “cái thứ khó ưa” ấy, bạn hãy tận hưởng khoảnh khắc và nghĩ về bản thân như một Bug Bounty Hunter – thợ săn tiền thưởng lỗi.
Khi gỡ lỗi, điều quan trọng là phải có một phương pháp phương pháp để giúp bạn tìm ra nơi đang bị lỗi phá hỏng. Xem qua code của bạn theo thứ tự thực thi và đảm bảo mỗi phần đều hoạt động là một cách khá ổn đấy.
Khi bạn có tìm được khu vực xuất hiện lỗi, chèn dòng mã sau vào tập lệnh của bạn và chạy nó:
import pdb; pdb.set_trace()
Đây là trình gỡ lỗi Python và sẽ đưa bạn vào chế độ interactive. Trình gỡ lỗi cũng có thể được chạy từ dòng lệnh:
Khi mọi thứ bắt đầu gắn bó, hãy tiến hành việc học của bạn thông qua sự hợp tác. Dưới đây là một số chiến lược để giúp bạn tận dụng tối đa công việc khi làm với người khác.
Tip #6: Học chung với những người cũng đang tìm tòi như bạn
Mặc dù việc code nghe có vẻ như là một hoạt động đơn độc, nhưng nó thực sự hoạt động tốt nhất khi có nhiều người làm việc cùng nhau. Đây là một tip rất quan trọng, bạn nên học viết mã Python cùng với những người khác có chung mục đích như mình. Điều này sẽ cho phép bạn chia sẻ và học tập thêm các mẹo hoặc thủ thuật hay ho.
Đừng lo lắng nếu bạn không biết nên học cùng ai. Có rất nhiều cách để gặp gỡ những người đam mê học Python! Ở Việt Nam thì chưa nhiều các sự kiện kết nối người học Python nhưng các diễn đàn thì vẫn có kha khá anh tài sẵn sàng giúp đỡ bạn. Nếu bạn đọc hiểu tốt Tiếng Anh thì hãy tham gia PythonistaCafe – một cộng đồng học tập ngang hàng cho những người đam mê Python như bạn!
Tip #7: Dạy Python cho người khác
Người ta nói rằng để học cái gì một cách tốt nhất, đầu tiên bạn nên tìm hiểu sâu về nó và dạy lại kiến thức cho người khác. Có nhiều cách để làm điều này: trình bày hoặc giảng lại với những người yêu thích và có nhu cầu học Python giống như bạn, viết bài đăng trên blog giải thích các khái niệm mới học, ghi lại video giải thích điều gì đó bạn đã tìm hiểu. Mỗi phương pháp này sẽ giúp củng cố sự kiến thức cũng như có thể phơi bày lỗ hổng trong sự hiểu biết giúp bạn nhanh chóng bổ sung kiến thức.
Tip #8: Áp dụng phương pháp Lập trình đôi – Pair Programming
Pair Programming là một phương pháp lập trình gồm 2 lập trình viên, chia sẻ với nhau một không gian làm việc chung (chuột, bàn phím, màn hình, nội dung công việc…) Người sử dụng bàn phím được gọi là “driver”, người còn lại cũng làm việc lập trình tuy nhiên quan tâm đến việc điều hướng hơn, người này được gọi là “navigator”. Vai trò của 2 người này sẽ được hoán đổi liên tục cho nhau sau một khoảng thời gian nhất định (thường khoảng 30 phút ~ 1 giờ). Cả 2 người phải trao đổi với nhau ở mức độ cao nhất, để hướng tới việc giải quyết công việc một cách hiệu quả, chất lượng cao, hạn chế sai sót cá nhân.
Pair Programming có nhiều lợi ích: nó mang đến cho bạn cơ hội không chỉ có ai đó xem lại code giúp bạn mà còn có thể lắng nghe, tham khảo ý kiến của người khác về cùng một vấn đề. Được tiếp xúc với nhiều ý tưởng và cách suy nghĩ sẽ giúp bạn giải quyết vấn đề tốt hơn khi quay lại tự mình viết code.
Tip #9: Đặt những câu hỏi hợp lý và cần thiết nếu cần sự giúp đỡ của người khác
Mọi người luôn nói rằng khi học hỏi thì không có gì gọi là một câu hỏi tồi, nhưng đối với lập trình, bạn rất có thể sẽ đặt một câu hỏi không tốt gây sự không thoải mái cho người giải đáp nếu không chuẩn bị kỹ càng. Khi bạn đang mong muốn có sự giúp đỡ từ một người chưa nắm rõ vấn đề mình đang gặp phải, tốt nhất bạn nên đặt câu hỏi rõ ràng để hiệu suất và chất lượng cao hơn.
Đưa ra tổng quan về những gì bạn đang cố gắng làm, mô tả rõ ràng vấn đề gặp phải.
Phác thảo những điều bạn đã cố gắng khắc phục.
Đưa ra dự đoán của bạn về vấn đề. Điều này để người đang giúp bạn biết bạn đang nghĩ gì và hiểu rằng bạn đã tự mình thực hiện một số suy nghĩ.
Demo những gì đang xảy ra. Bao gồm code, thông báo lỗi và giải thích về các bước bạn đã thực hiện dẫn đến lỗi. Bằng cách này, người giúp đỡ không phải cố gắng tạo lại vấn đề.
Câu hỏi phù hợp và vừa phải có thể tiết kiệm rất nhiều thời gian. Bỏ qua bất kỳ bước nào trong số này có thể dẫn đến cuộc trò chuyện qua lại dễ gây ra xung đột. Là một người mới, bạn nên chắc chắn rằng mình sẽ hỏi những câu hỏi hợp lý để truyền đạt suy nghĩ của mình, và để những người giúp đỡ bạn sẽ vui lòng tiếp tục giúp đỡ bạn ở những lần sau.
Những gì bạn xây dựng không quan trọng bằng cách bạn xây dựng nó. Hành trình tự mình xây dựng sẽ chỉ dạy cho bạn nhiều nhất. Bạn cũng có thể học được rất nhiều từ việc đọc các bài báo, sách, blog… Hầu hết việc học của bạn sẽ đến từ việc sử dụng Python để xây dựng một cái gì đó. Những vấn đề bạn phải giải quyết sẽ dạy cho bạn rất nhiều.
Tip #11: Đóng góp cho các dự án mã nguồn mở
Trong mô hình nguồn mở, mã nguồn phần mềm là có sẵn, công khai và bất kỳ ai cũng có thể cộng tác. Có nhiều thư viện Python là các dự án mã nguồn mở và bạn được đóng góp vào. Ngoài ra, có rất nhiều công ty công khai các dự án mã nguồn mở. Điều này có nghĩa là bạn có thể làm việc với code được viết và sản xuất bởi các kỹ sư làm việc trong các công ty này.
Đóng góp cho một dự án Python mã nguồn mở là một cách tuyệt vời để tạo ra những trải nghiệm học tập cực kỳ giá trị. Giả sử bạn gửi yêu cầu pull request, người nào quan tâm có thể review lại các thay đổi, hoặc thảo luận các sửa đổi tiềm năng, và có thể theo đó đẩy tiếp các commit của họ nếu cần thiết. Điều này sẽ cho phép bạn tìm hiểu các thực tiễn tốt nhất để lập trình Python, cũng như thực hành giao tiếp với các nhà phát triển khác.
Tiến về phía trước và không ngừng học hỏi. Bây giờ bạn có những chiến lược để học Python rồi đấy, bạn đã sẵn sàng để bắt đầu hành trình Python của mình chưa?
Chuyện gì xảy ra nếu chúng ta dùng var() với một biến undefined
Trước hết phải nói CSS và HTML là ngôn ngữ không quá strictly, một vài lỗi nhỏ không làm làm chết nguyên trang, nếu dùng var() với một biến không tồn tại, không gây ra ảnh hưởng parsing.
Sẽ có nhiều lý do cho việc xuất biến undefined trong var, có thể là
Gõ nhầm tên biến
Tưởng là có nhưng chưa define biến này
Biến đó ko tồn tại trên trang đang xem
ol li{--foo:red;}ul li{color:var(--foo);}
Bởi, lời khuyên là luôn đặt biết ở node trên cùng như :root hay html, như vậy biến có thể truy xuất ở bất cứ đâu trong DOM.
Mình mới bước chân vào con đường lập trình này chưa được bao lâu, nhưng chỉ xét riêng khía cạnh phát triển web, trong vòng 5 năm (2015 – 2020) qua đã có nhiều sự thay đổi đáng kể:
Javascript được sử dụng nhiều hơn: do sự nâng cấp của các trình duyệt, cũng như sự ra đời của NodeJS, khiến cho javascript có thể được sử dụng cả ở backend lẫn frontend.
Các trang web chú trọng nhiều cho giao diện mobile: Bây giờ làm gì còn ai không sử dụng smartphone cơ chứ, nên một trang web cũng cần phải được tối ưu cả cho mobile nữa.
Frontend phát triển mạnh: Sự ra đời của hàng loạt các frontend framework như vue, angular, reactjs đã khiến cho các frontend developer thời nay không chỉ là “biết cắt giao diện từ photoshop” nữa, họ cũng phải quan tâm tới giải thuật, tới cấu trúc dữ liệu không kém cạnh gì các backend developer.
Và còn nhiều sự thay đổi khác nữa…
Chứng kiến sự thay đổi trên, mới thấy rằng, quả đúng là “không có gì là mãi mãi”, mọi thứ xung quanh ta luôn không ngừng thay đổi. Và nếu không bắt kịp với sự thay đổi đó, chúng ta sẽ sớm thành những “người tối cổ hiện đại”.
“Không có gì là mãi mãi” cũng nhắc nhở mình phải luôn biết cách làm mới kiến thức, làm mới bản thân, đừng ngủ quên khi thấy bản thân đã làm tốt ở thời điểm hiện tại. Bởi bạn làm tốt hôm nay, đâu có nghĩa là bạn sẽ làm tốt ngày mai.
II. Sẵn sàng thay đổi để phù hợp
Cũng vì “không có gì là mãi mãi”, nên việc thay đổi để phù hợp là điều “tất lẽ dĩ ngẫu” nếu bạn không muốn bị bỏ lại phía sau.
Lúc mới học lập trình, thật sự mình rất ngại học cái mới, dù hiểu rằng cái mình biết đã cũ và không còn được trọng dụng ở giai đoạn hiện tại, nhưng vì một lý do nào đó mà mình vẫn không chịu học. Có thể là do mình lười, hoặc công nghệ mình biết mới chỉ đang ngấp ngoải mà chưa thật sự chết, làm mình không có động lực để học cái mới hơn.
Một câu chuyện nhỏ, xàm xí nhưng có thật với mình.
Ngày trước, codeigniter là một php framework được nhiều người sử dụng bởi nó đáp ứng được hầu hết các tác vụ web lúc bấy giờ. Đương nhiên, mình không thể bỏ qua một hot trend công nghệ như thế được, mình đã tìm hiểu về codeigniter và thích nó ngay lập tức. Nhưng chỉ sau 2 năm, đúng vào giai đoạn các website có sự phát triển vượt bậc, codeigniter có vẻ không còn phù hợp với các dự án web phức tạp, và một framework khác nổi lên có tên là Laravel – được mọi người ca ngợi là “ngon, đẹp, mạnh mẽ”, nhưng mình lại chẳng thèm quan tâm.
Việc mình không để ý đến Laravel, không phải vì codeigniter vẫn đủ mạnh mẽ. Thực chất, mình đã nhận ra một số điểm hạn chế của nó, nhưng vì ngại học cái mới nên mình vẫn tiếp tục sử dụng trong một thời gian dài (chừng 1 năm tiếp theo).
Rồi một ngày cuối tuần, vì muốn giết thời gian nên mình thử tìm hiểu về Laravel xem sao. Thì ôi, nó quá ngon, nó giải quyết về các vấn đề mà mình đang gặp ở thằng codeigniter. Lúc đó mới thấy bản thân sao ngu quá, sao không tìm hiểu sớm hơn thì đã tiết kiệm bao nhiêu thời gian.
Và đó là bài học đầu tiên cho mình thấy cái giá của việc ngại thay đổi.
Câu chuyện trên vốn không có gì to tát, chỉ là việc học một framework mới, thế nhưng khi nghĩ rộng ra, mới thấy rằng việc ngại thay đổi để trở nên tích cực hơn sẽ chỉ ngăn cản việc bạn phát triển mà thôi.
Cái này thì mình học được qua việc fix bug (sửa lỗi phần mềm).
Để có thể fix được bug, trước tiên mình cần phải tìm được nó, hiểu nó và tái hiện được nó. Việc tìm bug có thể khó dễ tùy trường hợp, nhưng đặc điểm chung của công việc này là “dò từng bước một”, dò đến bao giờ tìm thấy nơi phát sinh bug thì thôi.
Và sau nhiều lần tìm bug, nhất là các trường hợp bug liên hoàn bug, từ bug A dẫn tới bug B, từ bug B dẫn tới bug C,… Khiến mình nhận ra rằng thường có một bug quan trọng gây ra các bug còn lại, mà khi fix được bug đó, các bug khác cũng tự động biến mất. Các bug như vậy được mình coi là “điểm mấu chốt” của vấn đề.
Thực tế, “điểm mấu chốt” không chỉ xuất hiện dưới dạng bug của phần mềm, mà “điểm mấu chốt” tồn tại trong tất cả các sự vật, sự việc, sự kiện trong cuộc sống.
Hôm nay tôi đi làm muộn.
– Vậy tại sao tôi lại đi muộn? Vì tắc đường.
– Vậy tại sao lại tắc đường? Là vì tôi đi làm vào giờ cao điểm?
– Tại sao tôi lại đi làm vào giờ cao điểm, sao không đi sớm hơn? Vì tối qua tôi ngủ muộn, nên dậy muộn.
– Tại sao tôi tối qua tôi ngủ muộn? Vì tối qua tôi cố xem nốt bộ phim yêu thích.
Vậy điểm mấu chốt của việc đi làm muộn là do tối qua cố xem nốt bộ phim. Vì nếu không cố xem nốt phim, thì sẽ không xảy ra các sự kiện sau đó, dẫn tới việc bị đi làm muộn.
Có một phương pháp tên là 5 why (5 câu hỏi tại sao) để giúp bạn tìm ra điểm mấu chốt dễ dàng hơn.
Nếu bạn không vừa lòng với bất kỳ điều gì trong cuộc sống, thì hãy thử suy nghĩ và tìm ra điểm mấu chốt. Sau đó giải quyết điểm mấu chốt đó, rồi bạn sẽ thấy cuộc sống dễ dàng hơn nhiều.
IV. Sống có mục tiêu và kế hoạch
Làm bất kỳ công việc gì cũng cần có kế hoạch, làm phần mềm cũng vậy. Trước khi bắt đầu triển khai một tính năng mới, thường có kế hoạch và mục tiêu rất rõ ràng:
Mục đích của tính năng sắp tới là gì?
Để hoàn thiện tính năng này, cần trải qua các bước nào?
Thời gian để hoàn thiện là bao lâu?
Sẽ có bao nhiêu người tham gia?
Khi nào thì bắt đầu, khi nào thì kết thúc?
…
Việc phải lập kế hoạch trước khi làm việc cũng đã tạo cho mình thói quen lập kế hoạch cho cuộc sống:
5 năm nữa mình sẽ là ai?
Để đạt được mục tiêu 5 năm, thì mỗi năm, mỗi ngày mình phải làm gì?
Có bao nhiêu khó khăn, bao nhiêu điểm mấu chốt cần phải giải quyết để đạt được mục tiêu.
Làm sao để đo lường là mình vẫn đang thực hiện đúng?
…
Sống có mục tiêu và kế hoạch giúp mỗi ngày mình biết phải làm gì, biết việc gì nên làm, việc gì không nên làm, biết được bản thân mình đang nằm ở đâu, và mình phải cố gắng như thế nào vào ngày mai. Sau cùng, sống có mục tiêu và kế hoạch khiến mình cảm thấy cuộc đời này có ý nghĩa, bớt vô vị và tẻ nhạt.
V. Lời kết
Còn rất nhiều thứ khác nữa mà mình học được từ code, nhưng tạm thời kết thúc ở đây vì bài viết cũng hơn một nghìn từ rồi. Hẹn gặp lại các bạn ở phần tiếp theo. Mà nếu bạn cũng có những bài học hay rút ra được từ việc học lập trình, thì đừng ngại chia sẻ ở phần bình luận nhé.
Phỏng vấn được xem là “vòng loại trừ” nhằm đánh giá các ứng viên. Tất nhiên, nhà tuyển dụng sẽ luôn đặt ra những “cái bẫy” trong cuộc phỏng vấn. Ngoài hình thức phỏng vấn tình huống (Case Interview) thì phỏng vấn hành vi (Behavioral- Based Interview) được các nhà tuyển dụng cực kỳ quan tâm. Vậy đâu là những điều đáng lưu ý xoay quanh loại hình phỏng vấn này? Qua bài viết sau, TopDev sẽ giải đáp những thắc mắc đó.
Phỏng vấn hành vi là gì?
Phỏng vấn hành vi(Behavioral-Based Interview), hay còn được gọi là Phỏng vấn năng lực (Competency-Based Interview); là một phương pháp phỏng vấn dựa trên kỹ thuật đặt câu hỏi STAR (Situation, Task, Action, and Result).
Lấy cơ sở các khía cạnh phân tích về tình huống có thể xảy ra, nhà tuyển dụng khai thác và đánh giá ứng viên dựa trên quá trình tự tri nhận về các trải nghiệm cá nhân. Các phản ứng, hành vi, cảm xúc đều sẽ được ứng viên thể hiện một cách rõ nhất.
Một số mẫu câu hỏi phỏng vấn hành vi quen thuộc từ nhà tuyển dụng
– Bạn đã từng nói về các vi phạm của bản thân với cấp trên hay tổ chức của mình hay chưa? Bạn thực hiện điều đó như thế nào? Phản ứng của người trong cuộc ra sao?
– của bạn khá hoàn hảo, hãy nói về những điều bạn chưa trình bày trong CV.
– Bài học nào đối với bạn là có ý nghĩa nhất thông qua các trải nghiệm/
– Hãy mô tả lại quá trình bạn làm việc với một đồng nghiệp/khách hàng khó tính. Bạn đã có cách thức tổ chức thế nào để đảm bảo hiệu quả công việc?
– Những vai trò nào bạn đã từng đảm nhận.
– Bạn nghĩ khả năng teamwork và tư duy độc lập có thật sự cần thiết không? Hãy chia sẻ về nó
Phỏng vấn hành vi – Đặt câu hỏi thế nào là hiệu quả?
Tính hiệu quả được thể hiện qua việc khai thác toàn diện năng lực của một ứng viên. Nhà tuyển dụng cần đặt ra các câu hỏi nhằm tạo cơ hội cho ứng viên bộc lộ hết khả năng tương tác của mình.
Hãy đảm bảo rằng các ứng viên có đủ thời gian để suy nghĩ. Bởi lẽ, các các câu hỏi phỏng vấn hành vi là thách thức không hề dễ dàng. Đừng hối thúc ứng viên! Điều đó có thể tạo ra tác dụng ngược và khiến cho sự đánh giá bị chênh lệch.
3 nguyên tắc cần lưu ý
Một số ứng viên có thể còn bỡ ngỡ với việc phỏng vấn hành vi. Vì vậy, điều nhà tuyển dụng cần quan tâm là linh động đặt ra các cơ hội để ứng viên thỏa sức mô tả về bản thân mình. Đây làm một cách gián tiếp nhằm trao cơ hội đồng thời mong muốn ứng viên có một sự chuẩn bị tốt nhất.
Đối với ứng viên là sinh viên mới ra trường hoặc có ít kinh nghiệm, nhà tuyển dụng nên đề cao sự khuyến khích. Hãy cho họ cơ hội trình bày các trải nghiệm cá nhân dù nó là một môi trường chưa chuyên nghiệp.
Chú ý đến các ví dụ mà ứng viên lựa chọn. Cách họ khái quát, dẫn dắt sẽ làm bộc lộ khả năng nhận định, phân tích vấn đề một cách rõ ràng nhất.
Đánh giá câu trả lời của ứng viên – Bài toán của sự chủ động
Trả lời “đúng tiêu chuẩn”
Nếu ứng viên có cách trả lời quá đúng theo khuôn mẫu mà nhà tuyển dụng định hình trước, đó cho thấy ứng viên đang cố gắng làm hài lòng nhà tuyển dụng. Đủ nhưng chưa hấp dẫn? Dấu ấn cá nhân chưa nổi bật. Và thật đáng tiếc, nhà tuyển dụng không tìm kiếm sự nhàm chán. Tuy nhiên, một số trường hợp, các bạn vẫn có thể có được những vé vớt nếu thể hiện tốt hơn ở những khía cạnh khác.
Nhà tuyển dụng muốn thấy cái riêng của bạn.Đừng để các thông tin quá đại trà về bí kíp phỏng vấn kiểm soát sự thể hiện của bạn.
Trả lời quá chung chung
Thay vì đi khai thác các góc nhìn từ trải nghiệm đã có sẵn, ứng viên lại giả định các trải nghiệm. Đây là cách thức phản hồi phỏng vấn cho thấy ứng viên đang thiếu tự tin.
Điểm khác biệt lớn giữa câu hỏi phỏng vấn hành vi và câu hỏi tình huống là để xem cách thức ứng viên thực sự đã làm. Chứ không chỉ đơn thuần dừng lại ở việc tạo lập ra các trải nghiệm giả định quá lý tưởng.
Vì thế, dù trải nghiệm của bạn chưa chuyên nghiệp, bạn cũng cần phải tường thuật một cách chân thật. Nhà tuyển dụng luôn đánh giá đa chiều, chứ không chỉ ở một khía cạnh.
Không hề có câu trả lời
Đây là trường hợp mà nhà tuyển dụng dễ dàng đánh giá nhất. Ứng viên nếu không trả lời được bất cứ câu hỏi hành vi nào chứng tỏ ứng viên chưa đủ năng lực để đảm nhân công việc.
Trong trường hợp này, chúng ta sẽ vẫn xem xét khi ứng viên là người có thái độ tốt. Nhưng xét về năng lực, họ còn thiếu sót về mặt nền tảng. Nhà tuyển dụng cần tập trung vào kết quả. Và vì thế, sự linh động trong các quyết định là yếu tố cần thiết. Khó có thể chắc chắn được một ứng viên quá giỏi về năng lực sẽ làm việc tốt và ngược lại. Nhà tuyển dụng hãy dựa vào kết quả để thiết lập chỉ tiêu lựa chọn ứng viên phù hợp nhất.
Phỏng vấn hành vi có ý nghĩa rất quan trọng. Và bạn hoàn toàn có thể vận dung kỹ năng STAR để chinh phục cuộc phỏng vấn với nhà tuyển dụng. Lưu ý rằng, dù cho thách thức phỏng vấn có là gì đi chăng nữa, bạn vẫn phải cố gắng trả lời. Hãy bình tĩnh và sáng suốt trong từng lời chia sẻ, nhận định về các trải nghiệm quá khứ. TopDev hy vọng đã có thể cung cấp cho bạn nhiều thông tin thú vị xoay quanh phỏng vấn hành vi (Behavioral-Based Interview)
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
Socket là phương tiện hiệu quả để xây dựng các ứng dụng theo kiến trúc Client-Server. Trong bài viết này, tôi sẽ hướng dẫn các bạn các bước cơ bản trong việc xây dựng các ứng dụng Client-Server sử dụng Socket làm phương tiện giao tiếp theo cả hai chế độ: có nối kết (TCP – Transmission Control Protocol) và không nối kết ( UDP – User Datagram Protocol).
Các bạn nên xem bài viết giới thiệu Lập trình mạng trong Java trước khi tiếp tục xem nội dung tiếp theo của bài viết.
Mô hình Client-Server sử dụng Socket ở chế độ có nối kết (TCP)
Có thể phân thành 4 giai đoạn như sau:
Giai đoạn 1: Server tạo Socket, gán số hiệu cổng và lắng nghe yêu cầu nối kết. Server sẵn sàng phục vụ Client.socket(): Server yêu cầu tạo một socket để có thể sử dụng các dịch vụ của tầng vận chuyển.
bind(): Server yêu cầu gán số hiệu cổng (port) cho socket.
listen(): Server lắng nghe các yêu cầu nối kết từ các client trên cổng đã được gán.
Giai đoạn 2: Client tạo Socket, yêu cầu thiết lập một nối kết với Server.
socket(): Client yêu cầu tạo một socket để có thể sử dụng các dịch vụ của tầng vận chuyển, thông thường hệ thống tự động gán một số hiệu cổng còn rảnh cho socket của Client.
connect(): Client gởi yêu cầu nối kết đến server có địa chỉ IP và Port xác định.
accept(): Server chấp nhận nối kết của client, khi đó một kênh giao tiếp ảo được hình thành, Client và server có thể trao đổi thông tin với nhau thông qua kênh ảo này.
Giai đoạn 3: Trao đổi thông tin giữa Client và Server.
Sau khi chấp nhận yêu cầu nối kết, thông thường server thực hiện lệnh read() và nghẽn cho đến khi có thông điệp yêu cầu (Request Message) từ client gởi đến.
Server phân tích và thực thi yêu cầu. Kết quả sẽ được gởi về client bằng lệnh write().
Sau khi gởi yêu cầu bằng lệnh write(), client chờ nhận thông điệp kết quả (ReplyMessage) từ server bằng lệnh read().
Giai đoạn 4: Kết thúc phiên làm việc.
Các câu lệnh read(), write() có thể được thưc hiện nhiều lần (ký hiệu bằng hình ellipse).
Kênh ảo sẽ bị xóa khi Server hoặc Client đóng socket bằng lệnh close().
Mô hình Client-Server sử dụng Socket ở chế độ không nối kết (UDP)
Có thể phân thành 3 giai đoạn như sau:
Giai đoạn 1: Server tạo Socket – gán số hiệu cổng.
socket(): Server yêu cầu tạo một socket để có thể sử dụng các dịch vụ của tầng vận chuyển.
bind(): Server yêu cầu gán số hiệu cổng cho socket.
Giai đoạn 2: Client tạo Socket.
socket(): Client yêu cầu tạo một socket để có thể sử dụng các dịch vụ của tầng vận chuyển, thông thường hệ thống tự động gán một số hiệu cổng còn rảnh cho socket của Client.
Giai đoạn 3: Trao đổi thông tin giữa Client và Server.
Sau khi tạo Socket xong, Client và Server có thể trao đổi thông tin qua lại với nhau thông qua hai hàm send() và receive().
Đơn vị dữ liệu trao đổi giữa Client và Server là các Datagram Package (Gói tin thư tín).
Protocol của ứng dụng phải định nghĩa khuôn dạng và ý nghĩa của các Datagram Package. Mỗi Datagram Package có chứa thông tin về địa chỉ người gởi và người nhận (IP, Port).
Xây dựng ứng dụng Client-Server với Socket trong Java
Thông qua các lớp trong gói java.net, các chương trình Java có thể sử dụng TCP hoặc UDP để giao tiếp qua Internet.
Lớp IntetAddress: Lớp này quản lý địa chỉ Internet bao gồm địa chỉ IP và tên máy tính.
Lớp Socket: Hỗ trợ các phương thức liên quan đến Socket cho chương trình Client ở chế độ có nối kết.
Lớp ServerSocket: Hỗ trợ các phương thức liên quan đến Socket cho chương trình Server ở chế độ có nối kết.
Lớp DatagramSocket: Hỗ trợ các phương thức liên quan đến Socket ở chế độ không nối kết cho cả Client và Server.
Lớp DatagramPacket: Lớp cài đặt gói tin dạng thư tín người dùng (Datagram Packet) trong giao tiếp giữa Client và Server ở chế độ không nối kết.
Xây dựng chương trình Client – Server ở chế độ có nối kết (TCP)
Trong phần tiếp theo tôi sẽ hướng dẫn các bạn xây dựng chương trình Client – Server đơn giản. Client sẽ gởi lần lượt các số từ 0 đến 9 tới Server. Server lần lượt sẽ gởi các số nhận được về Client.
Các bước tổng quát xây dựng một chương trình Client – Server ở chế độ có nối kết như sau:
Mở một socket nối kết đến server đã biết địa chỉ IP (hay tên miền) và số hiệu cổng.
Lấy InputStream và OutputStream gán với Socket.
Tham khảo Protocol của dịch vụ để định dạng đúng dữ liệu trao đổi với Server.
Trao đổi dữ liệu với Server nhờ vào các InputStream và OutputStream.
Đóng Socket trước khi kết thúc chương trình.
Xây dựng chương trình Client ở chế độ có nối kết
Một số phương thức cần thiết để xây dựng các chương trình client sử dụng socket ở chế độ có nối kết:
public Socket(String HostName, int PortNumber) : Phương thức này dùng để nối kết đến một server có tên là HostName, cổng là PortNumber. Nếu nối kết thành công, một kênh ảo sẽ được hình thành giữa Client và Server.
HostName: Địa chỉ IP hoặc tên logic theo dạng tên miền.
PortNumber: có giả trị từ 0 ..65535
public InputStream getInputStream() : Phương thức này trả về InputStream nối với Socket. Chương trình Client dùng InputStream này để nhận dữ liệu từ Server gởi về.
public OutputStream getOutputStream() : Phương thức này trả về OutputStream nối với Socket. Chương trình Client dùng OutputStream này để gởi dữ liệu cho Server.
public close() : Phương thức này sẽ đóng Socket lại, giải phóng kênh ảo, xóa nối kết giữa Client và
Server.
Code của chương trình Client như sau:
package com.gpcoder.tcp;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class EchoChatClient {
public final static String SERVER_IP = "127.0.0.1";
public final static int SERVER_PORT = 7;
public static void main(String[] args) throws IOException, InterruptedException {
Socket socket = null;
try {
socket = new Socket(SERVER_IP, SERVER_PORT); // Connect to server
System.out.println("Connected: " + socket);
InputStream is = socket.getInputStream();
OutputStream os = socket.getOutputStream();
for (int i = '0'; i <= '9'; i++) {
os.write(i); // Send each number to the server
int ch = is.read(); // Waiting for results from server
System.out.print((char) ch + " "); // Display the results received from the server
Thread.sleep(200);
}
} catch (IOException ie) {
System.out.println("Can't connect to server");
} finally {
if (socket != null) {
socket.close();
}
}
}
}
Xây dựng chương trình Server ở chế độ có nối kết
Một số phương thức cần thiết để xây dụng các chương trình Server sử dụng socket ở chế độ có nối kết.:
public ServerSocket(int portNumber): phương thức này tạo một Socket với số hiệu cổng là portNumber mà sau đó Server sẽ lắng nghe trên cổng này.
public Socket accept(): Phương thức này lắng nghe yêu cầu nối kết của các Client. Đây là một phương thức hoạt động ở chế độ nghẽn. Nó sẽ bị nghẽn cho đến khi có một yêu cầu nối kết của client gởi đến. Khi có yêu cầu nối kết của Client gởi đến, nó sẽ chấp nhận yêu cầu nối kết, trả về
một Socket là một đầu của kênh giao tiếp ảo giữa Server và Client yêu cầu nối kết.
public InputStream getInputStream() : Phương thức này trả về InputStream nối với Socket. Chương trình Server dùng InputStream này để nhận dữ liệu từ Client gởi đến.
public OutputStream getOutputStream() : Phương thức này trả về OutputStream nối với Socket. Chương trình Server dùng OutputStream này để trả dữ liệu cho Client.
public close() : Phương thức này sẽ đóng Socket lại, giải phóng kênh ảo, xóa nối kết giữa Client và
Server.
Một Server có thể được cài đặt để phục vụ các Client theo hai cách: phục vụ tuần tự hoặc phục vụ song song.
Trong chế độ phục vụ tuần tự, tại một thời điểm Server chỉ chấp nhận một yêu cầu nối kết. Các yêu cầu nối kết của các Client khác đều không được đáp ứng (đưa vào hàng đợi).
Ngược lại trong chế độ phục vụ song song, tại một thời điểm Server chấp nhận nhiều yêu cầu nối kết và phục vụ nhiều Client cùng lúc.
Xây dựng chương trình Server phục vụ tuần tự
Các bước thực hiện như sau:
Tạo socket và gán số hiệu cổng cho server.
Lắng nghe yêu cầu nối kết.
Với một yêu cầu nối kết được chấp nhận thực hiện các bước sau:
Lấy InputStream và OutputStream gắn với Socket của kênh ảo vừa được hình thành.
Lặp lại công việc sau:
Chờ nhận các yêu cầu (công việc).
Phân tích và thực hiện yêu cầu.
Tạo thông điệp trả lời.
Gởi thông điệp trả lời về Client.
Nếu không còn yêu cầu hoặc Client kết thúc, đóng Socket và quay lại bước 2.
Code của chương trình Server như sau:
package com.gpcoder.tcp;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class EchoChatSingleServer {
public final static int SERVER_PORT = 7;
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = null;
try {
System.out.println("Binding to port " + SERVER_PORT + ", please wait ...");
serverSocket = new ServerSocket(SERVER_PORT);
System.out.println("Server started: " + serverSocket);
System.out.println("Waiting for a client ...");
while (true) {
try {
Socket socket = serverSocket.accept();
System.out.println("Client accepted: " + socket);
OutputStream os = socket.getOutputStream();
InputStream is = socket.getInputStream();
int ch = 0;
while (true) {
ch = is.read(); // Receive data from client
if (ch == -1) {
break;
}
os.write(ch); // Send the results to client
}
socket.close();
} catch (IOException e) {
System.err.println(" Connection Error: " + e);
}
}
} catch (IOException e1) {
e1.printStackTrace();
} finally {
if (serverSocket != null) {
serverSocket.close();
}
}
}
}
Chạy chương trình Server, ta có kết quả sau:
Tiếp tục chạy chương trình Client, ta có kết quả sau:
Xem lại cửa sổ console của Server, ta thấy kết quả như sau:
Xây dựng chương trình Server phục vụ song song
Server phục vụ song song có thể chia thành 2 phần thực hiện song song nhau:
Phần 1 (Dispatcher Thread) : Xử lý các yêu cầu nối kết. Lặp lại các công việc sau:
Lắng nghe yêu cầu nối kết của Client.
Chấp nhận một yêu cầu nối kết: Tạo kênh giao tiếp ảo mới với Client, tạo Phần 2 để xử lý các thông điệp yêu cầu của Client.
Phần 2 (Worker Thread) : Xử lý các thông điệp yêu cầu từ khách hàng. Lặp lại các công việc sau:
Chờ nhận thông điệp yêu cầu của khách hàng.
Phân tích và xử lý yêu cầu.
Gởi thông điệp trả lời cho khách hàng.
Phần 2 sẽ kết thúc khi kênh ảo bị xóa đi.
Với mỗi Client, trên Server sẽ có một Phần 2 để xử lý yêu cầu của khách hàng. Như vậy tại một thời điểm bất kỳ luôn tồn tại 1 Phần 1 và 0 hoặc nhiều Phần 2.
Code của chương trình Server như sau:
EchoChatMultiServer.java
package com.gpcoder.tcp;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class EchoChatMultiServer {
public static final int NUM_OF_THREAD = 4;
public final static int SERVER_PORT = 7;
public static void main(String[] args) throws IOException {
ExecutorService executor = Executors.newFixedThreadPool(NUM_OF_THREAD);
ServerSocket serverSocket = null;
try {
System.out.println("Binding to port " + SERVER_PORT + ", please wait ...");
serverSocket = new ServerSocket(SERVER_PORT);
System.out.println("Server started: " + serverSocket);
System.out.println("Waiting for a client ...");
while (true) {
try {
Socket socket = serverSocket.accept();
System.out.println("Client accepted: " + socket);
WorkerThread handler = new WorkerThread(socket);
executor.execute(handler);
} catch (IOException e) {
System.err.println(" Connection Error: " + e);
}
}
} catch (IOException e1) {
e1.printStackTrace();
} finally {
if (serverSocket != null) {
serverSocket.close();
}
}
}
}
WorkerThread.java
package com.gpcoder.tcp;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class WorkerThread extends Thread {
private Socket socket;
public WorkerThread(Socket socket) {
this.socket = socket;
}
public void run() {
System.out.println("Processing: " + socket);
try {
OutputStream os = socket.getOutputStream();
InputStream is = socket.getInputStream();
while (true) {
int ch = is.read(); // Receive data from client
if (ch == -1) {
break;
}
os.write(ch); // Send the results to client
}
} catch (IOException e) {
System.err.println("Request Processing Error: " + e);
}
System.out.println("Complete processing: " + socket);
}
}
Chạy chương trình Server, ta có kết quả sau:
Chạy liên tục 3 chương trình Client, ta có kết quả như sau:
Như bạn thấy, cả 3 chương trình Client đều được Server xử lý cùng lúc.
Xây dựng chương trình Client – Server ở chế độ không nối kết (UDP)
UDP – User Datagram Protocol : cung cấp cơ chế vận chuyển không bảo đảm và không nối kết trên mạng IP, ngược với giao thức vận chuyển tin cậy, có nối kết TCP.
Cả giao thức TCP và UDP đều phân dữ liệu ra thành các gói tin. Tuy nhiên TCP có thêm vào những tiêu đề (Header) vào trong gói tin để cho phép truyền lại những gói tin thất lạc và tập hợp các gói tin lại theo thứ tự đúng đắn. UDP không cung cấp tính năngnày, nếu một gói tin bị thất lạc hoặc bị lỗi, nó sẽ không được truyền lại, và thứ tự đến đích của các gói tin cũng không giống như thứ tự lúc nó được gởi đi.
Tuy nhiên, về tốc độ, UDP sẽ truyền nhanh gấp 3 lần TCP. Cho nên chúng thường được dùng trong các ứng dụng đòi hỏi thời gian truyền tải ngắn và không cần tính chính xác cao, ví dụ truyền âm thanh, hình ảnh …
Mô hình client – server sử dụng lớp ServerSocket và Socket ở trên sử dụng giao thức TCP. Nếu muốn sử dụng mô hình client – server với giao thức UDP, ta sử dụng hai lớp java.net.DatagramSocket và java.net.DatagramPacket.
DatagramSocket được sử dụng để truyền và nhận các DatagramPacket. Dữ liệu được truyền đi là một mảng những byte, chúng được gói vào trong lớp DatagramPacket. Chiều dài của dữ liệu tối đa có thể đưa vào DatagramPacket là khoảng 60.000 byte (phụ thuộc vào dạng đường truyền). Ngoài ra DatagramPacket còn chứa địa chỉ IP và cổng của quá trình gởi và nhận dữ liệu.
Cổng trong giao thức TCP và UDP có thể trùng nhau. Trên cùng một máy tính, bạn có thể gán cổng 20 cho socket dùng giao thức TCP và cổng 20 cho socket sử dụng giao thức UDP.
Một số phương thức cần thiết để xây dựng các chương trình Client-Server sử dụng socket ở chế độ không nối kết:
public DatagramPacket(byte[] b, int n, InternetAddress ia, int port) : Phương thức này cho phép tạo một DatagramPacket chứa dữ liệu và cả địa chỉ của máy nhận dữ liệu. Phương thức trả về một đối tượng thuộc lớp DatagramePacket.
public DatagramSocket( int port) : Tạo Socket kiểu không nối kết cho Client với số hiệu cổng được xác định trong tham số (port). Nếu không xác định port, hệ thống tự động gán số hiệu cổng chưa sử dụng cho socket.
public void send(DatagramPacket dp) : Dùng để gởi một DatagramPacket đi.
public synchronized void receive(Datagrampacket dp) : Chờ nhận một DatagramPacket. Quá trình sẽ bị nghẽn cho đến khi có dữ liệu đến.
Các phương thức lấy thông tin trên một DatagramPacket nhận được:
Khi nhận được một DatagramPacket từ một quá trình khác gởi đến, ta có thể lấy thông tin trên DatagramPacket này bằng các phương thức sau:
public synchronized() InternetAddress getAddress() : Địa chỉ máy gởi.
public synchronized() int getPort() : Cổng của quá trình gởi.
public synchronized() byte[] getData() : Dữ liệu từ gói tin.
public synchronized() int getLength() : Chiều dài của dữ liệu trong gói tin.
Các phương thức đặt thông tin cho gói tin gởi:
Trước khi gởi một DatagramPacket đi, ta có thể đặt thông tin trên DatagramPacket này bằng các phương thức sau:
public synchronized() void setAddress(IntermetAddress address) : Đặt địa chỉ máy nhận.
public synchronized() void setPort(int port) : Đặt cổng quá trình nhận.
public synchronized() void setData(byte buffer[]) : Đặt dữ liệu gởi.
public synchronized() void setLength(int len) : Đặt chiều dài dữ liệu gởi.
Xây dựng chương trình Server ở chế độ không nối kết
Chương trình EchoServer cài đặt Echo Server ở chế độ không nối kết, cổng mặc định là 7. Chương trình chờ nhận từng gói tin, lấy dữ liệu ra khỏi gói tin nhận được và gởi ngược dữ liệu đó về Client.
package com.gpcoder.udp;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class EchoServer {
public final static int SERVER_PORT = 7; // Cổng mặc định của Echo Server
public final static byte[] BUFFER = new byte[4096]; // Vùng đệm chứa dữ liệu cho gói tin nhận
public static void main(String[] args) {
DatagramSocket ds = null;
try {
System.out.println("Binding to port " + SERVER_PORT + ", please wait ...");
ds = new DatagramSocket(SERVER_PORT); // Tạo Socket với cổng là 7
System.out.println("Server started ");
System.out.println("Waiting for messages from Client ... ");
while (true) { // Tạo gói tin nhận
DatagramPacket incoming = new DatagramPacket(BUFFER, BUFFER.length);
ds.receive(incoming); // Chờ nhận gói tin gởi đến
// Lấy dữ liệu khỏi gói tin nhận
String message = new String(incoming.getData(), 0, incoming.getLength());
System.out.println("Received: " + message);
// Tạo gói tin gởi chứa dữ liệu vừa nhận được
DatagramPacket outsending = new DatagramPacket(message.getBytes(), incoming.getLength(),
incoming.getAddress(), incoming.getPort());
ds.send(outsending);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (ds != null) {
ds.close();
}
}
}
}
Xây dựng chương trình Client ở chế độ không nối kết
Chương trình này cho phép người sử dụng nhận các chuỗi từ bàn phím, gởi chuỗi sang EchoServer ở chế độ không nối kết ở cổng số 7, chờ nhận và in dữ liệu từ Server gởi về ra màn hình.
package com.gpcoder.udp;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class EchoClient {
public final static String SERVER_IP = "127.0.0.1";
public final static int SERVER_PORT = 7; // Cổng mặc định của Echo Server
public final static byte[] BUFFER = new byte[4096]; // Vùng đệm chứa dữ liệu cho gói tin nhận
public static void main(String[] args) {
DatagramSocket ds = null;
try {
ds = new DatagramSocket(); // Tạo DatagramSocket
System.out.println("Client started ");
InetAddress server = InetAddress.getByName(SERVER_IP);
while (true) {
System.out.println("Enter your message: ");
InputStreamReader isr = new InputStreamReader(System.in); // Nhập
BufferedReader br = new BufferedReader(isr); // một chuỗi
String theString = br.readLine(); // từ bàn phím
byte[] data = theString.getBytes(); // Đổi chuỗi ra mảng bytes
// Tạo gói tin gởi
DatagramPacket dp = new DatagramPacket(data, data.length, server, SERVER_PORT);
ds.send(dp); // Send gói tin sang Echo Server
// Gói tin nhận
DatagramPacket incoming = new DatagramPacket(BUFFER, BUFFER.length);
ds.receive(incoming); // Chờ nhận dữ liệu từ EchoServer gởi về
// Đổi dữ liệu nhận được dạng mảng bytes ra chuỗi và in ra màn hình
System.out.println("Received: " + new String(incoming.getData(), 0, incoming.getLength()));
}
} catch (IOException e) {
System.err.println(e);
} finally {
if (ds != null) {
ds.close();
}
}
}
}
Chạy chương trình Server, ta có kết quả như sau:
Chạy chương trình Client, ta có kết quả như sau:
Tại Client, nhập nội dung message là Hello. Ta có kết quả như sau:
Tại Cient, tiếp tục nhập nội dung là How are you. Ta có kết quả như sau:
Xây dựng chương trình Client-Server nối kết theo dạng multicast (truyền theo nhóm)
Các cơ chế Socket TCP và UDP đã giới thiệu ở trên đề gọi là unicast, nghĩa là giao tiếp chỉ diễn ra giữa một máy tính gửi và một máy tính nhận.
Multicast là việc gửi quảng bá (broadcast) nhưng đến một nhóm máy tính ở cùng một địa chỉ cho trước. Địa chỉ multicast là địa chỉ lớp D được xác định trong khoảng 244.0.0.0 đến 239.255.255.255. Địa chỉ 244.0.0.0 là địa chỉ riêng nên không sử dụng được.
Multicast được sử dụng trong game nhiều người chơi, trong những ứng dụng mà đối tượng là nhiều thiết bị hay nhiều máy tính cùng nhận một loại thông tin. Multicast cũng được sử dụng trong giải thuật vạch đường (Routing Protocol), khi các router muốn cập nhật thông tin với nhau.
Java hỗ trợ Multicast thông qua lớp java.net.MulticastSocket. Một Multicast Socket là 1 DatagramSocket (UDP) có khả năng gia nhập (joining) vào một nhóm các máy tính multicast trên mạng. Khi một máy tính nào gửi thông điệp đến nhóm thì tất cả các máy tính trong đó đều nhận được.
Một số phương thức cần thiết để xây dựng các chương trình Multicast:
public MulticastSocket(int port): Tạo Socket kiểu Multicast với số hiệu cổng được xác định trong tham số (port).
public void joinGroup(InetAddress group) : Tham gia nhóm Multicast tại địa chỉ xác định.
public void leaveGroup(InetAddress group) : Rời khỏi nhóm Multicast tại địa chỉ xác định.
public void send(DatagramPacket dp) : Dùng để gởi một DatagramPacket đi.
public synchronized void receive(Datagrampacket dp) : Chờ nhận một DatagramPacket.
Ví dụ:
Cài đặt một dịch vụ gởi tin nhắn trên cổng 8888, tại địa chỉ 224.0.0.1. Khi Client muốn nhận tin nhắn thì Join Group tại địa chỉ và cổng trên.
Lớp Sender
package com.gpcoder.multicast;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class MulticastSender {
public static final String GROUP_ADDRESS = "224.0.0.1";
public static final int PORT = 8888;
public static void main(String[] args) throws InterruptedException {
DatagramSocket socket = null;
try {
// Get the address that we are going to connect to.
InetAddress address = InetAddress.getByName(GROUP_ADDRESS);
// Create a new Multicast socket
socket = new DatagramSocket();
DatagramPacket outPacket = null;
long counter = 0;
while (true) {
String msg = "Sent message No. " + counter;
counter++;
outPacket = new DatagramPacket(msg.getBytes(), msg.getBytes().length, address, PORT);
socket.send(outPacket);
System.out.println("Server sent packet with msg: " + msg);
Thread.sleep(1000); // Sleep 1 second before sending the next message
}
} catch (IOException ex) {
ex.printStackTrace();
} finally {
if (socket != null) {
socket.close();
}
}
}
}
Lớp Receiver
package com.gpcoder.multicast;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
public class MulticastReceiver {
public static final byte[] BUFFER = new byte[4096];
public static void main(String[] args) {
MulticastSocket socket = null;
DatagramPacket inPacket = null;
try {
// Get the address that we are going to connect to.
InetAddress address = InetAddress.getByName(MulticastSender.GROUP_ADDRESS);
// Create a new Multicast socket
socket = new MulticastSocket(MulticastSender.PORT);
// Joint the Multicast group
socket.joinGroup(address);
while (true) {
// Receive the information and print it.
inPacket = new DatagramPacket(BUFFER, BUFFER.length);
socket.receive(inPacket);
String msg = new String(BUFFER, 0, inPacket.getLength());
System.out.println("From " + inPacket.getAddress() + " Msg : " + msg);
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
Chạy chương trình MulticastSender, sau đó start tiếp một vài chương trình MulticastReceiver. Chúng ta nhận được kết quả như sau:
Như bạn thấy, bất kỳ client nào join group đều nhận được nội dung message giống nhau, và nhận cùng thời điểm. Chương trình Multicast Server vẫn phục vụ theo dạng UDP, chỉ khác là sẽ gửi gói tin Datagram đến địa chỉ IP thuộc lớp D.
Bài viết được sự cho phép của tác giả Nguyễn Việt Hưng
Tôi là một người may mắn, và tôi không phải nói câu này. Nhưng giờ đã 12 năm sau cái ngày đó (2008), nhìn lại, thì đại học mang lại cho tôi những gì? Và nếu bạn trượt đại học, thì giờ làm gì đây?
Trượt đại học thì sao?
Thì buồn.
Đấy là điều đầu tiên có thể cảm nhận được. Dù chưa trải qua, chỉ cần nhìn những đứa bạn kém may mắn hơn chúng nó buồn, thậm chí còn xa lánh mình, sẽ hiểu trượt đại học thì buồn.
Thế tại sao lại buồn?
Xã hội sinh ra một định kiến: học hết cấp 3 thì PHẢI thi đại học, và đỗ đại học là giỏi, là vinh quang, còn trượt thì là … không giỏi. Bạn sẽ bị coi như 1 kẻ kém cỏi, hàng xóm, người quen, bạn bố mẹ sẽ hỏi thăm. Và bởi vì nó đã là một định kiến xã hội, nên 1 2 con người thay đổi cũng gặp rất nhiều khó khăn. Cái sức ép xã hội khiến bạn phải buồn, khiến bạn nghĩ rằng mình kém cỏi, vậy nên bạn buồn. Hay đơn giản buồn vì bố mẹ/người thân bạn buồn. Ngoài ra, phải rời xa bạn bè vì chúng nó đều đi lên thành phố học hết, cũng buồn.
Nhớ rằng “học tài, thi phận”, bởi nếu như bạn được 25 điểm mà cái trường bạn chọn năm nay nó tăng nhanh như chỉ số PM 2.5 ở thủ đô, lấy hản 27 thay vì 23 như năm trước, thì đâu phải do bạn kém? Hay thằng hàng xóm được 15 điểm, đăng ký vào trường năm nay lấy 15, thì nó lại đỗ. Hay con ông kia ôn trúng tủ, còn bạn thì lệch, nó đỗ là may hơn, chứ đâu phải giỏi hơn.
Năm 18 tuổi, tôi thi đại học vì 1 lý do đơn giản: vì đấy là điều ai cũng làm sau khi học xong lớp 12. Trong cái đầu của 1 thằng học sinh miền núi đi thi được cộng thêm 1.5 điểm, không hề từng nghĩ đến câu “tại sao lại phải học đại học”, hay “học đại học để làm gì?”. Chuyện chọn trường cũng đơn giản chỉ là “thích nghịch máy tính thì vào bách khoa” chứ chả hiểu bách khoa dạy cái gì để làm với máy tính.
Thế nên bạn có thể buồn, nhưng nhớ nghĩ kỹ hơn chút, là tại sao mình phải buồn.
Ngày ấy, hiểu đơn giản là cứ đi đại học thôi, đi đại học là thành công, đi đại học để học đại học. Học để ra trường, kiếm được 1 tấm bằng đại học, rồi cầm về để mang đi xin việc, làm ở cơ quan nào đó.
Giờ ngẫm lại, xã hội muốn mình đi học đại học mục đích ra là để kiếm cho mình được 1 công việc, nuôi bản thân, đóng góp cho xã hội.
Cái bằng là thứ công cụ để xin việc của thời ngày xưa, là tấm vé giải độc đắc để kiếm được 1 chỗ ngon trong cơ quan toàn là cán bộ.
Còn giờ là năm thứ 20 của thế kỷ 21, tấm bằng trở nên bớt quan trọng hơn nhiều, kể cả cầm 1 tấm bằng, đi xin việc thì vẫn phải THI (hay gọi nhẹ nhàng hơn là “phỏng vấn”). Ngoài ra, rất nhiều nơi / ngành nghề, không hề quan tâm đến bằng cấp, đặc biệt là ngành công nghệ thông tin.
Nếu anh giỏi, anh làm được, thì mang cái sản phẩm của mình ra mà khoe, còn anh chả có gì khoe, thì đành thôi: mang khoe cái bằng.
Xin chào, đây là website tôi làm ra, giải quyết vấn đề này, sử dụng công nghệ kia … app di động 1 triệu lượt tải trên app store …
Xin chào, em không biết code web/app nhưng em có bằng khá Bách Khoa, em chưa làm ra sản phẩm nào ngoài đoạn code tính tổng từ 1 đến 1000.
Cái bằng, không phải là mục đích của việc học đại học. Học đại học là để có được “kỹ năng”/”trình độ”, cái bằng chỉ là “bằng chứng” do trường đại học đó đánh giá, theo tiêu chuẩn của trường đó. Vậy nên nếu không học đại học, ta sẽ không có “bằng chứng” do trường đại học đó cung cấp, nhưng không hề liên quan đến chuyện “kỹ năng”/”trình độ”, thứ mà hoàn toàn có thể học ở chỗ khác.
Học đại học được gì
Nếu coi trường học như một cỗ máy, thì đầu vào là các sinh viên khá “thông minh” do điểm thi đầu vào trên mức N, còn đầu ra sẽ các kỹ sữ biết làm việc mà họ được đào tạo. Lý thuyết là vậy, còn thực tế thì khác hoàn toàn lý thuyết.
Khuôn mặt một sinh viên mùa ôn thi – Photo by Ray Hennessy on Unsplash
Nhìn lại, 5 năm đại học tôi có được:
Được lên thủ đô sống, làm quen với “văn minh xã hội”. Lần đầu xuống nhập học được học ngay bài học ăn phở không hỏi giá, bị chém đẹp 50k (thời 2008).
Những người bạn. Vui vẻ cùng nhau đến lớp ngủ, cùng nhau vượt qua các kỳ thi lại, cùng nhau uống rượu, cùng nhau đi chơi… Thứ tình bạn trong sáng (như hồi cấp 3), những người anh em chia ngọt sẻ bùi, điều mà sau này đi làm rồi, hay có gia đình riêng rồi, sẽ rất khó mà kiếm được.
Quãng thời gian sinh viên, học hành thì ít mà chơi thì nhiều, những va vấp nhẹ nhàng với xã hội khi lần đầu rời xa gia định đến 1 nơi xa lạ.
Một ngôi trường có cháo lòng, cháo sườn, bánh mì, rượu ốc ngon.
Những hoạt động thanh niên cấp tiến như sinh viên tình nguyện, tiếp sức mùa thi, chiếc khăn gió ấm, mùa đông không lạnh…
Khả năng tự học: cái này là kỹ năng tự luyện được, lôi sách lôi vở ra mà đọc mà luyện đề thi còn qua môn, chứ làm gì có ai dạy cho.
Còn kiến thức? không nhiều lắm. Những kiến thức ngày nay đi làm, đều do tôi tự mày mò, nhờ sự ham mê máy tính từ ngày còn nhỏ. Blog FAMILUG viết từ năm thứ 2 đại học là bằng chứng ấy. Tôi code Python khi ở Việt Nam chẳng mấy ai biết tên, tôi dùng Ubuntu khi mọi người còn không biết nó tồn tại.
Nói vậy không có nghĩa là 5 năm trường không dạy gì. Trường có dạy, vấn đề là bạn có học hay không? và học có giỏi hay không? Một phần nhỏ sinh viên thuộc nhóm có học, và học giỏi, ra sẽ học lên cao, xin học bổng nước ngoài, được giữ làm giảng viên, hay xin được công việc phù hợp. Nhưng nhớ là số này rất ít, một khóa học 100 sinh viên thì có 1, 2, 3, 4 thằng, chứ không phải là 20 thằng. Với nhóm này, học đại học còn có thêm cái lợi: quan hệ tốt với thầy cô, nhiều cơ hội xin học bổng du học lên cao, làm đề tài nghiên cứu khoa học cùng thầy cô … Đây là cái đầu ra mong ước, chuẩn của các trường. Số còn lại, chiếm tới hơn 90%, mới là phần đáng nói của câu chuyện.
Bằng giỏi Bách Khoa thời ấy, hiếm như khẩu trang đầu mùa COVID-19, sinh viên ra trường đúng hạn thì ít, bằng khá đã là học hành tử tế lắm rồi. Bằng khá Bách Khoa nó không nhiều nhan nhản như bằng giỏi bên kinh tế nha. Số này cỡ 2 chục người trong 1 khóa 100 người, cũng bằng số sinh viên ra trường trước hạn, bỏ học/đuổi học/quên đăng ký môn học… rồi bị đuổi.
Cái nhóm 60 sinh viên bằng “trung bình”, ra trường không đúng hạn ấy, học được gì ở trường? Năm 2008-2013+, khoa/viện toán ứng dụng và tin học Bách Khoa Hà Nội dạy:
2 năm học đại cương: toán, lý, hóa, nhiệt, điện, cơ học kỹ thuật, vẽ kỹ thuật, điện tử, triết học Mac Lê Nin, tư tưởng Hồ Chí Minh, … các môn học được coi là nền tảng phải có của mọi kỹ sư. Và để thêm chắc, các môn toán lý hóa có tới 5 7 môn khác nhau, lý 1 2 3 nữa cho nó chắc. Đây là thời kỳ học chán nản nhất cho các sinh viên, trượt/thi lại triền miên, bởi đây toàn những môn lý thuyết khó nhai. Có những môn học lại 10 kỳ, cho đến khi qua được thì cũng là lúc ra trường. Gọi là học, chứ thi xong là coi như trả hết chữ thầy, kiến thức cũng chẳng dùng đến bao giờ, như cách tra biểu đồ nhiệt chẳng hạn. Ở đâu đó, ai đó làm một nghề nào đó, có thể đang dùng, thậm chí là quan trọng. Sinh viên ra trường đi làm có người dùng tới có người không, nên nhớ đây là chương trình để đào tạo hàng loạt người, nên đứng dưới góc độ nhà trường, bạn thà dạy thừa còn hơn thiếu.
3 năm học chuyên ngành: Toán-Tin. Hầu hết sinh viên khóa này học toán-tin đơn giản là vì trượt nguyện vọng 1, rơi tự do xuống mà vào toán tin. Bách Khoa thời ấy, học 1 năm đại cương, lấy điểm 2 kỳ đầu để xét phân khoa. Đây cũng là thời mà hận những thằng giỏi học đại cương, chúng nó nộp vào CNTT ầm ầm, chỉ đơn giản là vì ngành hot, ra dễ kiếm việc lương cao – chứ thậm chí chưa chạm tay vào máy tính 1 lần. Khoa nào nhiều người vào thì hot, điểm cao, khoa nào không ai đăng ký… thì rơi tự do. Không nhiều sinh viên vào Toán-Tin để học toán, chắc cũng là một phần lý do mà kết quả học tập cũng không mấy đẹp đẽ gì. Hơn nửa chương trình chuyên ngành 3 năm này là toán, một chút ít “tin” cho có gọi là. Sinh viên muốn làm được đồ án tin để ra trường, phải tự kiếm chỗ mà học lập trình cho tử tế (tự học mà giỏi được thì tốt, ai cũng làm được thì người ta không phải mở trường, dựng trung tâm). Đừng hy vọng sẽ được học lập trình, ra thành 1 lập trình viên chuyên nghiệp từ đây. Với những sinh viên muốn theo ngành “tin học”, thì phần toán kia rất khó nuốt, khô khan, chẳng có chỗ dùng, không có hứng học, thi khó qua, điểm sẽ thấp. Chương trình học lạc hậu, đặc biệt với các môn tin, khi mà công nghệ thay đổi hàng năm còn toán thì trăm năm mới đổi. Đây là tên vài môn toán kinh (khủng) điển: giải tích hàm, phương trình đạo hàm riêng, giải tích số, giải tích phức, toán kinh tế, các phương pháp tối ưu, hệ mờ ?!? Chất lượng giảng dạy thì rất phụ thuộc vào giảng viên, một số môn có thầy cô dạy hay, phong cách hay, lôi cuốn sinh viên học dù môn học không có nhiều tính ứng dụng thấy ngay, có môn thầy đến lớp hì hục chép đầy 6 cái bảng 9 lần rồi về, sinh viên ra vào thậm chí không biết…
Đấy là thời đó, cũng gần 10 năm rồi, thời ấy học mạng neuron và hệ mờ trên giấy, chỉ biết lấy công thức ra tính, chả ai biết để làm gì, chưa ai nghe tới Machine Learning hay Deep Learning. Còn giờ thì Toán Tin đầu vào hẳn 27.56, xin được mừng cho viện nhà.
Xem chương trình đào tạo mới tại đây thấy đã bớt được nhiều môn học nền tảng, quan trọng như hóa hay nhiệt đi rồi, mừng cho các tài năng đất nước.
Nói vậy, không nghĩa là không nên học đại học. Đỗ rồi thì đi học thôi, nhưng nên thử để biết mình thích gì/hợp làm gì, mà tìm học thêm, chứ đừng thụ động ngồi chờ trường dạy cho.
Trượt đại học thì làm gì
Trượt đại học thì đi học cái khác, hoặc đi làm. Học đại học là con đường có vẻ như “dễ”/”sáng” nhất để dẫn đến “thành công”/”thành tài”, nhưng không phải con đường duy nhất. Cũng chẳng có gì đảm bảo, hàng năm sinh viên đại học, thậm chí cao học, ra trường vẫn thất nghiệp ầm ầm
Nếu muốn, nghỉ ngơi 1 thời gian rồi 3 tháng sau bắt đầu ôn thi để sang năm… chơi lại trò chơi may rủi.
Học đại học thời nay là một khoản đầu tư không nhỏ, học phí các trường công giờ cũng cao chót vót, mỗi kỳ học đóng học phí bằng 1/2 -> 1 con iPhone mới nhất vừa ra. Học 10 kỳ là 10 con (~tối thiểu 60 triệu cho 5 năm học), chưa kể thi lại, chưa tính chi phí ăn ở 4-5 năm. Nên nếu chỗ nào học phí 50 triệu, trong vòng 2 năm, hay 5 triệu trong vòng 2 tháng mà cho bạn cơ hội kiếm việc làm lương 8-10 triệu/tháng thì đừng xem là đắt, đi làm vài tháng là hồi vốn. Ngoài ra, nếu tôi học nửa năm rồi đi làm, sau 5 năm tôi có 4.5 năm kinh nghiệm, lương thừa X3 mấy cậu sinh viên mới rón rén ra trường.
Điều quan trọng là tìm ra thứ khiến mình thích thú, đam mê. Nếu có rồi, cứ thế mà học theo, nếu chưa biết, đỗ đại học, đi học 5 năm chăm chỉ ra rồi nhận ra mình không thích mới đổi, lúc ấy mới là muộn, đó mới là thất bại đáng lo.
Những thứ quan trọng cần đầu tư:
Ngoại ngữ: phổ biến, dễ học nhất là tiếng Anh. Dù học đại học hay không, đây vẫn là thứ quan trọng nhất. Nó mở ra cả 1 chân trời cơ hội, hàng triệu tài liệu hướng dẫn miễn phí bằng tiếng Anh trên internet, dù học bất cứ thứ gì, điều kiện làm các công việc lương cao, công ty nước ngoài.
Rèn luyện sức khỏe: tập gì cũng được, có sức khỏe, có cơ thể đẹp là một lợi thế cả đời, cực lớn, thậm chí giúp kiếm được nhiều công việc lương cực cao, ngàn đô 1 ngày!
Nếu muốn học ngành Công Nghệ Thông Tin, học xong đi kiếm việc làm lương khởi điểm 8-10 triệu, ghé ngay PyMi.vn để đăng ký học lập trình Python tại Hà Nội – Sài Gòn (TP HCM).
Học có 1.5 tháng mà đi làm được?
Tất nhiên là phải học, phải đầu tư thời gian, chăm chỉ luyện bài, thì học ra mới dễ xin được việc, mỗi tuần dành ~ 20 tiếng để cày cuốc bài tập. Chứ đừng nghĩ tới lớp xem giảng bài, về nhà bận đi chơi, rồi ra thì có người mời đi làm, sorry babe, ở đây không bán rượu mơ.
PyMi không chỉ dạy Python, mà sử dụng các công cụ / practice của lập trình viên trong suốt quá trình học (vd: Git/GitLab/CI/Code Review).
Lương chỉ có 8-10 triệu?
Đây là mức lương khởi điểm cho vị trí lập trình viên Python (thường là lập trình web-backend). Mức lương này ngang ngửa với sinh viên đại học mới ra trường. Còn muốn học 2 tháng ra làm lương ngàn đô, có lẽ qua bên các kênh đầu tư tài chính thì nhiều cơ hội hơn.
Sau khi đi làm 1 2 năm có thể tăng lên 15 triệu, hay $1000, và cứ thế tăng tiếp… PS: muốn > $1000, phải có ngoại ngữ tốt.
Tài liệu trên mạng đầy, lên youtube xem rồi tự học
Tự học là một kỹ năng không phải ai cũng có. Kỹ năng tự học phải luyện nhiều, mới có. Cũng chẳng phải đến đại học thì mới biết tự học. Cứ tự học nhiều (như 5 năm ở Bách Khoa) thì khác dần biết cách thôi. Nếu tự học mà hiệu quả được, đó là điều rất đáng mừng, bạn cũng không cần phải đi đại học làm gì cho mất thời gian.
Lên youtube xem/đọc tài liệu không hiểu thì lấy ai để hỏi?
Tài liệu chất lượng kém, đặc biệt các tài liệu tiếng Việt dùng Google Translate rồi paste vào. Tài liệu viết bởi những người không có trình độ, liệu bạn có phân biệt được?
Lên các diễn đàn/FaceBook group để hỏi rồi ngồi chờ hy vọng có ai đó tốt giúp trả lời, mà trả lời đúng hay sai cũng không chắc nữa.
Nếu lý do ngồi chờ cộng đồng trả lời sau vài ngày rồi mới học tiếp là để “tiết kiệm tiền”, thì chỉ chứng minh 1 điều là thời gian của bạn quá rẻ.
Tự học ngoài ra còn gặp một số vẫn đề như: “đâm đầu vào tường” nhiều, do không ai chỉ cho đâu là đúng sai, phải tự tìm ra, vậy nên mất thời gian hơn. Đi học, không hỏi thầy thì còn hỏi bạn, nhanh hơn rất nhiều. Ngoài ra bạn còn không biết mình không biết những gì.
Một khi đã tự học rồi, thì lo tập trung vào việc học, làm bài tập, tránh mất thời gian ít bổ ích trên các group online.
Các khóa học tiếng Anh trên mạng rẻ bèo, như Udemy
Nếu xem được mà hiểu thì trình độ tiếng Anh của bạn cũng thuộc top trên của người Việt Nam đó, chúc mừng nha. Như đã viết ở trên, nếu đã có tiếng Anh, thì toàn bộ phần còn lại chỉ là game dễ.
Các khóa học cũng có loại this, loại that. Học code mà chỉ xem video, không thò tay vào code, không có bài tập, không có sửa bài, thì chỉ là xem video.
Code là kỹ năng, muốn giỏi phải luyện tập nhiều. Làm ra phải được chấm (review), để biết là tốt hay xấu, đúng hay sai.
Học đại học 5 năm ra còn chẳng ăn ai, đòi học vài tháng
Bạn đã thấy có thằng học như điên 3 năm, học đủ cả sinh sử địa, giáo dục công dân nữa để “rèn luyện tư duy” mà trượt đại học khối A, còn có thằng đi ôn lò vài tháng, trúng tủ đỗ luôn chưa?
5 năm đại học không phải là học cả 5 năm, thời gian chơi có khi hết 4 năm rưỡi. 10 thằng học giỏi có đến 90 thằng loại bình thường.
Xem lại chương trình đại học Bách Khoa ở trên để thấy nếu muốn làm lập trình viên (nghề ghi đầu tiên trong bảng quảng cáo học Toán Tin), thì chỉ có vài môn học cuối khóa có chút liên quan, mà muốn ra đi làm được vẫn phải học thêm rất nhiều.
Học lâu mà sai không có ý nghĩa gì so với học đúng mà nhanh.
Kiến thức ở các trường đại học Việt Nam đều rất chậm thay đổi, trong khi công nghệ thay đổi hàng năm. 5 năm học, dùng C/Pascal vài ba project nhỏ ở trường sẽ khống kiếm cho bạn 1 công việc dev Python.
Giờ không biết đã trường nào dạy dùng git chưa, hay vẫn Turbo C màn hình xanh menu đỏ rồi tự hào công nghệ?
Học vậy không có “kiến thức cơ bản”/”kiến thức nền tảng”
“Kiến thức cơ bản” cụ thể là cái gì? hiểu cách các vi mạch điện hoạt động rồi chạy code như thế nào? (học đại học ở Việt Nam cũng không giúp bạn hiểu cái này), hay hiểu cách đổi 8 bit thành 1 byte?
Hay kiến thức cơ bản là môn “cấu trúc dữ liệu giải thuật/toán rời rạc” học trên giấy trong 1 kỳ mà cứ ngỡ như không đi đại học thì không được học/ không học được? Có bao nhiêu kiến thức cơ bản ấy ở lại trong sinh viên sau 5 năm ra trường, học môn ấy từ năm thứ 2.
Có 2 cách tiếp cần vấn đề, từ dưới lên, hoặc từ trên xuống. Các trường đại học dạy theo kiểu từ dưới lên, đến lúc lên đến trên thì sinh viên đã quên hết cái bên dưới.
Các trung tâm thì sẽ dạy từ trên xuống, học cái làm được luôn, có gì không hiểu thì đào sâu, tìm hiểu thêm.
Đừng nghĩ biết code mấy cái thuật toán sắp xếp học ở trường mà hơn người ta gõ list.sort(), cái bạn học ở trường, lúc đi ra làm, đâu có dùng? Bạn có biết list.sort() của Python dùng thuật toán gì không?
Nếu bạn thuộc “on the top của hành tinh này”, thiết kế thuật toán sắp xếp phù hợp với bài toán cụ thể, rõ ràng bạn không phải đối tượng của bài viết này.
Sao bài này toàn ví dụ viện Toán Tin – Bách Khoa Hà Nội
Vì tác giả đã học ở đó. Bạn học khoa khác, cậu chuyện có thể khác.
Học xong có làm được cái này, cái kia không?
Vui lòng đọc kỹ trang chủ Pymi và CV mẫu của học viên (cũng có link trên trang chủ).
Nói tóm lại, người muốn, sẽ tìm cách, còn không muốn, sẽ tìm lý do.
Hành động của chúng ta (Action Item)
Tự hỏi xem học đại học để làm gì?
Ngừng huyễn hoặc bản về sự cao siêu của đại học, hay “chỉ học đại học mới được học”.
Hồi tưởng xem học đại học đã học được gì có ích? và viết 1 bài.
Tìm cái bằng đại học xem nó ở góc nào.
Kết luận
"Don't let schooling interfere with your education." - Mark Twain
Trượt đại học nó không khủng khiếp như trượt vỏ chuối. Có đau vì sức ép xã hội, chứ không lo đập đầu xuống đất mà mất trí.
Đứng dậy, cầm laptop lên và đi học Python tại PyMi.vn đi nhé.
Mình là người rất yêu nghề lập trình, mình yêu lắm luôn ý, thế nhưng vẫn có lúc cũng cảm thấy ngán ngẩm mấy dòng code xanh đỏ trên cái màn hình xám xịt. Lý do ngán ngẩm không phải là mình chán nó, càng không phải mình ghét nó, mà là nó tẻ nhạt. Nhìn vào sự thật, những dòng code thật sự tẻ nhạt, nó không phát ra âm thanh hay, và cũng không ai khen một màn hình đầy code là đẹp cả.
Thế nhưng, code là một công việc quan trọng của lập trình viên, hơn nữa chúng ta đều là những người yêu nghề, bỏ code một ngày thì được, chứ bỏ code một tuần là nhớ ngay, nhưng code liên tục thì lại chán. Vậy có cách nào để việc code bớt nhàm chán hơn không, hay làm thế nào để code lâu chán hơn, thì trong bài viết này mình sẽ chỉ cho bạn vài mẹo nha.
1. VỪA CODE VỪA … NGHE NHẠC
Cách này thì chắc ai cũng biết rồi. Nếu như xem code là công việc nhàm chán, thì nghe nhạc lại rất thú vị, và chúng bù trừ cho nhau, khiến việc code trở nên thú vị hơn, nhất là nghe mấy bài EDM hay vinahouse thì cứ gọi là vừa code vừa quẩy banh nóc nhà…
Thế nhưng có vài lưu ý khi vừa code vừa nghe nhạc thế này nha:
Nếu ở chỗ đông người, hãy sắm cho mình một chiếc tai nghe thay vì bật loa ngoài sẽ gây ảnh hưởng tới mọi người. Nên chọn loại tai nghe có kết nối bluetooth để đỡ dây dợ vướng víu, hoặc sắm luôn em AirPort cho sang chảnh. Mình đang sở hữu một em Sony XB-400 nghe rất ổn.
Không nên nghe nhạc có nhiều lời, vì khả năng bạn sẽ nhẩm theo lời bài hát, cũng không nên nghe nhạc buồn (nhạc vàng, nhạc thất tình) kẻo bị phản tác dụng.
Không nên nghe nhạc quá lớn (kể cả đeo tai nghe), kẻo người khác gọi bạn sẽ không nghe thấy.
Không nên nghe nhạc trong những giai đoạn mà team cần trao đổi nhiều, vì bạn sẽ bị mất thông tin, hoặc người khác sẽ cho rằng bạn đang trong chế độ “không muốn bị làm phiền”.
2. ĐẶT RA CÁC THỬ THÁCH KHI CODE
Bạn có bao giờ đặt ra các thử thách trong khi code chưa, ví dụ như:
Cố gắng code một lần chạy đúng ngay.
Mỗi ngày học một tổ hợp phím mới để hạn chế sử dụng chuột.
Đứng code.
Code chạy sai hít đất 3 cái (chắc sớm thành gymer mất).
Trên là mấy gợi ý, bạn thử xem nha, cũng thú vị lắm đấy.
3. ĐỔI…
Đổi một vài thứ cũng là cách hiệu quả để việc code trở nên thú vị hơn:
3.1 Đổi theme IDE/Code editor
Đây có lẽ là cách nhanh gọn mà lại đem đến hiệu quả cao. Code editor/IDE là cái thứ mình nhìn vào suốt ngày, sẽ không phí thời gian nếu bạn sưu tầm cho mình vài bộ theme yêu thích để đổi qua đổi lại cho bớt nhàm chán.
Chắc mình không cần phải hướng dẫn bạn cách tìm theme đâu nhỉ, cứ lên google mà search thôi, đầy ra. Nếu muốn “hardcore” hơn, hãy thử code trên VIM.
3.2 Đổi hệ điều hành
Nếu đổi IDE/Code editor vẫn chưa đủ, thì hãy đổi hệ điều hành xem sao. Có 3 hệ điều hành phổ biến là Windows, Mac, Linux (Ubuntu), đổi qua đổi lại chắc chắn đem lại nhiều cảm giác thú vị hơn khi code.
3.3 Đổi công nghệ
Code đi code lại một stack công nghệ cũng chán, bạn thử đổi qua các công nghệ khác xem, như đổi ngôn ngữ lập trình khác, đổi vai trò code khác (backend, frontend), đổi database khác, đổi framework khác,… vừa đỡ nhàm chán, lại vừa học được thêm kiến thức mới.
3.4 Đổi góc làm việc
Sau cùng, đổi hết các thứ rồi mà bạn vẫn chán thì thử đổi luôn cả góc làm việc xem sao. Trước ngồi code thì quay mặt vào tường, giờ ngồi code quay mặt ra cửa sổ, mua một chậu sen đá, hay mấy cuốn sách mà bạn thích để trên bàn làm việc,… Nói tóm lại là làm bất cứ thứ gì để cái góc làm việc của bạn nó khác những ngày trước.
3.5 Đổi nghề
Đùa đấy… đừng đổi.
6. CODE TRÊN BÀN PHÍM CƠ
Bàn phím cơ đem lại trải nghiệm gõ sướng hơn hẳn bàn phím thông thường. Bàn phím cơ có nhiều loại, có loại thì tập trung vào việc giảm tiếng ồn khi gõ, nhưng cũng có loại lại tập trung vào việc “tạo thêm tiếng ồn” (tiếng tích tích) khi gõ, nói chung là tùy sở thích mỗi người. Nhưng chúng có đặc điểm chung cảm giác gõ nảy, êm, và rất bền, phù hợp với các anh em có thói quen code cục súc, nhất là những pha fix bug và chốt hạ bằng phím enter sẽ đã hơn.
Trong lúc viết bài này, mình cũng đang có ý định sắm một em bàn phím cơ để đổi trải nghiệm viết code, tiện chia sẻ với các bạn một số kinh nghiệm luôn nhé:
Bàn phím cơ có nhiều layout phím khác nhau, giá tiền cũng phụ thuộc nhiều vào layout phím, khi mua nhớ nhìn kỹ, đừng thấy giá rẻ mà lao vào, kẻo mua về code hỏng tay đó.
Nếu có điều kiện, nên chọn bàn phím không dây hơn là có dây.
Bàn phím cơ không dây không có giá dưới 1tr, bàn phím cơ có dây không có giá dưới 500k (giá theo năm 2020).
Đừng ham rẻ, nếu mua hãy chuẩn bị ngân sách khoảng 1tr500.
Không phải bàn phím cơ nào cũng có đèn led.
Một hãng phím cơ giá hợp lý mà chất lượng lại tốt được rất nhiều người lựa chọn là Keychron.
7. LỜI KẾT
Tạo cảm giác code thú vị hơn sẽ trực tiếp tăng hiệu quả công việc của bạn, vậy thì ngại gì mà không áp dụng thử mấy mẹo trên nhỉ. Biết đâu hiệu quả cao, lại được tăng lương thì sao.
Tạm kết ở đây, chào tạm biệt các bạn, mình đi hít đất đây, vì hôm nay code nhiều bug quá.
Trong lúc lầm Progressive Web App (PWA), chúng ta cần nhớ những điều sau
Không quan trọng user đang dùng trình duyệt gì
Hỗ trợ tốt trên nhiều loại thiết bị desktop, mobile, tablet bằng responsive
Sử dụng service worker để có thể làm việc offline hoặc khi mạng chậm
Có khả năng cài đặt, sử dụng web app manifest và sự kiện beforeinstallprompt để báo user biết có thể install
Ứng dụng sẽ thực hành là trang dự báo thời tiết
Chúng ta sẽ tìm hiểu các vấn đề Làm sao để tạo và thêm file web app manifest Cung cấp một trải nghiệm cơ bản khi không có mạng Làm sao để làm cho app có thể install Bạn cần gì để follow tuts này
Phiên bản mới nhất của Chrome
Kiến thức căn bản HTML/CSS/Javascript và Chrome DevTools
Đăng ký Dark Sky API để có 1 API key, dữ liệu thời tiết sẽ do API này cung cấp
Sao khi đã có 1 API key, chúng ta có thể kiểm tra xem nó có hoạt động hay không bằng cách mở URL này trên trình duyệt
Trước tiên chúng ta đánh giá sơ bộ trang hiện tại bằng công cụ Lighthouse có sẵn của Chrome. Trên DevTool sẽ có một tab là Audit ở cuối. Nó sẽ cho kết quả đánh giá performance, accessibility, PWA và một số thứ linh tinh khác nữa
Để chạy đánh giá 1. Mở DevTool lên, chọn vào Audits tab 2. Dùng tất cả các thiết đặt mặc định nếu ko có ý kiến gì khác 3. Click Run audit, đợi chút nó sẽ cho kết quả
Chúng ta tập trung fix mấy cái bị báo đỏ
Thêm web app manifest
Nó là một file JSON cho phép chúng ta config một số thứ khi xuất hiện trên thiết bị của user
Mở cửa sổ mới hay không display
Trang mặc định sẽ mở (nếu bạn không muốn là trang index) start_url
Icon sẽ hiển thị icons
Tên short_name
Splash screen name, icons, colors
Mở ngang hay dọc orientation
Tạo một file public/manifest.json rồi copy nội dung sau vào đó
Nếu cửa số Audit PWA có thông báo “Does not set an address-bar theme color”, chọn màu thanh address cho phù hợp với màu thương hiệu
<meta name="theme-color"content="#2F3BA2"/>
Offline mức căn bản
Bạn có thể tắt mạng, sau đó mở trang google drive, bạn sẽ thấy vẫn xem được danh sách file, folder trong drive, tất nhiên không mở xem chỉnh sửa mấy file này được, nhưng vẫn đảm bảo có những trải nghiệm “không quá tệ”
Service worker chỉ chạy trên trang web truy cập qua giao thức https
Những tính năng mà service worker cung cấp, câng nhắc nó như một dạng “nice-to-have”, đừng quá đặt nặng và xem service worker như đấng cứu thế, và cũng đừng chém xuyên lục địa về những tính năng siêu việt của service worker.
Service worker có scope (phạm vi hoạt động) theo vị trí file, nghĩa là nếu nhét nó vào file rồi đưa file này trong thư mục con scripts nó sẽ không can thiệp được gì những đoạn script nằm ngoài thư mục gốc, nếu đặt ở thư mục gốc, toàn bộ thư mục con sẽ kế thừa được service worker đăng ký ở thư mục gốc
Cache cái gì? Chúng ta có 1 file là public/offline.html, nếu không có mạng, chúng ta sẽ hiển thị file này, cache file này xuống trình duyệt là hợp lý.
// thêm xử lý sự kiện fetchif(evt.request.mode!=='navigate'){return;}
evt.respondWith(fetch(evt.request).catch(()=>{return caches.open(CACHE_NAME).then((cache)=>{return cache.match('offline.html');});}));
Nó giống như khái niệm middleware, incepter của axios vậy thôi.
Đưa đoạn fetch vào bên trong evt.respondWith() sẽ chặn trình duyệt tự ý đi mà không nói với ai, chúng ta sẽ dùng người trung gian để đi nói chuyện với thế giới. Nếu không sử dụng evt.respondWith() thì cache trước đó sẽ chẳng có tác dụng vì hết.
Bên dưới của tab Application, sẽ cho biết những gì đã được cache lại bên dưới trình duyệt
Để giả lập tình trạng mất mạng, quay lại Service workers, click chọn vào checkbox Offline. F5 nếu thấy hình em gấu này là coi như thành công.
Trên cửa sổ Service Workers có một số option khác ngoài Offline
Update on reload luôn luôn load lại service worker khi reload
Bypass for network bỏ qua service worker, chạy như không có
Trên điện thoại có thể dùng chế độ máy bay để tắt mạng và xem trang web nó sẽ ra hình thù thế nào.
Service worker life cycle
install
Sự kiện này sẽ bắn ra khi worker chạy, và chỉ được tạo ra một lần cho mỗi service worker
Thông thường nó được sử dụng để cache mọi thứ cho app
activate
Sau khi install, mỗi lần nó khởi động nó sẽ bắn ra sự kiện activate, tức là bạn truy cập lại trang web đã vào trước đó. Được dùng để xóa cache trước đó
fetch
Sự kiện này cho phép chúng ta can thiệp vào mọi network request, trước khi ra khỏi nhà, phải trình báo ở đây
Ở trên chúng ta chỉ hiển một trang HTML, thông báo với user là mày đang offline, giờ chúng ta sẽ cho nó thấy cái như là có mạng luôn, giống như khi bạn vào Google Drive lúc ko có mạng đó.
Quay lại với ví dụ, app chúng ta sử dụng object caches bên trong window, tuy nhiên không phải browser nào cũng hỗ trợ window.caches, chúng ta sẽ update hàm getForecastFromCache để rơi vào tình huống đó, vẫn ko ảnh hưởng gì tới app
// kiểm tra trước khi thực hiện những việc tiếp theoif(!('caches'inwindow)){returnnull;}const url =`${window.location.origin}/forecast/${coords}`;return caches.match(url).then((response)=>{if(response){return response.json();}returnnull;}).catch((err)=>{console.error('Error getting data from cache', err);returnnull;});
App sẽ gọi lấy dữ liệu từ 1 trong 2 hàm, thông qua cache hoặc fetch từ API. Với dữ liệu trả về, chúng ta sẽ xử lý để render lại giao diện nếu cần thiết
Vì danh sách mấy file này chúng ta thêm bằng tay, nếu sao này chúng ta thay đổi danh sách file này, phải sửa tay tên CACHE_NAME, ví dụ như từ
constCACHE_NAME='static-cache-v2';// đổi khi thay đổi danh sách file muốn cacheconstCACHE_NAME='static-cache-v3';
Nếu chỉ sửa mỗi cái tên file cũng phải đổi lại tên cache thì quá tốn công, chưa kể phía user phải down lại toàn bộ resource. Workbox do google phát triển sẽ giải quyết dùm chúng ta vấn đề này, trong quá trình build, chỉ những file nào đã thay đổi mới cần update phía người dùng
Để đảm bảo trong quá trình activate, nó ko vô tình xóa dữ liệu của chúng ta, bên trong hàm bắt sự kiện activate
public/service-worker.js
if(key !==CACHE_NAME&& key !==DATA_CACHE_NAME){
Trong sự kiện fetch của service worker, chúng ta cũng thực hiện cập nhập, chúng ta luôn ưu tiên lấy data từ API trước, chỉ khi ko thể gọi được API, chúng ta mới lôi thằng cache ra xài
if(evt.request.url.includes('/forecast/')){console.log('[Service Worker] Fetch (data)', evt.request.url);
evt.respondWith(
caches.open(DATA_CACHE_NAME).then((cache)=>{returnfetch(evt.request).then((response)=>{// nếu lấy được data từ API, xài luôn và lưu xuống cache một bảnif(response.status===200){
cache.put(evt.request.url, response.clone());}return response;}).catch((err)=>{// lỗi network thì đưa về cachereturn cache.match(evt.request);});}));return;}
evt.respondWith(
caches.open(CACHE_NAME).then((cache)=>{return cache.match(evt.request).then((response)=>{return response ||fetch(evt.request);});}));
Chúng ta bỏ phần điều kiện evt.request.mode !== 'navigate' vì không chỉ muốn lấy cache cho network request, chúng ta muốn cache mọi thứ từ HTML, CSS, script, image,…
Giờ gần như chúng ta đã đưa hết những gì cần thiết xuống cache, kiểm tra xem kết quả trên DevTool đã cache thành công chưa nhé
Thêm phần cài đặt
App thì phải cài đặt được chứ, chúng ta sẽ thêm một nút cho phép user “Cài đặt” vào màn hình điện thoại luôn
User nào thông minh như mình thì sẽ biết cách vào menu của Chrome (hoặc Safari) rồi chọn Add to Homescreen, tuy nhiên đâu ai thông minh như mình đâu!
deferredInstallPrompt.userChoice.then((choice)=>{if(choice.outcome==='accepted'){console.log('User accepted the A2HS prompt', choice);}else{console.log('User dismissed the A2HS prompt', choice);}
deferredInstallPrompt =null;});
Khi thêm vào màn hình chính thành công, hay gọi hoa mỹ là Cài đặt thành công, trình duyệt bắn tiếp một sự kiện khác, chúng ta có thể túm lấy sự kiện này và thông báo gì đó nếu thích
Bài viết được sự cho phép của tác giả Trần Anh Tuấn
Khi học HTML, CSS chắc các bạn sẽ gặp nhiều vấn đề, đang muốn thử một tính năng rất gì và này nọ cơ mà đăng lên nhóm hỏi mọi người thì không biết làm sao ngoài cách phải upload code lên một đống nhìn rối não, người ta vào đọc chẳng muốn thèm giúp chút nào luôn.
Ngồi nghiên cứu tìm tòi thì thấy có các trang cho phép code online và chạy trên đó luôn, hỗ trợ đầy đủ các ngôn ngữ về Frontend như HTML CSS SASS LESS JavaScript, thư viện các kiểu với giao diện dễ nhìn, dễ sử dụng và tiện lợi nữa. Và nổi bật một trong số các trang code online đó chính là Codepen.
# Codepen là gì?
CodePen là một nền tảng phát triển code online. Nó cho phép bạn viết code trong trình duyệt và xem kết quả online. Một trình soạn thảo code online hữu ích tập trung chủ yếu vào các ngôn ngữ về phía Frontend như HTML, CSS, JavaScript và các thư viện cũng như các Preprocessing như Sass, Less, TypeScript để hỗ trợ cho các ngôn ngữ đó.
# Hướng dẫn tạo tài khoản miễn phí
Để tạo tài khoản, các bạn truy cập vào trang codepen.io rồi sau đó các bạn nhấn vào nút Sign Up như hình
Sau đó các bạn có thể đăng ký tài khoản với các trang mạng xã hội như Twitter, Facebook hay là Github hoặc là đăng ký với Email cũng được.
Việc đăng ký rất là đơn giản, nếu các bạn đăng ký với các trang mạng xã hội thì cấp quyền là xong, rồi tự động đăng nhập luôn sau đó. Còn nếu các bạn đăng ký với Email thì các bạn sẽ điền các thông tin như là Name, Email, Username và Password vào rồi sau đó nhấn Submit là được.
Sau đó nó sẽ hiện ra trang thông tin cho phép các bạn nhập địa chỉ ,giới thiệu và ảnh avatar. Các bạn có thể cập nhật hoặc không cũng không sao rồi sau đó nhấn Save and Submit để hoàn thành.
Để tạo một Pen mới các bạn nhấn vào chữ Pen như hình
lúc này ta sẽ được một giao diện mới như hình gồm các tab chính là HTML, CSS và JS. Nút Save để lưu, nút Setting để thiết lập các cài đặt, nút Change View để đổi cấu trúc giao diện code, bên trái là icon bút chì để sửa tiêu đề của Pen.
Ở Codepen khi các bạn code HTML thì chỉ đơn giản code những thứ trong thẻ body là được không nhất thiết phải lôi cả cấu trúc HTML khi code dưới máy vào như thẻ html, head, body, script… Muốn chèn script vào hay fontawesomebootstrap thì các bạn nhấn vào nút Setting, sau đó gõ thư viện bạn muốn vào khung tìm kiếm rồi chọn sau đó nhấn Save & Close là được.
Các bạn muốn code SCSS, LESS trong CSS hay PUG trong HTML hoặc TypeScript trong JS thì các bạn cũng vào Setting rồi chọn mục tương ứng như HTML, CSS và JS lần lượt là
Ngoài ra còn có tab Behavior ở đây cho phép các bạn thiết lập sử dụng Tabs hay là Spaces tuỳ theo cách code của mỗi người. Và còn có thêm 2 lựa chọn khác là Autosave nghĩa là tự động lưu khi các bạn đang code và Auto-Updating Preview nghĩa là khi các bạn code tới đâu UI nó sẽ cập nhật tới đó ví dụ code thẻ p {color: red;} thì lập tức UI có thẻ p sẽ đổi sang đỏ ngay lập tức.
Ngoài ra còn có các thiết lập khác như là chỉnh kiểu chữ khi code, các theme hiển thị cho đẹp, dark hay là light theme, kích thước chữ, emmet khi gõ nhấn tab sẽ tự động sinh ra code… Các bạn có thể thiết lập bằng cách nhấn vào Avatar sau đó chọn mục Setting sẽ ra trang như hình dưới đây. Các bạn có thể tuỳ chỉnh tuỳ thích hoặc để thiết lập mặc định cũng được nhé.
Sau khi các bạn code xong một Pen và lưu lại thì để xem danh sách các Pens mà các bạn đã làm thì các bạn vào mục Dashboard nhé. Nó sẽ hiển thị ra danh sách cho các bạn như dưới đây
Ngoài ra sau khi các bạn code xong, các bạn muốn chia sẻ cho người khác xem thì các bạn copy đường dẫn phía trên thanh url có dạng codepen/username/sdaffjiuewrkjlz rồi đem đi chia sẻ là xong. Dưới đây là một ví dụ về Codepen mà mình code để các bạn tham khảo nha.
# Kết luận
Như vậy là mình đã nói sơ qua về Codepen cho các bạn cũng như hướng dẫn cho các bạn cách đăng ký tài khoản với Codepen, giới thiệu sơ về khả năng mạnh mẽ của Codepen là gì, cách tạo một Pen đơn giản cũng như là các thiết lập của nó. Hi vọng với những kiến thức cơ bản này sẽ giúp ích cho các bạn trong định hướng trở thành 1 Frontend-Developer thực thụ nhé.
Một chiến lược về tuyển dụng được hình thành trên nhiều khía cạnh. Một trong số đó chính là nội dung gắn với truyền thông (Recruitment Marketing).Nhưng làm thế nào để những nội dung trở nên độc đáo? Đâu là những nguyên tắc cần phải nắm bắt khi sáng tạo nội dung nhằm thu hút ứng viên? Cùng TopDev theo dõi bài viết sau để bỏ túi những ý tưởng sáng tạo nội dung hiệu quả nhất!
3 Nguyên tắc cần lưu tâm khi sáng tạo nội dung
Đây cũng được xem là 3 nguyên tắc cốt lõi để sáng tạo nội dung tuyển dụng.
Hiểu rõ về đối tượng
Bạn cần biết rõ về ứng viên trước khi lập kế hoạch xây dựng nội dung. Để nội dung đạt hiệu quả hoàn hảo, cách duy nhất là xác định trước chân dung điển hình của các ứng viên tiềm năng.
Tập trung vào ứng viên
Hãy đi tìm lời giải cho câu hỏi: “Nội dung bạn thực hiện sẽ mang lại những gì?”. Và đừng quên thử đặt mình vào vị trí các ứng viên. Hiểu được những thách thức về mặt sáng tạo giúp bạn biết đâu là nội dung mà các hình mẫu ứng viên lý tưởng sẽ bị thu hút.
Trung thực và chân thành
Đừng chỉ cố truyền tải thông điệp nội dung thông qua các logo. Thay vào đó, những hình chân thật của nhân viên và môi trường làm việc có thể tạo ra sức hút nhiều hơn. Vì đơn giản, mọi đặc trưng về văn hóa doanh nghiệp sẽ được thể hiện rất rõ.
4 ý tưởng nội dung Recruitment Marketing sáng tạo nhất
Tạo ra nội dụng sáng tạo là điều cần thực hiện. Dưới đây là 4 ý tưởng được nhiều doanh nghiệp lựa chọn cho chiến lược sáng tạo nội dung của tổ chức của mình.
Idea No.1 – Infographic
“Only text” mang lại những hiệu quả cơ bản trong việc truyền tải nội dung. Tuy nhiên, dù cho content có hay thì để đảm bảo được một sức hút tương đối thì nó còn hạn chế.
Bạn vẫn có thể phát triển cách tiếp cận ứng viên “thuần nội dung”. Nhưng nếu được, đừng ngại đầu tư đôi chút cho chính doanh nghiệp của mình. Hãy chú trọng nhiều hơn đến tính trực quan – Infographic.
“Chăm” cho nội dung tuyển dụng dưới một bản trình bày đầy sinh động là cách thức tạo ấn tượng sâu đậm nhất đối với các ứng viên. Với chỉ vài biểu tượng thú vị hơn, nội dung tuyển dụng của công ty bạn sẽ “ăn đứt” dạng checklist truyền thống đấy!
Idea No.2 – Video Recruitment
Video được xem là một hình thức hiệu quả trong việc tiếp cận ứng viên. Thương hiệu nhà tuyển dụng có tăng được độ nhận diện hay không, một phần lớn cũng nhờ sức lan tỏa từ các thông điệp về nội dung mà các video mang lại.
Thông qua hình thức thiết lập video, nhà tuyển dụng có thể cung cấp các thông tin tuyển dụng đến ứng viên đang tìm việc. Tuy nhiên, hãy thật sự khéo léo và đảm bảo tính cân bằng thông tin. Nội dung cần được xây dựng một cách dễ hiểu để ứng viên không cảm thấy bị “ngán”.
Nhiều hình thức video đa dạng mà các tổ chức có thể thực hiện: Update video tuyển dụng lên website, để chúng dưới dạng podcast, dẫn link; hoặc liên kết trực tiếp với Youtube của công ty, các Social Media Channel.
Idea No.3 – Slideshare
Nhiều người nghĩ rằng Slideshare là một hình thức chưa chuyên dụng và lỗi thời. Họ không đánh giá cao Slideshare. Và chỉ xem nó như một hình thức truyền tải nội dung thiếu chuyên nghiệp. Song, thực tế cho thấy, Slideshare vẫn là một trong những lựa chọn tốt nhất của các doanh nghiệp. Nó hữu ích và mang lại nhiều giá trị tuyệt vời hơn bạn nghĩ.
Slideshare nhấn mạnh sự truyền tải trực quan nhằm tạo ra sự tương tác đa chiều. Đồng thời, ứng viên hoàn toàn có thể chỉa sẻ thông tin về tuyển dụng cho nhau.
Hãy thiết lập một slideshare, cho nó những điểm nhấn khi đặt nó ở vị trí trung tâm trang truyển dụng hoặc những nơi tiềm năng nhất.
Idea No.4 – Career Blog
Career Blog thật sự là một ý tưởng tuyệt vời cho việc truyền tải các nội dung về tuyển dụng (Recruitment Marketing).
Blog nghề nghiệp được xem như một khía cạnh khác đầy tính thú vị hơn. Trên blog, doanh nghiệp có thể phát triển nội dung theo định hướng (Content Direction). Từ đó thiết lập các chủ đề (Topic) khác nhau. Đó có thể là:
Hướng nghiệp, đào tạo (Career guidance – Training)
Kiến thức chuyên môn các lĩnh vực (Specialist Knowlegde)
Phỏng vấn (Interview)
Các kỹ năng cần thiết trên hành trình tìm việc của ứng viên (Skills of candidate journey)
Mỗi Career blog được đều phải dựa trên nguyên tắc nền tảng là mối quan tâm của chính độc giả (tức ứng viên). Doanh nghiệp hoàn toàn có thể thu hút được nguồn ứng viên tiềm năng khi có sự chăm chút kỹ lưỡng cho Career blog của mình.
Lời kết
Hãy đảm bảo rằng doanh nghiệp của bạn hiểu rõ nguyên tắc cốt lõi của Recruitment Marketing. Việc nắm bắt sâu sắc có ý nghĩa quan trọng trong việc tạo ra các nội dung mang đậm dấu ấn của tổ chức. TopDev hy vọng bài viết sẽ cho người đọc những thông tin bổ ích về các idea sáng tạo nội dung. Hãy linh hoạt và vận dụng chúng vào qua trình tạo ra sự thu hút đối với ứng viên. Đồng thời gia tăng sức cạnh tranh về khía cạnh tuyển dụng nhân sự trên thị trường lớn.
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