Kotlin phân biệt kiểu có thể null và không thể null nhằm mục đích gì?
A.Cho phép biến nhận nhiều kiểu dữ liệu khác nhau
B.Tăng tốc độ khởi tạo đối tượng lúc chạy
C.Giảm bộ nhớ mà đối tượng chiếm giữ
D.Đưa lỗi null từ lúc chạy về lúc biên dịch
Đáp án: D
Kotlin đưa lỗi null từ lúc chạy về lúc biên dịch. String không nhận null, còn String? thì có, và trình biên dịch bắt buộc xử lý trường hợp null trước khi gọi thành viên. Đây là lý do chính khiến Android chuyển từ Java sang Kotlin.
val chỉ cấm gán lại biến, không khoá nội dung. val list = mutableListOf(1) vẫn cho list.add(2). Muốn nội dung bất biến thì phải chọn kiểu danh sách chỉ đọc, và đó là hai khái niệm khác nhau.
Data class sinh sẵn equals và hashCode theo giá trị, toString, copy và các hàm tách thành phần. Nhờ đó hai đối tượng cùng nội dung được coi là bằng nhau, điều quyết định cho việc so sánh state trong giao diện.
Xoay màn hình khiến Activity bị tạo lại và mất dữ liệu. Cách xử lý đúng?
A.Giữ dữ liệu trong ViewModel sống qua lần tạo lại
B.Khoá hướng màn hình để Activity không bị tạo lại
C.Đọc lại toàn bộ dữ liệu từ server sau khi xoay
D.Lưu dữ liệu vào biến tĩnh của lớp
Đáp án: A
Dùng ViewModel: nó sống qua các lần Activity bị tạo lại do thay đổi cấu hình, nên dữ liệu và trạng thái màn hình còn nguyên. Khoá hướng màn hình chỉ né được một trường hợp trong nhiều trường hợp cấu hình thay đổi.
Intent tường minh và Intent ngầm định khác nhau ở đâu?
A.Tường minh chỉ mở được thành phần trong cùng ứng dụng
B.Tường minh chạy đồng bộ còn ngầm định chạy bất đồng bộ
C.Ngầm định không truyền được dữ liệu kèm theo
D.Tường minh chỉ đích danh, ngầm định để hệ thống chọn
Đáp án: D
Intent tường minh chỉ đích danh thành phần cần mở, thường dùng trong nội bộ ứng dụng. Intent ngầm định mô tả hành động như chia sẻ hay mở liên kết, và hệ thống chọn ứng dụng khai báo xử lý được hành động đó.
Hàm đánh dấu Composable khác hàm thường ở điểm nào?
A.Nó trả về một đối tượng View để gắn vào cây giao diện
B.Nó luôn chạy trên background thread để không chặn giao diện
C.Nó chỉ được gọi đúng một lần trong vòng đời màn hình
D.Nó mô tả giao diện và được gọi lại khi state đổi
Đáp án: D
Hàm Composable mô tả giao diện theo state hiện tại và được gọi lại khi state nó đọc thay đổi. Trình biên dịch thêm phần theo dõi để chỉ chạy lại đúng những hàm phụ thuộc dữ liệu đã đổi, thay vì cả cây.
Biến đếm khai báo bằng var thường trong Composable không làm giao diện cập nhật. Vì sao?
A.Biến thường không được theo dõi nên không vẽ lại
B.Cần khai báo biến ở cấp lớp thay vì trong hàm
C.Biến bị đặt lại vì hàm Composable chạy trên thread khác
D.Kotlin không cho phép thay đổi biến trong hàm Composable
Đáp án: A
Giao diện chỉ vẽ lại khi giá trị được theo dõi thay đổi. Biến thường không nằm trong hệ thống theo dõi nên không có gì báo cho Compose biết cần chạy lại, và giá trị cũng bị đặt lại ở lần chạy sau.
Hiển thị danh sách dài trong Compose nên dùng thành phần nào?
A.Danh sách lười chỉ dựng phần thấy được
B.Hộp chứa với các phần tử xếp chồng
C.Cột thường kết hợp với khả năng cuộn
D.Lưới có số cột cố định
Đáp án: A
Dùng danh sách lười vì nó chỉ dựng các mục đang hiển thị. Cột thường kèm cuộn sẽ dựng toàn bộ phần tử ngay lập tức, nên với vài trăm mục là màn hình khựng khi mở và tốn bộ nhớ suốt vòng đời.
suspend đánh dấu hàm có thể tạm dừng và tiếp tục mà không chặn thread. Trong lúc chờ, thread được trả lại cho việc khác. Nó không nói gì về thread nào sẽ chạy, việc đó do bộ điều phối quyết định.
Vì sao chuỗi hiển thị nên đặt trong tệp tài nguyên thay vì viết thẳng trong mã?
A.Để chuỗi không bị đọc được khi dịch ngược
B.Để giảm dung lượng gói cài đặt
C.Để tăng tốc độ hiển thị văn bản
D.Để dịch được và sửa ở một chỗ
Đáp án: D
Tài nguyên cho phép dịch theo ngôn ngữ thiết bị mà không cần điều kiện trong mã, và cho phép sửa nội dung ở một chỗ. Hệ thống tự chọn tệp phù hợp theo ngôn ngữ, vùng, mật độ màn hình và chế độ tối.
Tệp cấu hình Gradle của module ứng dụng dùng để làm gì?
A.Lưu khoá ký ứng dụng dùng khi phát hành lên cửa hàng
B.Chứa chuỗi hiển thị và tài nguyên giao diện
C.Khai báo các màn hình và quyền của ứng dụng
D.Khai báo phụ thuộc và cấu hình đóng gói
Đáp án: D
Tệp cấu hình Gradle khai báo phụ thuộc và cách đóng gói: phiên bản tối thiểu, phiên bản đích, các biến thể build, tuỳ chọn rút gọn mã. Còn quyền và thành phần ứng dụng thì khai báo trong tệp khai báo.
Điểm khác biệt cốt lõi giữa hệ view XML và Compose là gì?
A.Compose chỉ chạy được trên các thiết bị đời mới
B.Một bên ra lệnh cập nhật, một bên khai báo
C.Hệ view cũ không hỗ trợ hoạt ảnh phức tạp
D.Compose không dùng được với thư viện Android hiện có
Đáp án: B
Hệ view cũ theo hướng ra lệnh: tìm view rồi gán giá trị mới. Compose theo hướng khai báo: mô tả giao diện theo state và để hệ thống tự cập nhật phần thay đổi. Khác biệt này đổi cách tổ chức toàn bộ mã màn hình.
RecyclerView tái dùng view của các mục đã cuộn qua nhằm mục đích gì?
A.Giảm dung lượng ứng dụng khi đóng gói
B.Tránh tạo và huỷ view liên tục khi cuộn
C.Tự động lưu vị trí cuộn khi xoay màn hình
D.Cho phép danh sách hiển thị nhiều kiểu bố cục
Đáp án: B
Tạo view là thao tác đắt, nên tái dùng view cũ và chỉ gán dữ liệu mới giúp danh sách giữ khung hình khi cuộn nhanh. Đây cũng là lý do phải cẩn thận với state cục bộ trong mục, vì view cũ có thể mang trạng thái sang mục khác.
Fragment là một phần giao diện nằm bên trong Activity, có vòng đời riêng và ghép lại được. Nhờ đó cùng một phần giao diện dùng được cho điện thoại và cho bố cục hai cột trên máy tính bảng.
A.Khi thông báo cần kèm một hành động như hoàn tác
B.Khi cần thông báo hiển thị lâu hơn năm giây
C.Khi thông báo phải hiện cả khi ứng dụng ở nền
D.Khi cần hiển thị nhiều dòng nội dung dài
Đáp án: A
Dùng snack bar khi thông báo cần một hành động đi kèm như hoàn tác, và khi nó thuộc về màn hình hiện tại. Toast chỉ hiển thị chữ, không tương tác được, và trên các phiên bản Android mới còn bị hạn chế.
Vì sao không nên để lệnh ghi nhật ký chi tiết trong bản phát hành?
A.Hệ điều hành từ chối chạy ứng dụng có ghi nhật ký
B.Nhật ký có thể lộ dữ liệu nhạy cảm
C.Nhật ký làm tăng đáng kể dung lượng gói cài đặt
D.Cửa hàng từ chối bản có lệnh ghi nhật ký
Đáp án: B
Nhật ký trên thiết bị đọc được, nên in token, thông tin cá nhân hay nội dung phản hồi API ra đó là rò rỉ thật. Ngoài ra ghi nhật ký dày đặc trong vòng lặp hoặc khi cuộn cũng tốn tài nguyên.
Biểu thức when trong Kotlin khác câu lệnh switch ở điểm nào?
A.Nó trả về giá trị và nhận điều kiện tuỳ ý
B.Nó chỉ so khớp được với chuỗi và số nguyên
C.Nó không cho phép nhiều điều kiện trong một nhánh
D.Nó bắt buộc phải có nhánh mặc định trong mọi trường hợp
Đáp án: A
when là biểu thức trả về giá trị và nhận điều kiện tuỳ ý, không chỉ so khớp hằng số: kiểm tra kiểu, kiểm tra khoảng, hay bất kỳ biểu thức boolean nào. Kết hợp với sealed class, nó còn được kiểm tra đủ nhánh lúc biên dịch.
Hàm mở rộng trong Kotlin hoạt động theo cơ chế nào?
A.Tạo lớp con kế thừa lớp được mở rộng
B.Ghi đè phương thức cùng tên của lớp gốc
C.Biên dịch thành hàm tĩnh nhận đối tượng
D.Thêm phương thức mới vào lớp gốc lúc chạy
Đáp án: C
Hàm mở rộng được biên dịch thành hàm tĩnh nhận đối tượng làm tham số. Vì thế nó không thấy thành viên riêng tư, không tham gia đa hình, và bị phương thức thành viên cùng tên che khuất.
Quyền khai báo trong tệp khai báo ứng dụng. Với các quyền nhạy cảm, khai báo là chưa đủ: từ Android 6 trở đi còn phải xin lúc chạy và người dùng có thể từ chối.
Phiên bản tối thiểu và phiên bản đích của ứng dụng khác nhau thế nào?
A.Tối thiểu chỉ ảnh hưởng tới hiệu năng của ứng dụng
B.Đích quyết định bộ API dùng được khi viết mã
C.Cả hai đều quyết định máy nào cài được ứng dụng
D.Tối thiểu quyết định máy nào cài được
Đáp án: D
Phiên bản tối thiểu quyết định máy nào cài được ứng dụng. Phiên bản đích nói rằng ứng dụng đã được kiểm chứng với hành vi của phiên bản đó, và nâng nó lên kéo theo phải tuân thủ các thay đổi hành vi mới.
Toàn bộ màn hình Compose vẽ lại khi chỉ một ô nhập thay đổi. Nguyên nhân?
A.Ô nhập không được bọc trong thành phần ghi nhớ
B.Thiếu khoá cho các thành phần trong danh sách
C.State được đọc ở hàm cấp cao quá
D.Compose luôn vẽ lại toàn bộ cây mỗi lần state đổi
Đáp án: C
Phạm vi vẽ lại là hàm đọc state. Đọc giá trị ở hàm cấp cao rồi truyền xuống khiến cả cây con chạy lại; đọc ngay tại nơi dùng, hoặc truyền hàm trả về giá trị thay vì giá trị, sẽ thu hẹp phạm vi.
Gọi API ngay trong thân hàm Composable gây vấn đề gì?
A.Lời gọi API bị chặn cho tới khi giao diện vẽ xong
B.Kết quả API không thể lưu vào state
C.Trình biên dịch từ chối biên dịch đoạn mã đó
D.API bị gọi lại mỗi lần hàm chạy lại
Đáp án: D
Hàm Composable chạy lại nhiều lần và không đoán trước được, nên lời gọi API sẽ lặp lại theo. Tác dụng phụ phải nằm trong các hàm hiệu ứng chuyên dụng, nơi có khoá phụ thuộc để kiểm soát thời điểm chạy.
Coroutine khởi chạy trong ViewModel nên dùng phạm vi nào?
A.Phạm vi gắn với ViewModel, tự huỷ khi bị xoá
B.Phạm vi gắn với Activity đang hiển thị
C.Phạm vi tạo mới trong mỗi hàm cần dùng
D.Phạm vi toàn cục để công việc không bị gián đoạn
Đáp án: A
Dùng phạm vi gắn với ViewModel: mọi coroutine trong đó tự huỷ khi ViewModel bị xoá. Phạm vi toàn cục không bao giờ bị huỷ, nên nó giữ tham chiếu và tiếp tục chạy sau khi màn hình đã đóng.
A.StateFlow luôn có giá trị hiện tại và bỏ giá trị trùng
B.StateFlow chạy trên main thread còn SharedFlow thì không
C.SharedFlow chỉ cho phép một người nghe duy nhất
D.SharedFlow không phát được giá trị mới sau khi tạo
Đáp án: A
StateFlow mô tả trạng thái: luôn có một giá trị hiện tại, người nghe mới nhận ngay giá trị mới nhất, và giá trị trùng với giá trị trước bị bỏ qua. SharedFlow mô tả sự kiện: không có giá trị hiện tại và không bỏ trùng.
Vì sao ViewModel không nên tham chiếu tới Context của Activity?
A.ViewModel chạy trên một tiến trình riêng biệt
B.ViewModel sống lâu hơn nên giữ luôn Activity cũ
C.Context không truyền được qua hàm dựng của ViewModel
D.Context không dùng được từ background thread
Đáp án: B
ViewModel sống qua các lần Activity bị tạo lại, nên giữ tham chiếu tới Activity sẽ giữ luôn Activity cũ trong bộ nhớ sau khi xoay màn hình. Khi cần Context thì dùng Context cấp ứng dụng.
Truy vấn Room trả về Flow có lợi thế gì so với trả về danh sách?
A.Truy vấn tự động chạy trên main thread an toàn
B.Giao diện tự cập nhật khi dữ liệu trong bảng đổi
C.Truy vấn chạy nhanh hơn nhờ được lưu đệm
D.Không cần khai báo kiểu trả về trong lớp truy cập
Đáp án: B
Truy vấn trả về Flow được Room phát lại mỗi khi bảng liên quan thay đổi, nên giao diện tự cập nhật sau khi ghi mà không phải gọi lại truy vấn. Đây là cách làm cho cơ sở dữ liệu trở thành nguồn sự thật duy nhất.
Tác vụ phải chạy tin cậy kể cả khi ứng dụng bị đóng nên dùng gì?
A.Bộ đếm giờ đặt lại mỗi lần mở ứng dụng
B.Bộ lập lịch công việc của hệ thống
C.Background thread tạo trực tiếp trong Activity
D.Coroutine trong phạm vi toàn cục của ứng dụng
Đáp án: B
Dùng bộ lập lịch công việc của hệ thống. Công việc được lưu lại và chạy khi đủ điều kiện như có mạng hoặc đang sạc, sống qua việc ứng dụng bị đóng và cả khi thiết bị khởi động lại.
Tiêm phụ thuộc giải quyết vấn đề gì trong ứng dụng Android?
A.Tăng tốc độ khởi động của ứng dụng
B.Tách việc tạo đối tượng khỏi nơi sử dụng
C.Tự động quản lý vòng đời của mọi đối tượng
D.Giảm số lượng lớp cần viết trong dự án
Đáp án: B
Nó tách việc tạo đối tượng khỏi nơi dùng, nên phụ thuộc thay được khi kiểm thử và vòng đời của đối tượng được khai báo ở một chỗ. Không có nó, lớp tự tạo phụ thuộc và kiểm thử buộc phải gọi mạng hay cơ sở dữ liệu thật.
Người dùng từ chối quyền hai lần trên Android thì lời gọi xin quyền tiếp theo ra sao?
A.Ứng dụng bị hệ thống tạm khoá quyền trong một ngày
B.Hộp thoại vẫn hiện kèm tuỳ chọn không hỏi lại
C.Không hiện hộp thoại, trả về từ chối ngay
D.Quyền được cấp tự động ở mức hạn chế
Đáp án: C
Lời gọi trả về từ chối ngay mà không hiện hộp thoại. Ứng dụng phải nhận ra trạng thái này, giải thích vì sao cần quyền và đưa nút mở phần cài đặt ứng dụng, đồng thời vẫn cho dùng các phần không cần quyền đó.
Nguồn rò bộ nhớ kinh điển nhất trên Android là gì?
A.Nạp ảnh từ mạng thay vì từ tài nguyên
B.Tạo quá nhiều đối tượng trong một vòng lặp
C.Dùng danh sách thay vì mảng cho dữ liệu lớn
D.Đối tượng sống lâu giữ tham chiếu tới Activity
Đáp án: D
Một đối tượng sống lâu như singleton, biến tĩnh, listener hay coroutine không huỷ giữ tham chiếu tới Activity. Vì Activity bị tạo lại mỗi lần xoay màn hình, mỗi lần như vậy lại thêm một bản cũ không được giải phóng.
Thông báo ứng dụng không phản hồi trên Android xuất hiện khi nào?
A.Khi ứng dụng gọi quá nhiều yêu cầu mạng cùng lúc
B.Khi main thread bị chặn quá lâu
C.Khi ứng dụng chạy nền quá thời gian cho phép
D.Khi ứng dụng dùng quá nhiều bộ nhớ cho phép
Đáp án: B
Khi main thread bị chặn quá lâu nên không xử lý được sự kiện đầu vào trong thời hạn hệ thống cho phép. Nguyên nhân thường là đọc ghi tệp, truy vấn cơ sở dữ liệu hoặc phân tích dữ liệu lớn chạy đồng bộ trên main thread.
Bật rút gọn mã cho bản phát hành làm ứng dụng đóng khi phân tích JSON. Nguyên nhân?
A.Rút gọn làm hỏng định dạng chuỗi JSON nhận về
B.Bản phát hành không có quyền truy cập mạng
C.Tên lớp và trường bị đổi khi rút gọn
D.Thư viện phân tích chỉ hoạt động ở chế độ gỡ lỗi
Đáp án: C
Rút gọn đổi tên lớp và trường, trong khi thư viện phân tích ánh xạ theo tên lúc chạy. Phải khai báo luật giữ tên cho các lớp mô hình dữ liệu, hoặc dùng thư viện sinh mã lúc biên dịch để không phụ thuộc tên.
Cách hiệu quả nhất để giảm dung lượng tải về của ứng dụng Android là gì?
A.Gỡ bớt ngôn ngữ được hỗ trợ trong ứng dụng
B.Nén lại toàn bộ ảnh trong thư mục tài nguyên
C.Phát hành app bundle thay cho tệp cài chung
D.Chuyển mã Java sang Kotlin để giảm số dòng
Đáp án: C
Phát hành app bundle: cửa hàng sinh bản cài riêng theo kiến trúc, mật độ màn hình và ngôn ngữ của từng máy. Kết hợp với rút gọn mã và loại tài nguyên không dùng, đây là hai bước cắt được nhiều nhất.
Truyền cả đối tượng dữ liệu lớn giữa các màn hình gây vấn đề gì?
A.Dữ liệu bị mã hoá nên màn hình đích không đọc được
B.Hệ thống từ chối mở màn hình mới
C.Vượt giới hạn dữ liệu truyền và làm ứng dụng đóng
D.Màn hình đích luôn nhận được bản sao rỗng
Đáp án: C
Có giới hạn dung lượng cho dữ liệu truyền giữa các thành phần, và vượt quá sẽ làm ứng dụng đóng với thông báo khó hiểu. Cách đúng là truyền định danh rồi để màn hình đích đọc dữ liệu từ nguồn chung.
Kiểm thử đơn vị cho ViewModel nên thay thế phần nào?
A.Hệ thống tài nguyên chuỗi của Android
B.Các hàm chuyển đổi dữ liệu thuần
C.Repository và bộ điều phối coroutine
D.Toàn bộ lớp giao diện của màn hình đó
Đáp án: C
Thay repository bằng bản giả lập để không phụ thuộc mạng, và thay bộ điều phối bằng bản kiểm thử để kiểm soát thời gian. Nhờ đó kiểm thử chạy trong vài mili giây và cho kết quả ổn định.
Đổi thứ tự padding và background trong chuỗi modifier dẫn tới điều gì?
A.Không có gì thay đổi vì thứ tự không quan trọng
B.Ứng dụng báo lỗi khi dựng giao diện
C.Vùng được tô màu khác nhau
D.Chỉ vùng chạm thay đổi còn hiển thị giữ nguyên
Đáp án: C
Modifier áp theo thứ tự khai báo. Đặt padding trước background thì phần đệm nằm ngoài vùng màu; đặt background trước padding thì màu phủ cả phần đệm. Vùng chạm cũng đổi theo, nên thứ tự là quyết định thật sự chứ không phải tuỳ ý.
Điều hướng trong Compose nên truyền dữ liệu giữa màn hình bằng cách nào?
A.Lưu vào biến toàn cục rồi màn hình sau đọc
B.Truyền định danh, màn hình đích tự đọc dữ liệu
C.Dùng ViewModel dùng chung cho toàn ứng dụng
D.Truyền cả đối tượng qua đối số điều hướng
Đáp án: B
Truyền định danh trong đường dẫn và để màn hình đích đọc dữ liệu từ repository. Nhờ vậy deep link mở thẳng được màn hình, và khi tiến trình bị đóng thì hệ thống dựng lại màn hình từ đối số đã lưu.
Danh sách vài nghìn bản ghi từ server nên xử lý thế nào?
A.Giới hạn danh sách ở một trăm bản ghi đầu tiên
B.Phân trang và chỉ giữ phần đang cần
C.Tải hết một lần rồi lọc trong bộ nhớ
D.Tải hết rồi lưu vào tệp JSON trên thiết bị
Đáp án: B
Dùng phân trang: tải theo trang, chỉ giữ phần cần trong bộ nhớ, và tự tải thêm khi người dùng cuộn gần cuối. Kết hợp với cache cục bộ thì mở lại màn hình là tức thì và ứng dụng vẫn dùng được khi mạng chập chờn.
DataStore được khuyến nghị thay cho SharedPreferences vì lý do gì?
A.Dữ liệu được mã hoá mặc định trên thiết bị
B.API bất đồng bộ và an toàn hơn về luồng
C.Đồng bộ tự động lên tài khoản người dùng
D.Cho phép truy vấn dữ liệu như cơ sở dữ liệu
Đáp án: B
DataStore có API bất đồng bộ dựa trên luồng dữ liệu, xử lý lỗi rõ ràng và tránh được các lời gọi đồng bộ chặn main thread vốn là nguồn báo ứng dụng không phản hồi. Nó vẫn không mã hoá, nên token phải nằm ở kho an toàn.
Làm mới access token khi API trả về 401 nên đặt ở đâu?
A.Ở ViewModel của màn hình đang mở
B.Ở bộ lập lịch chạy nền định kỳ
C.Ở mỗi hàm gọi API trong repository
D.Ở tầng client mạng, dùng chung cho mọi lời gọi
Đáp án: D
Đặt ở tầng client mạng: bắt phản hồi 401, làm mới token rồi phát lại đúng yêu cầu đó một lần. Phải khoá để nhiều yêu cầu song song chỉ kích hoạt một lượt làm mới, nếu không sẽ có chuỗi làm mới chồng chéo.
Danh sách ảnh làm ứng dụng bị đóng vì thiếu bộ nhớ. Nguyên nhân chính?
A.Ảnh giải mã ở kích thước gốc dù hiển thị nhỏ
B.Thiếu khoá ổn định cho từng mục danh sách
C.Ảnh được tải lại nhiều lần từ server
D.Danh sách giữ quá nhiều mục trong bộ nhớ
Đáp án: A
Bộ nhớ ảnh tính theo kích thước điểm ảnh sau giải mã, xấp xỉ rộng nhân cao nhân bốn byte. Một ảnh gốc từ máy ảnh chiếm hàng chục megabyte dù hiển thị trong ô nhỏ, nên phải yêu cầu ảnh đã thu nhỏ hoặc đặt kích thước giải mã.
Chia dự án Android thành nhiều module đem lại lợi ích chính nào?
A.Dung lượng ứng dụng giảm vì tách nhỏ mã
B.Mỗi module chạy trên một tiến trình riêng
C.Ranh giới phụ thuộc được ép, build nhanh hơn
D.Không cần viết kiểm thử cho module phụ
Đáp án: C
Hai lợi ích chính: ranh giới phụ thuộc do công cụ ép nên không ai vô tình gọi vào bên trong tính năng khác, và build lại nhanh hơn vì chỉ module bị sửa cùng những module phụ thuộc nó phải biên dịch lại.
Cài song song bản kiểm thử và bản chính thức trên cùng thiết bị cần gì?
A.Tên hiển thị khác nhau cho từng bản
B.Khoá ký khác nhau cho từng biến thể
C.Định danh ứng dụng khác nhau ở mỗi biến thể
D.Số phiên bản khác nhau giữa hai bản
Đáp án: C
Phải khác định danh ứng dụng, thường bằng cách thêm hậu tố cho biến thể gỡ lỗi và cho từng môi trường. Kèm theo đó nên đổi tên hiển thị và biểu tượng để người kiểm thử biết chắc mình đang mở bản nào.
Thông báo không hiển thị trên Android 13 dù mã gửi thông báo vẫn chạy. Nguyên nhân?
A.Thông báo phải gửi từ dịch vụ chạy nền
B.Hệ thống chặn thông báo trong hai tư giờ đầu
C.Kênh thông báo chỉ hoạt động ở bản gỡ lỗi
D.Quyền thông báo phải được xin lúc chạy
Đáp án: D
Từ Android 13, thông báo là quyền lúc chạy nên phải xin và người dùng có thể từ chối. Ngoài ra từ Android 8 mọi thông báo phải thuộc một kênh, và kênh chưa được tạo thì thông báo cũng không hiện.
Dịch vụ chạy nền có thông báo dùng cho loại công việc nào?
A.Công việc chạy định kỳ vào ban đêm
B.Công việc nhẹ chạy sau khi thiết bị khởi động
C.Công việc đang diễn ra, người dùng thấy được
D.Công việc chỉ cần khi ứng dụng đang mở
Đáp án: C
Dùng cho công việc đang diễn ra mà người dùng nhận biết được: phát nhạc, ghi lộ trình, tải tệp lớn. Hệ thống bắt buộc hiển thị thông báo, và từ Android 14 còn phải khai báo loại dịch vụ kèm lý do khi phát hành.
Ứng dụng cần lưu ảnh người dùng chụp vào thư viện chung. Cách đúng trên Android hiện nay?
A.Ghi thẳng vào thư mục ảnh bằng đường dẫn tuyệt đối
B.Xin quyền ghi bộ nhớ ngoài rồi ghi như trước
C.Lưu vào thư mục riêng của ứng dụng rồi báo người dùng
D.Ghi qua kho phương tiện của hệ thống
Đáp án: D
Ghi qua kho phương tiện của hệ thống: tạo bản ghi rồi ghi dữ liệu vào luồng nhận được. Từ Android 10, cơ chế lưu trữ có phạm vi không cho ứng dụng ghi tự do vào bộ nhớ chung bằng đường dẫn.
Liên kết https mở trình duyệt thay vì mở ứng dụng. Thiếu bước nào?
A.Tệp xác minh tên miền trên server
B.Đăng ký tên miền với cửa hàng ứng dụng
C.Bật chế độ mở liên kết trong phần cài đặt máy
D.Khai báo lược đồ riêng cho ứng dụng
Đáp án: A
Thiếu tệp assetlinks.json đặt đúng đường dẫn well-known trên https, với vân tay chứng chỉ ký khớp. Không có nó thì liên kết chỉ được coi là liên kết web thông thường và mở bằng trình duyệt.
Lưu refresh token trên Android nên dùng cơ chế nào?
A.Tệp trong thư mục riêng của ứng dụng
B.Kho thiết lập với chuỗi đã mã hoá tự viết
C.Khoá được bảo vệ bởi kho khoá của hệ thống
D.Biến trong bộ nhớ, đăng nhập lại mỗi lần mở
Đáp án: C
Dùng khoá do kho khoá của hệ thống bảo vệ để mã hoá dữ liệu trước khi lưu. Khoá nằm trong phần cứng bảo mật nên không trích xuất được, và có thể yêu cầu xác thực người dùng trước khi dùng khoá.
Nút chỉ có biểu tượng trên Android cần thêm gì cho trình đọc màn hình?
A.Kích thước biểu tượng lớn hơn mức khuyến nghị
B.Hiệu ứng phản hồi rõ hơn khi nhấn
C.Màu sắc có độ tương phản cao hơn nền
D.Mô tả nội dung nói rõ hành động sẽ xảy ra
Đáp án: D
Cần mô tả nội dung nói rõ hành động chứ không mô tả hình vẽ: đọc lên là lưu bài viết thì hữu ích, còn đọc lên là biểu tượng ngôi sao thì không. Biểu tượng thuần trang trí thì nên đánh dấu để trình đọc bỏ qua.
Kiểm thử giao diện Compose tìm phần tử theo tiêu chí nào là bền nhất?
A.Theo thứ tự khai báo trong mã nguồn
B.Theo tên hàm Composable đang dựng
C.Theo vị trí của phần tử trên màn hình
D.Theo chữ hiển thị và nhãn khả năng tiếp cận
Đáp án: D
Tìm theo thứ người dùng nhận biết được: chữ hiển thị, nhãn khả năng tiếp cận, hoặc thẻ kiểm thử khi cần. Cách này mô tả hành vi thay vì cấu trúc, nên tái cấu trúc component không làm kiểm thử vỡ.
Kiểm thử chạy trên máy phát triển khác kiểm thử chạy trên thiết bị ở đâu?
A.Loại trên thiết bị không truy cập được cơ sở dữ liệu
B.Loại trên máy không kiểm thử được logic bất đồng bộ
C.Loại trên máy nhanh hơn, không có API thật
D.Loại trên thiết bị không chạy được trong tích hợp liên tục
Đáp án: C
Kiểm thử trên máy phát triển chạy trong vài mili giây nhưng không có nền tảng Android thật, nên mọi thứ chạm tới hệ thống phải giả lập. Kiểm thử trên thiết bị dùng API thật nhưng chậm hơn hàng trăm lần.
B.let chạy khối trên background thread còn apply thì không
C.apply trả về đối tượng, let trả về kết quả
D.apply chỉ gán được thuộc tính chứ không gọi hàm
Đáp án: C
apply trả về chính đối tượng và tham chiếu tới nó bằng ngữ cảnh ngầm, hợp cho việc cấu hình. let trả về kết quả của khối và nhận đối tượng làm tham số, hợp cho việc biến đổi giá trị hoặc xử lý giá trị khác null.
Mô hình hoá trạng thái màn hình bằng sealed class có lợi ích gì?
A.Trình biên dịch bắt lỗi khi thiếu nhánh xử lý
B.Giao diện tự vẽ lại mà không cần luồng trạng thái
C.Trạng thái tự động được lưu khi tiến trình bị đóng
D.Giảm số lượng lớp phải khai báo trong dự án
Đáp án: A
Tập hợp lớp con là đóng nên biểu thức when được kiểm tra đủ nhánh lúc biên dịch. Thêm một trạng thái mới mà quên xử lý ở đâu đó thì build hỏng ngay, thay vì lộ ra khi người dùng gặp màn hình trắng.
Hệ điều hành đóng ứng dụng ở nền, người dùng quay lại thấy mất dữ liệu đang nhập. Xử lý thế nào?
A.Giữ dữ liệu trong ViewModel là đủ
B.Giữ ứng dụng sống bằng dịch vụ chạy nền
C.Bắt sự kiện trước khi ứng dụng bị đóng để lưu
D.Lưu qua cơ chế trạng thái đã lưu của hệ thống
Đáp án: D
Dùng cơ chế trạng thái đã lưu: dữ liệu nhỏ và quan trọng như nội dung đang nhập được ghi vào gói do hệ thống giữ, nên khi người dùng quay lại thì màn hình dựng lại đúng như trước. ViewModel một mình không đủ.
Báo cáo sự cố từ cửa hàng chỉ hiện tên lớp đã rút gọn. Thiếu gì?
A.Chế độ gỡ lỗi bật trong bản phát hành
B.Kết nối mạng ổn định lúc sự cố xảy ra
C.Quyền ghi nhật ký trên thiết bị người dùng
D.Tệp ánh xạ của đúng bản đã phát hành
Đáp án: D
Thiếu tệp ánh xạ khớp đúng phiên bản. Bản phát hành rút gọn và đổi tên ký hiệu, nên phải tải tệp ánh xạ lên dịch vụ giám sát ở mỗi lần phát hành, và với phần mã native còn cần tệp ký hiệu riêng.
Vì sao phải nâng phiên bản đích của ứng dụng theo chu kỳ?
A.Phiên bản đích quyết định số thiết bị hỗ trợ tối thiểu
B.Cửa hàng yêu cầu để tiếp tục nhận bản cập nhật
C.Ứng dụng sẽ không chạy trên thiết bị đời mới
D.Trình biên dịch từ chối build với phiên bản cũ
Đáp án: B
Cửa hàng đặt yêu cầu về phiên bản đích và từ chối bản cập nhật không đạt. Nâng phiên bản đích cũng kéo theo phải tuân thủ các thay đổi hành vi của hệ điều hành, và đó mới là phần tốn công thật sự.
Ứng dụng mất vài giây mới hiện màn hình đầu. Nên xem chỗ nào trước?
A.Khởi tạo chạy đồng bộ ngay lúc mở ứng dụng
B.Số lượng thành phần trên màn hình đầu tiên
C.Tốc độ mạng của thiết bị lúc mở ứng dụng
D.Kích thước ảnh nền của màn hình chờ
Đáp án: A
Rà phần khởi tạo chạy đồng bộ trong lớp ứng dụng: các thư viện phân tích, quảng cáo, giám sát lỗi thường khởi tạo ngay khi mở. Chỉ giữ những gì bắt buộc trước khung hình đầu, phần còn lại hoãn lại sau.
Buộc người dùng cập nhật khi bản cũ không còn tương thích nên làm thế nào?
A.Trông cậy vào cập nhật tự động của cửa hàng
B.Khoá tài khoản của người dùng chưa cập nhật
C.Server công bố phiên bản tối thiểu
D.Nhúng phiên bản tối thiểu ngay trong mã ứng dụng
Đáp án: C
Để server công bố phiên bản tối thiểu và ứng dụng kiểm tra khi khởi động, kết hợp với cơ chế cập nhật trong ứng dụng của nền tảng để người dùng không phải rời khỏi ứng dụng.
Bố cục cho máy tính bảng nên quyết định dựa trên tiêu chí nào?
A.Việc thiết bị có bàn phím rời hay không
B.Kích thước vật lý của màn hình thiết bị
C.Lớp kích thước cửa sổ hiện tại
D.Phiên bản hệ điều hành đang chạy
Đáp án: C
Dựa vào lớp kích thước cửa sổ chứ không phải loại thiết bị. Máy gập và chế độ chia đôi màn hình khiến cửa sổ nhỏ hơn màn hình, nên mọi giả định dạng máy tính bảng hay điện thoại đều sai trong các trường hợp đó.
Người dùng bấm nút gửi hai lần rất nhanh tạo hai đơn hàng. Xử lý bền vững thế nào?
A.Vô hiệu hoá nút ngay trong hàm xử lý chạm
B.Chống dội sự kiện chạm khoảng một giây
C.Khoá ở tầng state cộng khoá idempotent
D.Hiển thị hộp thoại xác nhận trước khi gửi
Đáp án: C
Cần hai lớp: cờ đang gửi ở tầng state để chặn lời gọi thứ hai và cho nút vào trạng thái chờ, và khoá idempotent gửi kèm yêu cầu để server nhận ra lần thử lại và trả về đúng bản ghi cũ.
Thu thập luồng dữ liệu trong giao diện mà không gắn vòng đời gây hậu quả gì?
A.Ứng dụng báo lỗi khi màn hình bị đóng
B.Luồng dữ liệu ngừng phát ngay khi mất tiêu điểm
C.Vẫn xử lý cập nhật khi màn hình không hiển thị
D.Dữ liệu mới bị mất cho tới khi màn hình mở lại
Đáp án: C
Việc thu thập tiếp tục chạy khi màn hình đã ở nền, nên tốn pin và mạng cho dữ liệu không ai nhìn. Cách đúng là thu thập trong phạm vi gắn vòng đời, để việc lắng nghe tạm dừng khi giao diện không hiển thị và tự nối lại khi quay lại.
Mở thông báo đẩy nhiều lần tạo ra nhiều bản của cùng một màn hình trong ngăn xếp. Nguyên nhân?
A.Ngăn xếp bị xoá mỗi lần ứng dụng vào nền
B.Thông báo gửi trùng nhiều lần từ server
C.Mỗi lần mở tạo một thể hiện mới
D.Hệ thống không cho phép quay lại màn hình cũ
Đáp án: C
Mặc định mỗi lần mở tạo một thể hiện mới. Cần cấu hình chế độ khởi chạy hoặc gắn cờ cho intent để dùng lại thể hiện đã có, và xử lý dữ liệu mới trong hàm nhận intent thay vì chỉ trong hàm khởi tạo.
Chia sẻ tệp của ứng dụng cho ứng dụng khác nên làm thế nào?
A.Truyền đường dẫn tuyệt đối của tệp qua intent
B.Tải tệp lên server rồi gửi liên kết
C.Cấp quyền tạm thời qua địa chỉ nội dung
D.Chép tệp ra bộ nhớ chung rồi gửi đường dẫn
Đáp án: C
Dùng nhà cung cấp nội dung của thư viện hỗ trợ để tạo địa chỉ nội dung và cấp quyền đọc tạm thời cho ứng dụng nhận. Truyền đường dẫn tuyệt đối không hoạt động vì ứng dụng khác không có quyền vào thư mục riêng.
Một coroutine con ném ngoại lệ trong coroutineScope dẫn tới điều gì?
A.Ngoại lệ bị nuốt và không lan ra ngoài
B.Chỉ coroutine đó dừng, các coroutine khác chạy tiếp
C.Ứng dụng đóng ngay lập tức không thể bắt lỗi
D.Các coroutine anh em bị huỷ theo
Đáp án: D
Trong phạm vi thường, một coroutine con thất bại sẽ huỷ các coroutine anh em và lan lỗi ra ngoài. Muốn các nhánh độc lập với nhau thì dùng phạm vi giám sát, nơi lỗi của một con không kéo theo các con khác.
Gọi ba API độc lập cho một màn hình nên viết thế nào để nhanh nhất?
A.Khởi chạy song song rồi chờ cả ba cùng lúc
B.Chạy mỗi lời gọi trên một thread hệ điều hành riêng
C.Gọi tuần tự và chờ từng cái hoàn tất
D.Gộp ba lời gọi thành một bằng cách nối chuỗi
Đáp án: A
Khởi chạy cả ba song song rồi chờ kết quả cùng lúc, thay vì chờ tuần tự. Tổng thời gian khi đó bằng lời gọi chậm nhất chứ không phải tổng của cả ba, và trên mạng di động khác biệt này rất rõ.
Flow lạnh chạy lại phần sinh dữ liệu cho mỗi người thu thập, nên hai màn hình cùng thu thập sẽ gọi nguồn hai lần. Flow nóng phát chung một dòng cho mọi người nghe, và người gắn vào muộn có thể bỏ lỡ giá trị cũ.
Repository nên trả về gì khi lời gọi mạng thất bại?
A.Giá trị null để nơi gọi tự hiểu là lỗi
B.Ném ngoại lệ của thư viện mạng ra ngoài
C.Danh sách rỗng để giao diện hiển thị trạng thái trống
D.Một kiểu kết quả mô tả rõ thành công hay thất bại
Đáp án: D
Trả về một kiểu kết quả tường minh phân biệt thành công và thất bại, kèm loại lỗi có ý nghĩa với ứng dụng như mất mạng, hết phiên hay lỗi server. Trả về null hoặc danh sách rỗng làm mất thông tin và gây hiểu nhầm cho người dùng.
Ứng dụng cần đọc được dữ liệu khi mất mạng. Kiến trúc phù hợp là gì?
A.Tải trước toàn bộ dữ liệu khi mở ứng dụng
B.Hiển thị thông báo yêu cầu bật mạng khi mất kết nối
C.Lưu phản hồi mạng vào cache trong bộ nhớ
D.Cơ sở dữ liệu cục bộ làm nguồn sự thật
Đáp án: D
Cho cơ sở dữ liệu cục bộ làm nguồn sự thật: dữ liệu tải về được ghi vào bảng, còn giao diện chỉ quan sát bảng. Nhờ vậy màn hình luôn hiển thị được nội dung đã có, và việc mất mạng chỉ ảnh hưởng tới độ mới của dữ liệu.
Dự án đang dùng hệ view cũ muốn viết màn hình mới bằng Compose. Cách tiếp cận hợp lý?
A.Viết lại toàn bộ ứng dụng bằng Compose trong một đợt
B.Nhúng Compose vào màn hình mới, giữ phần cũ
C.Tạo ứng dụng mới song song rồi chuyển người dùng sang
D.Chờ tới khi có thời gian rảnh để chuyển đổi toàn bộ
Đáp án: B
Chuyển đổi dần: màn hình mới viết bằng Compose và nhúng vào cấu trúc hiện có, còn màn hình cũ giữ nguyên cho tới khi thật sự cần sửa. Hai hệ dùng lẫn được theo cả hai chiều nên không cần một đợt viết lại lớn.
Màu động lấy từ hình nền của người dùng có rủi ro gì cần lường trước?
A.Tính năng này chỉ hoạt động ở chế độ tối
B.Ứng dụng phải xin quyền đọc hình nền của thiết bị
C.Bảng màu đổi nên tương phản có thể không đạt
D.Ứng dụng không dùng được màu thương hiệu nữa
Đáp án: C
Bảng màu do hệ thống sinh từ hình nền nên không đoán trước được. Phải luôn dùng cặp màu theo vai trò như màu nền và màu chữ trên nền đó, thay vì tự chọn màu chữ, nếu không sẽ có tổ hợp không đủ tương phản.
Cờ tính năng giải quyết vấn đề đặc thù nào của ứng dụng di động?
A.Tắt tính năng hỏng mà không chờ bản mới được duyệt
B.Thay thế nhu cầu kiểm thử trước khi phát hành
C.Giảm dung lượng vì tính năng tắt không được đóng gói
D.Cập nhật giao diện mà không cần phát hành mã mới
Đáp án: A
Trên di động, bản sửa lỗi phải qua duyệt và người dùng có thể không cập nhật trong nhiều tuần. Cờ tính năng cho phép tắt ngay một tính năng hỏng trên các bản đã cài, và mở dần tính năng mới cho một phần người dùng.
Chỉ số nào của cửa hàng phản ánh chất lượng kỹ thuật của ứng dụng?
A.Số lượt tải về trong tuần gần nhất
B.Tỉ lệ phiên gặp sự cố
C.Tỉ lệ phiên bị báo không phản hồi
D.Thời gian khởi động ở nhóm phần trăm cao
Đáp án: B, C, D
Ba chỉ số kỹ thuật cốt lõi: tỉ lệ phiên gặp sự cố, tỉ lệ báo không phản hồi, và thời gian khởi động. Vượt ngưỡng của cửa hàng còn ảnh hưởng tới khả năng ứng dụng được giới thiệu trong kết quả tìm kiếm.
Đặt tên sự kiện phân tích tuỳ hứng để lại hậu quả gì về sau?
A.Dịch vụ phân tích từ chối tên không theo chuẩn
B.Quy ước giúp giảm dung lượng dữ liệu gửi đi
C.Dữ liệu lịch sử đã ghi thì không đổi tên lại được
D.Tên sự kiện ảnh hưởng tới hiệu năng ứng dụng
Đáp án: C
Dữ liệu đã ghi không đổi tên lại được, nên một quy ước lỏng lẻo để lại hậu quả vĩnh viễn: các sự kiện gần giống nhau không ghép được và số liệu trước sau không so sánh được.
Vì sao bộ nhận quảng bá đăng ký trong tệp khai báo ngày càng ít dùng được?
A.Chúng chỉ hoạt động khi ứng dụng đang mở
B.Chúng yêu cầu quyền đặc biệt mà cửa hàng không duyệt
C.Hệ thống hạn chế nhiều loại quảng bá ngầm định
D.Bộ nhận quảng bá đã bị gỡ khỏi nền tảng Android
Đáp án: C
Việc đánh thức hàng loạt ứng dụng cho mỗi sự kiện hệ thống gây tốn pin, nên nền tảng đã hạn chế nhiều quảng bá ngầm định qua các phiên bản. Cách thay thế là bộ lập lịch công việc với ràng buộc phù hợp.
Hồ sơ tối ưu khởi động giúp gì cho ứng dụng Android?
A.Cho phép ứng dụng chạy nền lâu hơn
B.Giảm dung lượng gói cài đặt của ứng dụng
C.Tăng tốc mọi lời gọi mạng của ứng dụng
D.Mã đường nóng được biên dịch trước
Đáp án: D
Hồ sơ này liệt kê các đường mã hay chạy lúc khởi động và trong các thao tác chính, để chúng được biên dịch trước thay vì diễn giải ở lần chạy đầu. Kết quả rõ nhất là khởi động và cuộn ở lần đầu sau khi cài nhanh hơn hẳn.