3/25/2024

Free For Students 2 | Sharing


Neon Postgresql

Giống với MongoDB Atlas là một nền tảng lưu trữ dữ liệu dành cho cơ sở dữ liệu Mongodb thì Neon là một nền tảng lưu trữ dành cho cơ sở dữ liệu Postgresql, Neon tách biệt điện toán và lưu trữ để cung cấp các tính năng hiện đại dành cho nhà phát triển. 

Cũng với 512MB Free, mặc dù là không nhiều tuy nhiên sử dụng cho mục đích bài tập cá nhân hay đồ án thì cũng là một sự lựa chọn rất phù hợp cho sinh viên.

Website: 

Truy cập website tại: https://neon.tech/

alwaysdata.com

Lưu trữ web miễn phí 100 MB hỗ trợ MySQL, PostgreSQL, CouchDB, MongoDB, PHP, Python, Ruby, Node.js, Elixir, Java, Deno, máy chủ web tùy chỉnh, truy cập qua FTP, WebDAV và SSH; bao gồm hộp thư, danh sách gửi thư và trình cài đặt ứng dụng.

Dung lượng hỗ trợ cũng không nhiều, tuy nhiên trong bài tập lớn sử dụng trên trường có lẽ cũng đủ để có thể dựng một dự án nho nhỏ để demo.



Truy cập website tại: https://www.alwaysdata.com/

moqups.com

Những người làm thiết kế hay lập trình viên bình thường có lẽ đã rất quen với figma, công cụ thiết kế cực kỳ phổ biến. Tuy nhiên thì figma lại thường dành cho những người có chuyên môn và muốn làm được figma cũng phải dành chút thời gian ra với nó. 

Với bài tập lớn thì công việc mẽ mockup hay thiết kế chỉ là một công việc phụ vì vậy không thể dành nhiều thời gian quá nhiều cho nó, moqups cung cấp rất nhiều mẫu giao diện có sẵn để có thể làm những công việc này một cách dễ dàng hơn.


Truy cập website tại: https://app.moqups.com/

creately

Giống với moqups.com là nền tảng để vẽ mockup thì creately là một nền tảng hỗ trợ vẽ biểu đồ UML. creately cung cấp các mẫu UML cho phép xây dựng các sơ đồ UML một cách dễ dàng hơn.

Cũng giống với vẽ mockup chỉ là một bước nhỏ trong quá trình làm bài tập lớn, vì thế cũng không nên tập chung quá nhiều thời gian cho những công việc này, nên việc sử dụng các nền tảng hỗ trợ đa dạng mẫu template là rất cần thiết trong quá trình làm bài tập lớn.


Truy cập website tại: https://app.creately.com/

draw.io

Draw.io có lẽ không còn xa lạ gì với mọi người, đây là một nền tảng vô cùng phổ biến. Với draw.io chúng ta có thể làm gần như mọi thứ: vẽ biểu đồ UML, vẽ luồng hoạt động, vẽ kiến trúc, vẽ mockup, mindmap... Là về cơ bản thì draw.io cũng hoàn toàn có thể thay thế cho 2 nền tảng trên và đây là một nền tảng cực kỳ đa năng.

Draw.io còn cung cấp một kho mẫu có sẵn cho nhiều loại để có thể tùy chỉnh. Đây là một nền tảng mà mình rất hay sử dụng khi đi học và bây giờ là ngay cả khi đi làm. Mỗi lần bị bắt vẽ UML hay mockup là nghĩ ngay tới draw.io.


Truy cập website tại: https://app.diagrams.net/

replit

Replit cung cấp nhiều công cụ và tính năng cần thiết cho việc phát triển phần mềm. Nó hoạt động như một IDE oneline giúp mọi người tỏng nhóm có thể cùng nhau lập trình, nhà cung cấp đám mây, cộng đồng nhà phát triển.

Với các ngôn ngữ lập trình hay sử dụng thì chắc chắn là phải cài nó vào trong máy, còn với một số ngôn ngữ lập trình ít sử dụng mà yêu cầu trong môn học các bạn có thể sử dụng replit để có thể giảm bớt thời gian cài đặt môi trường và sau đó là gỡ đi khi hết môn học.



Truy cập website tại: https://replit.com/

dbdesigner.net

dbdesigner.net là một công cụ vẽ và mô hình hóa về cơ sở dữ liệu. Nền tảng này còn hỗ trợ việc gen các câu SQL sau khi thiết kế và hỗ trợ trên rất nhiều các cơ sở dữ liệu như là MySQL, PostgreSQL, Oracle, Sqlite,...

Tuy nhiên, phiên bản miễn phí hiện đang chỉ hỗ trợ gen SQL với hệ thống dưới 10 table.


Truy cập website tại: https://app.dbdesigner.net/

Paraphrasing Tool

https://quillbot.com/ là công cụ giúp viết lại câu văn để tránh bị ghi nhận đạo văn trên các nền tảng check đạo văn. Hiện tại hệ thông cũng hô trợ một số ngôn ngữ có cả tiếng Việt và Anh. Mọi người viết báo khoa học hay là viết báo cáo bài tập lớn mà có tham khảo từ nguồn khác hay tham khảo từ một bài viết của nhóm khác của thể sử dụng công cụ này để viết lại đoạn văn để tránh bị check đạo văn.


Microsoft Azure

Việc nhận được 100$ cho Azure qua email trường và 1 số package miễn phí dành cho sinh viên mình đã nó qua tại bài viêt Mail edu của trường làm được gì ? mọi người có thể xem chi tiết hơn tại bài viết trên.

123host

Nhận hosting free tại 123host.vn, các bạn có thể triển khai một số dự án bằng PHP hoặc HTML tĩnh để demo cho giáo viên/ giảng viên môn học. Phần này mình cũng có nói chi tiết tại bài viết Free hosting, domain trọn đời, phù hợp cho sinh viên, mọi người có thể xem chi tiết hơn tại bài viết trên.

Một số nền tảng khác

Một số nền tảng khác mình muốn chia sẻ thêm, có thể cũng có thể giúp ích cho mọi người trong một khoảnh khắc nào đó: 

- Công cụ biên dịch code online: https://www.codechef.com/ide

- Vẽ chart online: https://dashboard.visme.co/

- Công cụ viết markdown online theo nhóm: https://hackmd.io/

- Công cụ viết markdown: https://stackedit.io/


Cẩm nang HUST | Share


Ghi chú: bài viết sẽ được cập nhật thường xuyên khi có những thông tin mới

Trong quá trình học hay là hoạt động tại trường chắc hẳn nhiều lúc ai đó cũng sẽ một lần ngạc nhiên rằng là "ơ cái hoạt động này ở đâu vậy?", "ơ cái biểu mẫu này lấy ở đâu vậy?", "ơ sao mày biết phải email cho thầy/cô này!". Thực ra tất cả những thông tin này đều được trường đưa lên các trang web cổng thông tin của trường, nhưng vì lượng thông tin là quá nhiều nên việc tìm kiếm cũng rất khó khăn với nhiều cái trường hiện tại cũng đang tiến hành hợp nhất để mọi người có thể tìm kiếm trên một cổng thông tin duy nhất nhưng vẫn đang trong quá trình. Trong bài viết này mình sẽ ghi chú ra những thông tin hữu ích và cần thiết cho các bạn, nhớ bookmark lại các mục này để khi cần có thể tìm lại một cách nhanh nhất nha.

Mình chia sẻ còn thiếu những phần nào, hoặc mọi người thấy thiếu sót phần nào mà mọi người cho là quan trọng có thể comment lại dưới bài viết để những người sau có thể đọc được nha. Rất cảm ơn mọi người!

Hướng dẫn thủ tục, biểu mẫu, thắc mắc về học tập, học phí.

Tại Bách Khoa các bạn có thể sẽ phải email rất nhiều để hỏi về học tập, thắc mắc về học phí, biểu mẫu hay thủ tục gì đó. Có rất nhiều bạn đã bị trả về email vì email sai cách, không đúng cách, không đúng format hoặc email cho sai người. Việc vấn đề nào đó email cho ai, format email như nào đã được trường quy định và đăng trên cổng thông tin sinh viên tại https://sv-ctt.hust.edu.vn/#/so-tay-sv/69/huong-dan-gui-cau-hoi-toi-phong-dao-tao-cac-van-de-ve-hoc-tap-hoc-phi


Biểu mẫu về học tập

Các biểu mẫu về học tập như: 

- Đơn đề nghị điều chỉnh điểm
- Đơn xin chuyển điểm tương đương 
- Đơn xin đăng ký lớp
- Đơn xin rút lui học phần 
- Đơn xin hoãn thi 
- Đơn xin thi bù do hoãn thi
- Đơn xin học tiếp lên kỹ sư

Mọi người có thể tải về biểu mẫu tại: https://ctt.hust.edu.vn/DisplayWeb/DisplayBaiViet?baiviet=77&fbclid=IwAR1S-wuiqnE33s_ZOSwheDR-e4CNQiolznf7D_vL8Yy1fJBPDa7PHFdf12s

Hoặc tải biểu mẫu tại link (những biểu mẫu không có là mọi người sẽ phải tìm trong mục email phía trên để email cho giáo viên/ giảng viên): BIỂU MẪU HỌC TẬP

Thông báo

Thông báo của trường mới nhất sẽ được đăng tải tại https://ctt.hust.edu.vn/DisplayWeb/DisplayListBaiViet?tag=%C4%90T%C4%90H

Sẽ gồm có lịch thi giữa kì, cuối kì, thông tin cấp bằng, đăng ký xét tốt nghiệp, xét nhận đồ án, đăng ký môn, công tác sinh viên,...

2/12/2024

Free For Students | Sharing


Trong các bài viết trước đã có một số bài viết mình chia sẻ về cách sử dụng mail edu để sử dụng một số các ưu đãi dành cho sinh viên. Vì mail edu một số dịch vụ cũng hết hạn khá là nhanh, một số dịch vụ không khả dụng tại Việt Nam, một số dịch vụ cũng khó đăng ký và sử dụng, vì vậy bài viết này mình giới thiệu một số dịch vụ khác hữu ích cho sinh viên IT sử dụng trong quá trình làm đồ án hay bài tập lớn của mình.

1. MongoDB Atlas

MongoDB Atlas là nền tảng thuộc sự quản lý trực tiếp của MongoDB, người dùng đăng ký được sử dụng 512MB dung lượng miễn phí từ nền tảng này. Dung lượng lưu trữ không nhiều nhưng là vừa đủ để sinh viên sử dụng trong bài tập lớn hay đồ án của mình khi cần triển khai database lên internet.


MongoDB Atlas còn cung cấp tùy chọn lưu trữ dữ liệu trên Aws, GCP (Google Cloud Platform) hoặc Azure. Mình thấy đây là nền tảng mà sinh viên khá ưa thích khi bài tập lớn có sử dụng database là MongoDB.

Truy cập website tại: https://www.mongodb.com/atlas/database

2. InfinityFree - Free Website Hosting

Trang web cho phép bạn tạo website miễn phí mà không quảng cáo. Mình đã từng dùng nền tảng này để triển khai bài tập lớn môn công nghệ web và dịch vụ trực tuyến (Github của dự án tại https://github.com/trannguyenhan/selling-computer), đã hơn 2 năm mà website vẫn còn được giữ trên nền tảng này.

Tuy nhiên, thì nền tảng chỉ cho phép triển khai với ngôn ngữ lập trình PHP và cơ sở dữ liệu MySQL và tối đa 3 website trên 1 tài khoản.


Truy cập website tại https://www.infinityfree.com/

3. Proxy Free

Proxy là một phần không thể thiếu khi bạn làm các bài tập lớn liên quan tới thu thập dữ liệu từ internet. Một số môn học có yêu cầu là nhập môn khai phá dữ liệu một số thầy/cô có thể yêu cầu các bạn tự thu thập dữ liệu cho mô hình, tích hợp dữ liệu và đặc biệt là nhập môn khoa học dữ liệu cần phải làm một luồng từ đầu tới cuối về thu thập, xử lý và xây dựng mô hình.

Một website cung cấp proxy uy tín mà mình hay sử dụng là https://www.webshare.io/, website cung cấp miễn phí 10 proxy để để sử dụng trong bài tập lớn môn học. 

Ngoài ra, nếu có nhu cầu lớn hơn bạn cũng có thể tham khảo thêm về các dịch vụ trả phí mà website cung cấp, tất cả đều rất rẻ so với những nhà cung cấp khác. Ở trường hay ở cty mình cũng thường xuyên sử dụng proxy trên đây.



11/01/2023

Cấu trúc dữ liệu và thuật toán | tổng hợp 7 CTDL phổ biến


Xem lại 3 bài viết về CTDL trên website: 

Cấu trúc dữ liệu và thuật toán | Mảng (Array) và Linked List

Cấu trúc dữ liệu và thuật toán | Ngăn xếp (Stack)

Cấu trúc dữ liệu và thuật toán | Hàng đợi (Queue)

Cấu trúc dữ liệu là cách tổ chức và lưu trữ dữ liệu trong máy tính để chúng ta có thể thực hiện các hoạt động dựa trên dữ liệu được lưu trữ một cách hiệu quả hơn. Với sinh viên CNTT hay là các bạn đã ra trường đi làm, các lập trình viên lâu năm thì CTDL là hành trang không thể thiếu, và CTDL cũng là các câu hỏi được các nhà tuyển dụng thường xuyên sử dụng để hỏi các ứng viên. Trên website cũng đã có một bài viết tổng hợp các câu hỏi phỏng vấn về CTDL các bạn có thể xem lại TẠI ĐÂY.

7 CTDL phổ biến được đề cập tới trong bài viết bao gồm: 

- Mảng (Array)

- Danh sách liên kết ( Linked list)

- Ngăn xếp ( Stack)

- Hàng đợi ( Queue)

- Cây ( Tree)

- Đồ thị ( Graph)

- Bảng băm ( Hash table)

1. Mảng ( Array)

Một mảng ( Array) là một cấu trúc dữ liệu với kích thước cố định, lưu trữ các phần tử cùng kiểu dữ liệu. Nó có thể là một mảng số nguyên, mảng số thực, mảng chuỗi hay một mảng của mảng. Mảng được đánh chỉ mục, được lưu ở các ô nhớ liên tiếp nhau cho phép ta có thể truy cập ngẫu nhiên vào mảng một cách dễ dàng, nhanh chóng.


2. Danh sách liên kết ( Linked List)

Danh sách liên kết là một cấu trúc tuần tự bao gồm một chuỗi các phần tử theo thứ tự tuyến tính được liên kết với nhau. Việc truy cập vào các phần tử trong danh sách liên kết phải là tuần tự, không thể thực hiện truy cập ngẫu nhiên.

- Các phần tử trong danh sách liên kết được gọi là các node

- Mỗi node chứa giá trị và một con trỏ trỏ tới node kế tiếp

- Có một con trỏ head trỏ tới phần tử đầu tiên của danh sách liên kết


3. Ngăn xếp ( Stack)

Là một CTDL hoạt động theo nguyên tắc LIFO ( Last In First Out - phần tử đưa vào sau cùng sẽ được truy cập đầu tiên), CTDL này được thấy thường xuyên trong ngôn ngữ lập trình và ứng dụng của nó đem lại cũng là rất lớn.

Có 2 hoạt động cơ bản được thực hiện trên 1 ngăn xếp đó là: 

- Push: Thêm một phần tử vào đỉnh của ngăn xếp

- Pop: Xóa một phần tử khỏi đỉnh của ngăn xếp

Tùy vào nhu cầu mỗi bài toán chúng ta có thể thêm các hàm phù hợp để thuận tiện hơn khi sử dụng ngăn xếp, ví dụ như xem phần tử ở đỉnh mà không xóa, kiểm tra ngăn xếp rỗng,...


4. Hàng đợi ( Queue)

Là một CTDL hoạt động theo nguyên tắc FIFO ( First In First Out - phần tử được đặt ở đầu sẽ được truy cập đầu tiên), có 2 hoạt động cơ bản được thực hiện trên một hàng đợi đó là:  

- enqueue: thêm một phần tử vào phía cuối hàng đợi

- dequeue: xóa một phần tử ở phía đầu hàng đợi

Tùy vào nhu cầu mỗi bài toán chúng ta có thể thêm các hàm phù hợp để thuận tiện hơn khi sử dụng hàng đợi tương tự như ngăn xếp. Ngoài ra còn có rất nhiều biến thể của hàng đợi để phù hợp hơn với một số bài toán đặc thù như hàng đợi ưu tiên, hàng đợi 2 đầu,...

5. Cây ( Tree)

Cây là một cấu trúc dữ liệu có phân cấp, trong đó dữ liệu được tổ chức theo thứ bậc và được liên kết với nhau khi lưu trữ. Ứng dụng của cây là rất lớn mà bình thường chúng ta sẽ thấy được ở một số khái niệm như cây đơn vị, cây thư mục,...

Có rất nhiều loại cây đã ra đời để giải quyết các bài toán từ dễ tới khó, khắc phục nhược điểm của cây trước như: cây tìm kiếm nhị phân, B-Tree, Splay Tree, Cây đỏ đen,...


6. Đồ thị ( Graph)

Đồ thị là một tập hợp hữu hạn đỉnh ( nút) và đường đi giữa các đỉnh này. Có nhiều khái niệm liên quan tới đồ thị như bậc của đồ thị, kích thước đồ thị,... 2 đỉnh được gọi là liền kề nếu chúng được nối với nhau bởi 1 đường.

Cây cũng là một loại đồ thị và là đồ thị liên thông, không có chu trình. Nhưng vì cây đặc biệt và ứng dụng lớn vì thế chúng thường được nhắc riêng khi nói về chủ đề đồ thị.

Có 2 loại đồ thị: 

- Đồ thị có hướng: tất cả đường đi đều được đánh dấu chiều giữa điểm đầu và điểm cuối

- Đồ thị vô hướng: tất cả đường đi trên nó đều không quy định chiều


7. Bảng băm ( Hash table)

Bảng băm cũng là một loại CTDL khá phổ biến và đặc biệt, nó lưu trữ các giá trị mà mỗi giá trị có một khóa ( key) được liên kết với nó. Bảng băm hỗ trợ tìm kiếm hiệu quả nếu ta biết được khóa của giá trị cần tìm. 



10/01/2023

Những gì sắp tới mình sẽ viết và chia sẻ trên Blog? Xa hơn việc chỉ chia sẻ tài liệu | Sharing


Chắc nhiều bạn biết tới https://www.tailieubkhn.com/ qua những bài viết về tài liệu học tập, chia sẻ một ít source code các môn học như thuật toán ứng dụng, kỹ thuật lập trình,... Một số các chia sẻ của mình về môn học, trải nghiệm khi đi học hay là các kiến thức thú vị xung quanh. Nhưng mà tài liệu thì cũng có hạn và chắc là cũng tới lúc phải hết thôi, các bài viết về tài liệu các môn học mình sẽ CẬP NHẬT trực tiếp vào các bài viết đấy khi có những tài liệu mới và phù hợp với môn học, các bạn hãy cứ theo dõi các bài viết để cập nhật thêm những thông tin mới nhất mà mình update.


Các bài viết gần đây của website các bạn đang thấy là nó đi vào một số hướng hẹp hơn, ví dụ như là chỉ một chủ đề nhỏ thôi Pull down refresh và Pull up loading, đây chỉ là một câu hỏi trong môn phát triển ứng dụng đa nền tảng hay là việc cài đặt các CTDL ở 3 bài viết trước bài viết này cũng chỉ là 3 bài tập nhỏ trong môn CTDL&TT mà một số thầy cô yêu cầu... Và đây cũng là hướng đi sắp tới của Blog, mình sẽ đi sâu hơn nữa vào các vấn đề cụ thể, ngoài ra mình cũng sẽ chia sẻ nhiêu hơn về cuộc sống đi làm và cuộc sống đi học là trải nghiệm của chính bản thân mình.

Một điều nhỏ nhoi muốn gửi gắm tới mọi người, Blog của mình có đặt quảng cáo và mình đã cố gắng chèn những quảng cáo vào vị trí thích hợp nhất để không ảnh hưởng gì tới mọi người khi truy cập website và không bao giờ dùng những quảng cáo cả trang khi chuyển trang gây khó chịu cho các đọc giả. Mong rằng những quảng cáo mình đặt trên website không gây ảnh hưởng tới trải nghiệm của các bạn, nếu có thể các bạn có thể click vào các banner quảng cáo để mình có thêm kinh phí để gia hạn domain, một cốc cafe,... Rất cảm ơn các bạn  thời gian qua đã ủng hộ Blog của mình.

Tác giả: trannguyenhan

8/31/2023

Cấu trúc dữ liệu và thuật toán | Hàng đợi (Queue)


1. Cấu trúc dữ liệu hàng đợi và ứng dụng

Hàng đợi là một dạng CTDL mà ở đó thao tác chèn vào sẽ được diễn ra ở một đầu, thường gọi là phía sau hay cuối (back or rear), trong khi phép toán xóa chỉ được thực hiện ở phía còn lại, gọi là phía trước hay đầu (front or head).

Nguyên tắc của hàng đợi: Vào trước ra trước, First-In First-Oout (FIFO)


Giống với ngăn xếp, hàng đợi cũng có 2 cách cài đặt cơ bản là dùng mảng và con trỏ.

Hàng đợi cũng có rất nhiều ứng dụng trong thực tế, ví dụ như là:

- Trong hệ điều hành: hàng đợi xử lý sự kiện, quản lý tiến trình, xử lý các câu lệnh. CPU không thể chạy tất cả các task cùng lúc nên các task sẽ được sắp xếp theo thứ tự ưu tiên lần lượt.

- Web server: một trang web cần phải xử lý vài nghìn files của người dùng nhưng khả năng của trang web chỉ xử lý được 100 files cùng một lúc, lúc này chúng ta cần một hàng đợi để đưa các request vào hàng đợi để chờ xử lý.

- Ứng dụng khi in hoặc upload nhiều ảnh cùng lúc

- Lưu vết trong quá trình tìm kiếm, quay lui, vét cạn,...

- Duyệt đồ thị

2. Cài đặt ngăn xếp sử dụng mảng

Khai báo một struct Queue và viết các hàm tương ứng với các phép toán trên hàng đợi:

- isFull(): kiểm tra hàng đợi đã đầy chưa

- enqueue(): thêm phần từ vào cuối hàng đợi

- dequeue(): lấy phần tử ra khỏi đầu hàng đợi

- getFront(): xem phần tử đầu hàng đợi

- getRear(): xem phần tử ở cuối hàng đợi

Tùy thuộc vào từng bài toán, khi cần thêm những chức năng cụ thể nào cho hàng đợi thì chúng ta có thể viết thêm các hàng tương ứng để công việc được thực hiện một cách dễ dàng hơn.

#define INT_MIN -2147483648

struct Queue {
    int front, rear, size;
    unsigned capacity;
    int* array;
};

struct Queue* createQueue(unsigned capacity){
    struct Queue* queue = (struct Queue*) malloc(sizeof(struct Queue));
    queue->capacity = capacity;
    queue->front = queue->size = 0;
    queue->rear = -1;
    queue->array = (int*) malloc(queue->capacity * sizeof(int));
    return queue;
}

// Kiem tra queue day
int isFull(struct Queue* queue){
    return (queue->size == queue->capacity);
}

// Kiem tra queue rong
int isEmpty(struct Queue* queue){
    return (queue->size == 0);
}

// Them phan tu vao queue
void enqueue(struct Queue* queue, int item){
    if(isFull(queue)){
        return;
    }

    queue->rear = (queue->rear + 1);
    queue->array[queue->rear] = item;
    queue->size = queue->size + 1;
    printf("%d enqueued to queue\n", item);
}

int dequeue(struct Queue* queue){
    if(isEmpty(queue)){
        return INT_MIN;
    }

    int item = queue->array[queue->front];
    queue->front = (queue->front + 1);
    queue->size = queue->size - 1;
    return item;
}

int getFront(struct Queue* queue){
    if(isEmpty(queue)){
        return INT_MIN;
    }

    return queue->array[queue->front];
}

int getRear(struct Queue* queue){
    if(isEmpty(queue)){
        return INT_MIN;
    }

    return queue->array[queue->rear];
}

int main(){
    struct Queue* queue = createQueue(10);
    enqueue(queue, 1);
    enqueue(queue, 2);
    printf("Top of queue is %d", getFront(queue));
    printf("Rear of queue is %d", getRear(queue));

}

3. Cài đặt ngăn xếp sử dụng con trỏ

Với con trỏ thì chúng ta cũng cài đặt tương tự các hàm so với sử dụng mảng.


#include<stdio.h>
#include<stdlib.h>

struct node
{
    int data;
    struct node *next;
};

struct node *front = NULL, *rear = NULL;

void enqueue(int val)
{
    struct node *newNode = malloc(sizeof(struct node));
    newNode->data = val;
    newNode->next = NULL;

    if(front == NULL && rear == NULL){
        front = rear = newNode;
    } else {
        rear->next = newNode;
        rear = newNode;
    }
}

void dequeue()
{
    struct node *temp;

    if(front == NULL)
         printf("Queue is Empty\n");
    else
    {
        temp = front;
        front = front->next;

        if(front == NULL){
            rear = NULL;
        }

       free(temp);
    }

}

void printList()
{
    struct node *temp = front;

    while(temp)
    {
        printf("%d->",temp->data);
        temp = temp->next;
    }
    printf("NULL\n");
}

int main()
{
    enqueue(10);
    enqueue(20);
    enqueue(30);
    printf("Queue :");
    printList();
    dequeue();
    printf("After dequeue the new Queue :");
    printList();
    dequeue();
    printf("After dequeue the new Queue :");
    printList();

    return 0;
}

Xem đầy đủ code tại repo github: https://github.com/piandhust/data-structures/blob/main/queue.chttps://github.com/piandhust/data-structures/blob/main/queue_pointer.c

8/27/2023

Cấu trúc dữ liệu và thuật toán | Ngăn xếp (Stack)


1. Cấu trúc dữ liệu ngăn xếp và ứng dụng

Ngăp xếp là một dạng cấu trúc dữ liệu mà ở đó các thao tác với CTDL này chỉ diễn ra ở một đầu, được gọi là đỉnh của ngăn xếp (top). Hai thao tác phổ biến đối với ngăn xếp là đẩy vào (push) và lấy ra (pop), cả hai thao tác này đều tác động vào đỉnh của ngăn xếp.

Nguyên tắc của ngăn xếp: Vào trước ra sao, First-In Last-Out (FILO)

Có 2 cách cài đặt ngăn xếp là sử dụng mảng hoặc sử dụng con trỏ.

Mặc dù nhìn bề ngoài ngăn xếp có vẻ trông đơn giản nhưng nó lại có ứng dụng rất lớn trong thực tế. Ứng dụng trong sử dụng điều hướng các màn hình của điện thoại, ví dụ chúng ta đang ở một màn hình Settings của Facebook, Khi bấm vào General sẽ bị chuyển hướng sang một màn khác, vậy thì làm sao để khi bấm quay lại có thể quay lại đúng màn Settings một cách nhanh nhất? Đó chính là vứt nó vào ngăn xếp, mỗi khi bấm quay lại chỉ cần lấy nó ra từ đỉnh của ngăn xếp là được. Một số các ứng dụng khác của ngăn xếp như là lịch sử trình duyệt, hay là các cơ chế Undo (Redo) trong các trình soạn thảo văn bản. 

Ngăn xếp còn rất quan trọng trong việc giải một số bài toán như: 

- Tính giá trị biểu thức trung tố, hậu tố

- Bài toán cộng hai số lớn

- Bài toán kiểm tra ngoặc đúng 

- Bài toán đảo ngược xâu

2. Cài đặt ngăn xếp sử dụng mảng

Khai báo một struct Stack và viết các hàm tương ứng với các phép toán trên ngăn xếp: 

- isFull(stack): kiểm tra xem ngăn xếp đã đầy chưa 

- isEmpty(stack): kiểm tra ngăn xếp có rỗng không

- push(stack, item):  thêm phần tử vào ngăn xếp

- pop(stack): lấy phần tử ra khỏi ngăn xếp

- getTop(stack): xem phần tử ở đầu ngăn xếp và không xóa phần tử đó khỏi ngăn xếp

Tùy thuộc vào từng bài toán, khi cần thêm những chức năng cụ thể nào cho ngăn xếp thì chúng ta có thể viết thêm các hàm tương ứng để công việc được thực hiện một cách dễ dàng hơn.


#define INT_MIN -2147483648

struct Stack {
    int top;
    unsigned capacity;
    int* array;
};


// Khoi tao ngan xep
struct Stack* createStack(unsigned capacity){
    struct Stack* stack = (struct Stack*) malloc(sizeof(struct Stack));
    stack->capacity = capacity;
    stack->top = -1;
    stack->array = (int*) malloc(stack->capacity * sizeof(int));
}

// Kiem tra xem ngan xep day chua
int isFull(struct Stack* stack){
    return stack->top == stack->capacity - 1;
}

// Kiem tra ngan xep rong khong
int isEmpty(struct Stack* stack){
    return stack->top == -1;
}

// Them phan tu vao stack
void push(struct Stack* stack, int item){
    if(isFull(stack)){
        return;
    }

    stack->array[++stack->top] = item;
    printf("%d push to stack\n", item);
}

int pop(struct Stack* stack){
    if(isEmpty(stack)){
        return INT_MIN;
    }

    return stack->array[stack->top--];
}

int getTop(struct Stack* stack){
    if(isEmpty(stack)){
        return INT_MIN;
    }

    return stack->array[stack->top];
}

int main(){
    struct Stack* stack = createStack(10);
    push(stack, 2);
    push(stack, 3);
    printf("Top of value in stack: %d", getTop(stack));

}

3. Cài đặt ngăn xếp sử dụng con trỏ

Với con trỏ thì chúng ta cũng cài đặt tương tự các hàm so với cài đặt ngăn xếp sử dụng mảng.


#include <stdio.h>

struct Node {
    int data;
    struct Node* next;
};

struct Node* newNode(int val){
    struct Node* newN = (struct Node*) malloc(sizeof(struct Node));
    newN->data = val;
    newN->next = NULL;

    return newN;
}

void push(struct Node* head, int val){
    struct Node* newN = newNode(val);
    if(head == NULL){
        newN->next = NULL;
    } else {
        newN->next = head;
    }

    head = newN;

    printf("Top of stack is %d\n", head->data);
    printf("----------------\n");
}

int pop(struct Node* head){
    if(head == NULL){
        printf("Stack is empty\n");
        return;
    }

    int item = head->data;
    struct Node* tmp = head;
    head = head->next;
    free(tmp);

    printf("Top of stack is %d\n", head->data);
    return item;
}

int isEmpty(struct Node* head){
    return head == NULL;
}

int getTop(struct Node* head){
    if(head == NULL){
        return NULL;
    }

    return head->data;
}

int main(){
    struct Node* head = NULL;
    push(head, 10);
    pop(head);

    //printf("Top stack: %d", getTop(head));
}

Xem đầy đủ code tại repo github: https://github.com/piandhust/data-structures/blob/main/stack.chttps://github.com/piandhust/data-structures/blob/main/stack_pointer.c

8/19/2023

Cấu trúc dữ liệu và thuật toán | Mảng (Array) và Linked List


1. "Cấu trúc dữ liệu"

Cấu trúc dữ liệu là một họ các biến có thể có kiểu dữ liệu khác nhau, được liên kết với nhau theo một cách thức được quy định trước nào đó. Ví dụ như mảng là một dãy các ô có cùng kiểu dữ liệu xác định. 

Một số cấu trúc dữ liệu phổ biến như là: 

- Mảng

- Danh sách

- Đồ thị

- Ngăn xếp

- Hàng đợi

- Cây

Với các bài viết về cấu trúc dữ liệu này, mình sẽ đề cập tới khái niệm chính và cách cài đặt từng loại cấu trúc dữ liệu.

2. Cấu trúc dữ liệu mảng 

Dữ liệu dạng mảng là một dạng dữ liệu vô cùng phổ biến mà chúng ta có thể gặp thường xuyên trong mọi ngôn ngữ lập trình và mọi dự án.

Thông thường mảng thường được lưu trữ trên một dãy liên tiếp các ô nhớ trên bộ nhớ, vì vậy việc truy cập các phần tử trong mảng là cực kỳ nhanh chóng, nhưng lại bất lợi trong việc phân bổ thêm ô nhớ cho mảng.

Mảng thì rất quen thuộc rồi, các ngôn ngữ lập trình đều hỗ trợ hầu như mọi phép toán liên quan tới mảng, nên phần cài đặt mảng mình sẽ không đề cập tới trong phần này.

3. Cấu trúc dữ liệu danh sách liên kết đơn 

Danh sách liên kết đơn (hay một số tài liệu đề cập là danh sách móc nối đơn) là danh sách các phần tử mà mỗi phần tử sẽ chứa giá trị và một con trỏ chứa trỏ tới ô kế tiếp của danh sách.



Danh sách liên kết sẽ khắc phục được một số nhược điểm của việc sử dụng mảng đó là: 

- Bổ sung một phần tử tốn kém thời gian

- Lãng phí khoảng bộ nhớ trống khai báo ban đầu không dùng đến

- Phải duy trì một khoảng không gian lưu trữ liên tục trong bộ nhớ

3.1 Cài đặt danh sách liên kết đơn

Các ví dụ về cài đặt cấu trúc dữ liệu trong các bài viết mình sẽ sử dụng ngôn ngữ lập trình C.

Khai báo một struct node, và viết 5 hàm tương ứng với 5 phép toán trên danh sách liên kết: 

- isEmpty(): kiểm tra danh sách liên kết rỗng 

- print_list(): in danh sách phần tử 

- push(item): thêm phần tử vào đầu danh sách liên kết

- pop(): loại bỏ phần tử cuối danh sách

- insert_by_index(inx, item): chèn một phần tử vào vị trí bất kỳ trong danh sách liên kết

Tùy thuộc vào từng bài toán, khi cần thêm những chức năng cụ thể nào cho danh sách liên kết thì chúng ta có thể viết thêm các hàm tương ứng để công việc được thực hiện một cách dễ dàng hơn.

#include<stdio.h>
#define INT_MIN -2147483648

struct node {
    int data;
    struct node *next;
};

struct node* head = NULL;

int isEmpty(){
    return head == NULL;
}

void print_list(){
    struct node *current = head;

    while(current != NULL){
        printf("%d\n", current->data);
        current = current->next;
    }
}

// push to front list
void push(int item){
    struct node* newN = (struct node*) malloc(sizeof(struct node));
    newN->data = item;
    newN->next = head;

    head = newN;
}

// pop last
void pop(){
    struct node* it = head;

    if(it->next == NULL){
        head = NULL;
        free(it);
        return;
    }

    while(it->next->next != NULL){
        it = it->next;
    }

    struct node* lastN = it->next;
    it->next = NULL;
    free(lastN);
}

void insert_by_index(int item, int inx){
    if(inx == 0){
        push(item);
        return;
    }

    struct node* it = head;
    int cnt = 1;

    while(cnt < inx){
        it = it->next;
        cnt++;
    }

    struct node* prev = it;
    struct node* next = it->next;

    // create new node
    struct node* newN = (struct node*) malloc(sizeof(struct node));
    newN->data = item;


}

3.2 Kiểm tra danh sách liên kết đơn vừa cài đặt

Chúng ta kiểm tra nhanh về cấu trúc dữ liệu vừa cài đặt có đúng không bằng cách sử dụng các hàm vừa cài đặt để thao tác với cấu trúc dữ liệu và kiểm tra dữ liệu sau khi sử dụng các hàm đã đúng chưa bằng cách in ra (sử dụng hàm print_list()).

int main(){
    // data example
    push(1);
    push(2);
    push(4);
    pop();
    pop();
    push(4);

    print_list();
}

Xem đẩy đủ code tại repo github: https://github.com/piandhust/data-structures/blob/main/list.c

5/19/2023

Tổng hợp câu hỏi phỏng vấn về cấu trúc dữ liệu và giải thuật


Câu 1: Độ phức tạp của thuật toán sắp xếp nổi bọt?

A. N

B. 2N

C. N * Log(N)


Câu 2: Độ phức tạp của thuật toán sắp xếp Quicksort

a. N

b. 2N

c. N * Log(N)


Câu 3: Cấu trúc dữ liệu nào hỗ trợ nhanh nhất việc kiểm tra một phần tử có nằm trong danh sách hay không?

A. ArrayList

B. HashSet

C. TreeMap


Câu 4: Giải thuật đệ quy là?

A. Trong giải thuật của nó có lời gọi tới chính nó nhưng với phạm vi nhỏ hơn

B. Trong giải thuật của nó có lời gọi tới chính nó

C. Trong giải thuật của nó có lời gọi tới một giải thuật khác đã biết kết quả

D. Trong giải thuật của nó có lời gọi tới chính nó nhưng với phạm vi lớn hơn


Câu 5: Ngăn xếp làm việc theo nguyên tắc

A. LILO ( last in last out)

B. LIFO ( last in first out)

c. FOLO (first out last out)

d. FIFO ( first in first out)


Câu 6: Định nghĩa danh sách tuyến tính hàng đợi:

A. Là một danh sách tuyến tính trong đó phép bổ sung một phần tử và phép loại bỏ một phần tử được thực hiện ở tại một vị trí bất kì trong danh sách.

B. Hàng đợi là kiểu danh sách tuyến tính trong đó, phép bổ sung một phần tử được thực hiện ở một đầu, gọi là lối sau (rear) hay lối trước (front). Phép loại bỏ không thực hiện được.

C. Hàng đợi là kiểu danh sách tuyến tính trong đó, phép bổ sung một phần tử hay loại bỏ được thực hiện ở một đầu danh sách gọi là đỉnh (Top)

D. Hàng đợi là kiểu danh sách tuyến tính trong đó, phép bổ sung phần tử ở một đầu, gọi là lối sau (rear) và phép loại bỏ phần tử được thực hiện ở đầu kia, gọi là lối trước (front).


Câu 7: Độ phức tạp của việc tìm kiếm 1 số trong 1 mảng số nguyên đã sắp xếp là bao nhiêu?

A. N

B. N * Log(N)

C. Log(N)

D. N


Câu 8: Tạo một file ignore.txt gồm 500 nghìn phần tử random từ 1-> 2triệu.  Tạo một file data.txt có 1,5 triệu phần tử. Các phần tử tăng dần từ 1 đến 2 triệu và loại trừ các phần tử trong file ignore yêu cầu: Có thể dùng bất kỳ ngôn ngữ gì để thực hiện. 

Áp dụng các kiến thức về cấu trúc dữ liệu giải thuật sao cho code tối ưu và thời gian thực thi ngắn nhất có thể. 

Bài nộp bao gồm code và thời gian thực thi đoạn code đó. Không bao gồm các file dữ liệu.


Câu 9: A là một sinh viên CNTT, làm thêm việc shipper hàng ngày. A nhận ra, mỗi ngày mình chỉ có thể chở tổng cộng 100kg. Nên giờ A cần tìm một thuật toán để tối ưu giá trị thu lại của mình. Vì vậy A lên danh sách các đơn hàng mỗi ngày. Trong ngày hôm nay, A có danh sách như sau: 

Cân nặng = [20, 30, 40, 50]

Giá trị = [10, 40, 10, 20]

Theo danh sách trên, A sẽ trở món hàng ở vị trí 0, 1, 3 - tổng cân nặng là 20 + 30 + 50 = 100kg và có tổng giá trị là 10 + 40 + 20 = 70 là lớn nhất.

Yếu cầu: viết hàm với đầu vào là 2 danh sách, danh sách cân nặng và giá trị theo thứ tự tương ứng của từng mặt hàng, tính ra phương án cho A chọn những mặt hàng nào để tối ưu giá trị nhận được.

Input:

    Cân nặng = [20,30,40,50]

    Giá trị = [10,40,10,20]

Output:

    [0, 1, 3],100,70


Câu 10: Ai là người nổi tiếng:

Người nổi tiếng trong một nhóm là người không biết ai trong nhóm đó, nhưng tất cả mọi người trong nhóm đó đều biết anh ta. 

Ví dụ 1: Cho một nhóm người, dưới dạng ma trận như sau:

A B C
A 0 0 0
B 1 0 1
C 1 0 0

Như vậy người nổi tiếng là A, vì anh ta không quen ai trong nhóm, nhưng tất cả đều biết anh ta.

Ví dụ 2: 

A B C
A 0 1 0
B 1 0 1
C 1 1 0

Trong ví dụ này không có ai là người nổi tiếng cả.

Yêu cầu: Đầu vào là một ma trận quen biết như ví dụ, hãy tìm nguời nổi tiếng trong danh sách đầu vào.

Input:
[
[0, 0, 0],
[1, 0, 1],
[1, 0, 0]
      ]
Output: 0 => người ở vị trí 0 là người nổi tiếng

Input:
[
[0, 1, 0],
[1, 0, 1],
[1, 0, 0]
      ]
Output: null => không có ai là người nổi tiếng

Câu 11: Tính giai thừa của n một cách nhanh nhất.  Với n được người dùng nhập.

1/17/2023

What’s the Best Programming Language to Learn? | Sharing


Chúc mừng năm mới 2023, mình xin chúc toàn bộ đọc giả của tailieubkhn có một năm mới thuật lợi, dành dựt được nhiều học bổng, học thêm được vô vàn kiến thức, vân vân và mây mây. Lâu lắm rồi mình mới quay trở lại blog, bỏ bê cũng khá lâu và hôm nay nhân dịp một trong những ngày đầu năm 2023 mình muốn chia sẻ quan điểm của mình về một chủ đề mình nghĩ cũng khá thu hút là: đâu là ngôn ngữ lập trình đáng học nhất năm? Mình không nhắc tới năm 2022 hay 2023 vì mình nghĩ bài viết sẽ giúp ích cho các bạn dù cho đang ở năm nào đi nữa.

Nếu các bạn theo dõi nhiều các bài viết của HUST & PI thì chắc nhiều bạn cũng biết quan điểm của mình là chúng ta nên học những cái gốc dễ, hiểu những cái gốc dễ như là cấu trúc dữ liệu và thuật toán, lập trình hướng đối tượng, kỹ thuật lập trình, mạng máy tính,... Khi hiểu rõ, nắm bắt được các kiến thức trên thì việc tiếp cận với từng ngôn ngữ lập trình các bạn sẽ thấy điều đó là cực kỳ dễ dàng. 

Tuy nhiên thì chắc chắn rồi, mỗi lập trình viên phải biết và thành thạo ít nhất một ngôn ngữ lập trình, không thì phát triển ứng dụng như thế nào, đúng không! Vậy thì học ngôn ngữ gì?

Có bao giờ bạn tự hỏi rằng tại sao lại có nhiều ngôn ngữ lập trình như vậy không? Tại sao không thống nhất chúng lại thành một ngôn ngữ lập trình duy nhất để cho lập trình viên dễ học và dễ sử dụng hơn. Mình sẽ giải thích với hai ý như sau: 

- Đầu tiên là mỗi ngôn ngữ lập trình được phát triển bởi những người/nhóm người khác nhau vì thế việc gộp vào chưa chắc đã dễ dàng hay tóm gọn lại là khó khăn.

- Tiếp là, mọi thứ sinh ra thì đều có những ý nghĩa của nó, các ngôn ngữ lập trình cũng vậy, mỗi ngôn ngữ lập trình sẽ sinh ra để giải quyết một vấn đề riêng và việc gộp lại chưa chắc đã tốt, vì khi gộp toàn bộ lại thành một thì chúng ta sẽ có một ngôn ngữ khổng lồ với bộ biên/phiên dịch cực lớn mà rõ ràng với những vấn đề cụ thể thì chúng ta chỉ cần một ngôn ngữ tương ứng để giải quyết vấn đề đó. Vậy lúc này thay vì gọt quả táo chúng ta chỉ cần con dao gọt hoa quả là được thì chúng ta lại cầm hẳn con dao thịt lợn để gọt quả táo đó, xong thì cũng xong thôi nhưng chắc chắn thời gian gọt sẽ lâu hơn, quả táo gọt ra sẽ không đẹp và tròn, chúng ta còn vất vả trong việc cầm con dao để gọt quả táo nữa.

Điểm qua một số ngôn ngữ phổ biến thì có thể thấy Python là một ngôn ngữ ngắn gọn, cú pháp gần gũi, phù hợp với các nhà toán học hay các nhà phân tích dữ liệu để họ có thể biểu diễn một cách dễ dàng các công thức toán học sang ngôn ngữ lập trình. Javascript là một ngôn ngữ bất đồng bộ và chỉ chạy đơn luồng. C/C++ giúp lập trình viên tự quản lý và phân chia bộ nhớ, với C/C++ lập trình viên có thể "thao túng" máy tính ở mức độ khá thấp (có rất nhiều người vẫn coi C/C++ là một ngôn ngữ lập trình bậc thấp hoặc bậc trung). Java thì lại là một ngôn ngữ 100% hướng đối tượng, hướng tới việc viết một lần và chạy trên nhiều nền tảng. PHP là một ngôn ngữ khá dễ dàng trong phát triển các trang web...


Bây giờ chúng ta sẽ quay lại câu hỏi ở đầu bài viết, Vậy thì học ngôn ngữ gì?, và câu trả lời dưới đây là quan điểm của riêng mình về vấn đề này.

Mình sẽ đưa ra một số các gạch đầu dòng về tiêu chí để chọn ngôn ngữ lập trình như sau:

- Một là về chuyên ngành mà bạn theo đuổi. Như mình nói bên trên thì mỗi ngôn ngữ lập trình sinh ra để giải quyết một số vấn đề cụ thể vì thế khi bạn quyết định chọn một chuyên ngành hẹp thì hãy chọn một ngôn ngữ lập trình mà cộng đồng trong đó sử dụng phổ biến vì chắc chắn là nó phù hợp đã, phù hợp thì nó mới phổ biến, tiếp là sẽ có một cộng đồng mạnh hỗ trợ, có nhiều các hướng dẫn trên Google hay StackOverFlow. Một số đại diện tiêu biểu mà mình đưa ra là: 

    - Web Frontend: Javascript, HTML, CSS

    - Web Backend: Hầu như mọi ngôn ngữ lập trình đều có thể làm được web backend, tùy mục đích của bạn để chọn ngôn ngữ cho phù hợp. Nếu như bạn muốn làm một hệ thống chat realtime thì có thể nghĩ tới Nodejs. Nếu như bạn đang chuẩn bị làm một hệ thống thanh toán thì có thể nghĩ tới Java. Nếu như trang web của bạn là một trang web nhỏ, thuần là web bán hàng thì có thể sử dụng PHP,...

    - Game: C/C++, Java, C#

    - AI, Khoa học dữ liệu: Python và 1 số ít là Java

    - Nhúng, IoT: C/C++

    - ...

-  Hai là về độ hot của nó hiện tại hay chính là nhu cầu của thị trường hiện tại. Các doanh nghiệp và nhất là các doanh nghiệp Việt Nam thì thường chạy theo trend khá nhanh. Vì đa số các doanh nghiệp Việt Nam là làm outsource nên họ sẽ sử dụng các công nghệ mới nhất để có thể hỗ trợ tối đa trong việc phát triển, vì thế việc chọn một ngôn ngữ được nhiều lập trình viên sử dụng hay nhiều nhà tuyển dụng đăng tuyển thì sẽ là một lợi thế lớn cho mọi người. Để biết ngôn ngữ lập trình nào đang hot, đang top, các bạn có thể tham khảo một số bảng xếp hạng sau: 

    1. PYPL (The PopularitY of Programming Language): bảng xếp hạng này dựa trên việc theo dõi tìm kiếm của từ khóa "[language] tutorial" (hướng dẫn học [ngôn ngữ]) trên Google. Bảng xếp hạng này rất tốt cho việc thống kê xem có bao nhiêu lập trình viên đang tiếp cận một ngôn ngữ mới.

    2. TIOBE INDEX: cũng giống với PYPL, TIOBE cũng dựa trên việc tìm kiếm để xác định sự phổ biến của một ngôn ngữ

    3. IEEE SpectrumIEEE kết hợp dữ liệu từ khắp nơi trên Internet để xác định ngôn ngữ nào đang phát triển. Bạn thậm chí có thể sắp xếp danh sách của họ theo xu hướng, tìm kiếm việc làm hoặc xếp hạng tùy chỉnh

    4. Stackoverflow Developer SurveysMỗi năm, StackOverflow, một trang web hỏi đáp rất phổ biến dành cho các nhà phát triển, tổ chức một cuộc khảo sát người dùng. Tại đây, bạn có thể tìm thấy các ngôn ngữ phổ biến nhất được các nhà phát triển như bạn sử dụng, cũng như các công nghệ được mong muốn nhất và thậm chí bị ghét nhất.

- Ba là độ yêu thích của bạn với ngôn ngữ đó. Ví dụ như mình là người yêu thích sự chặt chẽ, rõ ràng nên mình khá thích Java và khá ghét Javascript. Dĩ nhiên ghét hay thích còn tùy thuộc vào khi bạn tiếp cận với chúng nữa.

Cuối cùng, với mình thì lập trình viên nên có cho mình một ngôn ngữ tủ và bạn có thể học thêm một vài các ngôn ngữ tùy trường hợp và sở thích. Chúc mọi người một năm mới vui vẻ!

Tham khảo: https://torquemag.io/