Home Blog Page 101

Lập trình IOS: Triển khai MVVM cho project swift(phần 2)

Triển khai MVVM cho project swift(phần 2)

Bài viết được sự cho phép của tác giả Lê Xuân Quỳnh

Hello guys! Trong bài trước chúng ta đã hiển thị 1 danh sách động vật theo mô hình MVVM rất đơn giản.

Trong bài này, chúng ta sẽ nâng độ khó lên bằng cách request data từ server thật, cụ thể là server của github. Và bài này tôi sẽ viết 1 lớp layer cho network mà bạn có thể bưng vào project của bạn luôn.

  5 bài học quí giá về việc phát triển ứng dụng iOS
  Cách làm một ứng dụng Chat cho Android & iOS bằng Contus Fly như thế nào?

Lần này chúng ta sẽ hiển thị danh sách các Repositories – các source code của Github và hiển thị lên app của mình. Hình ảnh như sau:

Danh sách repositories từ github server

Nhấp 1 ngụm cà phê và vào việc nào 

Đầu tiên source code vẫn là link bài 1:

https://github.com/codetoanbug/MVVMSample.git

Tuy nhiên tôi khuyên bạn chơi với terminal của MacBook cho nó pro nhé. Vì nếu bạn tải chay về bằng trình duyệt thì không thấy source code ở đâu đâu :v

Chơi với terminal đơn giản như sau:

  1. Bạn gõ lệnh cd vào source code hôm trước bạn tải về:
cd TableviewSample

2. Tiếp theo là gõ fetch để lấy source code mới nhất của tôi về:

git fetch

3. Tiếp theo là bạn show toàn bộ branch trên repo của tôi bằng lệnh:

git branch -a

Ở đây bạn sẽ thấy các branch sau:

  bai1
* bai2
  master

Ví dụ bài này, tôi để hết source vào branch tên là bai2. Bạn chuyển sang source code bài 2 như sau:

git checkout bai2

Sau khi branch bai2 được bôi đậm chuyển màu nghĩa là bạn đã thành công rồi đó. Còn nếu nó báo không thấy thì chứng tỏ bạn làm sai, hãy làm lại!

Vẫn chưa chạy được source nhá. Muốn chạy thì phải cài pod cho nó. Nếu máy bạn chưa cài pod thì gõ lệnh sau:

sudo gem install cocoapods

Nhập mật khẩu và bấm enter nhé. Còn nếu bạn cài rồi thì bỏ qua lệnh trên và gõ tiếp lệnh:

pod install

Nếu bạn vào thư mục và thấy như sau nghĩa là đã thành công:

pod sẽ tạo file mới bôi xanh

Và bây giờ hãy mở file TableviewSample.xcworkspace lên và tiến hành ngâm cứu nào 

Hãy chạy project lên và bạn sẽ thấy nó sẽ khác bài 1 với giao diện như sau:

Màn hình mới của app

Tôi đã tạo thêm 1 màn hình, có 2 nút bấm. Nút Local Animals List sẽ load lại ví dụ bài 1 hôm trước. Nút Remote repositories lists sẽ load ví dụ của bài hôm nay. Khi bạn bấm vào nút này nó sẽ show ra màn hình list như tôi đã trình bày ở đầu bài viết. OK, về cơ bản màn hình này tôi đã làm như sau:

  1. Tôi tạo table view như bài 1
  2. Tôi tạo 1 lớp network để call API
  3. Tôi tạo 1 service để viết API lấy data về show
  4. Tôi viết view model sử dụng service trên để lấy data về đổ vào view model
  5. Tôi bắn hết data sang view để hiển thị lên

Khi bạn tách các công việc riêng biệt như này, thì view sẽ chả quan tâm bạn lấy data từ local hay từ server. Nó chỉ quan tâm là view model sẽ trả về cho nó mà thôi. Và nó cũng không có xử lý dữ liệu gì cả.

Đúng phong cách của MVVM rồi đó nha. Còn bây giờ chúng ta hãy tìm hiểu qua về network moya trước nha.

Moya là gì?

Đầu tiên, chúng ta cần hiểu qua 1 số kiến thức cơ bản về mạng internet và cách gọi API từ server. Các ứng dụng ta dùng hằng ngày như mạng xã hội thì đa số sẽ dùng cơ chế gọi tới các API và lấy kết quả trả về. Cơ chế đó có thể là Restful, GraphQL. Ở đây chúng ta sẽ nghiên cứu về Restful, còn thằng GraphQL thì tạm thời học bài khác ha, facebook nó cũng chơi với mấy kiểu GraphQL đó, viết API 1 lần, online realtime luôn, nhưng mà bây giờ chưa phải lúc ta học mấy cái này, để giành lần sau tôi viết bài khác về topic này.

Vậy Restful là gì? Nói nôm na nó là cơ chế gửi request lên, nhận 1 cái json trả về. Sau đó ứng dụng của chúng ta phải đọc được cái json này và chuyển thành model để sử dụng trong app của chúng ta. Có thể dùng get, post, put… Để hiểu nó hơn, bạn hãy vọc qua 1 tí về cái API mà chúng ta sắp sửa request nhé.

Đầu tiên bạn tải cho tôi cái ứng dụng Postman, trước khi code gì bên IOS, thì bạn sẽ có 1 cái API từ bọn backend gửi cho bạn(hoặc bạn làm nó), và chạy nó xem kết quả thế nào. Postman tải ở đây:

https://www.postman.com/downloads/

Khi tải xong bạn cài đặt lên máy, tạo 1 cái get request và chép đường link vào như hình:

https://api.github.com/search/repositories?q=language:swift&sort=stars&order=desc

OK nếu bạn thấy như này nghĩa là thành công:

Hình ảnh Postman gửi get request

Bạn để ý thì mình dùng get để lấy dữ liệu. Ở đây là 1 API của github, dùng để request repositories với ngôn ngữ lập trình là swift. Trong nhiều trường hợp sau này với ứng dụng bạn làm, thì phương thức gửi lên là post. Post hay get thì tùy cách backend định nghĩa bạn nha. OK, vậy là chúng ta sẽ viết code để xử lý API này. Bạn vào đây để xem source code của Moya:

https://github.com/Moya/Moya

Trong phần readme của Moya, nó viết rất chi tiết bằng tiếng Anh cách mà nó hoạt động nha. Moya viết theo kiểu là tao cho mày các tham số đây để gọi 1 API, mày chỉ cần điền vào chỗ trống cho tao, việc còn lại tao làm. Mày điền phương thức là gì(get hay post..), đường dẫn, path, params mày gửi lên là gì, file để test ra sao.. Rồi việc còn lại tao lo cho mày hết. Đó là moya. Rất sexy phải không nào  OK còn cụ thể nó như nào thì đọc tiếp nhé.

Và bây giờ là bắt đầu viết lớp layer network cực kỳ quan trọng sau đây.

  1. Tạo lớp base để request network

Các bạn xem thư mục code base như sau:

Và cùng xem từng thành phần nhé. Nào bây giờ hãy ngắm mấy em mông to ngực bự hoặc làm 1 ít cà phê cho thư giãn đầu óc rồi tiếp tục nhé 

Đầu tiên là file Configs như hình:

Code file config

Ở đây tôi dùng kỹ thuật tự động chuyển server test hay production nhờ flag đơn giản của Xcode. Các bạn để ý struct Network nằm trong struct Configs, nghĩa là nếu sau này bạn cần cố định các giá trị config cho nó thì có thể tạo thêm các struct khác như Color, Dimention… Ở đây bạn chú ý cho tôi đoạn macro #if DEBUG #else. Câu lệnh này nghĩa là nếu như các bạn đang chạy chế độ Debug(chế độ gỡ lỗi) trên Xcode, thì đường dẫn server sẽ là dòng nằm trên, còn nếu các bạn chạy chế độ Release(khi upload lên Appstore) thì dòng dưới. Nghĩa là trình biên dịch Xcode sẽ tự động thay đổi cái baseUrl cho bạn tùy thuộc vào bạn đang chạy debug hay đẩy app lên store nhé.

Tôi dùng 2 dòng giống nhau vì tôi lười, nhưng thực tế nếu làm các dự án thật, bạn sẽ được cung cấp 2 server dev và release, khi đó bạn phải biết cách config như tôi chỉ nhé. Việc nhẹ lương cao cho người lười. Nói thêm, chạy chế độ Debug thì mặc định Xcode nó chọn. Bạn có thể chỉnh về release như sau:

Chỉnh edit Scheme
Chỉnh lại thành Release

Vậy tại sao lại có 2 chế độ này? Các bạn mới sẽ thắc mắc, mình nói đơn giản là nếu chạy debug thì Xcode thêm nhiều đoạn code ẩn vào chương trình nhằm mục đích gỡ lỗi, nên chương trình nặng hơn. Còn khi các bạn fix hết bug rồi, thì khi upload lên không cần phải có mấy đoạn code ẩn đó, cho nên mới sinh ra chế độ release. Mặc định các IDE khác đều xử lý như vậy cả nhé. Như android studio, visual studio..

Đơn giản đúng không nào? OK tiếp theo chúng ta vào file BaseError như hình:

File BaseError

File này 1 enum để tôi xử lý lỗi trả về từ server. Server chúng ta sẽ gặp lỗi cơ bản:

  • Một là lỗi request sai. Ví dụ thằng backend bảo mày gửi get lên nhé, nhưng bạn cố tình post. Hoặc nó bảo bạn truyền 2 param lên để lấy(như username, password để đăng nhập) thì bạn cố tình truyền 1 cái lên, thì cũng được gọi là request sai. Hoặc như mất kết nối và bạn request thì cũng gọi là sai. Đại loại sai thì nhiều loại lắm, bạn cứ hiểu thế cho nó đơn giản.
  • Tiếp theo là đã request lên, server có trả về kết quả. Tuy nhiên khi dịch cái file json của server thì bằng 1 cách nào đó nó sai. Có thể là trả về rỗng, trả về null, trả về không có mà chúng ta lại cố tình decode nó.

Ở đây có bạn hỏi mình vậy json anh nói là cái gì vậy? Cái này bạn hiểu nôm na nó là 1 cái object gồm key và value tương ứng. Còn nếu muốn biết thêm chi tiết xin vui lòng đợi mình viết bài khác hoặc google nhé.

Trong cái postman bạn làm ở trên cái json cũng trả về và bạn có thể nhìn sâu vào nó và đọc từng key và value tương ứng nha.

Rồi, vì mình vừa mô tả ở trên nên mình đã tạo enum như mình nói. Nó gồm 2 case tương ứng. Mỗi case mình lại có 1 title để hiển thị lỗi, và 1 cái description mô tả chi tiết lỗi.

OK, đến đây nếu bạn mông lung không hiểu tôi đang nói gì thì có lẽ bạn lại phải nghỉ ngơi thư giãn 1 tí và xem lại, vì phần sau đây là quan trọng nhất. Phần NetworkProvider là trong tâm của bài này. Các bạn xem file NetworkProvider như sau:

Ở dòng 9 tôi bắt đầu sử dụng thư viện Moya để viết lại lớp provider này. Provider nghĩa là cung cấp nha, nghĩa là tôi muốn refactor moya 1 tí cho dễ dùng hơn(mặc dù nó cũng dễ dùng rồi). Dòng 11 tôi đổi tên 1 tí cho nó ngắn.

Dòng 14 đến 18, tôi lại dùng kỹ thuật debug như trên, tôi chỉ show các log của moya khi chạy debug. Nếu bạn thấy khó chịu khi nhiều dòng chữ in ra ở màn hình console của Xcode, thì bạn có thể bỏ false hết ở 1 chế độ.

Dòng 20 đến 25, tôi tạo 1 protocol nhằm mục đích:

  • Nếu như tôi chạy chế độ defaultNetworking(), nghĩa là tôi gọi API trực tiếp lên server và nhận kết quả trả về.
  • Nếu tôi chạy chế độ stubbingNetworking(), nghĩa là tôi gọi API từ app luôn, và trả kết quả thông qua 1 file json ở dưới app. Do vậy bạn sẽ không cần server khi chạy chế độ này. Nó hay dùng để test API hoặc là khi thằng server đang bận bế vợ hay bồ nó chưa kịp viết thì bạn vẫn ok viết API chạy dưới app mà không phụ thuộc nó, miễn là nó cho bạn 1 file json kết quả trả về.

Đoạn code trên là hàm tạo cho cái provider, rất nhiều tham số của Moya và tôi cũng không muốn giải thích chi tiết nó làm gì. Nhưng mà bạn cứ viết y hệt vậy sau có thời gian vào thư viện Moya xem nó giải thích. Có 1 biến online nhằm mục đích kiểm tra xem mạng mẽo có hoạt động tốt không. Nhưng thực tế trong project này tôi không có xử lý, bạn có thể tự code xem nhé.

Hàm request API:

Hàm request trên tôi chọn chế độ mutil target, vì theo kinh nghiệm code của tôi thì khi chọn Mutil target, bạn có nhiều API, mỗi API 1 cụm nào đó ví dụ như app bạn có các cụm: login gồm (login, logout), Home gồm feed, hot feature… Thì khi xử lý mutil target ở trong Moya, bạn sẽ tách được nhiều file API riêng biệt cho dễ viết code và unit test. Target ở đây bạn hiểu nó là cái server bạn sẽ gọi đến, nó sẽ gồm các thành phần sau:

Nếu bạn đọc được tiếng Anh thì nó dễ hiểu đúng không? còn không thì tôi dịch nôm na thế này. Muốn call API bạn cần:

  • Biết base URL nó là gì
  • Path là gì? ví dụ của chúng ta https://api.github.com/search/repositories thì base URL là https://api.github.com/ còn path là search/repositories
  • Method là get, post, put, download…
  • Sample data là cái mà tôi nói bạn không cần server, chỉ cần 1 file json ở dưới app là có thể viết unit test cho API của bạn. Moya làm sẵn cho bạn để bạn viết test hoặc chạy app dưới local nha
  • Task thì có thể là request dưới dạng param là json gửi lên, hoặc parameter, hoặc plain. Đây là quy tắc call server nên bạn cũng chỉ cần hiểu nôm na nếu như thằng server nó bảo bạn tao bảo mày gọi lên bằng post thì mày chọn kiểu jsonEncoding cho tao. Còn nếu mày gọi là get thì mày chọn parameterEncoding cho tao. Tôi tạo sẵn cho bạn ở đây:

Trong nhiều trường hợp nếu bạn chọn sai thì code của bạn sẽ trả về lỗi không gọi được(gửi get thay vì postjsonEncoding thay vì parameterEncoding)… Rồi sau đó mất cả buổi chả hiểu mình sai chỗ nào. Chú ý cấu hình cho đúng nếu không đừng trách nước biển lại mặn 

Quay lại với cái provider ở trên, Moya trả về 2 case, 1 case success và 1 case là failed. khi call api success, thì nghĩa là response.statusCode == 200, tôi tiến hành dịch cái json đó thành object codeable của tôi.

 if response.statusCode == 200 {
                    guard let results = try? JSONDecoder().decode(T.self, from: response.data) else {
                        // Decode error
                        completion(.failure(BaseError.parseResponseDataFalse(title: target.path)))
                        return
                    }
                    DispatchQueue.main.async {
                        completion(.success(results))
                    }
                }

Đoạn code trên tôi try decode, mục đích là giả sử như bạn viết model để dịch cái response ra object của nó bị sai thì nó sẽ bắn ra lỗi nha(chỗ decode error), và return luôn.

Chú ý là tôi trả về completion hết vào main thread để đảm bảo rằng, UI của view khi có kết quả từ server sẽ xử lý trên main thread luôn nhé. Mặc định Apple chỉ cho phép xử lý UI trên main thread. Còn trường hợp case failed như sau:

Ở đây nghĩa là gọi API bị sai như tôi đã nói ở trên(mất mạng, gọi sai get, post, hay encode sai…) thì nó bắn vào đây. Tôi cũng completion thất bại như code. Tiếng anh completion nghĩa là hoàn thành, ở đây là hoàn thành việc gọi api nhé 

Đoạn code từ dòng 86 bạn thấy cũng na ná đoạn code trên, chỉ khác nhau cái trả về thôi. Ở API request trên là trả về 1 object codeable. Còn request dưới này là trả về mảng. Tôi viết sẵn cho bạn nếu như bạn muốn xử lý mảng nha.

Đoạn code xử lý chạy server real hay là server fake nà 

Như tôi nhắc 2 lần ở trên, đoạn này sẽ giúp bạn xử lý gọi API thật hay là gọi local nha. Cách dùng thì từ từ đọc tiếp nhá. Về cơ bản provider sẽ có những thứ quan trọng như vậy.

2. Tạo GithubAPI cho api của github

Rồi tiếp theo chúng ta sẽ viết GithubAPI cho github này. Sau này nếu có các cụm API khác như authen(bao gồm api Login và logout,…) thì bạn sẽ phải viết tách biệt ra 1 file khác nha.

Dòng 11 đến 13, các bạn xem lại Postman thì thấy rằng API gồm 3 tham số truyền lên:

Cho nên tôi lười tôi cũng đặt tên y hệt luôn như postman. Tên và param bạn nên đặt sát với API nhá. kiểu nó là string hết nha.

Tiếp theo từ dòng 15 trở đi, tôi bắt đầu mô tả cho API này.

  • Đầu tiên là base URL bằng việc lấy từ struct config đã trình bày.
  • – path thì là search/repositories(cũng đã trình bày ở trên).
  • Method là .get
  • sampleData là phần đọc file SearchRepositoriesResponse.json ở local như tôi đã trình bày. Bạn gọi dưới local thì nó sẽ lấy file này fake server trả về kết quả nha. File SearchRepositoriesResponse.json có nội dung y hệt cái response của backend nha bạn. Bạn có thể vào file đó mà xem.
  • Tiếp theo là headers, thường sẽ như dòng 59 nhé. Dòng 62 đến 70 sẽ là phần mô tả params truyền lên cho server:

Vậy là bạn đã hoàn thành viết API cho github nha.

3. Tạo service để gọi API github

Tiếp theo chúng ta phải viết 1 file service để gọi API. Các bạn vào file GithubSearchService:

File này đơn giản kế thừa từ BaseService. nó sẽ dùng provider của BaseService để gọi api của github. Bạn dùng MutilTarget để gọi, thì bạn sẽ tách được các cụm API riêng rẽ. Ví dụ trên là cụm GithubAPI, sau này có thể là AuthenAPI… Khi gọi request bạn cần truyền vào:

  • Target mà bạn muốn gọi. Ở đây là GithubAPI.searchRepositories
  • Kiểu model mà bạn muốn decode để trả về. Ở đây là GithubSearchResponse. Model này tôi tạo sau nhé.

Trong BaseService code như sau:

Ở đây tôi mặc định chế độ test là false. Nếu như bạn tạo service mà set isTest là true thì nó sẽ không bao giờ gọi lên server mà hoàn toàn lấy file json của bạn ở dưới local trả về kết quả. Nó phục vụ cho mục đích test API hay bạn không muốn đợi thằng backend viết xong API.

Rồi bây giờ sau khi xong file service thì bạn tiếp tục viết model. Nghe phức tạp nhỉ? viết code dài dòng vãi. Chắc các bạn mới sẽ phàn nàn với tôi như vậy. Nhưng khi mà bạn làm team lớn thì việc chia nhỏ sẽ như này sẽ hợp lý cho team work nè, và làm nhiều quen thì lại nghiện đó.

4. Tạo model để hứng dữ liệu từ server

Các bạn vào file SearchRepositoriesResponse.json, các bạn sẽ thấy rất nhiều key và value. Ở đây nếu bạn lười bạn có thể vào trang này để tạo model 1 cách nhanh chóng:

https://app.quicktype.io/

Các bạn chép cái json đó rồi parse vào nha. Đảm bảo nó ra 1 cái model luôn. Tuy nhiên vì tôi không cần tất cả data trong đó mà chỉ cần tên và đường dẫn để hiển thị cho nên tôi tạo đơn giản như sau(xem ở file GithubSearchResponse):

Model hứng dữ liệu từ server

Sau khi có model rồi thì các bạn tạo view model nhé!

5. Tạo view model để lấy dữ liệu từ service

Các bạn vào GithubViewModel để theo dõi code như sau:

  • Dòng 12 tôi dùng GithubSearchService. Thực tế dự án thật 1 view model có thể dùng nhiều services các bạn nhé.
  • Dòng 14 là biến closure để nhằm mục đích callback ra view, báo cho view reload lại table khi có kết quả từ server.
  • Dòng 15 tương tự nhưng báo lỗi và hiển thị lên màn hình.
  • Dòng 26 đến 42, tôi viết hàm gọi API từ view model, thông qua service. Có 2 trường hợp, nếu có kết quả tôi tiến hành lưu vào model nằm trong viewmodel và callback ra view để reload lại table. Nếu như thất bại tôi sẽ hiển thị lỗi. Rất clear đúng không nào 

Rồi bây giờ thì đơn giản rồi, việc cuối cùng từ view gọi view model.

6. Sử dụng viewmodel trong view

Các bạn vào file GithubViewController, nhưng tập trung đoạn code trên cho tôi.

  • Dòng 30 là tạo viewmodel nha.
  • Dòng 31 tới 22 là call back khi có kết quả từ server, thì tôi reload lại table để hiển thị kết quả.
  • Dòng 35 đến 37 là khi server báo lỗi, tôi hiển thị lỗi lên view controller.

Vậy là các bạn đã hoàn thành quá trình viết 1 chương trình theo kiến trúc MVVM để gọi api thật. Ở ứng dụng này tôi cũng hay sử dụng thực tế trong các dự án công ty hay cá nhân. Còn thiếu 1 mục quan trọng là unit test cho nó nhưng thôi, vì bài dài quá rồi nên ta để sau nha. Nếu như bạn thấy bài viết hay thì chia sẻ hộ mình. Còn nếu sai sót chỗ nào vui lòng comment ở dưới bài nhé.

OK, tôi tổng kết lại các mục chính cho bạn nắm vững khi viết MVVM thực tế:

  • Tạo provider để call API
  • Tạo file mô tả API của API đó
  • Tạo services để call API
  • Tạo model để hứng dữ liệu từ server
  • Tạo view model để sử dụng services
  • Cuối cùng là dùng view model trong view để hiển thị kết quả

Hi vọng bài viết sẽ giúp các bạn mới làm quen dễ dàng hơn và chuyên nghiệp hơn trong việc viết code MVVM trong dự án của bạn.

Bài viết gốc được đăng tải tại codetoanbug.com

Có thể bạn quan tâm:

Xem thêm Việc làm it swift hấp dẫn trên TopDev

Những hướng đi cho dân IT: Không chỉ là lập trình viên

Những hướng đi cho dân IT: Không chỉ là lập trình viên

Bài viết được sự cho phép của smartjob.vn

Hiện nay, ngành công nghệ thông tin của Việt Nam đang phát triển mạnh mẽ hơn bất cứ khi nào hết và cũng bởi lẽ đó lập trình viên trở thành một nghề được rất nhiều bạn trẻ theo đuổi. Chúng ta đã chứng kiến sự thăng hoa của ngành ngân hàng trong thập kỷ trước để rồi liên tiếp những ngân hàng chìm đắm trong khủng hoảng. Liệu nghề lập trình có đi theo vết xe đổ ấy? Sự bùng nổ của ngành công nghệ thông tin khiến rất nhiều học sinh đổ xô vào các trường về công nghệ. Tuy nhiên không phải ai cũng có đam mê về lập trình, thương mại điện tử, về truyền thông để rồi lại tự hỏi sau này ra trường mình sẽ làm gì, đây có phải ngành nghề phù hợp với mình? Đó là bài toán muôn thuở của các nhà hoạch định khi học sinh, sinh viên không được định hướng kỹ càng, không được thử sức với các công việc thực tế và cuối cùng là không biết cuộc đời mình sẽ đi về đâu.

  Top 7 phương pháp tự học lập trình tốt nhất dành cho Developer
  10 nguyên tắc lập trình nền tảng mà lập trình viên nào cũng cần biết

Trong bài viết này, chúng tôi sẽ chia sẻ những công việc mà một người lập trình hoàn toàn có thể làm sau khi ra trường. Bạn học lập trình không có nghĩa là sau này sẽ phải cắm đầu vào máy tính, code những dòng dài lê thê hay làm những công việc bạn không yêu thích. Hãy chuẩn bị cho mình một chút tư duy kinh tế, một cái nhìn bao quát nhất về xã hội, tôi tin bạn sẽ tìm ra hướng đi cho mình.

Trên thực tế, có những người thực sự đam mê với nghề lập trình. Họ rất thông minh, có tư duy tốt và một nhãn quan khủng khiếp. Đó dường như là tài năng thiên bẩm mà họ có được. Tuy nhiên, chúng ta lại khác: học hành chểnh mảng, không được định hướng, làm bài và thi cử một cách đối phó. Có những sinh viên chưa qua nổi năm nhất đã chán ngấy việc học đại học. Vậy đâu là giải pháp?

Một là bạn bỏ học, theo đuổi thứ mà bạn thực sự yêu thích. Điều này tôi không khuyến khích bởi các bạn sẽ phải chịu rất nhiều áp lực từ gia đình, áp lực từ chính bản thân. Nhưng nếu bạn đã chán ngấy lắm rồi, không có động lực để tiếp tục theo đuổi thì bạn nên dừng lại. Bên cạnh đó, bạn cần có cơ sở để bỏ học, hãy tìm ra những lý do cho riêng bản thân mình (bạn sẽ thi lại, bạn sẽ theo đuổi một nghề mới, bạn đã đủ quyết tâm,…).

Hai là bạn sẽ tiếp tục theo đuổi và nỗ lực hết mình để gắn bó với nghề lập trình. Nếu quyết định như thế, bạn cần:

  • Chăm chỉ: Bạn sẽ không thể trở thành người này người nọ nếu bạn không chăm chỉ. Bạn cần biết học chuyên sâu một ngôn ngữ; bạn cần biết thêm một vài ngôn ngữ khác, bạn cần rèn luyện những kỹ năng cơ bản nhất khi lập trình.
  • Kinh nghiệm: Đây là thứ rất quan trọng khi bắt đầu đi làm. Sẽ có rất nhiều khó khăn bởi công việc thực tế chẳng giống như những gì đã được học nhưng nếu bạn đủ thông minh, bạn sẽ lĩnh hội được rất nhiều. Hãy tạo ra giá trị mà chỉ mình bạn có chẳng hạn bạn code rất nhanh mà không dính nhiều lỗi; bạn giỏi trong việc tìm ra và xử lý bug; bạn có thể làm việc với người nước ngoài;… Đó là những lý do các doanh nghiệp muốn giữ bạn lại, muốn tăng lương cho bạn.

Bạn có thể làm gì?

Trở thành lập trình viên – Developer

Là người thiết kế, xây dựng và bảo trì các chương trình máy tính, các website, các ứng dụng trên điện thoại di động. Trong bài viết Làm thế nào để trở thành lập trình viên, Smartjob đã đề cập đến những kỹ năng, phẩm chất cần thiết nhất để bạn có thể rèn luyện và chuẩn bị hành trang cho mình một cách sớm nhất, đúng hướng nhất. Ngoài ra, như đã đề cập ở trên, kinh nghiệm là thứ quan trọng bậc nhất mà lập trình viên cần có. Bạn sẽ chẳng thể làm gì nếu không có kinh nghiệm. Kinh nghiệm tạo ra giá trị cho bạn, giúp bạn sáng tạo ra những cái mới và khiến công việc của bạn bớt  khó khăn đi rất nhiều. Đề có kinh nghiệm, hãy bắt tay vào code ngay từ khi còn ngồi trên ghế nhà trường. Lập trình là công việc mà càng sai ta càng nhận ra nhiều điều.

Trở thành một Tester

Công việc này có thể nói nôm na là bới bèo ra bọ, bới lông tìm vết. Sau khi lập trình viên đã code, Tester sẽ chạy thử, tìm mọi cách để mò ra những lỗi trong quá trình vận hành. Với nhiều người đây thực sự là công việc nhàm chán và nhức đầu. Nó phù hợp hơn với những bạn gái có tính tỉ mỉ, cẩn thận. Bạn cần đặt mình vào vị trí người dùng để trải nghiệm sản phẩm của nhóm và tìm ra những lỗi hay nhược điểm của sản phẩm.

Tester thường được mệnh danh là “bà già khó tính” bởi khi làm ở vị trí này bạn luôn bắt được những lỗi cơ bản, sai rồi mà cứ lặp lại khiến mình trở nên điên đầu. Đây là công việc không dành cho những người dễ bị stress – Cáu xong rồi thôi chứ không nên để sự nóng giận của mình làm ảnh hưởng đến cả nhóm. Tỉ mỉ, bình tĩnh và nóng nảy đúng lúc là những phẩm chất cần thiết nhất cho công việc này.

Tuyển dụng Tester lương cao tại Topdev

Thiết kế web, thiết kế đồ họa

Được gọi là Designer, có nhiệm vụ tạo ra giao diện của một website hay một ứng dụng một cách hoàn chỉnh. Công việc này cũng liên quan khá mật thiết đến lập trình, seo,… Yêu cầu là bạn phải sử dụng thành thạo các chương trình thiết kế, tạo đồ họa như Photoshop, Al, Dreamweaver, Flash,… và rất nhiều phần mềm hỗ trợ khác. Càng thành thạo bao nhiêu, càng biết nhiều chương trình bao nhiêu thì việc làm của bạn càng hiệu quả bấy nhiêu.

Thường thì những doanh nghiệp nhỏ chỉ có một designer hoặc lập trình viên sẽ kiêm luôn design nên cường độ làm việc của bạn sẽ rất dày. Bạn sẽ phải “ôm” một vài dự án một lúc. Tuy nhiên công việc này không quá nặng đầu như lập trình viên hay tester. Chỉ cần đam mê và có đầu óc thiết kế, bạn sẽ hoàn thành tốt công việc.

Tuyển thiết kế đồ họa designer

Chuyên viên phân tích dữ liệu

Làm việc cho các công ty phần mềm, công ty tư vấn hay công ty ứng dụng công nghệ. Việc của bạn là thu thập, xử lý và tổng hợp dữ liệu sau đó sử dụng chúng để chuẩn bị cho các chương trình nghiên cứu, marketing hay các chương trình giới thiệu sản phẩm. Muốn làm được việc này, bạn không cần phải code giỏi mà nên tìm hiểu càng nhiều phần mềm càng tốt. Bên cạnh đó, tư duy là thứ rất quan trọng và bạn nên tìm hiểu kỹ trước khi phỏng vấn vào vị trí này. Cần có cái nhìn bao quát toàn bộ dự án chứ không chỉ có mớ code trong đầu.

Thường thì công việc này dành cho người lập trình đã có kinh nghiệm 2 đến 3 năm, biết phân tích, biết “chém gió” bởi bạn sẽ phải truyền đạt cho người khác ý tưởng và cách làm của mình; đôi khi còn phải thuyết phục được cấp trên hay đối tác. Đây là hướng đi hoàn toàn có triển vọng nếu bạn muốn làm lãnh đạo các dự án.

Nhân viên kinh doanh

Thoạt nghe có vẻ không hợp lý nhưng rất nhiều lập trình viên sau khi làm một thời gian đã phát hiện ra tài năng “chém gió” của mình và chuyển hướng sang công việc này. Chúng ta thường nghĩ đây là vị trí dành cho sinh viên kinh tế, marketing tuy nhiên thực tế không phải vậy. Rất nhiều người đã làm việc đúng ngành nghề của mình một thời gian để lấy kinh nghiệm sau đó dùng kiến thức của mình để thuyết phục khách hàng, làm việc với các đối tác nhằm phục vụ mục đích kinh doanh của công ty.

Nhân viên kinh doanh ở đây có thể là kinh doanh phần mềm, truyền thông cho các dịch vụ giá trị gia tăng, kinh doanh giải pháp, giới thiệu các dự án mới,… Thường thì vị trí này sẽ thoải mái hơn về thời gian nhưng cũng sẽ bị áp doanh số. Những kiến thức về marketing, quảng cáo thực sự hữu ích nếu bạn muốn “dấn thân” vào công việc này.

SEOer

SEO là từ viết tắt của Search Engine Optimization có nghĩa là tối ưu hóa công cụ tìm kiếm. Chúng ta có thể hiểu nôm na SEO là tổng hợp những phương pháp làm gia tăng lượng traffic của website với công cụ tìm kiếm chính là Google. Đây làm một nghề mới trong những năm trở lại đây và hiện đang được rất nhiều bạn trẻ theo đuổi.

Việc của bạn là sẽ phải làm sao cho các từ khóa được xuất hiện ở những vị trí top trên google, được nhiều người tìm kiếm, mang lại lượng truy cập cho website nhằm phục vụ những mục đích khác nhau (tuyển dụng, tin tức, kinh doanh,…). Những tố chất cần cho nghề SEO là kiên trì, tỉ mỉ và làm đúng phương pháp. Bạn cần được các chuyên gia hướng dẫn và tham gia một vài dự án trước khi có thể tự mình lập kế hoạch thực hiện dự án. Nếu thành thạo SEO, bạn hoàn toàn có thể tự mình kinh doanh, tự marketing cho các sản phẩm của mình.

Những công việc kể trên là những việc phổ biến nhất với dân IT ở Việt Nam hiện tại. Ngoài ra còn rất nhiều ngành nghề mới nếu bạn muốn làm việc tại các công ty liên doanh, các tập đoàn nước ngoài:

  • Kỹ sư phần mềm
  • Kỹ sư phần cứng
  • Kỹ sư blogchain
  • Kỹ sư thực tế ảo
  • Kiến trúc sư IoT
  • Kỹ sư cụm GPU
  • Chuyên gia an ninh mạng
  • …..

Cuối cùng, Smartjob cho bạn một lời khuyên là hãy học tốt một trong ba thứ tiếng Anh, Nhật, Hàn bởi chúng có thể mở ra những cơ hội mới mà chúng ta chẳng thể tưởng tượng nổi.

Bài viết gốc được đăng tải tại smartjob.vn

Có thể bạn quan tâm:

Truy cập ngay việc làm IT đãi ngộ tốt trên TopDev

Node.js và Mongodb hướng dẫn kết nối

Node.js và Mongodb hướng dẫn kết nối

Bài viết được sự cho phép của smartjob.vn

Mục đích: Kết nối node js với cơ sở dữ liệu mongodb.

Ở phần này hướng dẫn một số cách kết nối với cơ sở dữ liệu Mongodb và các truy vấn Mongodb.

  MongoDB là gì? Cơ sở dữ liệu phi quan hệ
  Cách tạo một Docker đơn giản cho Node.JS

Các bạn xem qua ở phần trước đã có hướng dẫn cài đặt Node.js trước khi tới phần này.Hướng dẫn nhanh phần cài đặt Mongodb.

Hướng dẫn cài đặt Mongo db phiên bản mới nhất và tool Robomongo quản lý (nó giống các tool quản lý mysql như Naviacat )

Cách cài đặt riêng từng gói .Truy cập trang chủ, download bản cài đặt: https://www.mongodb.org/downloads#production

Lưu ý: Bạn nên sử dụng hệ điều hành 64 bit, không khuyến khích sử dụng hệ điều hành 32 bit

Gói cài đặt điển hình (như ảnh chụp màn hình) là mongodb-win32-x86_64-3.2.3-signed.msi có dung lượng 93 MB

Tiếp tục cài đặt và tới finish

Sau đó cài đặt biến môi trường như sau :

Bấm tổ hợp phím Windows + R để gọi tiện ích Run, gõ systempropertiesadvanced  để vào chương trình thiết lập biến môi trường.

thêm text :    ;C:\Program Files\MongoDB\Server\3.2\bin   vào cuối bước 3

 Mở CMD và gõ lệnh : mongod -version

Hiện lên màn hình sau nếu thành công

Sau đó tạo thư mục để chứa Data base như hình sau :

Nội dung file config.txt

Sau đó trỏ tới thư mục cài đặt mông trên ổ C: của mình đã cài đặt như đường link:

C:\Program Files\MongoDB\Server\3.2\bin

Và gõ lệnh sau :

Sau đó gõ lệnh sau để kiểm tra version : mongodb -version

Sau đó tới thư mục sau và gõ lệnh để chạy :mongod.exe –dbpath “C:\mongodb\data”

Chú ý : Từ lần sau khi muốn kết nối với Mongodb bằng Node.js hay PHP … bạn mở CMD và thự thi dòng lệnh trên

Các bạn tham khảo nội dung hướng dẫn dung Robomongo quản lý Mongodb: https://smartjob.vn/huong-dan-dung-robomongo-quan-ly-mongodb/

Tải source code tại đây:node_mongo

Tạo cấu trúc file thư mục như sau : folder : node_mongo  file : conect_smartjob_mongo.js

Mở CMD và trỏ tới thư mục chứa file conect_smartjob_mongo.js gõ lệnh :   npm install mongodb  như hình dưới

Sau đó thì thư mục sẽ xuất hiện thêm folder:node_modules  như hình vẽ

Nội dung file : conect_smartjob_mongo.js

Ở dòng 24 của file conect_smartjob_mongo.js như trên ta thấy điều kiện truyền vào lấy ra các bản ghi (theo cách nói của cơ sở dư liệu mysql ) ở đây là lấy ra các document có điều kiện là có  state bằng ‘MA‘ và hiển thị lên cửa sổ lệnh cmd qua lệnh console.log  sau đây là kết quả hiển thị được:

Ở cùng dòng đó  ta có thể thay bằng các điều kiện khác để thực hiện truy vấn như:

– collection.find( ).toArray      // lấy tất cả các kết quả trong collection

– collection.find({‘state’: ‘MA’,’pop’:9610}).toArray      // thêm 1 điều kiện query nữa

– collection.find({‘address.zipcode’: 10075}).toArray   // nếu có chứa các cặp field: value lồng trong cặp field:value

-collection.find({ pop:{$gt:9600} }).toArray    //  điều kiện lớn hơn với filed pop

-collection.find({ pop:{$lt:9600} }).toArray   // nhỏ hơn

–  collection.find( {$or: [ { “sate”: “MA” }, { ‘pop’:{ $gt:40992} } ]}).toArray   // phép toán OR

Làm tương tự và thực hiện lệnh thực thi file insert.js giống như ở trên : node insert.js file code insert.js như sau:

Chú ý dòng 27  insert dữ liệu vào qua hai biến smartjob1,smartjob2.

và file update.js  update thay đổi 1 thông số trong document

Chú ý dòng 22 thay thế 1 document có thông số city = smartjob.vn và update city = smartjob.vn2

Xóa 1 document có trường (key) citysmartjob.vn2

Ở các bài tiếp theo mình cũng giới thiệu cách kết nối Mongodb bằng node.js theo ODM  hướng đối tượng băng Mongose . Chúc các bạn thực hành thành công mọi thắc mắc các bạn có thể liên hệ qua Skype : nguyenanhdung90.

strongmindinstrongbody-expert

Bài viết gốc được đăng tải tại smartjob.vn

Có thể bạn quan tâm:

Xem thêm Jobs Developer hấp dẫn trên TopDev

Lập trình IOS: Tạo Leak memory trong singleton (bonus observers) (phần 2)

Tạo Leak memory trong singleton(bonus observers) (phần 2)

Bài viết được sự cho phép của tác giả Lê Xuân Quỳnh

Trong phần 1, chúng ta đã tạo được leak memory trong closure. Việc tự tạo ra 1 cái leak để nghiên cứu cũng giống như câu nói “đừng đẩy tao tự ngã” 🤣

For fun tí thôi, nhưng mà thực tế khi bạn hiểu được tại sao lại leak như vậy rồi thì lần sau bạn sẽ không dễ bị leak thế nữa, đúng không nào? Trong bài này, chúng ta lại tự ngã vào 1 leak hoàn toàn mới: Đó là leak trong singleton. Ồ nghe nó có vẻ nguy hiểm nhỉ. Nhưng mình cá khi đọc xong cái bài này các bạn lại bảo “ôi tưởng thế nào, dễ vãi lằn ” OK con dê, vậy hãy bóp mông em đồng nghiệp 1 cái rồi vào việc luôn nào.

  Mọi thứ bạn nên biết về Memory Leaks trong IOS (phần 1)
  Mọi thứ bạn nên biết về Memory Leaks trong IOS (phần 1)

Đầu tiên là bạn cần có source nha:

https://github.com/codetoanbug/LeakMemorySamples.git

Code nằm ở branch bai2, và nếu bạn không biết tôi nói gì thì vui lòng đọc đoạn sau:

trích dẫn từ bài: https://codetoanbug.com/lap-trinh-ios-trien-khai-mvvm-cho-prject-swiftphan-2/

Tuy nhiên tôi khuyên bạn chơi với terminal của MacBook cho nó pro nhé. Vì nếu bạn tải chay về bằng trình duyệt thì không thấy source code ở đâu đâu :v
Chơi với terminal đơn giản như sau:
Bạn gõ lệnh cd vào source code hôm trước bạn tải về:
cd LeakMemorySample
2. Tiếp theo là gõ fetch để lấy source code mới nhất của tôi về:
git fetch
3. Tiếp theo là bạn show toàn bộ branch trên repo của tôi bằng lệnh:
git branch -a
Ở đây bạn sẽ thấy các branch sau:
bai1 * bai2 master
Ví dụ bài này, tôi để hết source vào branch tên là bai2. Bạn chuyển sang source code bài 2 như sau:
git checkout bai2
Sau khi branch bai2 được bôi đậm chuyển màu nghĩa là bạn đã thành công rồi đó. Còn nếu nó báo không thấy thì chứng tỏ bạn làm sai, hãy làm lại!

  1. Singleton là gì?

Trước khi tạo được leak cho nó thì chúng ta hãy hiểu Singleton là gì đã nha? Nó là 1 cái khái niệm gì đó bằng tiếng Anh. Nhưng nếu hiểu theo nghĩa thuần Việt singleton là kỹ thuật tạo class mà chỉ khởi tạo được duy nhất 1 lần. Nghĩa là gì? Cùng xem ví dụ sau:

class AlertViewHandleLogic {
}

Tôi tạo 1 class như trên và hoàn toàn không có gì trong đó cả. và bạn mở project lên, vào file SingletonLeakViewController:

thì thấy nó chạy bình thường như hình. Tiếp theo tôi biến class AlertViewHandleLogic thành singleton như sau:

Chuyển class thường thành class Singleton
  1. Dòng 11: Tôi đưa hàm tạo init thành private, nghĩa là không cho phép các lớp khác khởi tạo nó nữa.
  2. Dòng 12: Tôi tạo 1 biến static shared để gọi hàm tạo tại chính nó, ok nó chạy được.

Khi tạo như này, bạn build lại và vào xem ở file SingletonLeakViewController thì kết quả như sau:

Nó báo lỗi đỏ chót, dịch ra nghĩa là hàm init được bảo vệ private – do đó bạn không thể gọi hàm tạo được ở đây. OK vậy tôi sẽ gọi lớp này như nào?

Tôi gọi nó qua biến shared. Lúc này do shared là biến static nên nó chỉ khởi tạo đúng 1 lần và biến này tồn tại mãi mãi trong class AlertViewHandleLogic. Vậy là bạn đã tạo được 1 class Singleton thành công 😻

Vậy trong thực tế, chúng ta có hay gặp singleton không? Ồ rất nhiều luôn bạn nhé. Ví dụ Apple có 1 đoạn code trong UIKit như sau:

UIApplication.shared.keyWindow?.rootViewController

Thì biến shared ở trên chính là singleton nha. Ở ví dụ trên, khi tôi muốn lấy rootViewController thì tôi thông qua biến shared của lớp UIApplication để truy cập. Vì mỗi ứng dụng IOS thì cần 1 biến để lưu rootViewController và duy nhất thôi, cho nên họ tạo singleton cho nó. Quy tắc đặt tên cho singleton thường là shared, hoặc là getInstance() như thời Objective-C bạn nhé. Vậy là bạn biết được tác dụng của Singleton như nào rồi ha. Hãy nhớ cho mình chúng ta chỉ tạo Singleton khi:

  • Quản lý 1 biến hay class duy nhất chạy xuyên suốt ứng dụng
  • Static sẽ không được giải phóng cho đến khi ứng dụng giải phóng

Do vậy, cũng không thể lạm dụng Singleton hay static được đúng không nào? Nếu bạn hiểu đơn giản thì swift hay các ngôn ngữ lập trình khác có 2 loại biến cơ bản là dynamic và static. Dynamic thì khởi tạo runtime, và giải phóng khi lớp chứa nó hủy. Còn static thì khởi tạo luôn khi class đó được gọi init, và tồn tại xuyên suốt ứng dụng. Tuy nhiên nhiều trường hợp bắt buộc vẫn phải dùng static dù muốn hay không.

Trong ví dụ chúng ta làm sau đây, tôi muốn chương trình sẽ sau 1 khoảng thời gian nào đó hiển thị 1 màn hình alert lên view controller, bất kỳ ở đâu nó cũng show lên được ha. Và việc xử lý show đó do class AlertViewHandleLogic xử lý. Nghe hấp dẫn nhỉ? Trong thực tế có những ví dụ như bạn muốn sau 1 khoảng thời gian ứng dụng tự lock màn hình cũng có thể áp dụng, vân vân mây mây ha.

OK đọc đến đây thì cũng mệt rồi, nên hãy đi hát 1 bài rồi ta lại tiếp tục nha 😷

2. Tạo singleton quản lý show alert

Cùng theo dõi đoạn code sau:

Xử lý logic show popup nhờ timer
  • Dòng 12, 13 tôi có 1 biến timer để tính sau 1 khoảng thời gian sẽ show alert ra
  • Dòng 23 đến 27, tôi tạo hàm để cứ sau 1 khoảng 5s nó sẽ gọi vào biến closure needShowAlertView. Mục đích biến này là bắn ra callback cho view controller nào được gán sẽ thực hiện action này.

Vào SingletonLeakViewController và theo dõi đoạn code sau:

  • Dòng 15, tôi khởi tạo biến singleton của class AlertViewHandleLogic
  • Dòng 16 tôi gán closure needShowAlertView và hiển thị 1 dòng chữ need show here
  • Dòng 20 tôi gọi hàm resetShowAlertTimer để timer hoạt động

Sau khi build tôi nhận được kết quả sau:

Vậy là cứ đều đặn 5s nó sẽ bắn ra callback để chúng ta có thể viết logic show cái alert này ra.

Tuy nhiên, vì hàm alertViewHandleLogic.resetShowAlertTimer() gọi rườm rà nên tôi sẽ đưa nó vào hàm init của AlertViewHandleLogic để không phải gọi mỗi khi tạo callback needShowAlertView.

Tuy nhiên có 1 vấn đề nghiêm trọng như sau:

  • Biến closure needShowAlertView thuộc lớp AlertViewHandleLogic, là class Singleton. Do đó khi biến này được gán ở SingletonLeakViewController thì chỉ có view này show alert thôi. Giả sử tôi gán vào SecondViewController thì nó không còn hoạt động ở SingletonLeakViewController. Ồ trong khi tôi muốn là nó phải hoạt động ở tất cả các viewcontroller cơ mà 😡🤬

Khó rồi nha, vì singleton chỉ là 1 và duy nhất, cho nên chúng ta không thể áp dụng kỹ thuật callback bằng closure này được. Giải pháp là gì?

3. Thay thế closure callback bằng observers

quát dờ heo? Ông vừa chỉ tụi tôi cái singleton rồi định chỉ thêm cái observers? Có nhiều quá không vậy? 🥱😲 Ồ nếu bạn vừa ngáp ngủ thì thôi tạm thời làm cốc trà đá, hút điếu thuốc, ngắm em bán nước mông cong 1 lúc rồi lên tiếp tục sau nha.

😍 OK rồi bây giờ ta sẽ tiếp tục nghiên cứu observers là gì nè?

Observers dịch theo nghĩa thuần Việt nhất là 1 cái quan sát viên. Mỗi khi timer tới 5s, thì nó sẽ phải báo cho tất cả những thằng view controller dùng nó phải show alert lên. Tất nhiên là view controller đang ở chế độ hiển thị nha. Kỹ thuật này dùng thế nào?

Đơn giản là bạn tạo 1 cái protocol ở cái class AlertViewHandleLogic, sau đó bạn tạo thêm các hàm add và remove các protocol này để sử dụng hay xóa việc lắng nghe protocol ở các view. Protocol có nhiệm vụ báo cho các view controllers.

Nói thì hay lắm, code xem nào 😅 Theo dõi đoạn code sau:

  • Dòng 11 đến 14, Ở đây tôi tạo protocol AlertViewHandleLogicDelegate có nhiệm vụ là bắn hàm needShowAlertView để show alert. Một số quy tắc viết protocol nếu bạn chưa nắm vững có thể xem tại đây ha.
  • Dòng 18 tôi làm 1 biến observers kiểu AlertViewHandleLogicDelegate nhằm lưu trữ các observer(quan sát viên) của các view controller muốn listen nó.

Tiếp tục xem đoạn code:

  • Dòng 43 đến 46, tôi tạo hàm add observer. Tôi có check nếu nó chưa được add thì mới thêm, có rồi thì bỏ qua không thêm nữa.
  • Dòng 51 đến 54 tôi viết hàm remove observer. Vì không thêm lặp cho nên tôi chỉ check phần tử đầu tiên nếu là thằng cần remove thì xóa ra khỏi list thôi.

Trong hàm bạn sửa lại 1 xíu như sau:

Mục đích là chạy 1 vòng for rồi notification cho tất cả những thằng đã add observer nha. Tôi comment cái callback bằng closure.

OK vậy là bạn đã chuẩn bị để chơi với observer rồi nha. Bây giờ bạn vào SingletonLeakViewController và code như sau:

  • Dòng 21 tôi add observer cho SingletonLeakViewController. Khi add như này thì nó sẽ lắng nghe được sự kiện sau 5s sẽ show alert.
  • Dòng 26 đến 29, vì tôi add cho nên class SingletonLeakViewController phải extend các hàm từ protocol AlertViewHandleLogicDelegate. Tôi show print để biết nó hoạt động.
  • Ở các view controller khác bạn làm tương tự.

Và kết quả chạy như sau:

Good job. Vậy là nó đã hoạt động 🥰

Nhưng khoan đã, ông vừa bảo leak cái mẽ gì trong singleton rồi cơ mà, sao giờ lại lan man ra đây? Ồ bây giờ tôi mới chốt issue nè. Leak memory đã xảy ra rồi đó!

Bây giờ bạn thêm dòng code sau để check SingletonLeakViewController giải phóng khi bấm back ra không:

Và nó hoàn toàn không nhảy vào! OMG tôi đã làm gì sai mà leak vậy 😩🥺

Rồi quay lại vấn đề, việc ta add 1 observer vào SingletonLeakViewController như sau:

AlertViewHandleLogic.shared.addObserver(self)

Thì view controller này đã tham chiếu mạnh tới class AlertViewHandleLogic. Nghĩa là lớp SingletonLeakViewController chỉ bị giải phóng khi observer trong AlertViewHandleLogic được giải phóng. Tuy nhiên AlertViewHandleLogic làm sao mà giải phóng được khi nó có hàm remove ở đâu đâu. Có bạn bảo bạn ơi sao bạn không đưa hàm remove như này:

deinit {
        NSLog("free memory SingletonLeakViewController")
        AlertViewHandleLogic.shared.removeObserver(self)
    }

Rất tiếc là nó đã không giải phóng thì không nhảy vào deinit, mà không vào thì không chạy remove observer được. Câu chuyện trở thành bế tắc rồi 😢

Giải pháp của tôi như sau:

  • Tôi trick khi nhấn nút back ở UIBarButtonItem thì sẽ gọi vào hàm viewWillDisappear, tôi sẽ xóa ở đó:

Kết quả như sau:

Vậy là SingletonLeakViewController đã call được vào deinit, nghĩa là nó được giải phóng 😍

Tuy nhiên tôi thấy thật sự đây cũng chưa phải là giải pháp thông minh nhất, vì bạn sẽ phải biết trick tùy trường hợp mà giải phóng chứ không phải lúc nào cũng là như tôi làm ở trên.

OK vậy là bài này cũng khá dài rồi, nếu bạn có giải pháp nào hay hơn của tôi vui lòng hãy comment cho tôi biết ở dưới bài này nhé.

Cảm ơn vì đã theo dõi tới đây và hi vọng bạn sẽ học được thêm nhiều kiến thức hay ho, thực tế qua bài này. Thanks all!

Bài viết gốc được đăng tải tại codetoanbug.com

Có thể bạn quan tâm:

Xem thêm Việc làm ios hấp dẫn trên TopDev

Vuejs Render Process bao gồm những bước nào?

Vuejs Render Process bao gồm những bước nào?

Bài viết được sự cho phép của tác giả Kiên Nguyễn

Tuần trước đã có bài viết về nextTick() trong Vuejs, nhân đây muốn giới thiệu qua cho anh em luôn về Vuejs Render Process. Hiểu process của Vue mới nâng tầm lên được. Chứ cứ v-if, v-else, v-show hoài mà không biết nó render như thế nào thì toang.

Sẵn sàng chưa nào?. Xúc ngay và luôn cho nóng nha!

  Cách sử dụng các plugins jQuery trong VueJS
  Call API trong VueJS theo cách thông minh nhất

1. Virtual DOM

Trước khi tìm hiểu về Vuejs Render Process, bắt buộc phải có kiến thức về DOM (Document Object Model). Anh em nào chưa biết có thể tìm hiểu qua bài viết này. Trước đây khi có thay đổi phía FE, một node trên DOM tree thay đổi sẽ kéo theo phải render lại toàn bộ tree.

Việc thay đổi trên toàn bộ cây DOM thật sự tệ. Chính vì vậy, Virutal DOM ra đời.

Tóm tắt nhanh như tốc độ crush tỏ tình như sau:

  • Virtual DOM giúp tăng perfomance khi thực hiện thay đổi trên screen
  • Luôn có sự so sánh những gì thay đổi giữa VirtualDOM và DOM trước khi cập nhật.
  • Virtual DOM được sử dụng cho các dự án sử dụng Vuejs

Thực chất, khi run build Vuejs Application

2. Vuejs Render Process

Cả một quá trình dài trước khi Virtual DOM được sinh ra và phản ánh lên DOM thật. Quá trình này bao gồm 4 bước (nói rõ ra thì Vuejs Render Process) bao gồm 4 bước chính. Để hiểu rõ hơn về quá trình render, bắt buộc phải nhớ kĩ các step đó như sau:

vue-render-process4 bước render process của Vuejs nằm ở đây.
Nguồn / Source: Medium

2.1 defineProperty

Bắt đầu một process dài cập nhật lên DOM tree luôn là defineProperty. Ở step này, một khi dữ liệu được cập nhật và xác nhận là có thay đổi, method defineProperty sẽ được goi.

Về mặt bản chất, defineProperty có vai trò như người thông báo. Nó luôn lắng nghe cho mỗi lần data thay đổi, thông báo tới watcher sự thay đổi về data tại component.

Dữ liệu A thay đổi -> defineProperty gọi function setter -> thông báo cho watcher.

Rõ ràng mà nói, step đầu tiên trong Vuejs Render Process là defineProperty, việc xác định được data nào thay đổi báo cho watcher là bước đi vô cùng quan trọng

2.2 Watcher

Watcher được khởi tạo cho từng component trên Vue, ngay lúc application được khởi tạo. Nhiệm vụ chính của watcher là cập nhật DOM và Virtual DOM. Tuy nhiên, Watcher chỉ update cây DOM tạm thời (immediately) sau khi setter thông báo cho nó biết.

2.3 Queue

Khi thằng watcher nhận được thông báo thay đổi, nó tự đưa nó vào một hàng đợi (Queue). Nguyên nhân là có nhiều data thay đổi cùng lúc. Để xử lý được hết cần đẩy vào hàng đợi (để xử lý từ từ).

Nếu cả title và message trên component được update data cùng lúc (sau khi gọi API thành công). Vue Watcher sẽ đẩy từng thay đổi đó vào Queue (thứ tự order theo các điều kiện đặc biệt)

2.4 nextTick

Cuối cùng là nextTick API (bạn nào chưa biết có thể tham khảo bài viết này). nextTick giúp consumed and flushed (dịch tạm là chấp nhận và đẩy ra) cây DOM thật. Mỗi watcher sẽ được cập nhật lên DOM thật từ Virtual DOM. Đây cũng là cách là phương thức watch trong Vuejs hoạt động.

Việc cập nhật từ Virtual DOM lên DOM được thực hiện tự động bởi Vue qua method run(). Tuy nhiên, cũng có thể tự gọi function này khi muốn cập nhật DOM ngay lập tức.

3. Kết luận

Tóm lại, Vuejs Render Process chỉ tóm gọn lại trong bức hình dưới đây. Mỗi quá trình đều có một chức năng và nhiệm vụ khác nhau. Tuy nhiên, chỉ đơn giản nhớ rằng:

  • data thay đổi -> gọi defineProperty -> báo cho watcher cái gì đã thay đổi
  • watcher trên từng component được tạo -> nếu có nhiều watcher -> đẩy vào queue
  • Lần lượt từng Queue gọi nextTick() API -> cập nhật lên DOM

Qua bài viết này, mong rằng các vị huynh đài có cái nhìn khách quan và rõ ràng hơn về Vuejs Render Process. Để làm việc, code được với Vuejs thì không cần hiểu tới render process. Nhưng để trở thành master, được gọi là Senior thì cần nắm rõ kiến thức này.

Ngoài hiểu sâu để nhớ lâu, những thông tin bài viết cũng cấp còn giúp fix những bug quái lạ khi làm việc. Biết khi nào nên set data thay đổikhi nào nên cập nhật Virtual DOM lên DOM.

vue-render-processChả liên quan gì nhưng thấy process nào cũng hay!

4. Tham khảo

Hết rồi. Cảm ơn anh em đã đọc bài. Nhớ like và share Facebook page nha!

Bài viết gốc được đăng tải tại kieblog.vn

Có thể bạn quan tâm:

Xem thêm Việc làm Developer hấp dẫn trên TopDev

Những Tố Chất Cần Thiết Của BrSE

Những Tố Chất Cần Thiết Của BrSE

Bài viết được sự cho phép của tác giả Nguyễn Văn Trọng

Sau 6 tháng trời bỏ bê thì nay mình quay lại viết lách một chút. Đợt rồi có xuất bản sách nhưng thiết nghĩ những gì viết trong đó đều ở mức rất cơ bản. Không biết thì không làm được nhưng cho dù biết hết cũng chưa chắc giỏi được. Bởi vậy mình sẽ quyết định viết tiếp cho tới khi nào anh em chán đọc thì dừng. Chắc không ai chán tại viết hay thế kia mà (muahaaa, tự an ủi).

Vào luôn chủ đề chính, nay mình tản mạn một chút về các tố chất cần thiết để có thể theo nghề này.
– Kiên trì
– Tập trung
– Thích nghi

Có rất nhiều yếu tố để tạo nên thành công trong sự nghiệp mỗi người. Mình không tự nhận bản thân đã làm được gì to tát nhưng nếu không có những tố chất trên thì rất khó để đi xa được cho tới ngày hôm nay. Bởi vì nó quá cần thiết nên muốn chia sẻ ngay cho anh em.

Tuyển dụng kỹ sư cầu nối lương cao lên đến 3000 USD

Kiên Trì

Nếu chọn đích đến là BrSE thực thụ thì cần có 3 kỹ năng chính : Code, JP và kỹ năng mềm. Cái này mình đã nói nhiều lần, vậy nên cho dù xuất phát điểm làm NonIT-JPN2 +, IT + NonJP, hoặc không có cái gì hết … thì cũng tới đích được, thời gian dài ngắn tuỳ điểm bắt đầu cũng như nỗ lực từng người. Cuối cùng người kiên trì nhất mới là người tới đích.

Ví dụ như việc học tiếng Nhật. Hồi sinh viên cũng chỉ tình cờ đi phỏng vấn 1 công ty Nhật về trường tuyển và pass, cũng không hiểu sao lại được chọn với tỉ lệ 40/1000 sinh viên, chắc tại đẹp trai. Sau đấy là một khoảng thời gian vật lộn với biết bao cám dỗ (game, nhậu, bóng đá …) để theo lớp tới cùng, và mình là một trong 9 người còn lại của lớp đấy trong khi mấy bạn khác bỏ hết. Sau đấy dù cố thế nào thì hợp đồng bị huỷ do khủng hoảng, vậy là hơn 6 tháng công sức đổ biển. Sau đấy ra trường đi làm, trong khi các bạn khác bỏ luôn thì mình vẫn miệt mài đi học thêm JP ở các lớp buổi tối, rồi tham gia khoá BrSE cho tới lúc có thể nghe nói đọc viết tốt và sang được JP. Nhưng sau đấy lại phải học thêm vì nghe khách nói chả hiểu mie gì, nói năng lắp ba lắp bắp nhưng trước đấy cứ nghĩ mình ngon rồi. Tiếp tục mài dùi cho tới bây giờ vẫn vậy.

Đó chính là tính kiên trì. Vậy nên nếu bạn nào đang bơ vơ lạc lõng thấy học mãi không vào thì cứ so đi, mình mất gần 10 năm học, các bạn đã bỏ ra bao lâu thời gian mà ngồi đấy than ? Không chỉ tiếng Nhật, code và kỹ năng mềm nó cũng vậy, cứ đi tiếp thì dù nhanh chậm thế nào cũng sẽ tới đích.

Tập Trung

Tập trung có thể hay bị nhầm với kiên trì. Thực sự không phải. Có những người rất kiên trì học, học JP không ổn học tiếng Anh, học không xong chuyển qua tiếng Hàn, và cứ kiên trì trong việc “HỌC NGOẠI NGỮ” nhưng quên mất rằng do thiếu sự tập trung nên chả đi tới đâu, có thể đi du lịch vòng quanh thế giới, tới đâu chào hỏi bằng thứ ngôn ngữ đó có vẻ rất siêu phàm nhưng chừng đó không đủ để làm việc – họp hành – đàm phán.

Huyền thoại võ thuật Lý Tiểu Long có một câu nói : “Tôi không sợ người luyện tập 10.000 cú đá chỉ một lần mà chỉ sợ người thực hành một cú đá 10.000 lần”. Và chính câu nói này đã giúp mình rất nhiều qua năm tháng.

Trong việc học code cũng thế, kiên trì học năm này qua năm khác, C# học 3 tháng chuyển qua Java, rồi vài tháng sau nhảy qua Python, chưa hết, khi thấy người ta thi nhau học trí tuệ nhân tạo, blockchain thì lại bỏ ngang cái đang học tiếp tục lao vào cái mới. Cứ thế đến cuối cùng cái gì cũng biết sơ sơ nhưng chả thạo, mà không thạo rất khó dùng. Có những kỹ sư chỉ biết mỗi 1 ngôn ngữ họ vẫn sống rất tốt, lương rất cao vì họ cực kỳ tập trung trau dồi cái mình mạnh nhất. Cắt nghĩa 1 chút để các bạn đỡ hiểu nhầm, vì có lần mình đã khuyên nên học để biết thật nhiều ngôn ngữ, nhưng nên nhớ phải có một thứ nổi bật nhất, giỏi nhất chứ không phải biết cho rộng nhưng không cái nào dùng được.

Lúc đi phỏng vấn thường các bài thi code người ta sẽ cho mình chọn một ngôn ngữ tự tin nhất để giải đề, dù ngôn ngữ nào cũng sẽ cho ra cùng 1 kết quả. Đó chính là lúc dùng sự tinh nhuệ. Còn trong trường hợp một dự án sử dụng nhiều loại ngôn ngữ khác nhau ví dụ : Front-End dùng html+css+Javascript+Angular+Node, Back-End dùng Java Spring Boot, Bath dùng C++(để chạy cho nhẹ trong đồng bộ dữ liệu). Đây chính là lúc cần sự hiểu rộng.

Tóm lại phải tập trung để mang lại cho mình một thứ giỏi nhất nhưng đừng quên tìm hiểu rộng ra để hình dung được mọi thứ xung quanh.

  5 Ngộ nhận về nghề BrSE
  Những kỹ năng cần có của 1 BrSE

Thích Nghi

Xưa lúc còn làm công ty cũ, ktx có phòng dành cho 2 người. Vừa tiết kiệm tiền nhà cho công ty, vừa có bạn cũng vui. Mình có ở cùng ông anh hơn 3 tuổi. Cũng là kỹ sư, onsite như nhau nhưng thấy anh khó ăn khó uống, chỉ ăn được đồ Việt không ăn đồ Nhật nên 6 tháng công tác toàn nấu cho ăn, sau đó mình chuyển chỗ, anh ăn mỳ tôm 2 tháng chịu không nổi nên xin về nước. Còn mình thì cuộc sống nhẹ nhàng, thích ăn gì ăn thích ngủ đâu ngủ, có bữa còn ngủ ở ga tàu đợi 5h sáng tàu chạy mới về nhà ngủ tiếp :))) đàn hát bóng đá bóng chuyền bơi lội cái gì cũng tham gia hoà mình vào. Ngày đi làm, tối đứng bếp nấu ăn ngon không thua gì các mẹ các chị. Việc nhiều làm nhiều, việc ít thì dành thời gian đọc cái này cái kia, rồi luyện kỹ năng viết lách. Khách dễ thì mình vui, gặp khách khó chửi bới om sòm thì mình coi như gặp “thầy”, họ dạy mình để sau này gặp khách bớt khó hơn sẽ coi là dễ. Đi nhậu, khách uống bia mình bia, họ rượu mình rượu, ăn cá sống cũng ăn, ngay cả thịt gà sống người ta làm susi cũng ăn thử cho biết. Không có gì phải ngại.

Trong suốt 10 năm làm nghề đã từng rất nhiều lần chuyển dự án, chuyển team, bộ phận và kể cả chuyển việc. Mình khá quen với việc thoát ra khỏi vùng an toàn và tập thích nghi với cái mới. Phải tập vì ban đầu cái gì cũng khó khăn, và đều vượt qua cả. Như con tắc kè, nhảy vào chỗ nào lập tức đổi màu theo môi trường xung quanh để tránh bị ăn thịt. Bản thân mình cũng thế, tự biết chả giỏi giang gì nên mỗi lần tới đâu luôn cố tránh sự khác biệt nhất có thể, và không bao giờ làm mình nổi bật để người ta ghét. Nhập gia tuỳ tục, vào dự án thấy team OT thấy bà nội thì cũng xắn tay làm tới khuya cùng mọi người, cuối tuần người ta tụ tập hát hò thì cũng sắp xếp đi theo, vài buổi cũng được. Chứ đừng có kiểu chảnh chó bảo trước giờ làm 4-5 công ty, hàng chục dự án chưa phải OT lần nào, tụi bây làm gì làm, cứ kẻng đánh 6h chiều xách mông về. Vậy chỉ có làm việc với dế, trừ khi anh có thực tài làm được những việc không ai làm được thì mới được hưởng những đặc ân không ai có. Nên nhớ kỹ điều này.

Kết

Tính thích nghi nó cũng liên quan tới kiên trì, vì việc tập làm quen cái mới bao giờ cũng cần thời gian. Còn kiên trì thì bắt buộc phải tập trung thì mới có hiệu quả. 3 tố chất này bổ trợ cho nhau giúp bạn đi tới đích. Không phải ai ban đầu cũng hội tụ đủ, nhưng nếu có quyết tâm cùng với thời gian trau dồi sẽ tự khắc tiến bộ. Và chắc chắn đường xa mấy cũng tới nơi, quan trọng có chịu đi hay không, vấp ngã có tự đứng dậy hay dọc đường thấy tiên nữ tắm suối quên luôn mục đích ban đầu ?

Lâu rồi mới viết lại, thấy vẫn giữ phong độ như trước. Tay nghề không hề mai một, và đặc biệt là độ tự tin không hề suy giảm, biết dở nhưng vẫn tự khen hay kkk.

Bài viết gốc được đăng tải tại kysubrse.com

Có thể bạn quan tâm:

Xem thêm Việc làm Developer hấp dẫn trên TopDev

Firebase security – 3 điểm không thể bỏ qua

Firebase security – 3 điểm không thể bỏ qua

Bài viết được sự cho phép của tác giả Kiên Nguyễn

1. Firebase security là gì?

Firebase Security là phần đứng giữa data và user trong ứng dụng. Không phải ngẫu nhiên mà Google thêm nội dung này vào Firebase. Trước đây, muốn thực hiện bảo mật hoặc phân quyền cho database cần nhiều thời gian để thực hiện.

Đối với các ứng dụng lớn và phân quyền phức tạp, người ta còn viết ra cả một service riêng để check permission. Đã thiết kế vậy đòi hỏi phải thiết kế DB, nếu chưa biết có thể tham khảo các bài viết về antipattern khi thiết kế DB tại đây.

  Firebase là gì? Tìm hiểu tính năng và ưu nhược điểm của Firebase
  Firebase & 5 nhầm lẫn tai hại thường gặp

Nhưng với các ứng dụng nhỏ, không quá phức tạp thì sao?. Đấy, lúc đấy Firebase Security trở nên đơn giản, gọn nhẹ.

Nhờ vào tính flexible (linh động) và independent (độc lập), firebase database nói chung và Firebase Security càng ngày càng hot. Cùng Kieblog tìm hiểu ngay 3 điểm cần chú ý nha.

firebase security test modeTrường hợp mà muốn test function hay feature thì có ngay mode test, mở toang cho anh em vào thử nha. Nghe hấp dẫn vcl, cùng tìm hiểu thôi

1.1 Hoạt động như thế nào?

Theo như lý thuyết từ trang chủ thì:

Firebase Security Rules work by matching a pattern against database paths, and then applying custom conditions to allow access to data at those paths.

Firebase Security Rules hoạt động bằng cách khớp các mẫu (matching a pattern) trên các đường dẫn database và áp dụng các điều kiện cho phép truy cập data hay không trên các đường dẫn này

À, vậy là tất cả các đường dẫn trên database đều có thể thiết lập các rules này. Rules thường được việt với if else, tuy nhiên cũng có thể viết các điều kiện phức tạp hơn (tùy thuộc yêu cầu của ứng dụng đang dùng).

service <<name>> {
// Match the resource path.
match <<path>> {
// Allow the request if the following conditions are true.
// Cho phép làm gì đó (read, write,...) nếu khớp điều kiện gì đó.
allow <<methods>> : if <<condition>>
}
}

2. Ba chức năng chính

2.1 Flexibility – linh hoạt

Linh hoạt ở đây không phải cho người khác dễ dàng thao tác mà là cho quản trị viên. Trường hợp muốn thay đổi rule gì đó trong security thì dễ dàng thêm thắt hay sửa đổi.

Write custom rules that make sense for your app’s structure and behavior. Rules use languages that allow you to leverage your own data to authorize access.

Viết các rules tùy biến phù hợp với cấu trúc và hành vi của ứng dụng. Rules còn được sử dụng từ các dữ liệu của chính bạn để quản lý việc truy cập.

firebase-security-operatorNói về độ flexible khi viết thì với đống Operator này là dư sức rồi nha

Tất nhiên Firebase Security viết ra không phải cho một loại ứng dụng. Chính vì vậy người dùng sẽ muốn thay đổi rule cho phù hợp với đặc thù ứng dụng của mình.

Cùng xem xét một số ví dụ sau đây nha:

// Trường hợp này lock toàn bộ document trên firestore
match /{document=**} {
allow read, write: if false;
}
// Chỉ các user đã authen mới được read, write
match /products/{productId} {
allow read: if request.auth != null;
}

2.2 Granularity – Chi tiết

Ở một số ứng dụng, việc phân chia user actions có thể chi tiết tới từng thao tác. User này có quyền được tạo data, trong khi user kia chỉ được xem.

Nhân thấy yêu cầu phân quyền chi tiết, Firebase Security chia read và write thành các thao tác chi tiết nhỏ.

In some situations, it’s useful to break down read and write into more granular operations. For example, your app may want to enforce different conditions on document creation than on document deletion. Or you may want to allow single document reads but deny large queries.

Trong một số tình huống, sẽ rất hữu ích nếu chia nhỏ read và write thành các thao tác nhỏ. Một số có thể chập nhận duy nhất một yêu cầu dọc dữ liêu, nhưng từ chối các truy vấn lớn hơn

service cloud.firestore {
match /databases/{database}/documents {
// Read chia thành get và list
match /cities/{city} {
// Applies to single document read requests
allow get: if <condition>;

// Applies to queries and collection read requests
allow list: if <condition>;
}

// Write thì chi tiết hơn, tạo, cập nhật và xóa
match /cities/{city} {
// Applies to writes to nonexistent documents
allow create: if <condition>;

// Applies to writes to existing documents
allow update: if <condition>;

// Applies to delete operations
allow delete: if <condition>;
}
}
}

Thay vì viết một service riêng rẽ kiểm tra các điều kiện để thực hiện phân quyền. Thằng Firebase Security chia nhỏ các thao tác đó ra. Phần thao tác truy cập database được phân quyền chi tiết theo các điều kiện if, dễ để kiểm soát

Việc phân quyền trong một file duy nhật với các condition còn dễ dàng cho việc maintainance sau này.

2.3 Independent security – Tính độc lập

Cái hay của Firebase Security là nó tách bạch phần phân quyền, bảo mật data riêng rẽ ra ngoài.

firebase-securityMỗi database đều có một tab rules, cần gì cứ bay vào đó mà sửa thôi

Có thể một số ứng dụng phức tạp hoặc có các yêu cầu phân quyền đặc biệt không sử dụng. Nhưng đối với các ứng dụng đơn giản không có yêu cầu quá phức tạp về phân quyền có thể custom nhanh chóng phần này.

Because Rules are defined outside of your app (in the Firebase console or Firebase CLI), clients aren’t responsible for enforcing securitybugs don’t compromise data, and your data is always protected.

Bởi vì Rules được định nghĩa bên ngoài ứng dụng (trong Firebase console hoặc Firebase CLI), client không chịu trách nhiệm về vấn đề bảo mật, dữ liệu luôn được bảo vệ.

Tính độc lập của Firebase Security luôn được đánh giá cao. Dễ dàng custom và maintainance, đây là điểm cộng lớn cho Firebase. Một số đối thủ khác của Firebase đang cố gắng thực hiện tính năng tương tự.

Đây, introduction về Firebase security rules, vô cùng hữu ích

3. Tham khảo

Bài viết gốc được đăng tải tại kieblog.vn

Có thể bạn quan tâm:

Xem thêm Việc làm Developer hấp dẫn trên TopDev

Công nghệ JSF trong JavaEE

Công nghệ JSF trong JavaEE

Bài viết được sự cho phép của smartjob.vn

Giới thiệu đến bạn công nghệ JSF – một hợp phần trong hệ sinh thái JavaEE [1]. Phiên bản mới nhất hiện tại của JavaEE là phiên bản 7, phiên bản mới nhất của JSF (JavaServer Faces) là 2.2, được phát triển theo JSR344 [2]. JSF 1.0 được phát hành lần đầu vào ngày 11/03/2004, dùng để xây dựng các hợp phần (component) để xây dựng giao diện đồ họa người dùng (GUI) cho ứng dụng Java web. Các công nghệ WinForm, ZK Framework, GWT, Vaadin, JavaFX đều sử dụng cơ chế hợp phần (component) lắp ghép lại với nhau, JSF cũng vậy. Khi sử dụng JSF, bạn có thể khai thác tính năng AJAX phong phú, đơn giản, dễ dùng.

  10 tips để trở thành Java Developer xịn hơn
  11 mẹo đơn giản để tăng hiệu suất Java cấp tốc

JavaEE là bộ đặc tả do Oracle cùng cộng đồng cùng xây dựng, JSF là công nghệ nằm trong bộ JavaEE do đó JSF là một công nghệ tiêu chuẩn và được hỗ trợ chính thức. JSF chạy được trên các JavaEE-compliance application server ( máy chủ tuân thủ bộ tiêu chuẩn JavaEE, như Oracle WebLogic, IBM WebSphere, GlassFish, v.v..).

Có nhiều JSF framework cho bạn lựa chọn

Hiện tại công nghệ JSF có rất nhiều framework, đó là:

  • Mojarra JavaServer Faces (cung cấp bởi Oracle [3])
  • PrimeFaces ( cung cấp bởi PrimeTek – một công ty phần mềm Brazil [4])
  • RichFaces (cung cấp bởi JBOSS – Redhat [5])
  • MyFaces Trinidad (cung cấp bởi Apache Software Foundation [6])
  • OmniFaces (được phát triển chính bởi Arijan Tijims, Bauke Scholtz, Jan Beernink [7])
  • ICEfaces (phát triển bởi ICEsoft [8])

Có vài framework nữa tuy nhiên không phổ biến nên chúng tôi không liệt kê thêm. Các JSF framework kể trên đều có phiên bản miễn phí. Thực tế sử dụng trên thế giới, cũng như tại Việt Nam, trong các JSF framework kể trên, thì phổ biến hơn cả là PrimeFaces, sau đó đến RichFaces.

Ứng tuyển các vị trí việc làm Java lương cao trên TopDev

JSF là ca nhạc, PrimeFaces là ca sỹ

Tác giả bài viết cố gắng trả lời cho bạn đọc một câu hỏi phổ biến khiến lập trình viên bối rối. Sự khác nhau giữa JSF và RichFaces là gì? Sự khác nhau giữa ICEfaces và JSF là gì?

Câu nói trên là cách dễ nhất để giải thích cho bạn về sự khác nhau giữa JSF và hàng loạt framework JSF đang tồn tại. JSF là công nghệ, còn PrimeFaces là sản phẩm cụ thể hóa công nghệ JSF. Bạn hãy liên tưởng, có công nghệ sản xuất động cơ đốt trong 4 thì, và Honda Air Blade là một sản phẩm cụ thể hóa công nghệ đó. Nếu JSF là ca nhạc, thì RichFaces, ICEfaces cũng là ca sỹ, v.v..

JSF khá dễ dùng, linh hoạt. Giả sử SmartJob sử dụng PrimeFaces để làm biểu mẫu nhập thông tin về công việc (job), các trường và loại component tương ứng sẽ là:

Các nhãn: label
Tên công việc: textbox
Công ty tuyển dụng: drop-down list (combo box)
Nội dung tuyển dụng: textbox
Ngày bắt đầu đăng tuyển: calendar
Ngày kết thúc đăng tuyển: calendar
Nút bấm gửi thông tin lên server: Button (type = submit)

Công nghệ JSF có nhiều ưu điểm: thời gian phát triển ứng dụng nhanh mà vẫn hỗ trợ AJAX. JSF có nhược điểm, JSF dựa trên cơ chế stateful component (tương tự cơ chế của ASP.NET WebForm) nên có nhược điểm là dung lượng request, response gửi qua lại giữa client-server lớn, dẫn đến thời gian giao tiếp giữa 2 phía sẽ lâu. Bản chất của HTTP là stateless , trong khi JSF cố giữ trạng thái các component trong ứng dụng bằng cơ chế stateful của component.

Ghi chú
[1] http://www.oracle.com/technetwork/java/javaee/overview/index.html
[2] JSR (Java Specification Request): Yêu cầu đặc tả (công nghệ cụ thể nào đó trong) Java
[3] https://javaserverfaces.java.net/
[4] http://www.primetek.com.tr/
[5] http://richfaces.jboss.org/
[6] http://myfaces.apache.org/trinidad/
[7] http://omnifaces.org/
[8] http://www.icesoft.org/java/home.jsf

Đỗ Như Vý – developer tại SmartJob

Bài viết gốc được đăng tải tại smartjob.vn

Có thể bạn quan tâm:

Xem thêm Việc làm Java hấp dẫn trên TopDev

Xu Hướng Gia Công Phần Mềm Cho Nhật Bản

Xu Hướng Gia Công Phần Mềm Cho Nhật Bản

Bài viết được sự cho phép của tác giả Nguyễn Văn Trọng

Dạo gần đây mình hay nhận được nhiều câu hỏi của các bạn sinh viên và một số bạn trẻ đang theo nghề lập trình. Nội dung xoay quanh chuyện cơm áo. Vì thấy nó rất chính đáng nên mình mới viết bài này để giải đáp thắc mắc. Trên thực tế, sau khi ra trường đi làm thì ai cũng vậy, theo đuổi đam mê là một chuyện nhưng ít ra phải đủ ăn. Đi làm vài năm dành dụm chút tiền, chưa tính đến chuyện phụng dưỡng cha mẹ nhưng chí ít cũng phải đủ cưới vợ.

  "Dân làm Product khác hoàn toàn 180 độ với dân làm outsourcing"
  Chuyện bi kịch của công ty code outsourcing

Mình vẫn còn nhớ như in hồi 2012, mới bập bẹ bước vào nghề BrSE thì cũng là thời điểm lên xe bông. Vì chưa tích cóp được gì nhiều nên ngửa tay xin ông anh trai. Cũng may anh mình lúc đó còn đang độc thân, đi xkld Hàn nên có dư được chút. Nghĩ lại thì hơi kỳ kỳ, các bạn đừng có vậy nghen, tự thân tự lực vẫn tốt hơn “gọi trợ giúp” người thân.

Quay lại chủ đề chính, xu hướng gia công phần mềm cho Nhật. Những ai đang hoặc có ý định học tiếng Nhật thì đây là bài viết đáng để các bạn bỏ 5 phút ra nghiền ngẫm.Lịch sử gia công phần mềm

Thời điểm những năm 80-90 Các doanh Nghiệp của Nhật như Hitachi, Fujitsu, Toshiba, NEC, Sony … đều có bộ phận Software riêng. Họ tự xây dựng hệ thống thông tin cho mình. Sau này đến khoảng đầu 2000 trở đi thì xu hướng khoán ngoài (outsource) mới bắt đầu nở rộ. Lý do chính là Nhật vào thời kỳ này đã qua thời hoàng kim, các doanh nghiệp không còn giữ mức lợi nhuận khủng bố để nuôi bộ máy IT riêng. Họ buộc phải giữ lại những nhân sự chủ chốt chỉ để nghiên cứu giải pháp. Phần việc triển khai thì có 2 hướng. Đối với các dự án liên quan tính bảo mật cao, quyết định thành bại của tập đoàn thì thông thường sẽ do nội bộ làm từ A->Z. Hoặc có thể thuê các công ty uy tín trong nước để đảm bảo an toàn, không bị rò rỉ tài liệu hay ý tưởng. Còn những việc khác sẽ khoán ngoài mà chủ yếu là Ấn Độ, Trung Quốc. Điều này nhằm mục đích tiết kiệm chi phí tối đa, đồng thời mang lại hiệu quả cao.

Thời gian đầu thì Ấn độ là mạnh nhất, sau đấy Trung Quốc mới nhảy vào và dần chứng minh được tuyệt chiêu “lấy thịt đè người”. Đến giữa những năm 2000 thì Trung Quốc vượt lên thành đối tác số 1, thời điểm này Việt Nam mới manh nha nhúng tay vào. Bạn sẽ khá bất ngờ khi 1 người Ấn hay Việt lấy N2 trong vòng 1 năm, nhưng với dân Tàu thì chuyện N2 trong 6 tháng không có gì ghê ghớm. Bởi vậy có những dự án yêu cầu vài nghìn người N2-N3 thì các doanh nghiệp ở Đại Liên, Thượng Hải hay Thiên Tân đều có thể chiến được.

Những năm 2010 thì bắt đầu xu hướng dịch chuyển từ TQ sang các nước đông nam á trong đó Việt Nam được ưu tiên. Ngoài Việt ra còn có Myanma, Thái, Phi, Bangladesh. Nhưng các bác JP vẫn like dân ta, 1 phần vì rẻ, 2 là dễ bảo, thứ 3 code trâu. Còn về lý do dịch chuyển này nói ra đây hơi dài dòng, hẹn 1 bài khác vậy.

Thị Trường Gia Công Phần Mềm Nhật Hiện Nay

Vì tính tiết kiệm cộng với hiệu quả nên thì trường outsource vẫn phát triển mạnh trong vài năm gần đây. Các công ty liên tục mọc lên như nấm sau mưa. Có rất nhiều BrSE mà mình biết sau vài năm chinh chiến đã ra lập công ty riêng và khá thành công. Các bạn tham khảo danh sách Outsource Company List bên dưới.

http://www.offshore-kaihatsu.com/company_list/

Mình sẽ cắt nghĩa một chút vì sao lại tiết kiệm, vì sao lại hiệu quả. Về chi phí, nếu nuôi bộ phận IT đông người thì việc trả lương thưởng sẽ ngốn kha khá, trung bình 1 người tầm 50 man (~100 triệu)/tháng, 1000 người thì … nhiều quá tính không nổi. Chưa kể cơ chế tuyển dụng trọn đời ở Nhật, tức là chỉ có tuyển chứ hiếm khi sa thải, nghĩa là nuôi cả đời. Trong khi outsource thì hết dự án là thôi, trả 1 cục tiền lấy sản phẩm cái rẹc … xong.

Còn về tính hiệu quả, người chưa làm với Nhật nhiều mà chỉ “nghe nói” thường hay thần thánh hoá kỹ sư JP. Thực ra họ có các kỹ sư rất giỏi, rất sáng tạo nhưng tỉ lệ chỉ chiếm phần nhỏ. Hầu hết các kỹ sư IT đều ở mức biết việc, cẩn thận tỉ mỉ chứ rất yếu khoản học cái mới. Vậy nên đối với các dự án công nghệ tiên tiến thường họ chỉ nghiên cứu giải pháp, còn việc coding giao cho các doanh nghiệp Việt Nam sẽ hiệu quả hơn. Dân IT của nước mình kỹ thuật được đánh giá khá cao, chỉ thua Ấn vs Trung chút xíu.

Xu Hướng Tương Lai (5 – 10 Năm Nữa)

Có 3 xu hướng chính :

  • Tuyển người giỏi vào làm SE. Hiện có nhiều công ty như Rakuten, Line (chat), Microsoft JP, Recruit jp… hay tuyển kỹ sư chất lượng cao từ các nước khác. Yêu cầu là giỏi tiếng Anh/Nhật và kỹ thuật đỉnh. Profile họ sẽ refer từ nhiều nguồn, trong đó có Github hay các dự án mã nguồn mở. Ngoài ra sẽ test lúc phỏng vấn qua Skype.
  • Tiếp tục khoán ngoài các dự án phần mềm. Những công ty IT liên doanh Việt Nhật hoặc VN mà làm chuyên cho thị trường Nhật sẽ tiếp tục mở rộng. Hiện tại theo ước tính thì số lượng nhân viên mảng JP đang khoảng trên dưới 20 ngàn người và sẽ tiếp tục tăng.
  • Mua bán – sát nhập : Ngoài việc tự mở các chi nhánh tại Việt Nam thì các công ty JP để tránh rủi ro sẽ bỏ tiền ra mua đứt luôn các công ty đang hoạt động. Như vậy sẽ đỡ mất công xây dựng, tránh được các sự cố không đáng có hoặc khó khăn trong việc hoà nhập văn hoá. Vì thông thường sau khi mua/sát nhập, bộ máy cũ hầu như giữ nguyên. Vẫn hoạt động trên nguyên tắc mẹ con nhưng việc điều hành hoạt động vẫn theo tập quán như trước và chỉ thay đổi về mặt chiến lược.

Kết

Các bạn đang theo mảng JP hoặc sắp sửa học tiếng Nhật đọc xong hy vọng là đỡ hoang mang. Thêm 1 yếu tố nữa mà các bạn sẽ yên tâm là dân số Nhật hiện đang già dần. Số liệu dự đoán trong vài chục năm nữa sẽ giảm kinh khủng. Các tập đoàn lớn dày công gây dựng lên nên không dễ gì họ để suy yếu chỉ vì thiếu nhân lực trong nước.

Ngày nay các bác đều có xu hướng toàn cầu hoá. Không chỉ là trong việc kinh doanh mà ngay cả nhân sự cũng vậy. Chuyện cán bộ cấp cao họ có tỉ lệ ngầm 20 – 50 % buộc phải là người nước ngoài. Cái này hơi xa vời so với tầm hiểu biết hạn hẹp của mình. Còn riêng chuyện dev thì hiện tại ngồi quanh mình không ít người Trung Quốc, Myanma, Bangladesh, Ấn độ.

Thêm cái cuối cùng, nghành công nghiệp phim *** của Nhật thì khỏi nói rồi, nên lỡ học JP mà không dùng được cho công việc thì chí ít là xem phim không cần sub 😀 . Mấy đoạn hội thoại đầu phim cũng hay và “nhân bản” lắm.

Bài viết gốc được đăng tải tại kysubrse.com

Có thể bạn quan tâm:

Xem thêm Việc làm Developer hấp dẫn trên TopDev

Các cải tiến của Java cho Switch statement từ Java 12

Các cải tiến của Java cho Switch statement từ Java 12

Bài viết được sự cho phép của tác giả Nguyễn Hữu Khanh

Khi làm việc với switch statement, các bạn sẽ hay gặp những vấn đề sau:

  • Vấn đề thứ nhất là chúng ta quên khai báo break statement: điều này có nghĩa code chúng ta sẽ không thoát khỏi switch statement sau khi match case đầu tiên mà sẽ thực thi tiếp những case tiếp theo, ví dụ như:
  10 lý do cho thấy tại sao bạn nên theo học ngôn ngữ lập trình Java
  10 tips để trở thành Java Developer xịn hơn
package com.huongdanjava;

public class SwitchExample {

public static void main(String[] args) {
int a = 1;
int b = 2;
switch (a + b) {
case 2:
System.out.println("Khanh");
break;
case 3:
System.out.println("Huong Dan Java");
case 4:
System.out.println("Lap Trinh Java");
default:
System.out.println("Hello");
break;
}
}

}

Kết quả:

Các cải tiến của Java cho Switch statement từ Java 12

  • Vấn đề thứ hai là nếu các bạn muốn trong trường hợp giá trị của biến với các giá trị khác nhau a và b thì xử lý cùng một đoạn code. Chúng ta sẽ viết code như sau:
package com.huongdanjava;

public class SwitchExample {

public static void main(String[] args) {
int a = 1;
int b = 2;
switch (a + b) {
case 2:
System.out.println("Khanh");
break;
case 3:
System.out.println("Huong Dan Java");
break;
case 4:
System.out.println("Huong Dan Java");
break;
default:
System.out.println("Hello");
break;
}
}

}

Hoặc:

package com.huongdanjava;

public class SwitchExample {

public static void main(String[] args) {
int a = 1;
int b = 2;
switch (a + b) {
case 2:
System.out.println("Khanh");
break;
case 3:
case 4:
System.out.println("Huong Dan Java");
break;
default:
System.out.println("Hello");
break;
}
}

}

Những cách viết này bất tiện vì duplicate code hoặc chúng ta đôi khi không control được nên đặt break statement ở chỗ nào.

  • Vấn đề thứ ba là nếu các bạn muốn sử dụng switch statement để determine giá trị của một biến nào đó, các bạn phải viết như sau:
package com.huongdanjava;

public class SwitchExample {

public static void main(String[] args) {
String message = "";
int n = 1;
switch (n) {
case 1:
message = "Khanh";
break;
case 2:
message = "Huong Dan Java";
break;
case 3:
message = "Lap Trinh Java";
break;
default:
break;
}
System.err.println(message);
}

}

Để giải quyết những vấn đề trên, từ Java 12, các bạn có thể viết switch statement với những cải tiến như sau:

  • Đối với vấn đề thứ nhất, Java 12 hỗ trợ chúng ta cách viết switch statement giống như lambda expression, ví dụ như:
package com.huongdanjava;

public class SwitchExample {

public static void main(String[] args) {
int a = 1;
int b = 2;
switch (a + b) {
case 2 -> System.out.println("Khanh");
case 3 -> System.out.println("Huong Dan Java");
case 4 -> System.out.println("Lap Trinh Java");
default -> System.out.println("Hello");
}
}

}

Kết quả:

Các cải tiến của Java cho Switch statement từ Java 12

Đối với vấn đề thứ 2 thì các bạn có thể viết lại switch statement như sau:

package com.huongdanjava;

public class SwitchExample {

public static void main(String[] args) {
int a = 1;
int b = 2;
switch (a + b) {
case 2 -> System.out.println("Khanh");
case 3, 4 -> System.out.println("Huong Dan Java");
default -> System.out.println("Hello");
}
}

}

Kết quả:

Các cải tiến của Java cho Switch statement từ Java 12

Còn đối vấn đề thứ ba thì bây giờ Java 12 đã hỗ trợ chúng ta return lại value với switch statement như sau:

package com.huongdanjava;

public class SwitchExample {

public static void main(String[] args) {
int n = 1;
var message = switch (n) {
case 1 -> "Khanh";
case 2 -> "Huong Dan Java";
case 3 -> "Lap Trinh Java";
default -> "Hello";
};
System.out.println(message);
}

}

Kết quả:

Các cải tiến của Java cho Switch statement từ Java 12Nếu các bạn muốn thêm code để xử lý business logic trong mỗi case của switch statement thì các bạn cần upgrade lên Java 13, sau đó thêm code và sử dụng từ khóa yield để return lại giá trị mà mình mong muốn. Ví dụ như sau:

package com.huongdanjava;

public class SwitchExample {

public static void main(String[] args) {
int n = 1;
var message = switch (n) {
case 1 -> "Khanh";
case 2 -> "Huong Dan Java";
case 3 -> "Lap Trinh Java";
default -> "Hello";
};
System.out.println(message);
}

}

Kết quả:

Các cải tiến của Java cho Switch statement từ Java 12

Xem thêm Tuyển lập trình Java lương cao hấp dẫn trên TopDev

Những kinh nghiệm từ quá trình tự phát triển của một Developer (Phần 1)

kinh nghiệm tự học lập trình
Những kinh nghiệm từ quá trình tự phát triển của một Developer (Phần 1)

Tác giả: Victor Cassone

Con đường tự học và trưởng thành của một nhà phát triển luôn khó khăn và đầy bất trắc. Không có một đường thẳng nào từ người mới thành lập trình viên đến nghề nghiệp. Vì điều này, tôi tin rằng tất cả các nhà phát triển tự học đều có những câu chuyện hay ho để chia sẻ đến với mọi người.

1. Tập trung vào quy trình học tập và làm việc

Khi mới bắt đầu học lập trình, tôi chưa bao giờ có ý định lập nghiệp từ nó. Tôi chỉ muốn tạo ra một ứng dụng cụ thể và chân thật mà thôi. Cuộc hành trình của tôi bắt đầu khi tôi là sinh viên năm cuối đại học. Tôi vừa đọc xong tiểu sử của Richard Branson và có lẽ đã đọc quá nhiều TechCrunch. Tôi được bơm đầy năng lượng về mảng kinh doanh.

Một ngày nọ, một ý tưởng về việc xây dựng ứng dụng đã xuất hiện trong đầu tôi. Tôi nhanh chóng vẽ ra viễn cảnh về những thứ lớn lao tiếp theo mà mình có thể làm được. Tôi bị cuốn hút bởi ý tưởng và ngừng chú ý đến các bài giảng. Sự hào hứng của tôi đối với ý tưởng ứng dụng nhanh chóng phát triển đến mức tôi cảm thấy mình cần phải hành động.

Nhưng có một vấn đề lớn, ý tưởng của tôi là một ứng dụng dành cho thiết bị di động và tôi không biết bất kỳ ai có thể xây dựng các ứng dụng dành cho thiết bị di động. Tôi là một sinh viên đại học không có kinh nghiệm lập trình, kinh doanh hoặc thiết kế đang cố gắng học Android để có thể xây dựng một ứng dụng di động phức tạp. Tôi đoán đó là những gì bạn nhận được khi kết hợp một ý tưởng lớn với cỗ máy cường điệu của Thung lũng Silicon.

Tôi đã mua một vài cuốn sách về phát triển Android và giành vô số giờ trong phòng để cố gắng dán các ứng dụng của mình lại với nhau. Tôi không quan tâm ứng dụng hoạt động như thế nào, tôi chỉ muốn có một sản phẩm hoàn chỉnh.

Thời gian trôi qua và ứng dụng biến thành một Frankenstein của mã sao chép và dán. Ứng dụng không có nhiều tính năng và nó hầu như không chạy mà không gặp sự cố. Cho đến khi vô tình tham gia một lớp Khoa học Máy tính, tôi mới nhận ra rằng mình nên tập trung hơn vào việc thực sự cố gắng học phát triển phần mềm.

Không có khả năng lập trình khiến tôi từ bỏ ý tưởng ứng dụng ban đầu. Tôi nhận ra rằng tôi sẽ không làm nên điều lớn lao tiếp theo, ít nhất là hiện tại thì vẫn chưa. Theo thời gian, tôi quyết tâm và lên kế hoạch cho bản thân để có thể học tập nghiêm túc hơn. Tôi bắt đầu thích lập trình và cuối cùng bắt đầu sự nghiệp của một nhà phát triển phần mềm.

Ý tưởng về việc xây dựng ứng dụng lớn của tôi đã làm lãng phí một khoảng thời gian dài. Nhưng may mắn là tôi đã tìm thấy được sự tập trung ở những phút cuối. Khi bạn quá tập trung vào kết quả cuối cùng, bạn sẽ bắt đầu đi những con đường tắt. Các lối tắt có thể dẫn đến một số tiến bộ trong ngắn hạn nhưng về lâu dài, việc thiếu sót các kiến thức chuyên môn cơ bản sẽ xảy ra.

Điều quan trọng cần nhớ là khi bắt đầu học bất cứ điều gì mới đều sẽ yêu cầu bạn cần hoàn chỉnh ngay từ những bước nhỏ nhất. Mỗi bước đều sẽ đòi hỏi bạn phải cẩn thận và chuyên tâm nhiều hơn. Học những điều mới cũng giống như xây một ngôi nhà. Bạn bắt đầu với nền tảng trước khi bắt đầu quá trình xây dựng. Nếu nền móng bị lỗi, tất cả mọi thứ sớm muộn sẽ sụp đổ.

Đôi khi việc xây dựng một nền tảng vững chắc đòi hỏi bạn phải chậm lại. Không có gì phải xấu hổ khi đi chậm. Những người hiểu những điều cơ bản lần đầu tiên sẽ đi trước những người phải quay lại và học lại chúng. Thật sự tập trung vào quá trình làm việc sẽ giúp ích rất nhiều cho quá trình làm việc của bạn.

Xem thêm Tuyển it developer lương cao hấp dẫn trên TopDev

2. Stack Overflow thật tuyệt vời – nhưng khá nguy hiểm

Khi tôi đang xây dựng ứng dụng của mình, Stack Overflow đã trở thành “người bạn” đồng hành xuyên suốt với tôi. Bất cứ khi nào tôi gặp khó khăn, tôi sẽ cố gắng cùng nhau tạo ra một câu hỏi hoàn hảo để hỏi cộng đồng Stack Overflow. Tôi trả lời trung bình một vài câu hỏi mỗi ngày.

Tôi sẽ dành một khoảng thời gian để rà soát trang web và cố gắng tìm một đoạn code chính xác có thể khắc phục các vấn đề mà tôi gặp phải. Khi tôi tìm thấy câu trả lời phù hợp, tôi sẽ sao chép và dán vào codebase của mình và cố gắng làm cho nó hoạt động với code hiện có của tôi. Tôi dành một ít thời gian để cố gắng hiểu code mà tôi đã thêm.

Quá trình này diễn ra trong một thời gian cho đến khi tôi tìm hiểu và nhận ra những sai sót trong phương pháp của mình. Stack Overflow vừa là cơ hội nhưng thực tế cũng là thách thức. Nó rất tốt trong việc giúp bạn giải quyết vấn đề, tuy nhiên, nếu không cẩn thận, bạn có thể nhanh chóng trở nên phụ thuộc vào trang web.

Đôi khi trang web giải quyết vấn đề quá tốt. Nó tạo ra một cảm giác tự tin sai lầm có thể dẫn đến đau đầu hơn trên đường. Stack Overflow chỉ cho bạn cách bắt một thứ gì đó hoạt động nhưng nó thường không cho bạn biết rõ ràng tại sao nó hoạt động. Hiểu được vấn đề như thế nào là quan trọng. Các lỗi cần được sửa và code cần chạy là những gì… Hiểu rõ lý do tại sao điều gì đó hoạt động sẽ giúp bạn áp dụng lại kiến ​​thức trong tương lai.

  10 câu nói cực hay về lập trình
  2 nhận định sai lầm về việc bắt đầu học lập trình

Sao chép và dán code từ Stack Overflow giống như có ai đó cho bạn một con cá. Trong khi đó, việc hiểu rõ lý do tại sao một đoạn code hoạt động giống như dạy chúng câu cá. Không có gì sai khi sao chép và sử dụng code đó. Tất cả chúng ta đều làm được. Nó chỉ là một vấn đề khi nó cản trở sự phát triển của bạn với tư cách là một nhà phát triển.

Điều tôi đã phải học một cách khó khăn là không thể học được bất cứ điều gì nếu các câu trả lời liên tục được đưa ra cho bạn. Không có đường tắt trong quá trình học tập. Khi bạn gặp khó khăn, hãy cố gắng giải quyết vấn đề mã hóa ít nhất một vài lần trước khi truy cập Google. Khi sử dụng những đoạn code có sẵn, hãy dành một chút thời gian để cố gắng hiểu đoạn code trước khi tiếp tục.

học lập trình

3. Tìm hiểu sự trợ giúp từ những người có kinh nghiệm

Điều đầu tiên tôi làm sau khi quyết định học lập trình là mua hai cuốn sách phát triển Android. Khi bắt đầu, tôi theo sát các bài tập trong sách và làm việc thông qua các dự án ví dụ. Tuy nhiên, tôi nhanh chóng thất vọng với tiến độ mà tôi đang đạt được sau cuốn sách và quyết định bắt đầu tìm hiểu cách lập trình cho riêng mình.

Tôi đã giành vô số giờ ngồi một mình trong phòng để cố gắng tìm ra các vấn đề lập trình đơn giản. Tôi bị mắc kẹt với các dòng code mới và không hề cảm thấy mình đang tiến bộ. Tôi bế tắc một cách bất lực và cuộc sống của tôi là một hỗn hợp của sự nghi ngờ, thất vọng và cảm giác lạc lõng.

Để làm cho vấn đề tồi tệ hơn, tôi có một ý tưởng sáng tạo là bắt đầu sử dụng một C library khổng lồ có tên là FFMPEG. Ứng dụng của tôi cần để chỉnh sửa video, vì vậy tôi nghĩ rằng việc sử dụng chức năng mạnh mẽ của thư viện là một ý tưởng hay.

Đó không phải là bước đi thông minh nhất của tôi, vì vào thời điểm đó, tôi hầu như không thể làm cho ứng dụng Android của mình hoạt động. Tôi đã lãng phí rất nhiều thời gian để cố gắng đọc code C và tìm ra cách tôi có thể sử dụng nó trong ứng dụng của mình. Tôi đã đấu tranh để thậm chí nhập thư viện vào dự án Android của mình.

  32 cuốn sách học lập trình bạn nhất định phải đọc

Sau nhiều giờ không đi đến đâu, cuối cùng tôi đã chán nản và từ bỏ thư viện. Cùng khoảng thời gian với sự cố FFMPEG, tôi đã đăng ký một lớp Lập trình hướng đối tượng. Nhiệm vụ đầu tiên là xây dựng một chương trình Blackjack. Tôi đã tự học lập trình được 5 – 6 tháng cho đến thời điểm này và tôi cảm thấy tự tin với kỹ năng của mình. Tôi đã hoàn thành bài tập và cảm thấy hài lòng về công việc của mình. Nhưng, không mất nhiều thời gian để cảm giác đó biến mất. Toàn bộ chương trình của tôi được viết theo một phương pháp rất lớn. Mọi người khác trong lớp đều có thể nhận ra rằng chương trình cần được tách thành các lớp. Nó không thật sự tốt!

May mắn thay, bài tập trên lớp và sự hướng dẫn từ giáo viên đã cho phép tôi bước ra khỏi ứng dụng Android và suy ngẫm về khả năng lập trình của mình. Tôi bắt đầu coi trọng việc học và khắc phục mong muốn của mình là tạo ra một ứng dụng hoàn chỉnh.

Bây giờ tôi nhận ra rằng nếu tôi chỉ nói chuyện với một nhà phát triển có kinh nghiệm trong những ngày đầu đó, họ sẽ thấy những gì tôi đang làm. Tôi có thể đã thiết lập các ưu tiên của mình một cách thẳng thắn, và nói lên một điều gì đó có ý nghĩa với tôi. Họ sẽ giúp tôi sửa chữa con đường của mình khi tôi đi vào những ngõ cụt vô ích (như cố gắng làm việc với FFMPEG).

Có rất nhiều cách tôi có thể làm để tìm kiếm sự trợ giúp. Tôi cố gắng tìm một giáo sư / sinh viên tại trường đại học có kinh nghiệm về Android hoặc tìm đến cộng đồng địa phương để được giúp đỡ. Tôi cũng có thể đã thử tìm một cộng đồng Android trực tuyến.

Các nhà phát triển có kinh nghiệm giống như một chiếc la bàn. Họ sẽ không đưa bạn đến đích nhưng họ sẽ đảm bảo bạn được chỉ dẫn đúng hướng. Sự giúp đỡ của họ có thể sẽ tạo nên sự khác biệt giữa thành công và thất bại. Đảm bảo rằng bạn tìm kiếm hướng dẫn ở bất cứ nơi nào bạn có thể tìm thấy. Nó sẽ giúp bạn tiết kiệm thời gian và hạn chế sự thất vọng trên chặng đường làm việc của mình.

Hi vọng những thông tin trên đây sẽ giúp bạn nắm được các vấn đề cơ bản khi bắt quá trình tự phát triển của bản thân. Đón xem phần tiếp theo cũng TopDev nhé!

Phỏng dịch theo bài viết gốc tại freecodecamp.org

Có thể bạn quan tâm:

Hướng dẫn cách tùy chỉnh GeoGebra trước khi sử dụng

Hướng dẫn cách tùy chỉnh GeoGebra trước khi sử dụng

Bài viết được sự cho phép của blogchiasekienthuc.com

Các tùy chỉnh mặc định của GeoGebra phần lớn thì đã phù hợp với đại đa số người dùng rồi. Tuy nhiên, vẫn có một số trường hợp ngoại lệ, ví dụ như là:

  • Mỗi lần dựng lên một đối tượng mới (điểm, đoạn thẳng, đường thẳng, …) thì tên của đối tượng này sẽ tự động được tạo và hiển thị trên Graphics.
  • Tên điểm có kích thước khá nhỏ.
  • Giao diện sử dụng là tiếng Anh …

Và mỗi lần như vậy, chúng ta đều phải tùy chỉnh lại => điều này tốn không ít thời gian, công sức và còn nhàm chán nữa. Chính vì vậy mà trong bài viết này, mình sẽ hướng dẫn cho các bạn cách thiết lập lại GeoGebra để sử dụng được hiệu quả hơn.

  Middleware là gì? Tìm hiểu về Middleware và tự tạo một middleware tùy chỉnh
  10 câu nói cực hay về lập trình

Các thao tác tùy chỉnh thông thường chỉ tự động lưu lại trong cửa sổ hiện tại. Vậy nên, nếu bạn muốn lưu lại cho các lần sử dụng tiếp theo thì bạn cần phải vào Options => chọn Save Settings để cài đặt.

#1. Không hiển thị tên đối tượng mới

Như đã giới thiệu ở trên, mỗi lần dựng một đối tượng mới (điểm, đoạn thẳng, đường thẳng, …) thì tên của đối tượng này sẽ tự động được tạo và hiển thị trên Graphics.

Thường thì chúng ta rất ít sử dụng những tên này, vì vậy nên tùy chỉnh ẩn ngay ban đầu chứ không phải tạo xong rồi mới ẩn một cách thủ công nữa.

Thực hiện: Chọn Options => chọn Labeling => chọn No New Objects để ẩn tên của các đối tượng.

Hướng dẫn cách tùy chỉnh GeoGebra trước khi sử dụng

#2. Cách chỉnh cỡ chữ lớn hơn trong GeoGebra

Theo mặc định thì tên của điểm có cỡ chữ khá là nhỏ, vì vậy nếu bạn trình chiều bằng Smart Tivi thì nhiều khả năng là học sinh ngồi ở những dãy bàn cuối lớp sẽ không thể nhìn thấy rõ được.

Chúng ta có hai phương pháp để giải quyết được vấn đề này, đó là:

2.1. Phương pháp thứ nhất

Thay đổi Font Size lớn hơn: Chọn Options => chọn Font Size => chọn 28pt

Phương pháp này có ưu điểm là rất nhanh chóng và áp dụng cho được cho tất cả các điểm hiện tại, nhưng nhược điểm của nó là toàn bộ cửa sổ GeoGebra cũng đều bị to lên theo.

Hướng dẫn cách tùy chỉnh GeoGebra trước khi sử dụng

2.2. Phương pháp thứ 2

Gán tên bằng công cụ Text và định dạng lại cỡ chữ, các bước thực hiện như sau:

+ Bước 1: Chọn công cụ Text

Hướng dẫn cách tùy chỉnh GeoGebra trước khi sử dụng

+ Bước 2: Nháy chuột trái vào điểm cần tạo tên => đánh dấu chọn vào LaTeX formula => nhập tên => và chọn OK

Hướng dẫn cách tùy chỉnh GeoGebra trước khi sử dụng

+ Bước 3: Nháy vào tên vừa tạo => chọn Graphics => chọn Large hoặc Very Large hoặc Extra Large

Hướng dẫn cách tùy chỉnh GeoGebra trước khi sử dụng

Phương pháp này tuy phải thực hiện qua nhiều bước, nhưng tên của điểm được tạo ra bằng phương pháp này khá đẹp mắt và có độ tùy biến khá cao.

Có một lưu ý dành cho các bạn khi sử dụng phương pháp này là trong trường hợp: tên ban đầu và tên tạo bằng công cụ Text là khác nhau – thì tên mà GeoGebra đọc sẽ được hiểu là tên ban đầu.

#3. Thiết lập ngôn ngữ tiếng Việt cho GeoGebra

GeoGebra không chỉ là một phần mềm đa nền tảng, mà nó còn là một phần mềm đa ngôn ngữ nữa. Cụ thể là phần mềm này hỗ trợ rất nhiều ngôn ngữ khác nhau trên thế giới, trong đó có tiếng Việt 🙂

Hướng dẫn cách tùy chỉnh GeoGebra trước khi sử dụng

Cá nhân mình thường không sử dụng tiếng Việt đối với các phần mềm nước ngoài. Bởi vì có khá nhiều từ khi được dịch sang tiếng Việt thì nghĩa của nó không còn được sát với nghĩa ban đầu.

Thậm chí trong một số trường hợp còn không thể dịch được mà phải mô tả. Cái thứ 2 nữa là khi gặp lỗi thì việc tìm kiếm cách sửa lỗi cũng khó khăn hơn, vì đa số các bài hướng dẫn đều là tiếng Anh.

Vì vậy cá nhân mình không khuyến khích các bạn sử dụng tiếng Việt với phần mềm GeoGebra. Mình chỉ sử dụng tiếng Việt khi phần mềm là thuần Việt mà thôi..

Trường hợp bạn muốn sử dụng giao diện tiếng Việt cho phần mềm GeoGebra thì bạn thực hiện theo các tao tác sau:

Chọn Options => chọn Language => chọn R – Z => chọn Tiếng Việt như hình bên dưới là được.

Hướng dẫn cách tùy chỉnh GeoGebra trước khi sử dụng

#4. Tùy chỉnh hộp thoại Preferences trong GeoGebra

Hộp thoại Preferences cho phép chúng ta tùy chỉnh các tùy chọn mà chúng ta yêu thích. Chẳng hạn bạn có thể tùy chỉnh màu sắc và kích thước của điểm, hoặc đoạn thẳng, hoặc…

Từ đây về sau mỗi khi tạo điểm, điểm sẽ tự động có màu sắc và kích thức như chúng ta đã tùy chỉnh trước đó.

Để mở hộp thoại Preferences bạn có thể vào Options => chọn Advanced …

cach-tuy-chinh-geogebra-truoc-khi-su-dung (8)

4.1. Màu sắc và kích thước của điểm

Trong hộp thoại Advanced => bạn hãy chọn Defaultscach-tuy-chinh-geogebra-truoc-khi-su-dung (9)

cach-tuy-chinh-geogebra-truoc-khi-su-dung (10)

GeoGebra hiện tại đang cung cấp cho chúng ta 5 loại điểm:

  • Free điểm tự do.
  • Dependent điểm phụ thuộc.
  • On Path điểm nằm trên đường.
  • In Region điểm nằm trong một miền nào đó (miền đa giác, hình tròn, …).
  • Complex Number điểm biểu diễn một số phức.

Chẳng hạn ở đây chúng ta cần tùy chỉnh lại màu sắc và kích thước của điểm tự do thì bạn hãy chọn Free => chọn

  • Color để tùy chỉnh màu sắc.
  • Style (Point Sixe) để tùy chỉnh kích thước của điềm tự do..

cach-tuy-chinh-geogebra-truoc-khi-su-dung (11)

4.2. Màu sắc và kích thước của đoạn thẳng

Trong hộp thoại Advanced => bạn hãy chọn Defaults

  • Color để tùy chỉnh màu sắc.
  • Style (Line Thickness) để tùy chỉnh độ dày của đoạn thẳng.

cach-tuy-chinh-geogebra-truoc-khi-su-dung (12)

Các đối tượng còn lại như DeLine, Ray, Polyline, Vector, Conic, Sector, … các bạn cũng tùy chỉnh tương tự nếu muốn nhé. Tùy thuộc vào đối tượng được chọn mà các tùy chọn trong hộp thoại Preferences sẽ có khác nhau đôi chút.

#5. Lời kết

Okay, trên đây là những bước tùy chỉnh lại GeoGebra trước khi sử dụng – giúp bạn làm việc hiệu quả hơn với phần mềm này.

Những tùy chỉnh bên trên là tương đối phù hợp với đại đa số người dùng Việt Nam chúng ta. Tất nhiên là bạn có thể tùy chỉnh khác theo sở thích cá nhân của bạn, miễn sao là nó phù hợp với bạn nhất là được.

Ngoài các tùy chỉnh cơ bản bên trên, GeoGebra còn cung cấp cho chúng ta rất nhiều tùy chỉnh khác, chẳng hạn như: đơn vị của góc, hiển thị/ không hiển thị (thanh nhập lệnh, thanh công cụ, thanh phụ, lưới, trục trung, trục hoành, …), kiểu lưới, màu lưới, …

Các bạn có thể tự tìm hiểu và khám phá thêm nhé. Xin chào tạm biệt và hẹn gặp lại các bạn trong những bài viết tiếp theo !

CTV: Nhựt Nguyễn – Bài viết gốc được đăng tải tại blogchiasekienthuc.com

Có thể bạn quan tâm:

Xem thêm Việc làm Developer hấp dẫn trên TopDev

Lập trình IOS: Tạo Leak memory trong closure (phần 1)

Bài viết được sự cho phép của tác giả Lê Xuân Quỳnh

Hello guys! Chúng ta code ios mỗi ngày, và chắc hẳn nhiều thanh niên giống mình ít khi check memory của app khi sử dụng để tìm hiểu những vấn đề bất thường của app. Trong ví dụ hôm nay chúng ta sẽ tự tay mình tạo ra leak để hiểu bản chất nó là gì, thay vì nghe các ông chém gió suông đọc xong rồi không hiểu gì cả.

  Mọi thứ bạn nên biết về Memory Leaks trong IOS (phần 1)
  Sự khác nhau giữa close() và quit() trong Selenium

Hình ảnh demo:

Lập trình IOS: Tạo Leak memory trong closure (phần 1)
Màn hình thứ nhất hiển thị logo app, mình xin ít quảng cáo cho web
Lập trình IOS: Tạo Leak memory trong closure (phần 1)
Hình ảnh màn hình tạo ra leak bằng closure

Đầu tiên bạn tải source code ở đây:

https://github.com/codetoanbug/LeakMemorySamples.git

Code ở branch bai1 nên bạn cần chuyển source về nhánh này nha. Cách chuyển xem phần mình pink sau:

Tuy nhiên tôi khuyên bạn chơi với terminal của MacBook cho nó pro nhé. Vì nếu bạn tải chay về bằng trình duyệt thì không thấy source code ở đâu đâu :v
Chơi với terminal đơn giản như sau:
Bạn gõ lệnh cd vào source code hôm trước bạn tải về:
cd LeakMemorySample
2. Tiếp theo là gõ fetch để lấy source code mới nhất của tôi về:
git fetch
3. Tiếp theo là bạn show toàn bộ branch trên repo của tôi bằng lệnh:
git branch -a
Ở đây bạn sẽ thấy các branch sau:
bai1 * bai2 master
Ví dụ bài này, tôi để hết source vào branch tên là bai2. Bạn chuyển sang source code bài 2 như sau:
git checkout bai1
Sau khi branch bai1 được bôi đậm chuyển màu nghĩa là bạn đã thành công rồi đó. Còn nếu nó báo không thấy thì chứng tỏ bạn làm sai, hãy làm lại!

Tôi sẽ giải thích từng phần 1.

  1. Màn hình thứ nhất: ViewController.

Tôi lười nên tôi lấy mặc định file do Xcode tạo luôn. Bạn vào file Main.storyboard để xem cách tôi layout kéo thả các thứ 😂

Màn hình này chả có gì cả, ngoài cái ảnh logo web, 1 cái nút để mở sang màn thứ 2, nơi chứa leak memory.

2. Màn hình thứ 2: SecondViewController.

Màn này code như sau:

Lập trình IOS: Tạo Leak memory trong closure (phần 1)

Tôi giải thích đoạn code trên:

Dòng 19 – tôi gọi hàm bindViewModel để kết nối viewmodel với view. Tôi thích làm MVVM cho code clean. Nên nếu bạn không hiểu về MVVM là cái gì, thì vui lòng tìm tag MVVM ở web này để hiểu thêm.

Từ dòng 23:

Tôi tạo viewModel ở đây. Ở dòng 27, tôi có 1 hàm closure. Hàm này làm cái gì? Nó chứa đoạn code 28(hoặc 29) set lại màu của background. Như ảnh thì tôi đang comment cái dòng 27 đằng sau, và dòng 28. Nếu bạn không biết gì về closure, thì hiểu nôm na nó là cái hàm chạy vào 1 thời điểm nào đó từ view model phát ra. Nó không chạy luôn ngay lúc khai báo đâu nha. Giống như bạn tạo 1 cái lịch biểu, rằng nếu như người yêu mà hôn bạn thì bạn làm cái gì đó 😘 Hôn ở đây là hàm needClosure, còn làm gì đó là dòng 28(hoặc 29).

Dòng 33, tôi tạo 1 hàm fake request API, có thời gian delay, và cuối cùng giả sử khi có kết quả thì nó sẽ call vào closure tôi nói ở trên.

Rồi vậy viewModel tôi có gì nào? Theo dõi code sau:

Lập trình IOS: Tạo Leak memory trong closure (phần 1)

Ở dòng 11, tôi tạo 1 biến closure để bắn sự kiện ra khi API có kết quả trả về.

Dòng 12 tôi tạo 1 timer fake timeout của API.

Dòng 13 tôi tạo 1 biến lưu mảng số nguyên data.

Dòng 18 tới 21, tôi cố gắng tạo ra nhiều dữ liệu chiếm memory để cho bạn thấy sẽ tai hại thế nào khi ta không giải phóng nó. Tôi đẩy nó vào background thread để không block main thread khi bạn cố gắng mở SecondViewController.

Dòng 25 tới 30, tôi tạo fake 1 hàm call API. Hàm này sau 1 giây sẽ trả về kết quả. Khi có kết quả, nó sẽ gọi vào biến closure để bắn ra cho thằng SecondViewController xử lý. SecondViewController sẽ thực hiện việc đổi màu.

OK vậy là bạn đã hiểu luồng của app rồi. Vậy việc tiếp theo là theo dõi nó đã leak memory như nào.

Đầu tiên bạn chạy app và xem memory sử dụng như hình:

Lập trình IOS: Tạo Leak memory trong closure (phần 1)Bấm như hình để xem memory khi chạy app

Bạn bấm vào nút Open Second screen, sau đó đợi 1 lát cho SecondViewController tạo data rồi bấm back ra màn 1. Cứ làm như vậy dăm bảy lần, bạn sẽ thấy 1 điều là bộ nhớ chỉ có tăng mà không có giảm.

Chúc mừng bạn đã tạo leak memory thành công.

Thế tại sao nó lại leak memory?

Quay lại với đoạn code closure dưới đây:

Lập trình IOS: Tạo Leak memory trong closure (phần 1)
Đoạn code gây leak memory

Ở đây tôi sử dụng liên kết mạnh từ viewModel sang view controller, bằng việc lấy self.view. Nghĩa là thằng viewModel này chỉ thực sự bị hủy khi thằng SecondViewController bị hủy. Tuy nhiên, thằng ViewModel này là con của thằng SecondViewController. Mà thằng SecondViewController muốn hủy thì nghĩa là con nó phải hủy trước. Ồ, vậy là bố bảo là con hủy thì bố mới hủy, con thì nói bố ơi bố hủy đi thì con mới hủy nè. Cuối cùng 2 thằng chả ai chịu ai, bộ nhớ vẫn cứ ở đấy, chả bao giờ giải phóng được.

Rất simple đúng không?

Vậy cách khắc phục thế nào? Chúng ta tiến hành sửa lại đoạn code trên như sau:

Lập trình IOS: Tạo Leak memory trong closure (phần 1)
Tiến hành capture cho closure

Tôi tiến hành capture cho hàm closure trên. Ồ thế capture là gì? Đơn giản là thằng con nói bố ơi bố khi con có closure trả về, nếu như bố vẫn sống ở đó thì con sẽ set màu cho bố nhé! Mà bố ngỏm rồi(đã bị giải phóng khi bấm back) thì thôi con không gán nữa. Tôi tạo capture [weak self] để tạo liên kết yếu cho điều đó. Khi đó đoạn code ở closure sẽ là self?. thay vì self. Thật là đơn giản đúng không nào 😍

Khi đó hàm sau sẽ in ra dòng chữ “free memory SecondViewController”

deinit {
        NSLog("free memory SecondViewController")
    }

Từ nay về sau mỗi khi bạn tạo 1 view controller mới, bạn hãy thêm hàm deinit vào và đặt debug vào đó, xem nó đã được giải phóng chưa? Nếu như bạn đã hủy view controller rồi thì không có leak memory ở nó. Còn mà không in ra thì chắc chắn leak memory rồi bạn nhé.

Vậy là tôi đã trình bày xong trường hợp leak memory ở closure. Qua ví dụ hi vọng bạn sẽ cẩn thận hơn trong việc code của mình. App chạy được nhưng phải chạy mượt.

Hope you enjoy it!

Bài viết gốc được đăng tải tại codetoanbug.com

Có thể bạn quan tâm:

Xem thêm tuyển dụng ios hấp dẫn trên TopDev

Chia sẻ thư viện javascript mở rộng khi kết nối tới Hub sử dụng SignalR

Chia sẻ thư viện javascript mở rộng khi kết nối tới Hub sử dụng SignalR

Bài viết được sự cho phép của tác giả Phạm Công Sơn

Tôi chia sẻ kinh nghiệm và thư viện mở rộng mà tôi viết để kết nối tới Hub sử dụng SignalR. Thư viện do tôi mở rộng thêm với mục đích

  1. 1. Có thể kết nối được tới nhiều Hub
  2. 2. Duy trì được kết nối ổn định: Khi disconnected thì sẽ tự động kết nối trở lại
  3. 3. Có thể đăng ký nhiều sự kiện để nhận data được push từ server gửi về
  4. 4. Khi gửi request lên server Hub thì chỉ gửi được khi đang ở trạng thái kết nối tốt.
  10 câu hỏi javascript để nâng cao trình độ
  10 tip tối ưu code trên JavaScript mà web developer nào cũng nên biết

Để tải thư viện mở rộng do tôi viết các bạn có thể tải tại đây.

function Hub(hubUrl, hubName) {     this.onOk = function (func) { if (state == 2) func(); };     this.onBeforeStart = function () { };     this.start = function() {/* Code coe */ }; }

Phần mở rộng tôi viết gồm hubUrlhubName là trỏ đến địa chỉ Hub cần kết nối tới. this.onOk là phương thức đảm bảo đang ở trạng thái kết nối mới thực hiện func (một hành động nào đó). Với class Hub tôi đã xử lý hết các sự kiện khi mất kết nối, đang kết nối và kết nối

// Nếu bị mất kết nối thì 2s sau sẽ kết nối lại
$this.hub.connection.disconnected(function ()
{
console.log("disconnected");
state = 1;
var t = setInterval(function () { $this.doHubStart(true); clearInterval(t); }, $this.timeout);
});
$this.hub.connection.reconnecting(function ()
{
state = 1;
console.log("reconnecting");
});

// Đã được kết nối lại
$this.hub.connection.reconnected(function ()
{
console.log("reconnected");
var t = setInterval(function () { $this.doHubStart(true); clearInterval(t); }, $this.timeout);
});

Nếu bị mất kết nối, thì sau khoảng this.timeout (mặc định 2000ms) sẽ thực hiện kết nối lại.

Hub.ActionRegistry = function ()
{
this.registry = function (func) { /* Code code */ }
/* Code Code */
}

Với Hub.ActionRegistry được dùng để đăng ký các hành động sau khi nhận dữ liệu được push từ server gửi về. Tại sao tôi lại viết class này, vì tôi hướng tới có thể nhiều nơi, nhiều module mà cũng muốn nhận dữ liệu push về mà không phải lúc nào cũng phải sửa lại phương thức nhận dữ liệu tại client của Hub. Điều này cũng đồng nghĩa với việc lúc nào module nào dùng thì có thể đăng ký nhận dữ liệu.

Tham khảo tuyển dụng javascript lương cao trên TopDev

Sau đây là code mẫu tôi viết cho chương trình chat đơn giản về sử dụng thư viện mở rộng trên

Tán gẫu nào
Trước tiên bạn cũng cài đặt SignalR và gắn thẻ script ở client
<script src='/signalr/hubs'></script> <!-- file js mà hub sinh ra --> <script src='Hub.js'></script>        <!-- Thư viện mở rộng của tôi -->
Code server để định nghĩa Hub
public class ExampleHub : Hub
{
public void ClientSendMessage(string userName, string msg, string color)
{
userName = userName.Trim();
if (userName.IsNull()) return;

msg = msg.Trim();
if (msg.IsNull()) return;

var data = new { userName, avatar = userName.First(), msg, time = DateTime.Now.ToString("HH:mm dd/MM/yyyy"), color };

Clients.AllExcept(Context.ConnectionId).receiveMessage(data, false);
Clients.Client(Context.ConnectionId).receiveMessage(data, true);
}
}
Code javascript tại client để kết nối tới Hub
function ExampleHub()
{
$.extend(this, new Hub("", "exampleHub"));

this.actionReceiveMessage = new Hub.ActionRegistry();

this.onBeforeStart = function ()
{
var $this = this;

// Client
this.hub.client.receiveMessage = function (data, right)
{
$this.actionReceiveMessage.do(function (func) { func(data, right); });
};

// Server
this.startDone = function () { };
this.clientSendMessage = function (userName, message, color)
{
this.onOk(function ()
{
$this.hub.server.clientSendMessage(userName, message, color);
});
}
};
}

Ở đây các bạn có thể thấy ExampleHub kế thừa tới Hub và gán 2 giá trị: hubUrl = “” (Do server của hub nằm ngay tại server web của tôi) và hubName = “exampleHub”.

Ở phía xử lý client có this.actionReceiveMessage là đối tượng đăng ký nhận hành động muốn xử lý data gửi về từ server.  Client muốn giao tiếp gửi request tới server thì thông qua this.onOk để luôn đảm bảo chỉ thực hiện request khi ở trạng thái kết nối ổn định.

Và cuối cùng là giao diện hiển thị tôi định nghĩa một BoxChat như sau
function BoxChat()
{
this.ws = null; // là một instance của ExampleHub
this.area = null;
var template = null;

var colors = { 0: "bg-danger text-white", 1: "bg-success text-white", 2: "bg-primary text-white", 3: "bg-warning text-white", 4: "bg-secondary text-white", 5: "bg-dark text-white", 6: "bg-orangered text-white" };
var names = { 0: "Sơn20", 1: "Dũng", 2: "Việt Anh", 3: "TuhiKing", 4: "Tàn Long", 5: "ButaKing", 6: "Osoft" };

var color = null;

this.start = function ()
{
color = colors[Core.random(6)];

var $this = this;
template = this.area.find("[data-form=template] .direct-chat-msg");
var userNameInput = this.area.find("[name=userName]");
var messageInput = this.area.find("[name=message]").focus();
var butonSend = this.area.find("[data-form=button]");

userNameInput.val(names[Core.random(6)] + "." + Core.random(20)); // Tạo một tên ngẫu nhiên
butonSend.click(function ()
{
var userName = userNameInput.val();
if (userName == "") { Core.alert("Vui lòng nhập tên tài khoản để tán gẫu"); return; };

var message = messageInput.val();
if (message == "") { Core.alert("Vui lòng nhập nội dung để tán gẫu"); return; };

$this.ws.clientSendMessage(userName, message, color);
});
messageInput.keypress(function (event)
{
if (event.keyCode == "13")
{
butonSend.click();
return false;
}
});

var formChat = this.area.find("[data-form=chat]");
this.ws.actionReceiveMessage.registry(function (data, right)
{
var chatItem = template.clone();
chatItem.find("[data-chat]").each(function () { $(this).html(data[$(this).attr("data-chat")]); });
chatItem.find("[data-chat=avatar]").addClass(data.color);
if (right) chatItem.addClass("right");
formChat.append(chatItem);

formChat.scrollTop(formChat[0].scrollHeight);
messageInput.val("").focus();
});
}
}

Tại hàm start của BoxChat tôi đăng ký hành động khi có message gửi về thì hiển thị nội dung tin nhắn lên. Như đã nói ở trên, actionRegistry giúp đăng ký hành động nhận push từ server ở mọi module mà mình muốn mà không cần phải sửa lại hàm ở client trong hub.

Cuối cùng là khai báo và sử dụng
var ws = new ExampleHub();
ws.timeout = 2000; // Mặc định
ws.start();

var boxChat = new BoxChat();
boxChat.ws = ws;
boxChat.area = $("article");
boxChat.start();

// Ví dụ viết code đăng ký thêm một hành động nhận dữ liệu từ server push về
// Thì hiển thị một notify bên góc phải trên cùng màn hình
// Để cho thấy là có thể đăng ký sự kiện nhận dữ liệu ở mọi nơi.
ws.actionReceiveMessage.registry(function (data, right)
{
new PNotify({ target: $("article"), text: data.userName + ":" + data.msg, type: "success", delay: 1000 });
});

Tại bài viết này tôi vẫn đang sử dụng asp.net SignalR mà chưa chuyển sang asp.net Core SignalR. Do chưa đủ điều kiện về vật chất, hạ tầng và nhất là hệ thống phần mềm hiện tại của tôi vẫn đang viết trên asp.net. Tuy nhiên với cách làm này của tôi thì chuyển sang asp.net Core tôi cũng sẽ làm tương tự. Và đây là chia sẻ nhỏ mà tôi đã làm trong thực tế.

Chia sẻ thư viện javascript mở rộng khi kết nối tới Hub sử dụng SignalR

Gửi cảnh báo khi nhân viên thêm phiếu chi với một mục đích chi nào đó bị quá giới hạn cho phép mà quản lý đã cấu hình

Chia sẻ thư viện javascript mở rộng khi kết nối tới Hub sử dụng SignalR

Click vào cảnh báo ở góc phải bên dưới màn hình xem ngay được nội dung cảnh báo

Chia sẻ thư viện javascript mở rộng khi kết nối tới Hub sử dụng SignalR

Tại nội dung cảnh báo. Click xem chi tiết phiếu để xem nhân viên đã thêm chi cho những mục đích gì

Chúc các bạn lập trình ngày càng tốt hơn. Nếu có thắc mắc các bạn hãy để lại bình luận nhé. Xin cảm ơn smiley

Sơn 20

Bài viết gốc được đăng tải tại sonpc20.com

Có thể bạn quan tâm:

Tham khảo tìm việc IT hấp dẫn trên TopDev

JasperReport là gì?

JasperReport là gì?

Bài viết được sự cho phép của tác giả Kien Dang Chung

Các lập trình viên gạo cội chắc không lạ gì với JasperReport, nhưng với một số người mới JasperReport có thể là một khái niệm rất mới. Vậy JasperReport là gì? nó được ứng dụng như thế nào trong các hệ thống phần mềm?

  Làm việc với nguồn dữ liệu trong JasperReport
  Cách viết một bug report tốt

1. JasperReport công cụ tuyệt vời cho các báo cáo

Trong các hệ thống ứng dụng, các mẫu biểu chứng từ, các loại tài liệu báo cáo… là rất cần thiết. Ví dụ, với một hệ thống quản lý bán hàng chúng ta có các mẫu chứng từ như phiếu xuất kho, phiếu bảo hành… Hệ thống ngân hàng có thể có các chứng từ như các mẫu thu chi, phiếu tạo khách hàng, phiếu gửi tiền… JasperReport là bộ máy tạo các báo cáo mã nguồn mở được viết bằng ngôn ngữ Java giúp tích hợp vào các hệ thống nhằm tạo ra các mẫu biểu báo cáo, chứng từ phức tạp một cách dễ dàng.

JasperReport là gì?

JasperReport là một thư viện viết bằng Java, vậy tại sao Allaravel một website chuyên về framework Laravel lại giới thiệu JasperReport? Bạn có thể tham khảo bài viết Xây dựng báo cáo với JasperReport trong Laravel để hiểu hơn. Quay lại với bài viết, giờ thì bạn có thể đã hiểu sơ bộ được JasperReport là gì?

JasperReport có rất nhiều ưu điểm để trở thành một lựa chọn tốt nhất của bạn cho việc xây dựng hệ thống xuất chứng từ:

  1. JasperReport là phần mềm mã nguồn mở được phát triển từ năm 2001, do vậy nó hoàn toàn miễn phí và có một cộng đồng sử dụng rất lớn.
  2. Có rất nhiều các công cụ được phát triển giúp cho việc xuất báo cáo với JasperReport đơn giản:
    1. iReport là công cụ giao diện trực quan GUI giúp tạo ra các mẫu chứng từ chính xác dễ dàng. Phiên bản cuối cùng 5.5.0 phát hành ngày 31/12/2015 và sau đó chuyển sang công cụ mới là JasperSoft Studio.
    2. JasperSoft Studio công cụ thế hệ mới của iReport. Trong các bài viết của loạt bài về JasperReport chúng ta sẽ chỉ sử dụng JasperSoft Studio thay cho iReport.
    3. JasperStarter là công cụ giúp xuất báo cáo thông qua các câu lệnh trong màn hình dòng lệnh (console).
    4. JasViewer công cụ giúp chạy các file jasper, hiển thị người dùng tham số đầu vào chứng từ, hiển thị nội dung chứng từ.
    5. JasperReport Server là máy chủ chạy báo cáo có thể tích hợp cho phép chạy các báo cáo thời gian thực hoặc theo lịch trình dựa trên nền tảng web. Khi xây dựng các file báo cáo bằng iReport hoặc JasperSoft Studio, các file này có thể triển khai lên máy chủ và được thực hiện, xuất ra các định dạng khác nhau.

2. So sánh JasperReport với các hệ thống báo cáo khác như Crystal Report, KoolReport

Crystal Report là công cụ báo cáo rất quen thuộc với các lập trình viên .NET do nó tích hợp sâu vào Visual Studio .NET. Microsoft sau đó cũng phát triển riêng một hệ thống báo cáo là Microsoft Report. Sự khác biệt lớn là Crystal Report là phần mềm có phí do vậy để sử dụng bạn phải mua bản quyền.

KoolReport là hệ thống báo cáo viết bằng ngôn ngữ PHP, nó cũng là lựa chọn tốt khi sử dụng framework Laravel, đặc biệt nó có một gói tích hợp giúp phát triển báo cáo KoolReport trong Laravel nhanh chóng mà không cần phải viết nhiều code. Tuy nhiên, để thiết kế được báo cáo chúng ta cần có KoolReport Pro với giá 129$.

Qua rất nhiều so sánh chúng ta có thể thấy JasperReport là lựa chọn tốt với chi phí thấp (gần như không mất phí) cho phép tạo ra các chứng từ phức tạp nhất với các thành phần báo cáo hiện đại như biểu đồ, các loại mã vạch, QR code, bản đồ…

3. Cấu trúc thư viện JasperReport

JasperReport là gì?

  • net.sf.jasperreports.engine.JasperCompileManager: sử dụng để biên dịch JRXML report template.
  • net.sf.jasperreports.engine.JasperFillManager: Sử dụng để fill report với dữ liệu từ data source.
  • net.sf.jasperreports.engine.JasperPrintManager: Sử dụng để in tài liệu được sinh ra từ các thư viện JasperReports.
  • net.sf.jasperreports.engine.JasperExportManager: Sử dụng để xuất ra các định dạng PDF, HTML, hoặc XML.
  • net.sf.jasperreports.view.JasperViewer: Hiển thị một ứng dụng Java Swing đơn giản có thể hiển thị các báo cáo.
  • net.sf.jasperreports.view.JasperDesignViewer: Sử dụng để thiết kế và xem trước report templates.

4. Lời kết

JasperReport với bề dầy về phát triển gần 20 năm và một cộng đồng lớn kế thừa từ Java, Eclipse… đã tạo nên một hệ sinh thái xoay quanh các báo cáo, các hệ thống phân tích ra quyết định BI cực phong phú với giá thành cực thấp. JasperReport là lựa chọn tốt khi bạn muốn triển khai các hệ thống báo cáo, hệ thống in ấn chứng từ… tích hợp với các ứng dụng trên nền tảng Laravel. Chúng tôi mong muốn được đem đến cho các bạn các kiến thức cơ bản nhất giúp ích cho công việc các bạn sau này, các kiến thức có thể chưa được biên tập bài bản và đôi khi đưa ra theo những suy nghỉ cảm tính rất mong nhận được sự góp ý từ các bạn bè.

Bài viết gốc được đăng tải tại allaravel.com

Có thể bạn quan tâm:

Xem thêm Việc làm Developer hấp dẫn trên TopDev

Mybatis separator – tiện lợi và nguy hiểm

Mybatis separator – tiện lợi và nguy hiểm

Bài viết được sự cho phép của tác giả Kiên Nguyễn

Trước khi bắt đầu tìm hiểu Mybatis separator là gì?. Nếu yếu sinh lí, ý lộn, nếu chưa biết về Mybatis thì các ông có thể đọc bài giới thiệu về Mybatis ở Kieblog.

Tựa đề bài viết là Mybatis – chim nhỏ nhưng làm được lâu!. Đọc thôi là đã thấy cường dương bổ thận như rocket 1h rồi.

  “Sống chung” với sếp siêu nóng tính, bí kíp nào là khôn ngoan?
  Cải thiện mối quan hệ giữa lập trình viên với sếp: dễ hay khó? (P1)

Trong quá trình làm việc tại công ty, gặp phải một dự án sử dụng Mybatis. Va vấp khá nhiều, rút ra không ít kinh nghiệm khi làm việc với chim nhỏ, nên viết ra bài này chia sẻ chút kinh nghiệm nhỏ nhoi khi làm việc với Mybatis separator.

Mong anh em đón đọc, có gì chưa đúng xin vui lòng bình luận phía dưới. Đm, tôi thề là ông nào chửi tôi cũng rep lại lịch sự nhé!.

Mybatis separator – tiện lợi và nguy hiểm
Nhìn quen không?. Dynamic với Mybatis rõ ràng render động giấu phẩy giữa các điều kiện IN

BẮT ĐẦU NHA!

1. Mybatis separator là gì?

Trường hợp sử dụng foreach, seperator giúp thêm các dấu phân tách khi thực hiện loop bằng foreach. Cùng xem xét trường hợp dưới đây.

<select id="searchCoursesByTutors" parameterType="map" resultMap="CourseResult"> 
SELECT * FROM COURSES 
<if test="tutorIds != null"> 
<where> 
tutor_id IN 
<foreach item="tutorId" collection="tutorIds" open="(" separator="," close=")"> 
#{tutorId} 
</foreach> 
</where> 
</if> 
</select>

Trong trường hợp này seperator giúp thêm các dấu phẩy giữa các điều kiện IN. SQL sẽ generate ra như sau:

SELECT * FROM COURSES 
WHERE tutor_id IN (1,2,3)

Không phải chỉ mỗi cho các điều kiện WHERE IN, seperator còn hỗ trợ loop đối với các câu SQL cơ bản. các cặp value phức tạp hơn

SELECT * FROM COURSES 
WHERE (tutor_id, lession_id) IN ((1, 2), (2,3), (3,4))

2. Kinh nghiệm xương máu

Sử dụng Mybatis separator thật sự tiện lợi. Nói thẳng ra nhắc tới Dynamic SQL mà không có ví dụ về Mybatis separator thì cũng hết cả vui, hết cả sinh động.

Tuy nhiên, thực tế cho thấy, cần phải thật sự cẩn thận khi sử dụng separator.

Chuyện thế này, ở công ty, khi cả team tôi đang phát hục mặt làm task cho kịp tiến độ thì QC hét lên.

Ủa, sao cái bảng ABC này có tới cả triệu dòng thế?. Ai đã làm gì?. Mới chạy test lòng vòng có vài lần. Sao dữ liệu đâu ra lắm thế?.

Chả có gì để nói nếu tôi không phải là người vô tình tìm ra cái bug do vô tình mà có này.

Nói là bug vô tình nhưng nếu cứ để vậy mà release thì bug này không phải chuyện nhỏ. Tất cả các câu SQL viết cho dự án đều được yêu cầu tối ưu triệt để. (Anh em nào chưa biết thì đọc qua bài viết này Tối ưu SQL, jouneu to the west)

Dự án thì đang dùng Amazon EC3, nếu mới trong một thời gian ngắn sử dụng mà đã có tới mấy chục triệu row trong table thì thật là lạ (dự án đâu làm về big data)

Cắm đầu nhìn code, ban đầu thì chả có gì đặc biệt, anh đồng nghiệp insert một list data. Tất nhiên ảnh sẽ dùng foreach của separator, truyền vào một listrồi cứ loop trên list đó để insert vào DB thôi.

Đại khái viết thế này:

// Tôi viết đại khái thôi nhé!. 
// Chứ theo policy công ty không thể public source được.
<foreach collection="danh_sach_group" item="group" separator="UNION">
<foreach collection="group" item="model">
insert into BANG_NAO_DO
(ten, tuoi)
values 
(#{model.ten}, #{model.tuoi})
</foreach>
</foreach>

3. Vấn đề ở đâu?

Như cái ví dụ phía trên tôi post lên thì các ông thấy vấn đề nằm ở đâu không?.

Vấn đề nằm ở chỗ cái separator=”UNION” đấy, thật sự tai hại. Nói không chắc một số anh em chưa hiểu được (cái Dynamic SQL thật sự cần trí tưởng tượng một chút).

Tôi lấy ví dụ nhé:

// Công ty có 2 group (A và B)
Group A - 2 thằng (Tên TÈO - 11 tuổi, tên TỒ - 12 tuổi)
Group B - 3 thằng (Tên TÍ - 13 tuổi, tên TỦN - 14 tuổi, tên TỊT - 15 tuổi)

// Với 2 group này, ta cần 5 câu insert vào BANG_NAO_DO

INSERT INTO BANG_NAO_DO (ten, tuoi) VALUES (TEO, 11)
INSERT INTO BANG_NAO_DO (ten, tuoi) VALUES (TO, 12)
INSERT INTO BANG_NAO_DO (ten, tuoi) VALUES (TI, 13)
INSERT INTO BANG_NAO_DO (ten, tuoi) VALUES (TUN, 14)
INSERT INTO BANG_NAO_DO (ten, tuoi) VALUES (TIT, 15)

Đấy, yêu cầu dùng Mybatis separator chỉ có thế. Insert 5 thằng trong 2 group vào là ổn, nhưng đây lại insert tới gấp đôi, gấp ba. Bảo sao database không quá tải!.

Ra production kiểu này là toang, dễ đi lắm, dễ ăn chửi lắm!. Nên anh em nhớ cẩn thận nha

4. Kết luận

Dynamic SQL thật sự rất tiện lợi, từ khóa Separator cũng vậy. Trường hợp sử dụng lịnh hoạt, SQL sẽ làm rất nhiều việc, bớt phải code ở phần logic Java.

Tuy nhiên, trường hợp sử dụng cần đặc biệt chú ý các từ khóa foreach, separator by UNION, OR, AND. Trước khi viết cần lường được trước câu SQL sẽ render như thế nào?.

Mybatis separator – tiện lợi và nguy hiểm
Nhớ lường trước cái nguy hiểm của seperator UNION trước khi bắt đầu nha!

Nếu không thể lường trước, phải cố gắng show log câu SQL được render ra như thế nào rồi run thử. Tránh các trường hợp SQLException khi chạy production thực tế.

5. Tham khảo

Cảm ơn anh em đã đọc bài. Nhớ like và share bài viết nha. HAPPY CODING.

Bài viết gốc được đăng tải tại kieblog.vn

Có thể bạn quan tâm:

Xem thêm Việc làm Developer hấp dẫn trên TopDev

Những Nguyên Tắc Cơ Bản Của BrSE

Những Nguyên Tắc Cơ Bản Của BrSE

Bài viết được sự cho phép của tác giả Nguyễn Văn Trọng

Làm việc với vai trò của BrSE là người trung gian thực sự không phải việc đơn giản, vì 1 quyết định đưa ra sẽ có ảnh hưởng đến cả nhiều phía. Dưới đây là 1 số tình huống dở khóc dở cười mà mình đã từng gặp phải.

Khi phát hiện ra hệ thống cần có thêm chức năng abc, nếu nói cho khách hàng biết thì offshore sẽ nổi khùng vì phải overtime, mà không nói thì khách hàng cũng không biết, vậy nên nói không ?

Khi khách hàng không chấp nhận estimate vì các bác nghĩ quá cao, còn nếu giảm xuống thì bên phía nhà mình cho rằng quá thấp, thì phải làm thế nào ?

Khi khách hàng yêu cầu điều tra 1 lỗi hệ thống mà phần này mình chưa từng làm bao giờ, từ chối thì sẽ bị đánh giá thấp, mà nhận nếu làm không được thì gay go nữa ? vậy phải làm sao ?

Để trở thành 1 BrSE tốt thì trong quá trình làm việc hay mỗi lần đưa ra quyết định phải dựa trên nhiều nguyên tắc. Quyết định thì có thể đúng hoặc sai, nhưng 1 khi đã làm thì hãy dứt khoát, có sai thì mới có đúng – có dở thì sau này mới hay được.Có 3 nguyên tắc chính mà bản thân mình cho là quan trọng nhất.

Mình sẽ đưa dẫn chứng cụ thể để giải thích, mời các bạn cùng tham khảo nhé.

Tuyển lập trình Brse lương cao tại Topdev

Nguyên Tắc 1 : Nhìn Sự Việc Trên View Khách Hàng

Những Nguyên Tắc Cơ Bản Của BrSENhìn mọi việc với view của khách hàng

Tại sao lại vậy ? đơn giản “khách hàng là thượng đế”, còn nếu bạn muốn làm thượng đế thì … cái này mình bó tay thật.

Các cụ có câu (các cậu có …) “Thương nhau cau sáu bổ ba, ghét nhau cau sáu bổ ra làm mười” – cái ni là mạ miềng (mẹ mình) dạy. Khi mà các bác khách hàng thương mình rồi mọi việc sau này nó dễ dàng vô cùng, làm đúng thì bị khen lấy khen để, mà sai nhỏ nhỏ thì cũng … xí xóa cho qua. Để các bác ấy thương thì phải chiều, chiều sao cho đúng ? thì đơn giản là nhìn mọi việc trên view khách hàng sẽ hiểu ra được những mong muốn sâu xa mà các bác ko nói, hoặc đôi khi chưa nghĩ ra để nói.

Dạo trước, có lần mình phát hiện ra 1 lỗi khá to trong FW của khách hàng (FW này phát triển dựa trên Struts và Spring), lúc này cực kỳ khó xử vì nếu sửa 1 phát thì sẽ phải test lại toàn bộ, anh em offshore Over Time vỡ mật luôn. Mình quyết định nói nhưng kèm theo điều kiện là xin cho mọi người nghỉ vài ngày xả hơi sau khi xong cái ấy. Kết quả là giai đoạn đó tuy căng thẳng nhưng đổi lại từ đó về sau FW chạy rất mượt mà, khách hàng hài lòng còn anh em ở nhà cũng thoải mái hơn rất nhiều.

Đứng về phía khách hàng nhưng cũng phải nghĩ cho bên mình sao cho hài hòa

Nguyên Tắc 2 : Khách Hàng Không Phải Lúc Nào Cũng Đúng

Những Nguyên Tắc Cơ Bản Của BrSEHãy luôn đặt nghi vấn

Đối với người Nhật, họ luôn chỉn chu trong mọi quyết định, thường sẽ họp hành bàn bạc rất kỹ lưỡng, làm gì cũng có lý do hết. Nên nói họ sai thì rất hiếm khi, nhưng có hoàn toàn hợp lý chưa thì chưa chắc. Hãy luôn đặt ra nghi vấn với yêu cầu. Tại sao họ là yêu cầu làm vậy ? có cách nào hay hơn không ?

Cách đây 3 năm, trong 1 dự án mà các bác giao cho team BrSE mình làm từ design (basic + detail) đến test nghiệm thu. Thì ở giai đoạn design các bác muốn tụi mình làm = WORD. Thiệt sự mình cực kỳ ghét làm với word mà chỉ thích exel, 2 anh trong team cũng vậy vì nó rất khó format, bể tùm lum, ko thích hợp để làm design với đặc thù dự án lúc đó. Rất may là dự án trước đó mình cũng từng dùng word để làm rồi nên hiểu được những khó khăn khi phải chỉnh sửa nhiều, khi mình kể chuyện này cho các bác ấy nghe thì được chấp nhận chuyển đổi yêu cầu. Và sau này viết thêm mấy cái tool macro (word thì bótay) Gen tài liệu nữa nên năng suất vù vù mới thấy quyết định đó quá đúng đắn.

  5 Ngộ nhận về nghề BrSE
  Kinh Nghiệm Phỏng Vấn BrSE

Nguyên Tắc 3 : Không Nhất Thiết Phải Nói Thật Nhưng Tuyệt Đối KHÔNG ĐƯỢC NÓI DỐI

Những Nguyên Tắc Cơ Bản Của BrSELuôn tôn trọng sự thật

Đây là kinh nghiệm mình được 1 anh senpai truyền lại, trải nghiệm và thấy nó rất cần thiết. Người Nhật ghét nhất 2 thứ : ăn cắp và dối trá. Dân tộc Nhật, nền kinh tết Nhật dựa trên niềm tin, làm giàu bằng niềm tin từ khách hàng nên dối trá đối với họ là cái gì đó rất kinh khủng.

Khi khách hàng hỏi “tiến độ coding đến đâu rồi mậy”, còn 1 tuần nữa release mà đang cháy bùng bùng, cái module to nhất thì chú dev phụ trách lại nghỉ phép giữa chừng vì cô người yêu bị … sổ mũi. Tình hình có vẻ căng ! trả lời sao đây ?

“dạ bác ok lắm ah” – vừa nói xong bỗng nhận được mail xin dời deadline của PM bên offshore => vỡ mặt.

“Dạ Function xxxOzawa do chú Kim phụ trách nhưng chú ấy xin nghỉ phép rồi ah, chắc là sẽ bị trễ … vài ngày” => vỡ đầu.

Lúc này tốt nhất là xin trả lời sau, trước mắt phải bàn bạc cụ thể với PM để bàn đối sách giải quyết, đưa ra giả thuyết cho trường hợp tốt nhất – xấu nhất, rồi sau đó mới thành thật với khách hàng (thành thật về tiến độ – kèm đối sách, nhưng mấy cái lý do lãng xẹt liên quan chú dev tên Kim thì ko nên nói ra).

Tổng Kết

  • Đánh giá sự việc trên view khách hàng
  • Khách hàng không phải lúc nào cũng đúng.
  • Không nói dối nhưng không nhất thiết phải nói thật.

Trên đây là bộ 3 nguyên tắc cơ bản của bản thân mình, tất nhiên là cũng có vài nguyên tắc khác nhưng mình thấy nó không quan trọng lắm nên ko liệt kê. Các bạn có thể áp dụng theo nhưng đừng cứng nhắc quá nhé, nếu có gì hay cứ share cho mình học hỏi thêm ờ comment bên dưới nhé.

Bài viết gốc được đăng tải tại kysubrse.com

Có thể bạn quan tâm:

Xem thêm Việc làm ngành cntt hấp dẫn trên TopDev

Hot Reload với dự án Spring Boot trên IntelliJ

Hot Reload với dự án Spring Boot trên IntelliJ

Bài viết được sự cho phép của tapchilaptrinh.vn

Giới thiệu

Hot Reload là tính năng tự động chạy lại dự án với bất kì sửa đổi nào vào mã nguồn. Lập trình viên không phải chạy lại dự án một cách thủ công.

  Preload, prefetch và các thuộc tính khác trên link
  Bảo mật ứng dụng Java web bởi Spring Security

Cách thực hiện

Bước 1 — Bổ sung gói thư viện spring-boot-devtools

Đối với dự án dùng Gradle:

compile group: 'org.springframework.boot', name: 'spring-boot-devtools'

Đối dự án dùng với Maven:

<dependency>
    <groupid>org.springframework.boot</groupid>
    <artifactid>spring-boot-devtools</artifactid>
</dependency>

Bước 2 — Cấu hình IntelliJ

  1. Mở mục Settings (Hoặc Preferences trên MacOS) → Build-Execution-Deployment → Compiler
  2. Bật chế độ Build Project Automatically
  3. Bấm tổ hợp phím Ctrl+Shift+A (Windows) hoặc Cmd + Shift + A (MacOS), tìm Registry. Khi hộp thoại Registry hiển thị thì kích hoạt (enable) cấu hình compiler.automake.allow.when.app.running

Bước 3 — Khởi động lại IntelliJ và thưởng thức

Chú ý:

Một số tình huống có thể xảy ra khi sử dụng tính năng Hot Reload là lỗi chạy lại nếu có sử dụng@Autowired trong mã nguồn Spring. Cách giải quyết: dùng phương pháp inject qua contructor thay vì @Autowired .

Author: Đặng Huy Hòa

Bài viết gốc được đăng tải tại tapchilaptrinh.vn

Có thể bạn quan tâm:

Xem thêm Việc làm Developer hấp dẫn trên TopDev

Nested class trong Java

Nested class trong Java

Bài viết được sự cho phép của tác giả Nguyễn Hữu Khanh

Java cho phép chúng ta có thể định nghĩa một class nằm trong một class khác, ví dụ như:

package com.huongdanjava.javaexample;
public class Application {
class Builder {
}
}

Class được định nghĩa bên trong một class khác, chúng ta gọi nó là nested class còn class khác này được gọi là outer class. Trong ví dụ của mình ở trên thì Builder là một nested class còn Application là một outer class. Nested class còn được chia thành 2 loại khác nhau là Non-static nested class và Static nested class. Cụ thể như thế nào? Trong bài viết này, chúng ta sẽ tìm hiểu về các nested class trong Java các bạn nhé!

Việc làm Java không yêu cầu kinh nghiệm

Non-static nested class

Non-static nested class hay còn gọi là những Inner class. Chúng ta có thể declare những Inner class này bên trong một class khác như class Builder ở trên, bên trong một phương thức nào đó (Method-local Inner Class), ngoài ra chúng ta còn có những class không có tên gọi là Anonymous Inner Class.

Khác với việc khai báo một class, chúng ta không thể declare nó với private access modifier, đối với Inner class chúng ta có thể làm điều này. Như ví dụ trên, mình có thể declare class Builder là private như sau:

package com.huongdanjava.javaexample;
public class Application {
private class Builder {
}
}

Mà khi đã declare một Inner class là private thì nó chỉ có thể được access bên trong class nó được khai báo thôi các bạn nhé!

Để khởi tạo một Inner class, các bạn cần khởi tạo đối tượng cho outer class trước. Ví dụ như:

package com.huongdanjava.javaexample;
public class Application {
private class Builder {
}
public static void main(String[] args) {
Application app = new Application();
Builder builder = app.new Builder();
}
}

Khi chúng ta khai báo một class bên trong một method nào đó, gọi là Method-local Inner Class, thì scope của class này chỉ thuộc về method đó mà thôi. Các bạn không thể khai báo class này với access modifier trong trường hợp này. Ví dụ như:

package com.huongdanjava.javaexample;
public class Application {
public void print() {
class Builder {
}
}
}

Và do đó, chúng ta chỉ có thể khởi tạo đối tượng của class này bên trong method:

package com.huongdanjava.javaexample;
public class Application {
public void print() {
class Builder {
}
Builder builder = new Builder();
}
}

Các bạn có thể khai báo final class hoặc abstract class bên trong một method các bạn nhé:

package com.huongdanjava.javaexample;

public class Application {
private void print() {
abstract class Builder {
}
}
}

Hay:

package com.huongdanjava.javaexample;

public class Application {
private void print() {
final class Builder {

}
}

}

Anonymous Inner Class thường được khai báo khi chúng ta muốn override một phương thức nào đó của một class hoặc interface. Chúng ta sẽ khai báo Anonymous Inner Class và khởi tạo đối tượng cho class này cùng một thời điểm. Ví dụ như:

package com.huongdanjava.javaexample;

public class Application {

public void print() {
Comparable<String> comparable = new Comparable<String>() {
public int compareTo(String o) {
return 0;
}
};
}
}

Các bạn cũng có thể declare Anonymous Inner Class bên ngoài method như sau:

package com.huongdanjava.javaexample;

public class Application {

Comparable<String> comparable = new Comparable<String>() {
public int compareTo(String o) {
return 0;
}
};

public void print() {

}
}
  10 Java Web Framework tốt nhất
  Factory Function vs. Class

Static Nested Class

Static nested class là những class được định nghĩa với từ khoá static. Nó là static member của outer class và do đó chúng ta không cần phải khởi tạo đối tượng của outer class và chính class này để access tới nó luôn. Ví dụ như:

package com.huongdanjava.javaexample;

public class Application {

static class Builder {

private static void print() {

}
}

public static void main(String[] args) {
Application.Builder.print();
}
}

Static nested class sẽ không access được tới các field, methods non-static của outer class. Ví dụ như:

Chúng ta không thể declare Static nested class bên trong method các bạn nhé!

Bài viết gốc được đăng tải tại huongdanjava.com

Có thể bạn quan tâm:

Xem thêm Việc làm Developer hấp dẫn trên TopDev

Top 5 câu hỏi phỏng vấn Vuejs hay và khó

Top 5 câu hỏi phỏng vấn Vuejs hay và khó

Bài viết được sự cho phép của tác giả Kiên Nguyễn

Bữa rồi rảnh rỗi ngồi lướt Facebook thấy có status đăng như sau “Phỏng vấn Vuejs một bạn làm Vuejs 2 năm nhưng không rõ về mounted, computed và created“.

  Cách sử dụng các plugins jQuery trong VueJS
  Instant AJAX Search với Laravel và Vuejs

Nghĩ mà buồn thay, nên tiếp sau bài viết về Vuejs life cycle – hiểu sao cho đúng. Mình quyết định viết thêm bài viết một số câu hỏi phỏng vấn Vuejs cơ bản. Hy vọng sẽ giúp đỡ các bạn khi try hard phỏng vấn Vuejs nha.

Top 5 câu hỏi phỏng vấn Vuejs hay và khó
Đệch, đặt tên con đi phỏng vấn đâu cũng pass. LOL

1. Sự khác biệt giữa v-if và v-show?

// V-if condition group 
<template v-if="ok">
<h1>Title</h1>
<p>Paragraph 1</p>
<p>Paragraph 2</p>
</template>

v-if only renders the element to the DOM if the expression passes whereas v-show renders all elements to the DOM and then uses the CSS display property to show/hide elements based on expression.

v-if chỉ render các element tới cây DOM nếu biểu thức bên trong dấu bằng đúng (true). Trong khi đó, v-show render tất cả các element đó trên DOM và sử dụng CSS để ẩn hiện thông qua tính đúng sai trong biểu thức

Rõ ràng mà nói, sự khác biệt cơ bản và chuẩn chỉnh nhất giữa v-if và v-show là có render lên DOM tree hay không?. V-if rõ ràng không hề render object đó nếu không thỏa điều kiện, còn v-show thì có.

v-if has higher toggle costs while v-show has higher initial render costs

v-if có chi phí render khá cao, chắc chắn là cao hơn v-show, thoải điều kiện thì v-show sẽ render lại object đó trên DOM. Nên cẩn thận khi dùng

// v-show render trên DOM, nhưng display: none để ẩn đi
<h1 v-show="ok">Hello!</h1>
Top 5 câu hỏi phỏng vấn Vuejs hay và khó

Nên một số đối tượng thường xuyên ẩn hiện nên sử dụng v-show. Bạn nào chưa biết về cây DOM có thể tham khảo bài viết này tại Kieblog.

Đấy, đọc thì tưởng là câu hỏi phỏng vấn Vuejs dễ. Trả lời cho đúng với bài bản thì không phải dễ nha.

2. Tại sao khi bind v-for thường phải mapping key

Hơi kì kì nhưng câu trả lời cũng có ý đúng là v-if thì có v-else còn v-show thì không

3. Có thể for loop một range với v-for được không?

Căng, trước giờ v-for với index cho từng item thì thấy nhiều, chứ for cho range thì hơi lạ. Tuy nhiên đây không phải câu phỏng vấn Vuejs khó. Chỉ là một câu hỏi mẹo thôi

v-for với kiểu mapping idx kiểu này thì bình thường, xài rất nhiều.

 <div
class="message-content"
v-for="(msg, idx) in message.contents"
v-bind:key="idx"
v-html="msg"
></div>
Tuy nhiên, vẫn có một kiểu khác ít biết hơn có thể for trong range như sau:
// Sử dụng từ khóa in, loop trong dãy từ 1->10
<div>
<span v-for="n in 10">{{ n }} </span>
</div>

Đù, hỏi thách đố vl, nhưng không sao, biết thêm chừng nào tốt chừng đó. Code kiểu này trong pro ra hẳn.

4. Dynamic route matching là gì?

Dynamic route cũng là một câu hỏi phỏng vấn khá hay. Tất nhiên đã làm nhiều với Vuejs sẽ trả lời hoặc đưa ra được ví dụ về câu hỏi này. Đã làm Vue thì mình nghĩ trong quá trình phỏng vấn Vuejs chắc chắn sẽ có một câu liên quan tới Router. Nên ôn kĩ nha!.

Tuy nhiên, chính xác mà nói:

Dynamic route matching to map routes to the same component based on a pattern.

Dynamic route matching giúp ta map các route tới component với các pattern khác nhau

Cùng xem xét ví dụ dưới đây:

// Sử dụng từ khóa in, loop trong dãy từ 1->10
const Aritcle = {
template: '<div>Aritcle {{ $route.params.subjectId }}, PostId: {{ route.params.postid }}</div>'
}

const router = new VueRouter({
routes: [
// dynamic segments start with a colon
{ path: '/subject/:subjectId/post/:postid', component: Aritcle }
]
})

Khi sử dụng, các URL mapping với router param sẽ cho các kết quả như sau:

/subject/vuejs/post/123 hoặc /subject/react/post/234

5. Mục đích của keep alive tag?

Câu hỏi phỏng vấn Vuejs về keep-alive thường không hỏi nhiều. Tuy nhiên khá dễ để nắm bắt, bạn nào có đọc qua chắc chắn trả lời được.

Keep-alive tag is an abstract component used to preserve component state or avoid re-rendering. When you wrapped tag around a dynamic component, it caches the inactive component instances without destroying them.

Keep-alive tag sử dụng để giữ trạng thái hiện có của component và tránh việc render lại component quá nhiều lần. Các đối tượng được đóng ở trong tag keep-alive sẽ được giữ instances

Keep-alive component đặc biệt hữu ích ở các component stepper. Một khi đã lưu các thông tin ở step này, back lại sẽ có ngay, không phải render.

<!-- Inactive components will be cached! -->
<keep-alive>
<component v-bind:is="currentTabComponent"></component>
</keep-alive>

Ngoài việc không phải render lại (về perfomance), sử dụng keep alive tag còn tránh việc sử dụng Store vô tội vạ để lưu trữ khi back đi back lại

<!-- basic -->
<keep-alive>
<component :is="view"></component>
</keep-alive>

<!-- multiple conditional children -->
<keep-alive>
<comp-a v-if="a > 1"></comp-a>
<comp-b v-else></comp-b>
</keep-alive>

<!-- used together with `<transition>` -->
<transition>
<keep-alive>
<component :is="view"></component>
</keep-alive>
</transition>

6. Tham khảo một số câu hỏi phỏng vấn Vuejs khác

Cảm ơn vì đã đọc bài. Nhớ đón đọc vào thứ 2 và thứ 5 hằng tuần nha. Happy coding!

Bài viết gốc được đăng tải tại kieblog.vn

Có thể bạn quan tâm:

Xem thêm Việc làm Developer hấp dẫn trên TopDev