Để có thể tải Bootstrap Tourist các bạn có thể click vào đây hoặc truy cập vào Github Bootstrap Tourist. Tại đường link tải thư viện của tôi, tôi đã thêm vào một đối tượng MyTour để tối giản việc sử dụng Bootstrap Tourist hơn.
Tại các element trên website, những chỗ mà các bạn muốn làm các hướng dẫn cho khách hàng (các bước trong tour) thì các element cần phải có các attribute sau đây
data-tour-header: Tiêu đề của box hướng dẫn khi xuất hiện
data-tour: Nội dung của box hướng dẫn khi xuất hiện
data-tour-position: Vị trí hiển thị. Có 4 giá trị: left,right,bottom,top
Ví dụ như hướng dẫn hiển thị ở tiêu đề bài viết này
<h2class="post-title text-danger tour-tourist-0-element"data-tour-header="Đây là tiêu đề bài viết"data-tour="Hướng dẫn sử dụng bootstrap tourist để làm trợ giúp cho phần mềm"data-tour-id="2244"data-tour-position="bottom">Hướng dẫn sử dụng bootstrap tourist để làm trợ giúp cho phần mềm</h2>
Tiếp đến các bạn gọi hàm trên javascript để thực thi
var tour = new MyTour({ area: $("body") });tour.init();$("[data-btn=StartTour]").click(function (){tour.start();});
Trong các bài trước chúng ta đã làm quen với các kiểu dữ liệu số nguyên (int), số thập phân (float) và kiểu chuỗi (string) trong Python. Tiếp theo, chúng ta sẽ làm quen với một kiểu dữ liệu khác là Boolean, một kiểu dữ liệu được sử dụng trong hầu hết các ngôn ngữ lập trình hiện nay. Cùng TopDev tìm hiểu về Boolean trong Python và các toán tử AND OR NOT thông qua các ví dụ minh họa thật chi tiết.
Boolean hay Bool trong python là gì? Boolean là kiểu dữ liệu mà mọi ngôn ngữ lập trình ngày này đều sử dụng, và tất nhiên Boolean cũng là một kiểu dữ liệu trong Python.
Boolean đại diện cho hai giá trị logic duy nhất là: đúng (True) và sai (False).
Lưu ý khi code, giá trị True/False phải viết hoa, nếu không sẽ bị báo lỗi.
Trong máy tính, kiểu dữ liệu này được lưu trữ trên 1 bit (là đơn vị lưu trữ nhỏ nhất), có giá trị là 1 hoặc 0.
Thông thường, các giá trị Boolean là True hoặc False không được gán trực tiếp với biến mà thông qua một phép so sánh, ví dụ:
age =20
is_over_age = age >=18
is_under_age = age <18
is_twenty = age ==20
Một biểu thức so sánh sẽ trả về kết quả là dạng Boolean tức là True hay False. Chúng ta có các phép so sánh thường dùng như:
Trong Python, có thể sử dụng các toán tử Logic Boolean để tạo ra những so sánh phức tạp. Danh sách các toán tử logic trong Python bao gồm:
and: Trả về kết quả là True nếu cả hai vế là True, trả về False nếu 1 trong hai vế là False.
or: Trả về kết quả là True nếu 1 trong 2 vế là True và trả về False nếu cả hai vế là False.
not: đứng trước một biểu thức so sánh, trả về giá trị phủ định của biểu thức đứng sau.
Toán tử NOT trong Python
Toán tử logic not là một phép toán đơn giản và chỉ tác động lên một giá trị Boolean. Nó đảo ngược giá trị của một biểu thức Boolean: nếu biểu thức là True, not sẽ biến nó thành False, và ngược lại.
NOT True sẽ thành False.
NOT False sẽ thành True.
Giả sử bạn có một biến is_raining để chỉ định xem trời có đang mưa không và bạn muốn in ra thông báo chỉ khi trời không mưa:
is_raining = Falseifnot is_raining:
print("Trời không mưa, bạn có thể ra ngoài!")
else:
print("Trời đang mưa, hãy ở trong nhà!")
Kết quả:Trời không mưa, bạn có thể ra ngoài!
Trong ví dụ này, not is_raining sẽ đảo ngược giá trị Boolean của is_raining. Vì is_raining là False, not is_raining sẽ là True, do đó câu lệnh print("Trời không mưa, bạn có thể ra ngoài!") được thực thi.
Toán tử AND trong Python
Phép toán and là một phép toán nhị phân (binary operator) và tác động lên hai giá trị Boolean. Kết quả của phép toán and chỉ là True khi cả hai giá trị đều là True; nếu một trong hai giá trị là False, kết quả sẽ là False:
True AND True sẽ là True.
True AND False sẽ là False.
False AND True sẽ là False.
False AND False sẽ là False.
Giả sử bạn muốn kiểm tra xem một số y có nằm trong khoảng từ 5 đến 15 hay không:
y = 12if y > 5and y < 15:
print("y nằm trong khoảng từ 5 đến 15")
else:
print("y không nằm trong khoảng từ 5 đến 15")
Kết quả:y nằm trong khoảng từ 5 đến 15
Biểu thức y > 5 and y < 15 chỉ trả về True nếu cả hai điều kiện y > 5 và y < 15 đều đúng.
Toán tử OR trong Python
Phép toán or cũng là một phép toán nhị phân và tác động lên hai giá trị Boolean. Kết quả của phép toán or là True nếu ít nhất một trong hai giá trị là True. Chỉ khi cả hai giá trị đều là False, kết quả mới là False.
True OR True sẽ là True.
True OR False sẽ là True.
False OR True sẽ là True.
False OR False sẽ là False.
Sử dụng toán tử or
Nếu bạn muốn kiểm tra xem một số z có phải là số chẵn hoặc là một số dương hay không:
z = -4if z % 2 == 0or z > 0:
print("z là số chẵn hoặc là số dương")
else:
print("z không là số chẵn và không phải là số dương")
Kết quả:z là số chẵn hoặc là số dương
Trong ví dụ này, biểu thức z % 2 == 0 or z > 0 trả về True vì z % 2 == 0 là True (vì z là số chẵn), dù z > 0 là False.
Trong Python, các toán tử so sánh được sử dụng để so sánh hai giá trị và kết quả của các phép so sánh này luôn là một giá trị Boolean: True hoặc False. Các toán tử so sánh giúp kiểm tra mối quan hệ giữa hai biến hoặc giữa một biến và một giá trị cụ thể, và được sử dụng rộng rãi trong các câu lệnh điều kiện như if, while.
Dưới đây là bảng trình bày các toán tử so sánh trong Python và kết quả Boolean tương ứng:
Toán tử
Ý nghĩa
Ví dụ
Kết quả
==
Bằng nhau
5 == 5
True
5 == 10
False
!=
Khác nhau
5 != 10
True
5 != 5
False
>
Lớn hơn
10 > 5
True
5 > 10
False
<
Nhỏ hơn
3 < 7
True
7 < 3
False
>=
Lớn hơn hoặc bằng
10 >= 10
True
5 >= 10
False
<=
Nhỏ hơn hoặc bằng
7 <= 10
True
10 <= 7
False
Kết hợp với toán tử logic:
Biểu thức
Ý nghĩa
Kết quả
x == z and y > x
Kiểm tra xem cả hai điều kiện đều đúng hay không (x == z và y > x)
True
x == z or y < x
Kiểm tra xem ít nhất một trong hai điều kiện đúng (x == z hoặc y < x)
True
not x == z
Đảo ngược kết quả của điều kiện (x == z)
False
Bảng trên cung cấp cái nhìn tổng quan về cách sử dụng các toán tử so sánh và kết quả của chúng khi kết hợp với các toán tử logic Boolean trong Python.
Các toán tử logic boolean NOT, AND, và OR là nền tảng của logic trong lập trình và được sử dụng rộng rãi trong việc kiểm tra điều kiện, xây dựng biểu thức phức tạp và điều khiển luồng chương trình. Hiểu sâu sắc về kiểu dữ liệu Boolean và các toán tử NOT, AND, và OR là bước quan trọng để viết mã Python hiệu quả và logic hơn.
Bài viết được sự cho phép của tác giả Nguyễn Việt Hưng
10x engineer là một thần thoại (myth) lâu đời trong giới IT, mơ tưởng về 1 developer có khả năng code “hơn” người bình thường 10 lần. Vì là “myth”, nên có người tin, có người không.
Thần thoại 3x 4x 5x … 10x (xxxxxxxxxx)
Việc lên internet tìm kiếm 10x engineer trên thế giới không quá khó khăn, nhưng gặp khi đi làm ngoài thực tế là chuyện không nhiều. 10x thế giới tạm kể:
những ví dụ trên chỉ phục vụ mục đích dễ hình dung, bởi họ thuộc cỡ 100 hay 1000x chứ không phải 10x. Bí quyết là gì không rõ, nhưng điểm chung: họ đều đã ngoài 40 và dành hơn nửa cuộc đời làm software. Không có ai 30 đã về nghỉ hay lên làm manager cả.
Tiêu chí 10x không rõ ràng, vì đây là “myth”, nên mỗi người nghĩ theo 1 kiểu. Theo một tiêu chí ví dụ, mrX gõ nhanh hơn mrY 10 lần, nên cũng có khi được gọi là 10x engineer.
Bài viết này không liên quan tới chuyện các 10x nói trên, mà đơn giản chỉ là tiết kiệm 10x chi phí chạy code Python, nhờ được học Python “tử tế”.
Ví dụ
Sinh ra 1 file .log.gz chứa 1_500_000 dòng (từ 3 dòng lặp đi lặp lại)
$ python makelog.py; ls -la bigfile.log.gz
-rw-rw-r-- 1 hvn hvn 2960897 Jun 3022:42 bigfile.log.gz
$ gunzip bigfile.log.gz; wc -l bigfile.log; ls -l bigfile.log
1500000 bigfile.log
-rw-rw-r-- 1 hvn hvn 559000000 Jun 3022:42 bigfile.log
$ ls -lh bigfile.log
-rw-rw-r-- 1 hvn hvn 534M Jun 3022:42 bigfile.log
nhưng khi giải nén, kích thước lớn hơn rất nhiều lần (do dữ liệu trùng lặp nhiều nên nén lại từ to thành rất nhỏ).
Đây là đoạn code ban đầu, nó đọc các dòng text từ 1 file có đuôi .log.gz ra. Hãy xem kỹ xem bạn có thể “tối ưu” được bao nhiêu bước và trở thành mấy x từ đây?
File nén có đuôi .gz được tạo bởi các chương trình gzip, bên dưới dùng thư viện zlib. Thư viện gzip của Python cho phép mở file .gz như file text bình thường, nó thực hiện giải nén phía sau bức màn bí mật. Mode mở file rt giúp lib gzip hiểu ta muốn thu được str sau khi giải nén, còn khi mặc định nó mở ở mode rb, trả về kiểu bytes. Chạy đoạn code trên, sử dụng /usr/bin/time -v để đo thời gian chạy và các thông số chi tiết về bộ nhớ max. (trên MacOS dùng -l)
$ /usr/bin/time -v python3 albv1.py
Proceeded 10 lines
...
Maximum resident set size (kbytes): 693652
...
Code này dùng ~ 600 MB RAM.
Sau khi thay đổi, code chỉ còn dùng ~ 9MB RAM
$ /usr/bin/time -v python3 albv2.py
Proceeded 10 lines
...
Maximum resident set size (kbytes): 9752
...
Chỉ thay đổi duy nhất 1 dòng:
$ diff albv1.py albv2.py
12c12
< for line in f.readlines():
---
> for line in f:
Điều này bất kỳ học viên Pymi.vn nào cũng phát hiện ra ngay, bởi trong hệ thống bài tập đã có 1 bài xử lý file 30 triệu dòng nặng hơn 500 MB tương tự. Cách xử lý từng dòng một:
forlineinf:
mà không dùng f.readlines() hay f.read(), vì chúng đọc toàn bộ nội dung file từ ổ cứng vào RAM. Chú ý cả sự chênh lệch, Python đọc file text 534MB vào thành 670MB RAM.
“Bí kíp” đọc file theo dòng này dù chẳng có gì đặc biệt, ghi rõ trong tài liệu trang chủ nhưng lại trở thành chuyện lạ với hàng ngàn bài hướng dẫn trên mạng, thậm chí cả sách cũng dạy dùng readlines. Hãy thử search github có tới hơn 2 triệu kết quả, dù cho github không search chính xác được, thì chuyện này vẫn không phải là hiếm.
readlines hay read hoàn toàn ok khi lập trình viên làm chủ được kích thước file đầu vào (file cố định, file được cam kết là nhỏ), nhưng khi file có size tới hàng MB, nó sẽ chiếm không ít RAM để chạy chương trình.
Phiên bản v2 có thể xử lý file có kích thước lớn tùy ý, 10GB, 100GB, đều vẫn chỉ dùng < 10MB (với giả thiết kích thước mỗi dòng không quá khác biệt).
Vậy chỉ cần được học Python tử tế, đã trở thành 10x rồi.
Độ đo
Để tính mấy x cho rõ ràng, bài này sẽ sử dụng đơn vị đo mà loài người ưa chuộng nhất: tiền.
Tính tiền 1 chương trình trong 1 cái máy thì khá khó, nhưng ngày nay, khi “cloud computing” là thời thượng, chạy code trên AWS lambda giúp chuyện tính tiền dễ như học toán cấp 1. Xem AWS Lambda pricing
Tiền cũng là thước đo lý tưởng khi các công ty ngày nay đua theo “performance review”, “360 review”, “data driven”… Một dòng review ghi: “cắt giảm chi phí 70.000 đô la Biden/năm nhờ tối ưu code” sẽ giúp manager dễ hiểu, dễ đánh giá hơn hẳn viết “tăng tốc chương trình 100 lần nhờ tối ưu regex sử dụng non greedy-matching” hay “cải thiện tính đọc được và tính ổn định của code”.
Theo thử nghiệm trên máy, hai phiên bản v1 và v2 chạy về tốc độ là như nhau (hoặc chênh 1 2 3 giây trên tổng 60s không đáng kể), thì phần còn lại của biểu thức phụ thuộc vào lượng RAM sử dụng. Tăng cấu hình RAM cho Lambda function bao nhiêu lần, thì giá gấp bấy nhiêu. Code đăng ký dùng 256 MB RAM sẽ có giá đắt gấp đôi code đăng ký 128MB. Với ví dụ trong bài, mỗi file log kích thước cỡ 300-600 MB, lập trình viên sẽ thường để mức an toàn là 1024MB (1GB) tránh tình trạng có file 800MB xuất hiện mà thiếu RAM.
Code v2 luôn dùng 10MB RAM (=> 100x), nhưng mức tối thiểu AWS Lambda cho phép là 128MB, vậy ở đây tiết kiệm 8 lần => 8x.
Cú twist giật mình: câu chuyện thực ra không đơn giản vậy, với nhiều RAM hơn, AWS Lambda sẽ cấp thêm “năng lượng” cho CPU tỷ lệ với RAM, trong ví dụ này, nếu hầu hết thời gian chương trình đều để dùng CPU, giảm 8x RAM đăng ký đồng nghĩa với giảm tốc độ CPU 8 lần. Hay kết quả là v2 chạy mất 8s x 128MB thì v1 chạy mất 1s x 1024 MB, và giá tiền là như nhau.
Lambda allocates CPU power in proportion to the amount of memory configured. Memory is the amount of memory available to your Lambda function at runtime. You can increase or decrease the memory and CPU power allocated to your function using the Memory (MB) setting. To configure the memory for your function, set a value between 128 MB and 10,240 MB in 1-MB increments. At 1,769 MB, a function has the equivalent of one vCPU (one vCPU-second of credits per second).
Theo tài liệu này, nếu function chỉ sử dụng 1 core (code không sử dụng thư viện multiprocess), tốc độ CPU của nó đạt tối đa khi cấu hình 1769MB, dù có tăng RAM lên 2048MB thì chỉ tăng thêm 1 core nữa chứ không làm core ban đầu mạnh lên, hay nói cách khác: không làm code chạy nhanh hơn.
PS: trong môi trường lượng CPU là cố định (máy ảo, máy vật lý…), v2 vẫn là 100x.
Cú twist số 2: việc tính tiền trên các hệ thống cloud không hề đơn giản, có hàng ngàn dịch vụ cung cấp giải pháp phân tích, đọc hiểu, tối ưu code cloud. Hay mọc cả ra nghề FinOps chuyên về tối ưu hóa cloud cost, ngành kinh tế trên mây (cloud economics) với các chuyên gia có nghệ danh “cloud economist”.
Kết luận 1: 100x là có thật, nhưng còn phụ thuộc vào hoàn cảnh, không nằm ngoài “thuyết tương đối”. Việc giảm 8x RAM ở đây không làm giảm chi phí, công việc tiếp theo là cắt giảm chi phí bằng cách tăng tốc code.
Tuy không cải thiện về đơn vị đo của bài này là tiền, nhưng một đoạn code không chỉ có mỗi tiền, ngoài hiệu năng, nó còn nhiều tiêu chí khác khó đánh giá hơn như “tính đọc được” (code dễ đọc), “tính ổn định”,… Dùng for line in f cải thiện được tính ổn định của chương trình, cho phép nó chạy ngon lành khi kích thước file đầu vào tăng lên – trong khi chương trình ban đầu sẽ lỗi do không đủ RAM.
Tăng tốc regex
Phiên bản sau thêm công đoạn xử lý từng dòng để lọc ra các giá trị mong muốn, sử dụng công cụ: “regular expression” – hay gọi ngắn là regex. Bạn đọc không nên quá tập trung hay sợ hãi khi nhìn vào phần “pattern” viết đống giun dế gì, vì không nhiều người có khả năng đọc, hiểu, phân tích đoạn này, kể cả có 10 năm đi code hay làm sysadmin. Code regex thường khó đọc khó hiểu, khi cần dùng chủ yếu các lập trình viên đi copy, đoạn bên dưới cũng là copy từ link trong comment.
importgzipimportregex# copied and edited from https://gist.github.com/szinck/d456fbf691483ab77d2453c316db3371pattern='(.*?) (.*?) (.*?) ([0-9.]+):([0-9]*) ([0-9.]+):([0-9]*) ([.0-9]*) ([.0-9]*) ([.0-9]*) (-|[0-9]*) (-|[0-9]*) ([-0-9]*) ([-0-9]*) "(.*?) .*:([0-9]+)([^? ]*)(\\x3f?.*?) (.*?)" "(.*?)" (.*?) (.*?) (.*?) "(.*?)" *$'# example in AWS docs does not work directly with python https://docs.aws.amazon.com/athena/latest/ug/application-load-balancer-logs.htmlp=re.compile(pattern)i=0withgzip.open("bigfile.log.gz","rt")asf:forlineinf.readlines():i=i+1m=p.match(line)ifm:result=" ".join(m.group(17,11))# print("sending", result)ifi==10:breakprint("Proceeded {} lines".format(i))
Không hiểu gì thì làm sao mà tăng tốc?
Học regex trong 7 phút
7 phút đủ để quán bia làm xong món “giò nóng 7 phút”. Trong 7 phút đủ để bạn có kiến thức regex bằng với 90% lập trình viên trên thế giới.
regex là gì
regex là một ngôn ngữ dùng để mô tả pattern (tiếng Việt hay dịch là dạng, mẫu) của 1 giá trị. Ví dụ: một số điện thoại di động ở Việt Nam là một số có 10 hay 11 chữ số. Các pattern sau sẽ “match” (khớp mẫu) số điện thoại:
\d+
[0-9]+
Hai pattern này tương đương, nó sẽ match với 1 hoặc nhiều chữ số viết liền nhau. Dấu + theo sau là biểu diễn cho “1 hoặc nhiều”. Phổ biến không kém dấu +, là dấu *. Dấu * có nghĩa là match 0 hoặc nhiều:
\d*
[0-9]*
cũng sẽ match số điện thoại di động ở Việt Nam.
Dùng + khẳng định phải có ít nhất 1 số từ 0 đến 9 (ký hiệu [0-9]), thì dùng * dễ dãi hơn, không có số nào cũng được. Pattern .* là pattern phổ biến nhất với người học regex với thời lượng dưới 5 ngày.
. đại diện cho 1 ký tự nào đó, nào cũng được, a b c hay 0 1 2 hay % = # gì cũng ok. .* là pattern match được mọi thứ.
Tránh nhầm lẫn dấu * hay thấy khi gõ câu lệnh Linux, kiểu như ls ~/*.py, * này không phải regex, đây là khái niệm globbing, mặc dù tác dụng hơi giống, nó sẽ trả về tất cả các tên file có đuôi .py
Dấu ? match 0 hoặc 1 lần, pattern https? sẽ match cả http lẫn https.
Dùng trang regex101.com để thử các pattern và xem kết quả cho tiện.
Hay bật python3 lên rồi gõ
>>> import re
>>> re.findall('.*', '0987654321')['0987654321', '']
Có thể chỉ định số lần match với cú pháp {ít nhất, nhiều nhất}, pattern 0[0-9]{9, 10} match số điện thoại di động ở Việt Nam.
Đơn giản, đúng không? Hãy viết 1 đoạn regex để kiểm tra 1 email có hợp lệ không.
Mọi người đều biết “chung chung” là email có dạng gìđó@gìđấy.đuôi, vậy regex có thể là .+@.+\..+. Chú ý dấu . trong tên miền phải gõ \., vì dấu . là 1 ký hiệu regex đặc biệt đã nói ở trên. Đây là regex đầy đủ để kiểm tra 1 địa chỉ email, và không có một ai trên trái đất này cho rằng nó đơn giản cả.
Đến đây, đã có 1 manh mối để tối ưu tốc độ rồi… re là standard library của Python, có sẵn, không cài gì cả. Nhưng đoạn code trên lại import 1 thư viện tên regex. Đây là thư viện phải cài thêm,
This regex implementation is backwards-compatible with the standard ‘re’ module, but offers additional functionality.
Thử thay regex bằng re giúp cắt giảm 10s trong đoạn code chạy 60s trên máy tác giả. Có thể “đoán” rằng re có trong stdlib và được tối ưu đủ trò nên chạy nhanh hơn. Những việc đoán này phải dựa trên cơ sở đo. Để đo tốc độ trong Python, python có sãn thư viện cProfile.
Profiling Python với cProfile
Thay regex bằng re, chạy lại đoạn code với câu lệnh sau để xem các function nào dùng nhiều thời gian nhất/gọi nhiều lần nhất.
tottime total time: tổng thời gian function chạy sau N lần, không tính chuyện gọi function khác.
cumtime cummulative time: tổng thời gian function chạy sau N lần, bao gồm cả việc gọi các function khác.
Kết quả cho thấy hầu hết thời gian đều dùng vào việc chạy regex method match. re viết bằng C, lẽ ra phải chạy rất nhanh, thì khi copy thử pattern và 1 ví dụ lên regex101, sẽ thấy lý do vì sao nó chậm. Để kiểm tra pattern có match string ví dụ sau không, re phải dùng tới 112690 bước!!!
con số này quá lớn, dù có viết đoạn code lằng nhằng với 20 câu if, cũng không thể tới 112690 bước. Tăng tốc regex không phải chuyện dễ, nhưng có 1 tip rất phổ biến: chỗ nào dùng .* chỗ đó có vẻ chậm/sai/cần tối ưu (khác với .*?).
chỗ .*:([0-9]+) dùng để match domain và port như https://pymi.vn:443, thay .* trong đoạn này với https?://[^:]+ cho tác dụng tương đương. https?://[^:]+ match 1 đoạn text bắt đầu bằng http hay https, rồi :// rồi bất cứ thứ gì cho tới khi gặp dấu : thì dừng lại. Đoạn này match sau 524 bước
Chú ý đoạn code mới cho rằng mọi url đều bắt đầu với http hay https, điều này có thể sai (ví dụ wss:// cho websocket), tùy theo yêu cầu bài toán.
Một cách khác, là dùng pattern [^:]+:[^:]+: match mọi thứ có dạng something:something dừng lại khi gặp dấu : thứ 2. Pattern sẽ match wss://abcde trong string wss://abcde:443, pattern này match sau 518 bước.
Một cách khác nữa, là dùng .+?:.+?:. + và * bình thường sẽ match nhiều nhất có thể, thì khi thêm ? sau nó, +? hay *? sẽ match ít nhất có thể. Đây gọi là tính năng non-greedy Cho string abcdabcd, a.+d sẽ match abcdabcd nhưng a.+?d chỉ match abcd. Pattern này match sau 543 bước.
Dấu đóng mở ngoặc () dùng để capture kết quả, kết quả match thành công sẽ được lưu lại thành 1 group, đánh theo thứ tự xuất hiện. Đoạn code trong bài lấy ra group 17 và 11 từ kết quả match.
PS: khi tối ưu đoạn code này, vô tình phát hiện ra đoạn code ban đầu xử lý không đúng khi URL path có chứa dấu :, 3 phiên bản mới không gặp phải vấn đề này.
Kết luận 2: 150x là có thật và không cần phải học “regex” nâng cao.
Học và dùng regex
Python có viết 1 tài liệu cơ bản về regex trong mục howto, nếu một ngày buồn chán quá không có gì làm, hay muốn tìm ý nghĩa của cuộc sống, bạn có thể ngồi học regex.
Hoặc đi tìm một “khóa học regex”? cái này chưa có, cơ hội khởi nghiệp làm giàu còn rất rộng mở cho các chuyên gia công nghệ bán “khoá học làm chủ regex để học sâu với trí tuệ nhân tạo 4.0”.
Some people, when confronted with a problem, think “I know, I’ll use regular expressions.” Now they have two problems.
Khi một bài toán có thể giải quyết theo 1 cách khác đơn giản hơn, thì nên tránh dùng regex.
Chú ý: trong ví dụ này, nhằm mục tiêu giữ lại code gần giống với code ban đầu nhất, không thay đổi quá nhiều, nên đã không viết lại đoạn code lọc ra urlpath và statuscode mà vẫn dùng regex.
Tăng tốc gửi message đến kafka
Kafka là gì
Apache Kafka is an open-source distributed event streaming platform used by thousands of companies for high-performance data pipelines, streaming analytics, data integration, and mission-critical applications.
Nói đơn giản, Kafka như hệ thống ống nước, mạng lưới điện, mạng lưới viễn thông, nó đủ tính năng để đáp ứng mọi nhu cầu truyền tải dữ liệu từ nhiều nguồn đến nhiều đích. Kafka được dùng phổ biến trong các doanh nghiệp, các hệ thống xử lý data, logging…
Kafka có nhiều tính năng, bài này sử dụng nó như 1 hệ thống pub-sub, tức có 1 bên gửi message đi, và 1/nhiều bên nhận message.
curl -LO https://mirror.downloadvn.com/apache/kafka/2.8.0/kafka_2.13-2.8.0.tgz
tar xvf kafka_2.13-2.8.0.tgz
cd kafka_2.13-2.8.0
bin/zookeeper-server-start.sh config/zookeeper.properties
## mở 1 terminal kháccd kafka_2.13-2.8.0
bin/kafka-server-start.sh config/server.properties
Python Kafka producer
Phiên bản đầy đủ của chương trình trước khi mang đi tối ưu: nó đọc file log AWS ALB đã nén .gz, lấy ra urlpath và status code bằng regex, rồi gửi kết quả đến kafka.
Khi chưa gửi message tới kafka, code chạy mất 8s, khi gửi đến kafka trên cùng máy, code chạy mất 60s (khi profile chậm hơn nữa do quá trình profile can thiệp ảnh hưởng tới tốc độ):
Việc gửi 1.5 triệu message tới kafka chạy cùng máy mất tới 73s (cumtime) trong output profiling. Trong đó có dòng thứ 3, 4 và 5 đều là “append”. Mở code của thư viện kafka-python ra xem, phần này append các message vào 1 list “accumulator”, để bao giờ đủ 65536 phần tử mới gửi đi (batch_size=65536 lúc tạo producer). Batching là tính năng phổ biến trong các thư viện liên quan tới network, do việc gửi nhận qua network thường chậm, nên gom lại một đống rồi gửi đi để giảm số lần gửi/nhận. Nhưng trong ví dụ này, việc batching tốn tới 20s thì có vẻ không ổn. Sau một hồi chỉnh sửa các tham số (batch_size, linger_ms …), giải pháp lại là “think outside of the box”, tìm xem Python còn có thư viện kafka nào khác không.
Kết luận 3: thư viện có this có that, hãy tự đo và kiểm tra các options.
Kết quả
Sau 3 lần tối ưu, code mới dùng 100x ít RAM hơn, nhanh gấp 150 * 4 == 600 lần code ban đầu, chi phí giảm: 600 lần so với ban đầu. Giả sử đoạn code này hiện đang tốn $6000/tháng (6 * 12 = $72k/năm), thì sau khi tối ưu còn $10/tháng -> $120/năm.
$70.000 mỗi năm được tiết kiệm này nên dùng để thưởng nóng cho 10x dev hay chỉ thưởng $7k?
Thực tế (kinh tế) thì không phải thế, thưởng nóng $1-2-3k đã là nhiều lắm rồi. Không bàn tới chuyện quản lý doanh nghiệp/nhân sự/kinh tế ở đây, nhưng có thể thấy 1 điều, 1 lập trình viên có mức lương cao ngất ngưởng không phải là chuyện vô lý, khi họ có thể tự trả lương cho mình 1 vài năm trong vòng 1 2 ngày tối ưu code.
Kết luận
10x engineering là có thật. 10x phụ thuộc vào hoàn cảnh, tiêu chí đánh giá, nhưng học Python tại PyMi.vn rõ ràng là khoản đầu tư 10x. Việc tối ưu code, sử dụng cProfile của Python là một công việc thú vị, nhưng cần đặt vào đúng chỗ. Tối ưu đoạn code tiêu tốn $72k/năm để còn $120/năm mang lại lợi ích kinh tế khác biệt (trong môi trường doanh nghiệp) so với tối ưu đoạn code $72/năm còn $0.12/năm.
Giống như mọi bài viết về optimize/benchmark, kết quả rất phụ thuộc và bài toán cụ thể, môi trường (phiên bản, hệ điều hành …) cụ thể. Bài viết này KHÔNG kết luận:
for line in f nhanh hay chậm hơn for line in f.readlines()
Lib re nhanh hơn lib regex
confluent-kafka-python nhanh hơn kafka-python
Kết quả có thể hoàn toàn bị đảo ngược khi test trên 1 hệ điều hành khác (như MacOS, Windows) hay một phiên bản Python/thư viện khác, hay từng đoạn code chạy riêng sẽ khác với khi 2,3 đoạn code kết hợp lại. Kết luận chỉ nên đưa ra khi đem đi chạy thật với tình huống cụ thể, đến lúc tính tiền.
Bài viết được sự cho phép của tác giả Trần Hữu Cương
Code ví dụ TypeScript Eslint (áp dụng eslint cho TypeScript).
Eslint là một package (thư viện) cho phép tìm và sửa các vấn đề trong project typescript. Ví dụ như các vấn đề format code, cú pháp…
Thử tưởng tượng, nhiều người cùng code chung 1 project, nhưng người thì để tag, người thì dùng space; người thì dùng double quote, người thì dùng single quote… như thế khi gộp lại sẽ rất rối mắt và dễ gây conflict. Trong trường hợp này, eslint sẽ giúp chúng ta tìm các lỗi format và tự động sửa lại theo 1 chuẩn định nghĩa sẵn. Với các lỗi ko thể tự sửa thì nó sẽ báo lỗi/cảnh báo để cho ta sửa.
(lúc trước người ta dùng tslint, nhưng tslint hiện tại đã bị decrepated, và chuyển sang dùng eslint)
Trong phần rules sẽ định nghĩa các rule đã chọn: như indent bằng space, sử dụng single quote, kết thúc bằng dấu chấm phẩy, nếu ko follow theo các rule này thì khi lint (kiểm tra) sẽ có lỗi. Nếu chỉ muốn thông báo warning thì ta thay "error" bằng "warn" hoặc có thể dụng số 0 (ko báo lỗi) / 1 (báo warning)/ 2 (báo error). Ví dụ
"semi": ["warn","always"]hoặc"semi": [1,"always"]
Sau khi đã cấu hình xong eslint, ta thêm 2 script lint và lint-and-fix vào file package.json
Lệnh lint sẽ tìm các file .ts để kiểm tra theo rules đã định nghĩa
Lệnh lint-and-fix sẽ kiểm tra các file .ts để sửa lại theo các rules đã định nghĩa. Với các lỗi ko thể tự sửa thì sẽ báo lỗi, ví dụ mình thêm rule "no-console": "error" mà trong code có dùng console.log thì nó sẽ thông báo lỗi
Demo
Chạy lệnh npm run lint để kiểm tra:
Như hình trên có thể thấy trong file index.ts của mình có các lỗi như ko code theo chuẩn indent đã định nghĩa, vẫn sử dụng double quote, hay vẫn đang kết thúc file bằng CRLF (windows).
Thực ra thì khi bạn cài eslint, Ide nó đã warning lỗi cho bạn ngay khi code rồi: ví dụ ở đây mình dùng visual studio và đã cài plugin eslint
Thực hiện fix lại các lỗi chưa theo rule bằng cách chạy lệnh npm run lint-and-fix
Kết quả:
Dấu nháy kép được thay bằng dấu nháy đơn; dấu cách thừa bị xóa đi
Senior & Junior Java Dev – điều gì làm nên sự khác biệt
Bài viết được sự cho phép của tác giả Kiên Nguyễn
Đối với nghề lập trình viên, kinh nghiệm code là cực kì quan trọng. Nhìn vào một đoạn code, người làm lâu năm có thể nhìn ra đó là đoạn code của SeniorJava hay JuniorJava. Cũng chẳng phải ngẫu nhiên lại có sự chênh lệch mức lương giữa 2 rank này. =)))
Để cố gắng trở thành Senior, bản thân chúng ta phải luôn luôn học hỏi, trau dồi kiến thức. May mắn thay, ngay từ những ngày đầu lọ mọ code từng dòng code, mình đã được sư phụ chỉ cho vài đường cơ bản, tiện đây muốn chia sẻ với các bạn.
Bài viết này mình được sư phụ đầu tiên của mình viết cho. Anh Lương Nguyễn Trung (Senior Java Developer).
1. Kiểm tra NULL (CHECK NULL).
Java NULL, vấn đề muôn thủa. Một Senior với kinh nghiệm code dồi dào sẽ biết cách phòng tránh, hạn chế các trường hợp dẫn tới NullPointerException.
But when i do. So funny!.
Một trong những lỗi thường gặp nhất của những bạn mới đó là thiếu kiểm tra Object có phải là NULL hay không.
Thay vì sử dụng những Object này một cách trực tiếp để thực hiện xử lý (cộng trừ nhân chia, cắt chuỗi, nối chuỗi, getLength size…)
Hãy tạo ra những hàm common, trong những hàm này sẽ thực hiện việc kiểm tra giá trị NULL, và thực hiện sử lý tương ứng.
BAD CODE:
public String StringUtil.nullToEmpty(String str) {
if (str == null) {
return "";
}
return str;
}
GOOD CODE:
public String StringUtil.substring(String str, int start, int len) {
str = nullToEmpty(str);
// Luôn thực hiện kiểm tra độ dài trước khi substring.
if (str.length() > len) {
return str.substring(start, len);
}
return str.substring(start);
}
Mặc dù là nỗi sợ hãi thường trực của các Java Dev, null cũng có đôi điều thú vị. Các bạn có thể đọc thêm ở bài viết này.
2. Sử dụng toán tử cộng trừ nhân chia.
Khi thực hiện cộng trừ nhân chia, trường hợp nếu sử dụng kiểu dữ liệu là Long, Double,… sẽ có trường hợp giá trị trả về bị sai
Decimal dec1 = 4;
Decimal dec2 = 2;
Decimal dec3 = dec1 / dec2;
-> Đúng ra, giá dec3 sẽ có giá trị là 2
Tuy nhiên, trong một vài trường hợp dec3 sẽ có giá trị là 2.0000…1 hoặc 1.99999…9
Do đó, nếu ta dùng giá trị dec3 để đi so sánh với 2, giá trị sẽ trả về là FALSE
Trường hợp này, nên sử dụng để tính toán. Kì công hơn, hãy tạo class NumberUtil để sử lý việc cộng trừ nhân chia, làm tròn, compare giá trị, format kiểu số…
3. Khai báo biến bên ngoài IF FOR WHILE.
String str;
for (int i = 0; i < strList.size(); i++) {
str = strList.get(i);
…
}
// Biến str chỉ được sử dụng bên trong FOR
// Nhưng lại được khai báo bên ngoài.
Source vẫn sẽ chạy đúng, không sai.
Tuy nhiên, sẽ có một vài vấn đề sau:
Trường hợp xử lý phức tạp, sẽ khó để một người khác đọc và hiểu ý nghĩa của biến này là gì.
Nếu str không phải là String, Number, Date… mà là một kiểu Object có kích thước lớn, thì mặc dù đã ra khỏi IF, FOR, WHILE (biến không còn được sử dụng nữa), nhưng biến này vẫn sẽ giữ giá trị và gây tốn memory.
Xử lí như thế nào?.
Khai báo biến bên trong IF FOR WHILE
Sử dụng for each (for (String str : strList) {)
4. Danh sách chứa rất nhiều giá trị, không nên sử dụng list.get(i).
Khi danh sách chứa rất nhiều giá trị, không nên sử dụng hàm get tại vị trí thứ i để lấy giá trị này ra.
Nguyên nhân là do hàm get sẽ thực hiện duyệt từng phần tử từ 0 -> i để lấy giá trị của vị trí thứ i này ra, việc này sẽ tốn rất nhiều thời gian nếu vị trí cần lấy là càng về cuối của danh sách.
Ví dụ:
get(0)-> Danh sách duyệt 1 lần để trả về giá trị tại vị trí thứ 0.
get(10)-> Danh sách duyệt 11 lần để trả về giá trị tại vị trí thứ 10.
get(100)-> Danh sách duyệt 101 lần để trả về giá trị tại vị trí thứ 100
// Trường hợp giá trị của danh sách là kiểu Object,
// Object này có một hạng mục là key để phân biệt với các phần tử khác trong danh sách.
-> Sử dụng map<key, object>
// Trường hợp cần loop trên từng phần tử của danh sách
-> Sử dụng for each
for (Object dto : dtoList) {
-> Sử dụng iterator
Iterator ite = dtoList.iterator();
while (ite.hasNext()) {
Object obj = ite.next();
}
5. So sánh String trong Java.
Khi thực hiện so sánh String, không nên sử dụng ==.
if (str == "1")
// Trường hợp str là NULL, sẽ phát sinh NullPoiterException
Nên:
Sử dụng equals
Để giá trị cố định đằng trước.
if ("1".equals(str))
// Trường hợp str là NULL,
// Giá trị sẽ trả về là FALSE mà không phát sinh NullPoiterException
Tất nhiên, không phải lúc nào sử dụng equals cũng tốt!.
6. Hạn chế thiết lập cứng giá trị trong source code.
Nhiều bạn thường hay thiết lập giá trị cố định vào đoạn source của mình. Tuy nhiên, giá trị này có khi được sử dụng ở nhiều nơi khác nhau trong source.
Như thế, trường hợp có thay đổi tài liệu, hoặc do mình thiết lập giá trị sai, ta phải sửa lại giá trị này ở tất cả mọi nơi đang sử dụng nó, trong lúc sửa, có thể ta cũng sẽ sửa sót, không hết những chỗ cần sửa.
Hãy khai báo Constants ở đầu file, hoặc trong constants.java
public static String PROJECT_NAME = "Project AAA";
public static String VERSION = "1.0.0";
public void Function_1() {
String projectNameHasVersion = PROJECT_NAME + VERSION;
}
public void Function_2() {
if (VERSION > …)
}
7. Luôn sử dụng ENUM khi có thể.
Trường hợp cần phải thiết lập nhiều giá trị Constants mà lại phụ thuộc vào một Key nào đó, nếu ta chỉ khai báo constant thì khi sử dụng có khả năng ta sẽ sử dụng sai giá trị constants của key tương ứng này.
public static String TYPE_A_NAME = "...";
public static String TYPE_A_WIDTH = "...";
public static String TYPE_A_LENGTH = "...";
public static String TYPE_B_NAME = "...";
public static String TYPE_B_WIDTH = "...";
public static String TYPE_B_LENGTH = "...";
public void getInfo(String typeName) {
if (TYPE_A_NAME.equals(typeName) {
return TYPE_A_WIDTH + TYPE_A_LENGTH;
} else if (TYPE_B_NAME.equals(typeName) {
// -> Ở đây đúng ra cần trả về thông tin của TYPE_B,
// Nhưng có thể do bất cẩn hoặc do lỗi copy
// lại đang trả về giá trị của TYPE_A
return TYPE_B_WIDTH + TYPE_A_LENGTH;
}
}
Nên:
Tạo enum để lưu các giá trị thuộc về cùng một key vào 1 giá trị duy nhất
public enum MyType {
TYPE_A("Type A", "Width of A", "Length of A"), -> Mô tả các giá trị của TYPE_A
TYPE_B("Type B", "Width of B", "Length of B"), -> Mô tả các giá trị của TYPE_B
;
private String name;
private String width;
private String length;
MyType(String name, String width, String length) {
this.name = name;
this.width = width;
this.length = length;
}
public String getName() {
return name;
}
public String getWidth() {
return width;
}
public String getLength() {
return length;
}
}
public void getInfo(String typeName) {
if (MyType.TYPE_A.getName().equals(typeName) {
return MyType.TYPE_A.getWidth() + MyType.TYPE_A.getLength();
if (MyType.TYPE_B.getName().equals(typeName) {
return MyType.TYPE_B.getWidth() + MyType.TYPE_B.getLength();
}
}
public void getInfo(MyType myType) {
return myType.getWidth() + myType.getLength();
}
If you know, what i mean.
Tại sao Enum lại luôn được ưu tiên sử dụng?. Để tìm hiểu sâu hơn, các bạn có thể đọc thêm bài viết này.
8. Tìm hiểu thêm về Stream, forEach, Lambda.
Từ phiên bản 1.8 trở đi, java có hỗ trợ thêm các feature mới là Stream, forEach, Lambda nếu có thời gian, nên tìm hiểu thêm phần này. Các bạn cũng có thể đọc thêm ở bài viết về stream trên blog này. Muốn trở thành Senior tất nhiên phải bỏ công học hỏi. kkk
Nó sẽ giúp việc lập trình trở nên đơn giản và tiết kiệm thời gian hơn!.
mkdir typescript-log4jcd typescript-log4jnpm i typescript --save-devnpx tsc --init
Cài đặt module log4js
npm i log4js
Tạo file src/logger.ts: khởi tạo và cấu hình log4j
import{ configure, getLogger } from "log4js";configure({"appenders":{"application":{"type":"console"},"file":{"type":"file","filename":"/logs/application.log","compression":true,"maxLogSize":10485760,"backups":100}},"categories":{"default":{"appenders":["application","file"],"level":"info"}}});exportconst logger = getLogger();
Trong đó:
export const logger = getLogger(); : khởi tạo đối tượng log4js và export ra để các file khác sử dụng.
configure: cấu hình log4js, ở đây mình cấu hình 2 kiểu log là log ra file và log ra console với level là info. Riêng phần log ra file thì cấu hình ghi log ra file /logs/application.log với kích thước là 10485760 byte, nếu vượt quá thì sẽ tạo file mới (không quá 100 file)
Tạo file src/index.ts gọi tới đối tượng log4js đã export từ file logger.ts để ghi log:
import{ logger } from "./logger";logger.trace("stackjava.com");logger.debug("stackjava.com");logger.info("stackjava.com");logger.warn("stackjava.com");logger.error("stackjava.com");logger.fatal("stackjava.com");
Bài viết được sự cho phép của blogchiasekienthuc.com
Nếu như bạn thường xuyên theo dõi các bài viết có trên Blog Chia Sẻ Kiến Thức thì có lẽ file có định dạng *.reg đã quá quen thuộc với bạn rồi đúng không 🙂
File *.reg là danh sách các tùy chỉnh cho Windows Registry, nó rất thuận tiện để thay đổi những key đơn giản, giúp bạn tùy chỉnh và can thiệp sâu vào hệ thống.
Tuy nhiên, nó lại ẩn chứa những nguy hiểm tiềm tàng nếu bạn chỉnh sửa sai, thiết lập sai, hoặc khi bạn tải một file *.reg ở một trang không được chứng thực sau đó sử dụng nó.
Chính vì vậy mà hôm nay, mình sẽ hướng dẫn cho các bạn cách để kiểm tra file *.reg trước khi sử dụng nó nhé. Điều này là rất cần thiết nha các bạn !
#1. File *.reg là gì?
Như mình đã nói ở trên, file *.reg là danh sách tất cả những tùy chỉnh cho Windows Registry để thêm bớt một thành phần nào đó trong hệ thống Windows, đồng thời bạn cũng có thể thêm các phần mềm hoặc dữ liệu từ bên thứ ba.
Có những tùy chỉnh mà bạn chỉ có thể chỉnh sửa thông qua Windows Registry (đôi khi vẫn có thể chỉnh sửa thông qua Local Group Policy).
Tuy nhiên, chỉ có các phiên bản cao cấp như Windows Pro, Windows Enterprise hay Windows Education thì bạn mới có thể vào được Local Group Policy. Mà hầu hết các máy tính được tích hợp sẵn bản quyền hiện nay đều chỉ cài sẵn Windows 10 Home mà thôi.
Với Windows Registry, bạn hoàn toàn có thể chỉnh sửa thủ công bằng Registry Editor. Tuy nhiên, cách chỉnh sửa này rất lằng nhằng đối với những người không có nhiều kiến thức về máy tính.
Vì vậy các trang web hướng dẫn sẽ cung cấp các file *.reg để đơn giản hóa việc chỉnh sửa Registry chỉ bằng một vài click chuột.
#2. Vì sao file *.reg lại có thể gây nguy hiểm cho máy tính?
File *.reg chứa danh sách các thiết lập nâng cao trong Registry. Khi khởi chạy file này, Windows sẽ thêm, bớt hoặc chỉnh sửa các key trong hệ thống Windows theo thiết lập sẵn có của file *.reg đó.
Chính vì vậy, nếu file *.reg bị lỗi, hoặc người tạo ra nó cố tình tạo ra một file để phá hoại máy tính thì hậu quả sẽ rất nặng nề 🙂
Nếu như không có kinh nghiệm xử lý thì thường là bạn sẽ phải cài lại Windows do lỗi quá nặng hoặc một thành phần nào đó trong Windows bị hỏng và không hoạt động được đúng cách nữa.
#3. Cách đọc nội dung file *.reg
Để đọc được nội dung file *.reg thì rất đơn giản thôi, bạn bấm chuột phải vào file REG đó => sau đó chọn Edit.
Khi đó file REG sẽ được mở lên bằng Notepad. Hoặc nếu bạn đã cài NotePad++ cho máy tính thì bạn có thể mở bằng Notepad++ cho dễ xem hơn.
Ở dòng đầu tiên luôn là Windows Registry Editor Version 5.00 giúp nhận biết loại file và định danh file.
Đôi khi ở các dòng tiếp theo, sẽ có những thông tin hoặc comment của người tạo ra file REG đó. Như trong ví dụ là:
? Modified by: Tuan ga
?https://blogchiasekienthuc.com/
Nó không ảnh hưởng gì đến file REG cả, chỉ có tác dụng là để người khác đọc được khi mở file đó bằng notepad. Những comment đó luôn đứng đằng sau kí tự “;”.
Tiếp theo là phần quan trọng nhất của file *.reg, đó là phần nội dung của các chỉnh sửa/ thiết lập cho Windows Registry.
Nếu các bạn có kiến thức về Registry thì có thể đọc và kiểm tra phần này để nhận biết file REG có gây hại gì cho máy tính hay không.
#4. Cách chạy file *.reg trên Windows
+ Bước 1: Đơn giản thôi, bạn nháy đúp chuột vào file REG đó.
+ Bước 2: Sau đó sẽ có một cảnh báo xuất hiện, bạn bấm Yes để đồng ý thay đổi.
+ Bước 3: Thông báo hoàn thành xuất hiện, bạn bấm OK để kết thúc. Sau đó khởi động lại máy tính để áp dụng các thay đổi.
#5. Cách nhận biết file *.reg liệu có an toàn hay không
Để nhận biết một file *.reg có an toàn hay không. Đầu tiên bạn phải biết chắc chắn về cách sử dụng và công dụng của file *.reg đó là để làm gì.
Nếu bạn là một người không hề biết gì về máy tính thì hãy cân nhắc việc chạy file REG đó, trừ khi là làm theo hướng dẫn của những trang web uy tín.
Điều tiên quyết tiếp theo và nó cũng liên quan đến vấn đề mà mình vừa đề cập ở trên đó là tải file REG trên những trang Web uy tín và đã được kiểm duyệt. Một trong số đó tất nhiên là blogchiasekienthuc.com rồi 🙂
Trong trường hợp file REG đó chỉ có trên các trang web là mà bạn chưa biết nhiều về trang web này thì hãy chạy thử file REG đó trên máy tính ảo để thử trước, hoặc chạy trong một môi trường an toàn nào đó.
Nếu bạn không có thời gian hoặc không muốn cài máy ảo thì bạn hãy backup, sao lưu Registry trước khi thực thi file đó. Đồng thời, hãy xác định tâm lý là trong trường hợp xấu nhất sẽ phải cài lại Windows.
Đừng trông chờ vào các phần mềm diệt virus, bởi chúng không thể quét các file *.reg cho dù nó có là file gây lỗi hoặc phá hoại máy tính đi chăng nữa.
#6. Lời kết
Okay, như vậy mình đã hướng dẫn xong cho các bạn cách để kiểm tra file *.reg liệu có an toàn hay không rồi nhé.
Ngoài những kiến thức mà mình chia sẻ bên trên ra, nếu như bạn còn có thêm những kinh nghiệm hay về file REG này thì đừng ngần ngại chia sẻ dưới phần commnet để anh em cùng nhau học hỏi và thảo luận thêm ha 🙂
Chúc các bạn thành công, và đừng quên ghé thăm Blog khi rảnh nhé !
Bài viết được sự cho phép của blogchiasekienthuc.com
Bằng một lý do nào đó mà dữ liệu trên điện thoại iPhone của bạn đã biến mất, ví dụ như bạn vô tình xóa nhầm, hoặc lỡ tay khôi phục cài đặt gốc… Và bạn đang tìm kiếm một phần mềm hỗ trợ khôi phục dữ liệu đã xóa trên iPhone?
Vậy bạn đã tìm được phần mềm nào ưng ý chưa? Vâng, nếu bạn đang tìm kiếm một giải pháp hiệu quả để cứu vớt dữ liệu trên chiếc điện thoại iPhone của bạn thì có lẽ Coolmuster iPhone Data Recovery sẽ một một lựa chọn phù hợp đấy.
#1. Coolmuster iPhone Data Recovery có những ưu điểm gì?
Hỗ trợ phục hồi các file bị mất hoặc bị xóa trên các thiết bị iOS (iPhone, iPad..) và bản sao lưu iTunes.
Các bước thao tác để phục hồi dữ liệu là rất đơn giản, ngay cả với những người lần đầu sử dụng.
Khôi phục các file quan trọng trực tiếp từ iPhone: Tin nhắn SMS, danh bạ, hình ảnh, video, ghi chú, lịch, Safari,…. Phần mềm sẽ khôi phục dữ liệu từ điện thoại sang máy tính.
Khôi phục dữ liệu từ file backup iTrunes: Phần mềm sẽ hỗ trợ khôi phục lại danh bạ, tin nhắn và file đính kèm tin với nhắn đã xóa, cũng như là các file hiện có từ tệp sao lưu iTunes vào máy tính. Ngoài ra phần mềm cũng hỗ trợ trích xuất lịch sử cuộc gọi hiện có, ghi chú, tệp đính kèm ghi chú, Safari, lịch sử Safari, lịch, ghi nhớ thoại, thư viện ảnh và ảnh từ tệp sao lưu iTunes vào máy tính của bạn. (Lịch sử cuộc gọi và lịch sử Safari không được hỗ trợ trong iOS 10 trở lên)
Hỗ trợ xem trước các file dữ liệu hiện có và dữ liệu đã xóa => sau đó chọn file mà bạn muốn phục hồi.
Hỗ trợ các dòng điện thoại mới nhất hiện nay như iPhone, iPad và iPod (bao gồm cả iOS 14).
Bạn có thể cài đặt phần mềm trên tất cả các phiên bản Windows như: Windows 10/ Windows 8/ Windows 7 / Windows Vista / Windows XP, macOS..
#2. Tải phần mềm Coolmuster iPhone Data Recovery
Trang chủ: https://www.coolmuster.com/
Link giveaway: Hiện tại phần mềm đang miễn phí 1 năm tại đây ! Bạn hãy nhập thông tin, địa chỉ email => sau đó link tải phần mềm và key bản quyền sẽ được gửi thông qua Email bạn đăng ký nhé.
#3. Hướng dẫn sử dụng Coolmuster iPhone Data Recovery
Sau khi tải phần mềm về bạn hãy tiến hành cài đặt nó vào máy tính, quá trình cài đặt rất dễ nên mình sẽ không hướng dẫn thêm nữa. Đây là giao diện chính của phần mềm.
2.1. Cách khôi phục dữ liệu trực tiếp từ thiết bị iOS
Bạn hãy kết nối điện thoại cần phục hồi dữ liệu với máy tính bằng cáp điện thoại…
Bạn chọn Trust (tin cậy) nếu được hỏi nhé.
Okay, sau khi kết nối xong bạn sẽ thấy giao diện như hình bên dưới, bây giờ bạn hãy chọn tab Recovery from iOS Device.
Okay, bây giờ đến bước xem trước dữ liệu và phục hồi những file cần thiết. Bạn có thể gạt công tắc sang bên phải của tùy chọn Only display the deleted item(s) để chỉ hiển thị các tệp đã xóa.
Các tập tin đều đã được phân chia rõ ràng trong từng danh mục cụ thể, bạn có thể truy cập vào từng danh mục để khôi phục những file dữ liệu mà bạn cần.
Ví dụ như mình sẽ chọn tab Contacts để phục hồi danh bạ điện thoại..
Hoặc là tab Messages để khôi phục các tin nhắn đã xóa..
Còn đây là tab Photos, nới chứa các hình ảnh đã xóa của bạn..
Tương tự như vậy với các tab khác, sau khi bạn tìm được các file cần khôi phục => bạn hãy tích chọn các file đó => sau đó chọn Recovery to Computer (góc dưới cùng bên phải) để phục hồi là xong.
2.2. Cách khôi phục dữ liệu từ iTunes backup
Okay, trong trường hợp bạn muốn khôi phục dữ liệu từ file iTunes backup thì bạn hãy chuyển qua tab Recovery from iTunes Backup File => tại đây sẽ liệu kê ra tất cả những file mà bạn đã backup trước đó.
=> Bạn hãy chọn file backup mà bạn muốn phục hồi dữ liệu từ nó. Nếu trước đó bạn đã thay đổi vị trí lưu file backup thì bạn hãy nhấn vào nút Select để chọn lại cho phù hợp nhé.
Bước này bạn sẽ chọn kiểu dữ liệu mà bạn muốn khôi phục, nếu bạn muốn khôi phục lại hết thì cứ tích chọn hết như hình bên dưới nhé => sau đó bấm vào nút Start Scan để thực hiện quét.
Hoàn toàn tương tự như trong phần 2.1, chương trình sẽ tìm thấy các file (cả file đã xóa và file hiện có) trong file iTunes backup.
Những tin nhắn mà phần mềm load được..
Và cả hình ảnh nữa….
=> Bạn hãy chọn file hoặc tập tin mà bạn muốn khôi phục => sau đó chọn Recovery to Computer để khôi phục lại dữ liệu là xong.
NOTE: Okay, về cơ bản thì cách sử dụng như vậy. Nếu bạn muốn xem thêm nhiều hướng dẫn khác thì có thể vào trang chủ của họ để xem thêm nhé:
Một phần mềm hỗ trợ khôi phục dữ liệu iPhone rất đáng để thử. Bạn đang sử dụng phần mềm nào để khôi phục dữ liệu trên iPhone? Hãy chia sẻ kinh nghiệm của bạn cho mọi người cùng tham khảo nhé. Thank you !
Nay ngồi buồn nghĩ về quãng thời gian cày bừa với các dự án convert database (từ Oracle sang Postgres). Muốn chia sẻ chút kinh nghiệm nhỏ nhoi trên mặt này tới các bạn.
Bản thân mình đã từng làm cho 2 doanh nghiệp CNTT của Nhật Bản, đã kinh qua 6 dự án Convert Database. Nhận thấy:
Trong khoảng 5 năm trở lại đây, ngày có càng nhiều doanh nghiệp nhỏvà vừa chuyển đổi các phần mềm, ứng dụng của họ từ Oracle Database sang Postgres Database.
Việc chuyển đổi này đa phần đến từ các dự án cũ của doanh nghiệp Nhật Bản với quy mô không quá lớn. Trường hợp này sử dụng Postgres DB là hợp lý.
Dự án convert kiểu này thường không mấy HÀO HỨNG cho lập trình viên (khá chán).
Công nghệ sử dụng hầu hết là JDBC, rất hiếm có dự án nào sử dụng MyBatis hay Hibernate.
Đã từng hay chưa?
Nguyên nhân của việc chuyển đổi này là từ đâu?. Không thể bỗng nhiên những doanh nghiệp Nhật (vốn yêu thích sự ổn định, sử dụng phần mềm lâu dài), lại bỗng nhiên thực hiển chuyển đổi Database (việc làm vốn dĩ tiềm ẩn nhiều rủi ro).
Bài viết này sẽ phân tích về nguyên nhân sâu xa của vấn đề này.
1. Oracle – chi phí đắt đỏ.
1.1 Named User Plus (chi phí trên từng user).
Lý do đầu tiên và cũng là lý do quan trọng nhất – ĐẮT. Oracle Database thực sự đắt đỏ, khác hẳn với Postgres Database miễn phí. Nếu ứng dụng hoặc phần mềm của chúng ta chỉ sử dụng để đáp ứng cho một lượng nhỏ người dùng, không yêu cầu realtime, … thì việc bỏ tiền để sử dụng Oracle database là khá đắt đỏ.
The price of acquisition and product support for Oracle database is high and we need to pay in addition for every extra feature we need which is having the high price. So TCO is high for Oracle database.
Giá cả để sử dụng và hỗ trợ đối với Oracle database là tương đối cao, chúng ta cần trả thêm tiền cho việc thêm tính năng. Vì vây, TCO (total cost of ownership) là tương đối cao cho việc sử dụng Oracle database.
Chỉ với phiên bản tiêu chuẩn (standard edition) và tính theo số lương người dùng (Named User Plus), người sử dụng cũng đã phải bỏ ra 350$ (Thêm support và update là 77$). Đây là một con số không hề nhỏ.
1.2 Customer supprot và security.
Phải chăng bỏ tiền mua support là đã xong. Có vấn đề khi nào thì gọi support khi đó?. Cứ có vấn đề là rên?. Câu trả lời là ĐÉO!.
Customer support for Oracle database is not free; it is almost one-fourth of the license cost and increases 3 to 5 % annually.
Hỗ trợ khách hàng của Oracle database là đéo hề miễn phí. Cỡ khoảng 1/4 chi phí của license, và đm, tăng thêm 3%, 5% mỗi năm. Ẹc.
Trời đụ, vậy chắc OCD phải an toàn hơn rồi!. Tất nhiên, nhưng vẫn phải ói thêm tiền.
Oracle database has more security or advanced security but we need to purchase as part of the editions provided by Oracle corporation which have some features that protect the database.
Oracle database an toàn hơn nhiều, tuy nhiên chúng ta cần thanh toán thêm. Cái này như là một phần tính năng mở rộng. Thêm một vài tính năng để bảo về Database.
Thêm tính năng (advanced security) cho mỗi user sử dụng, cũng đồng nghĩa với 300 cành cọ cất cánh bay.
2. Postgres – miễn phí, ai chả thích.
Ui chà, MIỄN PHÍ. Đối với những doanh nghiệp vừa và nhỏ, tiết kiệm được chi phí phải trả cho database thật là một sự lựa chọn hoàn hảo.
Chính vì vậy, càng ngày có càng nhiều doanh nghiệp Nhật thực hiện chuyển đổi database từ Oracle sang Postgres (hầu hết là các dự án outsource – quy mô dự án không quá lớn).
As PostgreSQL is open-source there is no fee for acquisition and product support which are absolutely free of cost. We can get all the available features of PostgreSQL database for free as it is open-source.
PostgreSQL là mã nguồn mở, vì vậy không có bất cứ chi phí nào , product support cũng hoàn toàn miễn phí. Tất cả các tính năng của PostgreSQL database đều là miễn phí.
Postgresql Database là miễn phí. Vì vậy, chỉ có thể đóng góp (donate) để phát triển hệ cơ sở dữ liệu này. Theo mình dự đoán thì số lượng tiền donate cho postgresql là không hề nhỏ.
3. Sức mạnh của những chú voi.
Khi phải rời xa Oracle đắt đỏ, các doanh nghiệp thường phải đau đầu lựa chọn giữa Postgres và MySQL. Tất nhiên, hiện tại thì postgres đã có mặt khắp mọi nơi rồi.
3.1 SQL.
Windowing functions and analytics (OVER-clause) – Hàm và thống kê (sử dụng OVER)
Advanced locking mechanisms – Cơ chế khóa bổ sung cho từng bảng.
Many different types of indexes (btree, gist, gin, hash. sp-gist, brin, bloom, etc.) – Rất nhiều kiểu indexs (sử dụng để tăng tốc query).
Advanced cost-based query optimization – tối ưu hóa query dự.
Tablespaces
Partitioned tables – Tạo bảng phân vùng.
Synchronous and asynchronous COMMIT – COMMIT dựa trên cơ chế đồng bộ và bất đồng bộ.
Tiện nói luôn chút xíu về cơ chế COMMIT Synchronous (đồng bộ) của postgres. Cơ chế này đảm bảo rằng dữ liệu trước khi thực hiện commit sẽ được lưu vào ÍT NHẤT là 2 nodes. Việc này đảm bảo không xảy ra mất mát dữ liệu. Thực hiện đồng bộ đồng thời cũng phải đánh đổi về mặt hiệu suất (phải chờ để được commit).
Cơ chế commit đồng bộ trên Postgres.
3.3 Security.
Users, roles, etc.
Full support for SSL – Hỗ trợ cho SSL (Secure Socker Layer).
Full database encryption (with “Cybertec PostgreSQL_fde”) – Cơ chế mã hóa an toàn.
Support for single-sign-on (ActiveDirectory, LDAP, RADIUS, etc.)
3.4 Store Procedures.
Support for stored procedures in various languages.
Support for custom aggregates – hỗ trợ tùy chỉnh.
Professional triggers – sử dụng triggers (cơ chế bắt sự kiện trên table).
4. Kết luận.
Mong rằng bài viết này đã cho các bài một cái nhìn tổng quan về việc chuyển đổi cơ sở dữ liệu từ Oracle sang Postgres, nguyên nhân của việc chuyển đổi này.
Sẽ còn nhiều vấn đề để bàn về sự khác biệt giữa Oracle DB hay Postgres DB. Tuy nhiên, những vấn đề chuyên sâu này sẽ được viết ở các bài viết tiếp theo.
Hãy cố gắng để sử dụng Postgres một cách thuần thục như cách mà ta trộm nó (trộm gì khi nó là miễn phí =))).
Bài viết được sự cho phép của tác giả Trần Hữu Cương
Code ví dụ typescript, cấu hình eslint với prettier.
eslint đã có sẵn các rules để phân tích code và một số format, tuy nhiên riêng phần format thì prettier làm tốt hơn eslint và cung cấp 1 số tính năng mà eslint ko có.
Mongo hỗ trợ 2 cách để sao lưu, khôi phục data là mongodump/mongorestore với mongoimport/mongoexport tuy nhiên mongoimport/mongoexport chỉ dùng cho trường hợp data nhỏ nên ở đây mình chỉ đề cập tới mongodump/mongorestore.
1. Ví dụ mongodump
Để sao lưu data thành file .gz ta dùng câu lệnh sau:
(lệnh mongodump còn nhiều tùy chọn khác, tuy nhiên ở đây mình chỉ đưa ra các lựa chon đơn giản nhất để có thể sao lưu data).
Trong đó: --host={host:port} --authenticationDatabase={authenticationDatabase} -u={username} -p={password} là thông tin của database mà bạn cần backup lại
default host:port sẽ là localhost:27017 nên nếu bạn chạy ở local thì có thể bỏ qua option --host
nếu bạn ko cài password cho database thì cũng có thể bỏ qua các option --authenticationDatabase, -u, -p
--db: chỉ rõ database bạn muốn backup, nếu ko chọn thì mặc định nó sẽ sao lưu lại tất cả database trên host
--collection: chỉ rõ collection bạn muốn backup, nếu bỏ qua thì nó sẽ sao lưu tất cả collection trong database
--archive={filename.gz} --gzip: để chọn backup ra file .gz (nếu ko có sẽ lưu lại thành folder với nhiều mục nhỏ)
--query=<json>: dùng để tùy chọn các bản ghi được backup, ví dụ chỉ chọn backup các bản ghi có tên là ‘xyz’…
Lưu ý: khi sử dụng --query trên window thường hay bị lỗi parse json nên người ta hay dùng --queryFile=path_file. Với path_file là đường dẫn tới file json chứa thông tin query, cách này vừa hạn chế lỗi, vừa cho phép các câu query nâng cao).
2. Ví dụ mongorestore
Để khôi phục (restore) data từ file .gz được backup bằng lệnh mongodump, ta sử dụng lệnh mongorestore với cú pháp như sau:
Bắt đầu với lí do tại sao lại có chuỗi bài Vuejs Anti Pattern.
Trong quá trình lead một team làm việc chủ yếu với Nuxtjs và Typescript. Bản thân tôi thấy rất nhiều member bị dính những con bug khá khoai (đại loại như out of control)
Sau khi bỏ time điều tra, hầu hết do các bạn code không theo một quy củ nào. Cũng không có tài liệu nào cho biết cách làm A thì tốt hơn cách làm B. Hoặc cách làm C sẽ gây khó khăn sau này khi maintain
Communication là giao tiếp, trong Vuejs Anti Pattern thì pattern này khá phổ biến và cũng được biết tới rất nhiều. Hiện nay có vẻ không còn nhiều người còn dính pattern này trong quá trình làm
Giả sử ta cố 2 component, một là Todo List và thứ hai là Todo Item. Component Todo List sẽ render một loạt các component Todo Item. Lúc này việc giao tiếp giữa các component sẽ trở nên quan trọng.
Thông thường Vue sẽ cho phép ta access được tới $parent (component cha) và $child (component) con. Bằng cách này:
Pattern này khá phổ biến và cũng thường xuyên được áp dụng. Anh em có thể đã khá quen với pattern này rồi.
2. Children mutating props – Thay đổi props
Mục đích chính của pattern này là tuyệt đối không thay đổi props khi đã đưa qua component con
Props should be considered the source of truth when passed down to a component and thus, change the value from within a child component is typically bad practice
Props nên được cân nhắc để không thay đổi khi đã gửi qua component, thay đổi props khi gửi qua child component cũng là bad practice
Nếu muốn thay đổi giá trị props thì tạo variable mới, việc thay đổi hoặc change value của props rất dễ gây confuse cho việc sử dụng sau này, cũng như tiềm ẩn nhiều bug out of control.
3. Mutating property arrays
Trong danh sát Vuejs Anti Pattern được liệt kê ở bài viết này, mutating là pattern không được nhiều người để ý tới. Hoặc sau khi có bug ẩn mới phát hiện và chú ý tới. Pattern này cũng liên quan tới props, tuy nhiên cái cần để tâm là liên quan tới arrays
An important consideration to make when passing down arrays and objects as properties within JavaScript is the fact that they are passed by reference
Một điểm quan trọng khi pass props có kiểu dữ liệu array hoặc object thì kiểu gửi này là kiểu gửi tham chiếu (reference)
Chính vì kiểu gửi tham chiếu nên khi thay đổi data ở component con rất có thể sẽ ảnh hưởng tới props truyền vào ở component cha.
Đây là anti pattern cuối trong chuỗi bài Vuejs Anti Pattern. Pattern này nói về cách sử dụng data. Tuyệt đối tránh sử dụng data như là một object
When creating components with Vue, it’s important that the data option is a function that returns a new object holding data, rather than just a plain data object.
Khi tạo component với Vue, điều quan trọng là data option bản thân nó là một function trả về một object mới, không phải là một data object thuần túy
Nếu ta sử dụng data object không phải là một function, tất cả instance của component sẽ dùng chung một data, không tốt.
Mỗi khi data change, tất cả instance của component cũng sẽ thay đổi theo, cái này khá tệ về mặt performance. Để đảm bảo component chỉ quản lý data thuộc về nó, tránh những component khác bị kéo theo. Ta nên sử dụng return
By creating the return statement, it allows each instance created to have its own object rather than a shared one. This then allows the code to be used multiple times without the conflict of shared data.
Bằng cách sử dụng return, việc này cho phép mỗi instance khi được tạo sẽ có data object của riêng nó. Việc này cũng cho phép code được sử dụng nhiều lần mà không gây ra đụng độ do việc chia sẻ data
Component cũng có thể reuse nhiều lần mà không bị đụng độ cũng như tránh việc update data liên tục ở các component khác.
Ví dụ bây giờ, Docker trong máy mình đang chạy một container như sau:
Đây là container được chạy từ Docker Image của SonarQube, lúc chạy nó mình quên không đặt cho nó một cái tên để dễ phân biệt nếu sau này mình còn chạy thêm những Docker container khác. Hiện tại tên của nó là recursing_ardinghelli, mình sẽ rename nó lại sử dụng câu lệnh sau:
docker rename<container_id><new_name>
Ví dụ, mình đổi tên của container của mình sử dụng câu lệnh sau:
Ngành Công nghệ thông tin trong nhiều năm trở lại đây luôn được đánh giá là ngành hot với lực lượng lao động dồi dào cùng mức lương khá hấp dẫn. Nhiều sinh viên lựa chọn theo học ngành này với ước mơ về một mức lương cao và được đón đầu những công nghệ tiên tiến nhất trên thế giới. Những điểm sáng của ngành IT là không thể chối bỏ, nhưng cũng không thể phủ nhận rằng dân IT vẫn phải đối mặt với rất nhiều khó khăn để đạt được thành tựu trong công việc. Có những nỗi khổ của dân IT mà người ngoài ngành không phải ai cũng thấu hiểu.
Những nỗi khổ của dân IT mà người ngoài ngành có thể chưa biết
1. Thường xuyên stress và khó giao tiếp với thế giới bên ngoài hơn
Trong thực tế, lượng công việc và dự án mà mỗi lập trình viên phải làm việc hằng ngày là khá nhiều. Nguyên nhân chủ yếu là vì hầu hết các công ty ở Việt Nam vẫn đang trong quá trình cập nhật công nghệ và xây dựng tiến trình để phát triển, do đó đầu việc phải đáp ứng cũng nhiều hơn. Việc phải suy nghĩ nhiều, căng thẳng khi làm việc và thiếu ngủ thường xuyên sẽ khiến tình trạng stress ở các lập trình viên dần xuất hiện nhiều hơn. Vậy nên cũng không quá khó hiểu khi dân IT thường xuyên khó chịu hay gắt gỏng.
Bên cạnh đó, vì mỗi ngày phải dành trung bình 8 – 10 tiếng để đối diện với màn hình máy tính và ít khi ra ngoài nên khả năng giao tiếp của các lập trình viên cũng thường giảm đi. Dân IT luôn bị đánh giá là những người ít nói hay thiếu sự linh động trong giao tiếp một phần cũng vì những lý do này.
Đây có lẽ là nỗi khổ quen thuộc của dân IT. Việc bị bạn bè, người thân nhờ vả khi máy tính trục trặc, máy khởi động chậm, cài windows,… là chuyện mà lập trình viên nào cũng từng trải qua. Việc giúp đỡ không quá khó khăn với một người lập trình máy tính, tuy nhiên những lời nhờ vả không chỉ đến 1, 2 lần mà thậm chí là rất thường xuyên. Việc này có thể gây cản trở và làm ảnh hưởng đến luồng công việc đã dày đặc của lập trình viên. Do đó, hãy nói không khi bạn thật sự không thể để không gây trở ngại với công việc của bản thân.
Ánh sáng xanh của màn hình máy tính và các thiết bị điện tử không tốt cho sức khỏe, mắt và da của chúng ta. Trong khi đó, dân IT phải tiếp xúc với máy tính thường xuyên và liên tục mỗi ngày. Lâu dần sự tác động của những “chất độc hại” này lên da là rất nguy hiểm và khiến bạn có thể nhanh già hơn nếu không được chăm sóc cẩn thận.
Bên cạnh đó, không tập luyện thể dục thể thao thường xuyên cũng có thể khiến cơ thể dễ mắc bệnh hơn. Đặc biệt, nhiều minh chứng khoa học đã cho thấy người làm việc với máy tính quá nhiều có nguy cơ bị vô sinh cao hơn so với những ngành nghề khác.
Làm việc trong ngành IT lương khởi điểm của lập trình viên sẽ cao hơn hẳn so với một số ngành khác nhưng tốc độ tăng lương lại khá chậm. Do đó, đây cũng là một trong những nỗi khổ to lớn của dân IT. Nếu tìm được một công việc có mức lương đầu vào hấp dẫn, lập trình viên có thể sẽ thoải mái hơn khi làm việc và gắn bó với công việc đó lâu hơn. Và đa phần, để cải thiện mức lương của mình, cách giải quyết của dân IT là nhảy việc.
5. Khả năng bị tự kỷ cao hơn những ngành khác
Thói quen sinh hoạt thường gặp ở các lập trình viên là làm việc chủ yếu vào ban đêm, nhất là với các lập trình viên hoạt động tự do (freelance developers).
Mỗi khi có dự án mới xuất hiện thì tần suất “hoạt động về đêm” của lập trình viên càng tăng cao. Việc hoạt động như thế này lâu ngày khiến các lập trình viên dễ mắc các bệnh về dạ dày cũng như thần kinh hơn. Kết hợp với việc ít vận động nên cơ thể luôn trong tình trạng mệt mỏi mỗi khi kết thúc công việc. Duy trì lối sinh hoạt với giờ giấc thiếu khoa học là căn nguyên của nhiều căn bệnh nguy hiểm.
6. Làm thêm giờ đã trở thành thói quen
Với công việc của một lập trình viên, làm việc theo khung giờ nhất định và tan ca đúng giờ hiếm khi xảy ra. Lập trình viên sẽ thường xuyên tăng ca thêm 1, 2 tiếng để hoàn thành nốt công việc đang dang dở hoặc làm xong cho kịp deadline. Đây là đặc thù của công việc nên dù muốn hay không thì việc làm thêm ngoài giờ đã trở thành thói quen với nhiều lập trình viên.
7. Tỷ lệ độc thân cao hơn hẳn so với các ngành nghề khác
Vì đặc thù của ngành IT nên khi học đại học, số lượng sinh viên nữ rất ít so với các ngành nghề khác. Đến khi ra trường và đi làm thì số lượng nữ giới lại càng giảm đi. Việc ít có cơ hội tiếp xúc với người khác giới cũng là nguyên nhân khiến các lập trình viên luôn trong tình trạng độc thân. Và điều này cũng dẫn đến xác suất lập gia đình với người cùng ngành là rất cao.
Công việc IT có vẻ bề ngoài hào nhoáng nhưng cũng có không ít khó khăn mà người làm trong ngành phải đối mặt. Để thành công, mỗi người phải tự vượt qua chính mình và đương đầu với những thách thức mà ngành nghề đặt ra. Hy vọng với bài viết này, người đọc có thể hiểu thêm phần nào đó những nỗi khổ của dân IT.
Bài viết được sự cho phép của blogchiasekienthuc.com
Chào các bạn, trong các bài viết trước thì mình đã cùng với các bạn cài đặt SQL Server, tạo kết nối đến SQL Server thông qua SSMS (SQL Server Management Studio) và tìm hiểu về một số những thao tác cơ bản với SQL Server rồi phải không ạ.
Còn ở trong bài viết tiếp theo này, mình sẽ cùng với các bạn tìm hiểu về cách để mở và chạy một file script (file chứa các câu lệnh SQL) để thực hiện tạo các bảng và Insert dữ liệu mẫu vào SQL Server thông qua SSMS.
Việc hiểu và nắm được thiết kế của cơ sở dữ liệu là một điều rất quan trọng khi các bạn làm việc với các hệ quản trị cơ sở dữ liệu.
Dưới đây chính là thiết kế của cơ sở dữ liệu mẫu mà mình sẽ dùng trong bài viết này. Tất cả đã được viết dưới dạng Script. Các bạn có thể tải file tại đây hoặc tại đây.
#2. Tạo mới cơ sở dữ liệu
Đầu tiên thì anh em kết nối đến cơ sở dữ liệu SQL Server thông qua SSMS như mình đã hướng dẫn trong các bài viết trước.
Sau đó tạo mới một database bằng cách bấm vào Database => và chọn New Database… như hình bên dưới.
Do trong Script mình đã định nghĩa tên cở dữ liệu là BikeStores nên ở mục Database name các bạn nên đặt là BikeStores để tránh trường hợp biên dịch Script bị lỗi.
=> Sau khi đặt tên xong thì bấm OK để tiếp tục.
Okay, vậy là chúng ta đã có một database có tên là BikeStores rồi. Tuy nhiên, lúc này cơ sở dữ liệu của chúng ta vẫn trống và không có gì hết.
#3. Mở và chạy các file Script trong SSML
Tiếp theo chúng ta sẽ mở Script và chạy đoạn Script đó để thêm các bảng và dữ liệu mẫu vào cơ sở dữ liệu vừa tạo.
Thực hiện: Các bạn vào phần File => chọn Open => và chọn File như hình bên dưới. Hoặc bạn có thể sử dụng tổ hợp phím CTRL + O cho nhanh cũng được.
Đoạn Script đầu tiên (Create Objects) sẽ là đoạn Script dùng để tạo các bảng trong cơ sở dữ liệu. Các bạn sẽ mở và chạy file này đầu tiên để tạo các bảng trong cở sở dữ liệu.
Sau khi mở các bạn bấm Execute để thực hiên biên dịch đoạn Script đó.
Và lúc này trong phần Tables các bạn sẽ thấy toàn bộ các bảng như trong thiết kế đã được tạo thành công, ngoài ra sẽ có một thông báo với nội dung Commands completed successfully trong phần Messages.
Các bạn làm tương tự với file thứ 3 (Load data) là file sẽ thêm các dữ liệu mẫu vào trong các bảng của cơ sở dữ liệu.
Tiếp tục bấm Execute để biên dịch đoạn Script.
Các bạn có thể quan sát trong phần Messages trả về như hình bên dưới là đã thêm thành công dữ liệu.
Để kiếm tra lại các bạn có thể mở một bảng bất kỳ để xem dữ liệu đã được thêm vào hay chưa. Ở đây mình mở bảng production.categories
#4. Lời kết
Okay, quá trình Import dữ liệu từ vào trong SQL Server Management Studio cũng tương đối đơn giản phải không các bnạ.
Qua bài viết này thì mình tin là các bạn cũng đã biết cách dùng Script file để tạo ra các bảng cũng như thêm dữ liệu vào cơ sở dữ liệu trong SQL Server rồi phải không!
Trên thực tế khi làm dự án người ta có thể kết xuất một Database (Export) thành file Script để có thể mang sang các máy khác để chạy rất tiện lợi.
Okay, hẹn gặp lại các bạn trong các bài viết tiếp theo về SQL Server nhé.
Haskell là ngôn ngữ functional (lập trình hàm), thuộc nhóm “pure” blah blah blah có thể bỏ qua và gõ cho đến cuối bài, work first, talk is cheap, later.
REPL – Read Eval Print Loop, là chương trình nhận code người dùng nhập vào (Read), chạy code đó (Eval), in kết quả ra màn hình (Print), và cứ tiếp tục vậy (Loop).
Khái niệm này bắt nguồn từ ngôn ngữ lập trình cổ thứ 2 thế giới: LISP.
Việc viết code khi dùng các ngôn ngữ có REPL thường theo các bước:
bật REPL lên
gõ code thử cho tới khi thu được kết quả mong muốn
|| sẽ dừng lại và trả về kết quả ngay khi gặp True
&& sẽ dừng lại và trả về kết quả ngay khi gặp False
Với các ngôn ngữ khác, boolean có short-circuit hay không thì tùy từng ngôn ngữ quyết định, nhưng với một tính năng nổi bật của Haskell: Lazy, short-circuit là chuyện đương nhiên.
type
Các câu lệnh trong ghci
:help
:info
Prelude>:infomodtypeIntegral::*->Constraintclass(Reala,Enuma)=>Integralawhere...mod::a->a->a...-- Defined in ‘GHC.Real’infixl7`mod`Prelude>:info(+)typeNum::*->ConstraintclassNumawhere(+)::a->a->a...-- Defined in ‘GHC.Num’infixl6+
Chú ý: theo chương trình học của Pymi.vn, phần này được học ở buổi số 4. Bạn đọc cần biết Python để hiểu phần này hoặc chỉ cần gõ theo. Có thể đọc thêm tại đây.
If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23. Find the sum of all the multiples of 3 or 5 below 1000.
Tạo list các số từ 1 đến 5
Prelude>[1..5][1,2,3,4,5]
Haskell không dùng % cho phép chia lấy phần dư (modulo/remainder), code Python 10 % 3 tương đương với viết Haskell mod 10 3 hoặc rem 10 3
Haskell is a computer programming language. In particular, it is a polymorphically statically typed, lazy, purely functional language, quite different from most other programming languages. The language is named for Haskell Brooks Curry, whose work in mathematical logic serves as a foundation for functional languages. Haskell is based on the lambda calculus, hence the lambda we use as a logo.
polymorphically statically typed
lazy
purely functional
hoặc xem phần features trên https://www.haskell.org/
lập trình hàm là gì
Haskell là ngôn ngữ thuộc nhóm functional (lập trình hàm).
Trên lý thuyết, có nghĩa nó dựa trên “lambda calculus”, một mô hình/hệ thống tính toán dùng các function (hàm toán học), khác với mô hình Turing Machine mà các ngôn ngữ lập trình C, Java, Python, Go… dựa trên. Hai mô hình này được chứng minh về mặt toán học là có khả năng như nhau.
Về mặt thực hành, code với 1 ngôn ngữ functional thường có nghĩa là:
không dùng vòng lặp for/while mà dùng các function có sẵn để làm việc tương tự (vd: map, filter, fold, reduce,…) hoặc viết các recursive function để thu được kết quả tương ứng.
Các kiểu dữ liệu thường là immutable, khi thay đổi 1 list, Haskell sẽ tạo ra 1 list mới với những thay đổi đã thực hiện (và bỏ list cũ đi).
First class function: quen với việc dùng function này làm đầu vào cho function khác. Ví dụ map map (\x -> x * 2) [1..5] nhận function \x -> x * 2 và 1 list để thực hiện function đó trên tất cả các phần tử trong list.
Haskell purely functional là gì
pure function là một function không có “side effect”, giống hàm toán học, kết quả đầu ra chỉ phụ thuộc đầu vào.
f(x)=2x+1f(30)luônluônbằng61
Side effect là việc function thực hiện 1 thay đổi nào đó (thay đổi phần tử 1 list, đọc ghi 1 file, in ra màn hình, kết nối internet, sleep chương trình, …) hay phụ thuộc vào yếu tố khác với đầu vào (một chương trình phụ thuộc vào thời gian lúc nó chạy) nghe hơi vô lý khi một ngôn ngữ mà không tương tác với thế giới bên ngoài thì… chỉ để học toán. Nhưng Haskell sẽ dựa trên 1 khái niệm/cơ chế hoàn toàn khác để thực hiện các việc nói trên.
Haskell lazy là gì
lazy là chỉ thực hiện tính toán khi thực sự cần tới giá trị. Ví dụ có thể viết code tạo ra list từ 1 tới vô cùng, nhưng vì Haskell lazy, nó chỉ lấy ra phần tử nó cần, chứ không tạo list từ 1 tới vô cùng từ đầu.
Framework thì nên viết bằng Objective-C:
– Lý do chọn objective-C là vì nó đã không thay đổi gì nữa, chạy ổn định. Hiện tại mỗi năm Apple lại cho ra đời 1 phiên bản swift mới nên nếu dùng swift để viết thì đau thương lắm, mỗi lần lên là bạn phải update cho cả project đang dùng swift mới. Đây cũng là lý do vì sao mà bạn thấy FireBase hay FacebookCore đều dùng Objective-C để viết framework cho họ. Mặc dù mình biết nhiều người code swift chưa hẳn đã biết Objective-C, cú pháp khó hơn. Nhưng cuộc sống mà, bạn muốn làm Framework thì trình bạn cũng cao, nghĩa là bạn nên biết cả 2 ngôn ngữ.
2. Khi làm framework, thì bạn phải support cả simulator và device. Do vậy bạn phải có script để build cho chúng. Cụ thể là xcframework.
3. Bạn nên tạo 1 cái project demo tách biệt với project framework. Làm như vậy thì việc test chuẩn hơn, đôi khi phát hiện được lỗi dễ hơn.
Tôi sẽ tiến hành tạo 1 framework cho bạn hiểu.
Mở Xcode tạo mới Framework như hình.
Đặt tên là CodeToanBug(hoặc theo ý bạn).
Chỉnh lại version support càng thấp càng tốt, ví dụ mình chọn 9.0:
Tiến hành tạo workspace bằng cách File -> New -> Workspace. Đặt tên là CodeToanBug hoặc tùy ý.
Sau đó tắt project đang mở, nhưng vẫn mở Workspace nhé. Sau đó thì kéo file CodeToanBug.xcodeproj vào Workspace được như hình:
Sau khi kéo thả
Mục đích là để tý mình tạo thêm 1 project demo ở trong Workspace luôn.
Tiếp tục chọn target CodeToanBug rồi vào Organization thêm codetoanbug để định danh bản quyền, và Class Prefix CTB(viết tắt codetoanbug) để nó tự thêm prefix khi tạo mới file.
Bây giờ thêm 1 hàm cộng 2 số để framework có tính năng. Thêm file tên là CTBMath.h như hình:
#import "CTBMath.h"
@implementation CTBMath
/// Add two numbers
/// @param number1 number1 need add
/// @param number2 number2 need add
- (int)addTwoNumbers:(int)number1 secondnumber:(int)number2 {
return number1 + number2;
}
@end
Sau đó bấm vào file CTBMath.h rồi chọn như hình:
Hoặc biết kéo thả thì vào target CodeToanBug rồi chọn Build phases thêm file public để cho thằng nào dùng framework này cũng đọc được:
OK vậy là xong framework.
Bước tiếp theo là làm sao để build cho device và simulator.
Tạo universal framework như sau:
Chọn File -> New target -> Other -> Aggregate:
Đặt tên CodeToanBugFramework hoặc tùy ý.
Bây giờ nó xuất hiện thêm target này thì bạn chọn vào nó và chọn Build Phases và chọn New Run Script Phase:
Tiếp theo thêm mã này vào:
# Universal Script
set -e
FRAMEWORK_NAME="CodeToanBug"
IOS_SCHEME_NAME="CodeToanBug"
if [ -d "${SRCROOT}/build" ]; then
rm -rf "${SRCROOT}/build"
fi
SIMULATOR_ARCHIVE_PATH="${SRCROOT}/build/${FRAMEWORK_NAME}-iphonesimulator.xcarchive"
DEVICE_ARCHIVE_PATH="${SRCROOT}/build/${FRAMEWORK_NAME}-iphoneos.xcarchive"
OUTPUT_DIR="${SRCROOT}/framework_out_universal/"
# Simulator xcarchieve
xcodebuild archive \
-scheme ${IOS_SCHEME_NAME} \
-archivePath ${SIMULATOR_ARCHIVE_PATH} \
-configuration Release \
-sdk iphonesimulator \
SKIP_INSTALL=NO
# Device xcarchieve
xcodebuild archive \
-scheme ${IOS_SCHEME_NAME} \
-archivePath ${DEVICE_ARCHIVE_PATH} \
-sdk iphoneos \
-configuration Release \
SKIP_INSTALL=NO
# Clean up old output directory
rm -rf "${OUTPUT_DIR}"
# Create xcframwork combine of all frameworks
xcodebuild -create-xcframework \
-framework ${SIMULATOR_ARCHIVE_PATH}/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \
-framework ${DEVICE_ARCHIVE_PATH}/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \
-output ${OUTPUT_DIR}/${FRAMEWORK_NAME}.xcframework
# Delete the most recent build.
if [ -d "${SRCROOT}/build" ]; then
rm -rf "${SRCROOT}/build"
fi
Chọn như hình rồi bấm run:
Run thành công thì mở thư mục code lên bạn sẽ thấy cái này:
Đây chính là xcframework mà bạn có thể build cho cả 2.
Tạo 1 project demo trong Workspace này bằng cách File -> New -> Target -> App như hình:
Đặt tên là DemoSwift. Nhớ chọn Language là swift.
Sau đó sửa code ở file ViewController.swift như sau:
import UIKit
import CodeToanBug
class ViewController: UIViewController {
let math = CTBMath()
override func viewDidLoad() {
super.viewDidLoad()
print(math.addTwoNumbers(12, secondnumber: 12))
}
}
Nhưng muốn nó hiểu thì phải add CodeToanBug.framework vào như hình:
Nếu bạn build app mà nó lên 24 là đã chạy được.
Bây giờ tiến hành test với 1 project độc lập.
Tạo mới 1 project độc lập có tên là TestFramework bằng swift. Sau đó mở thư mục framework_out_universal rồi tiến hành kéo thả CodeToanBug.xcframework như hình(nhớ chọn copy if need):
Và chỉnh Embed & Sign(nếu không sẽ không build được máy thật – lỗi Reason: image not found):
Bài viết được sự cho phép của tác giả Trần Hữu Cương
Code ví dụ spring boot h2 database (khởi tạo database)
Trong bài này mình sẽ làm một ví dụ nhúng hệ quản trị cơ sở dữ liệu H2 vào project spring boot.
Việc này đặc biệt hữu ích trong quá trình làm các demo, với H2 chúng ta không cần phải cài các cơ sở dữ liệu phức tạp như MySQL, MSSQL… mà vẫn có thể thực thi các câu lệnh sql với database bình thường với H2.
Với H2 ta có thể nhúng sẵn 1 database, các data cần thiết và khởi tạo nó lúc chạy project.
spring.datasource.url: url của database, jdbc:h2:mem database sẽ được tạo ở bộ nhớ đệm, sẽ bị mất sau khi project bị tắt. Nếu bạn muốn lưu lại thì có thể lưu database ở file với jdbc:h2:file
spring.datasource.username và spring.datasource.password là thông tin xác thực cho database
spring.h2.console.enabled=true tức là cho phép truy cập database h2 qua giao diện
spring.h2.console.path=/h2 đường dẫn truy cập database h2 qua giao diện là /h2
File schema.sql
DROPTABLEIF EXISTS tbl_user;CREATETABLE tbl_user ( id INT AUTO_INCREMENT PRIMARYKEY, username VARCHAR(250) NOTNULL,passwordVARCHAR(250) NOTNULL);
Khi start project, hệ thống sẽ đọc file này để tạo database. (ở đây mình tạo bảng tbl_user với 3 column là id, username, password)
File data.sql
INSERT INTO tbl_user(username, password)VALUES('stackjava', 'stackjava'),('admin', 'admin1234'),('root', 'root');
Sau khi đọc file schema.sql hệ thống sẽ đọc file data.sql để xử lý data (ở đây mình thực hiện insert 3 bản ghi vào bảng t_user)
Với database này chúng ta có thể dễ dàng demo các ví dụ về spring data jpa, hibernate… có thể chạy thử dễ dàng, ko cần phải cài đặt các database phức tạp.
Những Câu Hỏi Phỏng Vấn Tiếng Anh Thường Gặp Trong Các Buổi Phỏng Vấn
Ngày nay, việc dùng tiếng Anh làm ngôn ngữ chính trong buổi phỏng vấn trở nên khá phổ biến do sự cần thiết của ngoại ngữ trong công việc. Để có thể tự tin trả lời những câu hỏi bằng tiếng Anh, việc có sự chuẩn bị trước để sắp xếp ý tưởng và logic cho câu trả lời của mình là yếu tố khá quan trọng mà bất cứ ứng viên nào cũng cần để tâm đến. Do đó, những câu hỏi phỏng vấn tiếng anh thường gặp được chia sẻ trong bài viết này sẽ giúp người đọc có sự chuẩn bị tốt hơn cho bản thân.
Một số câu hỏi phỏng vấn bằng tiếng Anh thường gặp
1. Can you introduce yourself? Tell me about yourself (Hãy giới thiệu về bản thân bạn)
Đối với câu hỏi này, người phỏng vấn chủ yếu muốn ứng viên khái quát một cách tổng quan những thông tin cơ bản của bản thân và thể hiện được mong muốn của mình với công việc. Về cơ bản cách trả lời câu hỏi này cũng tương tự như cách bạn trả lời trong buổi phỏng vấn bằng tiếng Việt. Tuy nhiên, với những ứng viên đã có kinh nghiệm làm việc, ứng viên có thể bổ sung thêm những kinh nghiệm mình đã có và cách bạn có thể áp dụng những điều ấy cho vị trí mà mình đang ứng tuyển.
Chẳng hạn với vị trí ứng tuyển liên quan đến Content Marketing, bạn có thể tham khảo mẫu câu trả lời như sau:
Hello, my name is Han. I’m 22 years old and I graduated from the University of Social Sciences and Humanity where I majored in International Relations. I have been working as a Content Creator at a small Vietnamese company for 2 years since I was a sophomore. My main duties were creating content for blogs, brochures, and social posting and also taking care of others’ social fanpages. I’m interested in writing and making creative products, that’s the reason I choose to follow this career path.
2. What are your strengths and weaknesses? (Điểm mạnh và điểm yếu của bạn là gì?)
Câu hỏi này gần như luôn xuất hiện trong tất cả các buổi phỏng vấn. Mục đích của việc đặt câu hỏi điểm mạnh và điểm yếu là để người phỏng vấn có thể xem xét khả năng tự đánh giá về bản thân của ứng viên như thế nào. Bạn có đủ tự tin với những điểm mạnh của mình không cũng như có dám tiết lộ một cách chân thật điểm yếu của mình không?
Tham khảo:
I have the ability to adapt very quickly to work and withstand pressure well. Due to the characteristics of working in the IT industry, I often work overtime to solve my assignments, but this has never been a thing that makes me feel depressed.
However, I am still not really satisfied with my professional knowledge. That’s also the reason I signed up for more external courses to upgrade my coding skills.
3. Why do you want to apply for this position? (Tại sao bạn lại muốn ứng tuyển vào vị trí này?)
Nếu như ở câu hỏi điểm mạnh, bạn có thể kể một cách thoải mái những điều ưu tú nhất của bản thân, thì với câu hỏi này, ứng viên nên đi sâu vào khai thác điểm mạnh ấy. Với những điểm mạnh ấy, bạn có thể đóng góp được gì cho công việc này. Đó là cách để ứng viên có thể thuyết phục nhà tuyển dụng rằng bạn phù hợp với vị trí này.
Tham khảo:
I have more than 3 years of experience in the field of information technology. And I think that’s one of my advantages when applying for this position. It will be easier for me to receive information as well as handle the professional work of a developer in my company. Besides, I also have experience working with the programming language that the current company is applying.
4. What are your short term goals in your career path? (Các mục tiêu ngắn hạn của bạn trong lộ trình sự nghiệp của bạn?)
So với mục tiêu dài hạn, mục tiêu ngắn hạn sẽ cụ thể và thực tế hơn rất nhiều. Nhà tuyển dụng nhờ thế cũng có thể đánh giá ứng viên một cách chính xác hơn, do đó họ thích đặt câu hỏi này hơn so với mục tiêu dài hạn. Vậy nên kể cả khi câu hỏi không nêu cụ thể mục tiêu ngắn hạn hay dài hạn, ứng viên vẫn nên ưu tiên các mục tiêu ngắn hạn để gây ấn tượng với nhà tuyển dụng cũng như có tính thuyết phục cao hơn.
Tham khảo:
I want to develop to a higher position and improve my knowledge of software programming with Python language. My specialty is computer sciences, I also have knowledge of SQL server databases, Postgres, knowledge of Linux centos operating system, Ubuntu, Odoo Framework and Python programming language. I want to continue to explore new languages at work.
5. What is your expected salary? (Bạn mong đợi mức lương bao nhiêu?)
Đây là câu hỏi mang tính chủ quan từ phía ứng viên do đó tốt hơn hết ứng viên nên có sự chuẩn bị trước với những câu hỏi như thế này. Bạn nên tham khảo mức lương thị trường với vị trí này để biết năng lực của mình đang ở đâu và có thể thương lượng được mức lương như ý nhất.
Tham khảo:
My salary expectations are commensurate with my experience and qualifications. In addition, I have also searched about the market salary for this position as well as the jobs that I can do, so I would like to receive a salary in the range from 12.000.000 VNĐ to 15.000.000 VNĐ.
Hi vọng một số câu hỏi tiếng Anh thường gặp trên đây sẽ giúp ứng viên trang bị thêm cho mình một số kiến thức để chuẩn bị cho những cuộc phỏng vấn quan trọng sắp tới. Đón đọc thêm các bài viết hữu ích khác về công nghệ và nhân sự tại TopDev nhé!
Bài viết được sự cho phép của tác giả Tô Thị Vân Anh
Nhân một sự kiện đáng nhớ của mình đã diễn ra hơn nửa năm về trước, đã khá là lâu rồi mà đến bây giờ mới có được chút sức mạnh để đánh bay cơn trì hoãn và cái sự lười đã bén rễ bên trong cơ thể này, để viết về một chủ đề quen thuộc đối với nhiều người theo con đường tester đó là chứng chỉ ISTQB (International Software Testing Qualifications Board).
À thì cái sự kiện đáng nhớ trên của mình ấy mà, thực ra cũng không có gì to tát đâu và đâu đó bạn sẽ phát hiện ra sau khi đọc xong bài viết này nhé!
Quay lại chủ đề liên quan đến mục đích của bài viết này, mình sẽ tổng hợp một số thông tin liên quan đến việc thi lấy chứng chỉ ISTQB, mình nghĩ là thông tin này sẽ khá là hữu ích dành cho bạn nào đang có ý định tìm hiểu và thi lấy chứng chỉ này đó. Bên cạnh những thông tin đưa ra dưới đây, các bạn có thắc mắc hay ý kiến đóng góp gì thì cũng cứ thoải mái để lại bình luận cho mình ở phần bình luận phía dưới nhé.
Bài viết của mình tập trung vào phần CORE của ISTQB Advanced level bao gồm các Module: TM (Test Management), TA (Test Analyst), TTA (Technical Test Analyst).
1. Nội dung kiến thức trong bài thi
Câu hỏi trong bài thi Advanced level sẽ dựa vào kiến thức có trong các Syllabus tương ứng. Theo thông tin từ trên trang chủ của istqb thì:
Với bài thi TA và TTA thì sẽ tham khảo Syllabus TA, TTA 2019 – có các thông tin được cập nhật, chỉnh sửa.
Ngoài ra còn có một số tài liệu khác nữa có thể tìm kiếm qua Google, hoặc nếu bạn thực sự cần để ôn luyện thì có thể liên hệ cho mình
Để có thể làm tốt được bài thi thì tất nhiên phải nắm được, hiểu được và vận dụng được kiến thức đã được tóm lược trong tài liệu đó để trả lời các câu hỏi trong bài thi. Bài thi bao gồm các câu hỏi bao hàm lượng kiến thức từ nhiều chương kết hợp. Đây là mức độ nâng cao nên tất nhiên câu hỏi sẽ không thể ở mức quá đơn giản được, đúng không nào. Hehe, có một cách khác đó là cày đề và học thuộc đáp án nha các bạn :v nhưng mà đề ở đâu để cày mới là vấn đề =)) thế là lại phải tốn thêm ít chi phí để đi học trung tâm. Hehehe.
Nếu xác định đi lên bằng thực lực thì chính bạn phải biết cách chắt lọc và nắm bắt nội dung kiến thức một cách đầy đủ và khoa học. Vấn đề là làm thế nào, câu trả lời đầu tiên đó là phải chăm chỉ cái đã. ;))
Một thông tin khác, không liên quan đến kiến thức trong bài thi, nhưng mình cũng bổ sung thêm ở đây để các bạn có thể cân nhắc thêm, đó là kinh phí dành cho bài thi này (Lưu ý: chi phí này mình tham khảo năm 10/2020, đơn vị được ủy quyền tổ chức thi là QRS):
Phí đăng ký hồ sơ thi: 3,000,000 VND (Ba triệu đồng). Hồ sơ này đóng 1 lần bao gồm: bằng đại học, chứng chỉ ISTQB Foundation (nếu chưa có thì bạn phải thi để có cái này trước đã nhé), một giấy xác nhận đã làm trong ngành CNTT được tối thiểu 3 năm – đối với người tốt nghiệp đúng chuyên ngành CNTT, và 5 năm đối với người tốt nghiệp ở ngành nghề khác). – Bạn sẽ được hỗ trợ thông tin khi đăng ký thi ở đơn vị được ủy quyền tổ chức thi nhé.
Lệ phí thi cho từng Module, mỗi Module là 4,500,000 VND (Bố triệu rưỡi đồng), nếu bạn thi cả 3 Module thì là 3×4,500,000. Phí này bao gồm việc xuất hóa đơn đỏ nếu bạn có nhu cầu.
Vì thi ở đơn vị ủy quyền nên trung tâm có một loại phí khác nữa là phí chuyển đề thi – phí này là 4,000,000/lần thi cho tất cả những người tham gia thi lần đó, do vậy sẽ tùy vào số người thi mà bạn sẽ cần phải đóng lượng phí tương ứng. Khoản số 3 này mình không chắc ở các đơn vị tổ chức ủy quyền thi khác có giống nhau đâu nhé!
2. Cấu trúc chung của các bài thi
Mỗi module sẽ bao gồm một bộ các câu hỏi theo các chương của Syllabi. Số lượng câu hỏi và độ khó (K-level) sẽ được lựa chọn và phân phối tương ứng dựa theo chương đó. Các câu hỏi có thể có một đáp án hoặc nhiều đáp án đúng. Theo như mình biết được thì hiện giờ các câu hỏi nếu có nhiều hơn 1 đáp án đúng, thì nó sẽ nói rõ yêu cầu là mình cần chọn 2 đáp án hoặc 3 đáp án đúng luôn, khác với trước đây là mình sẽ phải tự xác định số lượng đáp án đúng cho câu hỏi đó.
Điểm số cho một câu hỏi phản ánh độ khó của câu hỏi đó. Một câu hỏi K2 tương ứng với 1 điểm, thông thường thì K3 là 2 điểm và K4 là 3 điểm. Tuy nhiên, một câu hỏi K3 cũng có thể tương ứng với 1, 2 hoặc 3 điểm, một câu hỏi K4 cũng có thể tương ứng với 2 hoặc 3 điểm, tùy thuộc vào sự đánh giá của người ra đề.
Một câu hỏi khó yêu cầu người làm bài phải có sự hiểu biết sâu rộng, đa chiều nhất định, tức là bạn phải biết vận dụng kiến thức lý thuyết để suy luận, xử lý tốt một tình huống cụ thể nào đó chẳng hạn, mà không chỉ đơn thuần hỏi định nghĩa hay những cái có thể tra cứu trong tài liệu được. Và ngược lại với một câu hỏi dễ thì sẽ dễ dàng tìm được câu trả lời hơn.
Thông thường, trung bình một câu hỏi K2 sẽ cần khoảng 2 phút để đọc và trả lời, K3 thì 3 phút và K4 là 4 phút. Và vì đó là con số trung bình theo lý thuyết thế nên có thể có câu hỏi cần nhiều hơn hoặc ít hơn thời gian mong đợi trên kia.
Thời gian cho mỗi bài thi sẽ dựa vào số lượng câu hỏi và K-level của module đó. Nếu người thi không sử dụng ngôn ngữ của bài thi là ngôn ngữ chính thì thời gian đc tăng thêm 25%. Ơ nhưng mà mình đã thi 3 bài thì thời gian vẫn là 180p cho TM và TA và 120p cho TTA. Các bạn yên tâm, nhiều người cùng phòng thi với mình chưa dùng hết nửa thời gian kia đã nộp bài đi về rồi ấy nhé hehe.
Lười kẻ lại bảng nên chụp lại luôn từ file gốc -.-
3. Phân phối câu hỏi trong các bài thi
Với mỗi chương (Chapter), sẽ có các nội dung bài học cụ thể cần phải nắm được trong chương đó gọi là Learning Objective (viết tắt là LO) – mình hiểu nôm na thì đây là phần kiến thức lõi của chương đó – hay mục tiêu bài học cần đạt được của chương, phần này được tóm tắt ở mỗi đầu Chapter (Tham khảo hình phía dưới). Mỗi LO cũng được đánh dấu độ K tương ứng [K1, K2, K3…]. Các câu hỏi trong bài thi sẽ bám sát vào các LO của mỗi chương này:
Một chương sẽ truyền tải tương đối nhiều nội dung kiến thức cần phải nắm được (Lười quá nên cũng chụp lại từ Syllabus cho tiện)
Ví dụ ở Chapter 2 (hình bên trên), có 21 LO, số lượng câu hỏi cho chapter này có tối thiểu 24 câu và tối đa là 25 câu, ta có thể hiểu rằng trong 21 LO này sẽ có LO nào đó có 2 câu hỏi, LO có 1 câu hỏi và có thể có thể có LO không có câu hỏi nào. J Những LO nào mà có dấu (*) có nghĩa là nó thuộc dạng tùy chọn rằng nó mang tính ngẫu nhiên do người ra đề sắp xếp, do đó có thể xuất hiện ở bài thi hoặc không. Miễn sao đảm bảo số câu hỏi tối thiểu và tối đa của chương đó. Có hơi loằng ngoằng một chút nhỉ, nhưng các bạn có thể xem minh họa ở hình dưới đây:
Lại một pha lười nữa nên các bạn chịu khó xem hình mà không có Vietsub nhé!
Tóm tắt nhanh số lượng câu hỏi theo Chương cho từng Module sẽ như sau:
Bài thi TM:
Tổng điểm của bài thi TM là 115 điểm, điểm đỗ là 75 điểm trở lên.
Chapter
Số lượng câu hỏi
Chapter 1
Tối thiểu 13 câu, Tối đa 14 câu.
Chapter 2
Tối thiểu 24 câu, Tối đa 25 câu.
Chapter 3
6 câu hỏi
Chapter 4
4 Câu hỏi
Chapter 5
Tối thiểu 3 câu
Chapter 6
Tối thiểu 3 câu, Tối đa 4 câu.
Chapter 7
Tối thiểu 7 câu hỏi
Tổng số câu hỏi trong bài thi TM
65 câu
Bài thi TA:
Tổng điểm của bài thi TA là 120 điểm, điểm đỗ là 78 điểm trở lên.
Chapter
Số lượng câu hỏi
Chapter 1
Tối thiểu 9 câu.
Chapter 2
Tối thiểu 3 câu.
Chapter 3
Tối thiểu 31 câu
Chapter 4
Tối thiểu 4 câu
Chapter 5
Tối thiểu 4 câu, Tối đa 5 câu
Chapter 6
Tối thiểu 4 câu.
Chapter 7
Tối thiểu 1 câu (Có thể có hoặc ko)
Tổng số câu hỏi trong bài thi TA
60 câu
Bài thi TTA:
Tổng điểm của bài thi TTA là 80 điểm, điểm đỗ là 52 điểm trở lên.
Chapter
Số lượng câu hỏi
Chapter 1
2 câu hỏi.
Chapter 2
9 câu hỏi.
Chapter 3
7 câu hỏi.
Chapter 4
12 câu hỏi.
Chapter 5
5 câu hỏi.
Chapter 6
10 câu hỏi..
Tổng số câu hỏi trong bài thi TTA
45 câu
Trên đây là cấu trúc bài thi theo tài liệu hướng dẫn 2012. Tuy nhiên, theo cập nhật trên trang chủ ISTQB đã có thay đổi cho cấu trúc bài thi của TA và TTA phiên bản 2019, ở Việt Nam có vẻ như là chưa áp dụng cấu trúc mới này, tại vì hồi mình thi hồi tháng 10/2020 thì đề vẫn theo cấu trúc cũ.
Theo hướng dẫn mới 2019 thì TA sẽ có 40 câu hỏi – với 120 phút làm bài tiêu chuẩn (+25% thời gian với người thi ko sử dụng ngôn ngữ bài thi là ngôn ngữ chính), TTA sẽ có 45 câu hỏi và 120 phút (hoặc +25%) làm bài tiêu chuẩn:
Các bạn có thể xem đầy đủ và chi tiết thông tin bảng phân phối câu hỏi theo Chapter và LO phiên bản 2019 tại đây.
Hoặc xem mình tóm tắt ở hai bảng dưới này cũng được:
Bài thi TA (2019):
Tổng điểm cho bài thi TA này là 80 điểm, điểm đỗ là 52 điểm trở lên
Chapter
Số lượng câu hỏi
Chapter 1
6 câu hỏi.
Chapter 2
1 câu hỏi.
Chapter 3
17 câu hỏi.
Chapter 4
11 câu hỏi.
Chapter 5
3 câu hỏi.
Chapter 6
2 câu hỏi..
Tổng số câu hỏi trong bài thi TA
40 câu
Bài thi TTA (2019):
Tổng điểm cho bài thi TTA này là 76 điểm, điểm đỗ là 49 điểm trở lên.
Chapter
Số lượng câu hỏi
Chapter 1
2 câu hỏi.
Chapter 2
8 câu hỏi.
Chapter 3
7 câu hỏi.
Chapter 4
13 câu hỏi.
Chapter 5
5 câu hỏi.
Chapter 6
10 câu hỏi.
Tổng số câu hỏi trong bài thi TTA
45 câu
Tóm lại là việc thông tin các câu hỏi được phân bổ trong các chương khá là chi tiết như vậy sẽ giúp cho quá trình ôn tập kiến thức và lên chiến lược học tập của chúng ta được phù hợp hơn. Ví dụ như việc tập trung nỗ lực vào chương có phân phối nhiều câu hỏi nhất để có thể trả lời được đúng nhiều nhất chẳng hạn. Việc rèn luyện thực hành cũng giúp chúng ta khi đọc câu hỏi có thể suy luận ra được rằng câu này thuộc kiến thức của chương nào để vận dụng tương ứng.
4. Thông tin bên lề khác
Thông tin bên lề này là thông tin dựa theo kinh nghiệm và những trải nghiệm của mình trong quá trình ôn luyện và đi thi, xin phép được chia sẻ thêm với các bạn.
Thông thường sẽ có hai hướng chiến lược cho người xác định thi lấy chứng chỉ. Một là tự ộn tập và sau đó đăng ký thi. Hai là đăng ký học một khóa học tại trung tâm ôn luyện nào đó rồi mới thi.
Vậy thì tự ôn tập thì có khả năng thi đỗ được hay không?
Câu trả lời đơn giản lắm, chỉ cần bạn chăm chỉ ôn luyện là được. Hehe. Nói thế ai mà chả nói được. Tuy nhiên, mình lại xin phép chia sẻ ý kiến của mình đó là bạn nên tập hợp được một nhóm những người cùng mục tiêu và ý chí, ngồi lại và ôn tập cùng với nhau sẽ hiệu quả hơn nhiều. Có thể các bạn cùng công ty, hoặc khác công ty. ISTQB Advanced không chỉ có lý thuyết mà còn là những bài tình huống để bạn vận dụng những kiến thức lý thuyết đó để xử lý, trừ trường hợp bạn quá giỏi, quá nhiều kinh nghiệm thực tế rồi thì mình không đề cập ở đây, nhưng trong một nhóm sẽ có nhiều người với những góc nhìn khác nhau sẽ giúp chúng ta có cái nhìn đa chiều hơn đối với một vấn đề hoặc tình huống nào đó, điều này sẽ giúp ích cho quá trình ôn luyện rất nhiều.
Tất nhiên sẽ có lợi thế hơn nhiều nếu bạn có thể thu thập được một ngân hàng câu hỏi ôn tập nào đó, nhưng kiếm ở đâu ra được, đành phải nhờ vào kỹ năng tìm kiếm sử dụng Google và đặc biệt là các mối quan hệ. hehe.
Cách đơn giản hơn là đăng ký đi học trung tâm ôn luyện, họ đã soạn sẵn bài giảng, giáo trình, có người hướng dẫn, người học từ nhiều công ty khác nhau, trình độ và kinh nghiệm khác nhau cũng là một trải nghiệm vô vùng thú vị đấy các bạn, nhiều trung tâm còn cam kết cho bạn học đến khi nào đỗ thì thôi, chỉ có điều lại tốn xèng một chút thôi. – Một khóa đâu đấy 4-5tr thì phải.
Ôn tập bao nhiêu lâu thì có thể đăng ký thi được một Module?
Điều này tùy thuộc vào khả năng học tập của bạn, bạn mất ít thời gian ôn luyện thì bạn có thể đăng ký thi sớm, tuy nhiên với trường hợp vừa đi làm vừa ôn luyện thì chắc cũng phải cần bỏ ra 2-3 tháng đó. Không nên để thời gian học quá lâu vì có thể nó sẽ rơi vãi đâu đó mất nếu bạn không thường xuyên ôn luyện lại kiến thức.
Có nên thi cùng lúc nhiều Module?
Cái này cũng còn tùy thuộc vào mục đích, định hướng nghề nghiệp và nhu cầu của từng người. Có người chỉ thi TM, có người thì TM, TA, cũng có những người thi cả ba TM, TA, TTA. Mình thuộc nhóm thi cả 3 cùng một lúc vì mình thích sưu tầm chứng chỉ và quan trọng là mình cũng có tiền để thi nữa. Haha.
Nhưng câu hỏi là có nên hay không cơ mà nhỉ. Mình chia sẻ một số ý kiến liên quan, còn nên hay không thì do bạn tự quyết định nhé. Ở nội dung kiến thức TM và TA có một vài điểm chung theo đánh giá thì khoảng 60-65% là giống nhau, phần khác nhau là do đặc thù của từng mảng 1 cái là Management (Quản lý), một cái là Analyst (Chuyên môn), thế nên nếu mà bạn xác định chỉ thi TM thì bạn chỉ học chuyên kiến thức của TM, và nếu bạn có dự định thi cả TA thì bạn chỉ cần ôn luyện thêm phần khác của TA tức là khoảng 35-40% lượng kiến thức còn lại thuộc về TA thôi ;)) thế nên nhiều người thường nghĩ là thôi mất công học rồi thì học luôn một thể. Không thi, nhỡ đâu sau này cần lại phải học lại từ đầu thì lại tiếc =)), đấy nhiều người hay nghĩ thế.
Còn TTA, số lượng câu hỏi ít hơn hẳn so với 2 Module trên kia mà lại còn là Technical, nên nhiều người nghĩ là nó sẽ khó hơn và mất thời gian ôn tập hơn, rồi nghĩ là có 2 cái trên kia là ổn rồi. Với lại bỏ ra thêm tận 4 triệu rưỡi nữa thì tốn quá nhỉ, thế là thôi. ;))
Mình thì mình nghĩ mất công học rồi thì học luôn, vất vả luôn một lần cho xong. Có trong tay một lúc 3 cái liền chả vui hơn à. Hehehe, nhưng mà lúc học ôn cũng vất hơn đấy nhé à cả lúc chuyển tiền lệ phí thi cũng buốt ví, lại nhưng nữa là lúc nhận điểm đỗ cả 3 thì thấy nó cũng xứng đáng đấy chứ. >.*
Hi vọng là bài tổng hợp ngắn này có thể giúp các bạn có một cái nhìn tổng quan về bài thi Advanced này. Theo mình thấy thì hầu như mọi người khi đi học thì ko ai tìm hiểu cái này mấy, cũng có thể là do nó không có trong bài thi nên không cần quan tâm =)) tự tìm hiểu làm chi cho mất thời gian. Ơ hơ buồn thế, mất công viết cả bài dài thế này rồi cơ mà, thân dành cho những những bạn nào mà mới nung nấu ý định thi thôi thì có thể tham khảo bài viết này của mình để hiểu được sơ bộ và sau đó lên kế hoạch học tập cũng sẽ tiết kiệm được chút thời gian đó.