Lập trình IOS: Triển khai MVVM cho project swift (phần 5)
Bài viết được sự cho phép của tác giả Lê Xuân Quỳnh
Xin chào! Trong bài hôm trước chúng ta đã viết xong lớp base để xử lý realm database rồi. Và bài hôm nay chúng ta sẽ tiến hành viết các service kế thừa từ lớp này để sử dụng realm database 1 cách linh hoạt.
Lớp RealmGithubService của chúng ta sẽ có nhiều vụ sau:
Lưu trữ kết quả từ server trả về, cụ thể model GithubSearchResponse
Vì với mỗi keyword sẽ có 1 response khác nhau, đồng thời mỗi keyword này tùy vào số page gửi lên mà 1 kết quả khác nhau. Do vậy chúng ta cần lưu response này với khóa chính kết hợp giữa keyword và page
Lấy response đã lưu dựa vào keyword đã search và page tương ứng
Từ những phân tích trên, chúng ta tiến hành tạo 1 protocol như sau:
Tôi đã đặt tên sát với từng ý mà tôi đã phân tích ở trên. Tuy nhiên để model GithubSearchResponse tích hoạt realm thì chúng ta cần sửa đổi nó. Hãy cùng xem lớp này có gì nhé:
Lớp GithubSearchItem
Đầu tiên là lớp GithubSearchItem:
Dòng 49 tôi sử dụng @objcMembers để chỉ định rằng toàn bộ class này có thể truy cập được từ objective-C. Lý do mà tôi làm vậy vì realm được code từ C++, nên nó cần cho phép objective-C truy cập. Thông thường, C++ không thể truy cập trực tiếp vào swift, mà phải thông qua Objective-C. Cũng như bên java muốn truy cập được C++ thì cần JNI vậy Sau này bạn nhận ra 1 điều là bạn cũng có thể truy cập React native từ swift thông qua Objective-C.
Tôi muốn class GithubSearchItem vừa có thể dùng để nhận kết quả từ API, vừa có thể dùng nó như realm. Tham lam thật, nhưng chúng ta sẽ làm được điều đó bằng cách chỉnh sửa làm sao nó có thể hoạt động đồng thời cả với realm và codable.
dynamic var: Các cột trong bảng của realm bắt đầu bằng từ khóa này. Mỗi 1 thuộc tính là 1 cột. Ở đây tôi tạo ra 4 cột để lưu các thuộc tính này vào bảng của realm, gồm id, name, htmlURL, itemDescription.
override class func primaryKey: Hàm trả về khóa chính cho bảng. Một bảng có thể có khóa chính hoặc không nên hàm trả về kiểu optional. Tuy nhiên tôi muốn bảng này phải có khóa chính để sau này cập nhật. Trong SQL, khóa chính là tồn tại để định danh từng dòng trong bảng, duy nhất và khác nhau giữa các dòng. Realm cũng hoạt động tương tự. Ở đây ta thấy id có các tính chất như vậy nên ta chọn làm khóa chính.
required init(from decoder: Decoder) throws: Hàm dịch response của API thành object codable. Hàm này có mục đích là để mỗi khi decode xong json -> object, thì tôi tạo luôn realm cho object này. Chính là ở dòng này:
Tạo realm sau khi decode xong
Do vậy bạn có thể dùng cả codable và Object của realm. Xịn chưa
extension cho codable tương ứng với mỗi thuộc tính và key response tương ứng.
Tiếp theo chúng ta sẽ xem xét class GithubSearchResponse, chứa class GithubSearchItem trên:
class GithubSearchResponse
Tương tự, class này cũng chứa các thuộc tính có thể thao tác với realm nên ta define nó là @objcMembers
Ở đây, vì nó chứa list GithubSearchItem. Chúng ta bắt buộc phải sử dụng RealmSwift.List vì realm không hỗ trợ array thông thường của swift.
Ở đây tôi custom 1 khóa chính tên là keyword. Lý do là class này chưa có khóa chính, và vì với mỗi GithubSearchResponse trả về. Do đó tôi sẽ nghĩ ngay nó là khóa chính. Thứ 2 khóa chính này phụ thuộc vào page gửi lên, do vậy khóa chính sẽ là gộp của keyword và page.
Các extension và hàm init tương tự class GithubSearchItem
Vậy là bạn đã hoàn thành xong lớp GithubSearchResponse đảm bảo có thể lưu vào realm database. Việc của chúng ta tiếp theo là viết lớp RealmGithubService.
Định nghĩa lớp RealmGithubService
Như tôi đã trình bày ở bài trước, thì mọi class muốn kế thừa từ lớp RealmManager, đều phải khóa chính uid để có thể cập nhật hay xóa được. Do vậy bạn sẽ thấy đoạn code sau:
Tiếp theo, lớp RealmGithubService kế thừa các hàm của RealmGithubServiceProtocol, chúng ta sẽ định nghĩa các hàm này theo logic của app.
saveRepositoryResponse: Hàm này lưu response vào database. Trước khi lưu bạn cần gán keyword để làm khóa chính cho nó:
repoList.keyword = keyword
getRepositoryResponse: Hàm này sẽ tiến hành query toàn bộ model trong realm database, sau đó tìm model nào có keyword bằng keyword truyền vào, lấy thằng đầu tiên(first) và trả về.
deleteRepositoryResponse: Hàm xóa respone theo keyword. Tôi lấy model có khóa chính là keyword xong gọi hàm xóa. Rất đơn giản!
deleteAllRepositoryResponses: Xóa toàn bộ model GithubSearchResponse trong database
Ở đây tôi tạo class singleton. Nó đảm bảo trong 1 thời điểm chỉ có duy nhất 1 lớp có thể truy cập tới RealmGithubService.
Mọi thứ đã gần xong, giờ bạn hãy làm 1 cốc cà phê, ra ban công ngắm nhìn phố phường rồi tiếp tục sau nhé.
Chỉnh sửa GithubViewModel
Bây giờ chúng ta hãy tiến hành chỉnh sửa view model này. Hãy xem xét hàm requestRepositories đã có.
Mỗi khi tiến hành request API, chúng ta cần kiểm tra xem kết quả với từ khóa đó đã tồn tại trong database hay chưa bằng dòng code sau:
Ở đây bạn sẽ dùng hàm RealmGithubService.shared.getRepositoryResponse(with: keyword) để lấy response tương ứng với keyword gồm language + page. Nếu như nó đã tồn tại thì tiến hành các logic bình thường như sau khi API đã trả về kết quả. Còn nếu không, chúng ta sẽ tiến hành request API như bình thường. Tôi có dùng hàm print(“from local”) để đánh dấu việc lấy data từ databse, print(“from network”) để đánh dấu lấy data từ server.
Khi request các bạn sẽ thấy log ở Xcode như sau:
Thật tuyệt vời, bạn hãy thử tắt luôn mạng internet để check cho chắc cú là nó đã lấy data từ realm nha. Tôi chỉ đùa vậy thôi!
Okey, finally vậy là mọi thứ đã xong. Giờ đây bạn có thể tạo 1 ứng dụng cho phép sử dụng offline như facebook, không cần kết nối internet vẫn có thể thao tác với dữ liệu cũ, để tăng tính trải nghiệm người dùng, làm cho ứng dụng của bạn chuyên nghiệp hơn. Ứng dụng của chúng ta còn đơn giản, chưa nhiều logic phức tạp. Xong chắc hẳn tôi nghĩ bạn cũng đã hiểu được phần nào các làm 1 ứng dụng offline rồi phải hông? Và các bạn thấy được các tiện ích mà realm mang lại. Xin chào và hẹn gặp lại!
Bài viết được sự cho phép của tác giả Kien Dang Chung
Nội dung là phần quan trọng nhất của trang HTML, đây chính là phần người dùng có thể đọc được khi xem các trang web trên trình duyệt. Trong nội dung trang HTML có thể có rất nhiều các thành phần như các tiêu đề, các đoạn nội dung, hình ảnh, liên kết, các bảng thông tin… Trước khi bắt đầu tìm hiểu kiến thức các thành phần của nội dung trang HTML bạn cần nắm được cấu trúc chung của một trang HTML, vì trong bài viết này chúng ta sẽ xoay quanh nội dung nằm trong thẻ . Các thẻ HTML được giới thiệu trong bài viết này phần lớn đã có từ các phiên bản trước HTML5, chúng thường xuyên được sử dụng vì vậy bạn cần ghi nhớ chúng.
Tiêu đề là những dòng văn bản đầu tiên bạn đọc được, nó rất quan trọng trong nội dung trang web. Một tin tức có được người dùng nhấp vào xem chi tiết hay không là ở tiêu đề. Trong HTML tiêu đề được chia thành 6 cấp độ: h1, h2, h3, h4, h5, h6. Tiêu đề h1 sẽ là quan trọng nhất và mức độ quan trọng sẽ giảm dần cho đến h6.
Mỗi thẻ tiêu đề có một kích thước mặc định khác nhau, thẻ h1 có kích thước chữ là lớn nhất và h6 là nhỏ nhất. Bạn có thể thay đổi kích thước chữ mặc định này bằng cách thiết lập thuộc tính CSS font-size thông qua thuộc tính style của thẻ tiêu đề.
6 thẻ trong kết quả trông giống nhau, nhưng đấy là bạn đứng ở góc độ người xem, còn các bộ máy lọc và phân tích nội dung thì khác, chúng nhìn thấy sự khác nhau của 6 tiêu đề. Tiêu đề trong HTML là rất quan trọng Tiêu đề gần như là một mô tả ngắn gọn nhất, súc tích nhất cho toàn bộ nội dung phía sau. Chính vì vậy các tiêu đề thường ngắn và nên trong khoảng 70 ký tự để giúp cho các bộ máy tìm kiếm như Google chẳng hạn hiển thị tốt nhất trên kết quả tìm kiếm. Trong một trang web chỉ nên có duy nhất một thẻ h1, điều này cũng dễ hiểu thôi, cái gì cũng là quan trọng nhất thì không có gì là quan trọng cả.
2. Đoạn văn bản trong HTML
Trong một văn bản thường chúng ta trình bày thành nhiều đoạn khác nhau với nội dung được tách ra nhằm giúp người đọc nhanh chóng nắm bắt được nội dung của cả văn bản. Thẻ <p> (paragraph) được sử dụng để tạo ra các đoạn văn bản.
<h1>Thẻ p trong HTML</h1><p>Thẻ p sử dụng để tạo ra các đoạn văn bản trong nội dung. Với các văn bản dài, việc tách ra thành các đoạn văn bản giúp cho người đọc dễ dàng nắm bắt được nội dung tổng thể.</p><p>Trong một trang HTML có thể có nhiều thẻ p, các thẻ p được mặc định cách nhau một khoảng giúp cho việc tìm đoạn văn bản dễ dàng.</p>
[jsfiddle url=”https://jsfiddle.net/allaravel/57t5u2c8/” height=”300px” include=”result,html,js” font-color=”39464E” menu-background-color=”FFFFFF” code-background-color=”f3f5f6″ accent-color=”1C90F3″] Khi sử dụng thẻ
có một số chú ý:
Các khoảng trống nhiều hơn 1 khoảng trống sẽ thay thế bởi một khoảng trống.
Các dòng trống sẽ được bỏ qua.
Như vậy nếu bạn có ý định trình bày một bài thơ thì không thể viết theo kiểu như thế này được:
<h1>Cháu ngoại họ Cao</h1><p>
Thằng này nó rất là ngoan
Học hành chăm chỉ lại toàn điểm cao
Ông bà thì rất tự hào
Có thằng cháu ngoại họ Cao lại lùn
</p>
vì toàn bộ các khoảng trống lớn hơn 1 ký tự trống được đưa về thành 1 ký tự trống, các ký tự xuống dòng cũng được loại bỏ. Trong HTML nếu bạn muốn xuống dòng, bạn sẽ phải sử dụng thẻ <br>(break). Chúng ta cùng điều chỉnh lại đoạn code bài thơ trên xem thế nào?
<h1>Cháu ngoại họ Cao</h1><p>
Thằng này nó rất là ngoan<br>
Học hành chăm chỉ lại toàn điểm cao<br>
Ông bà thì rất tự hào<br>
Có thằng cháu ngoại họ Cao lại lùn<br></p>
Ngoài ra, HTML có thẻ <pre>, nó sẽ hiển thị văn bản nguyên trạng mà không bị định dạng lại như thẻ <p>, thẻ <pre> mặc định dùng font chữ Courier.
<h1>Cháu ngoại họ Cao</h1><pre>
Thằng này nó rất là ngoan
Học hành chăm chỉ lại toàn điểm cao
Ông bà thì rất tự hào
Có thằng cháu ngoại họ Cao lại lùn
</pre>
Danh sách là một thành phần dùng rất thường xuyên trong nội dung, nó có thể là mục lục bài viết, danh sách các tính năng… Danh sách được chia thành ba loại:
Danh sách không sắp xếp
Danh sách sắp xếp
Danh sách tự định nghĩa
4. Định dạng văn bản trong HTML
Văn bản khi được hiển thị thông thường sẽ khó đọc hơn, đặc biệt khi có những đoạn cần nhấn mạnh, những đoạn hội thoại hay trích dẫn… Định dạng lại văn bản giúp cho người đọc hiểu nội dung tốt hơn, nhanh hơn. Trong các nội dung HTML để định dạng văn bản có hai cách:
Định dạng văn bản bằng CSS
Sử dụng các thẻ HTML được cung cấp sẵn để định dạng
Trở lại khái niệm về CSS, bạn đã được giới thiệu sơ qua về ngôn ngữ giúp “trang điểm” thêm cho nội dung website trong bài Giới thiệu về HTML. Các kiến thức về CSS là khá nhiều và chúng ta sẽ nghiên cứu một cách chi tiết trong Khóa học CSS3 cơ bản sẽ được phát hành trong thời gian tới.
Trong khuôn khổ về kiến thức HTML, chúng ta sẽ liệt kê các cách thức định dạng văn bản bằng CSS mà không đi vào chi tiết. Có 3 cách để định dạng văn bản bằng CSS:
Sử dụng thuộc tính style để định dạng từng thẻ HTML cụ thể (cách này còn gọi là inline CSS).
Sử dụng thẻ HTML style để định dạng chung cho cả trang web (internal CSS).
Liên kết đến một file CSS ở ngoài thông qua thẻ HTML link (external CSS).
Lựa chọn cách thức định dạng nào tùy thuộc từng tình huống, có thể sử dụng đồng thời nhiều cách thức với nhau. Nếu bạn thiết kế website từ đầu thì nên sử dụng các thẻ HTML kết hợp với liên kết file CSS từ bên ngoài, cách này có nhiều lợi điểm:
Cung cấp thêm ngữ nghĩa cho các bộ máy tìm kiếm, giúp có thứ hạng cao hơn trong kết quả tìm kiếm của Google, Cốc cốc…
Tăng hiệu năng do trình duyệt sẽ lưu lại file CSS trong bộ nhớ riêng giúp tăng tốc tải trang web và nhanh hơn khi render trang.
Mã CSS dễ kiểm soát hơn và đơn giản khi chỉnh sửa, bảo trì mã nguồn.
Nếu bạn chỉnh sửa nhanh một website mà chưa nắm rõ về cấu trúc tổng thể thì cách Inline CSS là một lựa chọn tốt, cần chú ý Google khuyến cáo là không nên sử dụng Inline css bởi nó gây ra dư thừa code không cần thiết.
4.1 Định dạng văn bản với CSS
Ngôn ngữ CSS mang lại màu sắc và kiểu cách cho nội dung HTML, cách sử dụng CSS khá đơn giản, nó bao gồm một cặp thuộc tính CSS:giá trị CSS (property:value).
Ví dụ: color:blue sẽ thiết lập màu xanh cho các thẻ HTML được lựa chọn, font-family: arial thiết lập font chữ Arial cho các thẻ HTML được lựa chọn.
Chú ý: Kiến thức về CSS khá nhiều vấn đề, trong thời lượng một bài của Khóa học HTML5 cơ bản không thể giới thiệu hết do vậy, có những phần bạn sẽ hơi khó hiểu chút, nhưng không sao các kiến thức này sẽ được giới thiệu trong Khóa học CSS3 sắp tới.
4.1.1 Định dạng văn bản với thuộc tính style trên thẻ HTML – Inline CSS
Cú pháp định dạng văn bản với thuộc tính style như sau:
<tagname style="property:value;">
Trong đó:
tagname: Thẻ HTML cần định dạng, có thể là thẻ <h1>, .., <h6>, <p>, <a>…
property: thuộc tính CSS
value: giá trị CSS
Chúng ta thường dùng thuộc tính CSS như font-family, font-style, font-weight, font-size, color, background-color, text-align để định dạng văn bản, ví dụ:
<h1 style="color:red;">Thẻ HTML H1 màu đỏ</h1><p style="font-weight:bold;">Đoạn văn bản quan trọng cần bôi đậm</p>
Cách này thường dùng khi bạn chỉnh sửa một trang web có sẵn, ví dụ bạn muốn điều chỉnh màu hoặc độ lớn của tiêu đề bạn có thể thực hiện thay đổi thẻ h1 như sau:
<h1 style="color:green;font-size: 14px;">
Tuy nhiên khi thiết kế không sử dụng kiểu này do rất dễ bị dư thừa. Ví dụ khi bạn có hai thẻ <h2> trong trang và bạn muốn tô đậm và bôi màu vàng cho nó chẳng hạn, bạn phải thực hiện định dạng cả hai thẻ h2 này:
<h2 style="font-weight:bold;color:yellow;">Thẻ h2 thứ nhất</h2>
...
<h2 style="font-weight:bold;color:yellow;">Thẻ h2 thứ hai</h2>
Để tránh dư thừa code CSS không cần thiết, người ta lựa chọn đến các thẻ h2 và thiết lập CSS trong thẻ HTML style.
4.1.2 Định dạng văn bản với thẻ style – Internal CSS
Các thẻ HTML cần được định dạng giống nhau thì sẽ được nhóm lại và thiết lập thuộc tính CSS chung trong thẻ style, ví dụ về định dạng hai thẻ h2 ở trên có thể được viết lại như sau:
<body>
...
<style>h2 {font-weight: bold,
color: yellow
}</style><h2>Thẻ h2 thứ nhất</h2>
...
<h2>Thẻ h2 thứ hai</h2>
...
</body>
Cách định dạng thứ hai đã không còn bị dư thừa code CSS, khi cần thay đổi định dạng của cả hai thẻ h2 chúng ta chỉ cần điều chỉnh mã CSS tại một chỗ. Chú ý: HTML không giới hạn số lượng thẻ style có trong nội dung.
4.1.3 Định dạng văn bản với file CSS ở ngoài – External CSS
Nội dung định dạng CSS ở trên có thể tách ra một file riêng với phần mở rộng là .css và được liên kết với HTML thông qua thẻ HTML <link>. Thực hiện cách định dạng này với ví dụ ở phần trên, chúng ta tạo một file main.css có nội dung như sau (để cùng trong thư mục chứa file HTML hoặc gần nó để tiện tham chiếu đến):
h2 {font-weight: bold,
color: yellow
}
Sau đó trong file HTML chúng ta liên kết đến file main.css thông qua thẻ <link> được đặt trong phần <head>:
<!DOCTYPE html><html><head><link href="main.css"></head><body>
...
<h2>Thẻ h2 thứ nhất</h2>
...
<h2>Thẻ h2 thứ hai</h2>
...
</body></html>
Kết quả hiển thị trên trình duyệt không có gì thay đổi, tuy nhiên cách này giúp tăng tốc cho các lần tải trang tiếp theo, file main.css sẽ được lưu lại trên bộ đệm trình duyệt dẫn đến trong các lần tải tiếp theo trình duyệt không cần tải code CSS về nữa.
4.1.4 Độ ưu tiên trong định dạng văn bản với CSS
Các cách định dạng văn bản ở trên có thể dùng lẫn với nhau, vậy nếu thiết lập CSS ở các chỗ khác nhau thì kết quả hiển thị trên trình duyệt sẽ như thế nào? Mỗi cách định dạng có độ ưu tiên khác nhau, do vậy bạn yên tâm là không có sự xung đột về thiết lập CSS:
Độ ưu tiên cao nhất: Inline CSS – Sử dụng thuộc tính style của thẻ HTML.
Internal CSS – Sử dụng thẻ HTML style.
Độ ưu tiên thấp nhất: External CSS – Sử dụng file CSS ở ngoài và liên kết qua thẻ HTML <link>.
Như vậy nếu code CSS có ở 3 chỗ thì inline CSS sẽ được lấy để thiết lập kết quả hiển thị trên trình duyệt, chúng ta cùng kiểm tra ví dụ sau đây:
Bước 1: Tạo file main.css có nội dung
h1 {font-size: 10px;color: yellow
}
Bước 2: Tạo file HTML có nội dung, trong cùng thư mục với file main.css
<!DOCTYPE html><html><head><link href="main.css"></head><body><style>h1 {font-size: 20px,
color: red
}</style><h1 style="font-size: 30px;color: green">Kiểm tra độ ưu tiên trong các cách định dạng văn bản bằng CSS</h2></body></html>
Bước 3: Mở file HTML trên trình duyệt. Kết quả chúng ta có một thẻ h1 màu xanh và có kích thước font chữ là 30px do Inline CSS được ưu tiên cao nhất. Đây cũng chính là lý do mọi người hay sử dụng Inline CSS để chỉnh sửa nhanh một website mà chưa nắm rõ cấu trúc của nó.
4.2 Định dạng văn bảng bằng các thẻ HTML
Trong HTML cũng có một số thẻ giúp định dạng văn bản, việc sử dụng các thẻ HTML để định dạng cho kết quả hiển thị không khác gì so với sử dụng CSS nhưng sử dụng các thẻ này giúp cho bộ máy tìm kiếm như Google hiểu hơn về nội dung của bạn. Ví dụ cùng là in đậm chữ trong thẻ h1 như sau nhưng bộ máy tìm kiếm sẽ hiểu khác nhau:
<h1 style="font-weight: bold;">Thẻ HTML h1</h1><h1><b>Thẻ HTML h1</b></h1>
Bảng danh sách các thẻ HTML sử dụng định dạng văn bản:
Thẻ HTML
Mô tả
<b>
In đậm nội dung
<em>
In nghiêng nội dung được nhấn mạnh
<i>
In nghiêng nội dung
<small>
In nội dung với kích thước chữ nhỏ hơn
<strong>
In đậm nội dung được nhấn mạnh
<sub>
In nội dung theo kiểu chỉ số ở dòng dưới
<sup>
In nội dung theo kiểu chỉ số ở dòng trên (kiểu số mũ)
<ins>
Nội dung được chèn thêm vào, có gạch chân
<del>
Nội dung được xóa đi, có gạch ngang nội dung
<mark>
Highlight nội dung
<big>
In nội dung với kích thước chữ lớn hơn
<u>
Gạch chân nội dung
<strike>
Gạch ngang nội dung
Ví dụ sử dụng các thẻ HTML để định dạng văn bản:
<h1><small>Công thức</small> Rượu etylic</h1><h2>Tính chất vật lý</h2><p><b>Rượu etylic</b> C<sub>2</sub>H<sub>5</sub>OH là <i>chất lỏng không màu</i>, <mark>sôi ở 78.3<sup>o</sup>C</mark>, nhẹ hơn nước và tan vô hạn trong nước. Rượu etylic có thể hòa tan được nhiều chất như iot, benzen...</p><h2>Điều chế</h2><h3>Phương pháp sinh học</h3><p>Tinh bột hoặc đường lên men, quá trình nuôi cấy được gọi là ủ rượu và xuất hiện khoảng 20% rượu và sau đó nồng độ có thể tăng nhờ chưng cất. Công thức quá trình lên men: C<sub>6</sub>H<sub>10</sub>O<sub>2</sub>->2 CH<sub>3</sub>CH<sub>2</sub>OH + 2 CO<sub>2</sub></p><h3>Phương pháp công nghiệp</h3><p><strike>Cho etylen cộng hợp với nước với axit làm xúc tác.</strike> CH<sub>2</sub>=CH<sub>2</sub> + H<sub>2</sub>O -> C<sub>2</sub>H<sub>5</sub>OH</p>
Bảng dữ liệu là một thành phần không thể thiếu trong nội dung, bạn có thể gặp các bảng này trong danh sách người dùng, hóa đơn bán hàng… Chúng ta cùng tìm hiểu về các thành phần của một bảng dữ liệu:
Caption – Tiêu đề của bảng dữ liệu: mô tả ngắn gọn nội dung của bảng (thẻ <caption>)
Table header: Nhóm nội dung cho phần đầu bảng, ví dụ tên từng cột (thẻ <thead>)
Table body: Nội dung của bảng dữ liệu, trong nội dung có các thành phần sau (thẻ <tbody>)
Row: Dòng trong bảng dữ liệu (thẻ <tr>)
Column: Cột trong trong bảng dữ liệu (thẻ <col>)
Cell: Các ô dữ liệu (thẻ <td>)
Table footer: Nhóm nội dung cho phần cuối bảng dữ liệu, ví dụ các tổng kết (thẻ <tfoot>)
Với mỗi thành phần của bảng dữ liệu chúng ta đều có các thẻ HTML để xây dựng, các bước sau đây giúp bạn tạo bảng dữ liệu dễ dàng:
Bước 1: Định nghĩa bảng dữ liệu với thẻ <table>
Bước 2: Tạo tiêu đề cho bảng dữ liệu với thẻ <caption>
Bước 3: Tạo dòng tiêu đề cho từng cột với <thead>
Bước 3.1: Trong bảng dữ liệu, muốn xây dựng một ô dữ liệu thì trước hết phải xây dựng dòng trong bảng bằng thẻ <tr>.
Bước 3.2: Sau khi xây dựng dòng dữ liệu, xây dựng ô dữ liệu bằng thẻ hoặc bên trong thẻ <tr> (Trong tiêu đề sử dụng thẻ <th> để định nghĩa ô dữ liệu tiêu đề, trong phần thân thì dùng thẻ để định nghĩa ô dữ liệu)
Chú ý: Nếu có nhiều dòng tiêu đề thì chỉ cần sao chép và sửa lại thông tin.
Bước 4: Tạo phần thân bảng dữ liệu với <tbody>
Bước 4.1: Trước tiên xây dựng dòng dữ liệu bằng thẻ <tr>
Bước 4.2: Xây dựng các ô dữ liệu bên trong dòng dữ liệu bằng thẻ <td>
Khi có nhiều dòng dữ liệu, chúng ta chỉ việc sao chép và chỉnh sửa lại thông tin.
Bước 5: Tạo phần cuối bảng dữ liệu với <tfoot>
Kết quả bảng dữ liệu trên khi xem trên trình duyệt:
Trong bảng dữ liệu đôi khi chúng ta cần gộp một số ô dữ liệu theo hàng hoặc theo cột sử dụng thuộc tính rowspan hoặc colspan với giá trị là số ô cần gộp như trong ví dụ trên chúng ta có:
Hình ảnh là nội dung không thể thiếu trong các tài liệu, nó không những làm tài liệu trở nên hấp dẫn mà một hình ảnh có thể nói lên nhiều thông tin hơn cả văn bản. Các file hình ảnh có thể chèn vào văn bản thông qua thẻ <img>. Thẻ này cần thuộc tính src (source) để chỉ dẫn đến file ảnh cần hiển thị. Các dạng file ảnh phổ biến hiện nay có th:ể hiển thị tốt trên trình duyệt web:
JPEG (Joint Photographic Experts) hỗ trợ màu sắc 24-bit cho phép ảnh hiển thị lên đến hàng triệu màu. JPEG thường sử dụng cho các ảnh phức tạp như ảnh chụp, đồ họa sử dụng nhiều màu, các hình ảnh có nhiều chi tiết. File JPEG có phần mở rộng là .jpg.
PNG (Portable Network Graphics) là định dạng hỗ trợ nhiều màu sắc và cho phép nén ảnh tốt. Giống JPEG, PNG hỗ trợ màu 24 bit nhưng có thể được lưu trữ với số lượng màu ít hơn. File ảnh PNG có phần mở rộng là .png.
GIF (Graphics Interchange Format) hỗ trợ 256 màu, ảnh GIF sử dụng cho các ảnh đơn giản như logo, các đồ họa chứa các hình cơ bản và các đường thẳng. Có thể đưa các hoạt cảnh vào ảnh GIF, do vậy ảnh GIF động được sử dụng nhiều trong quảng cáo.
SVG (Scalable Vector Graphics) là định dạng ảnh sử dụng XML để mô tả ảnh, đặc điểm ảnh SVG là phóng to hay thu nhỏ thì hình ảnh vẫn rất sắc nét.
Ví dụ chèn một ảnh vào trang web:
<img src="url">
Ở đây url là đường dẫn đến ảnh, đường dẫn này có thể là đường dẫn tuyệt đối, ví dụ <img src=”/storage/app/media/uploads/2018/05/html-5-logo-200×200.png”>. Url cũng có thể là đường dẫn tương đối ví dụ <img src=”public\image\test-image.jpg”>.
Một số chú ý khi sử dụng thẻ <img>:
Ảnh cần được sử dụng đúng kích thước, ví dụ khung hiển thị là 300×200 px thì chọn ảnh đúng 300×200 do nếu ảnh có kích thước lớn hơn ảnh hưởng đến thời gian tải ảnh và ảnh hưởng đến xếp hạng trong tìm kiếm Google. Kích thước ảnh có thể được thiết lập bằng các thuộc tính width và height của thẻ <img>. Ví dụ <img src=”test-image.jpg” width=”300″ height=”200″>. Bạn cũng có thể sử dụng CSS để định dạng kích thước ảnh: <img src=”test-image.jpg” style=”width: 300px;height: 200px;>. Mỗi cách định dạng đều có ưu điểm riêng, với định dạng CSS chúng ta có thể định dạng hàng loạt ảnh, còn sử dụng thuộc tính width, height của thẻ <img> lại giúp Google hiểu về nội dung hơn.
Ảnh cần được tối ưu trước về kích thước, do trên trình duyệt mắt thường không thể phân biệt được các chi tiết ảnh quá nhiều nên có thể tối ưu hóa ảnh, có những công cụ tối ưu dung lượng ảnh lên đến 70-80%. Bạn tưởng tượng nếu website của bạn có 1GB ảnh, như vậy nếu qua công cụ tối ưu dung lượng lưu trữ sẽ còn 200MB, thật không tưởng. Bạn có thể tham khảo TinyPNG hoặc bài viết Giảm dung lượng ảnh với TinyPNG trong Laravel.
Ảnh cần được mô tả bằng thuộc tính alt, ví dụ <img src=”test-image.jpg” alt=”Ảnh thử nghiệm”>, thuộc tính này là rất cần thiết vì khi đường dẫn ảnh bị sai hoặc ảnh bị xóa trên máy chủ thì nó sẽ hiển thị văn bản trong thuộc tính alt.
Thuộc tính title giúp tạo ra văn bản mô tả và khi bạn di chuột vào ảnh thì văn bản này hiện ra, ví dụ <img scr=”test-image.jpg” alt=”Ảnh thử nghiệm” title=”Ảnh sử dụng cho thử nghiệm”>
Có rất nhiều các thuộc tính CSS để định dạng hiển thị một ảnh và chúng ta sẽ tìm hiểu sau bên Khóa học CSS3 cơ bản.
6.2 Sử dụng ảnh làm ảnh nền cho trang web
Trong quá trình sử dụng Internet chúng ta thấy có rất nhiều website có ảnh nền đằng sau, ảnh nền giúp website trở lên lung linh hơn hoặc giúp chữ dễ đọc hơn. Sử dụng ảnh làm nền cho trang web rất đơn giản bằng cách sử dụng thuộc tính style trong thẻ <body>:
<body style="background-image:url('anh-nen.jpg')">
...
<h2>Trang web có ảnh nền</h2>
...
</body>
Với cách này, bạn hoàn toàn có thể đưa ảnh nền vào cho từng đoạn văn bản:
<body>
...
<p style="background-image:url('anh-nen-van-ban.jpg')">
Đây là đoạn văn bản có ảnh nền
</p>
...
</body>
6.3 HTML5 có gì mới trong sử dụng ảnh
HTML5 cung cấp thêm một thẻ HTML mới là <picture>, nó giúp cho việc lựa chọn ảnh linh hoạt với từng điều kiện khác nhau. Bạn biết đấy hiện nay, smart phone, tablet đã rất phổ biến, các thiết bị này có kích thước màn hình hiển thị khác nhau, do vậy với thẻ <picture> trình duyệt sẽ lựa chọn ảnh phù hợp với thiết bị. Công việc này được thực hiện thông qua thẻ <source>. Ví dụ:
Chú ý, luôn có một thẻ là thành phần cuối cùng của thẻ <picture>, thẻ <img> được sử dụng bởi các trình duyệt không hỗ trợ HTML5 <picture> hoặc nếu không có thẻ <source> nào phù hợp.
7. Liên kết trong HTML
Liên kết (hyperlink hoặc link) là sức mạnh của siêu văn bản, dựa vào liên kết có thể chuyển từ trang web này sang một trang web hoặc một dịch vụ một cách nhanh chóng. Liên kết được ví như mối quan hệ trong cuộc sống hàng ngày, chính vì vậy một nội dung được đánh giá cao là một nội dung có
Các liên kết trong chính website đó (internal link)
Các liên kết từ trang ra các website bên ngoài (external link)
Các liên kết từ website bên ngoài vào trang web (backlink )
Khái niệm liên kết là hết sức đơn giản nhưng lại cực kỳ quan trọng trong được đánh giá và xếp hạng trong bảng kết quả tìm kiếm từ các bộ máy tìm kiếm như Google, Cốc cốc…
7.1 Liên kết dạng văn bản
Liên kết dạng văn bản có tần suất xuất hiện nhiều nhất, các liên kết này giúp điều hướng từ trang web này sang trang web khác một cách nhanh chóng. Thẻ HTML <a> định nghĩa các liên kết (a là viết tắt của anchor – mỏ neo).
Liên kết văn bản có hai loại:
Liên kết đến tài liệu (trang web) khác.
Liên kết đến một phần nội dung xác định của tài liệu (trang web) hiện tại hoặc trang web khác.
Liên kết tải tài liệu
7.1.1 Liên kết đến tài liệu (trang web) khác
Khi liên kết trên trang là liên kết đến trang khác thì địa chỉ của trang khác được chỉ ra trong thuộc tính href của thẻ <a>:
Xem chi tiết <a href="https://allaravel.com/tutorials/lap-trinh/khoa-hoc-html-tu-co-ban-den-nang-cao/">Khóa học HTML5 từ cơ bản đến nâng cao</a>.
Thuộc tính href của thẻ <a> giúp trình duyệt biết được địa chỉ tài liệu cần liên kết đến. Địa chỉ này có thể có nhiều dạng:
Địa chỉ tuyệt đối là địa chỉ đầy đủ không cần tham chiếu đến tài liệu hiện tại, ví dụ:
<a href="https://allaravel.com/tutorials/lap-trinh/khoa-hoc-html-tu-co-ban-den-nang-cao/>Khóa học HTML</a>
là địa chỉ tuyệt đối và bạn chỉ cần gõ địa chỉ này vào là trình duyệt có thể hiển thị được.
Địa chỉ tương đối là địa chỉ cần tham chiếu đến tài liệu hiện tại, ví dụ:
<a href="html-co-ban/html-la-gi.html">Khóa học HTML</a>
Khi bạn mở một liên kết, có thể bạn muốn nội dung của trang liên kết này sẽ ở trang một cửa sổ mới hoặc một tab mới hoặc đôi khi bạn muốn nội dung mới hiển thị đè lên nội dung cũ trong chính cửa sổ hiện tại hoặc tab hiện tại. Để thiết lập cách thức mở trang liên kết bạn sử dụng thuộc tính target, thuộc tính này có một số giá trị như sau:
_blank: mở tài liệu liên kết trong cửa sổ hoặc tab mới
_self: mở tài liệu liên kết trong cửa sổ hoặc tab hiện tại (tại đó bạn nhấp vào liên kết) – giá trị mặc định
_parent: mở tài liệu liên kết trong frame cha
_top: mở tài liệu liên kết trong phần thân của cửa sổ
framename: mở tài liệu liên kết trong frame có tên
Có một thuộc tính cực kỳ quan trọng của thẻ <a> là thuộc tính rel (relationship), nó định nghĩa mối quan hệ giữa trang hiện tại và trang liên kết đến. Thuộc tính này cũng có một số giá trị như sau:
<a href="html-co-ban/html-la-gi.html"rel="nofollow">HTML cơ bản</a>
Giá trị của thuộc tính rel
Ý nghĩa
alternate
Cung cấp một liên kết thay thế cho tài liệu (trang web) hiện tại, ví dụ: trang để in ấn, trang được dịch sang tiếng nước ngoài…
author
Cung cấp liên kết đến trang về tác giả của tài liệu hiện tại.
bookmark
URL lâu dài sử dụng cho bookmark
external
Đánh dấu tài liệu được tham chiếu không phải là một phần của cùng website với tài liệu hiện hành.
help
Cung cấp liên kết đến tài liệu trợ giúp.
license
Cung cấp liên kết đến thông tin bản quyền.
next
Cung cấp thông tin đến tài liệu tiếp theo trong một danh sách các tài liệu.
nofollow
Liên kết đến tài liệu không được chứng thực, ví dụ liên kết trả tiền. Nofollow được sử dụng bởi Google để xác định xem công cụ dò tìm có tiếp tục dò tìm trang liên kết không?
noreferrer
Yêu cầu trình duyệt không gửi header HTTPR tham chiếu nếu người dùng nhấp vào liên kết.
noopener
Requires that any browsing context created by following the hyperlink must not have an opener browsing context
prev
Mở tài liệu trước đó.
search
Liên kết đến công cụ tìm kiếm tài liệu.
tag
Liên kết là một thẻ (từ khóa) của tài liệu hiện tại
Trong các giá trị này thì nofollow là giá trị quan trọng nhất, nếu một liên kết dạng backlink có rel=”nofollow” thì sẽ được Google đánh giá thấp hơn rất nhiều so với liên kết thông thường.
Chú ý: Các liên kết mặc định có định dạng khác nhau tùy thuộc văn cảnh:
Liên kết chưa được vào lần nào thì nó sẽ gạch chân và có màu xanh da trời
Liên kết đã được vào thì nó sẽ gạch chân và có màu tía
7.1.2 Liên kết đến phần xác định của một trang web
Một trang web có nội dung dài thì cần có phần mục lục và mỗi khi bấm vào một mục trên đó, trình duyệt sẽ đưa bạn đến phần nội dung phù hợp trên trang hiện tại. Để thực hiện được liên kết này, bạn cần phải thực hiện khai báo hai bước.
Bước 1: Khai báo id cho phần tử HTML nơi mà nội dung bạn muốn đến khi nhấn vào liên kết (ví dụ nội dung này là của trang web-page.html)
<h3 id="text-link">Liên kết dạng văn bản</h3><!-- Nội dung phần liên kết văn bản ở đây --><h3 id="image-link">Liên kết dạng hình ảnh</h3><!-- Nội dung phần liên kết hình ảnh ở đây --><h3 id="other-link">Liên kết khác</h3><!-- Nội dung phần liên kết khác ở đây -->
Bước 2: Khai báo liên kết
<h3>Nội dung chính bài viết</h3><ol><li><a href="web-page.html#text-link">Liên kết dạng văn bản</a></li><li><a href="web-page.html#image-link">Liên kết dạng hình ảnh</a></li><li><a href="web-page.html#other-link">Liên kết dạng khác</a></li></ol>
Chú ý: nếu liên kết này nằm trên cùng trang web-page.html thì phần địa chỉ có thể bỏ đi phần địa chỉ trang web-page.html:
<a href="#text-link">Liên kết dạng văn bản</a>
Chú ý: Phiên bản trước sử dụng thuộc tính name để định nghĩa phần nội dung cần nhảy đến, tuy nhiên HTML5 không hưởng ứng việc này mà thay vào đó sử dụng thuộc tính id, lý do là id là một chuỗi định danh duy nhất nên không có việc xung đột khi nhấp vào một liên kết mà có hai nội dung được gán thẻ phù hợp.
7.1.3 Liên kết tải tài liệu
Một số trang web muốn đưa thẻ liên kết đến một file tài liệu để người dùng có thể tải về, ví dụ các tài liệu này có thể là dạng PDF, Microsoft Word, Excel, RAR… rất đơn giản chúng ta chỉ việc đưa tài liệu lên máy chủ web và tạo liên kết đến tài liệu này.
<a href="http://bigi.vn/public/files/Bao-gia-KLASS-86-KV1.docx">Tải báo giá dòng sản phẩm KLASS 86KV1</a>
7.2 Liên kết dạng hình ảnh
Hình ảnh chứa đựng nhiều thông tin hơn văn bản và tăng sức hấp dẫn làm cho người dùng muốn nhấp vào hơn, tuy nhiên không phải ai cũng biết được ảnh này là một liên kết nếu như không di chuột lên đó. Liên kết dạng hình ảnh thay vì đưa một đoạn văn bản vào, chúng ta đưa vào đó một ảnh thông qua thẻ <img>:
<a href="html5-co-ban.html"><img src="hinh-anh-html5-co-ban"alt="HTML5 cơ bản"/></a>
Liên kết dạng hình ảnh ở trên là toàn bộ bức ảnh, tức là bạn nhấp vào đâu trên bức ảnh thì trình duyệt cũng chuyển bạn đến trang liên kết. Một dạng liên kết hình ảnh thứ hai là sử dụng một vùng xác định trên hình ảnh để liên kết, ví dụ trên bức ảnh có một số biểu tượng của Vue.js, Laravel, HTML5 khi nhấp vào từng biểu tượng thì trình duyệt chuyển đến khóa học phù hợp.
<img src="/storage/app/media/uploads/2018/05/cac-khoa-hoc-hien-co-tren-allaravel.com_.jpg"alt="Các khóa học lập trình trên Allaravel"usemap="#coursemap"width="734"height="277"><map name="coursemap"><area shape="rect"coords="16,71,230,256"alt="Khóa học Vue.js cơ bản"href="https://allaravel.com/tutorials/lap-trinh/vuejs-framework/khoa-hoc-vue-js-2-mien-phi/"target="_blank"><area shape="circle"coords="350,144,120"alt="Khóa học HTML5 cơ bản"href="https://allaravel.com/tutorials/lap-trinh/khoa-hoc-html-tu-co-ban-den-nang-cao/"target="_blank"><area shape="rect"coords="448,71,715,256"alt="Khóa học Laravel cơ bản"href="https://allaravel.com/laravel-tutorials/khoa-hoc-laravel-5-mien-phi/"target="_blank"></map>
Trên mạng internet không chỉ có các trang web mà còn có rất nhiều các dịch vụ khác, như vậy việc liên kết không chỉ dừng lại ở việc liên kết các tài liệu mà nó còn cho phép liên kết đến các dịch khác nhau.
Liên kết đến tài khoản email: Khi nhấp vào nếu thiết bị có ứng dụng email nó sẽ tự động bật ra để soạn thảo email gửi đi.
Gửi đến địa chỉ email<a href="mailto: my_email@allaravel.com">My_email@Allaravel.com</a>
Liên kết đến số điện thoại: Khi nhấp vào nếu thiết bị có thể thực hiện cuộc gọi nó sẽ gọi đến số điện thoại được cung cấp (bạn có thể thử trên smart phone)
Gọi số <a href="tel: 0904666888">0904-666-888</a> để được tư vấn
Liên kết đến skype để chat
<a href="skype: kiendc0308g?chat">Chat skype</a> để được tư vấn
8. Trích dẫn, diễn giải, thêm ngữ nghĩa nội dung trong HTML
8.1 Trích dẫn trong HTML
Trong phần tiếp theo này chúng ta sẽ tìm hiểu những nội dung ít quan trọng hơn trong trang HTML, tuy nhiên khi sử dụng đúng mục đích các thẻ HTML trong phần này sẽ là gia vị cho món ăn của chúng ta thêm ngon hơn. Ví dụ, trích dẫn nội dung từ các trang uy tín, lời nói từ những người nổi tiếng có sức thuyết phục rất lớn, việc trích dẫn giống như “mượn gió bẻ măng” giúp cho nội dung được người đọc ghi nhớ lâu hơn. Trong HTML có hai kiểu trích dẫn, trích dẫn ngắn thường là trích dẫn câu nói sử dụng thể <q> và trích dẫn đầy đủ với thẻ <blockquote>.
<p>Tôn tử nói: <q>Biết mình biết ta, trăm trận trăm thắng.</q></p>
<p>Định nghĩa về HTML từ Wikipedia</p><blockquote>HTML viết tắt của Hypertext Markup Language là ngôn ngữ tiêu chuẩn đánh dấu siêu văn bản, nó tạo ra các rtrang web, các ứng dụng web. Với CSS (Cascading Style Sheets) và JavaScript, nó tạo nên nền tảng công nghệ cho Mạng diện rộng toàn cầu (World Wide Web)</blockquote>
Viết tắt là không tránh khỏi khi soạn thảo văn bản, đặc biệt các cụm từ được lặp đi lặp lại nhiều lần, ví dụ như trong bài viết này chúng ta thường xuyên dùng HTML thay cho cụm từ đầy đủ là Hypertext Markup Language. Với người đọc có thể hiểu được văn bản viết tắt nhưng với các bộ máy tìm kiếm là rất khó khăn, do vậy với thẻ <abbr>, nội dung viết tắt được cung cấp thêm thông tin giúp giải thích cụm từ viết tắt chuẩn xác hơn.
<p>Ngôn ngữ <abbr title="Hypertext Markup Language">HTML</abbr> là một tất yếu khách quan khi nhu cầu xây dựng các siêu văn bản ngày càng lớn.</p>
Thẻ <address> được sử dụng từ HTML4.01 để định nghĩa các thông tin về tác giả của tài liệu hay bài viết, nếu thẻ này nằm trong thẻ <article> thì nó thể hiện thông tin liên hệ cho bài viết đó. Văn bản trong thẻ <address> thường được in nghiêng khi hiển thị. Ví dụ:
<article><h1>Khóa học HTML từ cơ bản đến nâng cao</h1><p>Các nội dung cơ bản nhất của HTML sẽ được giới thiệu đến bạn đọc trong 4 bài đầu tiên. Sau đó các kiến thức mới nhất về HTML5 cũng như các kỹ thuật thường được sử dụng cho phát triển web hiện đại sẽ được giới thiệu trong phần nâng cao về HTML5.</p><p>Thông tin tác giả khóa học HTML5:</p><address>
Biên soạn: <a href="https://allaravel.com/author/kiendc/">FirebirD</a><br>
Học hàm: <cite>Giáo sư đại số</cite> (Chuyên nghiên cứu các con số trong phạm vi từ 00 đến 99 :D)
</address></article>
KHÔNG sử dụng thẻ <address> để mô tả các địa điểm trừ khi địa điểm này là một phần của thông tin liên hệ.
Thẻ <address> thường được đưa vào phần thông tin trong thẻ <footer>.
Trong ví dụ trên chúng ta có thêm thẻ <cite> sử dụng để mô tả chức danh công việc.
8.4 Diễn giải code trong HTML
Có lẽ đây là phần vô tác dụng nhất với người đọc nhưng lại rất hữu ích với người lập trình web, nếu code không có các đoạn diễn giải, thật khó để hiểu ý nghĩa của từng đoạn code cụ thể. Nội dung Diễn giải (comment) mã HTML được đưa vào giữa nhóm các ký tự sau:
<!-- Bắt đầu phần danh sách sản phẩm --><section>
... Mã liệt kê danh sách sản phẩm cỡ 1000 dòng không biết kết thúc ở đâu
</section><!-- Kết thúc phần liệt kê danh sách sản phẩm. May mà có diễn giải mới biết chỗ này là kết thúc -->
Ngoài ý nghĩa diễn giải nội dung cho một đoạn mã HTML, chúng ta có thể sử dụng cách thức này để bỏ qua tạm thời những đoạn mã HTML không muốn trình duyệt xử lý. Ví dụ:
<!-- Trình duyệt sẽ bỏ qua phần này vì khóa học này đang biên soạn
<a href="khoa-hoc-css3.html">Khóa học CSS3</a>
-->
9. Hiển thị code, ký tự đặc biệt trong HTML
9.1 Hiển thị code trong HTML
Trong các tài liệu về kỹ thuật hoặc đặc biệt là tài liệu công nghệ thông tin có rất nhiều các đoạn mã, việc hiển thị code trong văn bản về cơ bản được HTML5 hỗ trợ nhưng khi hiển thị trên trình duyệt không quá mỹ mãn như suy nghĩ. Trong thực tế, chúng ta có thể áp dụng các thư viện css, javascript giúp việc highlight code đẹp và hiệu quả hơn. Cơ bản HTML5 sử dụng thẻ <code> để hiển thị mã, ví dụ:
<code>
x = 5;
y = 6;
z = x + y;
</code>
Chú ý: khi hiển thị trên trình duyệt sẽ bỏ qua các ký tự xuống dòng, vì vậy thông thường chúng ta kết hợp thẻ <pre> với thẻ <code> để giữ nguyên định dạng.
<pre><code>
x = 5;
y = 6;
z = x + y;
</code></pre>
Hiển thị phím hoặc tổ hợp phím trong nội dung văn bản:
<p>Sử dụng tổ hợp phím <kbd>Ctrl + C</kbd> để sao chép nội dung.</p>
Hiển thị biến trong code sử dụng thẻ <var>
<p>Công thức tính năng lượng của Einstein: <var>E</var> = <var>mc</var><sup>2</sup></p>
9.2 Các ký tự đặc biệt trong mã HTML
HTML sử dụng các ký tự < và > để đánh dấu các thẻ do vậy các ký tự này không được sử dụng trong nội dung, nếu bạn muốn sử dụng ký tự <, > cho các biểu thức kiểu như 5 < 9 chúng ta phải sử dụng một nhóm các ký tự để trình duyệt có thể hiển thị đúng.
<p>5 < 9</p>
Các ký tự đặc biệt được liệt kê trong bảng dưới đây:
Ký tự hiển thị
Mô tả
Nhóm ký tự
Ký tự cách trống (ký tự này không bị trình duyệt bỏ qua khi có nhiều hơn 1 ký tự cách trống)
Như vậy là 10 gương mặt lập trình viên xuất sắc nhất đã xuất hiện cùng với những lời nhận xét tốt đẹp nhất từ phía các nhà khoa học máy tính, các đồng nghiệp của họ. Trong phần cuối, chúng ta sẽ chỉ còn 5 cái tên có mặt ở danh sách này. Hãy cùng chúng tôi tiếp tục khám phá.
Lập trình viên Fabrice Bellard – Người tạo ra QEMU
QEMU là một trong những máy ảo giống như VMWare, Vitual PC, Bochs. Nó có thể chạy tốt trên cả Linux lẫn Window. Có thể nói Fabrice là cha đẻ của nền tảng này. Không chỉ có vậy, ông còn tạo ra rất nhiều chương trình phần mềm với mã nguồn mở khác. Năm 2000 và 2001, ông đoạt giải Obfuscated C Code Contest và tiếp tục nhận giải Google-O’Reilly Open Source trong năm 2011. Ngoài ra, ông đã từng nắm giữ kỷ lục thế giới cho việc tính toán số lượng chữ số trong Pi.
Nhận xét:
“Tôi thấy những gì Fabrice Bellard đã làm thật ấn tượng.” Raphinou
“Fabrice Bellard là lập trình viên hiệu quả nhất thế giới.” Pavan Yara
“Ngài như Nicola Tesla của kỹ thuật phần mềm.” Michael Valladolid
“Anh ấy đã nối tiếp thành công từ những năm 1980.” Michael Biggins
Lập trình viên Jon Skeet – Đóng góp lớn cho trang Stack Overflow huyền thoại
Ông là kiến trúc sư của Google đồng thời là tác giả của C# trong Depth. Giữ điểm số uy tín cao nhất trên stack overflow.com (trang web hỏi đáp về lập trình uy tín nhất). Trung bình mỗi tháng ông tiếp nhận và trả lời 390 câu hỏi.
Nhận xét:
“Jon Skeet không cần một trình gỡ rối, ông chỉ cần nhìn xuống lỗi cho đến khi những đoạn mã chạy được” Steven A. Lowe
“Ông thường dùng những đoạn code sai để chỉ ra lỗi của người lập trình.” Dan Dyer
“Code của Jon Skeet không phải một thứ code thông thường. Đó là một thể loại code thực sự bình dân.” Anonymous
Lập trình viên Adam D’Angelo – Đồng sáng tạo Quora
Là một kỹ sư của Facebook, là người xây dựng cơ sở ban đầu cho nguồn tin của mạng xã hội này. Ông trở thành Giám đốc công nghệ của Facebook trước khi rời đi và là một trong những người góp công lớn tạo ra Quora(cũng là một trang web hỏi đáp về lập trình nổi tiếng). Giữ vị trí thứ 8 trong Cuộc thi khoa học máy tính Mỹ Olympiad khi còn học phổ thông năm 2001. Ông là thành viên của Học viện công nghệ California và đã đạt huy chương bạc trong Hội thảo lập trình ACM International Collegiate năm 2004. Và trong năm 2005, ông đã vô địch Cuộc thi Mã hóa thuật toán của Topcoder Collegiate Challege.
Nhận xét:
“ Một trong những lập trình viên chuyên nghiệp” Anonymous
“Khi mới chỉ 6 tuổi, anh ta đã làm được mọi thứ tôi có thể làm.” Mark Zuckerberg
Lập trình viên Petr Mitrechev – Một trong những lập trình viên có sức cạnh tranh cao nhất mọi thời đại
Sinh năm 1985, là một lập trình viên xuất sắc người Nga. Anh đã 2 lần đoạt huy chương vàng tại Olympic tin học quốc tế (2000 và 2002). Trong năm 2006, anh đã trở thành người lập trình của Google và vô địch Giải TopCoder Algorithm mở rộng. Thêm vào đó là hai lần chiến thắng trong Cup Facebook Hacker (2011, 2013). Hiện tại, anh đang nắm giữ vị trí thứ 2 trên Topcoder đồng thời cũng đứng thứ 2 trên Codeforces.
Nhận xét: “ Anh ấy là một thần tượng trong giới lập trình viên ngay cả ở đây – Ấn Độ” Kavish Dwivedi
Lập trình viên Gennady Korotkevich – Thần đồng lập trình
Lập trình viên cực kỳ tài năng người Belarus. Người nhỏ tuổi nhất tham gia Cuộc thi Tin học quốc tế (11 tuổi) và đã 6 lần đoạt giải trong kỳ thi này (từ năm 2007 đến 2012). Là thành viên của đội đoạt giải ACM ICPC năm 2013 và vô địch Cup Facebook Hacker 2014. Vào thời điểm này, thanh niên trẻ tuổi đang giữ vị trí số 1 trên Codeforces đồng thời cũng đứng số 1 ở Topcoder.
Nhận xét:
“Gennady thực sự rất tuyệt vời và đó là lý do cho thấy tại sao tôi có một đội ngũ phát triển hùng hậu tại Belarus.” Chris Howard
Bài viết được sự cho phép của tác giả Nguyễn Hữu Khanh
Internationalization là tính năng của các ứng dụng web hiện đại, có khả năng hiển thị giao diện trên nhiều ngôn ngữ từ các quốc gia khác nhau. Ví dụ như nếu ứng dụng web của bạn có thể hiển thị tiếng Anh, tiếng Việt, tiếng Đức, tiếng Hàn, tiếng Nhật thì người dùng biết một trong các ngôn ngữ này, có thể chọn lựa ngôn ngữ mà họ rành nhất. Nếu các bạn đang sử dụng Spring MVC cho ứng dụng web của mình thì có thể đọc bài viết này. Mình sẽ hướng dẫn các bạn cách hiện thực Internationalization trong Spring MVC các bạn nhé!
Để hiện thực internationalization trong Spring MVC, các bạn cần cấu hình các thông tin liên quan về messageSource, localeResolver và localeChangeInterceptor. Nói nôm na thì messageSource là nơi chúng ta sẽ định nghĩa đường dẫn tới các tập tin chứa các chuỗi sẽ hiển thị trong ứng dụng web ở nhiều ngôn ngữ khác nhau (nếu các bạn đã làm việc với internationalization của Java sử dụng class ResourceBundle thì messageSource cũng tương tự như vậy đó các bạn!), localeResolver sẽ xác định ngôn ngữ mà người dùng đang sử dụng là gì còn localeChangeInterceptor sẽ giúp chúng ta detect việc người dùng có đang change ngôn ngữ mà họ muốn sử dụng không?
messageSource
Spring cung cấp cho chúng ta interface MessageSource để hiện thực mục đích của messageSource. Interface MessageSource này có một sub-interface là
HierarchicalMessageSource với 2 implementation là ReloadableResourceBundleMessageSource và ResourceBundleMessageSource đó các bạn!
ResourceBundleMessageSource implementation sử dụng ResourceBundle của Java, nó sẽ load hết tất cả các chuỗi được định nghĩa và chúng ta không thể thay đổi nội dung của các chuỗi này trong suốt quá trình ứng dụng chạy. Còn ReloadableResourceBundleMessageSource implementation thì cũng tương tự như ResourceBundleMessageSource nhưng chúng ta có thể cấu hình thêm cho nó tự reload lại nội dung của các chuỗi được định nghĩa sau một khoảng thời gian nào đó.
Để cấu hình MessageSource, mình sẽ định nghĩa các tập tin .properties chứa các chuỗi với nhiều ngôn ngữ khác nhau như khi chúng ta làm việc với ResourceBundle trong Java đó các bạn!
Mình sẽ thêm mới 2 tập tin message.properties và message_vi.properties trong thư mục src/main/resources để định nghĩa cho ngôn ngữ mặc định của ví dụ của mình là tiếng Anh, ngoài ra ứng dụng này còn hỗ trợ cả tiếng Việt.
Trong ứng dụng ví dụ ở trên, mình sẽ internationalization 2 câu là “Hello World” với “The time on the server is” nên mình sẽ định nghĩa nội dung của tập tin message.properties và message_vi.properties như sau:
message.properties
app.lang.vi=Vietnamese
app.lang.en=English
app.welcome=Hello world
app.time=The time on the server is
message_vi.properties
app.lang.vi=Ti\u1EBFng Vi\u1EC7t
app.lang.en=Ti\u1EBFng Anh
app.welcome=Xin chào
app.time=Gi\u1EDD c\u1EE7a server lúc này là
Bây giờ, mình sẽ sử dụng ReloadableResourceBundleMessageSource implementation và định nghĩa nó trong Spring container (tập tin src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml) như sau:
Như các bạn thấy, thuộc tính basename của class ReloadableResourceBundleMessageSource được dùng để khai báo đường dẫn tới các tập tin .properties.
localeResolver
Như mình nói, localeResolver dùng để xác định ngôn ngữ mà người dùng đang sử dụng là gì để hiển thị cho đúng với ngôn ngữ đó. Spring sử dụng interface LocaleResolver để làm việc này.
Interface LocaleResolver có nhiều implementation khác nhau:
AcceptHeaderLocaleResolver: resolver này sẽ detect ngôn ngữ mà người dùng đang sử dụng dựa vào header “accept-language” của HTTP request.
FixedLocaleResolver: chúng ta dùng resolver này khi chúng ta cố định locale cho ứng dụng của chúng ta.
SessionLocaleResolver: resolver này sử dụng attribute locale trong user session, nếu không có attribute này thì nó sẽ fallback sử dụng header “accept-language” của HTTP request như AcceptHeaderLocaleResolver.
CookieLocaleResolver: sử dụng locale được lưu trữ trong cookie của trình duyệt mà user đang sử dụng.
Chúng ta sẽ sử dụng CookieLocaleResolver cho ví dụ của mình trong bài viết này các bạn nhé:
Khi người dùng muốn thay đổi ngôn ngữ hiển thị trên ứng dụng web, chúng ta phải có cơ chế để xử lý yêu cầu này. LocaleChangeInterceptor là một class của Spring cho phép chúng ta xử lý những yêu cầu này.
Class LocaleChangeInterceptor hiện thực interface HandlerInterceptor cho phép chúng ta chặn tất cả request của user để thêm logic xử lý. Class LocaleChangeInterceptor sẽ lấy giá trị của một request parameter mà chúng ta cấu hình để xử lý request change ngôn ngữ của người dùng.
Các bạn có thể đọc thêm code của phương thức preHandle() trong class LocaleChangeInterceptor để thấy điều này:
Chúng ta sẽ cấu hình LocaleChangeInterceptor trong tập tin src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml như sau:
Ở đây, mình đang cấu hình request parameter mà LocaleChangeInterceptor sẽ lấy giá trị ngôn ngữ là “lang”.
Đến đây là chúng ta đã hoàn thành việc cấu hình các bean, các interceptor cần thiết trong Spring container để hiện thực internationalization trong Spring MVC. Bây giờ, chúng ta sẽ đi chỉnh sửa các tập tin view để chúng có thể hiển thị nhiều ngôn ngữ khác nhau được các bạn nhé!
Mình sẽ chỉnh sửa tập tin home.jsp trong thư mục src/main/webapp/WEB-INF/views/home.jsp như sau:
Nếu bạn nào chưa biết về taglib thì mình có thể nói nôm na như thế này, nó là JSP Standard Tag Library hay viết tắt là JSTL, một bộ các thẻ HTML giúp chúng ta có thể làm nhiều việc với các tập tin JSP. Như các bạn thấy, mặc định, tập tin home.jsp đã định nghĩa JSTL core tags:
JSTL core tags này giúp chúng ta có thể loop data để được truyền từ Controller để hiển thị chúng trong trang JSP. Chúng ta cũng có thể thêm các điều kiện logic, catch exception, chuyển tiếp (forward) hoặc chuyển hướng (redirect), định nghĩa URL như mình đã làm ở trên với tag <c:url />, …
Spring hỗ trợ taglib trên, một trong số các tag trong bộ taglib này giúp chúng ta có thể hiển thị thông tin trên nhiều ngôn ngữ khác nhau là <spring:message />. Tag <spring:message /> có nhiều attribute, chúng ta có thể khai báo attribute code với value là property key trong các tập tin message properties để hiện thực internationalization. Trong trường hợp property key mà chúng ta khai báo trong attribute code không tồn tại, các bạn có thể set default value bằng cách khai báo thêm attribute text trong thẻ <spring:message /> này. Ví dụ như:
Anh Nguyễn Văn Hải, sinh năm 1990, hiện đang là Phó Giám đốc trung tâm phát triển phần mềm số 6 tại Rikkeisoft Hà Nội.
Anh đã có khoảng thời gian 4 năm làm việc tại Nhật trải qua các vị trí từ dev, tech lead, BrSE, BM và hiện tại mình đang làm vị trí Division Manager.
Anh có thể giải thích rõ hơn về công việc, vai trò của một kỹ sư cầu nối – Bridge Software Engineer (BrSE)?
BrSE là một công việc đặc thù trong các công ty cung cấp các giải pháp công nghệ thông tin outsourcing cho thị trường Nhật Bản, đặc thù ở thị trường Nhật Bản. Nơi làm việc hiện tại của mình là Rikkeisoft cũng là công ty top về outsourcing.
BrSE nội dung chính là truyền đạt thông tin và giải pháp giữa 2 bên Nhật Việt để đảm bảo công việc cho dự án được thuận lợi và kết nối dễ dàng hơn, cân bằng được yêu cầu giữa 2 bên.
Tham khảo thêm việc làm Brse lương cao tại Topdev.vn
Công việc hàng ngày và vai trò của một Division Manager trong một dự án là gì?
Thật ra có 2 người đảm nhiệm trong 1 vị trí Division, anh hiện tại là vị trí Phó Giám đốc. Một trung tâm sẽ có rất nhiều dự án, vị trí của anh hiện tại có các công việc khác nhau như quản lý tiến độ của nhiều dự án, họp với khách hàng để báo cáo tiến độ, họp cải thiện các dự án vào cuối tuần, trao đổi với các key members để lắng nghe về nguyện vọng, tình hình hiện tại tâm tư của anh em ra sao, lên kế hoạch cho nhân sự trong tháng tới, công việc tháng tới sẽ như thế nào và điều chỉnh nhân sự cho phù hợp. Đấy là công việc hàng ngày của vị trí Division Manager.
Vậy ở Rikkeisoft, ngoài 2 vị trí BrSE và Division Manager như chúng ta đã đề cập còn những vai trò gì khác trong một vị trí outsourcing hay không?
Trong một dự án sẽ có rất nhiều các vị trí như PM, Tester, developer, BA,… tiếp theo là các vị trí quan trọng như Bridge BM hoặc Senior PM.
Có quan điểm cho rằng một BrSE giống như một BA & PM “của khách hàng”, theo anh BrSE có phải là người đặt trách nhiệm với khách hàng lên trên hết không?
Mình nghĩ là không đúng vì nếu nghĩ vậy thì rõ ràng là offshore sẽ mất lợi thế, dev người Việt mình sẽ rất yếu thế, anh nghĩ nó phải là mối quan hệ hợp tác win – win giữa mình và khách hàng. Mình không phải là người làm thuê mà là người bán sản phẩm, là người bán trí tuệ cho khách hàng. Vậy nên đây là quan hệ đôi bên cùng hợp tác và mục đích quan trọng nhất là cho dự án đó thành công.
Vậy theo anh trách nhiệm lớn nhất của BrSE là gì? Người BrSE cần có những hiểu biết, kiến thức hay kĩ năng mềm gì để có thể dung hòa các bên với nhau?
Anh nghĩ trách nhiệm lớn nhất để 2 bên khách hàng và offshore hoàn thành dự án tốt nhất nó bao gồm những việc như truyền đạt đúng yêu cầu, mong muốn của khách hàng, truyền đạt giải pháp, cách thực thi từ offshore cho khách hàng.
Để làm được điều này thì kiến thức của BrSE phải bao gồm nhiều thứ như hiểu về nghiệp vụ, có kỹ năng cơ bản về kỹ thuật lập trình và ngoại ngữ để đảm bảo giao tiếp ở mức hiểu đúng và hiểu đủ, các kỹ năng mềm như lắng nghe, đàm phán khi dự án có những vấn đề rắc rối. Lúc này mình không chỉ truyền đạt đúng những gì 2 bên trao đổi mà còn phải hiểu thêm về khó khăn của offshore, hiểu được nguyên nhân của vấn đề của cả đôi bên, để giải quyết mâu thuẫn và đàm phán xem làm thế nào để tốt nhất cho 2 bên.
Tiếp theo là khi mình muốn truyền đạt một kỹ thuật nào đó cho khách hàng nó còn liên quan đến khả năng trình bày vấn đề. Và để dự án hoạt động suôn sẻ thì khả năng teamwork cũng khá cần thiết, đặc biệt là khi BrSE ngồi ở phía khách hàng ở Nhật chẳng hạn, với khoảng cách xa như vậy thì khả năng teamwork càng quan trọng hơn. Bên cạnh đó là kỹ năng quản lý về checking task, quản lý nhân sự làm sao để motivate các dev có động lực làm việc tốt nhất, tạo tinh thần ham học hỏi, cầu tiến hơn nữa trong công việc cho mọi người.
Để trở thành một BrSE thì yêu cầu tối thiểu về Nhật ngữ bên mình như thế nào?
Thật sự ở đây bằng cấp không quan trọng. Có đôi khi khách hàng chưa hợp tác với mình lần nào thì họ có thể dựa trên bằng cấp để họ đánh giá nhưng khi họ thật sự cần mình hoặc là trong thời điểm BrSE vẫn còn khan hiếm này thì mình chỉ cần thể hiện năng lực của mình làm sao để khách hàng hiểu mình và mình hiểu khách hàng là được.
Offshore và Nearshore, mặc dù là những thuật ngữ không mới nhưng anh có thể khái quát lại một lần nữa để khán giả hiểu rõ hơn được không ạ?
Offshore là hình thức hợp tác với 1 công ty bên ngoài, cách xa về địa lý và thời gian như giữa Nhật với Việt chẳng hạn. Nearshore là hình thức hợp tác với công ty bên ngoài khá gần với khoảng cách địa lý và múi giờ của mình như Việt với Lào hay trong nước với nhau.
Hiện tại Rikkeisoft đang áp dụng offshore như thế nào: Phía Nhật Bản sẽ tiến hành define requirements, tạo design document và bên Việt Nam phát triển product?
Thật ra việc này sẽ phụ thuộc vào đặc thù của mỗi dự án. Có những dự án khách hàng sẽ design rất rõ ràng từ requirement, design và mình chỉ việc code thôi. Nhưng cũng có những dự án khách hàng chỉ đơn giản yêu cầu tôi muốn cái này, tôi muốn cái kia thì mình phải đưa ra đề xuất của mình và thuyết phục khách hàng. Mình sẽ được quyền design, làm document, làm từ A đến Z tất cả các giai đoạn luôn, design UI, design coding đến coding, testing.
Ở Rikkeisoft hiện tại đủ khả năng đáp ứng các loại dự án như vậy và hiện tại cũng đang tham gia vào các dự án từ phát triển yêu cầu đến lúc bàn giao thực thi cho khách hàng.
Không biết ở Rikkeisoft có cung cấp dịch vụ Onsite hay không và khách hàng Nhật liệu họ có sẵn sàng cho dịch vụ này hay họ chỉ cần một team làm Offshore?
Thật ra thì Rikkeisoft đã thành lập một chi nhánh bên Nhật Bản đặt tại Osaka và dự kiến tương lai sẽ mở nhiều chi nhánh hơn tại Nhật, nghĩa là Rikkeisoft có cung cấp dịch vụ onsite. Khách hàng ngày nay hầu hết đều yêu cầu onsite, vì onsite thuận tiện cho việc giao tiếp, quản lý từ phía khách hàng, giảm airforce quản lý cho khách hàng, khách hàng sẽ không phải trực tiếp quản lý offshore nữa. Những việc đó sẽ giao cho một lead ngồi cạnh khách hàng và xây dựng niềm tin khách hàng, nhất là trong lần đầu hợp tác.
Vì lần đầu làm việc họ sẽ không biết trình độ offshore như thế nào, văn hóa làm việc ở Việt Nam ra sao, họ sẽ cần một người làm sao để họ tin tưởng. Tiếp theo nó sẽ nâng cao level bridge cho nhân viên, vì khi ngồi cạnh khách hàng mình sẽ được giao tiếp tiếng Nhật nhiều hơn, mình được làm việc trực tiếp, được học hỏi công nghệ, kỹ thuật từ khách hàng luôn.
Thường sẽ mất bao lâu tính từ lúc khách hàng liên hệ cho đến khi bàn giao sản phẩm cuối cùng cho khách hàng?
Tùy thuộc vào yêu cầu của khách hàng, mức độ rõ ràng của yêu cầu và sự phức tạp của hệ thống thì nó sẽ có thời gian bàn giao khác nhau. Quy trình làm dự án sẽ có các bước như sau:
Đầu tiên, mình phải nghe hiểu yêu cầu khách hàng rồi đưa ra các đề xuất, giải pháp, lên báo giá.
Sau đó sẽ trình bày kế hoạch với khách hàng, sau khi khách hàng đồng ý với kế hoạch đó mình mới nhận dự án.
Sau khi nhận dự án mình sẽ lên plan chi tiết, thiết kế, coding, testing và bàn giao. Nếu có điểm nào khách hàng chưa hài lòng thì mình phải xem xét và revise lại. Một bridge sẽ tham gia nhiều nhất ở 3 công đoạn là làm rõ yêu cầu, tức là đọc hiểu tài liệu tiếng Nhật và trao đổi với khách hàng.
Tiếp theo là thiết kế và bàn giao, mình sẽ là người “chốt chặn” để đảm bảo chất lượng dự án trước khi bàn giao cho khách hàng.
Theo anh BrSE có còn là “hot job” nữa hay không và nhận định của anh về ngành nghề này ở Việt Nam trong 5 năm tới như thế nào?
Mình cũng đã gặp rất nhiều bạn trẻ hỏi những câu như vậy. Thật sự mình thấy nó vẫn hot, BrSE vẫn sẽ là nghề còn hot trong 5 năm tới. Đặc thù của ngành này là khách hàng khá là kĩ tính, khó tính, họ sẽ luôn luôn cần một người có thể hiểu được văn hóa của họ, ngôn ngữ của họ. Họ cần một dev như là cầu nối trong công việc để trơn tru hoạt động giữa 2 bên nên có thể khẳng định đây là nghề không bao giờ hết hot cả.
Liệu có phải vị trí BrSE chỉ xuất hiện trong các công ty outsourcing và chỉ khi công ty outsourcing làm việc với khách hàng/thị trường Nhật Bản?
Thuật ngữ kỹ sư cầu nối xuất phát từ các kỹ sư làm cho thị trường Nhật nhưng mình nghĩ vói các thị trường khác thì khách hàng đều mong muốn có người hiểu được ngôn ngữ của mình nên anh nghĩ ở thị trường nào cũng cần vị trí này cả, chẳng qua là tên gọi của nó có thể khác đi thôi.
Đối với những dev không mạnh về kỹ năng mềm có phải là rào cản để trở thành BrSE không?
Nó đúng là rào cản nhưng mình nghĩ càng là rào cản mình càng phải cố gắng vượt qua nó. Nó là một kỹ năng hoàn toàn có thể rèn luyện được vì với thời đại hiện nay một coder cũng cần có kỹ năng giao tiếp. Một dự án không chỉ một, hai người làm mà là cả một team nên rõ ràng tinh thần teamwork là rất cần thiết, giao tiếp tốt và BrSE còn phải giao tiếp với nhiều đối tượng khác nhau nữa nên đây thật sự là một kỹ năng rất quan trọng. Vì nó quan trọng như vậy nên không còn là rào cản nữa mà sẽ là một tiêu chuẩn, để mọi người nhìn vào đấy mà rèn luyện.
Theo anh các bạn dev có background nào thì dễ chuyển sang làm BrSE nhất? Trình độ coding nên ở level nào?
BrSE có nhiều level và nó còn phụ thuộc vào các yêu cầu của khách hàng nên mình thấy dev nên ở trình độ từ junior trở lên, kinh nghiệm đi làm từ khoảng 2 năm đổ lên. Vì lúc này bạn đã đủ kinh nghiệm trải qua các dự án rồi, đủ kiến thức nền tảng về kỹ thuật cũng như các kỹ năng mềm để làm việc với các dự án trơn tru hơn và không mắc phải các lỗi cơ bản nữa.
Và ngược lại, với những bạn có mindset BA tốt, management tốt, kỹ năng giao tiếp tốt nhưng lại không xuất thân là dev mà muốn trở thành “người kết nối” trong một công ty outsourcing thì theo anh có khả thi không?
Theo mình thì rất khả thi luôn. Những bạn có nghiệp vụ tốt sẽ được giao cho những dự án khá lớn, độ phức tạp cao hơn. Ở những dự án đó đòi hỏi ít hơn các kỹ năng về coding mà nó đòi hỏi những kỹ năng mềm nhiều hơn, về quản lý tiến độ, giao tiếp với khách hàng, kỹ năng mềm về autivation trong team. Những kỹ năng đó sẽ giúp đưa dự án đến thành công nên những bạn có mindset tốt như vậy sẽ được trọng dụng nhiều hơn cả trong ngành này.
Anh có kỷ niệm nào trong quá trình làm việc với khách hàng muốn chia sẻ với mọi người chứ?
Mình cũng đã từng thất bại nhiều lần vì thời điểm mới bắt tay vào làm bridge, mình khá là chủ quan, tự tin vào khả năng giao tiếp, tự tin vào tiếng Nhật của mình, nghĩ là mình đã hiểu những gì khách hàng chia sẻ. Rõ ràng là nếu quá tự tin như vậy mình sẽ luôn cho rằng ý nghĩ của mình như vậy là đúng.
Sai lầm ở đây là khi khách hàng đưa ra yêu cầu mình luôn luôn nói rằng tôi hiểu rồi trong khi thật sự yêu cầu của khách hàng vẫn chưa rõ ràng và đôi khi nó vẫn ẩn chứa nhiều rủi ro. Nên khi bắt tay vào làm thực tế mình mới phát hiện ra nó không dễ dàng như vậy, những gì mình hiểu chỉ là bề nổi thôi, có thể mình đã hiểu sai và kết quả là bàn giao sản phẩm sai, dẫn đến hậu quả khá nghiêm trọng.
Mình nghĩ đó cũng là một bài học mà các BrSE khi mới bắt đầu đều dễ mắc phải, thậm chí có những BrSE lâu năm cũng mắc phải. Lời khuyên của mình là các BrSE nên cẩn trọng khi nói những câu như “Tôi đồng ý”, “Tôi đã hiểu, “Tôi hiểu rõ rồi”,… Mình nên confirm lại các ý của khách hàng và hỏi xem tôi nói như vậy có đúng không, nếu chưa hiểu hoàn toàn thì nên Q&A đến lúc không còn gì để hỏi nữa thì mới tự tin là mình đã hiểu rồi. Khi nào mình vẫn còn lăn tăn trong đầu, vẫn còn phải phán đoán thì cứ thoải mái hỏi để hiểu rõ vấn đề.
Anh có thể chia sẻ lời khuyên khi phỏng vấn cho vị trí BrSE?
Với kinh nghiệm phỏng vấn của mình thì mình nghĩ khả năng giao tiếp và sự cầu tiến, tinh thần ham học hỏi của một BrSE cần phải được đặt lên hàng đầu. Khi phỏng vấn mình thường sẽ hỏi những câu như Giới thiệu về bản thân, kinh nghiệm làm việc ở các dự án trước, kinh nghiệm làm việc với người Nhật, dự án thành công, dự án thất bại thì rút ra bài học gì. Và mình nghĩ để trả lời tốt những câu hỏi này thì ứng viên nên trả lời thành thật, tự tin, bình tĩnh, không cần phải dùng những từ tiếng Nhật quá khó, hãy dùng những từ ngữ đơn giản, dễ hiểu miễn diễn tả được ý nghĩ của mình là được.
Hãy mạnh dạn hỏi lại người phỏng vấn nếu có vấn đề gì mình không hiểu, tự tin hỏi về công ty, phạm vi công việc, mong đợi của họ ở vị trí công việc bạn đang ứng tuyển là gì. Từ đó mình có thể trình bày là mình có gì để đáp ứng được những mục tiêu đó, lộ trình tương lai mình đặt ra để làm việc là gì. Một điểm cần lưu ý là khi phỏng vấn vị trí BrSE mình có phỏng vấn cả tiếng Nhật.
Anh có thể chia sẻ nguồn tài liệu nào để các bạn tham khảo học ngoại ngữ không, đặc biệt là với từ vựng chuyên ngành lập trình?
Thật ra có rất nhiều nguồn, nếu ai học ngoại ngữ thường xuyên sẽ biết đến phần mềm quizlet.com. Đây là phần mềm có rất nhiều các bài đã được soạn sẵn, có đến hơn 1000 bài từ vựng tiếng Nhật, muốn tìm từ vựng IT tiếng Nhật mình search IT Tocobaga sẽ có rất nhiều. Thứ hai là mọi người nên đọc báo như NHK, NHKYJ tùy theo trình độ của mỗi người. Hoặc là các video youtube nói về cách giao tiếp trong ngành IT, xem qua để mình thấy được phong thái nói chuyện, làm việc của họ để sau này tiếp xúc sẽ đỡ bỡ ngỡ hơn. Thứ 4 là mọi người có thể xin bản tóm tắt các từ vựng của những người đã làm việc với phía Nhật rồi, đây là một nguồn rất hữu dụng.
Bài viết được sự cho phép của tác giả Kien Dang Chung
1. Nguyên lý Inversion of Control là gì?
Trước khi đến với định nghĩa Inversion of Control là gì? bạn hãy cùng tôi làm vài cốc trà đá chém gió tí. Trong ghế nhà trường có lẽ ai cũng sợ nhất môn Triết học bởi mấy lý do, khó hiểu (trìu tượng), nhiều định nghĩa cần học thuộc. Thế nhưng Triết học lại là khoa học của mọi khoa học bởi nó trìu tượng ở một tầng cao nhất. Bản thân tôi cũng đã quên tất cả những gì học được (nói đúng hơn là thuộc được) trong Triết học ngay sau khi thi xong môn này, thế nhưng sau một thời gian khá dài bộn bề lo toan với công việc và cuộc sống, những khái niệm, quy luật ngày xưa thuộc trong Triết học tự nhiên cứ lẩn vẩn trong đầu và rồi ngẫm lại, đúng thật! Điểm lại chút về 2 nguyên lý, 3 quy luật và 6 cặp phạm trù trong Triết học, có thể trong phạm vi hiểu biết của mình và những trải nghiệm đến hiện tại nó đã làm nên tất cả những gì đang diễn ra xung quanh ta. Sở dĩ viết vài câu chuyện phiếm ở đây hầu chuyện các bạn vì các khái niệm mà chúng ta bàn thảo trong bài viết này khá là trìu tượng, nó cũng như triết học là nguyên lý của các nguyên lý. Một trong những quy luật mà tôi hay chiêm nghiệm nhất là quy luật lượng chất:
Những thay đổi đơn thuần về lượng, đến một mức độ nhất định, sẽ chuyển hóa thành những sự khác nhau về chất.
Friedrich Engels
Bạn học một cái gì đó, hoặc làm một cái gì đó có thể không hiểu ngay nhưng đến khi có một lượng kiến thức, kinh nghiệm nhất định, bạn sẽ đột nhiên hiểu ra nó. Do vậy, nếu các định nghĩa về Inversion of Control dưới đây quá trìu tượng, khó hiểu bạn cũng đừng quá quan tâm, đến một ngày nào đó khi bạn lập trình đủ 100 dự án, có 10 năm “giờ bay” trong lập trình… tự nhiên sẽ hiểu. Chuyện phiếm vậy thôi, giờ chúng ta cùng vào phần chính của bài viết nhé. Định nghĩa nguyên lý Inversion of Control
Inversion of Control (IoC) là một nguyên lý thiết kế trong công nghệ phần mềm với các đoạn code khi đưa vào một framework sẽ nhận được luồng điều khiển từ framework hay nói một cách khác là được framework điều khiển. Kiến trúc phần mềm với thiết kế này sẽ đảo ngược quyền điều khiển so với lập trình hướng thủ tục truyền thống. Trong lập trình truyền thống các đoạn code thêm vào sẽ gọi các thư viện nhưng với IoC, framework sẽ gọi các mã thêm vào.
Nói thật, tôi cũng cố gắng đưa ra định nghĩa này về ngôn ngữ con người có thể hiểu được nhưng nó vẫn quá trìu tượng hoặc do tôi chưa đủ “giờ bay” nên cũng chỉ dừng lại ở một định nghĩa như vậy. Tôi cũng đã thử tìm hiểu các định nghĩa khác trên Internet nhưng cũng chỉ nhận được một câu: “Tốt nhất bạn nên quên nó đi”. Lại nói về cách nhận thức một vấn đề, theo quan điểm phép duy vật biện chứng, hoạt động nhận thức của con người đi từ trực quan sinh động đến tư duy trừu tượng, và từ tư duy trừu tượng đến thực tiễn. Tóm lại nếu chúng ta đi vào cái định nghĩa chết tiệt này ngay thì là một sai lầm trong cách tìm hiểu về một vấn đề.
Chém gió thôi nhé, Triết học ngày xưa mình thi lại đến lần thứ 3 mới qua :).
Inversion of Control là một sự “thi phường” trong việc mở rộng một framework, một đặc tính trong các framework. Chúng ta cùng xem một ví dụ đơn giản về chương trình nhập thông tin người dùng theo kiểu thủ tục truyền thống:
<?phpfunction process_name ($name){echo"Your name: ".$name;}function process_job ($job){echo"Your job: ".$job;}echo"What is your name?";$answer=rtrim(fgets(STDIN));process_name($answer);echo"What is your job?";$answer=rtrim(fgets(STDIN));process_job($answer);
Khi chạy ứng dụng này trong màn hình dòng lệnh, các dòng code của chúng ta đang có quyền kiểm soát, nó quyết định được khi nào đặt câu hỏi, khi nào đọc dữ liệu người dùng nhập vào và khi nào xử lý các kết quả này.
Tiếp tục, chúng ta viết lại ứng dụng sử dụng framework Laravel ở dạng giao diện đồ họa. Sự khác biệt lớn nhất giữa hai ứng dụng này là luồng điều khiển (flow of control). Trong chương trình dòng lệnh, chúng ta kiểm soát được khi nào các phương thức được gọi, nhưng trong trong chương trình dạng đồ họa thì không. Framework sẽ kiểm soát việc đó bằng một vòng lặp liên tục kiểm tra xem có dữ liệu nào được nhập vào không? Có thể bạn nhập nghề nghiệp trước khi nhập tên. Như vậy, trong ứng dụng thứ hai quyền điều khiển đã bị đảo ngược, quyền kiểm soát đã được về framework.
Đây là một ví dụ trực quan về nguyên lý Inversion of Control, nguyên lý này làm người ta liên tưởng đến một nguyên tắc khi làm việc trong Hollywood “Đừng gọi cho chúng tôi, chúng tôi sẽ gọi cho bạn”. Bạn đã hiểu được IoC là gì? nhưng tôi thì chưa, thật sự nó vẫn …éo thể hiểu được. Tạm thời gác qua việc đó, chúng ta cần thêm “lượng” để đến với bước nhảy vọt về “chất” ở cuối bài.
Một đặc điểm quan trọng của framework là các phương thức được định nghĩa bởi người dùng thông thường được gọi từ trong bản thân framework chứ không phải từ code ứng dụng của người dùng. Framework đóng vai trò của chương trình chính trong việc điều phối và sắp xếp hoạt động ứng dụng. Sự đảo ngược quyền kiểm soát này tạo ra cho framework sức mạnh thông qua việc mở rộng. Các phương thức được viết bởi người dùng định nghĩa các thuật toán trong framework cho một tính toán cụ thể. Inversion of Control cho thấy sự khác biệt giữa một framework và một thư viện.
Một thư viện chỉ là tập hợp các tính năng mà bạn có thể sử dụng, nó được tổ chứ thành các class. Sau mỗi lần gọi một phương thức, thư viện sẽ làm một số việc và sau đó trả quyền điều khiển về cho người dùng.
Framework là một biểu hiện của thiết kế trìu tượng với nhiều hành vi được xây dựng sẵn bên trong, để sử dụng nó bạn cần chèn các hành vi của bạn vào các nơi khác nhau trong framework bằng các class hoặc plugin. Code của framework sẽ gọi đến code của bạn tại những điểm cần thiết.
Có nhiều cách để bạn đưa thêm mã vào framework, trong ví dụ trên chúng ta sử dụng một textbox, bất kỳ khi nào, textbox phát hiện sự kiện người dùng nhập liệu, nó sẽ gọi đến các code trong một “bao đóng”. Một cách khác để làm điều này là để framework định nghĩa các sự kiện và code người sẽ đăng ký vào các sự kiện này. Trong Laravel, bạn có thể phát sinh một sự kiện khi thao tác với một đoạn code của mình và framework có cơ chế kiểm soát các sự kiện đó, hay nói cách khác bạn đã ủy quyền lại cho framework.
Các phương pháp tiếp cận là rất tốt, nhưng thỉnh thoảng bạn muốn kết hợp nhiều lời gọi phương thức trong một đơn vị mở rộng, framework cần định nghĩa một interface để client code phải thực thi nó cho các lời gọi phương thức liên quan. Đây chính là nguyên lý đóng mở trong nguyên lý SOLID cho thiết kế hướng đối tượng.
Thực sự bạn nào đọc được đến đoạn này tôi phải rất cảm phục vì sự kiên nhẫn của bạn, nhưng một lần nữa cặp phạm trù nguyên nhân và kết quả rất đáng để chúng ta phải cố gắng. Nguyên nhân: bạn kiên nhẫn tống vào đầu mớ lý thuyết trìu tượng này, kết quả: đến cuối bài bạn hiểu được “Inversion of Control là gì?”.
Trong cái trực quan có cái trực quan hơn, vậy tìm cái dễ nhất để hiểu trước rồi hiểu cái phức tạp sau. Nếu bạn đã tìm hiểu sơ lược về IoC trên mạng, bạn sẽ thấy có cả một rừng các thuật ngữ liên quan như Dependency Inversion Principle (DIP), Dependency Injection Pattern (DI), IoC Container. Khá là khó để phân biệt các khái niệm này, chúng ta cần một khẩu quyết chứa đựng cả một tàng thư.
DI is about wiring, IoC is about direction, and DIP is about shape.
IoC là hướng đi và DIP là định hình cụ thể của hướng đi còn DI là một thực hiện cụ thể.
Khẩu quyết này tạm vẽ thành hình ảnh cho dễ nhớ.
Đến đây chắc bạn đã đồng tình với tôi: “Inversion of Control là nguyên lý của các nguyên lý”.
3. Inversion of Control được hình thành như thế nào?
Đôi khi chúng ta tự hỏi, các nguyên lý như IoC, SOLID… được hình thành như thế nào? Tại sao người ta có thể nghĩ ra chúng? Quay trở lại với lập trình hướng đối tượng là một cách giải quyết các vấn đề theo tư duy hướng đối tượng. Cách thức này mô phỏng hệt như thế giới ngoài đời, do vậy các nguyên lý thiết kế trong cuộc sống thật hoàn toàn có thể đưa vào trong lập trình. Tiếp theo đây là một ví dụ tôi đọc được từ cuốn Dependency Injection in .NET, một cuốn sách giải thích khá hay về các khái niệm IoC, DI, DIP…
Trong nguyên lý cuối cùng Dependency Inversion của SOLID chúng ta có nói đến một ví dụ về một chiếc đèn bàn có dây điện được đấu nối trực tiếp vào ổ điện trong tường mà không qua ổ cắm và phích cắm, còn trong ví dụ này chúng ta thay nó bằng cái máy sấy tóc. Trường hợp này cho thấy vấn đề rất lớn khi các đối tượng phụ thuộc chặt chẽ với nhau trong thiết kế.
Trong một lần đi nhà nghỉ cùng bạn gái (giả tưởng thôi nhé), tôi đã giật mình khi nhìn thấy hình ảnh chiếc máy sấy được nối trực tiếp vào trong ổ điện mà không thông qua ổ cắm và phích cắm. Mục đích thì đã rõ, những kẻ thích táy máy sẽ “tắt điện” khi nhìn thấy cảnh này. Nhưng chuyện gì sẽ xảy ra khi chiếc máy sấy này hỏng, dù nó có là hàng Nhật xịn nhưng cũng có lúc hỏng chứ.
Để sửa chữa là khá phức tạp, đầu tiên chúng ta phải ngắt át-tô-mát, sau đó mở cái hộp điện ra và thay chiếc máy sấy mới vào. Ông thợ nào không cẩn thận có thể không bật điện lên để test xem cái máy mới thay có hoạt động không. Trong lập trình cũng vậy, nếu các module phụ thuộc chặt chẽ vào nhau (thường dùng thuật ngữ tightly coupled) thì khi một module có vấn đề, cả hệ thống sẽ rối tung, rất khó để duy trì và phát triển.
Thông thường, chẳng ai chạy dây các thiết bị điện trực tiếp vào hệ thống điện, thay vào đấy là sử dụng một phích cắm và ổ cắm. Một ổ cắm là một interface với chuẩn cắm phải phù hợp với hình dạng phích cắm. Như vậy, máy sấy tóc với ổ cắm và phích cắm đã hình thành một kết nối không phụ thuộc (loosely coupled). Có thể có nhiều cách kết hợp các thiết bị điện này với nhau để ra một hệ thống. Trong lập trình việc kết hợp này có thể so sánh với design pattern và các nguyên lý thiết kế.
Máy sấy tóc sẽ không còn ràng buộc với hệ thống điện, nếu chúng ta cần ổ điện cho laptop, đơn giản là rút máy sấy ra và cắm laptop vào ổ cắm. Các nhà thiết kế ổ cắm không quan tâm đến thiết bị điện như laptop, điện thoại, tivi… nhưng các thiết bị này vẫn hoạt động tốt khi cắm vào. Các thiết bị khác nhau có thể cắm vào ổ cắm mà không ảnh hưởng gì tương tự như nguyên lý thay thế Liskov trong thiết kế phần mềm. Trong Dependency Inject, nguyên lý Liskov là một trong những nguyên lý quan trọng, nó cho phép đáp ứng những yêu cầu trong tương lai thậm chí chúng ta chưa biết gì về nó trong hôm nay. Cũng giống như trong thực tế, nếu 10 năm nữa có một thiết bị điện mới thì nó vẫn cắm vào cái ổ cắm này mà không cần phải thay đổi bên trong.
Khi pin laptop đầy, bạn sẽ rút phích cắm của máy laptop ra và chuyển sang dùng pin. Trong lập trình, chúng ta luôn mong muốn một service/module/class nào đó là đang tồn tại, nếu thành phần đó đã được gỡ bỏ, chúng ta sẽ gặp lỗi NullReferenceException, với tình huống này chúng ta sẽ tạo ra một interface mà nó không làm gì. Đây là một design pattern được biết đến với tên là Null Object, nó đáp ứng việc rút phích cắm ra khỏi tường.
Mọi điều có thể xảy ra, nếu như hệ thống điện của cả khu đang gặp vấn đề, bạn sẽ cần đến một bộ lưu điện UPS để vẫn hoạt động được thêm một thời gian. Máy laptop và bộ lưu điện có những nhiệm vụ khác nhau, đây chính là nguyên lý đơn chức năng (single responsibility) trong thiết kế phần mềm. Cả UPS và laptop đều được sản xuất bởi các nhà máy khác nhau, được mua ở những thời điểm khác nhau nhưng có thể sử dụng kết hợp được với nhau, thậm chí bạn có thể cắm cả máy sấy tóc khi laptop không cắm vào bộ lưu điện.
Một thực tế là các nhu cầu luôn thay đổi, các hệ thống luôn mở rộng và cần thêm tính năng, việc mở rộng đôi khi chỉ là cách lắp ghép các thành phần với nhau theo những cách khác nhau. Decorator pattern là mẫu lập trình giúp thêm tính năng cho một class mà không cần viết lại hoặc thay đổi các code có sẵn. Một cách khác để thêm tính năng mới vào một code có sẵn là tổng hợp các implement hiện có cửa một interface sử dụng Composite pattern. Với việc sử dụng ổ cắm dài, chúng ta có thể thêm vào hoặc bớt đi các thiết bị điện cần chạy. Với cùng cách này Composite pattern dễ dàng thêm bớt tính năng bằng cách thay đổi tập các interface.
Đôi khi chúng ta có một thiết bị được mua ở nước ngoài với chuẩn đầu cắm khác với ổ cắm đang có, chúng ta cần một bộ chuyển đổi. Adapter pattern cũng thực hiện cùng một nhiệm vụ với các bộ chuyển đổi. Chỉ với một ví dụ thực tế về hệ thống điện đơn giản, chúng ta đã thấy có rất nhiều các ý tưởng đã được thực hiện ở trong thế giới hướng đối tượng trong lập trình.
4. Tại sao dùng Inversion of Control
Chuyện phiếm, chém gió kèm theo bao nhiêu cốc trà đá rồi mà vẫn không thể hiểu được đang nói về cái gì? Hic…
Ngay chính trong định nghĩa Inversion of Control đã nói nên mục đích chính của nguyên lý này đó là tính mở rộng của một hệ thống. Quay lại với câu chuyện về máy sấy tóc, các thiết kế ở ngoài đời giúp cho việc mở rộng một hệ thống là quá đơn giản. Trong lập trình cũng vậy, nhờ thực hiện những định hình cụ thể từ các nguyên lý, một hệ thống ứng dụng sẽ có tính mở rộng. Nhưng để đạt được tính mở rộng cho một ứng dụng thì trước tiên ứng dụng này cần loại bỏ sự phụ thuộc giữa một đối tượng này với một đối tượng khác.
Tính mở rộng có thể mở rộng ra hơn nữa ở góc độ duy trì và phát triển ứng dụng. Một hệ thống có thiết kế đơn giản sẽ dễ mở rộng hơn một hệ thống phức tạp. Hơn nữa các hệ thống áp dụng nguyên lý Inversion of Control sẽ dễ dàng trong kiểm thử ứng dụng do các thành phần có sự độc lập nhất định.
5. Quán đến giờ đóng cửa, hết trà đá!
“Em ơi! Anh thêm cốc nữa đê…”, không một tiếng đáp lại, miệng khô đắng, giọng gằn lên “Chủ quán…”, mịa nó chứ vẫn im lặng như tờ, cúi xuống định vớ đại con Chaco 81 lỗ quăng vào… Úi quá nửa đêm roài, con mưa ảnh hưởng bão cũng đã tạnh, chỉ còn chút gió vi vu… “Quán đến giờ đóng cửa, hết trà đá!” giọng nói lanh lảnh cất lên từ một khuôn mặt bây bi con bà chủ quán.
Mải chém gió, giờ mới nhớ ra, mới được nửa chặng đường từ trực quan đến tư duy trìu tượng. Thế còn từ tư duy trìu tượng đến thực tiễn, thôi hẹn bữa khác mạn đàm tiếp…
Các phần mềm trên iOS thông thường được người dùng tải về từ App Store – kho ứng dụng của Apple.
Các phần mềm này được viết bằng các ngôn ngữ lập trình Objective-C và sau này được thay thế bằng Swift.
Để phát hành phần mềm, nhà phát triển phải đăng ký 1 tài khoản Developer để được cấp phép phát hành phần mềm. Apple có thu phí cho loại tài khoản Developer này.
Objective-C hoặc Swift được lập trình bằng IDE Xcode:
3. Các yêu cầu để bạn có thể học được iOS
iOS là một phần trong hệ sinh thái của Apple nên bạn chỉ có thể lập trình iOS trên hệ điều hành MacOS. Đo đó bạn cần có một chiếc máy tính cài đặt MacOS hoặc sử dụng máy ảo MacOS
(Lời khuyên của mình, nếu bạn muốn trở thành một lập trình viên Swift hay lập trình viên iOS, mà xem đó là nghề của bạn, thì bạn nên mua một chiếc máy tính Macbook.)
Yêu cầu về phần cứng khi cài đặt Mac OS X chi tiết như sau
HDD (Hard drive): Đề xuất SSD. Tuy nhiên SATA cũng có thể chấp nhận.
Và đặc biệt các bạn đã biết 1 ít về các giải thuật trong lập trình.
Có tinh thần trách nhiệm và chịu khó thì mới có thể trở thanh lập trình giỏi.
4. Cơ hội nghề nghiệp lớn và lương cao
Bạn có thể tìm các trang tuyển tuyển dụng trên https://itviec.com/ thì thấy nhu cầu đối với nghề IOS cực kỳ lớn và mức lương cũng cao hơn lập trình web.
Hoặc bạn cũng có thể kiếm tiền với IOS ngoài việc làm ở công ty:
Bạn đã biết nhiều người kiếm tiền doanh thu lơn nhất hiện nay từ đâu và đặc biệt là anh Nguyễn Hà Đông với game flappybird là họ đã tích hợp admob vào app.
Bạn có thể làm các dự án Freelance có thể kiếm tiền tương đối lớn.
Ơn trời, cải tiến của Java 13 Switch và Text Blocks đây rồi!
1. Ấp ủ từ lâu
Ở Java 13, sự có mặt của JEP 354: Switch Expressions là sự kế thừa từ Java 12 Switch Expressions. Bản Java 12 đã bổ sung từ khóa yield (như bên Python). Mục đích của từ khóa yeild là return giá trị trong biểu thức Switch.
Đối với chuyện cộng chuỗi string bằng plus (+) thì quá đỗi ám ảnh anh em coder Java rồi. Mà hầu như chẳng còn xài nữa. Giờ có viết cũng cố đổi qua String Builder hay Buffer gì đó, chú ý sao cho performance không ảnh hưởng.
Tất nhiên, Java không như Javascript, cải tiến hay release feature mới liên tục, mỗi tuần vài shot. Nhưng mỗi thay đổi trong Java đều được chú ý, vì ít khi thay đổi.
Cùng xem xem có gì thay đổi khi Oracle release bản Java 13 nha. Đã là lập trình viên thì chắc chắn đụng tới Switch case hằng ngày. Tại sao?
Viết switch case trông code clean hơn hẳn.
Nhìn rõ ràng, dễ handle các case.
Trường hợp 6,7 cái trở lên thì ăn đứt if, else
// Kiểu viết thông thường
private String swithCaseNormal(int chanom) {
String result = "Kieblog";
switch (chanom){
case 1:
result = "Old switch";
break;
case 2:
result = "New switch";
break;
default:
yield -1;
break;
};
return result;
}
Ở Java 13 đã chuyển qua sử dụng yeild như thế này:
// Ở Java 13, không còn break, thay vào đó là yeild
private String swithCaseNormal(String mode) {
String result = "Kieblog";
switch (mode) {
case 1:
yield "Old switch";
case 2:
yield "New switch";
default:
yield -1;
};
return result;
}
Tuy nhiên, nếu viết kiểu arrow mũi tên thì Java 13 vẫn support như thường
// Nếu lỡ viết kiểu arrow như Java 12 thì Java 13 vẫn support như thường
private String swithCaseNormal(String mode) {
String result = "Kieblog";
switch (mode) {
case 1 -> "Old switch";
case 2 -> "New switch";
default -> -1;
};
return result;
}
Bỏ đi breaks để sử dụng arrow và yeild cũng có một số cái lợi như sau:
Đỡ mất công break cho từng case
Tránh bug khi quên break sẽ nhảy xuống case khác
Ngắn source, đơn giản, dễ hiểu, viết lẹ nữa chứ
3. Text Blocks
Thật lòng mà nói, ngoài Java 13 Switch, Text Blocks như là vị cứu tinh cho mấy cái dự án JDBC cũ cũ. Cũng đỡ tạo ác cảm, khẩu nghiệp cho lập trình viên.
Cứ có gì cần công chuyện, append bằng String Builder, String Buffer thì mệt vãi đ**. Mà cộng chuỗi bằng “+” thì củ chuối không thể chịu được.
// Một số dự án maintain SQL cũ còn viêt SQL Statement theo kiểu này
class KieBlog {
public void kieblogMain() {
String txt =
" Kie\n" +
" Blog\n" +
" Content\n" +
" Is\n" +
" Good\n";
}
}
Một số dự án render hoặc trả message lỗi bằng HTML tĩnh viết kiểu String cũng như được giải thoát
// Cách viết đơn giản, đỡ đâu đầu, chỉ cần """ rồi viết
class KieBlog {
public void kieblogMain() {
String txt = """
Kie
Blog
Content
Is
Good
""";
}
}
Sử dụng “”” cũng bỏ luôn nỗi ám ảnh dài lâu về tab hay space. Không format code cũng không được, mà format cho đẹp thì mất công, mất sức. Ba dấu phẩy thật sự lợi hại, tiết kiệm thời gian.
Trong phần 2, Smartjob sẽ tiếp tục cùng các bạn tìm hiểu những loại bàn phím được lập trình viênyêu thích nhất được tác giả Phil Johnson của IT World tổng hợp. Mình tin rằng trong phần này các bạn sẽ được nhìn thấy những kiểu dáng rất quen thuộc trong khoảng chục năm trở lại đây. Nếu bạn thích chúng, đừng ngại ngần bỏ công sức ra sưu tầm bởi sau này tìm lại được những mẫu thiết kế như thế chẳng hề dễ dàng gì.
Mọi người đã nói gì về nó? Không đắt đỏ, không cầu kỳ, trọng lượng nhẹ, nhỏ gọn với 104 phím và nút bấm. Những phím quan trọng vẫn được đặt ở các vị trí quen thuộc, không có marco hay phím media. Các phím có phản ứng với xúc giác nhưng vẫn rất yên tĩnh khi làm việc.
Nhận xét:
“Được làm việc với nó là một niềm vui lớn của tôi. Khi gõ phím, tôi có cảm giác mọi thứ đều thuộc về mình. Nó thực sự là chiếc bàn phím thuộc về tôi chứ không đơn thuần chỉ là một miếng nhựa lớn.” Tanerax
“Còn gì tuyệt vời hơn L100. Bạn có thể mua nó với chi phí cực rẻ. Đó là một sản phẩm hoàn hảo với tôi.” Polemon
“ Đây là bàn phím tốt nhất tôi đã từng sử dụng. Tôi nghĩ đây là loại bàn phím mà mỗi lập trình viên nên có.” Vedarthk
“Dell là bàn phím tuyệt vời.” Robert Harvey
Deck – 2005
Các phím của Deck được thiết kế theo kiểu phím cơ Cherry, là một loại backlit keyboard (bàn phím có đèn LED với các màu sắc khác nhau), có thể sáng cục bộ hoặc mờ đi tùy cách lập trình viên sử dụng. Loại bàn phím này có hai cỡ lớn và nhỏ (gồm 82 phím) như những phiên bản trước. Ưu điểm nổi bật của bàn phím Deck là rất bền với thời gian.
Nhận xét:
“Tôi thích mọi loại bàn phím của Deck. Chúng trông thực sự mát mẻ với gam màu lạnh và khiến tôi rất thoải mái khi gõ phím.” Spong
“Đây là bàn phím duy nhất trong loại của nó theo kiểu backlit. Nó hoàn toàn phù hợp với chiếc cặp của bạn.” Jeff Atwood
“The Deck được xây dựng dựa trên thực trạng lạm dụng bàn phím của game thủ vì vậy chúng rất bền. Đó là loại backlit nên bạn có thể thấy rõ những gì mình đang hack ngay cả khi tắt đèn vào lúc 2 giờ đêm.” Ken Jenni ngs
“ Nó thực sự rất tuyệt – Được thiết kế kiên cố và có màu xanh. Bàn phím đó sẽ mang lại cho bạn nhiều hơn những gì bạn có thể tưởng tượng.” John McC
Nhận xét của Smartjob: Nếu bạn thường xuyên phải code đêm, code rất nhiều thì đây là lựa chọn không thể bỏ qua. Nó sẽ giảm thiểu tối đa những tác hại mà bàn phím thông thường gây ra. Ngoài ra, gam màu đen kết hợp ánh sáng xanh sẽ làm cho quá trình làm việc của bạn có được hiệu quả cao khi phải ngồi lâu bên máy tính.
Das
Đây thực sự là loại bàn phím cho người lập dị – Nó được thiết kế tương tự bất cứ bàn phím thông thường nào khác chỉ có điều trên các phím không có bất cứ chữ cái, con số hay kí hiệu nào. Các phím trống tưởng có thể làm khó cho nhiều người tuy nhiên với một số lập trình viên nó thực sự đem lại cảm hứng lớn khi đánh máy. Tốc độ và sự chính xác sẽ được gia tăng đồng thời phím cơ Cherry MX sẽ mang đến cảm giác thỏa mãn khi gõ. Âm thanh của phím, không cần nhìn mà vẫn biết mình đang gõ gì – Đó là hai điểm khác biệt của Das.
Nhận xét
“Chúng thực sự khiến bạn gõ nhanh hơn. Bạn có thể gõ trong khi đang nói chuyện với mọi người.” Tom Morgan
“Người khác sẽ không thể đụng vào bàn phím của bạn nếu bạn chơi kiểu này =)).” Ackthpt
“Phải mất một khoảng thời gian để làm quen nhưng sau đó bạn có thể gõ phím mà không cần nhìn.” Luke Girvin
“Bàn phím này cho thực sự đem lại cho bạn nhiều sức mạnh. Bạn làm việc lâu bao nhiêu kết quả của bạn sẽ tốt bây nhiêu.” Jakobud
“Gõ kiểu này còn tốt hơn quan hệ tình dục.” Jeremy Cantrell
Microsoft Natural Ergonomic 4000 – 2005
Bàn phím Ergonomic tự nhiên hơn đối với rất nhiều người. Hai miếng đệm dựa luôn tạo ra sự thoải mái và giảm bớt việc bị đau cổ tay.
Nhận xét:
“ Cổ tay và bàn tay của tôi cảm giác thoải mái đến lạ kì. Những miếng da tạo cho bàn tay tôi cảm giác thoải mái hơn nhiều so với bàn phím chỉ toàn nhựa.” Paul Nathan
“Nó rất phù hợp với những người có bàn tay lớn.” JBRWilkinson
“Bàn phím tốt nhất mà tôi từng sử dụng. Mua một chiếc như vậy là quá đủ cho home(tôi là người sử dụng Linux)” David Rabinowitz
“Tuyệt vời, rất thoải mái. Mọi người sẽ tránh xa chiếc máy tính của tôi khi không thể sử dụng cái bàn phím kì lạ đó.” HappyCat
Microsoft Comfort Curve – 2005
Nó nhiều công thái học hơn bất cứ loại bàn phím nào – không quá lớn, không quá đắt tiền như bàn phím Natural Ergonomic của Microsoft. Một vài trong số chúng được thiết kế với các phím thấp.
Nhận xét:
“Đó là sự kết hợp tuyệt vời giữa bàn phím cơ bản và Ergonomic ” Carlos
“Đường cong tạo ra sự khác biệt. Ngoài ra mặt trên của bàn phím rất phẳng nên tôi có thể đánh phím từ mọi góc độ mà vẫn cảm thấy thoải mái. Các phím cũng rất dễ bấm.” EpsilonVector
“Các phím thấp thực sự rất hữu ích. Chúng được uốn cực kỳ chính xác và khi gõ cảm giác rất yên tĩnh.” Nlawalker
“Đẹp, bàn phím cứng, giá cả tuyệt vời… Nói chung nó rất tiện lợi vời những người đánh máy lâu năm.” Rob
Bàn phím nhôm không dây của Apple (Apple Aluminum)
Đây là loại bàn phím rất quen thuộc với các fan của Apple. Apple Animinum được thiết kế khá mỏng, bao bọc bởi vỏ nhôm và cách bố trí khá giống MacBook. Nhiều lập trình viên rất thích sự nhỏ gọn của nó (không có vùng phím số) và cơ chế ngăn cản caps-lock.
Nhận xét:
“Các phím ngăn cách nhau bởi bề mặt nhôm và điều đó giúp ích rất nhiều trong việc phòng ngừa lỗi fat-finger. Tôi khuyến khích các bạn nên dùng nó bất kể bạn đang dùng hệ điều hành nào.” Haploid
“Nhỏ gọn và xinh đẹp :D.” Randolf RF
“Đây là loại bàn phím yêu thích của tôi.” Dongsheng Cai
Như vậy là 12 loại bàn phím “bá” nhất đã được chúng ta khám phá. Đó là 12 kiểu dáng cơ bản nhất mang lại cảm hứng cho những mẫu thiết kế đương đại. Một lập trình viên thông minh không chỉ là người biết gõ code, fix lỗi hay hùng hục chạy theo các dự án. Các bạn hãy chọn cho mình loại bàn phím phù hợp nhất để có được thêm niềm cảm hứng và đam mê với công việc lập trình. Biết tận hưởng luôn tốt hơn là chỉ chăm chăm vào công việc. Chúng tôi sẽ tiếp tục đồng hành cùng các bạn trong suốt quãng đời của một lập trình viên và sẽ mang lại những kiến thức bổ ích nhất, biến lập trình trở thành một công việc thú vị chứ không chỉ là làm việc với những đoạn code khô khan, nhàm chán.
Theo Phil Johnson – Bài viết gốc được đăng tải tại smartjob.vn
Bài viết này sẽ giới thiệu tiếp phần còn lại của những kinh nghiệm tự học lập trình mà bạn có thể học hỏi để tự phát triển bản thân trong chặng đường trở thành developer của mình.
Kinh nghiệm tự học lập trình: Xây dựng không gian làm việc phù hợp
Tạo dựng cho bản thân một môi trường làm việc riêng biệt và khiến bản thân cảm thấy thoải mái có lẽ là điều duy nhất khiến tôi cảm thấy mình đã có quyết định đúng, cũng như muốn chia sẻ lại với bạn về kinh nghiệm tự học lập trình.
Cá nhân tôi không cảm thấy mình phù hợp với những môi trường quá yên tĩnh hay một không gian khép kín. Vậy nên tôi thường lựa chọn cho mình một vài quán cà phê gần nhà hoặc thư viện để học. Tôi thích âm nhạc vì vậy kể cả là khi đang tập trung để nghiên cứu tôi vẫn đảm bảo lượng âm thanh vừa đủ lớn để khiến tôi tập trung và không quan tâm đến những thứ diễn ra xung quanh.
Rõ ràng với môi trường làm việc phù hợp này tôi đã tăng hiệu suất học tập và nghiên cứu của mình lên đáng kể. Trong khi đây là một phần rất quan trọng thì vẫn có khá nhiều người bỏ qua nó.
Tập trung là một phần cơ bản nhưng có vai trò tiên quyết trong việc giúp bạn thu thập thông tin và tăng cường khả năng ghi nhớ. Khi bạn cố gắng tập trung để tăng cường khả năng ghi nhớ, sức mạnh của việc tiếp thu kiến thức sẽ được liên kết trực tiếp với cường độ tập trung. Khả năng tập trung kém đồng nghĩa với việc bạn sẽ học chậm hơn và mất nhiều thời gian hơn.
Hãy tìm cho mình một môi trường làm việc không khiến bạn bị phân tâm và cho phép khả năng tập trung có thể kéo dài lâu nhất có thể. Dưới đây là một số cách bạn có thể áp dụng để tạo cho mình một môi trường học tập và làm việc tập trung nhất:
Tìm một vị trí mà mọi người ít để tâm và không thể làm phiền bạn.
Cho điện thoại về chế độ im lặng hoặc để chế độ máy bay.
Sử dụng một số loại trình chặn trang web được hẹn giờ cho các trang web truyền thông xã hội và tin tức.
Đeo tai nghe và nghe các bản nhạc có thể tăng cường sự tập trung khi làm việc (tốt hơn hết nên là một danh sách dài các bài hát để tránh khiến bạn phải mất thời gian để chuyển bài).
Nên có một cuốn sổ bên cạnh để ghi chú lại bất kì thông tin mới nào hoặc một ý tưởng nào vừa nảy ra.
Chính bạn sẽ là người biết được đâu là môi trường làm việc tốt nhất với mình. Hãy cố gắng đưa ra những quyết định đúng đắn và tạo cho mình một không gian làm việc giúp tối ưu sự tập trung của bản thân nhé.
Bước ra thế giới bên ngoài và gặp gỡ nhiều người hơn
Công việc lập trình đến với tôi một cách rất ngẫu nhiên. Sau khi chuyển đến nơi ở mới tại Omaha, Nebraska, tôi đã dành khoảng một năm cho việc tự học lập trình. Vì dành quá nhiều thời gian và sự chuyên tâm cho việc học nên tôi không quen biết thêm được nhiều người mới tại đây.
Tôi quyết định tìm kiếm trên Meetup.com những người có cùng sự quan tâm đến việc lập trình android giống mình. Trong buổi giao lưu giữa các nhà phát triển android tôi đã cảm thấy hơi lo lắng và sợ hãi khi nhận thấy mọi người có nhiều kinh nghiệm hơn hẳn tôi và tôi hoàn toàn không đủ tự tin về khả năng lập trình của mình.
Tuy nhiên, may mắn là tôi đã không từ bỏ và tham gia các buổi Meetup này một cách thường xuyên hơn. Và không lâu sau tôi đã gặp một chuyên gia đang tìm kiếm một nhà phát triển trong lĩnh vực Android. Sau một lúc nói chuyện, tôi đã được hẹn đến để tham gia buổi phỏng vấn vào cuối tuần.
Trước khi đến buổi phỏng vấn, tôi đã rất tự tin rằng mình có thể làm tốt. Nhưng, sau khi buổi phỏng vấn diễn ra thì tôi cảm thấy khó khăn hơn hẳn. Người phỏng vấn nói về các dự án mà tôi sẽ phải tham gia và mọi thứ cứ thế lướt qua trong đầu tôi mà thôi. Dù tôi đã cố gắng tiếp tục tham gia nhưng dường như nó nằm ngoài khả năng của tôi. Sau buổi phỏng vấn tôi dành thời gian để thư giãn và suy nghĩ nhiều hơn về các thông tin mà công ty chia sẻ. Kết quả tôi nhận được là họ yêu cầu tôi tham gia vào công ty với vai trò là một thực tập sinh. Tôi thật sự rất bất ngờ với kết quả này.
Nhờ sự cố gắng và nỗ lực không ngừng mà sau khoảng thời gian thực tập, tôi đã được cân nhắc lên làm việc với tư cách một nhân viên chính thức về phát triển phần mềm. Khi bạn tự học, mọi người sẽ không thể nào biết hay tìm kiếm bạn. Bạn sẽ cần phải tự đi tìm kiếm cơ hội cho chính mình. Một sinh viên sau khi tốt nghiệp đại học có thể tận dụng lợi thế mạng lưới công việc do trường cung cấp để tìm việc. Nhưng với những nhà lập trình tự học, đây là một thứ xa xỉ.
Hãy cố gắng tự bước ra ngoài và xây dựng mạng lưới quan hệ cho bản thân để gia tăng cơ hội tìm kiếm những công việc tốt hơn. Bạn có thể xây dựng thông tin cá nhân trên các cổng trực tuyến để nhà tuyển dụng nhìn thấy bạn. Tuy nhiên, tìm việc thông qua những người quen cũng là một cách khá hay ho để bạn có thể tìm thấy những cơ hội việc là tốt nhất.
Các trang web như Meetup.com sẽ là một nơi tuyệt vời để tìm kiếm các hội nhóm dành riêng cho cá nhân và hoạt động theo nhóm. Ngay cả trong thời điểm dịch xảy ra, các buổi họp mặt nhóm online vẫn được tổ chức, cung cấp cho bạn nhiều thông tin có lợi và bổ ích.
Ngoài ra còn có các kênh khác như Slack hoặc Discord cũng là những nền tảng khá phổ biến được nhiều lập trình viên sử dụng để kết nối và mở rộng quan hệ. Khi gặp nhau, hãy thân thiện và chia sẻ về kinh nghiệm bạn với đối phương, đảm bảo để họ có thể biết được mục đích của bạn là đi tìm việc.
Hãy cân nhắc bất cứ cơ hội nào xuất hiện trong cuộc đời mình, vì biết đâu chính cơ hội đó, quyết định đó sẽ là thay đổi con đường sự nghiệp của bạn. Rõ ràng công việc thực tập mà tôi đã nhận trước đó có vẻ không thật sự phù hợp với tôi, nhưng tôi vẫn chấp nhận. Nhờ sự chăm chỉ và tận tâm mà tôi đã có thể lấn sân sang lĩnh vực lập trình một cách nghiêm túc và có cơ hội trở thành một nhân viên fulltime. Quan trọng là bạn cần biết vạch ra những hướng đi ngắn hạn và dài hạn phù hợp cho bản thân.
Điều quan trọng nhất mà tôi muốn chia sẻ là bạn có thể từ những lỗi lầm của mình là để bạn có thể rút ra được bài học cho cá nhân. Hạn chế tối đa những lỗi sai có thể biết trước chắc chắn sẽ giúp ích nhiều hơn cho công việc tương lai của bạn cũng như rút ngắn lộ trình của một công việc thành công. Hi vọng những kinh nghiệm tự học lập trình được chia sẻ sẽ giúp bạn cải thiện mọi thứ tốt hơn.
Bài viết được sự cho phép của tác giả Lê Xuân Quỳnh
Hello mọi người! Trong bài hôm nay chúng ta sẽ phát triển ứng dụng lên một tầm cao mới. Đó là có thể sử dụng ứng dụng offline được. Không cần mạng internet, chúng ta vẫn có thể truy cập dữ liệu đã tải trước đó. Như các bạn thấy, một số ứng dụng tiêu biểu cho việc này là facebook. Khi bạn tắt mạng đi, thì nó vẫn có thể đăng bài, tải các bài trên feed đã lưu trước đó. Trông cũng khá ổn, nó tăng tính trải nghiệm người dùng hơn, chuyên nghiệp hơn đúng không nào?
Vậy thì, hôm nay chúng ta làm điều đó, bằng 1 framework cho database, khá chuyên nghiệp đó là Realm. Vậy realm là gì? Có thể bằng vài câu thì không nói hết được các tiện ích mà framework này mang lại. Tuy nhiên, bạn có thể hiểu nôm na là realm giúp bạn lưu trữ giữ liệu, lôi ra khi cần. Bạn có thể thêm sửa xóa, có thể làm mọi thứ với dữ liệu bạn đã lưu. Rất tiện ích. Để hiểu hơn hãy đọc cẩn thận tài liệu của realm cho ios ở đây:
Trong bài trước, chúng ta đã thêm loading cho phần tìm kiếm để nó chuyên nghiệp hơn. Vẫn còn vài bug nhỏ, nhưng các bạn tự fix xem nhé. Trong bài lần này, tôi sẽ thêm realm vào để lưu trữ toàn bộ kết quả mà bạn đã search vào bộ nhớ. Sau đó mỗi lần search, nếu như nó tìm thấy kết quả đã có trong bộ nhớ, nó sẽ tiến hành lấy kết quả đó và hiển thị vào table, thay vì request lên network.
Đầu tiên như những bài trước, bạn phải tải code tại đây:
Và chuyển qua branch bai4 các bạn nhé. Cách chuyển thì xem lại bài đầu tiên nha.
Rồi bây giờ cùng bắt đầu làm quen và sử dụng realm bằng 1 cách chuyên nghiệp nào.
Xây dựng realm manager
Lớp RealmManager
Hãy xem xét lớp RealmManager mà tôi đã tạo. Source code hơi dài, nhưng đừng lo lắng, tôi sẽ phân tích từ từ từng dòng 1.
Ý tưởng của lớp này như sau:
Tôi muốn tạo 1 lớp quản lý database có đầy đủ tính năng thêm(save), sửa(update), xóa(delete).
Tôi muốn lưu trữ các model kế thừa từ Codable. Bằng việc này tôi có thể lưu thẳng kết quả trả về của API từ server vào realm.
Mỗi model phải có 1 khóa chính để update. Việc save có nghĩa là update 1 model vào realm. Nếu như nó chưa tồn tại thì thêm mới. Nếu nó đã có thì cập nhật vào model đã có sẵn.
OK, khi có realm manager này, các bạn sẽ dễ dàng làm những việc mà mục tiêu của đề bài đã yêu cầu.
Hãy cùng xem code từng dòng nhé:
Đầu tiên để chơi với realm, bạn cần phải cài đặt realm vào Podfile nhé:
Việc cài đặt rất đơn giản, bằng việc bạn mở Podfile ở project rồi thêm dòng 8 vào. Sau đó vào command line và cd vào thư mục source code, gõ: pod install là xong!
Khi cài xong rồi, bạn tạo 1 file có tên là RealmManager.swift, sau đó thêm dòng này vào trên cùng:
import Realm
import RealmSwift
2 dòng trên để các bạn có thể sử dụng realm.
/// Version realm database
enum RealmVersion: UInt64 {
case version1 = 0
}
Dòng trên tôi dùng để update database cho realm. Mỗi khi tôi sửa lại model thì cần migration, liên quan đến cập nhật dữ liệu với model mới. Cái này bạn sẽ quan tâm sau, bài này tôi không nói.
Tôi muốn update database theo khóa chính nên bạn cần có 1 cái RealmRepresentable bắt buộc phải có 1 khóa chính, tôi đặt tên là uid mà mọi object Codable muốn sử dụng realm đều phải có, tôi dùng protocol để làm việc đó. RealmRepresentable giúp bạn luôn phải có khóa chính cho model, đảm bảo model luôn luôn cập nhật được. RealmRepresentable này kế thừa từ Object – một class của realm dùng để xử lý database giống như model. Nếu bạn đã làm qua với sqlite, thì bạn sẽ thấy ưu điểm của realm ở đây, là bạn có thể thao tác với realm như thao tác với model vậy. Không phải select, delete… những câu lệnh khó nhằn của sql.
Protocol các hàm cơ bản của realm service
RealmServiceProtocol là protocol chứa các hàm có thể có của 1 manager. Nhìn tên hàm bạn cũng có thể đoán được ý nghĩa của nó đúng không:
associatedtype Entity: Định nghĩa 1 kiểu trừu tượng, protocol generic placeholder. Nói cách khác nó áp dụng kiểu cụ thể tại thời điểm compile. Nó làm cho code clear hơn nha. Entity chính là model chúng ta cần lưu, cụ thể là class của model codable kế thừa từ Object của realm.
queryAll: Hàm này trả về toàn bộ mảng [Entity]
func query(with predicate: NSPredicate, sortDescriptors: [NSSortDescriptor]) -> [Entity]: Hàm này dùng để truy vấn với điều kiện nào đó và sắp xếp theo yêu cầu nào đó.
func save(entity: Entity) -> Bool: lưu 1 entity vào database.
Ô kê la, vậy là bạn đã hiểu chúng ta sẽ làm gì rồi đúng hông? tất nhiên protocol thì là define thui, còn bây giờ mới tới màn coding thật sự nè. Nào hãy vào lớp RealmManager để xem nhé
Class RealmManager định nghĩa hơi khác 1 chút so với những gì bạn hay làm. Ở đây ta có toán tử <T: RealmRepresentable>, nghĩa là mọi lớp kế thừa lại lớp này đều phải có tính chất của RealmRepresentable, hay nói cách khác nó phải có khóa chính:
var uid: String { get }
RealmManager kế thừa RealmServiceProtocol, nghĩa là mọi hàm chúng ta vừa nói ở trên đều phải định nghĩa cho nó.
typealias Entity = T: Ở đây chúng ta định nghĩa kiểu của Entity là T, là RealmRepresentable, tức là các class có tính chất của RealmRepresentable
Realm.Configuration: Cấu hình tham số cho Realm.
var realm: Realm?: đối tượng realm mà chúng ta sẽ sử dụng để xử lý các tác vụ với database.
Hàm init khởi tạo configuration, trong này chứa việc xử lý việc thay đổi model của realm. Bạn có thể xem thêm ở đây để hiểu thêm.
68->71, nếu không khởi tạo được realm thì trả về rỗng
Nếu không thì lấy mảng Entity và trả về
Hàm lưu Entity
Nếu như không khởi tạo được realm thì trả về false
Nếu không tiến hành lưu entity vào database theo dạng update, nghĩa là nếu chưa có thì thêm mới vào, còn nếu đã tồn tại thì cập nhật. Sau đó refresh lại realm database.
Giả sử quá trình lưu thất bại, tiến hành in lỗi. Ở đây các bạn có thể để lệnh print trong cặp #if DEBUG
Tương tự hàm save 1 chuỗi “func save(entities: [Entity]) -> Bool” cũng như trên, chỉ khác là lưu 1 mảng vào.
Hàm xóa 1 Entity
Tiến hành tìm kiếm entity có khóa chính uid, nếu tìm được thì tiến hành xóa và trả về true. Nếu không trả về false.
Trường hợp xóa lỗi cũng hiển thị lỗi và trả về false.
Tương tự hàm “func delete(entities: [Entity]) -> Bool” dùng để xóa 1 mảng entities.
Hàm xóa toàn bộ Entity
Tiến hành xóa toàn bộ entities trong database và trả về true. Nếu không xóa được báo lỗi và trả về false.
Ở đây các bạn để ý mình viết hàm có phần comment ở trên hàm. Nếu bạn muốn nó sinh tự động có thể đặt con trỏ chuột vào tên hàm và bấm tổ hợp “Option + Command + /”, khi các bạn bấm vào dấu ? bên phải Xcode thì nó ra hướng dẫn của hàm, rất tiện lợi cho việc sinh documents sau này.
Hướng dẫn chuẩn format của Apple
Vậy là chúng ta đã hoàn thành cơ bản lớp RealmManager, base cơ bản để xử lý database trong realm.
Bài đã hơi dài, nên chúng ta sẽ tạm thời dừng ở đây. Trong bài tiếp theo mình sẽ hướng dẫn viết lớp RealmGithubService kế thừa từ RealmManager để xử lý data trả về từ API nhé.
Bàn phím là công cụ không thể thiếu với mỗi lập trình viên. Họ dùng chúng hằng ngày, tiếp xúc với chúng nhiều hơn bất cứ thứ gì khác. Với mỗi người sẽ có những loại bàn phím ưa chuộng riêng tùy theo sở thích, phong cách làm việc của họ. Sau đây là 12 loại bàn phím được rất nhiều lập trình viên muốn sở hữu bởi các style và tính năng riêng biệt mà chúng mang lại. Các bạn sẽ được chiêm ngưỡng những kiểu dáng điển hình nhất của từng thời đại, đã làm nên tên tuổi của các nhà sản xuất và đã gắn bó với giới lập trình trong một khoảng thời gian dài.
Đươc thiết kế với sự chủ đạo là tính đàn hồi, đem lại cảm giác rất thỏa mãn cho người dùng. Các lập trình viênđã từng rất ưa chuộng model này và rất thích thú với âm thanh của bàn phím. Chúng ta có thể bố trí bàn phím này ở nhiều góc khác nhau trên bàn làm việc bởi sự cơ động của nắp chụp phím. Một đặc điểm khác là độ bền của model này gần như là số 1. Đó là lý do nó đã gắn bó với nhiều lập trình viên trong suốt một khoảng thời gian dài.
Nhận xét:
“Bạn thích nó bởi phản ứng của từng phím mang lại cảm giác chắc chắn và sẽ cực kỳ thoải mái khi làm việc khi được nghe âm bàn phím kết hợp với tiếng nháy chuột.” Daniel C.Silvertein
“Nó được thiết kế như một chiếc xe tăng vậy. Tôi có thể gó phím cả ngày mà chẳng hề có dấu hiệu mỏi tay hay những bất cập từ bàn phím nhỏ.” Shog9
“Lợi ích tốt nhất mà nó mang lại là giảm bớt lỗi chính tả. Rất dễ dàng để gõ phím và tôi đã mắc ít sai lầm hơn.” AppDevGuy
“Model M mang lại cho bạn cảm giác tốt nhất khi gõ phím.” Falcon
Northgate OmniKey (1993)
Rất nặng, chắc chắn và rất bền. Nó dễ dàng cấu hình lại và khi lập trình nó cung cấp cảm giác thỏa mãn về xúc giác. Các lập trình viên thường so sánh nó với M. IBM
Nhận xét:
“Từng phím được xây dựng rất kiên cố với một công tắc cho phép bạn điều chỉnh mọi thứ, giống như bàn phím Drovak với loại phím đính được sử dụng từ những ngày xa xưa.” James Wan
“Mọi thứ được bố trí tuyệt vời, đó là một nền tảng vững chắc. Các phím có sức chịu đựng lớn. Bạn có thể dễ dàng ghi nhớ vị trí các phím và lắp ghép lại nó nên việc tháo gỡ, làm sách thực sự rất đơn giản.” Anonymous
“Nó nặng khoảng 6 pounds và cảm giác như được xây từ một khối thép. Đặc điểm chính là độ sắc nét, nó cho tôi cảm giác như được đánh máy trên chiếc IBM Selectric II nơi mà có một nam châm điện hay một cái gì đó ném phịch fontball (1 loại font chữ) vào con lăn với mỗi phím tắt. Rất nhanh chóng, tích cực. Tôi nhớ như in điều đó.” Jeff Paulsen
Datahand (1992)
Nó rất tiện dụng, cho phép các vị trí tay tùy chỉnh. Mỗi tay bạn có thể tiếp cận đến 5 phím chính và sử dụng tích hợp chuột.
Nhận xét:
“… nó không khó để tìm hiểu, là một loại keyboard tương tự như QUERTY. Khi tôi bắt đầu bị RSI, nó đã giúp tôi rất nhiều.” Spellboot
“Nó rất đáng để bạn trả tiền. Lý do chính tôi sử dụng nó là bởi bàn phím này có tích hợp chuột nên tôi có thể ngồi cả ngày bên máy tính mà chỉ phải di chuyển tay một chút.” User93422
“Những chiếc Datahand dành cho những người muốn code tất cả trong một ngày mà không hoàn thành công việc với ngón tay chảy máu hoặc bị RSI vào buổi tối.” Jan Goyvaerts
Note: RSI – Repetitive strain injury, một căn bệnh có triệu chứng là sưng ngón tay, cứng khớp,…do gõ bàn phím và đẩy chuột nhiều trong ngày.
Happy Hacking (1996)
Nhỏ gọn, dễ dàng bấm phím và các vị trí quan trọng được tối ưu cho người sử dụng Unix chẳng hạn như việc kiểm soát các chữ in hoa.
Nhận xét:
“… có các phím điều khiển ở vị trí đó có thể tránh được tình trạng gọi là Emacs Pinky” Simon Howard
“Tôi có vài chiếc trong số model này và tôi thấy chúng giúp tôi giảm bớt gánh nặng của cổ tay nhờ việc có thể dễ dàng di chuyển ở không gian xung quanh”
Type Matrix (1997)
Có các phím dọc thẳng thay vì so le, giúp giảm thiểu cử động tay và căng thẳng lặp đi lặp lại cũng như việc phím Enter và Space gần vị trí của ngón trỏ thay vì ngón cái. Kích thước nhỏ cũng làm giảm chuyển động cần thiết khi bạn muốn dùng tới chuột.
Nhận xét:
“ Các nút nằm ở vị trí kẻ ô thay vì nằm chéo nhau khiến tôi dễ dàng hơn trong việc gõ phím.” Maudite
“Enter và BackSpace nằm gần vị trí ngón trỏ của tay giúp bạn dễ dàng hơn trong việc giữ vị trí, giảm bớt các chuyển động của tay.” Kris
“Tất cả mọi người đều nghĩ tôi đã bị điên khi sử dụng nó. Nhưng thực sự rất tuyệt vời khi được trải nghiệm bàn phím này.” Jason Baker
Kinesis Advantage (2002)
Cách bố trí tiện lợi đúng như cái tên của nó; các phím không chữ được đặt ở phía trung tâm giúp giảm thiểu các tổn thương có thể gặp phải. Phím của nó có thể được sắp xếp lại và dễ dàng chuyển đổi thành kiểu QWERTY hay Drovak.
Nhận xét:
“Loại Kinesis làm cong các ngón tay của bạn. Khi dùng chúng, cổ tay của bạn như có được đệm lót và thực tế ngón tay cái được sử dụng rất tự nhiên chứ không phải vật đẩy cho nút Space nên sẽ giúp phân bổ công việc dễ dàng cho giữa các ngón tay.” Heptadecagram
“Tôi đã đổi chỗ Backspace và Delete Alt và việc gõ bàn phím đã trở nên đơn giản hơn bao giờ hết.” Kevin Cline
“Cổ tay của tôi gần như không phải làm việc và điều này làm công việc của tôi thoải mái hơn rất nhiều. Tôi thực sự rất thích nó.” Dean J
Bài viết được sự cho phép của tác giả Edward Thien Hoang
Là dạng kiến trúc rất phổ biến ngày nay, chắc chắn ai cũng đã từng nghe qua về kiến trúc 3 lớp, MVC, MVVM,… Tất cả đều có chung một mục đích là tổ chức, phân rã mã nguồn theo nhiều chức năng và nhiệm vụ khác nhau trong hệ thống.
Trong các hệ thống hướng đối tượng, UI, Database và các dạng mã khác thường được viết trực tiếp vào trong logic nghiệp vụ. Và theo chiều ngược lại, mã nghiệp vụ lâu lâu lại được nhúng vào trong UI, DB code. Không có sự phân cấp rõ ràng dẫn đến sự phức tạp trong tổ chức, quá nhiều phụ thuộc lẫn nhau giữa các mã nguồn. Sở dĩ điều này diễn ra là vì lập trình nó rất dễ và nhanh.. nhưng chỉ là lúc mới bắt đầu. Khi các đoạn mã liên quan đến nghiệp vụ được dàn trải ở khắp nơi, điều này sẽ trở nên rất phức tạp và rất khó để đọc hiểu được nghiệp vụ. Thay đổi trên giao diện người dùng cũng có thể làm thay đổi business logic. Để thay đổi business logic, chúng ta phải đi ngược lên các mã UI, cơ sở dữ liệu hoặc các phần tử của chương trình khác để xem những chỗ cần phải thay đổi theo. Điều này không cần nói cũng đủ hiểu nó gây ra khó khăn như thế nào.
In an object-oriented program, UI, database, and other support code often gets written directly into the business objects. Additional business logic is embedded in the behaviour of UI widgets and database scripts. This happens because it is the easiest way to make things work, in the short run.
When the domain-related code is diffused through such a large amount of other code, it becomes extremely difficult to see and to reason about. Superficial changes to the UI can actually change business logic. To change a business rule may require meticulous tracing of UI code, database code, or other program elements. Implementing coherent, model-driven objects becomes impractical. Automated testing is awkward. With all the technologies and logic involved in each activity, a program must be kept very simple or it becomes impossible to understand.
Không biết và không phụ thuộc vào các lớp bên trên sử dụng nó;
Trong kiến trúc phân lớp, các layer có thể được design theo hướng nghiêm ngặt, một layer chỉ có hiểu biết và sử dụng layer ngay bên dưới nó, hoặc theo hướng linh hoạt hơn, nghĩa là một layer có thể sử dụng tất cả các layer ở dưới nó. Cả Martin Fowler và tôi đều tán đồng cách thứ 2 để tạo nên sự linh hoạt, tránh phải tạo ra các proxy method (hoặc thậm chí là proxy class) trong các layer trung gian chỉ để truyền tải thông điệp từ lớp bên trên nó xuống lớp phía dưới nó. Việc sử dụng các layer trung gian như vậy được coi là 1 anti-pattern với tên gọi Lasagna Architecture.
Đôi khi các layer được thiết kế sao cho domain layer hoàn toàn không muốn presentation layer biết đến data source layer. Tuy nhiên, và thường xuyên, presentation layer nên truy cập trực tiếp đến data source layer. Mặc dù điều này không tinh khiết, nhưng nó có xu hướng hoạt động tốt hơn trong thực tế.
Sometimes the layers are arranged so that the domain layer completely hides the data source from the presentation. More often, however, the presentation accesses the data store directly. While this is less pure, it tends to work better in practice.
Chúng ta chỉ cần hiểu những lớp bên dưới lớp chúng ta đang làm;
Mỗi lớp có thể được thay thế bởi một thể hiện tương đương (equivalent implementation), không ảnh hưởng đến các lớp khác;
Một lớp có thể được sử dụng bởi một số lớp cấp cao khác nhau.
NHỮNG BẤT LỢI LÀ:
Lớp không thể đóng gói (encapsulate) tất cả mọi thứ (một field được thêm vào UI, rất có thể cũng cần phải được thêm vào DB);
Các lớp bổ sung (extra) có thể gây ảnh hưởng đến hiệu suất, đặc biệt nếu ở các tier khác nhau.
Cùng điểm qua sự tiến hóa của kiến trúc phân lớp qua các thời kỳ
NHỮNG NĂM 60 VÀ 70
Những application lúc đó (hầu như) hoàn toàn khác với ngày nay. Chẳng có GUI (cái chỉ mới xuất hiện vào những năm đầu thập nên 90), tất cả application được sử dụng thông qua CLI (Command-line interface) dưới dạng cửa sổ console với nhiệ vụ đơn giản là nhận input (bàn phím) từ người dùng và xuất ngược trở ra màn hình. Cũng chẳng có khái niệm Client-Server, tất cả được đóng gói thành một bản cài đặt trên từng máy trạm.
Vì ứng dụng lúc đó quá đơn giản nên chẳng ai buồn nghĩ tới chuyện phân tách layer/tier này nọ làm gì. Ta có thể gọi các ứng dụng lúc đó với kiến trúc 1 layer, 1 tier, chúng không thể mở rộng (scalable), ví dụ, nếu chúng ta muốn cập nhật phiên bản mới, thì chỉ có cách là cài đặt chúng trên từng máy trạm (client)
GIAI ĐOẠN NHỮNG NĂM 80 VÀ 90
Giai đoạn này đã bắt đầu xuất hiện các ứng dụng dành cho doanh nghiệp (enterprise) với lượng người sử dụng dùng máy tính cá nhân (desktop computer) để truy cập vào ứng dụng thông qua network.
CÓ 3 LAYERS ĐƯỢC CHIA RA:
User Interface (Presentation): là những chương trình chạy trên desktop / CLI hoặc các web page. Các chương trình client lúc này thường là các rich client (nơi luồng công việc và kiểm tra input đầu vào đặt ở client)
Business Logic (Domain): là nơi đặt các logic về nghiệp vụ chính của hệ thống, layer này sẽ tiếp nhận các request từ phía Client, xử lý và lưu trữ data thông qua Data source layer.
Data source: nhiệm vụ chính của layer này là thực thi các tác vụ lưu trữ dữ liệu và liên lạc với các applications khác (được request từ business logic layer).
Đây chính là mô hình 3 lớp (3-layers) kinh điển chúng ta đã từng biết khi còn là sinh viên. Tuy nhiên xét về mặt các lớp vật lý (tier) thì ứng dụng thường được tổ chức ở mức 2 tier hay còn gọi là Client-Server. Client side sẽ chứa Presentation layer, Server side sẽ chứa Business logic layer and Data source layer.
Kiến trúc này có thể giải quyết các vấn đề về mở rộng, tuy nhiên vẫn còn hạn chế. Các ứng dụng dạng rich-client khi được cài đặt ở một số lượng lớn máy trạm thì việc update, mở rộng sẽ gặp nhiều khó khăn.
VÀO GIỮA NHỮNG NĂM 90
Đây là giai đoạn thế giới công nghệ có những chuyển biến mạnh mẽ. từ những năm 95 đến 2005, thế giới bắt đầu dịch chuyển lên “mây”. Số lượng người dùng tăng lên, độ phức tạp về ứng dụng tăng lên, vấn đề về cơ sở hạ tầng cũng ngày càng phức tạp. Từ đó dẫn đến việc cải tiến các mô hình kiến trúc sao cho phù hợp với nhu cầu, kiến trúc phân lớp vào thời điểm này được biến đổi như sau:
Web browser: làm nhiệm vụ render và gửi / nhận request tới server.
Application server: chứa presentation layer, the application layer, the domain layer, và the persistence layer.
Database server: được tối ưu cho mục đích lưu trữ dữ liệu
Đây là một architecture pattern 3 lớp vật lý (3-tier) hay n-tier. Tất cả logic điều được move lên phía server, do đó giải quyết triệt để vấn đề về mở rộng, client bây giờ chỉ làm nhiệm vụ render mà không cần biết các thay đổi từ server ra sao.
NHỮNG NĂM 2000 TỚI NAY
Domain Driven Design là từ khóa rất hot trong giới kỹ nghệ lập trình. Eric Evan là người khởi xướng thuật ngữ này vào năm 2003 với cuốn sách nhan đề: Domain-Driven Design: Tackling Complexity in the Heart of Software. Cuốn sách chứa đựng rất nhiều khái niệm ảnh hưởng sâu rộng đến cách chúng ta định hình nên các bản thiết kế hiện nay.
User Interface
Chịu trách nhiệm trong việc render và truyền tải thông điệp từ client tới server. Client ở đây có thể là người dùng hoặc những application khác, gần giống với khái niệm Boundary object trong bài viết về EBI Architecture của Ivar Jacobson, chúng ta sẽ làm rõ thêm khái niệm này.
Application Layer
Gọi là Facede Layer cũng được. Điều khiển luồng công việc (use-case) bằng cách thực thi và kết hợp (Orchestrates) các Domain object. Nó không chứa business logic. Nó liên quan đến khái niệm Interactors trong EBI Architecture, ngoại trừ 1 điều là các interactors là bất kỳ object nào không phải là UI hoặc Entity.
Có 1 từ rất hay đó là Orchestration, nó được dùng trong SOA/ESB như là một điều phối viên. Ví dụ, Application Layer nhận 1 request từ Presentation, nó phải gọi xuống Domain Layer để thực hiện công việc đó, nhưng không đơn giản là 1 lời gọi đơn giản xuống Domain Layer, mà nó cần phải biết gọi Domain object nào, bao nhiêu Domain object để có thể thực hiện xong công việc, và trả về dữ liệu cho Presentation. Cho nên mình gọi nó là Application Services và Domain Services Layer.
Domain Layer
Layer này chứa các logic liên quan đến nghiệp vụ của ứng dụng, các Entities, Events, và bất cứ object nào handle logic nghiệp vụ. Rõ ràng, nó giống như Entiy trong EBI Architecture; là trái tim của cả hệ thống.
Infrastructure
Các common technical facilities dùng chung cho cả hệ thống, ví dụ như logging, persistance, messaging…
ANTI-PATTERN: LASAGNA ARCHITECTURE
Là tên gọi cho anti-pattern trong kiến trúc phân lớp, khi:
Chúng ta quyết định đề ra các chính sách nghiêm ngặt về việc liên lạc giữa các layer (một layer chỉ có thể liên lạc với layer ở dưới ngay nó). Trong trường hợp như vậy, rất có thể ta phải tạo ra rất nhiều proxy method, proxy class trong các layer trung gian cốt chỉ để by-pass việc communication này, gây tốn công và khó chịu khi làm việc. Vì vậy, hãy giảm bớt sự nghiêm ngặt để có thể trực tiếp đi thẳng tới các layer phía dưới nó mà không cần qua trung gian.
Một thay đổi nhỏ cũng có thể gây ảnh hưởng đến cả hệ thống. Ví dụ việc refactor lại 1 layer nào đó có thể gây ra hậu quả to lớn so với lợi ích nhận lại.
Tạo quá nhiều layer dẫn đến việc phức tạp cho cả hệ thống.
Có quá nhiều tier sẽ dẫn đến sự phức tạp và giảm performance trong hệ thống.
Chúng ta tổ chức, đóng gói layer theo chức năng kỹ thuật (functional) của nó, ví dụ như UI, Domain, DB,.. mà không chia theo chức năng nghiệp vụ (component) như Product, Payment, Checkout, làm mất đi khả năng module hóa và đóng gói (encapsulation) theo domain concept.
KẾT LUẬN
Layered Architecture là một cách chia để trị mối quan tâm, đóng gói và tách riêng, bằng cách nhóm các đơn vị mã bằng vai trò chức năng của chúng trong ứng dụng.
Tuy nhiên, như hầu hết mọi thứ trong cuộc sống, quá nhiều sẽ phản tác dụng! Vì vậy, quy tắc của ngón tay cái (rule-of-thumb) là: Chỉ sử dụng các lớp chúng ta cần, các lớp chúng ta cần, và không có gì nhiều hơn nữa! Chúng ta không được đuổi theo đuổi một chén thánh kiến trúc, cái không hề tồn tại. Những gì tồn tại là một nhu cầu, và sự phù hợp tốt nhất có thể cho nhu cầu đó. Đó là một phần của Lean, tiện thể.
Hơn nữa, điều quan trọng cần lưu ý là phương pháp tiếp cận top/down này đã lỗi thời. Không còn là những gì chúng ta nên làm trong phát triển phần mềm hiện đại, có những cách nghĩ mới và tốt hơn về một lớp ứng dụng. Tôi sẽ nói về sau đó trong bài viết sau.
Đây là bài viết trong loạt bài viết về “Tổng quan về sự phát triển của kiến trúc phần mềm“. Đây là loạt bài viết chủ yếu giới thiệu về một số mô hình kiến trúc phần mềm hay nói đúng hơn là sự phát triển của chúng qua từng giai đoạn, qua đó giúp chúng ta có cái nhìn tổng quát, up-to-date và là roadmap để bắt đầu hành trình chinh phục (đào sâu) thế giới của những bản thiết kế với vai trò là những kỹ sư và kiến trúc sư phần mềm đam mê với nghề.
Bài viết được sự cho phép của tác giả Nguyễn Văn Trọng
Câu hỏi đặt ra : học công nghệ đó để làm gì (nghe quen quen kiểu “làm từ thiện để làm gì”). Nếu học vì đam mê, yêu thích nó thì mình không bàn tới. Phạm vi bài viết này chỉ giới thiệu xu hướng công nghệ đang hot với BrSE ở thời điểm hiện tại và vài năm tới (ở Nhật), tức là dù không mê hay thậm chí …ghét cay ghét đắng cũng nên học. Mình sắp xếp theo 3 mảng : Maintain, Migartion, Development.
Hiện tại các hệ thống quản lý nội bộ công ty – quản lý khách hàng thuộc các domain như y tế, giáo dục, ngân hàng … đang lạc hậu trầm trọng về mặt tính năng, tính tương thích nhưng để làm mới là việc quá rủi ro vì hệ thống quá lớn đã được vận hành hàng thập kỷ. Khách hàng Nhật có tính chắc ăn trong mọi việc nên thường họ chọn cách làm maintain hệ thống cũ, tức là làm mới giao diện người dùng, thêm 1 vài tính năng mới…
Có nhiều ngôn ngữ nhưng 3 loại phổ biến nhất mà BrSE theo mảng maintain cần nắm.
Java
Khỏi cần nói nhiều vì Java quá phổ biến.
Cobol
Ngôn ngữ cũ ríc này hiện nay vẫn chưa tắt thở vì 1 lợi thế quá lớn về mặt performan. Và các hệ thống to đùng hầu hết tầng bên dưới đều dùng anh này.
VB
Một trong những ngôn ngữ lập trình hướng đối tượng ra đời sớm nhất, và được ứng dụng rộng rãi trong nhiều hệ thống quản lý nội bộ công ty. Và 1 điều mình cũng khá ngạc nhiên là đến bây giờ vẫn rất nhiều bác khách hàng thích VB, lý do có thể là do quen dùng.
Migration
Mảng này thường trải rất rộng. 1 hệ thống thường ứng dụng nhiều ngôn ngữ ở các tầng khác nhau vì mỗi loại có ưu nhược riêng. Ở tầng giao diện ASP, JSP, PHP khá phổ biến, còn tầng dưới (xử lý nghiệp vụ) thì Java, C#, VB. Về database thì có 3 ông lớn : DB2 (IBM), SQL, Oracle.
Các chuỗi Migration thường gặp
Java : từ các version cũ như 3,4 lên Java 7/8
ASP : từ ASP qua ASP.net, hoặc từ ASP.net version 2/3.5 lên ASP.net ver 4.5
VB (lại là VB) : từ VB4/VB6 lên VB.net hoặc từ VB.net ver thấp lên cao
Database : DB2 hoặc Oracle qua SQL, hoặc Oracle/SQL từ ver thấp lên cao. Thời điểm hiện tại thì Oracle 11 vs SQL 2012 là 2 bản database ổn định và được chọn làm đích upgrade.
Migration lên Cloud : đang cực kỳ HOT. Azure hoặc AWS là 2 dịch vụ mà bạn cần phải nắm vững nếu muốn nhảy vào mảng này. Mình nhắc lại thêm 1 lần nữa : nó rất rất hot – còn hơn cả Ngọc Trinh
Development
Phát triển mới hiện tại đang nhắm vào 3 mảng lớn : Web, Mobile và Embedded (lập trình nhúng). Thường đối với các dòng dự án phát triển mới thì BrSE sẽ tham gia từ design, vậy nên kỹ năng viết – trình bày tài liệu bằng tiếng nhật hay làm prototype (excel/html) quan trọng không kém ngôn ngữ – cộng nghệ.
Làm develop sướng hơn so với maintain và migration. Maintain là công việc khá nhàm chán (quan điểm cá nhân), còn migration thì khá là căng thẳng – vì nó trải rộng làm BrSE phải xì khói ra đào sâu từng chi tiết nhỏ khác biệt giữa các ngôn ngữ -cũng như giữa các version trong cùng thể loại, cộng thêm luôn dính phải anh Maintain :(.
Các ngôn ngữ phổ biến :
Mảng WEB
JavaScript: không chạy đâu được với anh này mặc dù anh hơi sida (nói theo cách toidicodedao). Đi kèm với nó là JQuery, Note.js, Angular.js, KnockOut. Các bạn nên chọn 1 Framework để học và làm tốt nó.
JSP
PHP
HTML 5
Ruby-on-rails : bên cạnh những ngôn ngữ truyền thống thì anh này hiện tại đang thấy khá hot, các nhà tuyển dụng săn mấy ông BrSE Ruby rất kinh, tức là thấy mặt cái tóm qua JP luôn – khỏi nói nhiều
Mảng Mobile
Android
IOS
Mảng này mình không rành nhiều nhưng có 1 điều chắc chắn là : không nên theo Window Phone.
Mảng Nhúng
C/C++
CAD, CAM
Có 1 điều thú vị là các dự án chuyên về ô tô, chip, smart tivi thì có nhu cầu rất lớn những bạn học điện tử viễn thông hay cơ điện tử.
Tổng Kết
Những liệt kê ở trên có thể không đầy đủ vì kiến thức còn hạn hẹp, nhưng mình nghĩ khá sát so với thực tế dựa theo kinh nghiệm 6 năm làm dự án với các bác Nhật. Ngoài ra có 1 điều đặc biệt quan trọng là mọi ngôn ngữ có thể học được rất nhanh nếu như nắm được cốt lõi. Ví dụ chỉ cần ngon JQuery thì mất thêm vài tuần là dùng được Angular.js.
Vậy nên nếu đang làm dự án với ngôn ngữ – công nghệ nào thì tốt nhất là cứ tập trung tối đa vào nó, lên lé vồ master thì dù nó không hot cũng thuộc hàng độc, cơ hội từ từ sẽ đến – trời đất không phụ người chăm chỉ
Bài viết được sự cho phép của tác giả To Thi Van Anh
Bài cuối cùng trong chuỗi mind map “lười biếng” này của mình xin được chia sẻ với các bạn những tổng hợp cơ bản nhất về Selenium IDE, cái add-on ai cũng nghĩ là dễ này. Lưu ý nho nhỏ cho các bạn là từ FireFox 55 trở đi thì Selenium IDE không được hỗ trên đó nữa. Muốn dùng thì các bạn phải sử dụng FF phiên bản thấp hơn nhé! Chi tiết có thể đọc thêm ở đây nha.
Updated 28.5.2018: Selenium IDE – tiện ích mở rộng dành cho trình duyệt Firefox hiện giờ đã update và thay đổi hình hiển thị của icon, và lưu ý là phiên bản của trình duyệt cần sẽ phải từ Firefox 56 trở lên chứ không phải Firefox 55 nữa nha.
Nhưng mà dù sao thì mình vẫn tổng hợp lại bài này coi như là một phần kiến thức đã học được, biết đâu là sẽ dùng nó vào một ngày nào đó hoặc là có vào dĩ vãng thì cũng có chút kỉ niệm về nhau hehe!
Hi vọng là các bạn sẽ thích bài này và một lần nữa mình vẫn mong nhận được những ý kiến đóng góp từ các bạn để các bài viết của mình được hoàn thiện hơn!
Bài viết được sự cho phép của blogchiasekienthuc.com
Chào anh em, đối với dân lập trình nói riêng và dân IT nói chung thì việc học và tiếp thu kiến thức mới mỗi ngày là một việc vô cùng quan trọng.
Mình có một bài viết chia sẻ về việc: lập trình viên có nên học nhiều hơn một ngôn ngữ lập trình không? Nếu bạn nào muốn đọc thì có thể tham khảo tại đây nhé:
Vậy một câu hỏi đặt ra lúc này là, nếu học nhiều thứ cùng một lúc thì phải học làm sao cho hiệu quả? Học như thế nào để có được kết quả tốt nhất?
Mình tin đây là câu hỏi mà mọi người đều trăn trở, một câu hỏi mà ai cũng muốn biết được câu trả lời chính xác nhất ᵔᴥᵔ Vâng, thực ra mỗi người sẽ có một cách học khác nhau.
Và ở trong bài viết này, mình sẽ chia sẻ với bạn một số phương pháp mà mình thấy mọi người và bản thân mình đã áp dụng, nó mang lại hiệu quả khá cao đối với cá nhân mình.
Cụ thể thì mình sẽ nói về cách tiếp cận và cách học một ngôn ngữ lập trình mới sao cho hiệu quả nha.
#1. Định hình loại ngôn ngữ lập trình
Đây là một bước tuy đơn giản nhưng nhiều anh em bỏ qua mà cứ thế lao đầu vào học cú pháp của ngôn ngữ luôn.
Vậy thế nào là định hình loại ngôn ngữ lập trình? Thực ra, ngôn ngữ lập trình được chia thành nhiều loại với nhiều mục đích và bản chất khác nhau.
Mình giả sử như bạn đang là một lập trình viên front-end (làm về giao diện) – như vậy bạn phải biết về JavaScript và cách dụng một Framework của nó (VueJS, ReactJS, Angular…)
Còn nếu bạn muốn học thêm về Back-end thì bạn chọn Java để học. Thực tế thì JavaScript và Java chả liên quan gì với nhau cả. Vậy nên việc bạn áp dụng cách học JavaScript cho Java sẽ không bao giờ đem lại hiệu quả cao được.
Vì vậy mà, trước khi học một ngôn ngữ lập trình mới thì bạn nên xác định ngôn ngữ đó thuộc loại nào (ngôn ngữ biên dịch hay thông dịch, bậc cao hay bậc thấp, có hướng đối tượng hay không…)
#2. Nắm được cú pháp cơ bản
Phần đa ngôn ngữ lập trình có cú pháp khác nhau và đây cũng là một trong những điểm quyết định ngôn ngữ lập trình có dễ học hay không.
Mình lấy ví dụ, nếu các bạn đem so sánh cú pháp của Python và Java thì chắc chắn 90% các bạn sẽ chọn học Python, đơn giản là vì cú pháp của Python tương đối dễ hiểu và dễ học cho người mới.
Nhưng xét cho cùng, dù là ngôn ngữ lập trình nào thì về cơ bản nó cũng sẽ có biến, có hàm, có các câu lệnh điều kiện và các cấu trúc dữ liệu.
Thứ bạn cần học đầu tiên đó chính là, nắm được cách mà ngôn ngữ lập trình triển khai các khái niệm cơ bản đó.
Nếu bạn đã có nền tảng vơi một ngôn ngữ lập trình nào đó trước rồi thì việc học và nắm được các khái niệm này sẽ không mất quá nhiều thời gian đâu.
Nhưng bạn đừng chỉ học theo kiểu biết cách viết, mà bạn phải học làm sao để biết cách dùng và áp dụng vào các ví dụ thực tế (để làm được điều này thì các bạn hãy thực hiện giải các bài toán cơ bản nhé).
#3. Làm một vài project với những gì học được
Sau khi đã nắm được hòm hòm về cú pháp rồi thì đã đến lúc các bạn nên làm ra một ứng dụng hay một chương trình nào đó từ những gì mà các bạn học được.
Câu hỏi ở đây là: tại sao không học sâu hơn nữa, vì nắm được cú pháp thì đã làm được gì đâu? Mình tin chắc nhiều bạn sẽ có thắc mắc như vậy, nhưng mình cũng đặt ngược lại cho các bạn một câu hỏi là học sâu nữa thì bạn định học đến bao giờ?
Học phải đi đôi với thực hành, hơn nữa khi làm ra được cái gì đó (có kết quả) thì bạn sẽ có động lực để học tiếp, vì nó giống như là một thành quả cho sự cố gắng của bạn vậy.
Quay lại với câu hỏi là làm sao để làm được một project với những gì mà các bạn có trong tay, khi mà chỉ là cú pháp của ngôn ngữ?
Thì đơn giản thôi, bạn có thể xem các video hướng dẫn trên mạng, đọc một bài tutorials nào đó mà người ta hướng dẫn chi tiết rồi làm theo, hoặc đơn giản là làm theo cách của các bạn.
Chắc chắn sẽ có chỗ các bạn chưa hiểu đâu, mình cá là như vậy! Nhưng đừng vội dừng lại, hãy cứ làm cho đến khi các bạn ra sản phẩm nhé.
#4. Ngồi xem lại các Project vừa làm
Nếu các bạn chỉ dừng lại ở bước làm theo như ở bên trên thì coi như các bạn chỉ dừng lại ở việc học thuộc cú pháp và làm theo người ta mà thôi.
Và nếu là như thế thì bạn sẽ không bao giờ có thể tiến bộ được bởi vì các bạn chưa biết cách biến code đó thành code của các bạn.
Chính vì vậy, sau khi làm xong các project rồi thì các bạn hãy ngồi lại và review chúng xem mình đã học được gì, tại sao người ta lại code như thế, mình có thể code hay hơn không, hoặc làm sao để thay đổi đi cho khác?
Đây giống như là bước để các bạn tổng hợp lại kiến thức vậy, vì bản chất, nếu cứ học chay mà không làm cái gì đó thì các bạn sẽ không thể biết được kiến thức mà bạn học được áp dụng vào đâu và áp dụng như thế nào.
Mình nhắc lại lần nữa, đây là một bước cực kỳ quan trọng nha, các bạn hãy cố gắng ngồi xem lại những gì minh đã làm chứ đừng vội nhảy qua làm project khác luôn.
#5. Chịu khó đọc docs để hiểu sâu hơn, rộng hơn
Sau khi xem lại những gì mà bạn đã làm thì mình đảm bảo với các bạn là bạn vẫn chưa hiểu hết 100% đâu ᵔᴥᵔ, mà muốn hiểu tường tận hơn buộc các bạn phải đọc tài liệu về em nó.
Bản chất của các bài hướng dẫn hay các video hướng dẫn là họ hướng đến việc các bạn làm theo và làm ra một cái gì đó có thể giống hoặc khác một chút so với người ta.
Kể cả khi bạn có ngồi xem lại thì đó vẫn là ý tưởng của người ta chứ không phải là ý tưởng hay kiến thức của bạn.
Vì vậy, bước đọc tài liệu (là các tài liệu chi tiết của ngôn ngữ lập trình đó, thường là documments do chính đội ngũ phát triển viết) là bước RẤT QUAN TRỌNG nếu bạn muốn trả lời cho câu hỏi: tại sao người ta lại code như vậy trong mục #4.
Có thể đọc tài liệu sẽ hơi chán một xíu do phần đa tài liệu không phải là hướng dẫn mà thiên về giải thích, nên đôi khi hơi dài và nhiều chữ.
Nhưng các bạn hãy cứ kiên trì đọc và mình tin chắc nếu đọc và hiểu thì các bạn sẽ ngỡ ra rất nhiều điều đó.
#6. Phát triển hoặc tối ưu các Project đã làm
Sau khi làm theo và hiểu được người ta làm như thế nào rồi thì đã đến lúc các bạn nên tự làm một project nào đó.
Về mặt ý tưởng, tốt nhất vẫn nên là ý tưởng của riêng các bạn. Nhưng nếu bạn không có ý tưởng gì thì các bạn có thể tham khảo trên mạng.
Sau khi có ý tưởng rồi thì dựa vào những gì đã học được, bạn hãy cố gắng tự làm từ đầu đến cuối project đó (tất nhiên cũng có những chỗ phải xem lại nhưng hãy cố gắng đừng copy – paste nhé). Có như thế bạn mới hiểu sâu và nhớ lâu hơn.
Tất nhiên đây là giai đoạn khó nhất, mình đã từng trải qua rồi nên mình hiểu rất rõ, bạn buộc phải tự mình tư duy, tự mình mày mò tìm kiếm cách giải quyết khi có vấn đề.
Nhưng nếu làm tốt bước này thì có thể nói là bạn đã thành công trong việc học một ngôn ngữ lập trình mới.
#7. Lời kết
Đó là một quy trình 6 bước giúp bạn học một ngôn ngữ lập trình mới được hiệu quả hơn.
Mình xin nhắc lại lần nữa là mỗi người sẽ có một phương pháp học tập khác nhau và mình chỉ đang chia sẻ những gì mà mình và nhiều người khác từng làm và nó đem lại hiệu quả.
Các bạn có thể áp dụng một cách linh hoạt nếu cảm thấy 6 bước trên phù hợp với cách học của các bạn. Xin chào và hẹn gặp lại các bạn trong các bài viết tiếp theo nha !
À quên, bạn đang sử dụng phương pháp nào để tiếp cận với các ngôn ngữ lập trình mới? Rất hi vọng bạn sẽ chia sẻ cho anh em cùng biết cách học tập của bạn, để anh em cùng học hỏi và trao đổi thêm. Thank you !
Bài viết được sự cho phép của tác giả Lê Xuân Quỳnh
Hello guys! Lại là mình đây
Trong bài trước, chúng ta đã học cách viết 1 lớp network layer rất chuyên nghiệp để call API, clear và simple. Hôm nay chúng ta sẽ tinh chỉnh cho app chuyên nghiệp hơn.
OKey, vậy chúng ta hãy cùng bắt đầu nhé. Đầu tiên như các bài trước bạn hãy checkout source code tại đây:
https://github.com/codetoanbug/MVVMSample.git
Vui lòng đọc cách chuyển sang branch bai3 dựa vào các bài trước để xem code nhé.
Hãy cùng bắt đầu nhé
Thêm phần loading cho search
Như các bạn thấy, thì các mục search trên các ứng dụng như facebook, google, họ thường hay thêm indicator hiển thị loading để người dùng chờ đợi. Vì thế mà ứng dụng của chúng ta cũng nên có cái này để tăng trải nghiệm người dùng. Chứ mà không có thì ai biết ứng dụng có đang working hay không.
Phần loading sẽ show khi người dùng bắt đầu search, và sẽ ẩn đi khi đã kết thúc tác vụ search. Vì thế chúng ta sẽ sửa lại giao diện như sau:
Thêm indicator
Trong hình trên, chúng ta sẽ thêm 1 indicator ở dưới ô search và trên ô table. Tôi đưa indicator và tableview vào 1 stack view vì khi indicator show/hide, thì tableview sẽ tự động full màn hình.
topIndicator: Show lên khi người dùng nhập text để search
bottomIndicator: Show lên khi người dùng scroll xuống dưới cùng để load thêm dữ liệu
OK, vậy bây giờ xử lý logic nó như thế nào?
2. Xử lý logic search
Khi chúng ta gõ text, thường sẽ đợi khoảng 0.5s khi gõ xong rồi mới gọi API, để giảm tải số lần call API tới server, và đỡ người dùng bấm nút search rồi mới search nha.
Khi có kết quả trả về, indicator cần ẩn đi.
Khi người dùng cuộn table, bàn phím cần ẩn đi
Kiểu bàn phím là search
Okey vậy chúng ta sẽ làm lần lượt từng yêu cầu trên.
Đầu tiên khi bạn muốn search sau 1 khoảng thời gian thì bạn cần có 1 timer để đếm. Đủ time sẽ search, đủ yêu thương thì sẽ về chung 1 nhà
Cài đặt timer cho việc search
Đoạn code trên check mỗi khi user gõ phím, thì timer được tạo ra. Đúng 0.5s sau khi user gõ ký tự cuối cùng, thì hàm performSearch sẽ chạy nha. Ở đây bạn capture để tránh trường hợp đang gõ, user thoát ra màn khác thì leak memory nha. Hàm shouldChangeCharactersIn có mục đích là lắng nghe sự kiện user gõ bàm phím, và hàm này thuộc UITextFieldDelegate, cho nên muốn xài nó bạn cần gán delegate cho textfield:
// Add delegate for textfield
searchTextField.delegate = self
Okey, vậy là đã xong mục timer.
Xử lý search:
Khi hàm performSearch gọi chúng ta sẽ làm những công việc sau:
Cần loại bỏ các dấu cách thừa ở đầu hay cuối nếu user cố tình nhập
Nếu text gọi lên giống với lần trước thì bỏ qua vì kết quả giống nhau mà
Nếu như user xóa trắng ô search thì clear kết quả đã search trước đó nếu có
Nếu mọi thứ ok thì show top indicator lên và bắt đầu search.
Cập nhật currentLanguage để so sánh cho lần tiếp theo
Khá đơn giản nhỉ
Tiếp theo chúng ta cài đặt search và search more trong view model nha:
Cài đặt search trong view model
Như quan điểm MVVM, thì mọi logic phức tạp sẽ move hết vào view model. Như vậy view hay view controller sẽ đỡ gánh nặng nha.
3. Sửa API theo document
Ở dòng 40, tôi có biến incompleteResults. Biến này có mục đích là xác định kết quả search có còn không. Nếu còn thì nó trả về false, còn nếu đã hết kết quả để search thì true. Mục đích của nó là xác định cho client xem mày có nên gọi request search lên nữa hay không nha.
Cùng xem và sửa API search trên trang github develop:
Hum trước thì cái API chưa có page, nên hum nay mình update page vào nè. dịch ra ở trên là page là số trang kết quả mà bạn muốn lấy. Người ta chia page với mục đích là load more đó bạn. Ví dụ server nó có 1000 kết quả, thì nó không thể trả 1 phát 1 nghìn lun, mà phải tách nhiều page. Giả sử 1 page có 100 kết quả thì có 10 page ha, mục đích làm việc trả kết quả nhanh, người dùng đỡ đợi nè. Vì thế khi bạn muốn load more, thì bạn phải tăng số page này lên. Đến bao giờ incompleteResults = true -> không có kết quả nữa thì thui hông call nữa nè. Đơn giản phải không nào
OK con dê, vì thế nên ta tiến hành thêm 1 biến page vào API ha.
Quay lại hàm search ở view model. Mình có 2 params truyền vào là:
language: String, loadMore: Bool = false
language là ngôn ngữ người dùng muốn tìm. Còn loadMore là để handle riêng cho trường hợp user muốn load more khi scroll table xuống bottom nà. Mặc định nó là false(nghĩa là search new).
Dòng 44->47 mình check nếu không phải load more thì cần sửa page về 0, đồng thời xóa trắng data cũ đi.
Dòng 56->60 mình xử lý để show cái bottomIndicator. Khi có kết quả trả về load more, thì cần ẩn cái bottomIndicator đi nhé.
Nếu search success, thì tiến hành append data mới vô githubSearchItem. Sau đó reload table nha.
Nếu thất bại thì báo lỗi
Vậy là xong phần search rồi. Tuy nhiên làm sao để biết lúc nào thì search more?
Khi người dùng cuộn xuống bottom, thì hàm trên sẽ được gọi. Do vậy mình check ở đây:
Nếu như cell đó là cell cuối cùng thì tiến hành tăng page lên 1, và hiển thị bottomIndicator lên, đồng thời gọi API để lấy thêm data vào.
Vậy là đã xong toàn bộ logic seach nè.
Tiếp tục quay ra GithubViewController để cài đặt các callback từ view model sang cho nó.
Cài đặt callback cho view controller
Dòng 46->49, khi needReloadTableView thì cần reload table và ẩn top indicator view đi.
Dòng 52->56, tương tự báo lỗi và ẩn indicator.
Dòng 58->65, xử lý cho bottomIndicator khi ẩn và hiện
Tiếp theo, chúng ta cần xử lý những logic be bé cho ứng dụng chạy đúng với trải nghiệm người dùng:
Dòng 128->130, khi người dùng bấm nút clear trên ô search, thì cần xóa data của table đi
Dòng 133->135, khi người dùng cuộn thì ẩn bàm phím đi.
Rồi vậy là đã xong đó. Mình cũng làm những logic cơ bản nhất của search. Nếu bạn muốn sử dụng indicator chuyên nghiệp hơn thì đây là 1 library mà mình hay dùng:
pod 'NVActivityIndicatorView', '~> 4.0' # https://github.com/ninjaprox/NVActivityIndicatorView
Chúc các bạn sẽ học được nhiều điều hay từ bài viết này
Mang tiếng là FE Developer, chính chiến khắp nơi, nào là Vuejs, ReactJs, Angular, nhưng đôi khi lại quên mất những điều đặc biệt ở Javascript ES6. Chà, tắc trách quá!
Hãy cùng Kieblog điểm qua một số điều thú vị đôi khi ta quên mất là chỉ có ở ES6. Cùng bắt đầu nha!
ES6 được xem như bước ngoặt lớn trong quá trình phát triển của ECMA Script
1. Default parameter
Rõ ràng mà nói, từ xưa tới nay vẫn luôn dùng || để set giá trị default cho argument trong trường hợp không được truyền vào
var kieblog = function (author, article, url) {
var author = author || 'Kien nguyen'
var article = article || 'Javascript ES6'
var url = url || 'https://kieblog.vn'
...
}
Tuy nhiên, ở Javascript ES6, ta có thể set giá trị default của argument ngay khi khai báo function. Đơn giản như sau:
Trước đây, khi muốn concat string các giá trị lấy theo chuỗi, ta sử dụng +. Tuy nhiên, với một hai cái thì không sao, tới chừng 5,6 cái thì thật sự là hoa cả mắt. Không ổn không ổn.
// Chỉ 2 cái thì okie, không sao hết
// Mặc dù nhìn hơi củ chuối, nhưng vẫn chấp nhận được!
var aboutme = 'My name is ' + first + ' ' + last + '.'
May mắn thay, ở Javascript ES6 ta có thể sử dụng syntax ${NAME} để bind các value vào String. Easy for ence như sau:
// Bind một phát,nhìn vừa gọn vừa chuyên nghiệp
var name = `My name is ${first} ${last}.`
Nhắc tới Javascript ES6 mà bỏ qua Arrow function thì thật sự là thiếu sót to lớn rồi. Dùng hằng ngày, viết hằng ngày thì tất nhiên phải nhớ có mặt ở ES6. Phải không nào?
// Với ES5, trước đây phải viến function(event)
var _this = this
$('.btn').click(function(event){
_this.doButtonThing()
})
Qua ES6, chỉ với Arrow function, đơn giản chỉ cần viết
// Với ES5, trước đây phải viến function(event)
var _this = this
$('.btn').click(function(event){
_this.doButtonThing()
})
Hiện tại, đơn giản chỉ cần nhớ. Tuy nhiên dùng arrow function thì không bind this trong đó, nên phải cẩn thận khi dùng this trong function có arrow
Ở ES5, var có scope ở cả function, thành ra đôi khi có mấy cái bug bi hài nếu dùng chung variable name. Mặc dù đã khai báo var các kiểu con đà điều, nhưng giá trị vẫn không đổi
// Với ES6
function theFunnyThingWithES5(es5) {
var es5Value = 99
if (es5) {
var es5Value = 100
}
{ // Cứ có block thì var sai
var es5Value = 101
{
var es5Value = 999
}
}
return es5Value
}
// Console ở đây log ra là 999 -> funny thing
console.log(theFunnyThingWithES5(true))
Quay trở lại Javascript ES6, thay đôi lớn nằm ở việc let có scope ở function, còn var thì giới hạn lại ở trong block
function theFunnyThingWithES6(es6) {
var es6Value = 99
if (es6) {
let es6Value = 100 // first es6Value is still 99
}
{ // more crazy blocks!
let es6Value = 101 // first es6Value is still 99
{
let es6Value = 999 // first es6Value is still 99
}
}
return es6Value
}
Bài viết được sự cho phép của tác giả Nguyễn Văn Trọng
Nguyên Do
Bài viết này hơi tự sự 1 chút. Chuyện kể về 1 anh chàng cu đơ lõm bõm chút tiếng Nhật cách đây 4 năm. Rồi tình cờ công việc rơi vào đầu anh và thế là anh trở thành 1 kỹ sư cầu nối bất đắc dĩ. Chỉ ngắn gọn vậy thôi. Rồi cũng tình cờ, sau mấy năm làm cái công việc mà có khi chả khác gì “dâu trăm họ” anh thấy mình chững lại, muốn bứt phá lên 1 mức cao hơn mà ở trên đó anh nghĩ là có nhiều cái mới, cái hay. Đời không như mơ, anh nói chuyện với bạn bè rồi đến các senpai, ai cũng loay hoay với vòng quay cơm áo gạo tiền bon chen cuộc sống, chả hơi đâu lại để ý đến chuyện chia sẻ kinh nghiệm này nọ. Không bỏ cuộc, anh tìm đọc hàng tá blog đủ mọi thể loại ngôn ngữ từ trên mạng rồi anh phát hiện ra 1 sự thật đau lòng : chả có 1 ai chia sẻ về nghiệp “kỹ sư cầu nối”. Thế đó, cái blog này ra đời 1 cách không tình cờ.
Có những lúc tự hỏi, phải chăng BrSE không phải là 1 cái nghề như bao thứ khác ? mà nó chỉ là bước đệm để cho anh em kỹ sư đạp lên đó mà dấn thân. Nghĩ nhiều vô ích, cho dù là gì đi chăng nữa thì đã – đang và sẽ có những con người tài năng đi qua đoạn đường này. Chi bằng ở trên đó, anh vẽ ra những biển chỉ dẫn – chỗ này nguy hiểm tránh xa – chỗ kia có thú dữ – chỗ nọ có nàng tiên cá … để cho khách bộ hành không dẫm lên những cái bãi lầy mà anh từng đạp ko biết bao lần. Và đôi khi lữ khách có thể tìm ra kho báu hay chỉ đơn giản là viên sỏi óng ánh mang trong mình tinh hoa của tạo hoá thông qua những chỉ dẫn mơ hồ mà anh dựng lên.
1 cánh én không thể làm nên mùa xuân, điều đó anh biết. Nhưng 1 đốm lửa vẩn có thể thiêu rụi cả 1 khu rừng. Nghĩ vậy nên anh càng tự tin hơn để cho ra những bài viết chả có 1 tí gì là văn hoa, lời lẽ thì khô khan, câu cú lủng củng, đôi khi còn nhiều chỗ phiến diện. Không phủ nhận, nhưng có 1 điều chắc chắn, trong những bài viết mà mỗi bạn chỉ đọc có 5p, anh đã dành ra 5h – có khi là 5 ngày để tổng hợp ý, tìm tài liệu và lục lọi trong ký ức những gì đi qua đã phủ bụi mờ của thời gian. Bạn có biết phương pháp chữa cháy rừng trong lúc nguy cấp là gì không ? không phải múc nước dưới sông lên dập lửa, càng không phải dùng bình cứu hoả – nguy cấp thì lấy đâu ra. Mà đó là ngăn sự lan rộng của ngọn lửa bằng cách vạch lá khô tạo vách ngăn. Ý ở đây là gì, nếu không có sự tiếp nối thì lửa không thể lan được, nó chỉ cháy âm ỷ trong phạm vi hẹp rồi lụi tàn. Thông tin cũng như ngọn lửa, mình thấy cái gì hay mà chỉ ôm – chỉ giữ khư khư thì rồi mình cũng lụi theo nó. Giữ chi vậy ? share ra cho anh em bạn bè đồng nghiệp còn biết chứ, đôi khi trong những cái mình đưa ra mà sai sót gì thì gặp cao nhân người ta còn chỉ giáo cho. Đó chính là suy nghĩ để anh làm động lực cho những bài viết tiếp theo.
Phương Pháp
Có nhiều cách để chia sẻ thông tin với độ lan toả cao như facebook hay twitter sao không chọn, anh chọn wordpress làm gì ? 1 góc nhỏ xíu trong này liệu ai biết để vào xem những cái hay ho của nghề ? đúng là độ lan toả thấp, nhưng đối tượng thì được chọn lọc 1 cách tuyệt vời. Không ai đi tìm hướng đi nghề nghiệp qua facebook cả, những bài viết chất lượng thì thường nằm ở những ngõ nhỏ phố nhỏ như này. Và những bạn tìm đến với anh, cùng gật đầu đồng cảm với ý kiến của anh, hoặc đôi khi là những cú bĩu môi chau mày theo kiểu “cha này viết linh tinh” – nhưng có lẽ không nhiều. Đó đều là những bạn trẻ có tâm với nghề, mong muốn con đường sự nghiệp của mình được tốt hơn.
Cái Tâm Và Tầm
Anh quen nhiều người, dẫu biết các anh – các bạn rất có tâm, nhưng lại ngại chia sẻ. Vì thực sự việc viết ra 1 cái gì đó công khai lên mạng thì đồng nghĩa với gạch đá, búa rìu. Đôi khi không cần phải lên đến mức chuyên gia mình mới có quyền chia sẻ. Ai cũng có cái quyền đó, vì mỗi người có 1 điểm nổi bật riêng mà cuộc đời này đã ban tặng. Có thể những cái bạn biết và nghĩ rằng ai cũng biết cả rồi, nhưng sự thực không phải vậy, trước đây anh cũng nghĩ thế. Đơn cử như vụ El nino – canh cua nấu với rau đay chẳng hạn. Từ khoá tìm kiếm trên google nhiều nhất đó là “El nino là ai” chứ không phải “El nino là gì”, rất nhiều người nghĩ El nino là tên 1 ai đó chứ không phải là 1 hiện tượng thời tiết. Vậy nên những cái anh viết ra có khi là kiến thức cũ mèm với nhiều người nhưng với 1 ai đó, nó lại là những thứ hay ho – mới mẻ. Không cần phải trở thành cá mập mới chia sẻ về đại dương, chỉ cần là cá trích – chú ấy có thể vẽ ra 1 khung cảnh dưới nước lung linh huyền ảo với vô số tầng sinh vật biển để tả lại cho nhưng đàn chym đang bay trên bầu trời. Chỉ cần tâm là đủ rồi.
Lời Đe Doạ
Sau khi đọc bài viết này, nếu có ý tưởng gì hay hãy viết Blog đi – không có gì hay ho cũng viết, dần dần sẽ hay. Bỏ những sts dài ngắn sướt mướt hay những giờ đắm chỳm vào mấy cái tin giật gân trên face liền. Những cái đó chả có ích gì, vì các mảnh thông tin chỉ tồn tại ở vỏ não 1 thời gian ngắn rồi cũng tiêu tan. Khi bắt tay vào viết 1 cái gì đó, lượng kiến thức sẽ hội tụ lại và khắc sâu vào trong các nếp nhăn, sau này chắc chắn sẽ có ích. Không cần ai đọc cũng được, coi việc viết như 1 sự luyện tập diễn đạt mà dân IT cực kỳ thiếu và yếu. Chỉ vì mục đích luyện tập và chia sẻ, đừng nghĩ gì cao xa, bắt tay vào làm ngay trước khi quá già. Hoặc nếu vì lười viết thì chí ít cũng comment bổ sung vào những bài viết để người khác xem và học hỏi, hoặc chỉ đơn giản là share nó ra cho ai cần.
Nay định bụng viết một bài “cao siêu sâu xa về git commit rebase”. Nhưng ngồi lướt face book lại thấy cái bài post hay quá. Nên lại viết về kinh nghiệm thực tế khi làm việc. Viết message commit như thế nào cho tốt?.
Thiết nghĩ theo cái nghề cũng là cái duyên cái nghiệp, không phải ai cũng ngồi trước máy tính làm việc 10-12 tiếng mà vẫn vui vẻ được. Cái nghề nó chọn mình, đeo bám lấy mình. Nhưng cứ “vững chí bền gan” – rèn luyện trau dồi thì nghề không phụ mình đâu!.
Lạc cmn đề, quay lại chủ đề chính “viết commit message sao cho tốt?“
1. Liên quan gì tới Senior?
Liên quan chứ, trở thành Senior không chỉ là “nắm rõ design pattern, hiểu tường tận về architecture“. Ngoài ra còn kĩ càng, chỉn chu trong những công việc nhỏ như viết nội dung commit, refactor các function nhỏ, hay viết manual document.
Một vài ví dụ. Blur là blur cái gì?, hot fix là fix khi nào?. Trước thì còn nóng sốt kịp release, nhưng giờ quay lại thì đâu thấy “gấp gáp” gì nữa. Vậy nội dung fix là gì?
Xin thưa là không phải nha, không phải code hoành tá tràng, giải thuật cao siêu hay component siêu to bự là muốn commit sao thì commit nha.
Vấn đề là feature này làm trong 2 tuần thì release, nên có viết content “ngáo ngơ” xíu thì cũng ok, nhìn vẫn nhớ. Còn nếu sau 2 tháng quay lại nhìn vào git history?.
Ơn chúa, “chỉ có chúa và con biết nội dung của nó là gì?. Mà đó còn là nội dung của bạn viết, chứ ông dev nào khác mà nhìn vào thì ôi thôi. Xác định là khỏi tra theo commit để mà tìm bug.
Ngoài ra, viết commit tốt còn giúp cho:
To speed up the reviewing process. (Tăng tốc quá trình review)
To help us write a good release note. (Viết release note tốt)
To help the future maintainers of Erlang/OTP (it could be you!), say five years into the future, to find out why a particular change was made to the code or why a specific feature was added. (Tìm lại những gì đã làm năm xưa một cách dễ dàng)
Để tránh những trường hợp đó. Ngoài có chuyên môn giỏi, khả năng code “thần sầu quỷ khóc”, cũng cần có tâm khi viết message content. How?, đây, tui chỉ cho
Rõ ràng phải nói là vậy, nhiều khi task dí tới đít, chạy còn không kịp, lấy đâu ra thời gian mà trau với chuốt nội dung commit. Biết là thế, nhưng mình vẫn khuyên là nên bỏ chút thời gian (khoảng 1,2 phút) để viết một nội dung có tâm.
Vậy nội dung có tâm là như thế nào? Có ngay đây!
git add .
git commit -m "fix bug"
git push
Nội dung commit không nên quá 50 kí tự (Limit the subject line to 50 characters). Đã là nội dung thì nên mô tả ngắn gọn, súc tích nhất có thể. Không nên viết quá dài dòng như tấu chương
Việc bỏ một chút thời gian để ghi rõ comment, commit message không những giúp rèn luyện tính cẩn thận tỉ mỉ. Từ những việc làm tưởng như nhỏ bé và đơn giản này cho ta cái nhìn khác biệt về hai người lập trình viên.
Chính vì vậy, hãy tập viết nội dung commit thật đàng hoàng ngay từ bây giờ nha. Có bị dí “chạy tụt quần” thì cũng bỏ ra 2 phút để viết được mà.