PRM393Chưa đoKỳ 8Chuyên ngành Cập nhật 07/09/2026

Lập trình di động (Flutter) - Mobile Programming

Lập trình di động với Flutter là môn học xây dựng ứng dụng đa nền tảng Android và iOS bằng Flutter và ngôn ngữ Dart. Ngân hàng câu hỏi trắc nghiệm PRM393 có giải thích bao quát trọn bộ chương trình: cài đặt Flutter SDK, cấu trúc project, hot reload và DevTools, nền tảng Dart (kiểu dữ liệu, null safety, class, collection, Map, generics, mixin, package và import), lập trình bất đồng bộ với Future, async/await, Stream, StreamController và StreamBuilder, dựng giao diện bằng widget tree, Scaffold, ListView, ThemeData, bố cục Row/Column, GridView, Stack, LayoutBuilder, MediaQuery và responsive UI, điều hướng với Navigator 1.0/2.0, named route, deep link và guarded route, form với TextEditingController và validation, gọi REST API bằng http, parse JSON, FutureBuilder, phân trang và caching, lưu trữ cục bộ bằng SharedPreferences, SQLite (sqflite) và Hive, xác thực bằng token và refresh token, quản lý state với setState, Provider, BLoC và Cubit, animation với Tween cùng AnimatedSwitcher, tối ưu hiệu năng bằng RepaintBoundary và thu hẹp phạm vi rebuild, kiểm thử unit/widget/integration, quản lý mã nguồn bằng Git và build - release ứng dụng. Tài liệu ôn thi FE dành cho sinh viên FPT University.

512Câu hỏi
1Bộ đề
15Chủ đề
5,02 đánh giá

Câu hỏi của môn

444/512 câuCòn 68
AOnly measure build time
BBreak down APK/AAB size (treemap, report)
CAutomatically remove unused dependencies
DMust run on iOS only
Lời giải
Tùy chọn `flutter build apk --analyze-size` giúp phân tích kích thước của tệp APK hoặc AAB. Khi chạy lệnh này, Flutter sẽ tạo ra một bản phân tích chi tiết về kích thước của từng phần trong tệp APK hoặc AAB, bao gồm cả hình ảnh, mã nguồn, thư viện phụ thuộc, v.v. Điều này giúp bạn dễ dàng xác định được phần nào trong ứng dụng chiếm nhiều không gian nhất và có thể giúp bạn tối ưu hóa kích thước của ứng dụng để giảm thiểu thời gian tải xuống và tăng tốc độ hoạt động.
Mở trang câu hỏi này →
AReplaces Hot Reload
BOnly applies to WebView
CRemoves unreferenced code in release builds (smaller size)
DIncreases app size
Lời giải
Tree shaking trong Dart/Flutter là một tính năng giúp loại bỏ mã không được sử dụng trong ứng dụng. Điều này có nghĩa là bất kỳ mã nào không được sử dụng trong mã nguồn sẽ không được bao gồm trong bản phát hành cuối cùng của ứng dụng. Điều này giúp giảm kích thước của ứng dụng và cải thiện hiệu suất. Khi bạn sử dụng tree shaking, Dart sẽ tự động loại bỏ mã không cần thiết, giúp bạn tiết kiệm thời gian và công sức. Điều này đặc biệt hữu ích khi bạn đang phát triển ứng dụng lớn và muốn đảm bảo rằng mã của bạn được tối ưu hóa.
Mở trang câu hỏi này →
427What is BuildContext used for?4 lựa chọn
AStore data
BWidget location in widget tree
CAPI calls
DAnimation
Lời giải
BuildContext là một đối tượng quan trọng trong Flutter, giúp xác định vị trí của một widget trong cây widget. Nó cung cấp thông tin về vị trí của widget, bao gồm cả vị trí của cha, mẹ và các anh chị em của nó. BuildContext cũng giúp bạn truy cập vào các phương thức và thuộc tính của widget cha, chẳng hạn như kích thước, vị trí và trạng thái của widget. Điều này cho phép bạn xây dựng các ứng dụng phức tạp hơn và dễ dàng hơn bằng cách chia nhỏ ứng dụng thành các phần nhỏ hơn và dễ quản lý hơn.
Mở trang câu hỏi này →
AIt allows a single child widget to be scrollable when it exceeds the screen's vertical or horizontal space.
BProfile mode is for performance testing with some debugging tools, while Release mode is fully optimised for deployment.
CIt manages the focus state of a specific widget, such as a text field, and handles keyboard events.
DIt allows a constructor to return an existing instance or a subclass instance instead of always creating a new one.
Lời giải
Khi chạy ứng dụng Flutter, có hai chế độ chạy chính là 'Profile mode' và 'Release mode'. 'Profile mode' được sử dụng để kiểm tra hiệu suất và thử nghiệm với một số công cụ debug. Trong khi đó, 'Release mode' được tối ưu hóa hoàn toàn cho việc triển khai ứng dụng. Điều này có nghĩa là khi bạn chạy ứng dụng trong 'Release mode', ứng dụng sẽ được tối ưu hóa để chạy nhanh và ổn định hơn, nhưng đồng thời cũng sẽ mất đi một số tính năng debug và kiểm tra hiệu suất. Vì vậy, 'Profile mode' thường được sử dụng trong quá trình phát triển và thử nghiệm, trong khi 'Release mode' được sử dụng khi ứng dụng đã sẵn sàng để triển khai.
Mở trang câu hỏi này →
AIt allows a constructor to return an existing instance or a subclass instance instead of always creating a new one.
BProfile mode is for performance testing with some debugging tools, while Release mode is fully optimised for deployment.
CIt allows a widget to rebuild only when a specific part of a model changes, rather than the entire model.
DIt allows a single child widget to be scrollable when it exceeds the screen's vertical or horizontal space.
Lời giải
Trong Dart, một 'factory' constructor là một loại constructor đặc biệt. Nó cho phép constructor tạo ra một đối tượng mới hoặc một đối tượng con thay vì luôn tạo ra một đối tượng mới. Điều này có nghĩa là factory constructor có thể trả về một đối tượng đã tồn tại hoặc một đối tượng con thay vì luôn tạo ra một đối tượng mới. Điều này rất hữu ích khi bạn muốn tạo ra một đối tượng mới dựa trên một đối tượng đã tồn tại hoặc khi bạn muốn tạo ra một đối tượng con từ một đối tượng cha. Ví dụ, bạn có thể sử dụng factory constructor để tạo ra một đối tượng mới dựa trên một đối tượng đã tồn tại hoặc để tạo ra một đối tượng con từ một đối tượng cha.
Mở trang câu hỏi này →
AArrange, Act, and Assert.
Bflutter build apk --analyze-size
CString interpolation using `${expression}`
DPerformance Timeline in DevTools
Lời giải
Để xác định các thành phần nào đang đóng góp nhiều nhất vào kích thước APK cuối cùng của ứng dụng, bạn cần sử dụng lệnh được cho phép phân tích kích thước APK. Trong Flutter, lệnh này được gọi là "flutter build apk --analyze-size". Lệnh này sẽ giúp bạn thấy được các thành phần nào đang chiếm nhiều không gian nhất trong APK của bạn, từ đó bạn có thể tối ưu hóa và giảm thiểu kích thước APK để ứng dụng của mình trở nên mỏng nhẹ hơn và tải nhanh hơn.
Mở trang câu hỏi này →
Aflutter build appbundle --release
Bflutter build ios
Cflutter pub publish
Dflutter build apk --release
Lời giải
Để xây dựng một ứng dụng Android dưới định dạng AAB (Google Play format), bạn cần sử dụng lệnh 'flutter build appbundle --release'. Đây là lệnh mặc định được sử dụng để tạo ra một tệp tin appbundle có thể được tải lên Google Play Store. Lệnh này sẽ xây dựng ứng dụng của bạn dưới dạng một tệp tin duy nhất có thể được phân phối trên các thiết bị Android khác nhau. Ngoài ra, bạn cũng có thể sử dụng lệnh này để tạo ra các bản dựng thử nghiệm trước khi tải lên Google Play Store.
Mở trang câu hỏi này →
Aflutter build apk --analyze-size
Bfactory Model.fromJson(Map<String, dynamic> json)
CPerformance Timeline in DevTools
DString interpolation using `${expression}`
Lời giải
Trong Dart, khi bạn muốn tạo một đối tượng từ một bản đồ dữ liệu, bạn thường sử dụng hàm tạo (constructor) đặc biệt. Hàm tạo này được gọi là 'factory' và nó được sử dụng để tạo một đối tượng từ một bản đồ dữ liệu. Ví dụ, nếu bạn có một lớp mô hình (model) tên là 'User', bạn có thể tạo một hàm tạo 'fromJson' để tạo một đối tượng 'User' từ một bản đồ dữ liệu. Hàm tạo này sẽ giúp bạn tạo một đối tượng 'User' từ một bản đồ dữ liệu mà không cần phải viết mã phức tạp. Điều này giúp bạn tạo và quản lý dữ liệu một cách dễ dàng và hiệu quả.
Mở trang câu hỏi này →
ASnackBar
BrunApp()
Cmain.dart
DScaffold
Lời giải
Hàm Flutter chịu trách nhiệm lấy widget gốc và gắn nó vào màn hình để xây dựng cây widget là runApp(). Hàm này được sử dụng để khởi tạo ứng dụng Flutter và gắn widget gốc vào màn hình. Nó được gọi là hàm entry point của ứng dụng, nơi mà ứng dụng bắt đầu xây dựng cây widget. runApp() nhận vào một widget gốc và sử dụng nó để xây dựng cây widget hoàn chỉnh. Ví dụ, bạn có thể sử dụng runApp() như sau: runApp(MyApp()). Trong ví dụ này, MyApp() là widget gốc và runApp() sẽ gắn nó vào màn hình để xây dựng cây widget.
Mở trang câu hỏi này →
AtextInputAction
BListView.builder
CprecacheImage()
DGestureDetector
Lời giải
Để tránh hiện tượng nhấp nháy (flickering) khi hiển thị hình ảnh, Flutter cung cấp một số phương thức giúp tải hình ảnh vào bộ nhớ trước khi chúng được hiển thị. Trong số các phương thức này, `precacheImage()` là một lựa chọn phổ biến. Phương thức này cho phép bạn tải hình ảnh vào bộ nhớ trước khi chúng được sử dụng, giúp giảm thiểu thời gian tải và cải thiện hiệu suất của ứng dụng. Điều này đặc biệt quan trọng khi bạn cần hiển thị nhiều hình ảnh cùng một lúc. Ngoài ra, `precacheImage()` cũng giúp giảm thiểu việc sử dụng tài nguyên hệ thống, giúp ứng dụng của bạn trở nên mượt mà hơn.
Mở trang câu hỏi này →
AprecacheImage()
BtextInputAction
CGestureDetector
DListView.builder
Lời giải
Widget phù hợp nhất để hiển thị danh sách tuyến tính có thể cuộn được, được xây dựng theo yêu cầu là ListView.builder. ListView.builder cho phép bạn xây dựng danh sách một phần tại một thời điểm, giúp tiết kiệm tài nguyên và tăng hiệu suất. Điều này đặc biệt hữu ích khi bạn cần hiển thị một danh sách dài nhưng chỉ cần hiển thị một phần của danh sách tại một thời điểm. Bạn có thể sử dụng ListView.builder để xây dựng danh sách các item có thể cuộn được, và nó sẽ tự động xây dựng các item khi cần.
Mở trang câu hỏi này →
AprecacheImage()
BListView.builder
CtextInputAction
DGestureDetector
Lời giải
Để phát hiện và phản hồi các tương tác chạm như nhấp và kéo mà không cung cấp phản hồi thị giác, bạn cần sử dụng widget Flutter phù hợp. Trong các lựa chọn trên, có một số widget có thể đáp ứng yêu cầu này. Tuy nhiên, widget chính xác nhất được sử dụng để phát hiện và phản hồi các tương tác chạm như nhấp và kéo mà không cung cấp phản hồi thị giác là GestureDetector. GestureDetector là một widget cơ bản trong Flutter, cho phép bạn phát hiện và phản hồi các tương tác chạm như nhấp, kéo, vuốt và xoay. Nó không cung cấp bất kỳ phản hồi thị giác nào, vì vậy bạn có thể sử dụng nó để tạo ra các tương tác chạm mà không cần phải thêm bất kỳ yếu tố thị giác nào.
Mở trang câu hỏi này →
AWidget Inspector
BHot Reload
CDebug (default)
DProfile
Lời giải
Để đo lường jank (làm chậm) với DevTools Performance, bạn cần chọn chế độ chạy gần giống với hiệu suất sản xuất và phù hợp nhất. Trong các lựa chọn, chế độ Profile là gần giống nhất với hiệu suất sản xuất và phù hợp để đo lường jank.
Mở trang câu hỏi này →
AArrange, Act, and Assert.
BPerformance Timeline in DevTools
Cflutter build apk --analyze-size
DString interpolation using `${expression}`
Lời giải
Để đo lường 'jank' hoặc tốc độ khung hình (FPS) của một ứng dụng Flutter, bạn cần sử dụng công cụ phù hợp. Trong số các lựa chọn trên, công cụ phù hợp nhất là Performance Timeline in DevTools. Công cụ này cho phép bạn xem xét và phân tích hiệu suất của ứng dụng Flutter, bao gồm cả tốc độ khung hình. Bạn có thể sử dụng nó để xác định các khu vực cần cải thiện hiệu suất và tối ưu hóa ứng dụng của mình. Ngoài ra, công cụ này còn giúp bạn đo lường thời gian thực hiện các tác vụ và xác định nguyên nhân gây ra sự chậm trễ.
Mở trang câu hỏi này →
AtextInputAction
BprecacheImage()
CGestureDetector
DListView.builder
Lời giải
Để di chuyển focus sang trường nhập liệu tiếp theo khi người dùng nhấn phím 'Enter' hoặc 'Next' trên bàn phím, bạn cần sử dụng thuộc tính widget nào?
Mở trang câu hỏi này →
ANo issue
BRisk of infinite loop: build → setState → build → …
CCompile error
DFlutter bans `StatefulWidget`
Lời giải
Khi gọi trực tiếp `setState` bên trong hàm `build()`, có thể dẫn đến vòng lặp vô hạn. Điều này xảy ra vì khi `build()` được gọi, nó sẽ tạo ra một bản sao mới của widget, sau đó gọi lại hàm `build()` để tạo ra một bản sao mới khác. Nếu trong hàm `build()` này, bạn gọi `setState()`, nó sẽ tạo ra một bản sao mới khác của widget và gọi lại hàm `build()` để tạo ra một bản sao mới khác nữa. Vòng lặp này có thể tiếp tục mãi mãi cho đến khi ứng dụng bị treo. Vì vậy, để tránh vòng lặp vô hạn này, bạn nên gọi `setState()` bên ngoài hàm `build()`.
Mở trang câu hỏi này →
ANo difference
BDebug is faster than release
CProfile disables GPU
DDebug has assertions and overhead — not real-world performance
Lời giải
Khi đo FPS (Frames Per Second) hoặc jank trong Profile/Release (thiết lập Profile/Release) thay vì Debug, có một số lý do quan trọng. Trước hết, thiết lập Debug thường đi kèm với các kiểm tra và chi phí tính toán (assertions và overhead) không phản ánh hiệu suất thực tế của ứng dụng. Điều này có nghĩa là hiệu suất đo được trong Debug không phải là hiệu suất thực tế mà người dùng sẽ gặp phải. Ngoài ra, Profile/Release thường được tối ưu hóa để đo hiệu suất chính xác hơn, trong khi Debug có thể có các tính năng khác như gỡ lỗi và theo dõi lỗi.
Mở trang câu hỏi này →
AUnrelated to debugging
BWidget tree, constraints, overflow
CBuild APK
DOnly theme
Lời giải
Widget Inspector trong DevTools giúp bạn xem xét và kiểm tra các widget trong ứng dụng Android. Nó cho phép bạn xem xét cấu trúc cây widget, các ràng buộc và sự cố tràn. Điều này giúp bạn dễ dàng xác định và sửa lỗi trong ứng dụng của mình. Widget Inspector cũng cho phép bạn xem xét các thuộc tính và hành vi của các widget, giúp bạn hiểu rõ hơn về cách chúng hoạt động. Với Widget Inspector, bạn có thể dễ dàng kiểm tra và sửa lỗi trong ứng dụng của mình, từ đó cải thiện trải nghiệm người dùng.
Mở trang câu hỏi này →
AFaster compilation
BBetter code reuse and UI consistency
CAutomatic navigation
DReduced memory usage
Lời giải
Khi lập trình với Flutter, việc tạo ra các widget có thể giúp bạn đạt được nhiều lợi ích. Một trong những lợi ích quan trọng nhất là việc tái sử dụng mã và duy trì sự nhất quán trong giao diện người dùng. Khi bạn tạo ra một widget, bạn có thể sử dụng nó nhiều lần trong ứng dụng của mình mà không cần phải viết mã lặp lại. Điều này giúp giảm thiểu thời gian lập trình và tăng cường hiệu suất của ứng dụng. Ngoài ra, việc tái sử dụng mã cũng giúp duy trì sự nhất quán trong giao diện người dùng, giúp ứng dụng của bạn trông chuyên nghiệp và dễ sử dụng hơn. Vì vậy, việc lập trình widget trong Flutter là một kỹ thuật quan trọng để đạt được sự tái sử dụng mã và duy trì sự nhất quán trong giao diện người dùng.
Mở trang câu hỏi này →
AManually updating UI elements
BEditing layout XML
CCalling native APIs
DRebuilding UI in response to state changes
Lời giải
Flutter sử dụng mô hình UI phản ứng, giúp ứng dụng của bạn luôn được cập nhật và đồng bộ với trạng thái dữ liệu. Mô hình này cho phép bạn xây dựng ứng dụng có thể tương tác và phản ứng với các thay đổi trong dữ liệu. Trong các lựa chọn trên, hành động nào cho thấy rõ nhất mô hình UI phản ứng của Flutter? Đó là việc xây dựng lại giao diện người dùng khi có thay đổi trong trạng thái dữ liệu. Điều này cho phép ứng dụng của bạn luôn được cập nhật và phản ứng với các thay đổi trong dữ liệu, tạo ra trải nghiệm người dùng mượt mà và liền mạch.
Mở trang câu hỏi này →