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

504/512 câuCòn 8
AAnalysis
BImplementation
CDesign
DTesting
Lời giải
Pha thu thập yêu cầu là bước quan trọng trong quá trình phát triển phần mềm. Trong pha này, người phát triển sẽ thu thập thông tin về yêu cầu của khách hàng, bao gồm cả yêu cầu chức năng và phi chức năng. Yêu cầu chức năng bao gồm các tính năng mà phần mềm cần phải có, trong khi yêu cầu phi chức năng bao gồm các tính chất mà phần mềm cần phải đáp ứng, chẳng hạn như độ tin cậy, bảo mật và hiệu suất. Quá trình thu thập yêu cầu này giúp người phát triển hiểu rõ hơn về nhu cầu của khách hàng và đảm bảo rằng phần mềm được phát triển đáp ứng được các yêu cầu đó.
Mở trang câu hỏi này →
AIntegration test
BWidget test
CUnit test
DSystem test
Lời giải
Loại thử nghiệm nào kiểm tra các chức năng hoặc lớp riêng lẻ? Trong quá trình phát triển phần mềm, việc kiểm tra các chức năng hoặc lớp riêng lẻ là rất quan trọng để đảm bảo rằng từng phần của hệ thống hoạt động chính xác. Loại thử nghiệm này được gọi là thử nghiệm đơn vị (Unit test). Thử nghiệm đơn vị là một loại thử nghiệm kiểm tra các chức năng hoặc lớp riêng lẻ, thường được sử dụng để kiểm tra các hàm, phương thức hoặc lớp trong một chương trình. Mục tiêu của thử nghiệm đơn vị là đảm bảo rằng từng phần của hệ thống hoạt động chính xác và không có lỗi. Điều này giúp phát hiện ra các lỗi sớm và cải thiện chất lượng của hệ thống.
Mở trang câu hỏi này →
AHot restart
BUsing global variables
CLarge widgets
DFine-grained state updates
Lời giải
Để giảm thiểu việc rebuild widget không cần thiết, chúng ta cần hiểu về các khái niệm liên quan đến widget và cách thức hoạt động của chúng trong ứng dụng. Fine-grained state updates là một phương pháp giúp tối ưu hóa quá trình rebuild widget. Phương pháp này liên quan đến việc cập nhật trạng thái của widget một cách tinh tế và có chọn lọc, giúp giảm thiểu số lượng rebuild không cần thiết. Điều này giúp cải thiện hiệu suất của ứng dụng và giảm thiểu thời gian tải trang. Fine-grained state updates cũng giúp giảm thiểu việc sử dụng tài nguyên hệ thống, từ đó giúp ứng dụng trở nên nhanh chóng và ổn định hơn. Vì vậy, phương pháp này là lựa chọn tốt nhất để giảm thiểu việc rebuild widget không cần thiết.
Mở trang câu hỏi này →
488Which command builds a release APK?4 lựa chọn
Aflutter clean
Bflutter run
Cflutter doctor
Dflutter build apk
Lời giải
Để xây dựng một bản phát hành APK trong Flutter, bạn cần sử dụng lệnh 'flutter build apk'. Lệnh này sẽ tạo ra một bản phát hành APK có thể được tải xuống và cài đặt trên thiết bị di động. Lệnh này khác với 'flutter run', vì 'flutter run' chỉ chạy ứng dụng trên thiết bị di động hoặc máy ảo, nhưng không tạo ra một bản phát hành APK. Ngoài ra, 'flutter clean' được sử dụng để xóa các tệp tạm thời được tạo ra trong quá trình xây dựng, trong khi 'flutter doctor' được sử dụng để kiểm tra xem Flutter đã được cấu hình đúng chưa. Vì vậy, nếu bạn muốn tạo một bản phát hành APK, bạn cần sử dụng lệnh 'flutter build apk'.
Mở trang câu hỏi này →
ADevTools
BInspector
CEmulator
DHot reload
Lời giải
Để giúp debug các yêu cầu mạng trong Flutter, bạn có thể sử dụng công cụ DevTools. DevTools là một công cụ mạnh mẽ giúp bạn theo dõi và debug các hoạt động của ứng dụng Flutter của mình. Trong đó, bạn có thể xem các yêu cầu mạng đang được thực hiện, bao gồm cả các yêu cầu GET và POST. Ngoài ra, bạn cũng có thể xem các phản hồi từ server và các lỗi xảy ra trong quá trình gửi yêu cầu. Điều này giúp bạn dễ dàng tìm ra nguyên nhân của các vấn đề và sửa lỗi nhanh chóng. Vì vậy, DevTools là công cụ cần thiết để giúp bạn debug các yêu cầu mạng trong Flutter.
Mở trang câu hỏi này →
AFix layout
BSpeed up builds
CPrevent memory leaks
DImprove UI
Lời giải
Animations trong ứng dụng thường tạo ra các đối tượng tạm thời, nếu không được xóa bỏ đúng cách sẽ dẫn đến tình trạng "nhớ" bộ nhớ, gây ra hiện tượng "memory leaks". Điều này có thể khiến ứng dụng trở nên chậm chạp và thậm chí bị treo. Vì vậy, việc xóa bỏ animations một cách hợp lý là rất quan trọng để đảm bảo ứng dụng hoạt động trơn tru và hiệu suất cao.
Mở trang câu hỏi này →
AsaveInt()
BputInt()
CsetInt()
DwriteInt()
Lời giải

Đáp án đúng: C. Trong Flutter, gói shared_preferences cung cấp các phương thức đặt giá trị theo kiểu dữ liệu: setInt, setString, setBool, setDouble và setStringList, đi kèm các phương thức đọc getInt, getString... Vì vậy để lưu một số nguyên ta gọi prefs.setInt('key', value). Cần phân biệt với SharedPreferences NATIVE của Android, nơi API là editor.putInt() - đó chính là bẫy của phương án B. Các phương án saveInt() (A) và writeInt() (D) không tồn tại trong cả hai nền tảng. Lưu ý các phương thức set này trả về Future<bool> nên thường được await.

Mở trang câu hỏi này →
492What is the purpose of the Flutter SDK?4 lựa chọn
ATo store application data permanently
BTo provide tools and libraries for Flutter development
CTo deploy applications directly to app stores
DTo replace the operating system of a device
Lời giải
Đáp án đúng: B. Flutter SDK là bộ công cụ phát triển gồm framework widget, công cụ dòng lệnh (flutter run, flutter build), trình biên dịch Dart, engine kết xuất và các thư viện hỗ trợ. Nói ngắn gọn, nó cung cấp CÔNG CỤ VÀ THƯ VIỆN để lập trình viên xây dựng ứng dụng Flutter. Phương án A nhầm sang vai trò của các giải pháp lưu trữ như shared_preferences, Hive hay sqflite; phương án C sai vì việc phát hành lên cửa hàng ứng dụng do các công cụ và quy trình riêng của Google Play hoặc App Store đảm nhiệm; phương án D vô lý vì SDK chạy trên hệ điều hành chứ không thay thế nó.
Mở trang câu hỏi này →
493Why is logout functionality important?4 lựa chọn
AFree memory
BEnd user session securely
CImprove UI
DChange theme
Lời giải
Đáp án đúng: B. Chức năng đăng xuất tồn tại vì lý do BẢO MẬT: nó kết thúc phiên làm việc một cách an toàn, xoá token đang lưu, xoá thông tin nhạy cảm khỏi bộ nhớ và bộ nhớ cục bộ, đồng thời báo cho máy chủ thu hồi phiên. Nếu thiếu, người dùng tiếp theo trên cùng thiết bị vẫn truy cập được tài khoản cũ. Giải phóng bộ nhớ (A) chỉ là hệ quả phụ không đáng kể; cải thiện giao diện (C) và đổi giao diện màu sắc (D) hoàn toàn không liên quan tới mục đích của thao tác đăng xuất.
Mở trang câu hỏi này →
Aasync
Bawait
Cfuture
Ddelay
Lời giải
Đáp án đúng: B. Từ khoá await tạm dừng việc thực thi hàm hiện tại cho tới khi Future hoàn tất rồi trả về giá trị của Future đó, giúp viết mã bất đồng bộ theo phong cách tuần tự dễ đọc. Nó chỉ dùng được bên trong hàm đã được đánh dấu async, và đó chính là vai trò của từ khoá async (A): đánh dấu hàm trả về Future chứ bản thân nó không tạm dừng gì cả. Future (C) là KIỂU dữ liệu biểu diễn một giá trị sẽ có trong tương lai, không phải từ khoá điều khiển; còn delay (D) không phải từ khoá của Dart - liên quan là hàm Future.delayed.
Mở trang câu hỏi này →
Asqflite
BFirebase Authentication
CProvider
Dhttp
Lời giải
Đáp án đúng: B. Firebase Authentication là dịch vụ xác thực sẵn có, hỗ trợ đăng nhập bằng email/mật khẩu, số điện thoại và các nhà cung cấp như Google, Facebook, Apple; nó quản lý token, làm mới phiên và trạng thái đăng nhập giúp lập trình viên, nên đơn giản hoá đáng kể việc triển khai xác thực trong Flutter. Các phương án còn lại là những gói phục vụ mục đích khác: sqflite (A) là cơ sở dữ liệu SQLite cục bộ, Provider (C) là giải pháp quản lý trạng thái, http (D) là thư viện gọi API - không gói nào tự thân cung cấp cơ chế xác thực.
Mở trang câu hỏi này →
ARequires separate codebases for Android and iOS
BUses JavaScript as its primary language
CEnables building apps from a single codebase for multiple platforms
DOnly supports mobile platforms
Lời giải
Đáp án đúng: C. Ưu thế lớn nhất của Flutter là cho phép xây dựng ứng dụng từ MỘT bộ mã nguồn duy nhất rồi biên dịch ra nhiều nền tảng: Android, iOS, web, Windows, macOS và Linux, nhờ engine tự vẽ giao diện nên hiển thị nhất quán giữa các nền tảng. Phương án A mô tả cách phát triển native truyền thống, đúng là điều Flutter khắc phục; phương án B sai vì Flutter dùng Dart chứ không phải JavaScript; phương án D sai vì từ phiên bản 2 trở đi Flutter đã hỗ trợ chính thức cả web và desktop, không giới hạn ở di động.
Mở trang câu hỏi này →
AXML
BCSV
CJSON
DBinary
Lời giải
Đáp án đúng: C. JSON là định dạng trao đổi dữ liệu phổ biến nhất trong các REST API hiện nay vì gọn nhẹ, dễ đọc với con người, ánh xạ tự nhiên sang cấu trúc đối tượng của hầu hết ngôn ngữ và được hỗ trợ sẵn ở cả trình duyệt lẫn máy chủ. Trong Flutter, dữ liệu JSON được xử lý bằng dart:convert với jsonDecode và jsonEncode. XML (A) từng thống trị thời SOAP nhưng nay ít dùng vì dài dòng; CSV (B) chỉ phù hợp dữ liệu bảng phẳng; còn định dạng nhị phân (D) chỉ dùng trong các trường hợp đặc thù cần hiệu năng cao như gRPC hay Protobuf.
Mở trang câu hỏi này →
AScreens are arranged in a grid layout
BScreens are managed using a stack (push and pop)
CScreens are loaded randomly
DScreens are replaced automatically without control
Lời giải
Đáp án đúng: B. Navigator quản lý các màn hình theo cấu trúc NGĂN XẾP: Navigator.push đặt một route mới lên đỉnh ngăn xếp, Navigator.pop lấy route trên cùng ra và quay lại màn hình trước đó. Chính mô hình này khiến nút Back của hệ thống hoạt động đúng như người dùng kỳ vọng, và cho phép truyền dữ liệu trả về khi pop. Phương án A nhầm sang cách bố trí widget dạng lưới; phương án C mô tả hành vi ngẫu nhiên không tồn tại; phương án D sai vì lập trình viên hoàn toàn kiểm soát việc đẩy và gỡ route.
Mở trang câu hỏi này →
ACannot persist data
BOnly works on web
CNot suitable for large or complex data
DRequires SQL queries
Lời giải
Đáp án đúng: C. SharedPreferences chỉ được thiết kế để lưu các cặp khoá - giá trị nhỏ, kiểu nguyên thuỷ như cờ đã đăng nhập, chế độ sáng tối, ngôn ngữ đã chọn. Toàn bộ nội dung được nạp vào bộ nhớ và ghi ra một tệp phẳng, nên nó KHÔNG phù hợp với dữ liệu lớn, có cấu trúc phức tạp hay cần truy vấn - những trường hợp đó phải dùng sqflite hoặc Hive. Phương án A sai vì dữ liệu vẫn được lưu bền qua các lần mở ứng dụng; phương án B sai vì gói hoạt động trên mọi nền tảng; phương án D sai vì SharedPreferences không dùng SQL.
Mở trang câu hỏi này →
ALong forms
BMinimal validation
CClear labels and feedback
DHidden errors
Lời giải
Đáp án đúng: C. Nguyên tắc thiết kế nâng cao trải nghiệm biểu mẫu là nhãn rõ ràng và phản hồi tức thời: mỗi trường có nhãn dễ hiểu, gợi ý định dạng, và khi nhập sai thì thông báo lỗi hiện ngay cạnh trường với hướng dẫn cách sửa. Trong Flutter, InputDecoration cùng validator của TextFormField phục vụ đúng mục đích này. Biểu mẫu quá dài (A) làm người dùng bỏ cuộc; kiểm tra dữ liệu sơ sài (B) đẩy lỗi xuống phía sau; ẩn thông báo lỗi (D) khiến người dùng không biết phải sửa gì - cả ba đều làm giảm tính khả dụng.
Mở trang câu hỏi này →
AStoring passwords locally
BEncrypting credentials
CUsing HTTP
DHardcoding tokens
Lời giải
Đáp án đúng: B. Mã hoá thông tin xác thực - dùng HTTPS khi truyền, băm mật khẩu phía máy chủ, lưu token trong kho an toàn của hệ điều hành như flutter_secure_storage - là thực hành cốt lõi để bảo vệ danh tính người dùng. Ngược lại, lưu mật khẩu ở dạng thô trên thiết bị (A) tạo ra điểm rò rỉ trực tiếp; dùng HTTP không mã hoá (C) khiến thông tin bị nghe lén trên đường truyền; và nhúng cứng token vào mã nguồn (D) là lỗi nghiêm trọng vì token sẽ lộ ngay khi ứng dụng bị dịch ngược.
Mở trang câu hỏi này →
502What does the Padding widget do?4 lựa chọn
AAdds space inside a widget
BAdds space between widgets
CAligns widgets
DControls widget size
Lời giải
Đáp án đúng: A. Padding là widget bọc quanh một widget con và chèn thêm khoảng trống Ở BÊN TRONG nó, giữa biên của Padding và widget con, theo giá trị EdgeInsets được truyền vào. Nói cách khác nó tạo lề trong cho phần nội dung mà nó bao. Phương án B mô tả khoảng cách GIỮA các widget anh em, thường đạt được bằng SizedBox, Spacer hoặc thuộc tính spacing của Row/Column; phương án C là việc của Align hay Center; phương án D thuộc về SizedBox, ConstrainedBox hoặc thuộc tính width và height của Container.
Mở trang câu hỏi này →
AReduce UI size
BImprove maintainability
CIncrease speed
DAvoid widgets
Lời giải
Đáp án đúng: B. Khi logic điều hướng được tổ chức tốt - đặt tên route tập trung, tách phần định nghĩa route ra khỏi widget, dùng router có cấu trúc - thì việc thêm màn hình mới, đổi luồng đi hay xử lý deep link đều gọn gàng và ít gây lỗi lan truyền. Đó chính là cải thiện khả năng BẢO TRÌ. Phương án A và C nhầm sang kích thước giao diện và tốc độ chạy, vốn không phụ thuộc vào cách tổ chức route; phương án D vô nghĩa vì điều hướng luôn làm việc với các widget màn hình chứ không nhằm né tránh chúng.
Mở trang câu hỏi này →
ADynamic typing
BHot reload
CNull safety
DAsynchronous execution
Lời giải
Đáp án đúng: C. Null safety, có từ Dart 2.12, làm cho mọi kiểu mặc định KHÔNG nhận null; muốn cho phép null phải khai báo tường minh bằng dấu chấm hỏi như String?. Nhờ đó trình biên dịch phát hiện ngay lúc dịch những chỗ có thể truy cập vào biến null, thay vì để lỗi bùng ra lúc chạy. Kiểu động (A) làm điều ngược lại là trì hoãn kiểm tra tới lúc chạy; hot reload (B) chỉ giúp nạp nhanh thay đổi mã vào ứng dụng đang chạy; còn thực thi bất đồng bộ (D) liên quan tới Future và Stream, không dính dáng tới việc kiểm soát giá trị null.
Mở trang câu hỏi này →