Dưới đây là bảng so sánh nhanh giữa Selenium và QTP dựa trên một số tiêu chí cơ bản để so sánh các công cụ kiểm thử tự động
STT
Tiêu chí
Selenium
QTP
1
Chi phí bản quyền
Đây là công cụ mã nguồn mở cho nên không có chi phí bản quyền, hoàn toàn miễn phí
Rất mắc…khoảng 5000USD cho 1 máy
2
Thực sự mô phỏng hành động của người dùng cuối
Selenium thực hiện hành động trong nền của trình duyệt tức là người sử dụng, có thể thực hiện các kiểm thử tự động với trình duyệt được thu nhỏ tối thiểu (minimized).
QTP thực hiện kiểm thử tự động tương đương với một người thực hiện các thao tác vào ứng dụng. Vì vậy, các trình duyệt không có thể được giảm thiểu (người sử dụng không thể thực hiện bất kỳ hành động nào khác trên máy tính trong khi kiểm thử đang chạy).
3
Plug-ins
Có và hoàn toàn miễn phí
Có. Người sử dụng phải trả tiền bản quyền
4
Nỗ lực và kỹ năng để sử dụng công cụ
Người dùng cần phải có kỹ năng tốt về lập trình và coding vì đây là điều kiện cần.
Đòi hỏi nỗ lực ít h ơn để tạo ra một kịch bản kiểm thử, vì nó có một môi trường phát triển rất tốt, thân thiện với người sử dụng.
5
Dễ dàng tạo ra các kịch bản kiểm thử?
Tốt. Selenium IDE Recorder không mạnh mẽ như QTP nhưng là một công cụ miễn phí, nhiều hành động không được ghi lại bởi các IDE và có thể tự nhập vào.
Hoàn hảo.
6
Hỗ trợ trên các HĐH
Windows, Linux, Unix và Macintosh.
Windows.
7
Loại ứng dụng
Web based applications.
Web-based và desktop applications.
8
Trình duyệt
IE, Firefox, Safari, Opera và một vài trình duyệt khác
IE, Chrome và Firefox.
9
Ngôn ngữ phát triển kịch bản kiểm thử
Java, Ruby, Python, C#, Perl, Groovy và nhiều ngôn ngữ khác
VBScript và/hoặc JavaScript.
10
Tích hợp với các công cụ quản lý thử nghiệm
Khi phát triển kiểm thử (test case) sử dụng C# trong VS thì có thể sử dụng MTM để quản lý test cases
HP Quality Center và TestDirector
11
Môi trường phát triển kiểm thử
Kịch bản thử nghiệm có thể được phát triển trong nhiều trình soạn thảo như Eclipse, Visual Studio, Netbeans…
Kịch bản thử nghiệm chỉ có thể được phát triển trong QTP.
12
Hỗ trợ kỹ thuật
Vì đây là công cụ m ã nguồn mở nên không có hỗ trợ kỹ thuật chính thức.
QTP cung cấp hỗ trợ kỹ thuật rất tốt qua điện thoại, mail, web, forum.
13
Quản lý và lưu trữ đối tượng giao diện (UI-Object)
Không. Đối tượng có thể được quản lý bằng cách sử dụng giao diện người dùng mở rộn g (UI-Element user extension) hoặc properties files. Tất cả các phương pháp trên đểu phải sử dụng code cứng (hard-code)
Có. QTP được xây dựng trong với Object Repository. Quản lý Object repository là khá dễ dàng trong QTP
14
Hỗ trợ cho các hộp thoại
Chỉ hỗ trợ 1 phần. Không thể thực hiện một số hành động như lấy tiêu đề của hộp thoại.
Có. QTP hỗ trợ tất cả các loại hộp thoại.
15
Hỗ trợ cho các kịch bản tải lên tập tin
Không. Selenium không hỗ trợ kịch bản này vì hạn chế JavaScript.
QTP không có vấn đề gì trong việc mô phỏng
Selenium là lựa chọn hoàn hảo nếu…
Developer chịu trách nhiệm phát triển và bảo trì các kiểm thử
Những kiểm thử bạn đang phát triển sẽ là 1 phần của một cơ sở hạ tầng lớn hơn
Chắc chắn là bạn sẽ thử hiện những kiểm thử trên trình duyệt mà thôi
Bạn nghĩ là bạn sẽ thực hiện những kiểm thử trên những môi trường khác ngoài Windows
Bạn muốn sử dụng những công cụ miễn phí
QTP có lẽ là lựa chọn tốt nếu…
Bạn muốn phát triển và duy trì các kiểm thử một cách nhanh chóng và dễ dàng.
Nếu bạn cần kiểm thử đáng kể bên ngoài trình duyệt
Hôm nay ngày 12/03, nhân kỷ niệm ngày World Wide Web, hãy cùng tìm hiểu về kiến trúc web (Web Architecture). Thiết nghĩ, với một thứ chúng ta làm việc, sử dụng hàng ngày, không ít thì nhiều, cũng nên hiểu về em nó đôi chút.
Duis id ante elit. Aliquam quis tellus id orci eleifend finibus. Donec consequat justo ligula, eget sodales purus hendrerit at.
Ut at interdum nunc. Maecenas commodo turpis quis elementum gravida.
Nunc ac sapien tellus. Quisque risus enim, tempus eget porttitor in, pellentesque vel urna.
Donec nibh massa, rutrum a sollicitudin eu,
lacinia in lorem.
1. DNS (Domain name server)
Graphic design is the paradise of individuality, eccentricity, heresy, abnormality, hobbies, and humors. — George Santayana
Vim te case nihil oblique, has partem interpretaris ne, ad admodum accusamus nam. Usu utinam dissentias referrentur ne, vim accusam voluptua pertinacia no. Est no posse utinam inermis, brute errem mentitum et ius, te prompta albucius quo. In pro simul soleat regione.
Ne reque offendit singulis mea, ad eos ferri doming nostrud. Duis suscipit usu ut, fuisset pericula ex est, et porro prompta his. Audire definiebas voluptatibus et duo, aperiam ocurreret ad nec. Vel ad nostrud principes. Ad liber congue iracundia sed, eirmod erroribus eam te, has veniam epicurei ea.
Pri probo alterum aliquando an. Duo appetere laboramus intellegat ea, ex suas diam exerci vix. Mel simul debitis id, est nusquam fuisset mentitum in. Te mei iudico iisque.
2. Load balancer
3. Web app servers
4. Database
5. Caching service
6a. Job queue
6b. Job servers
7. Full text search service
8. Services
9a. Data “firehose”
9b. Copy of data
9c. Data warehouse
10. Cloud storage data
11. CDN (Content delivery network)
Content delivery network, tạm dịch là Mạng lưới truyền tải nội dung. Tạm thời bỏ qua các khái niệm. Hằng ngày, chúng ta vẫn đọc báo, xem youtube, giao dịch online,… Chính những hoạt động này bản thân nó đã tương tác trực tiếp với CDN.
Vậy CDN ra đời với mục đích gì?.
Một buổi sáng đẹp trời, bạn truy cập website http://bbc.com. Tuy nhiên, do origin server nằm ở United Kingdom (khoảng cách xa, nội dung trang báo lại nặng), nên thời gian từ khi ấn enter cho tới khi thấy được nội dung tờ báo là 5s. Thời gian này tuy nhỏ, nhưng nếu phải làm việc nhiều, sẽ rất tốn thời gian. Để giảm thời gian tải này, CDN ra đời.
Ý tưởng:
Ở mỗi khu vực địa lý nhất định (ví dụ: cấp châu lục), đặt một serverCDN đóng vai trò như client trong mạng lưới Content Network, người dùng sẽ request tới serverCDN gần nhất mà mình có thể tiếp cận nhằm giảm thời gian và quá trình request tới origin server ở xa.
Thay request phải vượt Đại Tây Dương (3s), với CDN, chỉ mất 1s cho CDN Server ở UK
Nhưng làm gì có nội dung BBC ở serverCDN!
Xin thưa là có, server ở mỗi nơi đều có lưu trữ bộ đệm (cached), bao gồm hình ảnh, tài liệu, video, … Mỗi khi chúng ta request, thay vì tới thẳng origin server, sẽ chuyển qua request tới serverCDN, từ đó giảm thời gian truy xuất. Nếu số lượng request nhiều, việc sử dụng CDN còn giúp giảm tải cho origin server.
Tăng Tốc Và Bảo Mật Website Với vStack WordPress Plugin
Với hơn 60% website trên thế giới được xây dựng trên nền tảng WordPress, nhu cầu tăng tốc và bảo mật website bằng các plugin hiện nay luôn được các doanh nghiệp ưu tiên hàng đầu. VNG Cloud giới thiệu giải pháp vStack WordPress plugin, hỗ trợ doanh nghiệp tăng tốc và bảo mật toàn diện, nâng cao 60% tốc độ của website.
Với các tính năng nổi bật như:
Hỗ trợ tăng tốc website
Cấu hình tường lửa theo chuẩn
Tự động lọc mã độc và bảo vệ khỏi các cuộc tấn công
Với vStack plugin của VNG Cloud, website của bạn sẽ được tăng tốc và bảo vệ chỉ bằng vài thao tác click đơn giản:
Bước 1: Cài đặt plugin
Cài trực tiếp trên kho plugins: Bằng cách tìm “vStack” trên plugins của wordpress.org. Bạn chọn “Active” để cài đặt.
Upload plugin vào source code
Trong trường hợp “vStack” plugin không tìm thấy trên plugins của wordpress.org bạn có thể tải plugin từ github của vngcloud và giải nén vào wp-content/plugins.
Bước 2: Active Plugin
Khi plugin được hiển thị trong danh sách plugins, bạn chọn “Active” để sẵn sàng sử dụng, và chọn “Settings” để tiến hành xác thực và cấu hình.
Bước 3: Đăng nhập vào tài khoản VNG Cloud
Nếu bạn chưa có tài khoản VNG Cloud, chọn “Create Your Free Account” để tạo tài khoản VNG Cloud, một cửa sổ đăng kí sẽ giúp bạn tạo tài khoản.
Nếu bạn đã có tài khoản VNG Cloud, chọn “Sign in here”, một cửa sổ đăng nhập sẽ giúp bạn đăng nhập bằng cách chọn “Save API Credentials”.
Ở đây, bạn sẽ phải đăng nhập bằng tên tài khoản của VNG Cloud, và một TOKEN.
Nếu bạn chưa có TOKEN, bạn chọn “Get Your API Key from here”, một cửa sổ đăng nhập sẽ hiện ra.
Đăng nhập thành công, bạn sẽ được trả về mã TOKEN. Vui lòng lưu dự phòng TOKEN này, trong trường hợp bạn cần gỡ hoặc cài lại plugin, TOKEN này sẽ giúp bạn đăng nhập lại.
Bước 4: Quản lí plugin
Sau khi đăng nhập xong, bạn sẽ vào được trang quản lí.
Phía trên góc trái màn hình, bạn sẽ thấy tên miền có dạng “xxx.wp.vngstack.com”.
Đây là tên miền được khởi tạo định danh cho website của bạn trên vStack. Bằng cách tạo record CNAME domain website của bạn về đây, website của bạn đã sẵn sàng sử dụng dịch vụ.
Giả lập Google Cloud Storage sử dụng fake-gcs-server
Bài viết được sự cho phép của tác giả Nguyễn Hữu Khanh
Khi làm việc với các Cloud Provider, chúng ta cần tính toán đến các giải pháp để tiết kiệm chi phí, ít nhất là ở giai đoạn development. Vì đa số các service của các Cloud Provider mà chúng ta cần sử dụng, sẽ ít nhiều tốn tiền. Một giải pháp mà mình giới thiệu với các bạn trong bài viết này là về giả lập Google Cloud Storage sử dụng một open-source tên là fake-gcs-server, phù hợp cho những dự án nào có sử dụng Google Cloud Platform. Nó giúp chúng ta có thể start lên một standalone server có chức năng gần giống với Google Cloud Storage. Các bạn có thể sử dụng các thư viện của Google provide để làm việc với Google Cloud Storage, để làm việc với open-source này luôn.
fake-gcs-server cung cấp cho chúng ta một Docker Image, giúp chúng ta có thể dễ dàng start nó lên chỉ với vài bước.
Cụ thể, các bạn cần chạy Docker command sau:
docker run -d --name fake-gcs-server -p 4443:4443 fsouza/fake-gcs-server
Lúc này, nếu các bạn request tới URL để lấy thông tin Buckets list với host port sử dụng fake server: https://localhost:4443/storage/v1/b, các bạn sẽ thấy kết quả như sau:
Items hiển thị empty vì chúng ta chưa có một bucket nào trong fake-gcs-server.
Các bạn có thể mount một số data có sẵn và chạy fake-gcs-server như sau:
docker run -d --name fake-gcs-server -p 4443:4443 -v ${PWD}/examples/data:/data fsouza/fake-gcs-server
${PWD} là thư mục hiện hành các bạn đang chạy lệnh Docker cộng với thư mục example/data, sẽ được map với thư mục /data bên trong container của fake-gcs-server. Các bạn có thể thay đổi ${PWD}/examples/data thành bất cứ thư mục nào mà các bạn muốn. Những thư mục trong thư mục ${PWD}/examples/data này sẽ là những bucket, và tất nhiên những tập tin nằm trong các bucket sẽ là những object của những bucket này.
Ví dụ mình có tập tin test.txt nằm trong thư mục /Users/khanh/Document/data/sample-bucket, mình chạy câu lệnh start fake-gcs-server như sau:
docker run -d --name fake-gcs-server -p 4443:4443 -v /Users/khanh/Documents/data:/data fsouza/fake-gcs-server
thì lúc này sample-bucket sẽ là một bucket trong fake-gcs-server, và tập tin test.txt sẽ là một object trong bucket này.
Request lại URL https://localhost:4443/storage/v1/b, các bạn sẽ thấy kết quả như sau:
Lấy thông tin tất cả các object của bucket với URL https://localhost:4443/storage/v1/b/sample-bucket/o, các bạn sẽ thấy kết quả như sau:
Các bạn có thêm tuỳ ý bao nhiêu bucket cũng được, bao nhiêu object cũng được.
Mặc định thì fake-gcs-server sử dụng HTTPS, các bạn có thể sử dụng HTTP bằng cách thêm vào command start nó tham số scheme như sau:
Lúc này chúng ta có thể sử dụng fake-gcs-server với HTTP:
Sử dụng Spring Cloud GCP Storage để access vào bucket của fake-gcs-server
Để access vào các bucket trên Google Cloud Storage, các bạn có thể sử dụng thư viện spring-cloud-gcp-storage. Chúng ta cũng có thể sử dụng thư viện này với fake-gcs-server.
Một điều các bạn cần lưu ý là chúng ta không cần sử dụng credentials để access vào các bucket của fake-gcs-server.
Mình sẽ tạo một Maven project đơn giản, khai báo sử dụng spring-cloud-gcp-storage để access vào fake-gcs-server mà mình đã start ở trên, như sau:
Ở đây, mình không sử dụng credentials để access vào bucket của fake-gcs-server. Các bạn có thể thao tác trên bucket của fake-gcs-server tương tự như trên Google Cloud Storage sử dụng thư viện này.
Học cái gì đó mục đích cuối cùng là để có một nghề nghiệp hoặc sự nghiệp ổn định. Đó cũng là định luật muôn thuở và luôn đúng với bất kỳ người nào đang tìm kiếm các trung tâm hay học viện để học một cái gì đó? Vậy sau khi học lập trình, chúng ta có thể làm những nghề nào? Chia buồn với bạn, không phải cứ học xong thì Coder có thể làm bất cứ nghề nào về lập trình cũng được.
Bởi thế, trả lời cho câu hỏi “Tôi học cái này để làm gì?” luôn cần thiết ngay từ những bước chân đầu tiên. Câu trả lời chung chung thì rất nhiều. Nhưng câu trả lời chính xác là xác định mục đích cuối cùng và mong muốn của bạn là gì sau khi học lập trình xong. Sau đây, mình sẽ cho bạn những gợi ý về nghề nghiệp phù hợp con đường mà bạn đang theo đuổi.
Đây là công việc khá phổ biến về lập trình. Một Software Engineẻ cần phải học JavaScript, Ruby, HTML, và CSS. Ranh giới giữa Software Engineer và Software Developer khá mờ nhạt, vì vai trò của họ gần như tương đương nhau. Bạn có thể tìm hiểu kỹ hơn trên Reddit để có cái nhìn sâu hơn.
Đối với hầu hết mọi trường hợp, Software Engineer cần phải học lập trình và hiểu sản phẩm cuối được thiết kế và quản trị như thế nào. Thông qua những kiến thức đã học, kỹ sư phần mềm sẽ tìm ra hướng giải quyết hay phát triển phần mềm của mình.
Đối tượng phù hợp: Coder từng trải hay chuyên môn cao.
Đây là một nghề nghiệp đang hấp dẫn trong giới lập trình, theo điều tra của Glassdoor hay LinkedIn và một số người khác được khảo sát. Sở dĩ những người này khó kiếm vì yêu cầu kỹ năng đa dạng. Một người làm công việc này phải vừa là software engineer, vừa thực hành và học lập trình, vừa phân tích thống kê và trình bày số liệu để kể những câu chuyện và khám phá những thông tin đầy sức mạnh từ một lượng lớn dữ liệu thu thập được.
Data Scientist phải học Python, SQL, R và Java và sử dụng chúng thành thạo để xây dựng thuật toán và xây những model được sử dụng để phát hiện vấn đề mới và dự đoán hành vi người tiêu dùng.
Đối tượng phù hợp: Coder sáng tạo và thích hiện thực hóa các ý tưởng
Nếu bạn muốn tạo ra thứ gì đó để mọi người có thể xem trên mạng Internet, bạn nên là một Front-End Developer. Những người này sẽ phải học Front-end như JavaScript, HTML và CSS để hoàn thiện bề nổi của website. Ngoài ra, công việc của Front-End Developer còn liên quan tới thiết kế website và Back-End Developer để có thể hoàn thiện mọi thứ từ giao diện ấn tượng cho tới các chức năng độc đáo.
Bạn muốn là một Back-End Developer
Đối tượng phù hợp: Coder có kỹ năng tổ chức và đáng tin cậy
Back-End Developer vẫn thường bị đánh giá thấp. Họ sẽ phải xây dựng các nền tảng đặt nền móng cho các Front-End Developer thông qua các ngôn ngữ PHP, Java, Ruby, Python hay SQL. Ngoài ra, Back-End Developer còn sử dụng các ngôn ngữ server-side để kéo thông tin từ cơ sở dữ liệu và chuyển lại cho người dùng thông qua định dạng của ngôn ngữ Front-End.
Bạn muốn là một Full-Stack Developer
Đối tượng phù hợp: Coder trọn gói, hay còn gọi Coder “bao sô”
Full-Stack Developer nổi lên cùng với phong trào khởi nghiệp trên toàn cầu. Các công ty khởi nghiệp cần cả Front-End lẫn Back-End Developer, nhưng không đủ nguồn lực dành cho hai team độc lập. Full-Stack Developer cũng không phải là bậc thầy về ngôn ngữ lập trình. Họ biết mọi thứ ở mức vừa đủ để tạo ra và vận hành một website, đồng thời có thể xử lý sự cố ở Back-End khi có phát sinh.
Đối tượng phù hợp: Coder yêu thích ứng dụng di động
Đây là những người được sinh ra dành cho các ứng dụng di động. Mobile Developer cần ngôn ngữ Swift để tạo ra ứng dụng cho hệ điều hành iOS , trong khi với Android, họ cần ngôn ngữ Java, C# hoặc C/C++. Với sự phố biến của các thiết bị di động, số lượng Mobile Developer đã tăng trưởng đáng kể trong thời gian vừa qua, tỉ lệ thuận với số lượng ứng dụng phục vụ cho cộng đồng cũng ngày một nhiều hơn
Bạn muốn là một UI/UX Designer
Đối tượng phù hợp: Coder quan tâm đến trải nghiệm của người dùng và không quan tâm đến chức danh của mình
Chức danh của những Coder này vẫn còn gây ra rất nhiều tranh cãi và có không ít chủ đề bàn luận nên có hay không sự tồn tại vị trí UI/UX Designer trong lĩnh vực IT. Vì thế chúng ta sẽ không đi sâu về phương diện này, thay vào đó là cách một UI/UX Designer có thể tận dụng code vào trong công việc hằng ngày.
UX Designer tập trung hơn vào trải nghiệm tổng thể của người dùng, họ sẽ thiết kế các phiên bản test và bản thử nghiệm trước khi chuyển chúng đến tay của Front-End Developer. UI/UX Designers cũng thường không phải lập trình, nhưng hiểu biết coding sẽ giúp công việc của họ hiệu quả hơn. Ví dụ họ cần hiểu một chút về HTML hay Swift để hạn chế những trở ngại về công việc của mình.
Bạn muốn là một Product Manager
Đối tượng phù hợp: Coder thông thường nhưng có kỹ năng lãnh đạo và khả năng đọc mã code.
Product Manager có thể không phải là một Coder trong thời điểm hiện tại năm 2018. Nhưng họ có khả năng hiểu các đoạn mã và chức năng của nhiều ngôn ngữ khác nhau, để có thể hỗ trợ nhiều nhóm khi cần thiết. Product Manager làm sao có thể hiểu được những gì Software Engineer giải thích nếu không nắm các kiến thức căn bản về lập trình. Họ không cần phải là Coder, nhưng họ giúp xử lý các vấn đề hiệu quả hơn.
Đối tượng phù hợp: Coder sở hữu tất cả đáp án và tạo ra những kho dữ liệu khổng lồ
Ngay tên của chức danh này đã nói lên tất cả công việc của họ. Họ tạo ra và quản lý dữ liệu trong môi trường IT. Database Developer có thể làm việc như Database Administrator, đảm bảo khả năng lưu trữ thông tin, đảm bảo sự an toàn và khả năng truy xuất những thông tin này. Những người này cũng có thể phải liên tục nâng cấp hệ thống, và chịu trách nhiệm cập nhật liên tục dữ liệu trong hệ thống này.
Bạn muốn có vị trí trong DevOps
Đối tượng phù hợp: Coder nhanh nhẹn, thích làm việc với các quy trình vận hành
DevOps là viết tắt của Developement and Operations, kết nối quá trình phát triển và vận hành một ứng dụng hay website theo một quy trình thống nhất. Theo truyền thống, phải mất rất nhiều thời gian để một sản phẩm chuyển đổi từ bộ phận phát triển qua bộ phận triển khai. Và bộ phận DepOps giúp cho quá trình này diễn ra nhanh hơn, giúp người dùng không bị gián đoạn thông tin và các doanh nghiệp tăng khả năng cạnh tranh trong môi trường IT đang ngày một đông đúc hơn.
Bạn muốn làm bất cứ việc gì mình thích, ở nơi mà mình muốn
Bạn có thể thấy sự đa dạng về nghề nghiệp của một Coder, không đâu xa mà ngay từ danh sách này. Chưa từng có một quan điểm hay chỉ dẫn cho việc lựa chọn ngôn ngữ lập trình tiếp theo sau khi hoàn thành xong một ngôn ngữ lập trình nào đó. Ví dụ một Graphic Designer có thể học thêm kiến thức cơ bản về Front-End để giúp tăng khả năng cạnh tranh trong nghề nghiệp của mình. Ít nhiều cũng giúp cho họ có cái nhìn rõ ràng hơn trước những mô tả của bạn Front-End.
Có nhiều điều thú vị nhưng cũng tùy vào cách Coder lựa chọn công việc của mình. Không phải công ty nào cũng giống nhau và công việc coding ở công ty này tương tự công ty kia, chưa kể hàng ngàn các lĩnh vực khác nhau sẽ có cách lập trình khác nhau. Data Scientist có thể là nghề được biết đến nhiều nhất trong khoa học dữ liệu, nhưng vẫn còn đó vị trí Phân tích dữ liệu, Kỹ sư tự động hóa hay kỹ sư Big Data.
Tuy nhiên hãy thoải mái vì hiện tại có rất nhiều nghề nghiệp dành cho Coders. Bước tiếp theo của tiến trình chính là các định sở thích của mình và ngôn ngữ lập trình phù hợp nhất. Cách hay nhất chính là tham gia các sự kiện coding để có cái nhìn và tiếp cận rõ hơn về hướng đi cho tương lai. uCode.vn cung cấp cho bạn rất nhiều khóa học để nắm vững các kiến thức nền tảng thông qua các công cụ và ví dụ thực tiễn. Chúng tôi cũng có những buổi hội thảo cũng như tư vấn nhằm giúp các bạn tìm ra hướng đi phù hợp cho bản thân.
Bài viết được sự cho phép của tác giả Lê Xuân Quỳnh
Tuần trước, chúng ta đã xem qua 1 cách custom về thư viện bàn phím hiển thị gợi ý tiền Việt Nam. Hôm nay tôi sẽ hướng dẫn cách tạo 1 thư viện để gọi network dạng restful API. Thư viện tên là Qnetwork. Bạn có thể tải trên github tại đường dẫn:
Đầu tiên, bạn cần biết rằng tôi xây dựng thư viện này tốt nhất cho kiến trúc MVVM. Tuy nhiên bạn vẫn có thể sử dụng nó cho các architecture khác mà bạn muốn. Nếu hiểu theo cách đơn giản, bạn dùng thư viện này, bạn tạo các service để gọi API. Sau đó, bạn dùng nó để gọi bất cứ ở đâu bạn muốn.
Trong 1 bài viết trước đây, tôi đã giới thiệu khá kỹ càng cách viết API cho nó. Các bước tiến hành như sau:
Tạo 1 module Github. Mỗi module sẽ phục vụ cho 1 màn hình riêng biệt. Trong thiết kế MVVM tôi hay làm như vậy, module bao gồm View, Model, servive gọi API và view model. Bạn có thể mở souce code ở trên ra xem.
Tạo 1 file GithubAPI. File này chứa cụm API cần gọi. Thông thường trong ứng dụng của tôi sẽ có nhiều file dạng *API. Mỗi 1 file chứa 1 cụm, ví dụ AuthenAPI sẽ chứa cụm đăng nhập, đăng xuất. FeedAPI chứa cụm API liên quan đến feed. Cách đặt tên sẽ sát nghĩa nó làm gì. Mô tả file này như sau:
//
// GithubAPI.swift
// QNetworkDemo
//
// Created by Xuân Quỳnh Lê on 2021/06/26.
//
import Foundation
import QNetwork
import Moya
enum GithubAPI {
case searchRepositories(q: String, sort: String, order: String, page: Int)
}
extension GithubAPI: TargetType {
var baseURL: URL {
let url = URL(string: Configs.Network.baseUrl)!
return url
}
var path: String {
switch self {
case .searchRepositories:
return "search/repositories"
}
}
var method: Moya.Method {
return .get
}
var sampleData: Data {
var dataUrl: URL?
switch self {
case .searchRepositories:
if let file = Bundle.main.url(forResource: "SearchRepositoriesResponse", withExtension: "json") {
dataUrl = file
}
}
if let url = dataUrl, let data = try? Data(contentsOf: url) {
return data
}
return Data()
}
var task: Task {
switch self {
case .searchRepositories:
if let parameters = parameters {
return .requestParameters(parameters: parameters, encoding: parameterEncoding)
}
}
return .requestPlain
}
var headers: [String: String]? {
return ["Content-type": "application/json"]
}
var parameters: [String: Any]? {
var params: [String: Any] = [:]
switch self {
case .searchRepositories(let q, let sort, let order, let page):
params["q"] = q
params["sort"] = sort
params["order"] = order
params["page"] = page
}
return params
}
// For json encode. Use in post request
var jsonEncoding: JSONEncoding {
return JSONEncoding.default
}
// For param encode. Use in get request
var parameterEncoding: ParameterEncoding {
return URLEncoding.default
}
}
Sau đó bạn tạo tiếp file GithubSearchService. Ở đây bạn cần truyền 1 struct Codable để lúc API có response, bạn cần đưa nó vào và chuyển json sang struct này. Cụ thể là struct GithubSearchResponse:
// MARK: - GithubSearchResponse
struct GithubSearchResponse: Codable {
let totalCount: Int?
let incompleteResults: Bool
let items: [GithubSearchItem]?
enum CodingKeys: String, CodingKey {
case totalCount = "total_count"
case incompleteResults = "incomplete_results"
case items
}
}
// MARK: - Item
struct GithubSearchItem: Codable {
let id: Int
let name: String?
let htmlURL: String?
let itemDescription: String?
enum CodingKeys: String, CodingKey {
case id, name
case htmlURL = "html_url"
case itemDescription = "description"
}
}
Nhiều bạn hỏi tôi sao có thể từ json chuyển sang struct được như trên. Tôi là 1 người lười biếng, nên tôi hay vào trang này để chuyển: https://app.quicktype.io
Sau đó bạn chỉ cần chỉnh sửa tên cho hợp lý là được. Bạn làm nhiều sẽ quen tay thôi.
Sau khi xong cụm service ở trên, bạn cần tạo GithubViewModel:
import Foundation
class GithubViewModel {
// Service call API
let service: GithubSearchService!
// Callback to view
var needReloadTableView: (() -> Void)?
var needShowError: ((String) -> Void)?
var needSetStateBottomIndicatorView: ((_ show: Bool) -> Void)?
private var page: Int = 0
private var language = ""
private var incompleteResults = false
// Datasource
private var githubSearchItem: [GithubSearchItem] = []
init() {
// Turn on is test is true if you need test for API
self.service = GithubSearchService(isTest: false)
}
/// Clear tableview data source
func clearTableView() {
self.page = 0
self.incompleteResults = false
self.githubSearchItem.removeAll()
self.needReloadTableView?()
}
/// Request repositories
func requestRepositories(language: String, loadMore: Bool = false) {
// Check when load more
if self.incompleteResults {
return
}
if !loadMore {
self.page = 0
self.githubSearchItem.removeAll()
}
self.language = language
// Default param
let sort = "stars"
let order = "desc"
self.service.searchRepositories(language: language, sort: sort, order: order, page: self.page) { [weak self] result in
guard let strongSelf = self else { return }
// Check when load more
if loadMore {
strongSelf.needSetStateBottomIndicatorView?(false)
}
switch result {
case .success(let githubResponse):
strongSelf.incompleteResults = githubResponse.incompleteResults
if let items = githubResponse.items {
items.forEach( {strongSelf.githubSearchItem.append( $0 )})
}
strongSelf.needReloadTableView?()
case .failure(let error):
strongSelf.needShowError?(error.description)
}
}
}
func numberOfRowsInSection(section: Int) -> Int {
return githubSearchItem.count
}
func cellForRowAt(indexPath: IndexPath) -> GithubSearchItem {
// Check if the last row number is the same as the last current data element
if indexPath.row == self.githubSearchItem.count - 1 {
self.page += 1
self.requestRepositories(language: language, loadMore: true)
self.needSetStateBottomIndicatorView?(true)
}
return githubSearchItem[indexPath.row]
}
}
Nhiều bạn sẽ tò mò tại sao tôi lại viết được như trên. Cũng tương tự, tôi hay tải source của người khác về xem. Sau đó tôi clone y hệt, người ta viết gì, tôi viết nấy. Lâu dần quen tay, có phản xạ. Cuối cùng là hiểu được ý nghĩa mà người ta làm. Dù sao thì thực hành vẫn là cách tốt nhất để học lập trình.
Bạn xem kỹ video, làm theo anh ấy, bạn sẽ tạo được 1 swift package và có thể đưa cho người khác sử dụng thông qua 1 đường dẫn. Với Qnetwork, đơn giản bạn chỉ cần thêm đường dẫn này vào phần swift package của bạn(Xcode ➞ File ➞ New ➞ Swift Package):
Đm, ví dụ đọc chán đời vcl, lớn hơn 4 kiểu gì chả lớn hơn 0. Nhưng tui chán nghĩ cái ví dụ cụ thể, nên các ông đọc tạm. Ok, lúc này ta cần bind class cho end user biết lúc nào email input đúng, khi nào sai
Teleport provides a clean way to allow us to control under which parent in our DOM we want a piece of HTML to be rendered, without having to resort to global state or splitting this into two components.
Teleport cung cấp một cách hoàn hảo để control component cha nào muốn render thêm HTML ở trên DOM, nhưng không cần phải resort lại global state hoặc chia nó thành 2,3 component nhỏ.
Teleport ở đây cũng được hiểu như đường ống bên Mẽo hay ArabSaudi đã suy nghĩ và có plan để hiện thực hóa.
Thay vì chuyển người hay chuyển hàng thì ta chuyển code ra ngoài Vue application (ra ngoài <div id=”app”>)
Kinh Nghiệm Khi Phỏng Vấn Với Người Nhật Giúp Ứng Viên Ghi Điểm Tuyệt Đối
Đối với nhiều ứng viên, phỏng vấn luôn là phần căng thẳng và khó khăn vì cần phải cố gắng thể hiện tốt nhất năng lực của bản thân trực tiếp với nhà tuyển dụng. Đặc biệt, với người Nhật – những người được xem là có lối sống quy củ và tác phong nghiêm túc bậc nhất, việc phỏng vấn sẽ càng trở nên quan trọng hơn. Ở Việt Nam hiện nay đã xuất hiện khá nhiều các công ty IT đến từ Nhật Bản. Vậy có những kinh nghiệm phỏng vấn với người Nhật nào mà các ứng viên nói chung mà các lập trình viên nói riêng không nên bỏ qua nếu muốn đậu phỏng vấn?
Kinh Nghiệm Khi Phỏng Vấn Với Người Nhật Giúp Ứng Viên Ghi Điểm Tuyệt Đối
Cần chuẩn bị thật tốt trước khi bắt đầu buổi phỏng vấn
Khi biết mình được lên lịch để tham gia phỏng vấn với doanh nghiệp Nhật Bản, bạn cần ngay lập tức chuẩn bị cho mình mọi “hành lí” một cách chỉn chu nhất. Với người người Nhật, cái nhìn đầu tiên, sự tiếp xúc từ những giây đầu tiên ảnh hưởng khá nhiều đến thái độ và sự đánh giá của họ đối với bạn. Chính vì thế, việc có được một vẻ ngoài gọn gàng, thái độ lịch sự và chuẩn bị đầy đủ mọi tài liệu là rất cần thiết.
Đến đúng giờ là yếu tố tuyệt đối nên tuân thủ trong mọi cuộc phỏng vấn, nhất là với người Nhật. Ứng viên nên chuẩn bị cho mình một bộ Tây phục gọn gàng và vừa vặn để giúp bạn trông chuyên nghiệp và thành thạo hơn. Đầu tóc nên được cắt và buộc gọn gàng, phái nữ có thể trang điểm nhẹ nhàng để gây ấn tượng tốt hơn với nhà tuyển dụng. Khi gặp người phỏng vấn bạn nên cúi nhẹ người để chào và nở nụ cười thân thiện. Các kỹ năng mềm được phát huy khi giao tiếp sẽ giúp bạn rất nhiều trong quá trình phỏng vấn nhờ thái độ hòa nhã và cởi mở này.
Một số lưu ý khi trả lời phỏng vấn với người Nhật
Trả lời thành thật khi giới thiệu về bản thân và những điểm mạnh, điểm yếu
Người Nhật có khả năng phán đoán thái độ và biểu cảm của người đối diện khá tốt, vậy nên những ứng viên trả lời về bản thân theo kiểu nói quá hay quanh co thường rất dễ bị phát hiện. Khi trả lời, ứng viên hãy cố gắng giới thiệu một cách ngắn gọn và rõ ràng các thông tin về bản thân mình cũng như những kinh nghiệm làm việc đã có được. Hãy tự tin và nhìn thẳng vào đối phương khi trả lời, đó cũng là một cách để thể hiện bản lĩnh và sự mạnh mẽ của ứng viên.
Nhắc đến các điểm mạnh và điểm yếu của bản thân một cách thành thật. Nếu có thể, hãy khéo léo cho nhà tuyển dụng thấy được rằng những điểm mạnh này của bạn sẽ đóng góp được gì cho công ty và các điểm yếu sẽ được bạn khắc phục như thế nào trong tương lai. Sự thành thật khi trả lời những câu hỏi này sẽ giúp bạn rất nhiều khi nhà tuyển dụng tiếp tục đặt những câu hỏi từ câu trả lời của bạn và khai thác sâu hơn.
Việc đạt được thành tựu trong công việc hay các bằng cấp bạn tích lũy được trong quá trình trau dồi kiến thức chuyên môn của mình là rất tốt. Điều đó chứng tỏ năng lực chuyên môn của bạn đủ giỏi và bạn hoàn toàn có thể đảm nhận công việc ở vị trí mới, công ty mới. Tuy nhiên, với người Nhật, họ đánh giá cao tinh thần ham học hỏi, sự khiêm tốn và sẵn sàng chấp nhận những thách thức hơn là các thành tích của một cá nhân.
Người Nhật rất khiêm tốn. Người Nhật không phủ nhận năng lực của một cá nhân nhưng điều họ thích thú vẫn là sự hài hòa, do đó đây cũng là lưu ý quan trọng bạn cần nắm về kinh nghiệm phỏng vấn với người Nhật. Hãy kể về những thành tích của mình một cách vừa đủ và chia sẻ với người phỏng vấn tinh thần sẵn sàng cống hiến và không ngại học hỏi của bạn để buổi phỏng vấn thành công hơn nhé!
Lịch thiệp và thoải mái trong cách ứng xử
Đừng quá gồng mình hay căng thẳng vì lo sợ trong buổi phỏng vấn. Hãy thoải mái với chính mình và người đối diện để buổi phỏng vấn diễn ra suôn sẻ hơn, hai bên có thể trao đổi thông tin cho nhau một cách dễ dàng để hiểu rõ nhau hơn. Hãy tự tin về những gì mình chia sẻ và thoải mái trao đổi với nhà tuyển dụng mọi vấn đề mà bạn gặp phải để tìm được hướng đi chính xác nhất cho mình nhé.
Ngoài ra, trong các buổi phỏng vấn, ứng viên cũng có thể mang theo sổ tay để ghi chú các vấn đề cần thiết hoặc muốn lưu ý. Nhà tuyển dụng sẽ không có vấn đề gì với việc này mà thậm chí còn đánh giá cao những người chú trọng đến việc ghi chép để tránh quên thông tin sau này. Điều này cho thấy bạn là người cẩn thận và luôn biết cách chuẩn bị tốt trong mọi tình huống.
Mỗi đất nước, mỗi con người đều có nhiều tính cách khác nhau và nhiều thái độ khác nhau với việc phỏng vấn. Để thành công trong một buổi phỏng vấn, kinh nghiệm phỏng vấn với người Nhật là bạn hãy chia sẻ thành thật và thẳng thắn để hai bên có thể hiểu rõ nhau và làm việc tốt đẹp hơn trong thời gian sau này. Đón đọc thêm nhiều bài viết hấp dẫn khác tại TopDev dành cho dân IT nhé!
Cách cài đặt plugin gợi ý code Tabnine, thuật toán AI thông minh
Bài viết được sự cho phép của blogchiasekienthuc.com
Chào các bạn, chúng ta đều biết rằng, ngày nay việc viết mã nguồn (code) đối với lập trình viên không còn là việc quan trọng hàng đầu nữa.
Chính vì vậy, ngày càng có nhiều công cụ ra đời để hỗ trợ cho lập trình viên giảm bớt thời gian vào những việc không cần thiết, như gõ cọc cạch từng dòng mã nguồn.
Còn ở trong bài viết này thì mình sẽ cùng các bạn cài đặt plugin Tabnine trên các phần mềm soạn thảo code hàng đầu tiện nay như: VS Code, InteliJ Idea, Sublime Text. Tabnine cũng là một AI gợi ý code khá hay mà các bạn nên thử.
I. Tabnine là gì?
Tabnine bản chất là một công cụ được phát triển dựa trên các thuật toán học sâu (Deep Learning), với dữ liệu đào tạo được lấy từ hơn hai triệu tệp từ mã nguồn trên Github.
Hiện tại thì plugin Tabnine hỗ trợ khoảng hơn ba mươi ngôn ngữ lập trình khác nhau. Các bạn có thể tham khảo danh sách mà nó hỗ trợ trong hình bên dưới.
Ngoài ra thì Tabnine cũng hỗ trợ nhiều công cụ lập trình khác nhau, trong số đó hầu hết là các công cụ lập trình phổ biến. Cụ thể là:
II. Cài đặt Tabnine trên các công cụ VS Code, InteliJ Idea, Sublime Text
Okay, trong phần tiếp theo này mình sẽ cùng các bạn cài đặt Tabnine trên VS Code, IntelliJ Idea và Sublime Text – đây đều là những công cụ lập trình phổ biến hàng đầu hiện nay.
#1. Cài đặt Tabnine trên Visual Studio Code (VS Code)
+ Bước 1: Các bạn vào mục Extension => sau đó tìm kiếm từ khóa Tabnine như hình bên dưới.
+ Bước 2: Chọn kết quả đầu tiên => và sau đó bấm Install để bắt đầu cài đặt.
Quá trình cài đặt diễn ra tự động, nếu trong trường hợp bạn không muốn dùng nữa thì có thể nhấn Disable để vô hiệu hóa tạm thời, hoặc nhấn Uninstall để gỡ bỏ Plugin nhé.
#2. Cài đặt Tabnine trên InteliJ Idea
+ Bước 1: Đối với phần mềm lập trình IntelliJ thì đầu tiên, các bạn vào phần: File => chọn Setting => và chọn Plugin
+ Bước 2: Ở bước tiếp theo, các bạn chọn Plugins => chọn Tab Marketplace => sau đó tìm kiếm từ khóa Tabnine => và bấm Install để cài đặt.
Các bạn lưu ý là khi cài đặt một plugin trên IntelliJ thì bạn phải Restart lại để active plugin đó như hình bên dưới nhé.
#3. Cài đặt Tabnine trên Sublime Text
+ Bước 1: Đầu tiên các bạn vào mục Tools => chọn Install Package Control… để cài đặt Package Control..
+ Bước 2: Các bạn tiếp tục vào mục Tools => Command Palette… Hoặc phím tắt là Ctrl + Shift + P
+ Bước 3: Tiếp tục các bạn tìm kiếm từ khóa Install Package trong thanh tìm kiếm hiện ra như hình bên dưới.
+ Bước 4: Cuối cùng các bạn gõ Tabnine => và chọn kết quả đầu tiên như hình bên dưới sau đó bấm vào để cài đặt.
III. Kết luận
Vâng, như vậy là việc cài đặt plugin Tabnine trên VS Code, InteliJ Idea và Sublime Text cũng tương đối đơn giản phải không nhỉ 🙂
Việc sử dụng các công cụ gợi ý mã nguồn thực sự đem lại nhiều lợi ích về mặt tốc độ cũng như sự chính xác trong cú pháp. Các bạn có thể thấy rõ trong hình bên dưới.
Tuy nhiên, nói đi cũng phải nói lại, chúng ta vẫn nên nắm được các cú pháp cơ bản của các ngôn ngữ lập trình, bởi vì bản chất lập trình viên hay nhà phát triển vẫn là người quyết định.
Và chỉ khi nắm rõ được những gì chúng ta muốn thì lúc đó các công cụ hỗ trợ mới có ý nghĩa thực sự và thể hiện đúng vai trò của nó. Hẹn gặp lại các bạn trong các bài viết tiếp theo nha !
Bài viết được sự cho phép của tác giả Lê Xuân Quỳnh
Xin chào, lại là codetoanbug.com đây. Hôm nay chúng ta sẽ cùng sử dụng 1 design system framework cho iOS. Cụ thể chúng ta sẽ xây dựng màn hình giao diện như sau:
Giao diện này thư viện đã làm sẵn, việc của bạn là thay đổi chữ trên màn hình. Hoàn toàn đơn giản và không mất thời gian.
Nếu bạn là 1 developer thích quan tâm về trải nghiệm người dùng, các phong cách thiết kế, thì có lẽ bạn đã nghe qua khái niệm design system. Mình xin phép chia sẻ các bài viết dễ hiểu về design system tại đây của tác giả An:
Vậy FinniversKit là chuyển thể 1 design system trên figma hay các công cụ thiết kế khác thành framework có thể sử dụng được trên iOS.
Cùng dạo qua về framework này 1 chút:
Color – Font – Spacing
Chúng ta có dải màu như sau:
Đây là toàn bộ những màu có thể sử dụng ở trong framework này, hay nói cách khác nếu bạn dùng 1 màu khác dải màu này bạn đã không tuân thủ design system của nó.
Nếu như bạn đã đọc về POP trong 1 bài viết trước của tôi, thì hãy theo dõi đoạn code dưới đây bạn sẽ thấy sự quen thuộc:
public protocol ColorProvider {
var bgPrimary: UIColor { get }
var bgSecondary: UIColor { get }
var bgTertiary: UIColor { get }
var bgBottomSheet: UIColor { get }
var bgAlert: UIColor { get }
var bgSuccess: UIColor { get }
var bgCritical: UIColor { get }
var btnPrimary: UIColor { get }
var btnDisabled: UIColor { get }
var btnCritical: UIColor { get }
var btnAction: UIColor { get }
var textPrimary: UIColor { get }
var textSecondary: UIColor { get }
var textTertiary: UIColor { get }
var textAction: UIColor { get }
var textDisabled: UIColor { get }
var textCritical: UIColor { get }
var accentSecondaryBlue: UIColor { get }
var accentPea: UIColor { get }
var accentToothpaste: UIColor { get }
var textCTADisabled: UIColor { get }
var textToast: UIColor { get }
var tableViewSeparator: UIColor { get }
var imageBorder: UIColor { get }
var decorationSubtle: UIColor { get }
var iconPrimary: UIColor { get }
var iconSecondary: UIColor { get }
var iconTertiary: UIColor { get }
}
Bạn sẽ thấy họ thiết kế 1 protocol để định nghĩa tất cả các màu có thể sử dụng. Định nghĩa mã màu như sau:
public struct DefaultColorProvider: ColorProvider {
public var bgPrimary: UIColor {
.dynamicColorIfAvailable(defaultColor: .milk, darkModeColor: UIColor(hex: "#1B1B24"))
}
public var bgSecondary: UIColor {
.dynamicColorIfAvailable(defaultColor: .ice, darkModeColor: .darkIce)
}
public var bgTertiary: UIColor {
.dynamicColorIfAvailable(defaultColor: .marble, darkModeColor: UIColor(hex: "#13131A"))
}
public var bgBottomSheet: UIColor {
.dynamicColorIfAvailable(defaultColor: .milk, darkModeColor: .darkIce)
}
public var bgAlert: UIColor {
.banana
}
Với POP chúng ta sẽ không cần phải kế thừa, nhưng vẫn đảm bảo tính đóng gói của data, cụ thể là màu sắc ở trên.
Còn muốn apply chúng vào project của chúng ta, hãy xem demo của họ:
hay đơn giản là UIColor.ice
Thứ 2 hãy nói về Font. Hay nói cách khác là Typography – kiểu chữ.
Đây là những kiểu chữ mà chúng ta có thể sử dụng. Để vận dụng cách apply vào, đơn giản vào file FontDemoView.swift.
Về các components trong framework này, là phần rất quan trọng để chúng ta có thể tái sử dụng nó ở nhiều nơi. Các components phổ biến nhất như button, textfield, loading… sẽ tiết kiệm rất nhiều thời gian cho chúng ta. Thay vì bạn sẽ phải vẽ lại 1 nút: về độ bo, đổ bóng, shadow, hiệu ứng… thì việc đơn giản là tái sử dụng lại các dạng nút mà họ đã hỗ trợ:
Để hiểu cách dùng, chúng ta lại đơn giản vào màn hình demo ButtonDemoView.swift của họ. Nếu bạn thực sự không biết nó thuộc phần demo nào, hãy sử dụng công cụ debug UI xem
Còn rất nhiều components khác mà bạn có thể chạy ứng dụng demo của họ để xem. Tôi rất thích framework này, vì nó còn hỗ trợ cả dark mode – chế độ tối:
Nhiều components khác, ví dụ loading:
Sử dụng FinniversKit vào project iOS
Để sử dụng framework này, trong phần readme có nhiều cách, trong đó có cách đơn giản là sử dụng pod.
Riêng bài viết này tôi sẽ sử dụng Carthage. Lý do vì tôi bị ám ảnh việc pod build rất chậm khi sử dụng quá nhiều pods trong Podfile. Và bài hướng dẫn này cũng có mục đích cho bạn tham khảo triển khai Carthage như thế nào.
Lệnh trên để nó không build lại các framework Carthage đã build và chỉ build cho iOS. Đợi chờ lần đầu build, sau đó Carthage sinh ra thư mục framework đã build cho iOS:
../Carthage/Build/iOS/FinniversKit.framework
Phần còn lại là thêm thư viện vào.
Đầu tiên Tab vào General của project và nhấn vào nút “+” của phần Linked Frameworks and Library
Sau khi đã add Lib cần thiết vào, chúng ta đi chuyển đến Build Phases, nhất vào nút +, chọn New Run Script Phase:
/usr/local/bin/carthage copy-frameworks
Và điền như hình:
Việc này để Xcode copy framework vào project và sử dụng.
Sau khi đã thêm FinniversKit thành công, chúng ta hãy tạo màn hình login demo chẳng hạn:
Lấy thông tin version của ứng dụng từ tập tin META-INF/MANIFEST.MF bên trong tập tin jar
Bài viết được sự cho phép của tác giả Nguyễn Hữu Khanh
Một nhu cầu mà chúng ta thường gặp là làm sao để biết được ứng dụng mà chúng ta đang chạy có version là bao nhiêu, giúp chúng ta có thể biết được những feature mà ứng dụng đang hỗ trợ cho tới version này. Trong Java thì tuỳ theo ứng dụng mà các bạn đang sử dụng là gì, Web application hay Desktop application thì cách lấy thông tin version của ứng dụng sẽ khác nhau. Đối với các ứng dụng Java Desktop hoặc Java Console, các bạn có thể lưu trữ và lấy thông tin version của ứng dụng từ tập tin META-INF/MANIFEST.MF bên trong tập tin jar của ứng dụng.
Ví dụ như mình có một ứng dụng Java Console khi chạy sẽ in ra dòng chữ “Hello from Huong Dan Java”:
Mình đã sử dụng Maven Shade Plugin để build ứng dụng này, và khi build ứng dụng, mình đã thêm một số thông tin liên quan đến ứng dụng vào tập tin META-INF/MANIFEST.MF bên trong tập tin jar như sau:
Earthly là cú pháp để định nghĩa bản build cho hệ thống của bạn và dùng lại nó để dựng lại ở nơi khác như các server, cloud,…. Nó hoạt động giống với build đã cài đặt trong hệ thống hiện tại của bạn. Các bản build đóng gói có thể dễ dàng dùng lại.
Khi dùng Earthly bạn sẽ dễ dàng build system cho server mà không cần quá nhiều kiến thức như chuyên gia dựng server và rút ngắn thời gian build. Vì tất cả đều chứa trong build đều được đóng gói và dc sử dụng lại bất kỳ ngôn ngữ nào.
Bạn có quá nhiều instants trên các Cluster server khác nhau nằm trên nhiều khu vực và trong mỗi instant thì cài docker, build abc đễ hỗ trợ các kiểu giống nhau.
Việc này thì đòi hỏi DevOps có nhiều kinh nghiệm để remote vào từng cluster build lại hệ thống mới để integration, bla bla. Thay vì lặp lại 1 việc nhiều lần mà lại có rủi ro sai sót khi miss 1 bước hay 1 package nào đó thì dùng Earthly chỉ cần build 1 bản tốt nhất rồi để nó rebuild trên các cluster khác một cách nhanh gọn.
Xem thêm nhiều chương trình tuyển dụng VueJS hấp dẫn trên TopDev
1. Naming components – Vuejs Anti pattern
Về việc đặt tên cho components, thường một số bạn đặt tên component vô tội vạ, thích đặt gì thì đặt cái đó
Đặt tên component quá chung chung và không thể hiện được ý nghĩa của component có thể ảnh hưởng lớn tới project sau này. Cũng gây khó khăn không nhỏ cho việc maintain.
// This would not be an appropriate name as it conflicts with HTML elements.
Vue.component('form', Form)
// This is a better name as it's multi-word and there are less chances to conflict.
Vue.component('signup-form', Form)
Component nếu chỉ đặt tên form sẽ gây confuse cho người sử dụng. Best idea là thêm vào purpose của component, signup-form.
Pattern này là một Vuejs Anti pattern khá nhỏ và đơn giản, tuy nhỏ nhưng không kém phần quan trọng.
2. Template expressions
Often times, when we’re displaying items on the screen, we may have to compute values and call functions to change the way our data looks.
Thi thoảng, khi hiển thị items lên màn hình, ta có thể tính toán giá trị và gọi function để thay đổi data nếu cần thiết
Thay vì gọi thẳng function ở phía template hoặc viết logic ở phần này, ta có thể đem function tính toán này vào computed.
Việc này giúp việc maintain và đọc source sau này trở nên cực kì đơn giản và gọn gàng
Việc này theo đánh giá thì khá là tệ. Props thì định nghĩa ở component con, nhưng việc truyền props vào cho component con lại do thằng cha quản lý
Nếu gửi props sai thì sao?, props gửi không đúng hoặc sai có thể gây ra nhiều con bug ảo lòi
Bài viết được sự cho phép của tác giả Nguyễn Hữu Khanh
Maven Shade Plugin là một Maven plugin cho phép chúng ta có thể build các uber-jar. Nói nôm na thì uber-jar là những tập tin .jar ngoài chứa source code của ứng dụng thì nó còn chứa các dependencies mà ứng dụng đó đang sử dụng. Từ đó, nó giúp chúng ta có thể build các ứng dụng Java có thể chạy standalone được.
Lấy ví dụ như mình có một Maven project với một main class đơn giản, khi chạy sẽ hiển thị dòng chữ “Hello from Huong Dan Java” như sau:
package com.huongdanjava.mavenshadeplugin;
import org.apache.commons.lang3.StringUtils;
public class Application {
public static void main(String[] args) {
System.out.println(StringUtils.capitalize("hello from Huong Dan Java"));
}
}
Trong ví dụ này, mình có sử dụng thư viện commons-lang3 để in hoa chữ cái đầu tiên của dòng chữ này.
Ở đây, mình đã cấu hình để chạy Maven Shade Plugin khi chúng ta build ứng dụng với phase “package”. Lúc đó, Maven Shade Plugin sẽ chạy goal “shade” để đóng gói source code của chúng ta với các dependencies mà nó đang sử dụng. Mình còn cấu hình resources transformer cho Maven Shade Plugin với ManifestResourceTransformer cho phép chúng ta có thể định nghĩa một mainClass trong tập tin META-INF/MANIFEST.MF của tập tin jar, giúp cho tập tin jar sau khi build có thể chạy standalone được.
À, có một lưu ý là Maven Shade Plugin chỉ chạy được với Java từ version 7 trở lên thôi nhé các bạn! Các bạn có thể cấu hình Maven project của mình như sau để có thể sử dụng Maven Shade Plugin được:
Bây giờ, nếu các bạn chạy Maven build với goal “clean package” cho project này, sau đó mở Terminal trên Linux/macOS hoặc Console trên Window, vào thư mục target của project, chạy câu lệnh: “java -jar maven-shade-plugin-example-0.0.1-SNAPSHOT.jar”, các bạn sẽ thấy kết quả như sau:
Như các bạn thấy, mặc dù mình có sử dụng thư viện commons-lang3 cho ứng dụng của mình, nhưng mình không cần phải khai báo classpath đến thư viện này gì cả. Đó là bởi vì, thư viện này đã được include vào tập tin maven-shade-plugin-example-0.0.1-SNAPSHOT.jar rồi!
Các bạn cũng có thể định nghĩa một số thông tin khác trong tập tin META-INF/MANIFEST.MF bên trong tập tin jar, bằng cách cấu hình Maven Shade Plugin như sau:
Mọi thứ thật tuyệt vời cho đến khi ai đó cố tình nhét giá trị <img src onerror="stealYourPassword()"> cho message.text. Một kiểu hack nhẹ cũng rất phổ biến
Để tránh kiểu tấn công này, chúng ta dùng document.createTextNode() hoặc textContent, hoặc trục xuất hết các ký tự < và > để nó không thể nào chạy được.
Tất nhiên không phải ai cũng biết và nhớ hết các thủ tục xử lý này khi nhận giá trị input từ user. Đó là lý do tại sao, các thư viện như React, việc trục xuất này được thực hiện mặc định
<div>{message.text}</div>
Trong trường hợp chúng ta biết mình đang làm gì, muốn render thẻ HTML
dangerouslySetInnerHTML={{ __html: message.text}}
Vậy dùng React thì an toàn tuyệt đối? Không
Phải nói có nhiều lắm cách tấn công dùng HTML và DOM. Việc chặn hết là quá khó và quá tốn thời gian.
Ví dụ nếu render <a href={user.website}>, và trang web dẫn đến có thể chỉ là javascript: stealYourPassword(), hay spreading kiểu này <div {...userData}> cũng nguy hiểm phết.
Vì với cách viết này
// escape tự động<div>{message.text}</div>
…đã đủ an toàn lắm rồi đúng không? Không phải lúc nào cũng đúng. Đó là lý do tại sao có $$typeof
Tất nhiên chúng ta sẽ tạo ra object này bằng việc gọi React.createElement(). Nếu chúng ta sẽ lưu trữ object như một JSON ở phía server
// server cho phép user lưu ở dạng JSONlet expectedTextButGotJSON ={
type:'div',
props:{
dangerouslySetInnerHTML:{
__html:'/* put your exploit here */'},},// ...};let message ={ text: expectedTextButGotJSON };// Với React 0.13 đây là tử nguyệt<p>{message.text}</p>
React 0.13 đây là điểm bị lợi dụng để tấn công XSS. (Đáng lẽ ra ở phía Server không nên để cho user lưu dạng JSON như thế)
Phiên bản 0.14 React hỗ trợ xử lý con bug này bằng cách thêm đánh dấu đây chính hiệu là react element bằng Symbol
Bởi gì user hổng thể nào đặt một Symbol vào trong file JSON. Thậm chí mấy ông làm backend ẩu tả cho phép return JSON thay vì text cũng không vấn đề (Đoạn này chắc lão Dan đang cáo mấy chú Backend)
Điều tuyệt vời nữa là Symbol.for() thì scope ở mức global giữa các môi trường như iframe, worker. Nghĩa là việc ném các component qua lại giữa các môi trường cũng không bị ảnh hưởng.
Đó là chuyện của user, ai bảo xài trình duyệt cũ thì không được bảo hộ đầy đủ chứ biết sao. React sẽ vẫn thêm vào property $$typeof, nhưng với giá trị 0xeac7, tại sao là 0xeac7? Tại tụi tui (React team) thấy nhìn nó giống chữ “React”
Những điểm mới của Java 8 (phần 5: Tham chiếu phương thức)
Bài viết được sự cho phép của smartjob.vn
Từ phiên bản 8, lập trình viên Java có thể áp dụng kỹ thuật Tham chiếu phương thức (method reference). Trong những đoạn mã nguồn Java, khi bạn nhìn thấy ký hiệu :: (hai dấu hai chấm) thì đó chính là tham chiếu phương thức.
3 dạng của tham chiếu phương thức:
– Phương thức tĩnh (static method)
– Phương thức khởi tạo đối tượng (instance methods)
– Constructor (“Constructor”: hàm tạo về bản chất cũng là phương thức)
package vn.smartJob.java8features;
import java.util.List;
import java.util.ArrayList;
public class Example1 {
public static void main(String args[]) {
List employeeList = new ArrayList();
employeeList.add("Bùi Đăng Trường");
employeeList.add("Nguyễn Tiến Mạnh");
employeeList.add("Nguyễn Văn Bình");
employeeList.add("Nguyễn Anh Dũng");
employeeList.add("Đỗ Văn Cường");
employeeList.forEach(System.out::println);
}
}
// Kết quả:
//run:
//Bùi Đăng Trường
//Nguyễn Tiến Mạnh
//Nguyễn Văn Bình
//Nguyễn Anh Dũng
//Đỗ Văn Cường
//BUILD SUCCESSFUL (total time: 0 seconds)
Xem thêm các chương trình tuyển dụng Java hấp dẫn trên TopDev
Trong ví dụ trên, tại dòng 15, đã sử dụng kỹ thuật tham chiếu phương thức. Tham chiếu phương thức có thể kết hợp với Streams API giúp việc tăng tính linh hoạt (như chúng tôi đã trình bày trong phần 2).
package vn.smartJob.java8features;
import java.util.function.Supplier;
public class Example2 {
public static void main(String[] args) {
String s = "SmartJob - Mạng tuyển dụng hàng đầu Việt Nam";
printResult(s::length);
}
public static void printResult(Supplier<Integer> supplier) {
System.out.println(supplier.get());
}
}
// Kết quả:
// 44
Download mã nguồn từ server SmartJob: Java8_method_reference
hoặc clone/fork từ repository Github: https://github.com/SmartJobVN/java8
Đỗ Như Vý – Bài viết gốc được đăng tải tại smartjob.vn
Có phải Qualcomm đang lừa dối người dùng chúng ta?
Bài viết được sự cho phép của blogchiasekienthuc.com
Mỗi khi Qualcomm ra mắt một thế hệ chip di động mới, hoặc là đưa ra những lộ trình mới trong việc phát triển chip thì thường đi kèm với những lời có cánh như:
Sức mạnh vượt trội, tiết kiệm điện năng hơn nhiều so với thế hệ trước và đặc biệt là ít nóng hơn… Đi cùng với đó là hàng loạt những cải tiến về AI, về sức mạnh đồ họa và khả năng chụp ảnh.
Nhưng thực tế khi ra mắt thì con chip của họ lại không được như những lời quảng cáo đó, đặc biệt là thế hệ chip Snapdragon 888 mới nhất gần đây, nó đang bị tình trạng nóng khi sử dụng các tác vụ nặng và khi chụp ảnh.
Vậy lý do ở đây là gì? Liệu Qualcomm có đang quảng cáo quá đà và sản phẩm thực tế của họ thì không được như mong đợi? Mời các bạn hãy cùng mình tìm hiểu kỹ hơn trong nội dung bài viết hôm nay nhé.
Trên lý thuyết thì khi tiến trình càng nhỏ => chip càng tiêu hao ít điện năng hơn và máy thì ít bị nóng hơn, nhưng lý thuyết thì vẫn chỉ là lý thuyết mà thôi.
Không giống với khái niệm tiến trình ngày trước mà Intel hay nói, thực tế hiện nay khi nói tới tiến trình 5nm thì không có nghĩa là bóng bán dẫn chỉ nhỏ tới mức 5nm, mà nó chỉ là một cái tên gọi, là một công nghệ để phân biệt giữa các thế hệ chip mà thôi.
Khi bóng bán dẫn càng nhỏ thì việc sản xuất chip sẽ càng gặp khó khăn hơn và đặc biệt là sẽ gặp phải nhiều vấn đề về kỹ thuật hơn như rò rỉ điện bên trong nơi liên kết các bóng bán dẫn, gây ra hao hụt điện năng và hiện tượng quá nhiệt cũng từ đó mà ra.
Ngoài ra, nếu bóng bán dẫn càng nhỏ thì đòi hỏi vật liệu sản xuất, cũng như là cách thức chế tạo chip cũng phải thay đổi theo để đáp ứng được các tiêu chuẩn hóa lý bên trong.
Trên thực tế ở góc độ người dùng, thậm chí là chuyên gia đi chăng nữa thì chúng ta cũng không thể biết được Qualcomm đã là gì với tiến trình 5nm của họ (đó là một bí mật không thể bật mí). Vậy nên, những hiệu quả mà tiến trình 5nm mang lại thực tế chỉ có Qualcomm mới biết.
#2. Nhồi nhét quá nhiều thứ trong một con chip
Theo như công bố, Snapdragon 888 có các cụm nhân: 1 nhân Cortex X1, 3 nhân Cortex A78 và 4 nhân Cortex A55, nhân Kyro 680.
Trong đó đáng chú ý nhất là nhân Cortex X1 với tốc độ xung nhịp cực cao, có thế nói là tiệm cận với các con chip trên máy tính PC phổ thông hiện nay (cụ thể là 2.84GHz).
Mà các bạn nên nhớ một điều rằng, nhân hay CPU nói chung có xung nhịp càng cao thì CPU đó càng mạnh, nhưng nó sẽ càng nóng hơn khi sử dụng thực tế.
Bạn nào có PC hay sở hữu cho mình một chiếc máy tính cá nhân có cấu hình khủng chắc chắn sẽ hiểu rõ điều này, những CPU có nhiều nhân xung nhịp cao luôn phải đi kèm với một hệ thống tản nhiệt bên thứ 3 mới đủ đảm bảo hiệu năng cho máy.
Qualcomm cũng cho biết thêm, Snapdragon 888 đã tích hợp luôn bên trong modem 5G tốc độ cực cao, cụ thể thì tốc độ tải xuống là 7.5 Gbps và tải lên là 3 Gbps.
Theo mình nghĩ thì điều này cũng góp phần làm cho Snapdragon 888 nóng lên, bởi khi tích hợp vào bên trong thì đồng nghĩa với việc là bên trong con chip Snapdragon 888 càng chật chội hơn => dẫn tới càng dễ sinh nhiệt hơn.
Ngoài ra, Snapdragon 888 sở hữu khả năng xử lý màn hình Quad HD với tần số quét lên đến 144Hz, đây là một con số thực sự quá khủng với một thiết bị cầm tay mỏng nhẹ như điện thoại.
Hơn nữa Qualcomm cho biết, họ đã sử dụng những thuật toán xử lý game thế hệ mới để nạp vào con chip mới này nhằm mang lại khả năng chơi game mạnh mẽ hơn.
Qualcomm còn nhét vào con chip này 3 ISP ( bộ xử lý hình ảnh ) với khả năng xử lý 2.7 Gigapixels trong một giây.
Bộ xử lý này giúp kết hợp dữ liệu từ nhiều camera một lúc nhằm mang tới những bức hình đẹp và sắc nét hơn, hơn nữa chúng còn có khả năng xử lý video chất lượng 4K 120fps và 8K 30fps…
Và Qualcomm lại nâng sức mạnh của cụm AI lên một tầm cao mới, mà theo như dự đoán là mạnh gấp 2 lần thế hệ trước với bộ xử lý Hexagon 780 (có khả năng xử lý 26 nghìn tỷ phép tính mỗi giây).
=> Đó là những công nghệ tích hợp mà Qualcomm thông tin đến người dùng, phải nói là quá nhiều thứ được tích hợp trong một con chip.
#3. Qualcomm vẫn chưa nghĩ tới việc tối ưu chip (hoặc chưa thể tối ưu chip được tốt hơn)
Hiện nay, các chip nhà Qualcomm đưa ra dường như không được họ quan tâm lắm tới việc tối ưu hiệu năng thực tế, họ chỉ dừng ở mức phát triển công nghệ và phần còn lại là dành cho các bên thứ 3 tự nghiên cứu.
Hoặc cũng có thể là do họ chưa tìm được cách tối ưu tốt nhất cho con chip của mình !
Và thực tế cho thấy, các Flagship chạy Snapdragon 888 gần đây của các nhà sản xuất như Samsung, Xiaomi hay Sony…. đều gặp vấn đề về nhiệt. Rõ ràng là những gì mà các hãng sản xuất điện thoại có thể làm là chưa đủ.
Có thể thấy, dường như là Qualcomm đã nhồi nhét quá nhiều thứ vào Snapdragon 888 và có thể là những con chip trong tương lai nữa, điều này vô tình khiến mọi thứ như bị quá tải bên trong một con chip nhỏ ti tí.
Hơn nữa, như mình đã nói ở trên, có vẻ như tiến trình 5nm của Qualcomm vẫn chưa thực sự được tối ưu cho lắm, nếu nhìn qua các thế hệ chip PC thì không phải ngẫu nhiên mà Intel cứ dậm chân ở 14nm – bởi họ chưa tìm được cách tối ưu ở tiến trình nhỏ hơn.
Hay là AMD chẳng hạn, dù đi trước Intel ở tiến trình 7nm nhưng mãi tới tiến trình 5nm thì họ mới thực sự đạt được những ưu thế rõ ràng.
Tóm lại, Qualcomm về cơ bản cũng chỉ là một hãng sản xuất, vậy nên công việc kinh doanh và đạt lợi nhuận cao luôn được họ đặt lên hàng đầu, những lời quảng cáo hơi quá đà cũng là điều dễ hiểu.
Hi vọng là trong tương lai họ sẽ tối ưu lại tiến trình tốt hơn thay vì nhồi nhét nhiều thứ như bây giờ, bởi thực tế là 90% người dùng chẳng dùng hết được những gì mà Qualcomm trang bị cho con chip của họ.
Chúng ta thường phải đặt listener trên sự kiện window.scroll thực hiện một số thao tác tính toán, so sánh với thanh scroll để biết được khi nào element bắt đầu xuất hiện.
Cách làm này gây nhiều vấn đề hiệu năng và tương đối rườm rà. Giờ các trình duyệt đã đồng loạt hỗ trợ Intersection Observer API, chúng ta có một cách hoàn toàn gọn gàng, sạch sẽ mà lại tối ưu hiệu năng hơn nhiều.
Cách sử dụng như sau, chúng ta khởi tạo một instanceIntersectionObserver và gọi observe trên element muốn theo dõi (watch là thuật ngữ chuyên ngành hơn)
root element dùng để kiểm tra intersection, nếu null nó sẽ lấy document viewport
rootMargin: khai báo như giá trị margin css, ví dụ 3rem 2rem, có thể dùng để thêm offset cho intersection point
threhold: mảng giá trị từ 0 đến 1, tương ứng với ratio xuất hiện của element, 0 = hoàn toàn ra khỏi viewport, 1 là đang nằm trong viewport hoàn toàn, callback sẽ được gọi vào tất cả các giá trị đã khai báo
Element được xem là nằm ngoài viewport khi nó đã nằm ngoài viewport + 15px margin
Ứng dụng 2: Tự động pause video khi ra khỏi màn hình
let video =document.querySelector('video');let isPaused =false;/* Flag for auto-paused video */let observer =newIntersectionObserver((entries, observer)=>{
entries.forEach(entry=>{if(entry.intersectionRatio!=1&&!video.paused){
video.pause(); isPaused =true;}elseif(isPaused){video.play(); isPaused=false}});},{threshold:1});
observer.observe(video);