Giải thích về ghi chú 2: Trong hình minh họa ta sẽ thấy Stack nằm lộn ngược từ trên xuống, đó cũng là cách bộ nhớ Stack được tổ chức trong thực tế, nhờ phát triển từ địa chỉ cao xuống địa chỉ thấp mà CPU có thể phát hiện ra lỗi Stack overflow một cách dễ dàng (so sánh với 0).
Khi học về con trỏ, bạn sẽ thường xuyên phải xin cấp phát và giải phóng bộ nhớ, vậy những vùng nhớ này được quản lý bởi ai và như thế nào?
Về cơ bản, khi khởi động lên, hệ điều hành sẽ nắm quyền kiểm soát toàn bộ bộ nhớ, bởi bộ nhớ có thể coi như một sân chơi chung nên phải có phải có người cầm trịch, quản lý xem chỗ nào đã có người dùng, chỗ nào còn trống, tránh việc dữ liệu của một chương trình này bị ghi đè bởi một chương trình khác.Khi bạn gọi hàm malloc, hoặc new, trình quản lý bộ nhớ sẽ tìm xem chỗ nào chưa có ai sử dụng, nó lấy một phần vừa đủ với kích thước bạn xin cấp phát, đánh dấu vùng nhớ đó đã được cấp cho chương trình (process) của bạn và trả về địa chỉ. Nhiệm vụ của bạn là lưu lại địa chỉ (vào một biến con trỏ) và chỉ sử dụng trong phạm vi đã được cấp.Khi bạn yêu cầu delete, trình quản lý bộ nhớ sẽ gỡ bỏ đánh dấu. Lúc này nếu tiếp tục sử dụng, chương trình của bạn có thể bị lỗi truy cập vùng nhớ không được phép và bị kết thúc.
Tất cả các thao tác xin cấp phát và giải phóng này đều làm việc trên một vùng nhớ gọi là HEAP. Ta hiểu đơn giản heap là vùng nhớ còn lại sau khi đã trừ đi các phần khác của chương trình như code, dữ liệu tĩnh, stack…Việc cấp phát/sử dụng/giải phóng một vùng nhớ luôn phải làm cẩn thận vì:
Có nhiều bạn còn đi học vẫn thắc mắc không biết khi đi làm thì thế nào, vậy để tôi kể cho các bạn nghe về một ngày của tôi nhé .
Như đã từng kể trước đây, tôi hiện đang làm trong một nhóm phát triển phần mềm về quản lý vận tải, một mảng trong logistics. Bạn tưởng tượng đang làm chủ một công ty có 20 xe container, 40 tài xế, chuyên chở hàng hóa theo hợp đồng cho các siêu thị, các công ty bán lẻ, cửa hàng trực tuyến, công ty xây dựng… Bạn muốn quản lý các đơn hàng, hợp đồng, muốn biết chính xác xe nào đang ở đâu, trạng thái hàng hóa thế nào. Bạn cũng muốn cho phép khách hàng biết được chính xác từng món đã đi tới đâu, khi nào có thể nhận được… Vậy là bạn đang cần đến một phần mềm như chúng tôi cung cấp. Chúng tôi có các ứng dụng cho trung tâm điều hành, web app, các ứng dụng trên iOS và Android cho tài xế, khách hàng, thậm chí có cả ứng dụng tích hợp trên các xe tải.
Như trong những bài viết trước, ta đã thấy trừu tượng là khái niệm mà chúng ta luôn cố gắng hiện thực khi xây dựng phần mềm.
Nói một cách đơn giản, trừu tượng cho phép ta làm việc với các thành phần khác mà không cần quan tâm chúng được xây dựng như thế nào, không cần biết bên trong một lớp người ta viết gì và chúng ta không cần phải quan tâm đằng sau chúng có những thành phần nào để chạy.
Trong OOP, với bài toán quản lý sinh viên, ta tạo ra một lớp cha StudentStore, trong đó có 2 phương thức Find and Save, dùng để tìm và lưu trữ thông tin về các sinh viên.Trong phiên bản đầu tiên, Find và Save sẽ đọc và lưu lại thông tin vào các file trên đĩa. Nhưng đến khi bạn học sang phần Sql Server, bạn muốn lưu trữ vào cơ sở dữ liệu thay cho file, vì tất nhiên làm việc với dữ liệu trên file sẽ cực nhọc và kém hiệu quả hơn nhiều. Lúc đó bạn sẽ làm gì?
Con trỏ chưa bao giờ là dễ dàng với người học, vì sự trừu tượng của nó, và vì có nhiều khái niệm liên quan đến bộ nhớ, địa chỉ… vốn xa lạ với người mới. Lời khuyên trước tiên là bạn hãy đọc qua bài này: https://daohainam.com/2021/08/13/cau-chuyen-ve-con-tro-pointer/
Sau khi đọc xong, ta sẽ điểm thêm vài điều có thể bạn chưa biết:
Trong ngôn ngữ máy không có khái niệm con trỏ:
Đúng vậy, con trỏ là một khái niệm của ngôn ngữ bậc cao. Trong ngôn ngữ máy hoặc assembly, bạn chỉ có khái niệm địa chỉ, vì đối với nó, địa chỉ cũng chỉ là một số nguyên nên chẳng có lý do gì lại phải có thêm một kiểu dữ liệu mới.Trong các ngôn ngữ bậc cao, người ta cần con trỏ để giúp xác định “kiểu của vùng nhớ mà con trỏ trỏ đến”.
Những bạn nào muốn vừa học thuật toán vừa học tiếng Anh chuyên ngành có thể bắt đầu với cuốn này. Các bạn đừng sợ không đọc được, chúng ta nói tiếng Việt nên chẳng ai sinh ra mà đã đọc được cả.Nếu muốn bắt đầu học tiếng Anh chuyên ngành, các bạn nên đặt ra một mục tiêu, như đọc hết toàn bộ sau 2 tháng, từ đó hãy lập mục tiêu một ngày đọc bao nhiêu trang, đọc hết không có nghĩa là bạn hiểu hết những gì nó viết, nếu thấy khó quá thì bạn có thể tham khảo thêm một quyển sách tiếng Việt về cùng nội dung. Điều này cũng tương tự như khi bạn đọc một cuốn sách chuyên ngành bằng tiếng Việt: Bạn đọc được hết nhưng không chắc sẽ làm được tất cả những gì viết trong đó.
Sau một thời gian chinh chiến trên khắp các nẻo đường Facebook, tôi chợt phát hiện ra rằng rất nhiều bạn đang gặp trục trặc khi cài đặt SQL để thực hành. Vậy nên trong bài này tôi sẽ nói qua một số lỗi và cách khắc phục. Bài viết này sẽ trình bày dưới dạng hỏi đáp.
1.Nên chọn phiên bản SQL Server nào?
Trừ khi bạn có một yêu cầu nhất định, còn không thì cứ tải về phiên bản mới nhất mà dùng. Phiên bản hiện tại là 2019.
2. Có thể dùng SQL Server express hay Developer để học không?
Tất nhiên là được! Từ góc độ lập trình cơ bản, cả 2 phiên bản đều đáp ứng được yêu cầu của bạn.
Mình nhận được rất nhiều câu hỏi như trên? Nên muốn viết bài này để chia sẻ với mọi người.
Tôi là ai
Tôi là một người vô cùng đam mê lập trình, đam mê từ khi mới học cho đến tận bây giờ, thật sự đó là một điều may mắn, vì nhờ niềm đam mê đó mà tôi có thể đọc sách về máy tính, viết code, chạy thử, rồi nhìn thành quả thâu đêm suốt sáng mà không chán.Tôi biết có nhiều người không có may mắn này nên khi học họ cảm thấy rất chán, học trong sự hứng thú chắc chắn sung sướng hơn học trong sự chán nản rồi!Nhờ niềm đam mê này mà tôi đã đọc vô số sách, blog, mã nguồn, đọc cả mã dịch ngược, rồi cũng bắt tay vào làm, cài đặt, có khi đúng, có khi sai, rồi lại nghiền ngẫm vì sao làm thế này mà không thế kia… Tại sao mình hiểu như vậy, nhưng người ta nói thế này, vậy mình sai chỗ nào?
Đa hình là tính chất quan trọng nhưng khó hiểu nhất của OOP – nắm bắt được tính chất này, bạn sẽ dễ dàng hiểu được tất cả những gì còn lại, kể cả tính trừu tượng sau này. Trong bài này tôi sẽ giải thích nó theo cách đơn giản nhất, sau đó trong phần 2 ta sẽ đào sâu vào, xem những gì thực sự xảy ra ở bên dưới.
Giải thích đơn giản thì đa hình cho phép tự động gọi một phương thức dựa trên các tham số truyền vào (1) hoặc kiểu thực sự của đối tượng bạn đang có (2). (1) Nếu bạn có 2 phương thức:
function Add(x, y : Integer) : Integer;
begin
Add := x + y
end;
function Add(s, t : String) : String;
begin
Add := Concat(s, t)
end;
Có lẽ bạn không lạ gì hàm main, hàm đầu tiên bạn viết khi học lập trình C, ngay cả khi chuyển sang một ngôn ngữ khác, nhất là các ngôn ngữ thừa kế từ C như C++, Java và C#, bạn cũng sẽ thấy một hàm tương tự. Đặc trưng của main là nó sẽ nhận vào các tham số (các tham số này được truyền cho chương trình đang chạy từ trên dòng lệnh) và trả về dữ liệu kiểu int hoặc void.
Khi gọi một hàm (sqrt, rand, malloc…), bạn sẽ nhận được kết quả trả về của hàm đó, vậy giá trị trả về của hàm main sẽ trả về cho ai? Và để làm gì? Vì khi main kết thúc cũng đồng nghĩa với chương trình kết thúc, nên bên trong chương trình bạn không có cách nào lấy giá trị đó (trừ khi bạn cố ý gọi main), mà giá trị này sẽ trả về cho hệ điều hành, hệ điều hành sẽ lưu lại và cho phép chương trình kế tiếp thực thi có thể đọc được. Nhờ khả năng chuyển kết quả thực thi của một chương trình cho một chương trình khác mà ta có thể viết được các chuỗi lệnh (hay các batch scripts, bash scripts…).