Tag: dart

  • How to Learn any Programming Language

    How to Learn any Programming Language

    1. Learn language basics

    • Variable Types
    • Operators
    • Basic input and output
    • Print something on STDOUT
    • Basic program structure

    2. Learning out basic data structures / containers

    • Dictionary
    • Set
    • List/Array

    3. Learn basic file I/O

    • How to read a file in
    • How to write a file out
    • Crazy mileage ( simple ­> complicated )
    • This goes from simple reading of a text file to… DATABASE. Postgres, or mongodb (extremely complicated)

    4. Learn networking basics

    • Making HTTP requests with your language

      • Learn how to GET, POST, DELETE, etc. requests.
      • How to set your requests properly, how to handle responses and status codes
    • Learn some basic socket programming your language.
    • Overall, there are LIBRARIES out there to help you to do this.

    5. How to build your project and language

    • E.g. C++ you’ll have to learn how to build static libraries, shared libraries, how to link your applications properly.
    • E.g. Python developer. You’ll have to figure out how to separate out your modules well.
      • Execution vs import style
      • How does this is all fit into your project?

    6. Learn OO / functional programming paradigm tools

    • E.g. for OO you need to learn how to use classes, how to use inheritance, how to use polymorphism, etc.
    • E.g. functional. You’ll have to learn how your language uses blocks or lambdas, how function pointers or callbacks work.

    7. EXTRA Goodies in any language

    • Bag of trickies
    • You can come back to here and learn the subtleties and nice stuff of any language
    • E.g. Ruby has a lot of cool methods on enumerable types.
  • Các câu hỏi phỏng vấn Flutter

    Các câu hỏi phỏng vấn Flutter

    Các câu hỏi phỏng vấn Flutter

    Flutter ngày càng được nhiều người quan tâm nhờ khả năng phát triển app đa nền tảng. Dưới đây, chúng tôi giới thiệu Các câu hỏi phỏng vấn Flutter để bạn đọc tham khảo. Bạn có thể xem thêm KINH NGHIỆM PHỎNG VẤN FLUTTER.

    Flutter là gì?

    Flutter là một bộ công cụ giao diện người dùng để tạo các ứng dụng di động nhanh, đẹp, được biên dịch nguyên bản với một ngôn ngữ lập trình và một cơ sở code duy nhất. Nó là một framework phát triển code nguồn mở được phát triển bởi Google. Nói chung, Flutter không phải là một ngôn ngữ; nó là một SDK. Ứng dụng Flutter sử dụng ngôn ngữ lập trình Dart để tạo ứng dụng. Phiên bản alpha đầu tiên của Flutter được phát hành vào tháng 5 năm 2017.

    Flutter chủ yếu được tối ưu hóa cho các ứng dụng di động 2D có thể chạy trên cả nền tảng Android và iOS. Chúng tôi cũng có thể sử dụng nó để tạo các ứng dụng đầy đủ tính năng, bao gồm máy ảnh, bộ nhớ, vị trí địa lý, mạng, SDK của bên thứ ba, v.v.

    Mời bạn xem giới thiệu chi tiết hơn tại bài Flutter là gì?

    Dart là gì?

    Dart là một ngôn ngữ lập trình hướng đối tượng, có mục đích chung với cú pháp kiểu C. Nó là code nguồn mở và được phát triển bởi Google vào năm 2011. Mục đích của lập trình Dart là tạo giao diện người dùng frontend cho web và ứng dụng di động. Nó là một ngôn ngữ quan trọng để tạo ứng dụng Flutter. Ngôn ngữ Dart có thể được biên dịch cả AOT (Ahead-of-Time) và JIT (Just-in-Time.

    Học Flutter có cần học Dart không?

    Có, việc học ngôn ngữ Dart để xây dựng ứng dụng Flutter là rất cần thiết. Vì Flutter chỉ là một bộ khung (framework) sử dụng ngôn ngữ Dart để tạo nên ứng dụng.

    Flutter có miễn phí không?

    Có. Flutter hoàn toàn miễn phí và mã nguồn mở.

    Widget trong Flutter là gì?

    Một ứng dụng Flutter luôn được coi là một cây các material. Bất cứ khi nào bạn định viết code để xây dựng bất cứ thứ gì trong Flutter, nó sẽ nằm bên trong một widget. Các widget mô tả chế độ xem ứng dụng của bạn trông như thế nào với cấu hình và trạng thái hiện tại của chúng. Khi bạn thực hiện bất kỳ thay đổi nào trong code, widget con sẽ xây dựng lại mô tả của nó bằng cách tính toán sự khác biệt của widget con hiện tại và trước đó để xác định những thay đổi tối thiểu đối với việc hiển thị trong giao diện người dùng của ứng dụng.

    Các widget được lồng vào nhau để xây dựng ứng dụng. Nó có nghĩa là thư mục gốc của ứng dụng của bạn tự nó là một widget và tất cả các cách nhìn xuống cũng là một widget. Ví dụ: một widget có thể hiển thị một cái gì đó, có thể xác định thiết kế, có thể xử lý tương tác, v.v.

    Sự khác nhau giữa Stateful Widget và Stateless Widget?

    Một widget Stateful có thông tin state. Nó được gọi là động vì nó có thể thay đổi dữ liệu bên trong trong suốt thời gian tồn tại của widget. Một widget cho phép chúng ta làm mới màn hình được gọi là Stateful widget. widget con này không có phương thức build(). Nó có phương thức createState(), trả về một lớp mở rộng Lớp state Flutters. Các ví dụ về widget Stateful là Checkbox, Radio, Slider, InkWell, Form và TextField.

    widget không trạng thái(Stateless) không có bất kỳ thông tin trạng thái nào. Nó vẫn tĩnh trong suốt vòng đời của nó. Ví dụ về widget không trạng thái là Văn bản, Hàng, Cột, Vùng chứa, v.v. Nếu màn hình hoặc widget chứa nội dung tĩnh, nó phải là widget Stateless, nhưng nếu bạn muốn thay đổi nội dung, nó cần phải là widget Stateful.

    Các trình soạn thảo tốt nhất để phát triển Flutter là gì?

    Các công cụ phát triển Flutter cho phép phát triển Flutter nhanh hơn và do đó thúc đẩy quy trình làm việc của nhà phát triển. Flutter IDE và các công cụ cần một số plugin để phát triển các ứng dụng di động. Các plugin giúp chúng tôi biên dịch, phân tích code và phát triển Flutter. IDE phổ biến cho sự phát triển của Flutter như sau:

    • Android Studio
    • Visual Studio
    • IntelliJ IDEA
    • Xcode

    Tệp pubspec.yaml là gì?

    Đó là tệp cấu hình của dự án sẽ sử dụng rất nhiều trong quá trình làm việc với dự án Flutter. Nó cho phép bạn cách ứng dụng của bạn hoạt động. Nó cũng cho phép chúng tôi thiết lập các ràng buộc cho ứng dụng. Tệp này chứa:

    • Cài đặt chung của dự án như tên, mô tả và phiên bản của dự án.
    • Sự phụ thuộc của dự án.
    • Nội dung dự án (ví dụ: hình ảnh, âm thanh, v.v.).

    Các gói và plugin trong Flutter là gì?

    Gói là một nhóm các loại lớp, giao diện và gói con tương tự nhau. Các gói và plugin giúp chúng tôi xây dựng ứng dụng mà không cần phải phát triển mọi thứ từ các gói. Trong Flutter, nó cho phép bạn nhập các widget hoặc chức năng mới vào ứng dụng. Các gói và plugin có một sự khác biệt rất nhỏ. Nói chung, các gói là các thành phần mới hoặc code được viết bằng ngôn ngữ Dart, trong khi các plugin cho phép nhiều chức năng hơn trên thiết bị bằng cách sử dụng code gốc. Trong DartPub, cả gói và plugin đều được gọi là gói.

    Ưu điểm của Flutter là gì?

    Các câu hỏi phỏng vấn Flutter 1

    Các ưu điểm phổ biến của Flutter framework như sau:

    • Phát triển đa nền tảng: Tính năng này cho phép Flutter viết code một lần, duy trì và có thể chạy trên các nền tảng khác nhau. Nó tiết kiệm thời gian, công sức và tiền bạc của các nhà phát triển.
    • Phát triển nhanh hơn: Hiệu suất của ứng dụng Flutter rất nhanh. Flutter biên dịch ứng dụng bằng cách sử dụng thư viện nhánh C / C ++ giúp ứng dụng gần với code máy hơn và mang lại cho ứng dụng hiệu suất gốc tốt hơn.
    • Cộng đồng tốt: Flutter có hỗ trợ cộng đồng tốt, nơi các nhà phát triển có thể hỏi các vấn đề và nhận được kết quả nhanh chóng.
    • Tải lại trực tiếp và nóng: Nó làm cho quá trình phát triển ứng dụng cực kỳ nhanh chóng. Tính năng này cho phép chúng tôi thay đổi hoặc cập nhật code được phản ánh ngay sau khi các thay đổi được thực hiện.
    • code tối thiểu: Ứng dụng Flutter được phát triển bởi ngôn ngữ lập trình Dart, sử dụng biên dịch JIT và AOT để cải thiện thời gian khởi động tổng thể, hoạt động và tăng tốc hiệu suất. JIT nâng cao hệ thống phát triển và làm mới giao diện người dùng mà không cần nỗ lực thêm vào việc xây dựng hệ thống mới.
    • Tập trung vào giao diện người dùng: Nó có giao diện người dùng tuyệt vời vì nó sử dụng widget tập trung vào thiết kế, các công cụ phát triển cao, API nâng cao và nhiều tính năng khác.
    • Tài liệu: Flutter có hỗ trợ tài liệu rất tốt. Nó được tổ chức và nhiều thông tin hơn. Chúng ta có thể lấy mọi thứ mà chúng ta muốn viết ở một nơi.

    Bạn có thể cài đặt Flutter bằng cách nào?

    Để cài đặt và chạy Flutter trên hệ thống Windows, MacOS trước tiên bạn cần đáp ứng các yêu cầu này đối với môi trường phát triển của mình.

    Hệ điều hành Windows 7 trở lên (Tôi là Windows 10. Bạn cũng có thể sử dụng Mac hoặc Linux OS.).
    Dung lượng đĩa 400 MB (Nó không bao gồm không gian đĩa cho IDE / công cụ).
    Công cụ 1. Windows PowerShell2. Git dành cho Windows 2.x (Tại đây, Sử dụng Git từ tùy chọn Dấu nhắc Lệnh của Windows).
    SDK Flutter SDK dành cho Windows
    IDE Android Studio (Chính thức)

    Mời bạn tham khảo thêm Cài đặt Flutter với Visual Studio Code

    So sánh Flutter và React Native?

    • Flutter và React Native đều được sử dụng để phát triển ứng dụng kết hợp gốc từ một cơ sở code duy nhất. Các ứng dụng này có thể chạy trên nền tảng iOS và Android.
    • React Native do Facebook phát triển, trong khi framework công tác Flutter lần đầu tiên được giới thiệu bởi Google. Vì vậy, cả hai framework đều có tính năng và tính cộng đồng rất tốt.
    • Flutter sử dụng ngôn ngữ Dart để tạo ứng dụng, trong khi React Native sử dụng JavaScript để xây dựng ứng dụng.
    • Theo quan điểm của nhà phát triển, rất khó để lựa chọn trong số chúng. Do đó, rất khó để chọn ra người chiến thắng giữa Flutter và React Native.

    Tại sao build app Flutter lần đầu tiên mất nhiều thời gian?

    Khi bạn dựng ứng dụng Flutter lần đầu tiên, sẽ mất nhiều thời gian hơn. Đó là do Flutter đã xây dựng tệp APK hoặc IPA dành riêng cho thiết bị. Do đó, Gradle và Xcode được sử dụng để xây dựng tệp, mất nhiều thời gian.

    Tại sao thư mục Android và iOS lại nằm trong dự án Flutter?

    • Android: Thư mục này chứa một dự án Android hoàn chỉnh. Nó được sử dụng khi bạn tạo ứng dụng Flutter cho Android. Khi code Flutter được biên dịch thành code gốc, nó sẽ được đưa vào dự án Android này, do đó kết quả là một ứng dụng Android gốc. Ví dụ : Khi bạn đang sử dụng trình giả lập Android, dự án Android này được sử dụng để xây dựng ứng dụng Android, được triển khai thêm cho Thiết bị ảo Android.
    • iOS: Thư mục này chứa một dự án Mac hoàn chỉnh. Nó được sử dụng khi bạn xây dựng ứng dụng Flutter cho iOS. Nó tương tự như thư mục Android, được sử dụng khi phát triển ứng dụng cho Android. Khi code Flutter được biên dịch thành code gốc, nó sẽ được đưa vào dự án iOS này, để kết quả là một ứng dụng iOS gốc. Chỉ có thể xây dựng ứng dụng Flutter cho iOS khi bạn đang làm việc trên macOS và Xcode IDE.

    Tween Animation là gì?

    Đây là hình thức rút gọn của in-betweening. Trong hoạt ảnh tween, bắt buộc phải xác định điểm đầu và điểm cuối của hoạt ảnh. Nó có nghĩa là hoạt ảnh bắt đầu với giá trị bắt đầu, sau đó đi qua một loạt các giá trị trung gian và cuối cùng đạt đến giá trị kết thúc. Nó cũng cung cấp dòng thời gian và đường cong, xác định thời gian và tốc độ của quá trình chuyển đổi. framework công cụ cung cấp tính toán về cách chuyển đổi từ điểm đầu và điểm cuối.

    Giải thích Hot Reload trong Flutter?

    Tính năng tải lại nóng cho phép bạn nhanh chóng và dễ dàng thực hiện một thử nghiệm trong dự án. Nó giúp xây dựng giao diện người dùng, thêm các tính năng mới, sửa lỗi và phát triển ứng dụng nhanh chóng. Để thực hiện tải lại nóng ứng dụng Flutter, hãy làm theo các bước sau:

    Chạy ứng dụng trong trình chỉnh sửa Flutter hoặc cửa sổ dòng lệnh được hỗ trợ.

    Sửa đổi bất kỳ tệp Dart nào trong dự án.

    Nếu bạn sử dụng IDE hỗ trợ Flutter, hãy chọn Lưu tất cả hoặc nhấp vào nút Tải lại nóng trên thanh công cụ. Ngay lập tức, bạn có thể xem kết quả trong trình mô phỏng hoặc thiết bị thực của mình.

    Kể tên một số ứng dụng phổ biến sử dụng Flutter?

    Ngày nay, nhiều tổ chức sử dụng Flutter để xây dựng ứng dụng. Một số ứng dụng phổ biến nhất được xây dựng trên Flutter như sau:

    • Google Ads
    • Reflectly
    • Alibaba
    • Birch Finance
    • Coach Yourself
    • Tencent
    • Watermaniac

    Kể tên gói cơ sở dữ liệu phổ biến được sử dụng trong Flutter?

    Các gói cơ sở dữ liệu phổ biến và được sử dụng nhiều nhất được sử dụng trong Flutter như sau:

    • Cơ sở dữ liệu sqflite: Nó cho phép truy cập và thao tác với cơ sở dữ liệu SQLite.
    • Cơ sở dữ liệu Firebase: Nó sẽ cho phép bạn truy cập và thao tác với cơ sở dữ liệu đám mây.

    Animation nào cho phép bạn thể hiện hành vi trong thế giới thực?

    Animation dựa trên Vật lý cho phép bạn thể hiện hành vi trong thế giới thực trong Flutter.

    Sự khác biệt giữa Khởi động lại Nóng và Tải lại Nóng là gì?

    Sau đây là những điểm khác biệt cơ bản giữa Khởi động lại nóng và Tải lại nóng:

    Tải lại nóng (Hot reload) Khởi động lại nóng
    Nó hoạt động với một phím r nhỏ trên thiết bị đầu cuối hoặc dấu nhắc lệnh. Nó chủ yếu hoạt động bằng tay
    Tính năng tải lại nóng cho phép chúng tôi nhanh chóng biên dịch mã mới được thêm vào tệp và gửi chúng đến Máy ảo Dart (DVM). Sau khi hoàn tất cập nhật DVM, nó sẽ cập nhật ngay giao diện người dùng của ứng dụng. Nó cho phép các nhà phát triển có được một ứng dụng được biên dịch đầy đủ vì nó phá hủy các giá trị Trạng thái đã có và đặt chúng thành mặc định. Trên mỗi lần Khởi động lại nóng, cây widget ứng dụng của chúng ta được xây dựng lại hoàn toàn với code đã nhập mới.
    Nó giúp xây dựng giao diện người dùng, thêm các tính năng mới, sửa lỗi và phát triển ứng dụng nhanh chóng. Mất nhiều thời gian hơn Tải lại nóng để biên dịch và cập nhật ứng dụng.

    22. Trong đoạn mã dưới đây, hãy chuyển makeMangoShake() thành getter có tên là mangoshake bằng cách sử dụng cú pháp viết tắt “fat arrow”: 

    class Recipe {  
      int mango;  
      int milk;  
      int sugar;  
      Recipe(this.mango, this.milk, this.sugar);   
      int makeMangoShake() {  
        return mango+milk+sugar;  
      }  
    }

    Fat Arrow (=>) được sử dụng khi phương thức chứa một dòng code. Chúng ta có thể sử dụng nó bằng cú pháp sau:

    methodName(parameters) => statement;

    Cần lưu ý rằng chúng ta không thể sử dụng từ khóa return có mũi tên béo (=>). Sau khi chuyển makeMangoShake() thành một mũi tên, nó sẽ giống như đoạn mã dưới đây:

    int get mangoshake => mango + milk + sugar;

    Sự khác biệt giữa các hàm “main()” và “runApp()” trong Flutter là gì?

    Chúng ta có thể phân biệt các hàm chính và hàm runApp trong Flutter như sau:

    • Hàm main() chịu trách nhiệm khởi động chương trình. Nếu không có hàm main(), chúng ta không thể viết bất kỳ chương trình nào trên Flutter.
    • Hàm runApp() có nhiệm vụ trả về các widget được gắn vào màn hình dưới dạng gốc của cây widget và sẽ được hiển thị trên màn hình.

    Khi nào bạn nên sử dụng mainAxisAlignment và crossAxisAlignment?

    Chúng ta có thể sử dụng crossAxisAlignment và mainAxisAlignment để kiểm soát cách các widget hàng và cột sắp xếp các con của nó dựa trên sự lựa chọn của chúng ta.

    Trục chéo của hàng sẽ chạy theo chiều dọc và trục chính sẽ chạy theo chiều ngang. Xem hình ảnh minh họa bên dưới để hiểu rõ hơn.

    Các câu hỏi phỏng vấn Flutter 2

    Trục chéo của cột sẽ chạy theo chiều ngang và trục chính sẽ chạy theo chiều dọc. Hình ảnh minh họa dưới đây giải thích rõ ràng hơn.

    Các câu hỏi phỏng vấn Flutter 3

    Sự khác biệt giữa SizedBox và Container là gì?

    • Container trong Flutter là một widget có thể chứa nhiều widget và quản lý chúng một cách hiệu quả thông qua chiều rộng, chiều cao, phần đệm, màu nền, v.v. Nếu chúng ta có một widget cần một số kiểu nền có thể là hạn chế về màu sắc, hình dạng hoặc kích thước , chúng tôi có thể bọc nó trong một widget vùng chứa.
    • SizedBox trong Flutter là một hộp đi kèm với kích thước được chỉ định. Không giống như Container, nó không cho phép chúng ta thiết lập màu sắc hoặc trang trí cho widget. Chúng tôi chỉ có thể sử dụng nó để xác định kích thước của tiện ích được truyền khi còn nhỏ. Nó có nghĩa là nó buộc widget con của nó phải có chiều rộng hoặc chiều cao cụ thể.

    Stream trong Flutter là gì?

    Luồng là một chuỗi các sự kiện không đồng bộ. Nó cung cấp một chuỗi dữ liệu không đồng bộ. Nó cũng giống như một đường ống mà chúng ta đặt một số giá trị vào một đầu và nếu chúng ta có một người nghe ở đầu kia, nó sẽ nhận được giá trị đó. Chúng tôi có thể giữ nhiều người nghe trong một luồng và tất cả những người nghe đó sẽ nhận được cùng một giá trị khi được đưa vào đường dẫn.

    Chúng tôi có thể xử lý luồng bằng cách sử dụng hàm chờ hoặc nghe từ API luồng. Nó có một cách để phản hồi các lỗi. Chúng ta có thể tạo luồng theo nhiều cách, nhưng chúng có thể được sử dụng theo cách giống nhau. Xem ví dụ dưới đây:

    Future<int> sumStream(Stream<int> stream) async {  
        var sum = 0;  
        await for (var value in stream) {  
          sum = sum + value;  
        }  
        return sum;  
      }

    Các loại Stream trong Flutter?

    Stream có thể có hai loại, đó là:

    • Single subscription streams (Các luồng đăng ký đơn lẻ) Đây là loại luồng phổ biến nhất chứa một chuỗi các sự kiện, là các phần của một tổng thể lớn hơn. Nó sẽ cung cấp các sự kiện theo đúng thứ tự và không bỏ sót bất kỳ sự kiện nào. Nếu thiếu bất kỳ sự kiện nào, thì phần còn lại của luồng sẽ không có ý nghĩa gì. Luồng này chủ yếu được sử dụng để đọc tệp hoặc nhận yêu cầu web. Nó sẽ nghe một lần, và nếu nó đang nghe lại, điều đó có nghĩa là đã bỏ lỡ một sự kiện ban đầu. Khi nó bắt đầu nghe, dữ liệu sẽ được tìm nạp và cung cấp theo từng phần.
    • Broadcast streams (Các luồng phát sóng) Đây là một loại luồng được sử dụng cho các thư riêng lẻ có thể được xử lý từng thư một mà không cần biết về các sự kiện trước đó. Nó có thể có nhiều người nghe để nghe đồng thời và chúng ta có thể nghe lại sau khi hủy đăng ký trước đó. Sự kiện chuột này trong trình duyệt là một loại luồng này.

    Tại sao phương thức build() trên State mà không phải StatefulWidgets?

    Lý do chính đằng sau điều này là StatefulWidget sử dụng một lớp State riêng biệt mà không xây dựng một phương thức bên trong phần thân của nó. Nó có nghĩa là tất cả các trường bên trong Widget là bất biến và bao gồm tất cả các lớp con của nó.

    Mặt khác, StatelessWidget có các phương thức xây dựng và liên kết bên trong cơ thể của nó. Đó là do bản chất của StatelessWidget, được hiển thị hoàn toàn trên màn hình bằng cách sử dụng thông tin được cung cấp. Nó cũng không cho phép bất kỳ thay đổi nào trong tương lai đối với thông tin State của nó.

    StatefulWidget cho phép chúng tôi thay đổi thông tin State trong quá trình sử dụng ứng dụng. Do đó, nó không phù hợp để lưu trữ trong một phương thức xây dựng để thỏa mãn các điều kiện lớp Widget nơi tất cả các trường là bất biến. Đây là lý do chính để giới thiệu State . Ở đây, chúng ta chỉ cần ghi đè hàm createState () để đính kèm Trạng thái đã xác định với StatefulWidget, và sau đó tất cả các thay đổi dự kiến ​​sẽ xảy ra trong một lớp riêng biệt.

    Các chế độ build khác nhau trong Flutter là gì?

    Công cụ Flutter hỗ trợ ba chế độ trong khi biên dịch ứng dụng. Các chế độ biên dịch này có thể được chọn tùy thuộc vào vị trí của chúng ta trong chu trình phát triển. Tên của các chế độ là:

    • Debug
    • Profile
    • Release

    Tại sao chúng ta cần mixin?

    Dart không hỗ trợ nhiều thừa kế. Vì vậy, để triển khai nhiều kế thừa trong Flutter / Dart, chúng ta cần các mixin. Mixins cung cấp một cách để viết code của lớp có thể sử dụng lại trong nhiều phân cấp lớp.

    Tại sao chúng ta sử dụngTicker trong Flutter?

    Ticker trong Flutter là tốc độ làm mới hình ảnh động của chúng ta. Nó là một lớp gửi tín hiệu ở một khoảng thời gian đều đặn, tức là khoảng 60 lần mỗi giây. Chúng ta có thể hiểu điều đó bằng đồng hồ của mình, đồng hồ này hoạt động đều đặn. Tại mỗi lần đánh dấu, Ticker cung cấp một phương thức gọi lại với khoảng thời gian kể từ lần đánh dấu đầu tiên vào mỗi giây, sau khi nó được bắt đầu. Ngay cả khi các code bắt đầu vào các thời điểm khác nhau, nó luôn được đồng bộ hóa tự động.

    Key trong Flutter là gì?

    • Các Key trong Flutter được sử dụng làm code định danh cho Widget, Elements và SemanticsNodes. Chúng ta có thể sử dụng nó khi một widget mới cố gắng cập nhật một phần tử hiện có; sau đó, khóa của nó phải giống với khóa widget hiện tại được liên kết với phần tử.
    • Các khóa không được khác nhau giữa các Phần tử trong cùng một gốc.
    • Các lớp con của Key phải là GlobalKey hoặc LocalKey.
    • Key rất hữu ích khi chúng ta cố gắng thao tác (chẳng hạn như thêm, xóa hoặc sắp xếp lại thứ tự) một tập hợp các widget cùng loại có trạng thái nào đó.

    Làm thế nào bạn sẽ thực thi code chỉ trong chế độ gỡ lỗi?

    Để thực thi code chỉ trong chế độ gỡ lỗi, trước tiên chúng ta cần nhập nền tảng phi tiêu như bên dưới:

    import 'package:flutter/foundation.dart' as Foundation;

    Tiếp theo, chúng ta cần sử dụng kReleaseMode như bên dưới:

    if (Foundation.kReleaseMode){ // is Release Mode ??
    print('release mode');
    } else {
    print('debug mode');
    }

    Chế độ profile là gì, và bạn sử dụng nó khi nào?

    Chế độ hồ sơ(Profile) được sử dụng để đo hiệu suất của các ứng dụng của chúng ta. Trong chế độ này, một số khả năng gỡ lỗi được duy trì để xác định hiệu suất ứng dụng của bạn. Chế độ này bị tắt trên trình giả lập và trình mô phỏng vì chúng không đại diện cho hiệu suất thực.

    Chúng ta có thể sử dụng lệnh dưới đây để biên dịch chế độ cấu hình:

    Chế độ release là gì và bạn sử dụng nó khi nào?

    • Chế độ phát hành (release) cho phép chúng ta tối ưu hóa code và tạo chúng mà không có bất kỳ dữ liệu gỡ lỗi nào ở dạng được tối ưu hóa hoàn toàn. Trong chế độ này, nhiều code của ứng dụng sẽ bị xóa hoặc viết lại hoàn toàn.
    • Chúng ta sử dụng chế độ này khi chúng ta sẵn sàng phát hành ứng dụng. Nó cho phép tối ưu hóa tối đa và kích thước dấu chân tối thiểu của ứng dụng.
    • Chúng ta có thể sử dụng lệnh dưới đây để biên dịch chế độ phát hành:

    flutter run --release

    Sự khác biệt giữa WidgetsApp và MaterialApp là gì?

    Biểu đồ so sánh dưới đây giải thích sự khác biệt cơ bản giữa WidgesApp và MaterialApp:

    WidgetsApp MaterialApp
    WidgetsApp được sử dụng để điều hướng cơ bản. Nó bao gồm nhiều widget nền tảng cùng với thư viện widget mà Flutter sử dụng để tạo giao diện người dùng của ứng dụng của chúng ta. MaterialApp, cùng với thư viện material, là một lớp được xây dựng trên đầu WidgetsApp và thư viện của nó. Nó triển khai thiết kế Material Design cung cấp giao diện thống nhất cho ứng dụng của chúng ta trên bất kỳ nền tảng nào.
    Lớp WidgetsApp là lớp cơ sở cho lớp MaterialApp. Nó cung cấp nhiều công cụ thú vị như Bộ điều hướng hoặc Chủ đề để phát triển ứng dụng.
    Nó bao bọc một số widget cần thiết để xây dựng ứng dụng. Nó bao gồm một số widget cần thiết cho các ứng dụng thiết kế vật liệu xây dựng.

    BuildContext là gì?

    BuildContext trong Flutter là một phần của các widget trong cây Element để mỗi widget có BuildContext của riêng mình. Chúng ta chủ yếu sử dụng nó để tham chiếu đến một widget hoặc chủ đề khác. Ví dụ, nếu chúng ta muốn sử dụng một yếu tố thiết kế material design, thì nó bắt buộc phải tham chiếu nó đến Scaffold. Chúng ta có thể lấy nó bằng phương thức Scaffold.of (context).

    Bạn có thể thực hiện những loại kiểm tra nào trong Flutter?

    Kiểm tra là một hoạt động được sử dụng để xác minh và xác thực ứng dụng, không có lỗi và đáp ứng các yêu cầu của người dùng. Nói chung, chúng ta có thể sử dụng ba loại kiểm tra này trong Flutter:

    • Unit Tests: Nó kiểm tra một chức năng, phương thức hoặc lớp. Mục tiêu của nó là đảm bảo tính đúng đắn của code trong nhiều điều kiện khác nhau. Thử nghiệm này được sử dụng để kiểm tra tính hợp lệ của logic kinh doanh của chúng ta.
    • Widget Tests: Nó kiểm tra một widget duy nhất. Mục tiêu của nó là đảm bảo rằng giao diện người dùng của widget trông và tương tác với các widget khác như mong đợi.
    • Integration Tests: Nó xác thực một ứng dụng hoàn chỉnh hoặc một phần lớn của ứng dụng. Mục tiêu của nó là đảm bảo rằng tất cả các widget và dịch vụ cùng hoạt động như mong đợi.

    Toán tử kiểm tra Null là gì?

    Dart cung cấp một số thông tin hữu ích để xử lý các giá trị null.

    1. Toán tử gán “?? =” chỉ gán giá trị cho một biến khi biến đó đang rỗng (null).

    int a; // Initial value of a is null.  
    a ??= 5;  
    print(a); // It will print 5.

    2. Toán tử “??” được sử dụng để đánh giá và trả về giá trị giữa hai biểu thức. Đầu tiên, nó thực thi và kiểm tra biểu thức bên trái nếu khác rỗng thì trả về giá trị của biểu thức đó; nếu không, nó sẽ thực thi và trả về giá trị của biểu thức bên phải:

    print(3 ?? 5); // It will print 3.  
    print(null ?? 5); // It will print 5.

    Sự khác nhau giữa toán tử “??” và “?”

    Toán tử ??  Toán tử ? 
    Các “??” toán tử được sử dụng để đánh giá và trả về giá trị giữa hai biểu thức.

    Nó có thể được sử dụng như sau:expr1 ?? expr2Toán tử này đầu tiên kiểm tra biểu thức 1 và nếu nó không phải là null, trả về giá trị của nó; nếu không, nó sẽ đánh giá và trả về giá trị của biểu thức 2.

    Các “?” toán tử được sử dụng để đánh giá và trả về giá trị giữa hai biểu thức dựa trên điều kiện đã cho.

    Nó có thể được sử dụng như sau:điều kiện? expr1: expr2Toán tử này đầu tiên kiểm tra điều kiện và nếu nó đúng, nó sẽ đánh giá expr1 và trả về giá trị của nó (nếu điều kiện được khớp). Nếu không, nó sẽ đánh giá và trả về giá trị của expr2.

  • Flutter là gì?

    Flutter là gì?

    Flutter là gì?

    Để trả lời câu hỏi Flutter là gì, những đặc điểm cơ bản của Flutter, chúng tôi xin được trích đăng một phần đồ án tốt nghiệp của bạn Đỗ Thế Hiệp, sinh viên trường ĐH QUẢN LÝ và CÔNG NGHỆ HẢI PHÒNG.

    Flutter là gì?

    Flutter là một bộ SDK đa nền tảng có thể hoạt động trên iOS và Android do Google phát triển được sử dụng để tạo ra các ứng dụng dành cho di động (native app).

    Flutter gồm 2 thành phần quan trọng:

    • Một SDK (Software Development Kit): Một bộ sưu tập các công cụ sẽ giúp bạn phát triển các ứng dụng của mình.
    • Một Framework (UI Library based on widgets): Một tập hợp các thành phần giao diện người dùng (UI) có thể tái sử dụng (button, text inputs, slider, v.v.) giúp bạn có thể cá nhân hóa tùy theo nhu cầu của riêng mình.

    Nói chung, tạo một ứng dụng di động là một công việc rất phức tạp và đầy thử thách. Có rất nhiều framework có sẵn, cung cấp các tính năng tuyệt vời để phát triển các ứng dụng di động. Để phát triển các ứng dụng dành cho thiết bị di động, Android cung cấp một framework gốc dựa trên ngôn ngữ Java và Kotlin, trong khi iOS cung cấp một framework dựa trên ngôn ngữ Objective-C/Swift.

    Vì vậy, chúng ta cần hai ngôn ngữ và framework khác nhau để phát triển ứng dụng cho cả hai hệ điều hành. Ngày nay, để khắc phục sự phức tạp này, có một số framework đã được giới thiệu hỗ trợ cả hệ điều hành cùng với các ứng dụng dành cho máy tính để bàn. Những loại framework này được gọi là công cụ phát triển đa nền tảng [1] .

    Framework phát triển đa nền tảng có khả năng viết một code và có thể triển khai trên nhiều nền tảng khác nhau (Android, iOS và Máy tính để bàn). Nó tiết kiệm rất nhiều thời gian và nỗ lực phát triển của các nhà phát triển.

    Có một số công cụ có sẵn để phát triển đa nền tảng, bao gồm các công cụ dựa trên web. Mỗi framework này có mức độ thành công khác nhau trong ngành công nghiệp di động. Gần đây, một framework công tác mới đã được giới thiệu trong họ phát triển đa nền tảng có tên là Flutter được phát triển từ Google.

    Flutter là một bộ công cụ giao diện người dùng để tạo các ứng dụng nhanh, đẹp, được biên dịch nguyên bản cho thiết bị di động, web và máy tính để bàn với một ngôn ngữ lập trình và cơ sở code duy nhất. Nó là miễn phí và code nguồn mở. Ban đầu nó được phát triển từ Google và bây giờ được quản lý theo tiêu chuẩn ECMA. Ứng dụng Flutter sử dụng ngôn ngữ lập trình Dart để tạo ứng dụng.

    Flutter chủ yếu được tối ưu hóa cho các ứng dụng di động 2D có thể chạy trên cả nền tảng Android và iOS. Chúng ta cũng có thể sử dụng nó để xây dựng các ứng dụng đầy đủ tính năng, bao gồm máy ảnh, bộ nhớ, vị trí địa lý, mạng, SDK của bên thứ ba, v.v.

    Điều làm Flutter trở lên khác biệt?

    Flutter khác với các framework khác vì nó không sử dụng WebView cũng như các widget OEM (Original Equipment Manufacturer) đi kèm với thiết bị. Thay vào đó, nó sử dụng công cụ kết xuất hiệu suất cao của riêng mình để vẽ các widget. Nó cũng triển khai hầu hết các hệ thống của nó như hoạt ảnh, cử chỉ và widget bằng ngôn ngữ lập trình Dart cho phép các nhà phát triển đọc, thay đổi, thay thế hoặc loại bỏ mọi thứ một cách dễ dàng. Nó cung cấp khả năng kiểm soát tuyệt vời cho các nhà phát triển đối với hệ thống.

    Các tính năng của Flutter

    Flutter cung cấp các phương pháp dễ dàng và đơn giản để bắt đầu xây dựng các ứng dụng dành cho thiết bị di động và máy tính để bàn đẹp mắt với một bộ thiết kế material design và widget phong phú. Ở đây, chúng ta sẽ thảo luận về các tính năng chính của nó để phát triển framework di động.

     

    Các tính năng của Flutter
    Các tính năng của Flutter
    • Code nguồn mở(Open-Source:): Flutter là một framework code nguồn mở và miễn phí để phát triển các ứng dụng di động.
    • Đa nền tảng(Cross-platform): Tính năng này cho phép Flutter viết code một lần, duy trì và có thể chạy trên các nền tảng khác nhau. Nó tiết kiệm thời gian, công sức và tiền bạc của các nhà phát triển.
    • Tải lại nóng (Hot Reload): Bất cứ khi nào nhà phát triển thực hiện thay đổi trong code, thì những thay đổi này có thể được nhìn thấy ngay lập tức với Tải lại nóng. Nó có nghĩa là những thay đổi hiển thị ngay lập tức trong chính ứng dụng. Đây là một tính năng rất tiện dụng, cho phép nhà phát triển sửa các lỗi ngay lập tức.
    • Các tính năng và SDK gốc có thể truy cập (Accessible Native Features and SDKs): Tính năng này cho phép quá trình phát triển ứng dụng dễ dàng và thú vị thông qua code gốc của Flutter, tích hợp bên thứ ba và các API nền tảng. Do đó, chúng tôi có thể dễ dàng truy cập SDK trên cả hai nền tảng.
    • Code tối thiểu (Minimal code): Ứng dụng Flutter được phát triển bởi ngôn ngữ lập trình Dart, sử dụng biên dịch JIT và AOT để cải thiện thời gian khởi động tổng thể, hoạt động và tăng tốc hiệu suất. JIT nâng cao hệ thống phát triển và làm mới giao diện người dùng mà không cần nỗ lực thêm vào việc xây dựng hệ thống mới.
    • Widget: framework công tác Flutter cung cấp các widget có khả năng phát triển các thiết kế cụ thể có thể tùy chỉnh. Quan trọng nhất, Flutter có hai bộ widget: Material Design và các widget Cupertino giúp mang lại trải nghiệm không có trục trặc trên tất cả các nền tảng.

    Kiến trúc của Flutter

    Kiến trúc Flutter

    Trong phần này, chúng ta sẽ thảo luận về kiến trúc của Flutter framework. Kiến trúc Flutter chủ yếu bao gồm bốn thành phần.

    • Động cơ Flutter (Flutter Engine)
    • Thư viện nền tảng (Foundation Library)
    • Vật dụng (Widgets)
    • Thiết kế các widget cụ thể (Design Specific Widgets)

    Flutter Engine

    Nó là một cổng để giúp chạy các ứng dụng di động chất lượng cao và cơ bản dựa trên ngôn ngữ C ++. Nó triển khai các thư viện lõi Flutter bao gồm animation và đồ họa, tệp và mạng I / O, kiến trúc plugin, hỗ trợ trợ năng và thời gian chạy dart để phát triển, biên dịch và chạy các ứng dụng Flutter. Phải sử dụng thư viện đồ họa mã nguồn mở của Google, Skia, để hiển thị đồ họa cấp thấp.

    Thư viện nền tảng (Foundation Library)

    Nó chứa tất cả các gói cần thiết cho các khối build cơ bản để viết một ứng dụng Flutter. Các thư viện này được viết bằng ngôn ngữ Dart.

    Vật dụng (widget)

    Trong Flutter, mọi thứ đều là một widget, đó là khái niệm cốt lõi của framework. Widget trong Flutter về cơ bản là một thành phần giao diện người dùng ảnh hưởng và kiểm soát chế độ xem và giao diện của ứng dụng. Nó đại diện cho một mô tả bất biến về một phần của giao diện người dùng và bao gồm đồ họa, văn bản, hình dạng và animation được tạo bằng các widget. Các widget tương tự như các thành phần React.

    Trong Flutter, ứng dụng tự nó là một widget chứa nhiều widget con. Điều đó có nghĩa rằng ứng dụng là tiện ích con cấp cao nhất và giao diện người dùng của nó được xây dựng bằng cách sử dụng một hoặc nhiều tiện ích con, bao gồm các tiện ích con phụ. Tính năng này giúp bạn tạo một giao diện người dùng phức tạp rất dễ dàng.

    Kiến trúc Flutter
    Kiến trúc Flutter

    Trong ví dụ trên, chúng ta có thể thấy rằng tất cả các thành phần đều là các widget có chứa các widget con. Do đó, ứng dụng Flutter tự nó là một widget.

    Thiết kế các widget cụ thể

    Framework Flutter có hai bộ widget phù hợp với các ngôn ngữ thiết kế cụ thể. Đây là Material Design cho ứng dụng Android và Cupertino Style cho ứng dụng IOS.

  • Giải thuật Đệ quy là gì?

    Giải thuật Đệ quy là gì?

    Giải thuật Đệ quy là gì?

    Đệ quy (recursion) xảy ra khi một sự vật được định nghĩa theo chính nó hoặc thuộc loại của nó. Đệ quy được sử dụng trong nhiều lĩnh vực khác nhau, từ ngôn ngữ học đến logic.

    Ví dụ dễ hiểu nhất của đệ quy là một người đứng bên cạnh một TV đang ghi hình trực tiếp chính người đó như trong hình ảnh dưới đây. Lúc đó, trong TV lại có hình ảnh người đó bên cạnh chiếc TV…

    Giải thuật Đệ quy là gì? 4

    Hoặc trên bìa sách Toán 3 có hình ảnh các em học sinh đang cầm cuốn sách Toán lớp 3.

    chương trình đệ quy là gì

    Ứng dụng phổ biến nhất của đệ quy là trong toán học và khoa học máy tính, trong đó một hàm được định nghĩa bằng cách sử dụng theo định nghĩa của chính nó. Trong Toán học, đệ qui xuất hiện trong các bài toán sử dụng phương pháp quy nạp toán học, các bài toán dãy số sử dụng công thức truy hồi.

    1. Giải thuật Đệ quy là gì?

    Trong lập trình, một đối tượng (hàm, class…) được gọi là đệ quy nếu nó hoặc một phần của nó được định nghĩa thông qua chính nó.

    Chúng ta thường gặp nhiều nhất là các hàm đệ quy. Chẳng hạn, ta có hàm factorial(n) để tính giai thừa của số tự nhiên n thì hàm này có thể được định nghĩa thông qua lời gọi đến chính nó là factorial(n) = n * factorial(n-1)

    Tuy nhiên, cũng giống như phương pháp quy nạp trong Toán học. Nếu cứ gọi đến chính nó mãi như thế thì chương trình không có điểm dừng, nên chúng ta luôn phải có những trường hợp đặc biệt được tính toán/quy ước sẵn. Chẳng hạn, đối với hàm tính giai thừa, chúng ta phải quy ước factorial(0) = 1 để chương trình gọi đến factorial(0) thì sẽ dừng lại và sử dụng luôn giá trị được cung cấp sẵn này. Mời bạn xem chi tiết chương trình tính giai thừa ở phần sau bài viết này.

    Hàm đệ quy có thể chứa lời gọi trực tiếp đến chính nó hoặc lời gọi đến hàm khác mà hàm này lại chứa lời gọi đến chính nó.

    2. Đặc điểm của hàm đệ quy

    Một hàm đệ quy gồm 2 phần:

    • Phần cơ sở: Điều kiện để thoát khỏi đệ quy. Nếu như không có phần này, hàm đệ quy sẽ thực hiện mãi mãi gây ra tràn bộ nhớ Stack.
    • Phần đệ quy: Thân hàm có chứa phần gọi đệ quy, thực hiện cho đến khi thỏa mãn điều kiện ở phần cơ sở.

    Ưu nhược điểm của chương trình đệ quy

    • Ưu điểm: Chương trình rất ngắn gọn và dễ đọc, dễ hiểu.
    • Nhược điểm: Chương trình chạy chậm và tốn nhiều bộ nhớ.

    Bài toán đệ quy

    Đó là những bài toán mang bản chất đệ quy. Nghĩa là những bài toán này có thể được phân rã thành các bài toán nhỏ hơn, đơn giản hơn nhưng có cùng dạng với bài toán ban đầu. Những bài toán nhỏ lại được phân rã thành các bài toán nhỏ hơn. Cứ như vậy, việc phân rã chỉ dừng lại khi bài toán con đơn giản đến mức có thể suy ra ngay kết quả mà không cần phải phân rã nữa. Ta phải giải tất cả các bài toán con rồi kết hợp các kết quả đó lại để có được lời giải cho bài toán lớn ban đầu. Cách phân rã bài toán như vậy gọi là “chia để trị” (devide and conquer), là một dạng của đệ quy.

    3. Một số ví dụ về đệ quy

    Một số ví dụ kinh điển về đệ quy như hàm tính giai thừa, tính tổng, tìm số hạng của dãy Fibonacci… Dưới đây, chúng ta cùng sử dụng ngôn ngữ Dart để giải quyết các bài toán này.

    Tính giai thừa bằng đệ quy

    Đề bài. Viết chương trình tính giai thừa của một số tự nhiên n.

    Giả mã của hàm tính giai thừa factorial(n) như sau:

    def factorial(n) {
      nếu n = 0 trả về kết quả 1;
      nếu n > 0 trả về kết quả n * factorial(n-1);
    }

    Dưới đây là mã nguồn chương trình viết bằng ngôn ngữ Python

    def factorial(n):     
        if (n==1 or n==0):
            return 1
        else:
            return (n * factorial(n - 1)) 
    
    print(factorial(7))//kết quả 5040

    Mã nguồn viết bằng ngôn ngữ Dart

    int factorial(int n) {
      if (n == 0)
        return 1;
      else
        return n * factorial(n - 1);
    }
    
    void main() {
      print(factorial(6)); //kết quả 720
    }

    Bạn có thể tham khảo thêm các bài tập khác bằng ngôn ngữ Dart 50 bài tập lập trình Dart cơ bản

    Tính tổng bằng đệ quy

    Viết chương trình tính tổng các số tự nhiên từ 1 tới n, sử dụng đệ quy.

    int sum(int n) {
      if (n == 1)
        return 1;
      else
        return n + sum(n - 1);
    }
    
    void main() {
      print(sum(100)); //kết quả 5050
    }

    Tìm số Fibonacci bằng đệ quy

    Viết chương trình tính số fibonacci thứ n.

    int fibo(int n) {
      if (n == 1 || n == 2)
        return 1;
      else
        return fibo(n-1) + fibo(n-2);
    }
    
    void main() {
      print(fibo(20)); //kết quả 6765
    }

    Tính số tổ hợp bằng đệ quy

    Viết chương trình tính số tổ hợp chập k của n phần tử.

    Chúng ta sử dụng 3 kiến thức sau:

    • $C^k_n=C^{k}_{n-1}+C^{k-1}_{n-1}$
    • $C^0_n=C^{n}_{n}=1$
    • $C^1_n=n$

    Mã nguồn chương trình như sau:

    int bin_coefficient(int k, int n) {
      if (k == 0 || k == n) return 1;
      if (k == 1) return n;
      return bin_coefficient(k, n - 1) + bin_coefficient(k - 1, n - 1);
    }
    
    void main() {
      print(bin_coefficient(3, 5)); //kết quả 10
      print(bin_coefficient(7, 10)); //kết quả 120
    }

    Bạn có thể xem thêm Bài toán Tháp Hà Nội được giải bằng đệ quy.

    bài toán tháp hà nội

    Các loại bài toán đệ quy

    Đệ quy có thể được phân chia thành các loại:

    • Đệ quy tuyến tính (Linear Recursion): Mỗi lần thực thi chỉ gọi đệ quy một lần, chẳng hạn hàm tính giai thừa.
    • Đệ quy nhị phân (Binary Recursion): Mỗi lần thực thi có thể gọi đệ quy 2 lần, ví dụ tính số tổ hợp chập k của n, hoặc tìm số Fibonacci ở trên.
    • Đệ quy lồng nhau (Nested Recursion): Tham số trong lời gọi đệ quy là một lời gọi đệ quy, đệ quy lồng chiếm bộ nhớ rất nhanh.
    • Đệ quy tương hỗ (Mutual Recursion): Các hàm gọi đệ quy lẫn nhau.
    • Quay lui (Backtracking). Trong lập trình, có một chiến lược giải bài toán một cách đầy đủ nhất, đảm bảo đủ mọi trường hợp bằng phương pháp Thử và Sai (Try and Error). Bạn có thể xem thêm trong bài toán Thuật toán quay lui và minh họa. Ví dụ điển hình là Bài toán xếp hậu (N-Queens)

    4. Bài tập lập trình sử dụng Đệ quy

    Sử dụng đệ quy quay lui để giải bài tập sau:

    Bài 1. Viết chương trình tính tích các số tự nhiên liên tiếp từ 1 tới n.

    Bài 2. Viết chương trình tính tổng các số tự nhiên lẻ liên tiếp từ 1 tới n.

    Bài 3. Viết chương trình tính tích các số tự nhiên liên tiếp từ 1 tới n.

    Bài 4. Đếm số lượng chữ số của số nguyên dương n.

    Bài 5. Tìm UCLN của 2 số nguyên dương ab.

    Bài 6. Tính lũy thừa n^k với nk là hai số nguyên dương được nhập vào từ bàn phím.

  • Thuật toán kiểm tra Số Nguyên Tố

    Thuật toán kiểm tra Số Nguyên Tố

    Thuật toán kiểm tra Số Nguyên Tố

    Thuật toán kiểm tra Số Nguyên Tố của một số nguyên dương, cùng với thuật toán tìm UCLN của hai số tự nhiên là những bài toán quan trọng trong Lập trình.

    Kiểm tra tính nguyên tố là bài toán kiểm tra xem một số tự nhiên n có phải là số nguyên tố hay không. Bài toán này đặc biệt trở nên quan trọng khi các hệ mật mã khoá công khai ra đời.

    1. Số nguyên tố là gì?

    Số nguyên tố (prime) là số tự nhiên lớn hơn 1, chỉ có hai ước số là 1 và chính nó. Theo định nghĩa này thì các số 2, 3, 5, 7, 11,… là các số nguyên tố, trong đó số 2 là số nguyên tố chẵn duy nhất.

    số nguyên tố là gì

    Ví dụ: 7 là số nguyên tố vì trong khoảng từ 2 đến 6 không tồn tại số nào mà 7 chia hết cả.

    2. Các Thuật toán kiểm tra Số Nguyên Tố Đơn Giản

    Phương pháp đơn giản nhất để kiểm tra một số n có là số nguyên tố không là kiểm tra xem nó có chia hết cho các số m nằm trong khoảng 2 đến n-1 hay không.

    Nếu n chia hết cho một trong các số m nào đó thì n không là số nguyên tố (còn được gọi là hợp số composite). Ngược lại, nếu n không chia hết cho bất kì số m nào thì kết lianaj n là số nguyên tố.

    Thực ra việc kiểm tra với m từ 2 đến n-1 là không cần thiết, mà chỉ cần kiểm tra đến $\sqrt{n}$ là đủ. Vì nếu n là hợp số thì nó chắc chắn có ước số không vượt quá sqrt(n).

    Lặp từng phần tử với bước nhảy 1 đến n-1

    Giả sử cần kiểm tra số n có phải là số nguyên tố hay không thì các bước thực hiện như sau:

    • Bước 1: Nhập vào n
    • Bước 2: Kiểm tra nếu n < 2 thì kết luận n không phải là số nguyên tố
    • Bước 3: Lặp từ 2 tới (n-1), nếu trong khoảng này tồn tại số mà n chia hết thì kết luận n không phải là số nguyên tố, ngược lại n là số nguyên tố.

    Độ phức tạp của thuật toán trên là $O(n)$.

    Lặp từng phần tử với bước nhảy 2

    Theo định nghĩa thì số 2 là số nguyên tố chẵn duy nhất, vì vậy ta sẽ loại 2 ra khỏi vòng lặp và trong thân vòng lặp chỉ kiểm tra các số lẻ mà thôi, cách này sẽ tối ưu hơn cách 1 rất nhiều.

    • Bước 1: Nhập vào n;
    • Bước 2: Kiểm tra nếu n < 2 thì kết luận n không phải là số nguyên tố;
    • Bước 3: Kiểm tra nếu n = 2 thì kết luận n là số nguyên tố;
    • Bước 4: Kiểm tra nếu n > 2 và chẵn thì kết luận n không phải là số nguyên tố;
    • Bước 5. Lặp từ 3 tới (n-1), bước nhảy là 2 nếu trong khoảng này tồn tại số mà n chia hết thì kết luận n không phải là số nguyên tố, ngược lại n là số nguyên tố.

    Lặp từng phần tử đến $\sqrt{n}$

    Để tối ưu hơn, thay vì lặp tới n-1, chúng ta chỉ cần lặp các số từ 2 đến sqrt(n), nếu n chia hết cho một trong những số đó thì n không phải là số nguyên tố. Ngược lại thì n là số nguyên tố.

    Độ phức tạp của thuật toán trên là $O(\sqrt{n})$.

    Xem mã nguồn viết bằng ngôn ngữ Dart tại đây https://divin.dev/dart/2021/10/14/bai-tap-dart-17.html

    3. Tối ưu thuật toán kiểm tra số nguyên tố

    Chúng ta có thể tối ưu thuật toán trên bằng cách chỉ ra n không chia hết cho những số nguyên tố nhỏ hơn nó. Tuy nhiên, chúng ta lại chưa biết được các số nguyên tố nhỏ hơn nó là những số nào (Bạn có thể sử dụng phương pháp sàng số nguyên tố – Sàng Eratosthenes để tìm ra các số nguyên tố nhỏ hơn số n cho trước). Nên ta sử dụng kết quả sau đây:

    Tất cả những số nguyên tố lớn hơn 3 đều có dạng 6k ± 1 (vì 6k, 6k ± 2, là những số chẵn; 6k + 3 thì chia hết cho 3).

    Do đó, chúng ta chỉ cần kiểm tra các số có dạng 6k ± 1 từ 2 đến √n, nếu n chia hết cho một trong những số đó thì n không phải là số nguyên tố. Ngược lại thì n là số nguyên tố.

    def is_prime(n: int) -> bool:
        """Primality test using 6k+-1 optimization."""
        if n <= 3:
            return n > 1
        if n % 2 == 0 or n % 3 == 0:
            return False
        i = 5
        while i ** 2 <= n:
            if n % i == 0 or n % (i + 2) == 0:
                return False
            i += 6
        return True

    4. Các Thuật toán kiểm tra Số Nguyên Tố Nâng Cao

    Các cách kiểm tra số nguyên tố kể trên có độ chính xác tuyệt đối nhưng khối lượng tính toán rất lớn. Theo Wiki thì chúng ta còn có những cách khác để kiểm tra tính nguyên tố của một số với một độ chính xác cho trước.

    Kiểm tra theo xác suất

    Các phép kiểm tra tính nguyên tố hay dùng nhất là các thuật toán ngẫu nhiên.

    Giả sử có một mệnh đề Q(p,a) nào đó đúng với mọi số nguyên tố p và một số tự nhiên a <= p. Nếu n là một số tự nhiên lẻ và mệnh đề Q(n,a) đúng với một a<= n được lấy ngẫu nhiên, khi đó a có khả năng là một số nguyên tố.

    Ta đưa ra một thuật toán, kết luận rằng n là số nguyên tố. Nó là một thuật toán ngẫu nhiên hay thuật toán xác suất. Trong các thuật toán loại này, dùng một kiểm tra ngẫu nhiên sẽ không bao giờ kết luận một số nguyên tố là hợp số nhưng lại có thể kết luận một hợp số là số nguyên tố. Do đó, phương pháp này không chính xác một cách tuyệt đối.

    Xác suất sai của phép kiểm tra có thể giảm xuống nhờ việc chọn một dãy độc lập các số a; nếu với mỗi số a xác suất để thuật toán kết luận một hợp số là số nguyên tố là nhỏ hơn một nửa thì sau k lần thử độc lập, xác suất sai là nhỏ hơn 2^k, độ tin cậy của thuật toán sẽ tăng lên theo k.

    Cấu trúc cơ bản của một phép kiểm tra ngẫu nhiên là:

    • Chọn một số ngẫu nhiên a.
    • Kiểm tra một hệ thức nào đó giữa số a và số n đã cho. Nếu hệ thức sai thì chắc chắn n là một hợp số (số a là “bằng chứng” chứng tỏ n là hợp số) và dừng thuật toán.
    • Nếu hệ thức đúng, chúng ta lặp lại hai bước trên cho đến khi đạt được một số lần định trước hoặc gặp trường hợp dừng thuật toán.

    Sau nhiều lần thử, nếu hệ thức đúng với nhiều giá trị của a, ta có thể nói rằng n “có khả năng cao” là số nguyên tố chứ không thể chắc chắn n là số nguyên tố. Tất nhiên là chúng ta sẽ tìm cách tăng “khả năng” này lên bằng cách thực hiện nhiều tính toán hơn.

    Các hệ thức thường sử dụng

    Nếu p là một số nguyên tố thì

    • 2p - 1 ≡ 1 (mod p) (đây là nội dung của định lí Fermat nhỏ)
    • fp + 1 ≡ 0 (mod p) (với fp + 1 là số Fibonacci thứ p + 1 và p có dạng 5k ± 2)
    • (p - 1)! ≡ -1 (mod p) khi và chỉ khi p nguyên tố. Đây là nội dung của định lí Wilson, nhưng việc tính toán biểu thức (n - 1)! % n sẽ có độ phức tạp lớn hơn log n.

    Các phép kiểm tra tính nguyên tố ngẫu nhiên là:

    • Phép kiểm tra tính nguyên tố của Fermat (kiểm tra Fermat). Đây là phép thử heuristic; tuy nhiên ít người sử dung phép thử này.
    • Kiểm tra Miller-Rabin và Kiểm tra Solovay-Strassen. Với mỗi hợp số n, ít nhất 3/4 (với kiểm tra Miller-Rabin) hoặc 1/2 (Với kiểm tra Solovay-Strassen) các số a là bằng chứng chứng tỏ n là hợp số).

    thuật toán kiểm tra số nguyên tố

    Các phép kiểm tra tất định

    Vào năm 2002, Manindra Agrawal, Nitin Saxena và Neeraj Kayal đề xuất một giải thuật tất định kiểm tra tính nguyên tố, là kiểm tra AKS, có khả năng chạy trong O((log n)12). Trên thực tế thuật toán này chạy chậm hơn các phương pháp xác suất.

    Các phương pháp này, mời bạn đọc tham khảo thêm tại https://en.wikipedia.org/wiki/Primality_test

     

  • 50 bài tập lập trình Dart cơ bản

    50 bài tập lập trình Dart cơ bản

    50 bài tập lập trình Dart cơ bản

    50 bài tập lập trình Dart cơ bản dưới đây được chúng tôi gợi ý giải bằng ngôn ngữ Dart. Tuy nhiên, bạn hoàn toàn có thể sử dụng Python, C, C#, C++, Java hoặc các ngôn ngữ lập trình khác để giải quyết. Do đó chúng tôi tổng hợp chung lại thành một bài viết. Phần lời giải, nếu có, của từng ngôn ngữ sẽ có bài viết riêng.

    Xem thêm: Giáo trình tự học Flutter/Dart

    Playlist dạy lập trình Dart:

    1. Bài tập lập trình Dart, C, Java cơ bản sử dụng if for while

    Các bài tập này sử dụng các câu lệnh điều kiện if, câu lệnh rẽ nhánh for, while (câu lệnh điều khiển luồng chương trình).

    Bài 1. Viết chương trình hỏi người dùng họ tên và tuổi (là một số nguyên). Tính và in ra màn hình còn bao nhiêu năm nữa thì người đó mừng thọ 100 tuổi 🙂

    Xem thêm: Cách đọc input từ người dùng tại https://www.youtube.com/watch?v=UH9Hs1wiIqM

    Lời giải: https://divin.dev/dart/2021/10/14/bai-tap-dart-1.html

    Bài 2. Viết chương trình hỏi người dùng nhập vào một số nguyên. In ra màn hình số nguyên đó là số chẵn hay lẻ.

    Lời giải: https://divin.dev/dart/2021/10/14/bai-tap-dart-2.html

    Bài 3. In ra màn hình tất cả các số nguyên dương lẻ nhỏ hơn 100.

    Lời giải: https://divin.dev/dart/2021/10/14/bai-tap-dart-3.html

    Bài 4. Viết chương trình in ra tất cả các số lẻ nhỏ hơn 100 trừ các số 5, 7, 93.

    Lời giải: https://divin.dev/dart/2021/10/14/bai-tap-dart-4.html

    Bài 5. Viết chương trình tìm số lớn nhất trong ba số thực a, b, c.

    Lời giải: https://divin.dev/dart/2021/10/14/bai-tap-dart-5.html

    Bài 6. Viết chương trình kiểm tra xem hai số thực a b cho trước có cùng dấu hay không.

    Lời giải: https://divin.dev/dart/2021/10/14/bai-tap-dart-6.html

    Bài 7. Viết chương trình in ra cách đọc của một số nguyên n cho trước có ba chữ số. Ví dụ với n=123 thì kết quả in ra màn hình là Một trăm hai mươi ba.

    Lời giải: https://divin.dev/dart/2021/10/14/bai-tap-dart-7.html

    Bài 8. Viết chương trình sinh ra một số tự nhiên n ngẫu nhiên từ 1 đến 100. Đề nghị người dùng đoán một số và nhập vào. In ra màn hình thông báo xem số người dùng đoán đúng, lớn hơn hay nhỏ hơn số n. Nếu chưa đúng thì cho phép người dùng đoán lại hai lần nữa.

    Lời giải: https://divin.dev/dart/2021/10/14/bai-tap-dart-8.html

    Bài 9. Viết chương trình tìm tất cả các số chia hết cho 7 nhưng không phải bội số của 5, nằm trong đoạn 10200. Các số thu được sẽ được in thành chuỗi trên một dòng, cách nhau bằng dấu phẩy.

    Lời giải: https://divin.dev/dart/2021/10/14/bai-tap-dart-9.html

    Bài 10. Viết chương trình nhập ngày, tháng, năm. Hãy cho biết tháng đó có bao nhiêu ngày.

    Lời giải: https://divin.dev/dart/2021/10/14/bai-tap-dart-10.html

    Bài 11. Viết chương trình nhập ngày, tháng, năm. Hãy cho biết ngày đó là thứ mấy.

    Lời giải: https://divin.dev/dart/2021/10/14/bai-tap-dart-11.html

    Bài 12. Viết chương trình in bảng cửu chương ra màn hình.

    Lời giải: https://divin.dev/dart/2021/10/14/bai-tap-dart-12.html

    Bài 13. Hãy sử dụng vòng lặp for để in tất cả các ký tự A tới Z ra màn hình.

    Lời giải: https://divin.dev/dart/2021/10/14/bai-tap-dart-13.html

    Bài 14. Viết một chương trình tính giai thừa của một số nguyên dương n. Với n được nhập từ bàn phím. Ví dụ, n = 8 thì kết quả đầu ra phải là

    1*2*3*4*5*6*7*8 = 40320

    Lời giải: https://divin.dev/dart/2021/10/14/bai-tap-dart-14.html

    Bài 15. Viết chương trình tìm ước số chung lớn nhất (UCLN) của hai số nguyên dương ab nhập từ bàn phím.

    Lời giải: https://divin.dev/dart/2021/10/14/bai-tap-dart-15.html

    Bài 16. Viết chương trình tìm bội số chung nhỏ nhất (BCNN) của hai số nguyên dương ab nhập từ bàn phím.

    Bài 17. Viết chương trình kiểm tra một số nguyên dương n có phải là số nguyên tố hay không.

    Lời giải: https://divin.dev/dart/2021/10/14/bai-tap-dart-17.html

    Bài 18. Viết chương trình liệt kê n số nguyên tố đầu tiên. Số nguyên dương n được nhập từ bàn phím.

    Hướng dẫn. Bạn có thể tham khảo về sàng số nguyên tố

    Bài 19. Tìm số nguyên dương n nhỏ nhất sao cho 1 + 2 + … + n > 10000.

    Lời giải: Bài tập Dart số 19

    Bài 20. Viết chương trình liệt kê n số hạng đầu tiên của dãy Fibonacci không sử dụng hàm.

    Hướng dẫn. Nếu sử dụng hàm và lời gọi đệ qui thì bài toán khá đơn giản, xin mời xem lời giải ở bài 54. Ở đây, chúng ta sẽ sử dụng ba biến để luôn phiên thay đổi các số hạng của dãy Fibonacci và một biến đếm. 

    Lời giải: Bài tập Dart số 20-Dãy Fibonacci

    Bài 21. Viết chương trình tính tổng các giá trị lẻ nguyên dương nhỏ hơn số nguyên dương n cho trước.

    Bài 22. Viết chương trình tìm số nguyên dương m lớn nhất sao cho 1 + 2 + 3 + … + m < N.

    Bài 23. Viết chương trình liệt kê tất cả số nguyên tố có 5 chữ số.

    Bài 24. Viết chương trình phân tích số nguyên n thành các thừa số nguyên tố. Ví dụ: 100 = 2*2*5*5.

    Bài 25. Viết chương trình tính tổng của các chữ số của môt số nguyên n trong Dart. Số nguyên dương n được nhập từ bàn phím. Với n = 1234, tổng các chữ số: 1 + 2 + 3 + 4 = 10.

    Bài 26. Viết chương trình kiểm tra một số nguyên dương n có là số thuận nghịch hay không.

    Bài 27. Viết chương trình liệt kê tất cả các số nguyên tố nhỏ hơn n. Số nguyên dương n được nhập từ bàn phím.

    Bài 28. Liệt kê tất cả ước số của số nguyên dương n.

    Bài 29. Tính tổng tất cả ước số của số nguyên dương n.

    Bài 30. Tính tích tất cả ước số của số nguyên dương n.

    Bài 31. Đếm số lượng ước số của số nguyên dương n.

    Bài 32. Liệt kê tất cả ước số lẻ của số nguyên dương n.

    Bài 33. Cho số nguyên dương n. Tính tổng các ước số nhỏ hơn chính nó.

    Bài 34. Tìm ước số lẻ lớn nhất của số nguyên dương n. Ví dụ n = 100 ước lẻ lớn nhất của 10025.

    Bài 35. Cho số nguyên dương n. Kiểm tra số dương n có phải là số hoàn thiện (số hoàn hảo) hay không.

    Bài 36. Cho số nguyên dương n. Kiểm tra số nguyên dương n có phải là số nguyên tố hay không.

    Bài 37. Cho số nguyên dương n. Kiểm tra số nguyên dương n có phải là sốchính phương hay không.

    Bài 38. Cho n là số nguyên dương. Hãy tìm giá trị nguyên dương k lớn nhất sao cho S(k) < n. Trong đó chuỗi S(k) được định nghĩa như sau:

    S(k) = 1 + 2 + 3 + … + k

    Bài 39. Hãy đếm số lượng chữ số của số nguyên dương n.

    Bài 40. Hãy tính tổng các chữ số của số nguyên dương n.

    Bài 41. Hãy tìm chữ số đảo ngược của số nguyên dương n.

    Bài 42. Tìm chữ số nhỏ nhất của số nguyên dương n.

    Bài 43. Hãy kiểm tra số nguyên dương n có toàn chữ số lẻ hay không.

    Bài 44. Hãy kiểm tra các chữ số của số nguyên dương n có tăng dần từ trái sang phải hay không.

    Bài 45. Hãy kiểm tra các chữ số của số nguyên dương n có giảm dần từ trái sang phải hay không.

    Bài 46. Giải phương trình bậc nhất ax+b=0.

    Bài 47. Giải phương trình bậc hai ax^2+bx+c=0.

    Bài 48. Giải phương trình trùng phương ax^4+bx^2+c=0.

    Bài 49. Viết chương trình nhập 3 cạnh của một tam giác là các số nguyên dương. Hãy cho biết đó là tam giác gì.

    Bài 50. Lập chương trình giải hệ: $$\begin{cases} ax+by=c\\ dx+ey=f \end{cases}$$ Các hệ số a b c d e f nhập từ bàn phím. Yêu cầu xét tất cả các trường hợp có thể. (Gợi ý: Sử dụng định thức)

    2. Bài tập lập trình Dart, C, Java cơ bản sử dụng hàm

    Bài 51. Cần có tổng 200.000đ từ 3 loại tiền 1000đ, 2000đ, và 5000đ. Lập chương tình để tìm tất cả các phương án có thể.Tìm giá trị lớn nhất trong mảng một chiều các số thực.

    Bài 52. Viết chương trình tính tổng các số tự nhiên từ 1 tới n.

    Bài 53. Viết chương trình tính giai thừa của số tự nhiên n.

    Bài 54. Viết hàm tính số hạng thứ n của dãy Fibonacci.

    Bài 55. Viết hàm kiểm tra xem số nguyên dương n có là số nguyên tố hay không.

    Bài 56. Viết hàm tìm UCLN của hai số nguyên ab sử dụng đệ quy.

  • Class in Dart / Flutter

    Class in Dart / Flutter

    Class in Dart/Flutter

    What is class in Dart?

    • In object-oriented programming, a class is a blueprint for creating objects (a particular data structure), providing initial values for state (member variables or attributes), and implementations of behavior (member functions or methods).
    • We can assume a class as a sketch (prototype) or a car. It contains all the details about model name, year, features, price, etc. Based on these properties of the car, we can build the car. Here the car is an object.
    • There can be many cars so we can create many objects of cars to access all the properties.

    what is class in dart flutter

    Benefit of object-oriented programming

    • Modularity: The source code of an object can be maintained individually and can hide from the other object’s source code.
    • Data – hiding: Using oops programming, the details of the internal functionality of code are hidden from the others. For example – Users only interact with the application, but they don’t familiar with the internal implementation.
    • Reusability: We don’t need to write the same code again and again. We can use the object of class multiple times in our program.
    • Pluggability and debugging easy: If any object is creating a problem in our program, and then we can replace it in our program and plug the new object as its replacement. The oops code can be easy to debug.

    Defining a Class in Dart

    Dart provides class keyword followed by a ClassName is used to define a class; all fields and functions are enclosed by the pair of curly braces {}.

    class ClassName {
      <fields/properties>
      <getters/setters>
      <constructors>
      <functions>
    }
    • <fields/properties> any variable declared in a class, represent data pertaining to objects.
    • <getters/setters> initialize and retrieve the values of the fields of a class
    • <constructors> responsible for allocating memory for the objects of the class.
    • <functions> represent actions an object can take

    class in dart

    Creating Instance of the class

    • To create an instance of the class, use the new keyword followed by the class name.

    var object_name = new ClassName([arguments])

    • The new keyword is responsible for instantiation. Starting from Dart 2, the keyword new can be omitted.
    • The right-hand side of the expression invokes the constructor.
    • The constructor should be passed values if it is parameterized.

    Libraries and visibility

    • a library referring to the code inside a file with the .dart extension
    • to use that particular library, you have to reference its content with the import keyword
    • using the as keyword if have two different libraries have implemented a class with the same name
    • selectively import or exclude types using the show and hide keywords

    Class Constructors

    A constructor is a special function of the class that is responsible for initializing the variables of the class. Dart defines a constructor with the same name as that of the class. A constructor is a function and hence can be parameterized. However, unlike a function, constructors cannot have a return type.

    👉Named and positional parameters in Dart

    Class_name(parameter_list) {
    //constructor body
    //.............
    }
    • If your class doesn’t define a constructor, the compiler automatically adds a default constructor with no parameters and an empty body.
    • The “initializing formal” using this keyword, more readable and it initializes the variables immediately
    • With null safety, a named argument with a non-nullable type must either have a default or be marked with the new required keyword. Otherwise, it wouldn’t make sense for it to be non-nullable, because it would default to null when not passed.
    • With the “initializing formal” you can still declare a body to perform additional setup for the class, constructors cannot have a return type.
    • If you don’t declare a constructor, a default no-argument constructor is provided for you.

    Initializer list

    • When using the initializing formal approach, the names of the variables must match the ones declared in the constructor.
    • If you wanted to keep fields private but with a different name in the constructor, use an initializer list
    class Test {
    int _secret;
    double _superSecret;
    Test(int age, double wallet)
    : _secret = age,
    _superSecret = wallet;
    }

    Named Constructors

    Named constructors are generally used to implement a default behavior the user expects from your class. They are the only alternative to have multiple constructors since Dart has no method overload.

    Class_name.constructor_name(param_list)

    Redirecting constructors

    Sometimes you might have a constructor that does almost the same thing already implemented by another one. It may be the case to use redirecting constructors in order to avoid code duplication.

    Factory constructors

    • The factory keyword returns an instance of the given class that’s not necessarily a new one. It can be useful when:
      • you want to return an instance of a subclass instead of the class itself,
      • you want to implement a singleton (the Singleton pattern),
      • you want to return an instance from a cache.
    • Factory constructors are like static methods and so they don’t have access to this. There cannot be together a factory and a “normal” constructor with the same name.

    static variables and methods

    • The static keyword can be applied to the data members of a class, i.e., fields and methods. A static variable retains its values till the program finishes execution. Static members are referenced by the class name.
    • The static variables and methods are part of the class instead of a specific instance.
    • The static keyword is used for a class-level variable and method that is the same for every instance of a class, this means if a data member is static, it can be accessed without creating an object.
    • The static keyword allows data members to persist values between different instances of a class.
    • There is no need to create a class object to access a static variable or call a static method: simply put the class name before the static variable or method name to use them.

    The this keyword

    The this keyword refers to the current instance of the class. Here, the parameter name and the name of the class’s field are the same. Hence to avoid ambiguity, the class’s field is prefixed with the this keyword.

    Accessing Attributes and Functions

    A class’s attributes and functions can be accessed through the object. Use the “.” dot notation (called as the period) to access the data members of a class.

    //accessing an attribute
    obj.field_name
    //accessing a function
    obj.function_name()

    Cascade notation

    • The cascade notation (..) in Dart allows you to make a sequence of operations on the same object (including function calls and field access).
    • This notation helps keep Dart code compact and removes the need to create temporary variables to store data.

    Encapsulation (Access modifiers)

    • In Java, we can use public, protected, and private keywords to control the access scope for a property or method. However, Dart doesn’t provide that
      kind of keywords. Instead, you can use _ (underscore) at the start of the name to make a data member of a class becomes private.
    • In Dart, the privacy is at library level rather than class level. It means other classes and functions in the same library still have the access. So, a data member is either public (if not preceded by _) or private (if preceded by _)

    Getters and Setters

    • Getters and Setters, also called as accessors and mutators, allow the program to initialize and retrieve the values of class fields respectively. Getters or accessors are defined using the get keyword. Setters or mutators are defined using the set keyword.
    • A default getter/setter is associated with every class. However, the default ones can be overridden by explicitly defining a setter/ getter. A getter has no parameters and returns a value, and the setter has one parameter and does not return a value.

    Class Inheritance

    • Dart supports the concept of Inheritance which is the ability of a program to create new classes from an existing class. The class that is extended to create newer classes is called the parent class/super class. The newly created classes are called the child/sub classes.
    • A class inherits from another class using the extends keyword. Child classes inherit all properties and methods except constructors from the parent class.

    Types of Inheritance

    • Inheritance can be of the following three types:
    • Single – Every class can at the most extend from one parent class.
    • Multiple – A class can inherit from multiple classes. Dart doesn’t support multiple inheritance.
      Multi-level – A class can inherit from another child class.

    Class Inheritance and Method Overriding

    • Method Overriding is a mechanism by which the child class redefines a method in its parent class.

    super keyword

    • The super keyword is used to refer to the immediate parent of a class.
    • The super keyword can be used to refer to the super class version of a variable, property, or method.

    super and constructors

    Every subclass in Dart automatically tries to call the default constructor of the superclass. If there isn’t one, you must call the superclass constructor
    manually in the initializer list.

    Abstract class

    • The abstract keyword defines a class that cannot be directly instantiated: only its derived classes can. An abstract class can define one (or more)
      constructors as usual.
    • Usually abstract classes contain abstract methods which can be defined putting a semicolon (;) instead of the body. You cannot define an abstract
      method in a class that’s not been marked with the abstract modifier.
    • If your class contains at least one method with no body, then it must be abstract and the children must provide an implementation.

    Interfaces

    • In contrast to other programming languages, Dart does not have an interface keyword and you have to use classes to create interfaces. Your class can
      implement more than a single interface.
    • The keyword is implements and, differently from a regular subclass, here you must override every method defined by the class/interface.
    • In Dart when you use the term interface you are referring to a class that is going to be used by others along with implements because it only provides method signatures. The concept is the same you can find in Java, Delphi or C# with the only difference that Dart doesn’t have a dedicated keyword.
    • While extends can be used with only one class, implements works with one or more classes, which you should treat as interfaces (methods with no body).

    extends vs implements

    • When you use class B extends A {} you are NOT forced to override every method of class A. Inheritance takes place and you can override as many methods as you want. This is the typical OOP inheritance that can be used when you want to add some missing features in a subclass.
    • When you use class B implements A {} you must override every method of class A. Inheritance does NOT take place because methods just provide an API, a “skeleton” that the subclass must concretize.
    • Interfaces are useful when you don’t want to provide an implementation of the functions but just the API. It’s like if the interface was wall socket and the class was the plug that adapts to the holes. While multiple inheritance is not allowed, you can extends a class and implements more than one.

    Mixins

    • a mixin is simply a class with no constructor that can be “attached” to other classes to reuse the code without inheritance
    • mixins like a “copy/paste” tool to reuse methods

    override operators

    • Operator overloading gives the possibility to customize the usage of operators in your classes.
    • Arithmetic operators like +, -, *, or /.
    • Relational operators such as >=, <=, > or <.
    • Equality operators like != and ==

    callable classes

    There is a special call() method which is very closely related to an operator overload because it allows classes to be called like if they were functions with
    the () operator.

  • Named and positional parameters in Dart

    Named and positional parameters in Dart

    Named and positional parameters in Dart

    In Dart, we have two types of optional parameters: named and positional.

    • Dart’s optional parameters are optional in that the caller isn’t required to specify a value for the parameter when calling the function.
    • Optional parameters can only be declared after any required parameters.
    • Optional parameters can have a default value, which is used when a caller does not specify a value.

    Optional parameters are parameters which don’t have to be specified when calling given function. Optional parameters must be declared after required parameters. Additionally, optional parameters can have a default value, which is used once the function invocation doesn’t specify it.

    👉Dart Cheat Sheet and Quick Reference

    Positional Parameters in Dart

    Square brackets [] are used to specify optional, positional parameters in Dart.

    void hamViDu(int a, [int b = 0, int c = 0]) {
      if (b != 0 && c != 0) {
        print('a:$a - b:$b - c:$c');
      } else if (b != 0) {
        print('a:$a - b:$b');
      } else {
        print('a:$a');
      }
    }
    
    void main() {
      hamViDu(5, 10, 15);
    
      print('----------------------');
      hamViDu(5);
    
      print('----------------------');
      hamViDu(5, 10);
    }

    For such declaration a is always required while b and c are optional. Also, b, c will default to 0 if not specified.

    hamViDu(5, 10, 15); //print a:5 - b:10 - c:15
    
    hamViDu(5); //print a:5
    
    hamViDu(5, 10);//print a:5 - b:10

    Additionally, the parameter names are specified and visible only at the level of the function declaration. The function caller must know which position corresponds to which parameter. This leads to a slightly less readable code.

    Named parameters in Dart

    Curly brackets {} are used to specify optional, named parameters in Dart.

    readFile(String name, {String mode, String charset = 'utf-8'}) { 
    //......
    }

    Named parameters are referenced by name, which means that they can be used during the function invocation in an order different from the function declaration.

    void hamViDu({int a = 0, int b = 0, int c = 0}) {
      print('a:$a - b:$b - c:$c');
    }
    
    void main() {
      hamViDu();
    
      print('----------------------');
      hamViDu(a: 5, c: 15, b: 10);
    
      print('----------------------');
      hamViDu(c: 5);
      
      print('----------------------');
      hamViDu(b: 5, c: 10);
    }

    Checking if optional parameter was provided

    Unfortunately, you cannot distinguish between the cases “an optional parameter was not provided” and “an optional parameter was provided with the default value”.

    Note: You may use positional optional parameters or named optional parameters, but not both in the same function or method. The following is not allowed.

    thisFunctionWontWork(String foo, [String positonal], {String named}) {
     // will not work! 
    }
  • Kiểu null trong Dart

    Kiểu null trong Dart

    Kiểu null trong Dart là một đối tượng đặc biệt dùng để biểu thị cho một đối tượng rỗng, trống, không chứa gì.

    Trước phiên bản 2.0 thì khi tạo mới một biến, Dart sẽ gán giá trị mặc định cho biến đó là null, nếu không được cung cấp.

    Từ phiên bản 2.0 trở đi thì Dart hỗ trợ tính năng null safety, do đó bạn cần cung cấp cho biến một giá trị trước khi sử dụng biến đó, nếu không Dart sẽ cảnh báo ngay trong khi soạn thảo mà không cần đợi đến khi biên dịch chương trình. Chi tiết, xin mời xem trong bài 🎯 Null safety Dart / Null safety Flutter là gì?

    Có một số toán tử đặc biệt làm việc với giá trị null??!