Loại bỏ Windows Terminal khỏi Menu chuột phải Windows 10
Bài viết được sự cho phép của blogchiasekienthuc.com
Có lẽ, lập trình đang là một trong những ngành nghề hot nhất hiện nay, một công việc nhàn hạ cùng với một mức lương đáng mơ ước ! Vâng, đấy là nhiều bạn đang nghĩ thế 😀 Còn thực tế thì xem tại đây 🙂
Mà đã là dân lập trình (dev) thì chắn chắn không còn xa lạ gì với các công cụ dòng lệnh như Terminal trên Linux, macOS, thậm chí là bạn còn biết cách sử dụng nó một cách thuần thục nữa.
Trên hệ điều hành Windows 10 mà chúng ta đang sử dụng cũng có một công cụ tương tự như vậy, không chỉ một mà có tới hai luôn các bạn ạ.
Khỏi cần kể tên thì chắc các bạn cũng biết hai công cụ mà mình đang muốn đề cập đến nó là gì rồi đúng không 🙂 Vâng, chính là Windows PowerShell và Command Prompt !
Tuy vậy, trên thực tế thì chức năng và ứng dụng của hai công cụ này không thể bằng được so với Terminal, đây cũng chính là lí do mà dân lập trình ưa dùng Linux và macOS hơn là Windows 10.
Mới đây, Microsoft đã giới thiệu và phát hành một ứng dụng mang tên Windows Terminal với mục đích thay thế Command Prompt và PowerShell.
Và nếu bạn không phải dân lập trình, không thường xuyên sử dụng công cụ này thì mình sẽ hướng dẫn cho các bạn cách loại bỏ Windows Terminal khỏi menu chuột phải của Windows 10 nhé !
#1. Windows Terminal xuất hiện ở đâu?
Windows Terminal là một ứng dụng mã nguồn mở được Microsoft phát triển và phát hành miễn phí trên Windows 10.
Đây là một công cụ dòng lệnh có giao diện rất hiện đại, mạnh mẽ, mượt mà và giúp tăng hiệu suất làm việc của người dùng.
Ban đầu, nghe tin Microsoft ra mắt ứng dụng Terminal mới mình đã cảm thấy rất phấn khích và hóng ngày được dùng thử.
Nhưng hy vọng càng nhiều thì thất vọng càng nhiều các bạn ạ, ứng dụng Windows Terminal thực chất vẫn chỉ là Windows PowerShell và Command Prompt trong lớp vỏ trông có phần hiện đại hơn, kèm vài tính năng không mấy hữu ích lắm. Kiểu bình mới rượu cũ ấy 🙁
Và từ đó đến giờ mình cũng chẳng động đến cái ứng dụng Terminal đó lần nào nữa. Ai chưa biết và cũng chưa dùng thử ứng dụng này bao giờ thì có thể xem lại bài viết giới thiệu và hướng dẫn cài đặt Windows Terminal trước đó của mình nha.
Khi đã được cài đặt vào Windows 10, Windows Terminal sẽ mặc định có trong menu chuột phải của File Explorer tùy chọn Open in Windows Terminal.
Nó cho phép bạn mở nhanh một thư mục trong Windows Terminal để làm việc, thay vì phải gõ lệnh cd + đường dẫn thư mục như thông thường, đây là một tính năng khá hữu ích, giúp tiện kiệm thời gian gõ lệnh, đặc biệt là với các thư mục có đường dẫn dài và phức tạp.
Tuy nhiên, nếu bạn không có nhu cầu sử dụng đến tính năng Open in Windows Terminal nhưng vẫn cần dùng Terminal, hoặc cảm thấy khó chịu khi thường bấm nhầm vào tùy chọn này thì hoàn toàn có thể gỡ bỏ nó khỏi menu chuột phải của Windows 10.
#2. Loại bỏ Windows Terminal khỏi Menu chuột phải trên Windows 10
Để loại bỏ tùy chọn Open in Windows Terminal ra khỏi menu chuột phải của Windows 10, chúng ta không có cách nào khác ngoài việc chỉnh sửa trong Registry của hệ thống.
Chính vì thế mà bạn nên sao lưu lại toàn bộ Registry trước khi làm theo bài hướng dẫn này để nếu có lỡ chỉnh sửa sai gây lỗi Windows 10 thì vẫn có thể khôi phục lại được.
Thực hiện:
+ Bước 1: Trước hết, bạn mở hộp thoại RUN lên (Windows + R) => rồi nhập vào lệnh regedit => và bấm phím Enter để truy cập nhanh công cụ quen thuộc Registry Editor trên Windows 10.
+ Bước 2: Tiếp theo, bạn truy cập vào thư mục Blocked trong Registry theo đường dẫn:
NOTE: Bạn có thể truy cập nhanh vào thư mục này bằng cách dán trực tiếp đường dẫn trên vào thanh địa chỉ của Registry Editor rồi bấm Enter là xong.
Ngoài ra, bạn có thể tham khảo cách mở nhanh một đường dẫn bật kỳ trong Registry chỉ với một cú click chuột để rút ngắn, tiết kiệm thời gian truy cập thủ công như mình làm đây ha.
Mặc định thư mục Blocked này sẽ chưa có khóa nào cả, khóa Default (String) không tính vì nó là khóa mặc định và bắt buộc phải có của mọi thư mục trong Registry Editor.
+ Bước 3: Giờ để loại bỏOpen in Windows Terminal trong menu chuột phải, bạn hãy click chuột phải vào khoản trống bất kỳ trong khung bên phải => chọn New => chọn String Value để tạo một khóa mới dạng chuỗi như khóa Default ở trên.
Sau đó, bạn đặt tên cho khóa vừa tạo là {9F156763-7844-4DC4-B2B1-901F640F5155} và phần Value data hãy để trống.
=> Vậy là xong rồi đó, bạn không cần phải chỉnh sửa phức tạp cả và đã có thể đóng Registry Editor đi được rồi.
__________________
Bonus: Nếu bạn sợ thao tác sai thì có thể sử dụng file REG mà mình đã tạo sẵn bên dưới đây !
Vẫn như mọi lần, mình đã chuẩn bị sẵn file REG để cho các bạn tiện sử dụng, chỉ việc giải nén ra và dùng file REG tương ứng thôi.
Chọn một trong các đường link bên dưới để tải về, file ZIP đã bao gồm cả file REG để loại bỏ và khôi phục dòng Open in Windows Terminal.
Thông thường sau khi chỉnh sửa trong Registry của Windows 10, chúng ta sẽ cần khởi động lại máy tính để các thay đổi đó có hiệu lực.
Nhưng đối với trường hợp này, bạn chỉ việc khởi động lại Windows Explorer là được. Mình cũng đã có hẳn một bài viết chia sẻ những cách khởi động lại Windows Explorer trên Windows 10 rồi, bạn có thể tìm và xem lại nha.
Còn cách mình thấy nhanh nhất và thườn xuyên sử dụng nhất đó là mở Task Manager lên (Ctrl + Shift + ESC) => bấn chuột phải vào tiến trình Windows Explorer => rồi chọn Restart thôi.
Và đây kết quả sau khi khởi động lại Windows Explorer, menu chuột phải đã trở về như bình thường.
Đây là cách để áp dụng cho những bạn vẫn có nhu cầu dùng ứng dụng Terminal, còn như mình, không dùng thì gỡ cài đặt Terminal là cách đơn giản và nhanh nhất để loại bỏ tùy chọn Open in Windows Terminal nha các bạn.
#3. Lời kết
Như vậy là mình đã vừa hướng dẫn xong cho các bạn cách để loại bỏ tùy chọn Open in Windows Terminal trong menu chuột phải của Windows 10 rồi.
Tùy chọn này nghe có vẻ hữu ích nhưng trong thực tế thì không được như Microsoft kỳ vọng, thậm chí còn gây phiền phức vì bấm nhầm trong quá trình sử dụng nữa. Và nó còn làm cho menu chuột phải thêm cồng kềnh..
Nhưng mình vẫn hi vọng Microsoft tiếp tục cải tiến nó trong những phiên bản sắp tới !
Nếu thấy thủ thuật mình vừa giới thiệu hay và hữu ích thì đừng quên chia sẻ để nhiều người cùng biết nữa nha. Chúc các bạn thành công !
Đầu tiên, bài viết này mình viết với mục đích chia sẻ kiến thức của mình về http cookies (hoặc http cookie). Nếu bạn nào chưa biết về HTTP, FTP, SMTP thì có thể đọc bài này trước. Cách chia sẻ của mình là cố gắng diễn tả vấn đề sao cho thật hài hước và dễ hiểu. Bằng cách này, việc đọc bài sẽ giúp các bạn nhớ lâu và việc học trở nên không nhàm chán, chứ không phải là không tôn trọng người đọc.
Vì vậy, việc này có thể sẽ không phù hợp với một số bạn, nên nếu có vấn đề gì về kiến thức hoặc cách diễn đạt của mình, các bạn có thể góp ý cho mình bằng cách comment phía dưới.
Http Cookie, thường được gọi là cookie (bánh). Từ thuở ban đầu dự định sử dụng vào việc lưu trữ thông tin session ở phía client. Theo bản chất, cookie sẽ được gắn với một tên miền (domain) cụ thể.
Câu chuyện ra đời của cookie khá là hấp diêm, ý lộn hấp dẫn.
1.1 Câu chuyện
Ngày xửa ngày xưa, có một cô nàng tên là Netscape, rất xinh đẹp và còn zin 😂😂. Cô ấy yêu say đắm một anh chàng tên Server. Vào một ngày kia, khi tình yêu đã chớm nở, cô gửi cho anh chàng một cái request (với header là hãy làm gì em đi!).
Không bỏ qua cơ hội ngon ăn, anh chàng server gửi ngay một response, anh check hàng (mất zin, ẹc) và đồng ý cho Netscape vào phòng.
Sẽ chẳng có gì để nói nếu 2 tiếng sau đó, cô nàng Netscape đi ra ngoài đổ rác và quay lại gõ cửa yêu cầu được quay trở lại phòng, trớ trêu thay, anh chàng server đã mất đi trí nhớ của mình và lại đòi check hàngNetscape. Vì quá bực tức với độ điếm thúi của server, cô nàng Nestcape đã lấy một ít bánh (cookie) còn sót trong thùng rác, ghi vào đó cặp name value rằng checkroi: 2tiengtruoc. Ngay khi nhận được bánh, server lập tức hiểu rằng đã check hàng, và nó cho Netscape vào. Từ đó cookie ra đời.
Vừa rồi là câu chuyện về sự ra đời của cookie do mình tự bịa, còn ngắn gọn thì cookie được phát minh bởi Netscape, với mục đích ban đầu là để cung cấp bộ nhớ cho máy chủ và trình duyệt web. 🤣🤣
2. Mày vừa mới troll tao đấy!, thế có những loại cookies nào, dùng nó làm gì?.
Tất nhiên, với câu chuyện ra đời hết sức xàm xí, ý lộn có lí của cookie thì về cơ bản cookie có thể được phân làm hai loại chính:
Session cookies (phiên cookie): giữ lại ở trình duyệt và sẽ bị xóa bỏ khi đóng trình duyệt. Khi cửa sổ trình duyệt mới được mở lại, người dùng sẽ phải cung cấp lại các chứng thực của mình.
Persistent cookise (coookie liên tục): giữ ở trình duyệt cho tới khi hết hạn hoặc được xóa một cách thủ công. Các trang web sẽ ghi nhớ các chứng thực ngay cả khi người dùng đóng trình duyệt.
Ứng dụng quan trọng nhất của cookies là giữ cho người dùng đăng nhập khi họ duyệt từ trang này qua trang khác. Một số trang web thương mại điện tử thì sử dụng cả session cookies và persistent cookies để tạo sự liền mạch cho giỏ hàng khi mua sắm.
3. Hai loại, fine!. Thế nó hoạt động như thế nào?.
Nghiêm túc lại nè.
Khi người dùng truy cập vào trang web lần đầu tiên, trang web sẽ tạo ra bản ghi của nó và lưu vào cookies trên trình duyệt của người dùng. Lúc này cookies chỉ là một dòng văn bản ngắn. Không chứa bất cứ thông tin nào về người dùng hoặc máy của người dùng. Thay vào đó, nó chứa URL của trang web đã đặt cookies.
Khi người dùng quay lại và lướt web, mỗi trang mới mà người dùng truy cập, trình duyệt sẽ tìm kiếm cookies. Nếu URL của cookies khớp với URL của trang web, trang web sẽ truy xuất thông tin máy chủ. Phương thức lấy sẽ là sử dụng thông tin lấy được từ cookies.
Bằng cách này, trang web có thể nâng cao trải nghiệm người dùng, hạn chế phải lặp đi lặp lại nhiều hoạt động của người dùng. Một số trang web cũng có thể sử dụng cookies để nâng cao trải nghiệm người dùng. Người dùng mới có thể thấy phiên bản mới của trang web, trong khi người dùng cũ lại thấy phiên bản trước đó.
Các bạn có thể theo dõi hình dưới:
4. Biết là dùng vậy rồi!. Thế bánh có nhiều thứ không?.
Bánh ngon thì nhiều thứ 😂. Một vài thứ làm nên bánh đây:
Name: Một tên duy nhất dùng để định danh (bánh đậu xanh, bánh pía, vân vân). Tên cookies không phân biệt chữ hoa và chữ thường, vậy nên việc sử dụng banhPIA và BanhPia là giống nhau. Tuy nhiên, trong thực tế ta nên phân biệt hoa thường. Một số phần mềm trên server có thể sẽ phân biệt hoa thường. Ngoài ra tên cookies phải được mã hóa URL (URL encoded).
Value: giá trị được lưu trữ trong cookies, giá trị này cũng nên được mã hóa URL.
Domain: là domain mà cookies chúng ta hợp lệ (bánh not for everyone). Mọi thứ được gửi hoặc được sử dụng từ domain này sẽ kèm theo cookies.
Path: đường dẫn được chỉ định trong domain (địa chỉ ship bánh), nơi mà cookies sẽ được gửi đến server.
Expiration: Đây là dấu thời gian, nó cho biết lúc nào cookies sẽ bị xóa (bánh có hạn sử dụng, không thể ăn mãi được). Mặc định thì tất cả cookies sẽ bị xóa khi ta tắt trình duyệt.
Secure Flag: cờ an toàn, với mục đích chỉ gửi cookies nếu kết nối SSL được sử dụng. Ví dụ: khi gửi request tới https://www.vietcombank.com.vn thì nên gửi kèm thông tin cookies, còn tới http://www.vietcombank.com.vn thì không.
Hình dưới là một số cookies được lưu trữ khi truy cập stackoverflow.com.
5. Thử một cái xem nào, nhắc tới bánh đói bụng quá!.
Ví dụ đầu tiên thường gặp khi sử dụng cookies là xác thực (authentication). Khi chúng ta đăng nhập ở một website.
Luồng thực hiện:
Bước 1: Gửi request method POST yêu cầu đăng nhập tới website (ví dụ github), thông tin là username và password, việc đầu tiên server thực hiện là xác thực tài khoản này.
Bước 2: Sau khi xác thực thành công, server sẽ cấp token, lưu trữ vào cookies, ở đây là giá trị usersession
Bước 3: Khi quay lại trang web, server sẽ thực hiện method GET. Method này thực hiện lấy nhiều thông tin, một trong số đó là usersession
Bước 4: Dựa vào thông tin usersession này, server sẽ xác thực và di chuyển thẳng tới trang dashboard
6. Bánh có độc không? (thử rồi mới nói, ẹc).
Khi chúng ta thiết lập một cookies mới, nó sẽ được gửi kèm theo các request tới domain mà nó được khởi tạo. Việc hạn chế này đảm bảo thông tin lưu trữ trong cookie được an toàn. Chỉ có người được cấp phép mới được tiếp cận và không thể truy cập bởi domain khác (ship bánh nhầm cmn địa chỉ).
Vì cookie được lưu trữ trên phía client. Nên dù bánh có ngon, ta cũng không thể ăn quá nhiều. Số lượng cookie trên mỗi domain là có giới hạn!.
Hạn chế này đảm bảo rằng cookies sẽ không bị sử dụng sai mục đích và chiếm quá nhiều dung lượng đĩa (disk space).
Mặc dù bị giới hạn, nhưng số lượng cookie tối đa trên mỗi domain cũng thay đổi qua các phiên bản của trình duyệt.
Internet Explorer 6 trở về trước thì tối đa là 20 cookie
Internet Explorer 7 trở về sau thì tối đa là 50 cookie (sau khi có bản vá từ Microsoft)
Firefox là 50 cookie
Chorme và safari thì không giới hạn
7. Tổng kết.
Cookies là một phần của Web Storage interface, cũng là một phần thiết yếu của internet. Thiếu đi nó các trang web sẽ ít tương tác với người dùng, trải nghiệm người dùng trên trang web cũng bị giảm đi đáng kể. Vậy mới nói, nếu không có một tình yêu mãnh liệt giữa Server và Nestcape. Làm sao chúng ta có cookies ngày hôm nay?.
Vậy same-origin tức là những url có cùng scheme, host name, port, ngược lại thì gọi là cross-origin
Origin A
Origin B
https://www.example.com:443
https://example.com:443
cross-origin: khác subdomain
https://www.evil.com:443
cross-origin: khác domain
https://login.example.com:443
cross-origin: khác subdomain
http://www.example.com:443
cross-origin: khác scheme
https://www.example.com:80
cross-origin: khác port
https://www.example.com
same-origin: ngầm hiểu cùng port 443 (port mặc định của web)
2. Site
Top-level domains (TLDs) như .com, .org được liệt kê trong trang này
site =TLD + phần ngay phía trước domain
Với ví dụ trên, thì site = example.com
Tuy nhiên với những tên miền kiểu .com.vn, github.io, cách xác định site này không còn đúng, nên người ta tạo thêm danh sách effective TLDs (eTLDs), xem chi tiết publicsuffix.org/list
Ví dụ, URL https://my-project.github.io thì site = my-project.github.io
Vậy same-site là những url có cùng site, ngược lại được gọi là cross-site
URL A
URL B
https://www.example.com:443
https://www.evil.com:443
cross-site: khác domain
https://login.example.com:443
same-site: khác subdomain không sao
http://www.example.com:443
same-site: khác scheme không sao
https://www.example.com:80
same-site: khác port không sao
https://www.example.com
same-site
Gần đây khái niệm same-site được mở rộng và bao gồm luôn scheme
Nếu tính luôn scheme, thì http://example.com và https://example.com là cross-site vì khác scheme
Các trang web có cùng eTLD + 1 được coi là “cùng một trang web”. Các trang web có eTLD + 1 khác là “trang web chéo”.
Xuất xứ A
Xuất xứ B
Giải thích về việc Xuất xứ A và B là “cùng một trang web” hay “trang web chéo”
https://www.example.com:443
https: // www.evil.com : 443
cross-site: các miền khác nhau
https: // đăng nhập .example.com: 443
cùng một trang web: các tên miền phụ khác nhau không quan trọng
http : //www.example.com: 443
cùng một trang web: các chương trình khác nhau không quan trọng
https://www.example.com: 80
cùng một trang web: các cổng khác nhau không quan trọng
https://www.example.com:443
cùng trang web: đối sánh chính xác
https://www.example.com
cùng trang web: các cổng không quan trọng
“schemeful same-site”
Định nghĩa “cùng một trang web” đang được phát triển để coi lược đồ URL là một phần của trang web nhằm ngăn chặn HTTP được sử dụng như một kênh yếu . Khi các trình duyệt chuyển sang phần diễn giải này, bạn có thể thấy các tham chiếu đến “trang web ít sơ đồ hơn” khi tham chiếu đến định nghĩa cũ hơn và ” trang web có sơ đồ tương tự ” tham chiếu đến định nghĩa chặt chẽ hơn. Trong trường hợp đó, http://www.example.comvà https://www.example.comđược coi là trang web chéo vì các lược đồ không khớp.
Xuất xứ A
Xuất xứ B
Giải thích về việc Xuất xứ A và B có phải là “cùng một trang web được sơ đồ hóa” hay không
https://www.example.com:443
https: // www.evil.com : 443
cross-site: các miền khác nhau
https: // đăng nhập .example.com: 443
cùng một trang web có kế hoạch: các tên miền phụ khác nhau không quan trọng
http : //www.example.com: 443
cross-site: các chương trình khác nhau
https://www.example.com: 80
cùng một trang web có sơ đồ: các cổng khác nhau không quan trọng
https://www.example.com:443
cùng một trang web có kế hoạch: kết hợp chính xác
https://www.example.com
cùng một trang web có kế hoạch: các cổng không quan trọng
Cách kiểm tra xem một yêu cầu là “cùng trang web”, “cùng nguồn gốc” hay “trang web chéo” #
Chrome gửi yêu cầu cùng với Sec-Fetch-Sitetiêu đề HTTP. Không có trình duyệt nào khác hỗ trợ Sec-Fetch-Sitekể từ tháng 4 năm 2020. Đây là một phần của đề xuất Tiêu đề yêu cầu siêu dữ liệu tìm nạp lớn hơn . Tiêu đề sẽ có một trong các giá trị sau:
cross-site
same-site
same-origin
none
Bằng cách kiểm tra giá trị của Sec-Fetch-Site, bạn có thể xác định xem yêu cầu là “cùng một trang web”, “cùng một nguồn gốc” hay “trang web chéo” (“sơ đồ cùng một trang web” không được nắm bắt Sec-Fetch-Site).
Nhân Viên QC & Mức Lương Của Nhân Viên QC Ở Thời Điểm Hiện Tại
Nhân viên QC – Quality Control (Kiểm soát chất lượng) là một trong những vị trí không thể thiếu với bất cứ công ty, tổ chức hay xí nghiệp nào. Với nhiệm vụ kiểm soát chất lượng và giám sát quy trình hoạt động, công việc của nhân viên QC phải làm hàng ngày đều rất nhiều và đòi hỏi tính cẩn thận cao. Vậy mức lương của nhân viên QC hiện đang nằm trong mức nào? Công việc phức tạp có đi kèm một mức lương hấp dẫn? Cùng TopDev tìm hiểu thêm với bài viết dưới đây nhé!
Lương của người làm QC trên thị trường đang như thế nào?
Các công việc nhân viên QC thường đảm nhận
Nhân viên QC – kiểm soát chất lượng sẽ chịu trách nhiệm chính trong việc kiểm tra và giám sát toàn bộ quy trình sản xuất sản phẩm. Để sản phẩm đến được tay khách hàng đảm bảo chất lượng, không xảy ra lỗi trong quá trình sử dụng, nhân viên QC phải làm việc liên tục để phát hiện kịp thời và phối hợp với nhân QA (Quality Assurance) để tìm ra phương án chỉnh sửa hợp lí nhất.
Nhân viên QC hiện đang có 3 dạng gồm: nhân viên kiểm soát chất lượng đầu vào, kiểm soát chất lượng quy trình sản xuất và kiểm soát chất lượng đầu ra. Tương ứng với mỗi giai đoạn, nhân viên QC ở mỗi vị trí sẽ có trách nhiệm chuyên môn riêng để giảm thiểu xuất hiện lỗi một cách tối đa. Thậm chí, đối với những nhân viên kiểm soát chất lượng chuyên nghiệp và đã có nhiều kinh nghiệm trong nghề, họ thậm chí có thể tìm được cách để gia tăng chất lượng sản phẩm so với ban đầu.
Mức lương của nhân viên QC hiện tại đang được chi trả dựa vào kinh nghiệm và năng lực làm việc. Theo đó, có thể kể qua mức lương của nhân viên QC fresher (chưa có/chưa nhiều kinh nghiệm) và mức lương nhân viên QC đã có nhiều kinh nghiệm làm việc trong ngành.
Mức lương của nhân viên QC chưa có nhiều kinh nghiệm
Vì có vai trò quan trọng nên các vị trí liên quan đến nhân viên kiểm soát chất lượng hiện nay đều có nhu cầu tuyển dụng rất cao. Do đó, với các sinh viên mới ra trường muốn tìm kiếm các công viên liên quan đến QC thì đây được xem là “mảnh đất cực kỳ màu mỡ”.
Mức lương trung bình của nhân viên QC mới ra trường, chưa có nhiều kinh nghiệm hoàn toàn có thể nằm trong khoảng từ 8 – 10 triệu đồng/tháng. Thậm chí, nếu bạn đã có một ít kinh nghiệm trong quá trình là sinh viên và có năng lực đảm nhận nhiều việc hơn, mức lương còn có thể cao hơn trong khoảng 12 triệu đồng/tháng.
Lương của nhân viên QC hiện được trả chủ yếu dựa trên kinh nghiệm làm việc
Mức lương của nhân viên QC đã có kinh nghiệm làm việc
Những nhân viên QC giỏi về chuyên môn cũng như có nhiều năm kinh nghiệm làm việc trong nghề được săn đón rất nhiệt tình. Do đó, mức lương cho vị trí này cũng hậu hĩnh hơn hẳn so với những công việc khác. Theo đó, ở thời điểm hiện tại, mức lương của một nhân viên QC đã có trên 3 – 4 năm kinh nghiệm ở mức trên 13 triệu đồng/tháng. Với những vị trí ở cấp quản lý như trưởng phòng, mức lương hoàn toàn có thể nằm trong khoảng trên 20 triệu đồng/tháng.
Không có một công việc nào là dễ dàng, và để có một mức thu nhập hấp dẫn thì việc đánh đổi sức lao động cũng sẽ nhiều hơn. Trau dồi và rèn luyện thật nhiều để có thể vững vàng với chuyên môn công việc của mình. Đón đọc thêm nhiều bài viết hấp dẫn trong lĩnh vực nhân sự và công nghệ cũng TopDev nhé!
Bài viết được sự cho phép của tác giả Nguyễn Hữu Khanh
Maven Archetype là một tính năng của Maven, các bạn hiểu nôm na là nó cho phép chúng ta tạo nhanh một Maven project với cấu trúc đã được định nghĩa sẵn. Chúng ta chỉ cần thay đổi những giá trị như Group Id, Artifact Id hay Version theo giá trị mà chúng ta muốn mà thôi. Mình thì mình hay sử dụng các Maven Archetype định nghĩa cấu trúc của các project Spring hay Jakarta EE. Trong bài viết này, mình sẽ hướng dẫn các bạn cách hiện thực một Maven archetype để nếu các bạn có ý định hiện thực một Maven Archetype cho riêng mình thì có thể dựa vào hướng dẫn của mình mà làm nhé!
Điều đầu tiên, mình cần nói với các bạn là Maven Archetype cũng là một Maven project nhưng packaging của nó không phải là jar, war hay là pom mà có giá trị là “maven-archetype”. Các bạn có thể sử dụng command line hoặc một Java IDE nào đó có hỗ trợ Maven project để generate Maven Archetype project đều được.
Tạo mới Maven Archetype project
Trong bài viết này, mình sẽ sử dụng Eclipse IDE để làm việc với Maven Archetype project.
Mình sẽ tạo mới một Maven project sử dụng một Maven Archetype của Maven để generate Maven Archetype project
Maven Archetype này có tên là maven-archetype-archetype:
Khai báo thông tin project:
Kết quả:
Các tập tin, thư mục nằm trong thư mục src/main/resources/archetype-resources sẽ nằm trong project mà chúng ta generate từ Maven Archetype project. Ví dụ, nếu bây giờ, các bạn chạy “mvn clean install” cho project này (các bạn nên sử dụng command line để chạy, chạy trong Eclipse có thể sẽ có issue liên quan đến “${maven.home} is not specified as a directory”) của Maven plugin, sau đó vào thư mục target/test-classes/projects/id-basic/project, các bạn sẽ thấy một project mới được generate từ Maven Archetype project của chúng ta:
Import Maven project này sử dụng một IDE khác như IntelliJ, các bạn sẽ thấy kết quả như sau:
Bây giờ, chúng ta sẽ thử hiện thực Maven Archetype project theo ý của mình nhé!
Hiện thực Maven Archetype project
Để lấy ví dụ cho bài viết này, mình sẽ hiện thực một Spring MVC project dựa trên project template của Spring Tool Suite 3, trong bài viết về Tạo ứng dụng web sử dụng Spring bằng Spring Legacy Project trong Spring Tool Suite 3. Nói cho các bạn hiểu thì Spring MVC project template của Spring Tool Suite 3 đang sử dụng những version cũ của Spring và các library khác, mỗi khi tạo mới project Spring MVC sử dụng nó, mình phải chỉnh sửa lại cho phù hợp với thời điểm hiện tại.
Đầu tiên, chúng ta cập nhập tập tin pom.xml ở thư mục src/main/resources/archetype-resources của Maven Archetype project.
Mình sẽ replace bằng nội dung của tập tin pom.xml trong project spring-mvc-example ở trên, xong chỉnh sửa lại version của các library, framework sử dụng latest version.
Nội dung của tập tin pom.xml của Maven Archetype project lúc này như sau:
Maven Archetype là một tính năng của Maven, các bạn hiểu nôm na là nó cho phép chúng ta tạo nhanh một Maven project với cấu trúc đã được định nghĩa sẵn. Chúng ta chỉ cần thay đổi những giá trị như Group Id, Artifact Id hay Version theo giá trị mà chúng ta muốn mà thôi. Mình thì mình hay sử dụng các Maven Archetype định nghĩa cấu trúc của các project Spring hay Jakarta EE. Trong bài viết này, mình sẽ hướng dẫn các bạn cách hiện thực một Maven archetype để nếu các bạn có ý định hiện thực một Maven Archetype cho riêng mình thì có thể dựa vào hướng dẫn của mình mà làm nhé!
Điều đầu tiên, mình cần nói với các bạn là Maven Archetype cũng là một Maven project nhưng packaging của nó không phải là jar, war hay là pom mà có giá trị là “maven-archetype”. Các bạn có thể sử dụng command line hoặc một Java IDE nào đó có hỗ trợ Maven project để generate Maven Archetype project đều được.
Tạo mới Maven Archetype project
Trong bài viết này, mình sẽ sử dụng Eclipse IDE để làm việc với Maven Archetype project.
Mình sẽ tạo mới một Maven project sử dụng một Maven Archetype của Maven để generate Maven Archetype project
Maven Archetype này có tên là maven-archetype-archetype:
Khai báo thông tin project:
Kết quả:
Các tập tin, thư mục nằm trong thư mục src/main/resources/archetype-resources sẽ nằm trong project mà chúng ta generate từ Maven Archetype project. Ví dụ, nếu bây giờ, các bạn chạy “mvn clean install” cho project này (các bạn nên sử dụng command line để chạy, chạy trong Eclipse có thể sẽ có issue liên quan đến “${maven.home} is not specified as a directory”) của Maven plugin, sau đó vào thư mục target/test-classes/projects/id-basic/project, các bạn sẽ thấy một project mới được generate từ Maven Archetype project của chúng ta:
Import Maven project này sử dụng một IDE khác như IntelliJ, các bạn sẽ thấy kết quả như sau:
Bây giờ, chúng ta sẽ thử hiện thực Maven Archetype project theo ý của mình nhé!
Hiện thực Maven Archetype project
Để lấy ví dụ cho bài viết này, mình sẽ hiện thực một Spring MVC project dựa trên project template của Spring Tool Suite 3, trong bài viết về Tạo ứng dụng web sử dụng Spring bằng Spring Legacy Project trong Spring Tool Suite 3. Nói cho các bạn hiểu thì Spring MVC project template của Spring Tool Suite 3 đang sử dụng những version cũ của Spring và các library khác, mỗi khi tạo mới project Spring MVC sử dụng nó, mình phải chỉnh sửa lại cho phù hợp với thời điểm hiện tại.
Đầu tiên, chúng ta cập nhập tập tin pom.xml ở thư mục src/main/resources/archetype-resources của Maven Archetype project.
Mình sẽ replace bằng nội dung của tập tin pom.xml trong project spring-mvc-example ở trên, xong chỉnh sửa lại version của các library, framework sử dụng latest version.
Nội dung của tập tin pom.xml của Maven Archetype project lúc này như sau:
Maven Archetype là một tính năng của Maven, các bạn hiểu nôm na là nó cho phép chúng ta tạo nhanh một Maven project với cấu trúc đã được định nghĩa sẵn. Chúng ta chỉ cần thay đổi những giá trị như Group Id, Artifact Id hay Version theo giá trị mà chúng ta muốn mà thôi. Mình thì mình hay sử dụng các Maven Archetype định nghĩa cấu trúc của các project Spring hay Jakarta EE. Trong bài viết này, mình sẽ hướng dẫn các bạn cách hiện thực một Maven archetype để nếu các bạn có ý định hiện thực một Maven Archetype cho riêng mình thì có thể dựa vào hướng dẫn của mình mà làm nhé!
Điều đầu tiên, mình cần nói với các bạn là Maven Archetype cũng là một Maven project nhưng packaging của nó không phải là jar, war hay là pom mà có giá trị là “maven-archetype”. Các bạn có thể sử dụng command line hoặc một Java IDE nào đó có hỗ trợ Maven project để generate Maven Archetype project đều được.
Tạo mới Maven Archetype project
Trong bài viết này, mình sẽ sử dụng Eclipse IDE để làm việc với Maven Archetype project.
Mình sẽ tạo mới một Maven project sử dụng một Maven Archetype của Maven để generate Maven Archetype project
Maven Archetype này có tên là maven-archetype-archetype:
Khai báo thông tin project:
Kết quả:
Các tập tin, thư mục nằm trong thư mục src/main/resources/archetype-resources sẽ nằm trong project mà chúng ta generate từ Maven Archetype project. Ví dụ, nếu bây giờ, các bạn chạy “mvn clean install” cho project này (các bạn nên sử dụng command line để chạy, chạy trong Eclipse có thể sẽ có issue liên quan đến “${maven.home} is not specified as a directory”) của Maven plugin, sau đó vào thư mục target/test-classes/projects/id-basic/project, các bạn sẽ thấy một project mới được generate từ Maven Archetype project của chúng ta:
Import Maven project này sử dụng một IDE khác như IntelliJ, các bạn sẽ thấy kết quả như sau:
Bây giờ, chúng ta sẽ thử hiện thực Maven Archetype project theo ý của mình nhé!
Hiện thực Maven Archetype project
Để lấy ví dụ cho bài viết này, mình sẽ hiện thực một Spring MVC project dựa trên project template của Spring Tool Suite 3, trong bài viết về Tạo ứng dụng web sử dụng Spring bằng Spring Legacy Project trong Spring Tool Suite 3. Nói cho các bạn hiểu thì Spring MVC project template của Spring Tool Suite 3 đang sử dụng những version cũ của Spring và các library khác, mỗi khi tạo mới project Spring MVC sử dụng nó, mình phải chỉnh sửa lại cho phù hợp với thời điểm hiện tại.
Đầu tiên, chúng ta cập nhập tập tin pom.xml ở thư mục src/main/resources/archetype-resources của Maven Archetype project.
Mình sẽ replace bằng nội dung của tập tin pom.xml trong project spring-mvc-example ở trên, xong chỉnh sửa lại version của các library, framework sử dụng latest version.
Nội dung của tập tin pom.xml của Maven Archetype project lúc này như sau:
Vấn đề chúng ta cần sửa để cho người dùng khi sử dụng có thể generate groupId, artifactId, version theo nhu cầu của họ là thay đổi cấu hình groupId, artifactId, version trong tập tin pom.xml này.
Chúng ta sẽ định nghĩa 3 properties là ${groupId}, ${artifactId}, ${version} rồi thay thế groupId, artifactId, version trong tập tin pom.xml bằng những properties này, như sau:
Giá trị của các properties này sẽ được người dùng nhập lúc generate project của họ từ Maven Archetype project của chúng ta các bạn nhé.
Tiếp theo, chúng ta sẽ copy class HomeController, package com.huongdanjava.springmvc trong project spring-mvc-example, bỏ vào thư mục src/main/resources/archetype-resources/src/main/java của Maven Archetype project.
Khi generate project sử dụng Maven Archetype, người dùng có thể đặt package name theo tên họ muốn. Câu hỏi đặt ra là làm sao Maven Archetype project của chúng ta có thể generate đúng package mà người dùng muốn. Solution ở đây là chúng ta sẽ khai báo sử dụng properties ${package} để làm điều này.
Ví dụ với class HomeController thì sau khi copy, mình sẽ sửa dòng code khai báo package như sau:
package $package;
import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
/**
* Handles requests for the application home page.
*/
@Controller
public class HomeController {
private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
/**
* Simply selects the home view to render by returning its name.
*/
@RequestMapping(value = "/", method = RequestMethod.GET)
public String home(Locale locale, Model model) {
logger.info("Welcome home! The client locale is {}.", locale);
Date date = new Date();
DateFormat dateFormat =
DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
String formattedDate = dateFormat.format(date);
model.addAttribute("serverTime", formattedDate);
return "home";
}
}
Nếu Maven Archetype project của các bạn có những sub-package nữa, ví dụ như trong project spring-mvc-example của mình, có thêm một package là com.huongdanjava.mvc.test, thì class nằm trong package com.huongdanjava.mvc.test này, cần khai báo dòng code package như sau:
package ${package}.test;
Trong Maven Archetype project ví dụ của mình, class App không cần thiết nữa nên mình sẽ xoá nó đi.
Đối với tập tin log4j.xml trong thư mục src/main/resources thì mình sẽ tạo mới thư mục resouces trong thư mục src/main/resources/archetype-resources/src/main của Maven Archetype project, để copy tập tin này qua.
Để copy các tập tin thư mục trong thư mục webapp của project spring-mvc-example, mình cũng sẽ tạo mới thư mục webapp trong thư mục src/main/resources/archetype-resources/src/main của Maven Archetype project.
Trong thư mục src/main/resources/archetype-resources/src/main/webapp/spring/appServlet có tập tin servlet-context.xml, có khai báo một cấu hình về component-scan của Spring framework, base-package liên quan đến project mà người dùng sẽ generate nên mình sẽ sửa lại sử dụng propery ${package} như sau:
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
<!-- Enables the Spring MVC @Controller programming model -->
<annotation-driven />
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the
${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />
<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views
directory -->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
<context:component-scan base-package="${package}" />
</beans:beans>
Class AppTest trong thư mục src/main/resources/archetype-resources/src/test/java không cần nữa, các bạn có thể remove nó đi nhé.
Sau khi đã có những resource cần thiết cho Maven project sẽ được generate, các bạn cần cập nhập tập tin archetype-metadata.xml nằm trong thư mục src/main/resources/META-INF/maven.
Tập tin này dùng để định nghĩa các tập tin, thư mục sẽ được generate thành project mà người dùng muốn. Mặc định thì nội dung của tập tin này như sau:
Các bạn để ý là khi khai báo cho thư mục webapp, mình không khai báo attribute “package=true” trong tag <fileSet>, để Maven Archetype không để thư mục này trong một package.
Đến đây thì chúng ta đã hoàn thành việc hiện thực một Maven Archetype project rồi đó các bạn!
Các bạn có thể chạy lại “mvn clean install” rồi refresh lại project đã import trong IDE như mình ở trên, các bạn sẽ thấy kết quả giống mình như sau:
One more thing, các bạn sẽ tự hỏi là groupId, artifactId và version của generated project trong ví dụ của mình lấy ở đâu? Nó nằm trong tập tin archetype.properties ở thư mục src/test/resources/projects/it-basic đó các bạn! Nội dung của tập tin này như sau:
Hôm nay, nhân tiện có task research call API bằng thằng AFNetworking bên Objective C. Lướt qua thấy một số kĩ thuật giao tiếp (Client / Server) mới. Đọc ra mới thấy có Library AFRocketClient sử dụng Server sent events (SSE), rồi thì là HTTP Polling, Long Polling. Đúng là đụng vào cái nào cũng brand new, nên có tìm hiểu đôi chút, viết bài này chia sẻ chút kiến thức nhỏ nhoi.
Do chưa bắt tay code thực tế, nên mình chỉ chú trọng vào bản chất, không có code ví dụ, mong anh em thông cảm.
1. HTTP Regular – Kiểu truyền thống (anh hỏi thì em thưa).
Đối với HTTP kiểu truyền thống, khi anh (client) đưa ra câu hỏi, yêu cầu có thể “ấy” một cái được không?. Nếu em đồng ý, lập tức trả lời CÓ, ngược lại thì nói là KHÔNG. Chả hề chần chừ suy nghĩ.
Vấn đề đối với kiểu truyền thống này là hai chữ lập tức. Thời nay đã hiện đại rồi, vừa mới 8h02 client (anh) gửi request cho em (server) thì sau 2 mi li se cần ba má server (em) gửi request với nội dung đồng ý.
Vậy là chỉ tại 2 mi li se cần mà client (anh) lại nhận được câu trả lời là “éo”.
Thiệt tình là cay cú vl, từ đó kỹ thuật HTTP Polling ra đời. Mục đích nhằm gia tăng khả năng kết đôi, giúp tăng tỉ lệ sinh, giảm tỉ lệ tử, … lạc đề
2. HTTP Polling – Kiểu siêng năng (cứ sau 5 phút lại hỏi, bất kể em có đồng ý không, hết 5 phút lại hỏi).
Chính vì kiểu regular hỏi phát bị từ chối luôn, nên Polling ra đời. Siêng năng cần cù gửi request sau một thời gian nhất định, vấn đề bất kể phản hồi (response) có dữ liệu hay không?. Cụ thể ra là kệ em có trả lời có hay là không?. Nếu ỉm (timeout) thì cứ 5 phút anh vẫn hỏi 1 lần (đẹp trai không bằng chai mặt)
Chính vì nguyên nhân đó, kĩ thuật này sẽ gây lãng phí lớn, tiêu chí realtime cũng không thật sự ổn định. Chính vì cái thái độ chày cối bất cần này, kĩ thuật HTTP Long Polling ra đời.
Hỗ trợ: Kĩ thuật này hoạt động ở tất cả browser có Javascript được bật.
Lưu ý: Kỹ thuật này là loại kĩ thuật gây lãng phí lớn, nếu thời gian giữa mỗi lần gửi request quá ít, gánh nặng về băng thông và xử lí request sẽ dồn nặng lên server. Ngay lúc này, một cuộc tấn công DDos bùng phát, đảm bảo server sẽ quá tải và chết bất đắc kì tử. Vì vậy, nếu không cần thiết, nên thận trọng khi sử dụng HTTP Polling
3. HTTP Long Polling – Kiểu chai mặt (anh hỏi nhưng phải chờ em hỏi ba má mới trả lời anh được).
Mới nhìn sơ thì phương thức này đập vào mặt là một chữ Long, vấn đề là cái gì Long (pen!s thì khỏi nói :v). Đáng buồn thay, kỹ thuật này lại nhấn mạnh vào thời gian chờ đợi dài.
Vậy kĩ thuật này hoạt động như thế nào?
Nhìn chung, client (anh) sẽ gửi request (yêu cầu) liên tục lặp lại giữa các khoảng thời gian dài (long). Hình dung ra theo 4 bước dưới đây:
Bước 1: Send request – anh hỏi em cho anh “ấy” cái được không?
Bước 2: Server event – em mở một luồng suy nghĩ (idle event – khoảng chờ), chờ sự hiện phản hồi từ một client khác (ba má). Vấn đề là anh (client) không thể chờ em cả đời -> Next step.
Bước 3: Nếu hết thời gian chờ, ba má chưa có câu trả lời thì em (server) vẫn phản hồi cho anh kết quả là “đéo”.
Bước 4: Send request again – sau khi nhận được câu trả lời (dù là yes hay no) thì anh (client) vẫn tiếp tục gửi lại request)
Bảng so sánh độ trễ và tốc độ load giữa Polling và Long Polling
Khi nào thì nên sử dụng kiểu chai mặt (HTTP Polling)?
So với kiểu truyền thống, kĩ thuật này mang màu sắc chai mặt (gửi request hoài hoài), nhưng cũng không phải là không có ưu điểm. Trường hợp user (ba má client) chỉ có mỗi một mụn con, đã gần đất xa trời, luôn mong ngóng có đứa nào đó chấp nhận cái request của con trai rồi mới nhắm mắt xuôi tay thì kĩ thuật này nên được áp dụng. Ưu điểm của HTTP Long polling là nó đáp ứng Realtime (thời gian thực), với độ trễ (Latency) gần như bằng Zero (0). Khi em trả lời là có, ngay lập tức anh (client) có câu trả lời sau 0 mi li se cần, sau đó ba má anh cũng biết, có thể thanh thản ra đi.
Nghiêm túc lại thì HTTP Polling sẽ cung cấp một API ổn định, mức độ phản hồi khi có thông tin mới rất nhanh, đáp ứng tiêu chí realtime.
Lưu ý: một nhược điểm tương đối cố hữu đối với HTTP Polling là chiếm băng thông (bandwidth), vì vậy cần phải cân nhắc chu kì gửi request không nên diễn ra quá nhanh.
Con nào mà cứ 2 phút lại hỏi “cho anh ấy một cái”, nó lại chả block
4. Server Sent Events – Kiểu dồn dập (anh hỏi một lần, em trả lời liên tục, chắc em cũng thích “ấy” ) .
Kỹ thuật này nhìn chung là giống HTTP Polling. Tuy nhiên có đôi chút khác biệt ở chỗ, client (anh) chỉ hỏi có một lần (kết nối chỉ mở một lần duy nhất), sau đó em (server) do quá hăng hái, nhiệt tình, nên cứ 3s em lại trả lời một lần rằng “ba má em chưa chịu”. Việc giao tiếp này gần như là một chiều (one way comminucation). Chiều từ server tới client.
Mới đầu đọc tới đây, mình cũng như anh em, đều phát sinh ý nghĩ rằng sao lại có cái kỹ thuật kết nối dở người kiểu này?.
Mục đích nó sinh ra là gì?
Sau một hồi research hăng hái, cuối cùng mình cũng có câu trả lời. Thực sự thì SSE (Server sent events) lại thật sự hữu ích đối với các yêu cầu dữ liệu phản hồi real time liên tục. Ví dụ như ứng dụng xem vị trí máy bay, ta chỉ gửi request xem lộ trình của máy bay A380 một lần, sau đó, server sẽ liên tục trả về tọa độ (latitude, longitude) của máy bay.
5. Kết luận
Túm cái quần lại, bài viết này cho các bạn một cái nhìn khách quan, vui vẻ về một số kỹ thuật mới (chắc có khi chỉ mới đối với mình ) sử dụng trong giao tiếp giữa client và server. Tuy nhiên, còn một thiếu sót nhỏ là chưa đề cập tới Websocket. Thời gian tới, mình sẽ viết riêng một bài mới về Websocket và so sánh giữa Websocket và SSE (Server sent events).
Cảm ơn các bạn đã đọc bài của mình, nếu bài viết của sai sót về nội dung, các bạn có thể comment phía dưới.
Thiết Kế Đồ Họa Và Những Tư Chất Cần Thiết Của Một Nhà Thiết Kế Đồ Họa
Thiết kế đồ họa là một trong những ngành nghề đã nằm trong top các công việc hấp dẫn nhân sự cũng như có thu nhập cao hiện nay. Tuy nhiên, có phải bất cứ ai cũng phù hợp với ngành nghề này hay học thiết kế đồ họa cần những gì khác nữa? Bài viết dưới đây sẽ phần nào giúp bạn giải tỏa những thắc mắc xoay quanh ngành thiết kế đồ họa nhé!
Thiết kế đồ họa và các vấn đề liên quan
Tại sao ngành thiết kế đồ họa trở nên quan trọng trong cuộc sống ngày nay?
Không quá khó để bạn bắt gặp rất nhiều hình ảnh khác nhau xuất hiện trong tầm mắt mỗi ngày. Trên đường đi làm, đi học, trên xe bus, trên các tòa nhà, các biển quảng cáo,… luôn có sự xuất hiện dày đặc của các hình ảnh mang tính chất giới thiệu, quảng cáo và truyền tải thông điệp. Một nội dung hay để nhanh chóng tiếp cận khách hàng luôn cần có những hình ảnh đẹp. Một hình ảnh sản phẩm tốt, một hình ảnh nắm bắt đúng tâm lí khách hàng với các thông tin cần, luôn là yếu tố quan trọng để giữ chân người đọc tìm hiểu thêm về nội dung sản phẩm.
Thêm vào đó, thiết kế đồ họa muốn thành công không chỉ đáp ứng được đúng nội dung truyền tải mà còn phải có tính thẩm mỹ cao. Vậy nên không khó hiểu khi tính thẩm mỹ cũng như màu sắc được yêu cầu rất cao với nhà thiết kế đồ họa – graphic designer. Một bức ảnh đẹp không chỉ truyền tải được ý nghĩa sản phẩm mà còn làm nổi bật được hình ảnh của công ty. Thông qua hình ảnh, người xem có thể dễ dàng nhận ra đây là màu sắc, là cá tính, là tiếng nói, là nội dung của công ty. Đó chính là thành công của đội ngũ thiết kế đồ họa.
Bên cạnh hình ảnh, thiết kế đồ họa còn có thể đảm nhận cả công việc thiết kế hình ảnh cho website, xây dựng landing page bắt mắt và thu hút người xem. Một landing page thu hút và dễ dàng sử dụng chắc chắn sẽ giúp khách hàng ở lại trên website lâu hơn và kích cầu mua sắm, sử dụng dịch vụ nhiều hơn. Làm được điều này chính là thành công của một nhà thiết kế đồ họa.
Học thiết kế đồ họa cần những gì?
Vậy để làm tốt trong ngành thiết kế đồ họa, bạn sẽ cần chuẩn bị những gì?
Một tinh thần và động lực luôn sẵn sàng cho việc học hỏi
Để trở nên thăng hoa trong công việc sau này, con đường học hỏi và theo đuổi sự nghiệp khi vừa mới bắt đầu của các nhà thiết kế đồ họa thực sự không dễ dàng. Bạn sẽ phải đối mặt với việc sáng tạo ý tưởng một cách liên tục mà không tạo sự nhàm chán, bạn phải xử lý và làm việc với nhiều phòng ban khác nhau để hoàn tất thông tin cần thiết cho công việc của mình.
Và còn vô vàn vấn đề khác mà bạn sẽ gặp phải trong suốt quá trình làm việc của mình. Ngoài ra, một nhà thiết kế đồ họa cũng cần liên tục tự học, tự trau dồi kiến thức cho mình để sáng tạo ra những hình ảnh không chỉ đẹp mà còn mới mẻ và bắt kịp xu hướng. Do đó, hãy chuẩn bị cho mình một tâm lí và động lực sẵn sàng đối diện với mọi khó khăn và chông gai trong công việc. Không ngại dành thời giờ để học hỏi và trau dồi liên tục chính là chìa khóa cho sự thành công.
Động lực mạnh mẽ là một trong những yếu tố quan trọng của các nhà thiết kế đồ họa
Chấp nhận làm việc nhiều hơn so với mức 8 tiếng một ngày
Như đã chia sẻ ở bên trên, công việc mà một nhà thiết kế đồ họa phải làm việc mỗi ngày là rất nhiều, do đó đừng mong chờ tìm được một công việc chỉ làm đúng 8 tiếng mỗi ngày nếu bạn theo đuổi nghiệp đồ họa. Thời gian làm việc của một nhà thiết kế đồ họa thật ra không luôn luôn gắn liền với làm thêm giờ, nếu bạn biết cách sắp xếp công việc cũng như tần suất hình ảnh phải làm mỗi ngày sẽ quyết định đến thời gian mà bạn làm việc.
Đặc biệt, với những lúc cần phải hoàn thành kịp thời hạn, việc chạy quá nhiều ý tưởng có thể khiến bạn trở nên khó khăn trong việc sáng tạo ra những hình ảnh, bố cục mới. Thậm chí, với những dự án lớn, bạn sẽ phải “căng mình” hoàn toàn để đáp ứng kịp công việc và hình ảnh đồ họa phải bàn giao mỗi ngày cho các team khác làm việc. Có một “tinh thần thép” trước áp lực trong công việc là điều cần thiết với các nhà thiết kế đồ họa.
Lựa chọn chuyên môn phù hợp với năng lực và sở thích bản thân
Không chỉ với thiết kế đồ họa mà với bất kì ngành nghề nào cũng thế, ngành nghề thì rất rộng nhưng chuyên môn sẽ khác nhau, vậy nên xác định rõ ràng lĩnh vực mình muốn làm việc sẽ giúp đỡ rất nhiều trong quá trình làm việc của bạn. Để trở thành thật sự giỏi trong lĩnh vực mà mình theo đuổi, bạn cần tìm ra xem đâu là điều mình mong muốn để dành thời gian nhiều hơn cho việc học hỏi và trau dồi.
Thiết kế đồ họa nói chung là một lĩnh vực rộng lớn và đa dạng các lĩnh vực chuyên môn khác nhau như: thiết kế web, thiết kế đồ họa chuyển động, thiết kế hình ảnh tạp chí, bìa sách, thiết kế hình ảnh quảng cáo,… Mỗi lĩnh vực khác nhau sẽ đòi hỏi những kiến thức, kỹ năng khác nhau, do đó đừng nên vội vàng trong việc lựa chọn mà bạn có thể thử qua tất cả các lĩnh vực này để xem đâu mới là chuyên môn mình thật sự yêu thích và có thể làm tốt. Lắng nghe ý kiến từ người khác cũng là một ý kiến hay ho mà bạn có thể lựa chọn.
Mỗi ngành nghề đều có những đòi hỏi riêng và yêu cầu riêng cho người trong ngành. Hãy làm hết sức của bản thân để thật sự đạt được những điều mà mình mong muốn. Hi vọng bài viết này đã mang đến cho người đọc một cái nhìn tổng quan về ngành thiết kế đồ họa cũng như việc học thiết kế đồ họa cần những gì. Đón đọc nhiều bài viết hấp dẫn khác cùng TopDev bạn nhé!
Lương lập trình viên có thể đạt 100 triệu/tháng: Tin được không?
Bài viết được sự cho phép của blogchiasekienthuc.com
Chào các bạn, đối với anh em làm trong giới lập trình thì mình tin chắc một điều là đã có không ít lần anh em nghe kể về những người có mức lương khủng.
Ở đây mình đang nói đến những người làm thuần về kỹ thuật, chứ không nói đến các vị trí cấp quản lý cao hơn. Vì nếu đã lên các vị trí cấp quản lý thì kiểu gì lương cũng cao rồi !
Và tất nhiên, còn một điều nữa là mình chỉ chia sẻ về ngành IT thôi, các ngành khác có thể sẽ có mức thu nhập cao hơn hoặc thấp hơn, cái này nếu thích thì các bạn tự tìm hiểu thêm nhé
Mình biết là mỗi ngành nghề thì đều có những đặc thù riêng và đặc thù đó quyết định ít nhiều tính chất của công việc.
Đối với ngành IT, mà cụ thể hơn là các lập trình viên thì đặc thù công việc chính là sự tư duy. Tư duy trong giải quyết vấn đề, tư duy trong xây dựng phát triển sản phẩm…
Chính vì công việc đòi hỏi phải suy nghĩ nhiều, mặc dù không nặng về chân tay nhưng nhiều khi anh em lập trình viên chúng ta sẽ cảm thấy cực kỳ stress và áp lực, mình tin là ai trong ngành này cũng vậy cả thôi !
Không phải ai cũng có thể chịu được áp lực của ngành lập trình này trong nhiều năm liền, chứ chưa muốn nói là làm được việc hay không.
Và chính vì đặc thù đó mà để đào tạo hoặc tuyển được một lập trình viên “cứng”, có thể làm ĐƯỢC VIỆC thì thực sự không phải là dễ.
Khái niệm OT (Overtime) gần như cũng được xuất phát từ các công ty công nghệ, khi mà khối lượng công việc quá nhiều nếu không làm thêm giờ thì không thể xong được.
Với đặc thù công việc áp lực là như vậy, thử hỏi nếu mức lương không tương xứng thì liệu có ai chấp nhận đánh đổi để làm hay không?
Đây là sự thật và là minh chứng rõ nhất cho câu nói làm bao nhiêu hưởng bấy nhiêu. Không có chuyện làm thì lười mà vẫn có ăn đâu nhé các bạn.
Nói về áp lực của anh em lập trình viên thì mình đã từng có một bài viết riêng về chủ đề này rồi, các bạn có thể tham khảo lại bài viết này để biết thêm về những áp lực đó: Những áp lực khi HỌC và LÀM IT [Lập Trình Viên]
Vậy áp lực thì liên quan gì đến việc lương cao hay thấp? Cá nhân mình thấy thì hầu như những công việc với mức thu nhập ổn thì đều áp lực cả.
Làm IT cũng tùy dự án, tùy công ty mà áp lực công việc là cao hay thấp. Nhưng có một điều chắc chắn là nếu bạn làm IT mà chịu được áp lực thì khi đó, mức lương của bạn không thể thấp được.
Tại sao mình lại có sự so sánh như vậy, bởi thực tế nhiều người chịu được áp lực nhưng lương đâu có cao đâu?
Nói đến đây thì mình lại phải tiếp tục chia nó ra làm 2 đối tượng, đó là: Người chịu được áp lực và người phải chịu áp lực.
Người chịu được áp lực là người biết biến áp lực công việc thành động lực, biết biến khó khăn thành cơ hội để tự nâng cao giá trị bản thân.
Ngược lại, người phải chịu áp lực là những người làm các công việc bản thân không mấy yêu thích nhưng vẫn phải làm. Họ quen với áp lực và đôi khi “thờ ơ” hoặc “miễn nhiễm” với áp lực. Dù công việc đó có vội đến đâu họ vẫn thảnh thơi làm.
Và tất nhiên, là một lập trình viên, nếu người nào chịu được áp lực tốt thì người đó ắt sẽ có mức lương tương xứng với trí tuệ và công sức mà họ bỏ ra.
#3. Xu hướng
Nếu các bạn để ý thì trong những năm trở lại đây, do sự phát triển của cuộc cách mạng công nghiệp 4.0 thì các ngành học liên quan đến kỹ thuật, công nghệ cao đang rất được quan tâm.
Song song với đó là số lượng các công việc liên quan đến các lĩnh vực này cũng tăng lên rất nhiều và đòi hỏi một đội ngũ nhân lực đủ tiêu chuẩn để đáp ứng được công việc.
Chúng ta có thể liên hệ một chút sang thị trường hàng hóa. Nếu nói một cách thẳng thắn thì sức lao động cũng là một dạng hàng hóa.
Mà đã là hàng hóa thì chắc chắn phải buôn bán được và nếu loại hàng hóa đó càng quý hiếm, càng khó để có được thì nó càng đắt.
Đến đây chắc các bạn có thể hình dung được là tại sao lương của lập trình viên thường cao hơn một số ngành khác rồi đúng không.
Đặc biệt là các bạn sinh viên có khả năng kỹ thuật tốt thì việc đạt mức lương 20-25 triệu/tháng là hoàn toàn có thể, chứ chưa muốn nói là có nhiều bạn giỏi đặc biệt thì con số này còn cao hơn rất nhiều lần.
Có thể lương của lập trình viên nói riêng và của các bạn làm về công nghệ nói chung cao hơn mặt bằng chung một phần cũng phần do ảnh hưởng của xu hướng thị trường việc làm.
#4. Nhu cầu từ thị trường
Thị trường mà mình muốn nói đến ở đây là thị trường lao động, đặc biệt là thị trường lao động với hàm lượng chất xám cao.
Mà đại diện tiêu biểu ở đây là những người làm trong giới lập trình, là các lập trình viên, kỹ sư phần mềm, chuyên viên hệ thống…
Chúng ta đều biết rằng, quy luật cung cầu của thị trường đó là: Nếu cung mà nhỏ hơn cầu thì giá trị mặt hàng sẽ bị tăng lên, hay nói cách khác là hàng hóa đó sẽ tăng giá.
Nói vậy để chúng ta hiểu rằng, nhu cầu thị trường về nguồn nhân lực chất lượng cao trong các lĩnh vực công nghệ đang tăng lên rất nhanh.
Trong khi các nguồn cung chất lượng thì lại rất ít và hầu như không đủ tiêu chuẩn. Rất nhiều trường đại học mở ra các ngành, chuyên ngành đào tạo nhân lực trong lĩnh vực công nghệ nhưng nhìn chung chất lượng không thực sự tốt.
Chính vì vậy, các lập trình viên nói riêng hay các kỹ sư làm trong lĩnh vực công nghệ thông tin nói chung mà có kinh nghiệm, kiến thức thì thực sự mức lương của họ là rất đáng mơ ước nếu ở Việt Nam. Và đó cũng là lý do mà nhiều người nói rằng thừa thầy thiếu thợ là như vậy !
#5. Chất lượng nhân sự
Chất lượng nhân sự đã được mình nhắc đến trong ý bên trên khi nói về nhu cầu thị trường. Vậy chất lượng nhân sự ảnh hưởng gì tới thu nhập của một người làm công nghệ, mà đại diện ở đây là các lập trình viên (dev)?
Thực tế thì Việt Nam xuất phát điểm là một quốc gia hàng đầu về Outsourcing, tức là một quốc gia chuyên đi “gia công phần mềm” cho các khách hàng từ nước ngoài (đặc biệt là thị trường Nhật).
Chúng ta sẽ không đánh giá việc gia công phần mềm là nên hay không nên, tốt hay không tốt khi muốn thúc đẩy sự phát triển về công nghệ của nước nhà.
Nhưng có một sự thật mà chúng ta phải thừa nhận, đó là hiện nay hầu hết các bạn sinh viên được đào tạo dù là cấp đại học hay cao đẳng thì các bạn vẫn mang cái tư duy đi làm thuê nhiều hơn là làm chủ.
Mà khi chấp nhận làm thuê thì chúng ta sẽ tự động hạ thấp chất lượng của mình xuống, không muốn cải thiện và không có ý chí thăng tiến mạnh mẽ.
Và chính cái tư duy đó sinh ra hệ lụy đó là chất lượng nhân sự không cao một cách đồng đều. Nếu các bạn để ý, nhiều bạn sinh viên mới ra trường làm lập trình viên nhưng chỉ được khoảng 4-6 triệu.
Có thể nói chất lượng nhân sự trong lĩnh vực công nghệ là một trong những lĩnh vực có chất lượng không đồng đều nhất tại Việt Nam.
Có những người rất giỏi với mức lương cực “khủng”, nhưng cũng có những người mức lương chỉ đủ chi tiêu sinh hoạt cơ bản là hết.
#6. Kết luận
Kết thúc bài viết này mình muốn khẳng định là nếu bạn là một lập trình viên bình thường, đặc biệt là lại chỉ làm việc ở Việt Nam thì rất khó mà đạt được mức lương 100 triệu/tháng.
Nhưng ngược lại, nếu bạn có khả năng kỹ thuật tốt, là người giỏi chịu được áp lực và ham học hỏi thì mình tin chắc một điều là các bạn cũng có cơ hội với mức lương 100 triệu/tháng. Hẹn gặp lại các bạn trong các bài viết tiếp theo nhé.
Trung Hoa quốc, Toàn chân giáo, 12/06/2018. Http Methods – bá chủ võ lâm.
Giáo chủ phái toàn chân Vương Trùng Dương, trong khẩu quyết truyền cho môn đệ có đoạn viết:
Các con, nay ta đã nghĩ ra “Thất tinh bắc đẩu trận là siêu cực trận đồ, để HTTPMethods có thể hùng cứ bốn phương trong làng IT, 7 người các con phải tuyệt đối kiên trì luyện tập, nắm vững bản chất của các vì tinh tú này.
GET, POST, PUT, HEAD, DELETE, PATCH, OPTIONS đều nhất mực nghe lời sư phụ, cố gắng tu luyện, cuối cùng đã thành 7 vì sao sáng, soi chiếu và bảo vệ HTTP Methods.
Bảy methods này phối hợp với nhau lập thành “THẤT TINH BẮC ĐẨU TRẬN” trận. Trận pháp này là xương sống cho RESTFul API. Nhờ trận pháp này mà phái RESFUL API đã bá chủ võ lâm, hùng cường thiên hạ.
Thất tinh bắc đẩu trận – hội chiếu phò trợ HTTP Methods.
Hãy cùng Kieblog tìm hiểu từng vị tinh tú trong bộ thất tinh này nhé.
1. Tứ hành xung, ý lộn, TỨ ĐẠI CÔNG PHU
Mỗi vị học trò của Vương Trùng Dương đều cố gắng rèn cho mình được thành tựu bốn loại công phu. Tuy nhiên, do tư chất mỗi người khác nhau, nên có người thành tựu, có người thất bại. Bốn loại công phu mà mỗi methods trong HTTPMethods được đem ra đánh giá là:
SAFE (Độ an toàn).
IDEMPOTENT (Tính bất biến).
VISIBILITY (Tính che giấu thông tin).
CACHEABLE (có thể cache được).
Bảng so sánh 4 tính chất của các methods trong HTTP Methods.
1.1 SAFE
ĐỊNH NGHĨA: Một request trong http methods được xem là safe khi sau rất nhiều lần gọi, nó vẫn không làm thay đổi resource mà nó đang truy cập đến.
1.2 IDEMPOTENT
ĐỊNH NGHĨA: Một request được xem là idempotent nếu sau nhiều lần gọi, nó vẫn trả về kết quả như nhau.
Để dễ hình dung, ta có biến i khai báo bằng 100 và biến i tăng 1.
int i = 100; // idempotent
i++; // not idempotent
Thao tác gán đầu tiên được hiểu là idempotent, vì cho dù ta thực hiện câu lệnh này bao nhiêu lần, giá trị của i cũng vẫn chỉ là 100. Ngược lại, khi giá trị i++, mỗi lần gọi sẽ tăng giá trị i lên 1. Vì vậy, i không là idempotent.
Understand result as the state of the resource on the server (and bear in mind that status codes are not relevant from the idempotency point of view).
Hãy chú rằng kết quả ở đây là trạng thái của nguồn dữ liệu trên server (lưu ý rằng các mã trạng thái (200,400,403,…) ở đây không liên quan tới tính ổn định).
1.3 VISIBILITY
ĐỊNH NGHĨA: Một request trong http methods được xem là visibility khi nó không để lộ ra thông tin trên URL khi request được gửi.
Cần lưu ý rằng visibility ở đây chỉ giới hạn ở URL (phần người dùng có thể nhìn thấy được).
1.4 CACHEABLE
ĐỊNH NGHĨA: Một request được xem là cacheable khi sau lần gửi thứ nhất của request, kết quả phản hồi có thể được lưu vào một trong các loại cache trên websites (localStorage, cookies, …).
Sơ đồ mô tả cách thức cache thông tin trên client browser
2. Thất tinh lộ diện – Http methods
2.1 GET
GET requests are the most common and widely used methods in HTTP methods and websites. Simply put, the GET method is used to retreive data from a server at the specified resource.
GET là phương thức phổ biến nhất và được sử dụng rộng rãi nhất trong HTTP methods và websites. Nói một cách đơn giản, GET là phương thức được sử dụng để truy xuất dữ liệu từ server ở một tài nguyên rõ ràng đã được chỉ định.
2.1.1 Safe – YES
Tất nhiên rồi, phương thức GET chỉ lấy, yêu cầu và truy xuất dữ liệu nên nó được xem là method an toàn nhất. Tuy nhiên, an toàn ở đây được hiểu rằng phương thức GET không làm thay đổi resources mà nó gọi tới.
Không nên nhầm lẫn tính an toàn này với việc xác thực API.
Nếu phương thức GET này cung cấp thông tin (user, password của admin) thì nó không được xem là an toàn. Vấn đề này sẽ được nói rõ hơn ở một bài viết khác về API attack.
2.1.2 Idempotent – YES
GET method luôn là idempotent, bởi vì cho dù ta có gọi hàng ngần method này tới Server thì cũng không làm thay đổi resource của nó. Chính vì lẽ này, GET luôn được đánh giá là method an toàn nhất trong 7 loại của htttp methods.
2.1.3 Visibility – NO
Khi nói tới tính che giấu thông tin khi thực hiện method. Phương thức GET không thực sự tốt, các parameter được nhìn thấy rõ trên URL. Điều này cũng đồng nghĩa với việc các param này được lưu lại trong lịch sử. Những ai tò mò muốn thay đổi cũng có thể dễ dàng thực hiện (không cần lập trình viên chuyên nghiệp – chỉ chỉnh sửa trên URL gọi tới server)
Method GET với từ khóa tìm kiếm là trump.Method GET với request chuyển tới trang số 5 (page 5).
2.1.4 Cacheable – YES
Vì method GET đơn thuần là dể lấy dữ liệu, nên khi đã lấy xong, ta có thể cache những giá trị này lại. Việc lưu trữ có thể là (Local Storage, Cookies, …)
2.2 POST
POST: Submits data to be processed to a specified resource.
POST: Gửi data lên server để xử lí ở một tài nguyên cố định.
2.2.1 Safe – NO
Suy nghĩ một tí, nếu người viết web service cho API không quản lí tốt cách thức xác thực người dùng được thực hiện method POST. Một lập trình viên có thể dễ dàng tạo các parameter fake. Sau đó gửi tới server, các hình thức tấn công đã được biết tới trước đây như là Cross-Site Request Forgery
2.2.2 Idempotent – NO
Methods POST là method được sử dụng rất nhiều trong Http Methods. Tuy nhiên, tính idempotent của methods POST lại rất khó để đảm bảo. Nếu một POST được gọi để khởi tạo folder, ở lần đầu tiên -> folder được tạo. Ở lần gọi thứ 2 -> thất bại -> do folder đã được tạo.
Ngày nay, xu hướng thiết kế API càng ngày càng chú ý tới tính idempotent của các method. POST cũng không là một ngoại lệ.
2.2.3 Visibility – YES
Các tham số được gửi lên sử dụng method post sẽ không để lộ ra trên URL.
2.2.4 Cacheable – NO
Phương thức POST không thể được cache lại. Mọi xử lí của chúng ta mong muốn về method cache đều được xử lí ở server. Chính vì vậy, không thể cache lại bất cứ giá trị gì ở phía client khi ta gọi method POST.
2.3 PUT
Used to create a resource, or overwrite it.
Method PUT được sử dụng để tạo tài nguyên, hoặc ghi đè nó.
2.3.1 Safe – NO
Do method PUT thực hiện cập nhật trạng thái tài nguyên. Nên nó được đánh giá là không an toàn.
2.3.2 Idempotent – YES
PUT APIs are used to update the resource state. If you invoke a PUT API N times, the very first request will update the resource; then rest N-1 requests will just overwrite the same resource state again and again – effectively not changing anything.
PUT sử dụng để cập nhật trạng thái của tài nguyên. Nên nếu ta gọi method PUT n lần, lần đầu tiên sẽ cập nhật trạng thái tài nguyên. Tiếp đến, N – 1 request tiếp theo sẽ thực hiện lặp đi lặp lại – không thay đổi gì.
2.3.3 Visibility – YES | Cacheable – NO
Method PUT giống với method POST ở 2 tính chất này. Nó ẩn đi các parameter gửi đi ở URL – Do không lấy dữ liệu gì ở server nên không thể cache lại các kết quả đã lấy được.
2.4 HEAD
The HTTP HEAD method requests the headers that are returned if the specified resource would be requested with an HTTP GET method.
HEAD method sẽ trả về nội dung headers nếu tài nguyên được chỉ định gọi tới có thể lấy được bằng method GET.
2.4.1 Safe – YES
Chính vì method Head chỉ trả về thông tin của headers, nên nó được xem là an toàn.
2.4.2 Idempotent – YES
Tương tự như GET, method HEAD cũng được đánh giá là idempotent -> do sau n lần gọi giá trị của nó vẫn trả về không đổi.
2.4.3 Visibility – NO
Vì thông tin được lấy cũng nằm trong URL, nên tính che dấu thông tin của HEAD method là giống GET -> không được đảm bảo.
2.4.4 Cacheable – YES
Do thông tin được lấy về là headers, nên có thể cache lại các giá trị này cho các request tiếp theo. GET và HEAD methods đều có thể cache được.
2.5 DELETE
The DELETE method requests that the origin server delete the resource identified by the Request-URI.
Method DELETE sẽ xóa một tài nguyên nhất định ở server bằng Request-URI.
2.5.1 Safe – NO
Nếu như ở method GET, khi thực hiện thành công, ta nhìn thấy dữ liệu trả về thì method DELETE là không an toàn vì.
The client cannot be guaranteed that the operation has been carried out, even if the status code returned from the origin server indicates that the action has been completed successfully
Client không đảm bảo được rằng các thao tác mong muốn khi gửi method GET đã được thực hiện ở Server.
2.5.2 Idempotent – NO
Bản thân mình nghĩ rằng DELETE methods là không idempotent. Tuy nhiên, vấn đề này hiện vẫn đang có nhiều bàn cãi.
Lấy ví dụ, nếu lần đầu tiên chúng ta xóa đi 1 ảnh ở server, lần request tiếp theo sẽ cho ra kết quả 404 Not Found. Vì kết quả khác nhau ở các lần gọi request -> không là idempotent.
Tuy nhiên, nếu nói về trạng thái ở server:
The state on the server is the same after each DELETE call, but the response is different.
Trạng thái ở server sau mỗi lần gọi DELETE là giống nhau, chỉ khác giá trị trả về.
2.5.3 Visibility – YES | Cacheable – NO
Về visibility và cacheable, method DELETE giống với method POST.
2.6 PATCH
The PATCH method is used to apply partial modifications to a resource.
PATCH method được sử dụng để ghi đè các thông tin thay đổi.
2.7 OPTIONS
The HTTP OPTIONS method is used to describe the communication options for the target resource. The client can specify a URL for the OPTIONS method, or an asterisk (*) to refer to the entire server.
HTTP OPTIONS method sử dụng để mô tả tùy các options giao tiếp cho tài nguyên đích. client có thể tùy chỉnh URL cho OPTIONS methods, hoặc sử dụng dấu *, với ý nghĩa cho cả server.
Bảng so sánh mức độ an toàn của các http methods. 2 methods được đánh giá là an toàn cho server là GET và HEAD.
Trong Hibernate, chúng ta sẽ tạo một đối tượng từ một Entity (thực thể) và lưu nó vào cơ sở dữ liệu hoặc chúng ta lấy dữ liệu từ cơ sở dữ liệu. Ở đây, mỗi Entity được liên kết với lifecycle (vòng đời), chịu sự quản lý của Session. Đối tượng Entity đi qua các giai đoạn khác nhau của lifecycle. Trong bài viết này, chúng ta sẽ cùng tìm hiểu về các giai đoạn này.
Khi nói về trạng thái (state) của object trong Hibernate, chúng ta nói một đối tượng có quan hệ với Session, nghĩa là Session có tham chiếu đến đối tượng đó, hay một cách khác là chịu sự quản lý của Session. Session được coi là một loại của Persistence Context.
Quản lý các Entity
Ngoài việc map đối tượng Java đến bản ghi trong CSDL (tức là ORM), thì có một vấn đề mà Hibernate phải care đến đó là quản lý các Entity. Cái ý niệm về “persistence context” chính là giải pháp để giúp Hibernate làm được việc này. Persistence context có thể coi là một “môi trường” chứa toàn bộ các đối tượng mà ta tạo ra và lưu vào csdl trong mỗi session.
Một Session, hay là 1 phiên, là một giao dịch, có phạm vi tùy vào từng ứng dụng. Khi ta làm việc với DB thông qua một Persistence Context, mọi thực-thể sẽ gắn vào context này, mỗi bản ghi trong DB mà ta tương tác sẽ tương ứng với 1 thực thể trong context này.
Trong Hibernate, PersistenceContext được tạo ra nhờ org.hibernate.Session . Với JPA, PersistenceContext được thể hiện thông qua class javax.persistence.EntityManager. JPA là bộ đặc tả cho việc lưu dữ liệu vào DB dành cho ngôn ngữ Java, Hibernate sau này đã tuân theo bộ đặc tả đó. Khi đó nếu dùng combo JPA-Hibernate, thì Persistence Context được tạo ra bởi EntityManager interface, thực tế sẽ là một lớp bọc lấy cái Session object ở phía dưới. Nếu ta xài thẳng Session (ko xài EntityManager) thì sẽ có nhiều phương thức cho ta xài hơn, tiện dụng hơn.
Trạng thái của các Entity
Một đối tượng trong Hibernate có 1 trong 4 trạng thái:
Transient (Tạm thời): Đối tượng không có quan hệ với Session hiện tại của Hibernate. Đối tượng ở trạng thái này chưa từng gắn vào context, nó không có bản ghi tương ứng trong CSDL
Persistent (Bền vững): Đối tượng đang liên hệ với một context, tức là với một đối tượng Session và trạng thái của nó được đồng bộ với cơ sở dữ liệu khi mà ta commit cái Session.
Detached (Đã bị tách riêng ra): Đối tượng đã từng có trạng thái persistent nhưng hiện tại đã không còn giữ quan hệ với Session. Nếu nó không được attached trở lại, nó sẽ bị bộ gom rác của Java quét đi theo cơ chế thông thường. Một đối tượng đang trong session muốn đạt đươc trạng thái này thì có những cách là gọi hàm evict(), close Session hoặc làm combo thao tác: serialize/deserialize.
Removed (Đã bị xóa): tương tự như detached nhưng bản ghi tương ứng với đối tượng này trước đó đã bị xóa khỏi database.
Sơ đồ bên dưới minh hoạ các trạng thái này:
(1) Transient: Trường hợp bạn tạo mới một đối tượng java từ một Entity, đối tượng đó có tình trạng là Transient. Hibernate không biết về sự tồn tại của nó. Nó nằm ngoài sự quản lý của Hibernate.
(2) Persistent: Trường hợp bạn lấy ra đối tượng Entity bằng method get, load hoặc find, bạn có được một đối tượng nó tương ứng với 1 record dưới database. Đối tượng này có trạng thái Persistent. Nó được quản lý bởi Hibernate. Khi đối tượng ở trạng thái persistent, tất cả các thay đổi mà bạn thực hiện đối với đối tượng này sẽ được áp dụng cho các bản ghi và các trường cơ sở dữ liệu tương ứng khi flush session.
(3) Transient -> Persistent: Session gọi một trong các method save, saveOrUpdate, persist, merge sẽ đẩy đối tượng Transient vào sự quản lý của Hibernate và đối tượng này chuyển sang trạng thái Persistent. Tùy tình huống nó sẽ insert hoặc update dữ liệu vào DB.
(4) Persistent -> Detached: Session gọi evict(..) hoặc clear() để đuổi các đối tượng có trạng thái persistent (bền vững) ra khỏi sự quản lý của Hibernate, giờ các đối tượng này sẽ có trạng thái mới là Detached (Bị tách ra). Nếu nó không được đính (Attached) trở lại, nó sẽ bị bộ gom rác của Java quét đi theo cơ chế thông thường.
(5) Detached -> Persistent: Sử dụng update(..), saveOrUpdate(..), merge(..) sẽ đính trở lại các đối tượng Detached vào lại. Tùy tình huống nó sẽ tạo ra dưới DB câu lệnh update hoặc insert. Các đối tượng sẽ trở về trạng thái Persistent (bền vững).
(6) Persistent -> Removed: Session gọi method remove(..), delete(..) để xóa một bản ghi, đối tượng persistent giờ chuyển sang trạng thái Removed (Đã bị xóa).
Thao tác Select, Insert, Update, Delete (CRUD) với Hibernate
Trước khi đi vào chi tiết từng phương thức, các bạn nên nhớ rằng tất cả các phương thức như persist, save, update, merge, saveOrUpdate, remove, … không ngay lập tức thực thi các câu lệnh SQL UPDAT, INSERT hoặc DELETE tương ứng. Việc thực thi câu lệnh SQL thực tế vào cơ sở dữ liệu xảy ra khi commit transaction hoặc flush session.
Các phương thức được đề cập về cơ bản quản lý trạng thái của các thể hiện của thực thể bằng cách chuyển chúng giữa các trạng thái khác nhau theo vòng đời của đối tượng trong Hibernate.
Persistent
Phương thức load()
Dùng để load một đối tượng từ database lên, nó sẽ có trạng thái persistent, throw ObjectNotFoundException nếu id không tồn tại.
Chỉ sử dụng method load() khi chắc chắn rằng đối tượng tồn tại trong database.
Method load() sẽ ném ra 1 exception nếu đối tượng không tìm thấy trong database.
Method load() chỉ trả về 1 đối tượng giả (proxy object) nó chỉ lấy dữ liệu từ database ra khi cần tới.
* Proxy Object là 1 đối tượng giả, nó chỉ có id, các thuộc tính khác không được khởi tạo, ví dụ khi bản để FETCH_TYPE = LAZY khi mapping thì nó cũng chỉ trả về 1 proxy object.
Phương thức get()
Giống load(), tuy nhiên trả về null nếu không tồn tại.
Nếu không chắc chắn rằng đối tượng có tồn tại trong database không thì hãy dùng get().
Method get() sẽ trả về null nếu không tìm thấy đối tượng trong database.
Method get() sẽ truy xuất vào database ngay lập tức để lấy đối tượng thực đang tồn tại.
Phương thức find()
Cách thức hoạt động tương tự như get(). Sự khác biệt giữa find() và get() là:
find() là một đặc tả của JPA, get() là đặc tả riêng của Hibernate.
Một điểm khác biệt nữa về mặt ngữ nghĩa sử dụng: find() có thể có kết quả hoặc không, get() sẽ luôn trả về một vài thứ gì đó thậm chí là null.
System.out.println("- Fullname of user 1 "+ user1.getFullname());
System.out.println("---");
System.out.println("- Getting user 2");
User user2 = session.get(User.class, 2L);
System.out.println("- After called ");
System.out.println("- Fullname of user 2 "+ user2.getFullname());
System.out.println("---");
System.out.println("- Finding user 3");
User user3 = session.find(User.class, 3L);
System.out.println("- After called ");
System.out.println("- Fullname of user 3 "+ user3.getFullname());
// Commit the current resource transaction, writing any unflushed changes to the database.
session.getTransaction().commit();
}
Log:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
- Loading user 1
- After called
Hibernate: select user0_.id as id1_3_0_, user0_.created_at as created_2_3_0_, user0_.fullname as fullname3_3_0_, user0_.modified_at as modified4_3_0_, user0_.password as password5_3_0_, user0_.username as username6_3_0_ from user user0_ where user0_.id=?
- Fullname of user 1Changed 2nd
---
- Getting user 2
Hibernate: select user0_.id as id1_3_0_, user0_.created_at as created_2_3_0_, user0_.fullname as fullname3_3_0_, user0_.modified_at as modified4_3_0_, user0_.password as password5_3_0_, user0_.username as username6_3_0_ from user user0_ where user0_.id=?
- After called
- Fullname of user 2Hibernate Example
---
- Finding user 3
Hibernate: select user0_.id as id1_3_0_, user0_.created_at as created_2_3_0_, user0_.fullname as fullname3_3_0_, user0_.modified_at as modified4_3_0_, user0_.password as password5_3_0_, user0_.username as username6_3_0_ from user user0_ where user0_.id=?
- After called
- Fullname of user 3Hibernate Example
Như bạn thấy, thời điểm thực thi SQL của get() và load() là khác nhau. Load() chỉ gọi SQL khi cần sử dụng, SQL được thực thi ngay khi hàm get() và find() được call.
Xem ví dụ về cách xử lý khi không tìm thấy data trong cơ sở dữ liệu:
System.out.println("- Fullname of user 1 "+ user1.getFullname());
} catch(ObjectNotFoundException e) {
System.out.println("Could not found user with id = 1");
}
System.out.println("---");
System.out.println("- Getting user 2");
User user2 = session.get(User.class, 2L);
System.out.println("- After called ");
System.out.println("- User 2 is null = "+ (user2 == null));
System.out.println("---");
System.out.println("- Finding user 3");
User user3 = session.find(User.class, 3L);
System.out.println("- After called ");
System.out.println("- User 3 is null = "+ (user3 == null));
// Commit the current resource transaction, writing any unflushed changes to the database.
session.getTransaction().commit();
}
Log:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
- Loading user 1
- After called
Hibernate: select user0_.id as id1_3_0_, user0_.created_at as created_2_3_0_, user0_.fullname as fullname3_3_0_, user0_.modified_at as modified4_3_0_, user0_.password as password5_3_0_, user0_.username as username6_3_0_ from user user0_ where user0_.id=?
Could not found user with id = 1
---
- Loading user 2
Hibernate: select user0_.id as id1_3_0_, user0_.created_at as created_2_3_0_, user0_.fullname as fullname3_3_0_, user0_.modified_at as modified4_3_0_, user0_.password as password5_3_0_, user0_.username as username6_3_0_ from user user0_ where user0_.id=?
- After called
- User 2is null= true
---
- Finding user 3
Hibernate: select user0_.id as id1_3_0_, user0_.created_at as created_2_3_0_, user0_.fullname as fullname3_3_0_, user0_.modified_at as modified4_3_0_, user0_.password as password5_3_0_, user0_.username as username6_3_0_ from user user0_ where user0_.id=?
- After called
- User 3is null= true
Như bạn thấy, load() sẽ throw 1 exception khi không tìm thấy dữ liệu, get() và find() sẽ return về một giá trị null khi không tìm thấy dữ liệu.
Nên sử dụng phương thức nào?
Phương thức get()/ find() thực thi SQL để lấy data ngay khi được gọi, trong khi phương thức load() trả về một proxy object, câu lệnh SQL thực sự chỉ được thực thi cần thiết. Vì vậy load() tốt hơn về performance bởi vì nó hỗ trợ lazy loading.
Phương thức load() sẽ throw exception khi không tìm thấy dữ liệu, vì vậy chúng ta chỉ sử dụng khi đã biết dữ liệu chắc chắn tồn tại.
Phương thức get()/ find() được sử dụng khi ta muốn make sure dữ liệu tồn tại trong database.
Transient –> Persistent
Phương thức persist()
Phương thức persist được thiết kế để thêm một thể hiện mới của thực thể vào persistent context, tức là chuyển một thể hiện từ trạng thái Transient sang trạng thái Persistent. Sau khi gọi persit(), đối tượng bây giờ trong persistence context, nhưng chưa được lưu vào cơ sở dữ liệu. Việc tạo ra các câu lệnh SQL INSERT sẽ chỉ xảy ra khi commit transaction, flush hoặc close session.
Ta thường sử dụng persit() khi ta muốn thêm một bản ghi vào cơ sở dữ liệu. Persit() hoạt động trên đối tượng được truyền “tại chỗ”, thay đổi trạng thái của chính nó và tham chiếu đến đối tượng tồn tại thực tế.
1
2
3
Category cat = newCategory();
cat.setName("Java");
session.persist(cat); // void
Phương thức save()
Phương thức save() là original Hibernate API, nó không thuộc đặc tả JPA. Mục đích của nó về cơ bản giống như persist(), nhưng implementation details của nó thì khác. Phương thức này sẽ tạo ra một định danh, đảm bảo rằng nó sẽ return the Serializable của định danh này.
1
2
3
4
5
6
7
8
Category cat = newCategory();
cat.setName("Java");
Long id = (Long) session.save(cat);
System.out.println("Cat id = "+ id); // 5
Long id2 = (Long) session.save(cat);
System.out.println("Cat id = "+ id2); // 5
Hiệu quả của việc lưu một persisted instance là giống như với persist. Sự khác biệt xuất hiện khi ta cố gắng lưu một detached instance:
1
2
3
4
5
6
7
8
9
10
Category cat = newCategory();
cat.setName("Java");
Long id = (Long) session.save(cat);
System.out.println("Cat id = "+ id); // 6
session.evict(cat);
Long id2 = (Long) session.save(cat);
System.out.println("Cat id = "+ id2); // 7
Như bạn thấy, sau khi gọi evict():
Id được save lần đầu khác với id được save lần sau.
Khi save trên một detached instance sẽ tạo ra một persistent instance mới và gán nó cho một định danh mới. Kết quả là bị duplicate bản ghi trong database khi commit hoặc flush.
Phương thức merge()
Mục đích chính của phương thức merge() là update một persistent entity instance với các giá trị mới từ một detached entity instance.
Phương thức này hoạt động như sau:
Tìm một entity instance bằng id lấy từ đối tượng được truyền (hoặc một existing entity instance từ persistence context được lấy ra, hoặc một new instance được load ra từ database).
Sao chép các trường từ đối tượng được truyền vào instance vừa tìm được.
returns instance mới đã được update, đối tượng trả về có trạng thái persistence, còn đối tượng ban đầu vẫn sẽ không bị quản lý bởi session.
Trong ví dụ sau, ta evict (detach) thực thể đã lưu khỏi context, thay đổi name field, và sau đó merge với detached entity.
System.out.println("saved object is managed by hibernate session = "+ session.contains(cat));
session.evict(cat);
System.out.println("evicted object is managed by hibernate session = "+ session.contains(cat));
cat.setName("Hibernate");
Category cat2 = (Category) session.merge(cat);
System.out.println("merged object is managed by hibernate session = "+ session.contains(cat2));
System.out.println("Saved object is equals with merged object = "+ (cat == cat2));
// Commit the current resource transaction, writing any unflushed changes to the database.
session.getTransaction().commit();
}
Log:
1
2
3
4
5
6
7
Hibernate: insert into Category (name) values (?)
saved object is managed by hibernate session = true
Hibernate: select category0_.id as id1_0_0_, category0_.name as name2_0_0_ from Category category0_ where category0_.id=?
evicted object is managed by hibernate session = false
merged object is managed by hibernate session = true
Saved object is equals with merged object = false
Hibernate: update Category set name=? where id=?
Lưu ý rằng phương thức merge trả về một đối tượng – nó là đối tượng được merge, được load vào persistent context và được update, không phải đối tượng category mà ta đã truyền làm đối số. Đó là hai đối tượng khác nhau, và đối tượng category thường cần phải được loại bỏ sau đó.
Như với phương thức persist(), phương thức merge() được chỉ định bởi JSR-220 để có một số ngữ nghĩa nhất định mà bạn có thể dựa vào:
Nếu thực thể là detached, nó được sao chép trên một existing persistent entity.
Nếu thực thể là transient, nó được sao chép trên một newly created persistent entity.
Hoạt động cascades cho tất cả các mối quan hệ : cascade = MERGE hoặc cascade = ALL.
Phương thức update()
Tương tự như với persist() và save(), phương thức update() là một “original” Hibernate API method đã tồn tại trước khi phương thức merge được thêm vào. Ngữ nghĩa của nó khác nhau ở một số điểm chính:
Nó hoạt động khi đối tượng được truyền là một persistence entity hoặc detached entity.
Phương thức này chuyển đổi đối tượng được truyền từ trạng thái detached thành trạng thái persistent.
Phương thức này ném một ngoại lệ nếu ta truyền vào nó một transient entity.
System.out.println("saved object is managed by hibernate session = "+ session.contains(cat));
session.evict(cat);
System.out.println("evicted object is managed by hibernate session = "+ session.contains(cat));
cat.setName("Hibernate");
session.update(cat);
System.out.println("updated object is managed by hibernate session = "+ session.contains(cat));
// Commit the current resource transaction, writing any unflushed changes to the database.
session.getTransaction().commit();
}
Log:
1
2
3
4
5
Hibernate: insert into Category (name) values (?)
saved object is managed by hibernate session = true
evicted object is managed by hibernate session = false
updated object is managed by hibernate session = true
Hibernate: update Category set name=? where id=?
Cố gắng thực hiện update trên một transient instance sẽ dẫn đến một ngoại lệ TransientObjectException. Điều sau đây sẽ không hoạt động:
1
2
3
Category cat = newCategory();
cat.setName("Java");
session.update(cat); // TransientObjectException
Phương thức SaveOrUpdate()
Phương thức này chỉ xuất hiện trong Hibernate API. Tương tự như update(), nó cũng có thể được sử dụng cho các trường hợp attached lại. Sự khác biệt chính của phương thức update() và saveOrUpdate() là nó không ném ngoại lệ khi được áp dụng cho một transient instance.
Phương thức này hoạt động như sau: nếu là đối tượng mới thì save xuống database, nếu không thì update xuống database. Nó sẽ thực hiện SELECT để kiểm tra trước khi save hoặc update.
Nếu đối tượng đã tồn tại trong session thì nó không làm gì cả.
Nếu tồn tại 1 đối tượng khác trong cùng session mà có cùng id thì sẽ xảy ra exception.
Nếu đối tượng tượng không có id (chưa tồn tại) thì sẽ thực hiện save().
Nếu đối tượng có id nhưng id đó chưa có trong database thì thực hiện save().
// Commit the current resource transaction, writing any unflushed changes to the database.
session.getTransaction().commit();
}
Khi chạy chương trình trên, chúng ta sẽ gặp một excepion NonUniqueObjectException. Lý do là có 2 đối tượng cùng được quản lý trong một session.
1
Exception in thread "main"org.hibernate.NonUniqueObjectException: A different object with the same identifier value was already associated with the session : [com.gpcoder.entities.Category#20]
Nên sử dụng phương thức nào?
Nếu không có bất kỳ yêu cầu đặc biệt nào, theo quy tắc chung, ta nên tuân thủ các phương thức persist() và merge(), vì chúng được chuẩn hóa và được đảm bảo để tuân theo đặc tả JPA. Nó sẽ dễ dàng hơn trong trường hợp ta quyết định chuyển sang một persistence provider khác, chẳng hạn iBatis, Eclipse Link, OpenJPA, … Tuy nhiên, một số trường hợp đặc biệt các phương thức Hibernate “gốc” như save(), update() và saveOrUpdate() sẽ hữu dụng hơn nhiều.
Persistent –> Detached
Phương thức evict()
Tách một đối tượng ra khỏi session, biến nó từ trạng thái persistent thành detached.
Các bạn có thể xem lại các ví dụ trên để thấy được cách sử dụng evict().
Phương thức clear()
Tách tất cả đối tượng ra khỏi session, biến tất cả chúng từ trạng thái persistent thành detached.
Rất tiếc, câu trả lời là không. Đối với C++, phép gán này sẽ cho ra một Object mới, hoàn toàn độc lập với Object cũ. Nhưng Java thì không làm được, nếu sử dụng phép toán ==, java sẽ tạo ra một biến tham chiếu (reference variable) -> không tạo ra một object mới.
Thực chất, trường hợp sử dụng Operator equal hay toán tử New, Java đều trỏ tới cùng một địa chỉ trên memory. Object được tạo ra có thể bị thay đổi nếu object mà nó reference trước đó thay đổi.
Để dễ hiểu hơn, ta cùng xem xét ví dụ dưới đây:
import java.io.*;
// Class Test, nơi chưa object ta muốn clone.
class Test
{
int x, y;
Test()
{
x = 10;
y = 20;
}
}
// Main Class
class Main
{
public static void main(String[] args)
{
// Tạo object ob1
Test ob1 = new Test();
System.out.println(ob1.x + " " + ob1.y);
// Tạo mới reference variable cho ob2
// Thực chất Object ob2 trỏ tới cùng một địa chỉ với Object ob1
Test ob2 = ob1;
// Bất cứ thay đổi nào ở Object 2 cũng đều reflect tới Object 1
// in ob1
ob2.x = 100;
System.out.println(ob1.x+" "+ob1.y);
System.out.println(ob2.x+" "+ob2.y);
}
}
Output:
10 20
100 20
100 20
2. Java clone ra đời.
3. Sử dụng như thế nào?.
Để có thể sử dụng method clone, có hai thứ cần làm:
Class chúng ta muốn Clone nhất thiết phải implement Cloneable interface. Nếu không, JVM sẽ throw exception CloneNotSupportedException khi ta gọi method clone() trong Object.
Trường hợp muốn gọi clone() ở class cha, sử dụng super.clone().
4. Shallow copy và deep copy.
4.1 Shallow copy
Shallow copy is method of copying an object and is followed by default in cloning. In this method the fields of an old object X are copied to the new object Y. While copying the object type field the reference is copied to Y i.e object Y will point to same location as pointed out by X. If the field value is a primitive type it copies the value of the primitive type.
Shallow copy là một method copy object, đây là phương thức được sử dụng mặc định trong cloning. Ở method này, các field của object X được copy tới object Y. Trong quá trình sao chép, cả Object X và Y đều cùng trỏ tới một địa chỉ. Trường hợp field value được copy là kiểu nguyên thủy -> giá trị của Object sẽ được copy.
Chính vì cả 2 Object X và Y đều trỏ về cùng 1 địa chỉ -> trường hợp có thay đổi giá trị ở Object cha, giá trị sẽ thay đổi luôn ở Object con. Tuy cũng sử dụng Java Clone, nhưng Shallow có chi phí khởi tạo (memory) thấp hơn.
Shallow copies are cheap and simple to make.
Shallow copies được tạo ra tương đối đơn giản, chi phí để tạo ra một Object được copy theo kiểu này cũng không quá cao.
4.2 Deep copy
Phương thức chính được sử dụng trong Java Clone là clone(). Phương thức này sử dụng Deep copy, ta sẽ sử dụng method clone(). Khi sử dụng clone(), một Object được tạo ra. Nhưng khi có sự thay đổi về giá trị ở Object cha -> sự thay đổi sẽ không reflect (phản án) tới Object con.
If we want to create a deep copy of object X and place it in a new object Y then new copy of any referenced objects fields are created and these references are placed in object Y. This means any changes made in referenced object fields in object X or Y will be reflected only in that object and not in the other.
Nếu bạn muốn tạo một deep copy của object X và biến nó trở thành một Object mới Y. Tất cả những thay đổi ở Object X sẽ chỉ được phản ánh cho chính nó. Các giá trị còn lại ở Object Y đã clone sẽ không thay đổi.
Bài viết được sự cho phép của tác giả Nguyễn Hữu Khanh
GlassFish là một trong những Java server runtime giúp chúng ta có thể chạy ứng dụng Java web application. Trong bài viết này, mình hướng dẫn các bạn cách cài đặt nó trong Eclipse để có thể dễ dàng phát triển các ứng dụng Java EE, Jakarta EE sử dụng Eclipse các bạn nhé!
Ứng dụng Visitor Pattern để làm configure UI driven
Bài viết được sự cho phép của tác giả Lưu Bình An
Vấn đề chúng ta cần giải quyết: chúng ta cần render form với các loại field phổ biến như date, number, dropdown, text, với điều kiện là những field này user có thể config được, giống như google form
Visitor pattern là 1 phương pháp thiết kế trong OOP, cách làm là chúng ta sẽ có một object với cấu trúc định sẵn, sử dụng object này để thực hiện những xử lý chúng mong muốn
object với cấu trúc định sẵn thường được gọi là schema, trong bài toán của chúng ta thì schema cần những property sau
ViewGenerator cũng chung một công dụng như Form ở trên, ở đây chúng ta chỉ làm thêm việc, 1 là đưa phần khai báo component ra defaultComponent và bổ sung tham số components để khi có nhu cầu mở rộng, override các component default thì truyền thêm. Quá generic!
const data ={
firstName:"John",
birthdate:"1992-02-01",
numPets:2}const profileViewComponents ={Text:({ label, name })=>(<div><p>{label}</p><p>{data[name]}</p></div>),Date:({ label, name })=>(<div><p>{label}</p><p>{data[name]}</p></div>),Number:({ label, name })=>(<div><p>{label}</p><p>{data[name]}</p></div>)}functionProfileView({ schema }){return(<ViewGeneratorschema={schema}components={profileViewComponents}/>)}
Giờ nếu các field được group vào kiểu cha-con thì sao? Một cách (mình cũng không thích lắm) là thêm children
Với một cấp duy nhất thì schema này ok, nhưng nếu lồng nhiều hơn một cấp thì đây không phải cách mình sẽ làm, anyway để đơn giản hóa chúng ta chỉ dùng một cấp. Phần ViewGenerator cần được cập nhập để render thêm các children
functionViewGenerator({ schema, components }){const mergedComponents ={...defaultComponents,...components,}return schema.map((field)=>{const children = field.children ?(<ViewGeneratorschema={field.children}components={mergedComponents}/>):nullreturn mergedComponents[field.fieldType]({...field, children });})}
Đệ quy như vậy chưa hẳn là giải pháp hoàn hảo, hy vọng các bạn nào có giải pháp nào tốt hơn thì góp ý thêm.
Khi nghĩ về visitor pattern, chúng ta nghĩ đến
Configure Object đứng độc lập
UI đứng độc lập
Hàm trung gian dùng để map configure object và UI tương ứng
Nhân Viên QC Và Những Kỹ Năng Không Thể Thiếu Trong Công Việc
Nhân viên QC là một trong những vị trí quan trọng giúp vận hành và duy trì chất lượng sản phẩm trong kinh doanh. Do đó, những yêu cầu về công việc đặt ra với nhân viên QC cũng phần nào khắt khe hơn so với các vị trí khác. Sở hữu những kỹ năng cần thiết cho công việc sẽ giúp cho quá trình làm việc được thuận lợi hơn. Vậy 3 kỹ năng quan trọng nhất cho nhân viên QC là gì? Cùng TopDev tìm hiểu thêm với bài viết dưới đây nhé!
Nhân viên QC phải đảm nhận nhiều công việc quan trọng
Nhân viên QC là gì?
Khái niệm nhân viên QC
QC là viết tắt của Quality Control, nhiệm vụ chính của một nhân viên QC liên quan phần nhiều đến việc kiểm tra và giám sát chất lượng sản phẩm. Nhân viên QC sẽ trực tiếp kiểm tra và đánh giá sản phẩm trước khi đưa ra thị trường để có thể mang đến cho khách hàng những sản phẩm tốt nhất. Nhân viên QC giúp doanh nghiệp tìm ra các sản phẩm bị lỗi sớm nhất trước khi được đưa ra thị trường, đảm bảo uy tín và hoạt động trơn tru cho doanh nghiệp.
Nhân viên kiểm soát chất lượng của quy trình sản xuất
Nhân viên kiểm soát chất lượng đầu ra
3 vị trí này sẽ theo dõi và làm việc xuyên suốt quá trình sản xuất để đảm bảo chất lượng sản phẩm.
Công việc chính của một nhân viên QC sẽ tập trung vào việc kiểm tra, phân loại và phát hiện sớm nhất các lỗi phát sinh. Sau khi phát hiện và phân tích lỗi sai, nhân viên QC sẽ làm việc với nhân viên QA (Quality Assurance) – bộ phận đảm bảo chất lượng cho sản phẩm để đề xuất hướng xử lý và sửa lỗi, đảm bảo chất lượng cho thành phẩm cuối cùng.
Vì là người trực tiếp quản lý và kiểm tra chất lượng của sản phẩm nên kỹ năng giám sát có thể nói là điều kiện tiên quyết với bất cứ nhân viên QC nào. Nhân viên QC cần có kỹ năng quan sát và giám sát tốt để phát hiện nhanh chóng các vấn đề còn chưa hoàn thiện và sửa chữa sớm nhất. Đôi mắt nhạy bén là một phần không thể thiếu với bất cứ nhân viên QC nào. Phát hiện được những lỗi sai dù rất nhỏ là công việc cần thiết của nhân viên QC.
Khả năng giám sát tốt cùng với tư duy logic sẽ giúp nhân viên QC không chỉ nhanh chóng phát hiện được vấn đề mà còn biết được cách để xử lý những lỗi sai đó theo hướng tối ưu về thời gian và sức lực. Những nhân viên QC chuyên nghiệp là những người phát huy rất tốt các khả năng này. Vì thời gian xử lý lỗi sai quá lâu chắc chắn sẽ kéo theo ảnh hưởng đến một dây chuyền hoạt động phía sau.
Về mặt chuyên môn, kỹ năng quản lý và điều hành chắc chắn không chỉ quan trọng với nhân viên QC mà còn với tất cả các ngành nghề khác. Với nhân viên QC – Quality Control, kỹ năng quản lý sẽ giúp bạn làm chủ được thời gian và công việc của mình, cũng như làm tốt hơn trong việc quản lý các nhân viên cấp dưới của mình nếu có.
Kỹ năng quản lý và điều hành công việc sẽ giúp bạn hoàn thành công việc tốt hơn nhờ phối hợp tốt giữa các quy trình, không bị lộn xộn hay ôm đồm quá nhiều công việc cùng lúc. Bên cạnh đó, khi nắm được thế mạnh cũng như điểm yếu của các nhân viên cấp dưới, bạn sẽ biết được nên giao cho họ công việc để họ làm tốt nhất. Giúp công việc được hoàn thành đúng thời hạn, thậm chí sớm hơn thời hạn mà vẫn đảm bảo được hiệu quả về mặt chất lượng cũng như số lượng.
3. Kỹ năng sử dụng công nghệ
Đối với vị trí của một nhân viên QC, một trong 3 kỹ năng quan trọng nhất cho nhân viên QC đó là khả năng sử dụng công nghệ và các thiết bị có liên quan đến công việc một cách thuần thục. Một số kỹ năng cần có với nhân viên kiểm soát chất lượng là biết cách sử dụng các thiết bị kỹ thuật số, các dụng cụ đo đạc và kiểm tra chất lượng sản phẩm chuyên dụng cũng như có khả năng tin học văn phòng tốt.
Bên cạnh những kỹ năng mềm như khả năng giao tiếp, diễn đạt tốt cũng năng lực hợp tác và phối hợp làm việc với nhiều phòng ban khác nhau, kỹ năng sử dụng các thiết bị công nghệ hoàn toàn có thể trau dồi qua thời gian. Chính vì thế, để công việc kiểm soát chất lượng có thể diễn ra suôn sẻ, việc đầu tư thời gian cho những kỹ năng này là hoàn toàn cần thiết cho một công việc trôi chảy và thuận lợi.
Chiếm vai trò quan trọng trong các khâu làm việc và quyết định đến thành phẩm cuối cùng, mức lương cho nhân viên QC hiện nay cũng được xếp vào nhóm khá cao, mức trung bình hoàn toàn có thể nằm khoảng 10 triệu đồng/tháng. Do đó, để sở hữu công việc mình đam mê với mức lương hấp dẫn, biết thêm 3 kỹ năng quan trọng nhất cho nhân viên QC có thể giúp bạn hoàn thiện năng lực làm việc của mình hơn. Cùng TopDev đón đọc thêm nhiều bài viết bổ ích và hấp dẫn khác nhé!
SSH Key hiểu đơn giản là một phương thức chứng thực người dùng truy cập vào server bằng cách đối chiếu giữa một key cá nhân (Private Key) trên thiết bị truy cập lưu trữ và key công khai(Public Key) trên server lưu trữ. Nội dung mã hóa trong 2 key này hoàn toàn khác nhau nhưng Server sẽ tự mã hóa Public Key theo một chuẩn RSA và đối chiếu với Private Keynếu 2 key này giống nhau là hợp lệ.
Thành phần chính của một SSH Key
Khi tạo ra một SSH Key, bạn cần biết sẽ có 3 thành phần quan trọng như sau:
Public Key (dạng file và string) – Copy ký tự key này sẽ bỏ vào file /root/.ssh/authorized_keys trên server của bạn.
Private Key (dạng file và string) – Lưu file này trên thiết bị đăng nhập, thiết lập cho PuTTY, WinSCP, MobaXterm,..
Keypharse (dạng string, cần ghi nhớ) – Mật khẩu để mở private key, khi đăng nhập vào server nó sẽ hỏi cái này. Nếu để trống nó sẽ không hỏi!
2. Tạo SSH Key
Trên Windows
Nếu bạn sử dụng Windows thì sẽ dùng phần mềm PuTTY-Gen để tạo SSH, bạn có thể tải PuTTY-Gen tại đây.
Tải xong bạn mở ra, bạn chọn các tùy chọn như trong ảnh dưới rồi ấn Generate.
Trong lúc tạo, bạn phải rê chuột và click vòng vòng màn hình cho đến khi nó tạo xong.
Sau khi tạo xong, bạn sẽ thấy nó hiện ra thế này.
Kế tiếp đặt mật khẩu cho keypharse.
Cuối cùng Save Private Key và backup nó ở một nơi thật an toàn.
Còn cái public key là cái dãy loằng ngoằng ở trên, nó bắt đầu bằng từ khóa ssh-rsa AAA…Đoạn code này bạn sẽ copy bỏ vào server. Khi nào cần bạn có thể Load private key trong PuTTYGen là nó hiện ra public key.
Lưu ý tạo OpenSSH pribvate_key cho linux thì export như sau:
Trên Linux (Mac/Ubuntu/LinuxMint,..)
Nếu bạn đang sử dụng Linux thì không cần phần mềm mà sẽ sử dụng Terminal gõ:
ssh-keygen -t rsa
Nó sẽ hỏi bạn muốn lưu private key này vào đâu, mặc định nó sẽ lưu vào /home/user/.ssh. Bạn có thể để trống và Enter.
Tiếp tục nó sẽ hỏi bạn có muốn thiết lập keypharse bạn thấy cần thì nhập vào rồi Enter.
Sau khi tạo xong, mặc định nó sẽ hiện ra thế này:
Trong đó bạn có thể thấy nó có ghi đường dẫn lưu file private key (id_rsa) và file public key (id_rsa.pub). Để xem được public key, bạn cứ mở file id_rsa.pub.
cat ~/.ssh/id_rsa.pub
Cái public key này bạn sẽ mang lên Server.
3. Cấu hình Public key trên Server
Đăng nhập vào Server với tài khoản mà bạn muốn áp dụng SSH Key.
Sau đó gõ các lệnh để tạo thư mục .ssh/ và file authorized_keys trong thư mục đó:
# Tạo foler .ssh
mkdir ~/.ssh
chmod 700 ~/.ssh
# Tạo file authorized_keys lưu Public Key
touch ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
Sau đó mở file authorized_keys trong thư mục .ssh ở thư mục gốc của user và copy toàn bộ ký tự của public key. Có bao nhiêu public key thì lưu bấy nhiêu dòng thôi.
Lưu ý:
SSH Key sẽ không thể hoạt động nếu bạn đang bật SELinux. Hãy tắt SELinux đi bằng cách mở file /etc/selinux/config, tìm SELINUX=enforcing và thay bằng SELINUX=disabled. Sau đó gõ lệnh reboot để khởi động lại server.
Để kiểm tra xem nó đã hoạt động chưa, hãy đăng nhập lại vào SSH với tài khoản vừa thêm SSH Key. Nếu bạn đăng nhập bằng Linux thì nó sẽ tự hỏi keypharse của bạn, còn nếu bạn đăng nhập ở Windows dùng PuTTY thì phải trỏ file private key vào để nó chứng thực.
Nếu dùng MobaXterm thì gắn trong phần Advanced SSH Settings nhé, phần Use private key.
Bây giờ bạn đăng nhập và nó sẽ hỏi keypharse nếu bạn có đặt keypharse, còn không đặt là nó vô thẳng server.
Tắt chức năng sử dụng mật khẩu
Sau khi kiểm tra, nếu bạn thấy đã có thể đăng nhập vào server bằng SSH Key thì có thể tắt chức năng sử dụng mật khẩu đi vì nếu không tắt, các hacker vẫn brute force attack được.
Để tắt chức năng sử dụng mật khẩu trên server, bạn mở file /etc/ssh/sshd_config, và cấu hình như sau:
Cách tạo sẵn mẫu comment trong INTELLIJ với Live Template
Bài viết được sự cho phép của blogchiasekienthuc.com
Chào các bạn, đối với anh em lập trình viên thì trong quá trình code có một việt rất quan trọng đó là viết comment.
Vậy comment trong INTELLIJ nghĩa là gì?
Vâng, comment là những chú thích, là những ghi chú với mục đích là để cho người viết code và cả người đọc code có thể hiểu được đoạn chương trình đó chạy như thế nào và mục đích là gì.
Nhưng trong thực tế có những comment lặp đi lặp lại với một dạng nhất định, nếu cứ mỗi lần tạo hàm mới lại hì hục viết comment thì sẽ rất mất thời gian.
Vì vậy trong bài viết này mình sẽ hướng dẫn anh em cách tạo một comment với định dạng sẵn, anh em chỉ cần gõ từ gợi ý là đoạn comment sẽ tự xổ ra.
Lưu ý: Hướng dẫn này mình dựa trên ngôn ngữ lập trình Java và công cụ IntelliJ Idea nhé.
#1. Ví dụ một đoạn comemnt với các thông tin
@author: Người tạo hàm đó
@since: Thời gian khởi tạo hàm
@description: Mô tả chức năng của hàm
@update: Các cập nhật của hàm này sẽ được ghi lại tại đây.
#2. Hướng dẫn tạo một template comment trong INTELLIJ
Đầu tiên các bạn vào mục File => chọn Setting… hoặc phím tắt là Ctrl + Alt + S như hình bên dưới.
Tiếp theo trong phần tìm kiếm các bạn nhập Live Templates => rồi chọn các lựa chọn như hình bên dưới.
Để tạo một Template:
(1) Đặt tên (tên này sẽ là tên gợi ý, khi bạn gõ tên này và Enter thì sẽ tạo một template được định nghĩa bên dưới)
Sau khi có tên và nội dung template rồi thì các bạn bấm vào chữ Define như hình ảnh bên dưới.
Tại đây, nếu bạn định tạo comment cho ngôn ngữ lập trình nào thì chọn ngôn ngữ tương ứng. Nguyên nhân bởi vì mỗi ngôn ngữ có thể có các kiểu comment khác nhau.
Tiếp theo, các bạn bấm Edit variables để chỉnh sửa các biến mà chúng ta sử dụng trong template. Ở đây mình có ba biến đó là:
$nowDate$: Ngày hiện tại
$dateTime$: Thời gian cụ thể
$desc$: Miêu tả
Sau khi chọn chức năng Edit thì đây chính là màn hình chúng ta sẽ sửa các biến, chính xác hơn chọn giá trị tương ứng cho các biến.
nowDate: Mình sẽ chọn tương ứng với date()
Tương tự thì dateTime mình sẽ chọn tương ứng với time() như hình bên dưới.
Okay, vậy là công đoạn tạo template đã xong rồi. Bây giờ các bạn có thể gõ chữ “com…” ở bất cứ đâu trong chương trình để tạo một comment với mẫu đã tạo.
Đây chính là kết quả, các bạn có thể thấy có rất nhiều trường hợp chúng ta phải tạo các comment như thế này. Việc chỉ cần nhập từ gợi ý để tạo một comment dài như thế này là thực sự rất tiện lợi.
Không những bạn có thể tạo một comment như vậy, mà bạn còn có thể tạo ra rất nhiều các comment khác nhau.
Ví dụ trong phần @update, mình cũng sẽ tạo một template với nội dung như ảnh bên dưới để phục vụ việc khi mình có cập nhật gì đó cho hàm mình đang viết.
Các bạn cũng có thể gõ gợi ý up… để tạo ra một comment tương ứng template mà các bạn đã định nghĩa thêm.
Và đây chính là một comment đầy đủ, nhìn có vẻ rất là dài nhưng thông qua việc sử dụng Live Template mình đã viết đoạn comment chỉ với một hai phím gõ.
#3. Kết luận
Vâng, như vậy là việc tạo comment ghi chú nhanh trong INTELLIJ với tính năng LIVE TEMPLATE cũng không có gì khó khăn cả, có đúng không ạ 🙂
Trên thực tế thì những dự án có nhiều người cùng làm và làm trong thời gian dài sẽ không thể tránh khỏi việc mỗi người code một kiểu.
Nếu không có các dòng comment để chú thích code thì thực sự rất khó cho người sau, chưa kể còn không biết được ai viết hàm đó, chức năng… đó để nhỡ có bị lỗi còn “lôi” ra hỏi.
Nhưng đôi khi việc viết comment lại khá tốn thời gian, vậy nên việc sử dụng Live Templates sẽ là một trong những cách rất hay để tạo nhanh comment mà không tốn quá nhiều thời gian cho nó.
Mẹo: trên trang chủ của bazel nội dung khác hẳn với file trên. Lý do tại sao các tag lại khác, đó là tại thời điểm viết bài này thì các tag của các repository ở trên đã cập nhật bản mới nhất. Cụ thể nếu bạn muốn lấy phiên bản repository mới nhất, ví dụ của link https://github.com/bazelbuild/rules_apple.git thì bạn gõ vào trình duyệt link đó, và vào mục tag của nó để xem tag hiện tại là bao nhiêu, ví dụ tôi tìm được tag:
objc_library(
name = "UrlGetClasses",
srcs = [
"UrlGet/AppDelegate.m",
"UrlGet/UrlGetViewController.m",
"UrlGet/main.m",
],
hdrs = glob(["UrlGet/*.h"]),
data = ["UrlGet/UrlGetViewController.xib"],
)
Đoạn này bạn tạo ra 1 library objective-c có tên là UrlGetClasses, gồm các file code .m nằm ở thư mục UrlGet. Các file header nằm ở hdrs, các file data chỉ có 1 file .xib ở trên.
Tên file build ra là ios-app, tên bundle_id của app là Google.UrlGet, hỗ trợ cho families là iphone và ipad. Phiên bản tối thiểu là minimum_os_version 9.0. File plit là UrlGet-Info.plist, trạng thái là visibility public. Phụ thuộc vào thư viện đầu ra thư viện là UrlGetClasses.
Build ứng dụng
Bạn cd ra thư mục tutorial và gõ:
bazel build //ios-app:ios-app
Đợi 1 lúc thấy thông báo như ảnh sau là thành công:
Bài viết được sự cho phép của tác giả Kien Dang Chung
Composer quản lý sự phụ thuộc của một dự án với các thư viện lập trình bên ngoài thông qua một số các tập tin và liên quan đến một số thuật ngữ, chúng ta sẽ bắt đầu tìm hiểu cách sử dụng composer nhé.
Composer.json file chứa các thiết lập dự án
Để bắt đầu một dự án bạn cần có một file composer.json, file này chứa mô tả các thư viện ngoài mà dự án cần cài đặt (phụ thuộc) bằng từ khóa require.
{"require":{"monolog/monolog":"1.0.*"}}
Phần thiết lập trên nói lên rằng dự án cần gói có tên là monolog/monolog với yêu cầu phiên bản là 1.0.*. Composer sẽ sử dụng thông tin này và tìm kiếm các gói được đăng ký bằng từ khóa repositories hoặc trong Packagist là một kho tài nguyên các gói thư viện trên mạng. Chúng ta tiếp tục làm quen một số thuật ngữ:
Package name
Package name chứa tên nhà cung cấp và tên dự án, ví dụ trên tên nhà cung cấp và tên dự án trùng nhau là monolog. Có thể hai nhà cung cấp khác nhau đặt trùng tên dự án, ví dụ igorw/json là dự án json của nhà cung cấp igorw khác với gói thư viện seldaek/json là dự án json của nhà cung cấp seldaek.
Hạn chế phiên bản gói thư viện
Chúng ta có thể hạn chế phiên bản gói cần cài đặt để đảm bảo dự án hoạt động tốt với tính năng của gói ở một số phiên bản. Trong ví dụ trên, chúng ta yêu cầu gói monolog/monolog với hạn chế phiên bản là 1.0.* tức là các phiên bản >1.0 và <1.1 thỏa mãn yêu cầu.
Thực hiện cài đặt các gói đã được khai báo trong composer.json bằng lệnh
php composer.phar install
Nếu bạn đã thêm đường dẫn đến composer.bat vào biến môi trường PATH thì chỉ cần gõ ngắn gọn hơn:
composer install
Khi chạy lệnh cài đặt này sẽ có hai tình huống xảy ra:
Nếu trước đó bạn chưa chạy lệnh này bao giờ sẽ không có file composer.lock. Composer sẽ đơn giản là đọc thông tin các gói cần thiết trong composer.json và tải phiên bản mới nhất trong hạn chế phiên bản về thư mục vendor trong dự án. Trong ví dụ trên khi thực hiện lệnh composer install xong chúng ta sẽ thấy có thư mục monolog/monolog trong thư mục vendor của dự án. Khi composer cài đặt xong, tất cả các gói cùng với phiên bản chính xác sẽ được lưu vào composer.lock, bởi vậy tất cả mọi người tham gia dự án sẽ bị lock ở cùng một phiên bản các gói thư viện lập trình.
Nếu file composer.lock tồn tại, có nghĩa là bạn đã chạy lệnh install trước đó hoặc có thể một ai đó đã chạy lệnh install và commit file composer.json. Chạy lệnh install khi có tập tin composer.lock giúp Composer sử dụng phiên bản chính xác được liệt kê trong composer.lock và đảm bảo phiên bản các gói thư viện sẽ phù hợp với mọi người đang tham gia trong dự án. Kết quả bạn sẽ có các phiên bản được yêu cầu trong composer.json nhưng không phải tất cả chúng ở phiên bản mới nhất do một số liệt kê trong composer.lock đã phát hành phiên bản mới hơn. Thiết kế này đảm bảo dự án của bạn không bị phá vỡ do những thay đổi bất ngờ trong các gói thư viện.
Commit composer.lock với trình quản lý phiên bản
Như đã viết ở trên, composer.lock sẽ ngăn chặn việc tự động lấy xuống các phiên bản mới nhất, để cập nhật chúng sử dụng lệnh update. Khi chạy lệnh này nó sẽ lấy tất cả các phiên bản mới nhất phù hợp với hạn chế phiên bản trong composer.json và sau đó nó update các thông tin phiên bản chính xác vào composer.lock.
php composer.phar update
hay ngắn gọn
composer update
Chú ý: Composer sẽ hiển thị một cảnh báo khi sử dụng lệnh install mà file composer.json và composer.lock chưa được đồng bộ. Nếu bạn chỉ muốn cập nhật một gói thư viện cụ thể, có thể sử dụng lệnh:
php composer.phar update monolog/monolog [...]
Packagist
Packagist là một nơi chứa các gói thư viện chính của Composer, bạn có thể truy cập Packagist tại https://packagist.org. Bạn có thể tải về các gói thư viện tại đây, vì vậy bạn có thể sử dụng lệnh require để yêu cầu bất kỳ gói thư viện nào có trên Packagist.
php composer.phar require vendor/package:2.*
Gói vendor/package phiên bản hạn chế 2.* sẽ được kiểm tra trong file composer.json, nếu chưa có sẽ được thêm vào phần require. Sau khi thêm hoặc thay đổi composer.json, các gói yêu cầu sẽ được cài đặt hoặc cập nhật.
Composer gọi các gói thư viện trong lập trình như thế nào?
Composer tạo ra file vendor/autoload.php, file này dùng để include vào bắt đầu sử dụng các class mà gói thư viện cung cấp.
Bạn có thể thêm các đoạn code riêng vào autoloader này bằng cách thêm vào trường autoload trong composer.json:
{"autoload":{"psr-4":{"Acme\\":"src/"}}}
Composer sẽ đăng ký PSR-4 cho namespace Acme. src là một thư mục nằm trong thư mục gốc của dự án, ngang mức với thư mục vendor, một file src/Foo.php chứa class Acme/Foo. Sau khi thêm autoload, bạn phải chạy lệnh dump-autoload để hệ thống build lại file vendor/autoload.php. Sau đó, bạn cũng include file vendor/autoload.php và gọi được các class mà bạn tự viết.
Thuật ngữ PSR-4 là viết tắt của PHP Standards Recommendation 4 là chuẩn quy ước viết code do nhóm FIG(Framework Interop Group) đề xuất và hiện tại có 5 chuẩn là PSR-0 đến PSR-4. Chúng tôi sẽ trở lại bài viết chi tiết các chuẩn này trong bài Các tiêu chuẩn viết code trong PHP.
Cách tạo sẵn mẫu comment trong INTELLIJ với Live Template
Bài viết được sự cho phép của blogchiasekienthuc.com
Chào các bạn, đối với anh em lập trình viên thì trong quá trình code có một việt rất quan trọng đó là viết comment.
Vậy comment trong INTELLIJ nghĩa là gì?
Vâng, comment là những chú thích, là những ghi chú với mục đích là để cho người viết code và cả người đọc code có thể hiểu được đoạn chương trình đó chạy như thế nào và mục đích là gì.
Nhưng trong thực tế có những comment lặp đi lặp lại với một dạng nhất định, nếu cứ mỗi lần tạo hàm mới lại hì hục viết comment thì sẽ rất mất thời gian.
Vì vậy trong bài viết này mình sẽ hướng dẫn anh em cách tạo một comment với định dạng sẵn, anh em chỉ cần gõ từ gợi ý là đoạn comment sẽ tự xổ ra.
#1. Ví dụ một đoạn comemnt với các thông tin
#2. Hướng dẫn tạo một template comment trong INTELLIJ
Đầu tiên các bạn vào mục
File=> chọnSetting…hoặc phím tắt làCtrl + Alt + Snhư hình bên dưới.Tiếp theo trong phần tìm kiếm các bạn nhập
Live Templates=> rồi chọn các lựa chọn như hình bên dưới.Để tạo một Template:
Sau khi có tên và nội dung template rồi thì các bạn bấm vào chữ
Definenhư hình ảnh bên dưới.Tại đây, nếu bạn định tạo comment cho ngôn ngữ lập trình nào thì chọn ngôn ngữ tương ứng. Nguyên nhân bởi vì mỗi ngôn ngữ có thể có các kiểu comment khác nhau.
Tiếp theo, các bạn bấm
Edit variablesđể chỉnh sửa các biến mà chúng ta sử dụng trong template. Ở đây mình có ba biến đó là:Sau khi chọn chức năng
Editthì đây chính là màn hình chúng ta sẽ sửa các biến, chính xác hơn chọn giá trị tương ứng cho các biến.Tương tự thì
dateTimemình sẽ chọn tương ứng vớitime()như hình bên dưới.Okay, vậy là công đoạn tạo template đã xong rồi. Bây giờ các bạn có thể gõ chữ “
com…” ở bất cứ đâu trong chương trình để tạo một comment với mẫu đã tạo.Đây chính là kết quả, các bạn có thể thấy có rất nhiều trường hợp chúng ta phải tạo các comment như thế này. Việc chỉ cần nhập từ gợi ý để tạo một comment dài như thế này là thực sự rất tiện lợi.
Không những bạn có thể tạo một comment như vậy, mà bạn còn có thể tạo ra rất nhiều các comment khác nhau.
Ví dụ trong phần
@update, mình cũng sẽ tạo một template với nội dung như ảnh bên dưới để phục vụ việc khi mình có cập nhật gì đó cho hàm mình đang viết.Các bạn cũng có thể gõ gợi ý
up…để tạo ra một comment tương ứng template mà các bạn đã định nghĩa thêm.Và đây chính là một comment đầy đủ, nhìn có vẻ rất là dài nhưng thông qua việc sử dụng
Live Templatemình đã viết đoạn comment chỉ với một hai phím gõ.#3. Kết luận
Vâng, như vậy là việc tạo comment ghi chú nhanh trong INTELLIJ với tính năng LIVE TEMPLATE cũng không có gì khó khăn cả, có đúng không ạ 🙂
Trên thực tế thì những dự án có nhiều người cùng làm và làm trong thời gian dài sẽ không thể tránh khỏi việc mỗi người code một kiểu.
Nếu không có các dòng comment để chú thích code thì thực sự rất khó cho người sau, chưa kể còn không biết được ai viết hàm đó, chức năng… đó để nhỡ có bị lỗi còn “lôi” ra hỏi.
Nhưng đôi khi việc viết comment lại khá tốn thời gian, vậy nên việc sử dụng Live Templates sẽ là một trong những cách rất hay để tạo nhanh comment mà không tốn quá nhiều thời gian cho nó.
CTV: Nguyễn Đức Cảnh – Bài viết gốc tại blogchiasekienthuc.com
Có thể bạn quan tâm:
Xem thêm Việc làm IT hấp dẫn trên TopDev