Sẽ là series 2 phần cho các câu hỏi phỏng vấn trong FLUTTER là góc nhìn tổng quan và tham khảo và qua quá trình làm việc mình sẽ tổng hợp các câu hỏi sau theo overview nhất cho mọi người có thể nắm qua được các trọng tâm cần nhớ

1.Tại sao lại lựa chọn Flutter để phát triển ứng dụng di động

Được Google giới thiệu vào 2017 cho đến nay Flutter đã có một chỗ đứng vững chắc trong lập trình di động

Lí do:
Flutter hỗ trợ phát triển đa nền tảng
Lập trình trong Flutter cực kỳ dễ dàng và linh hoạt (Có cả hot reload)
Quá trình xây dựng trong Flutter nhanh hơn nhiều so với lập trình Native (Android/ IOS) tiết kiệm được chi phí

  • Cả anh lớn Google support :))

2. Hạn chế của Flutter

Vì số năm ra đời tới 2024 nhưng vẫn đang trên đà cạnh tranh với các nền tảng khác

Kích thước ứng dụng phát triển bởi Flutter có size khá bự
Flutter yêu cầu phải được sử dụng cùng với một ngôn ngữ OOP là Dart
,nhưng ngôn ngữ này không thể cạnh tranh với các ngôn ngữ OOP khác như Java, C# như bảo mật, đóng gói, độ chặt chẽ

3. Tại sao lần đầu được build IOS/ANDROID lâu đến vậy

Vì Flutter tạo tệp IPA hoặc APK dành riêng cho thiết bị nên việc xây dựng ứng dụng Flutter sẽ mất nhiều thời gian hơn trong lần đầu tiên. Phương pháp này thường mất nhiều thời gian và sử dụng Xcode và Gradle để xây dựng tệp.

4. Key dùng để làm gì

Trong Flutter, các Keys chủ yếu đóng vai trò quan trọng trong việc bảo toàn trạng thái của các Widgets khi chúng được cập nhật trong cây Widget.

Một tập hợp các ID cho Widgets, Elements tạo thành lớp Key chính. Keys có trách nhiệm duy trì trạng thái của các widget khi chúng được cập nhật trong cây widget.

Keys cũng có thể được sử dụng để sửa đổi và sắp xếp lại các bộ sưu tập các widget cùng loại và các trạng thái đã định nghĩa.

Tuy nhiên, nếu cây widget chỉ gồm các widget không có trạng thái (stateless), thì việc sử dụng Keys sẽ không phải là cần thiết, mặc dù chúng không gây bất kỳ tác hại nào. Keys sẽ hữu ích khi bạn cần chỉnh sửa một cây widget với các widget có trạng thái (stateful).

5. Stream trong dart có mấy loại, sự khác nhau

Streams trong Flutter cung cấp một chuỗi dữ liệu bất đồng bộ. Lập trình bất đồng bộ sử dụng về Streams.Được coi

**để phân tích một ví dụ cụ thể về việc sử dụng Streams trong thực tế đời sống:

Hãy tưởng tượng bạn đang xây dựng một ứng dụng theo dõi sức khỏe. Ứng dụng này sẽ thu thập và hiển thị các chỉ số sức khỏe của người dùng như nhịp tim, lượng oxy trong máu, lượng glucose, v.v.

Trong trường hợp này, các chỉ số sức khỏe này có thể được coi là các “sự kiện” trong một Stream. Ứng dụng sẽ liên tục nhận dữ liệu đo lường từ các thiết bị theo dõi sức khỏe của người dùng và đưa chúng vào một Stream.

Ứng dụng của bạn có thể “lắng nghe” (listen) Stream này và sử dụng các giá trị được phát ra để:

Cập nhật biểu đồ và các chỉ số sức khỏe trên giao diện người dùng
So sánh các giá trị mới với các giá trị bình thường, và đưa ra cảnh báo nếu có bất thường
Lưu lại lịch sử các chỉ số sức khỏe để phân tích xu hướng
Bằng cách sử dụng Streams, ứng dụng có thể xử lý luồng dữ liệu sức khỏe liên tục và theo thời gian thực, thay vì phải đợi tất cả dữ liệu được thu thập trước khi hiển thị. Điều này giúp người dùng được theo dõi sức khỏe của họ một cách chủ động và kịp thời.**

Có hai loại luồng (Streams) trong Flutter:

Single Subscription Streams:

dart interview 1

Broadcast Streams:

dart interview 2

Tóm lại

Nếu có 1 listener, hãy sử dụng Single - Subscription Stream.
Nếu có nhiều listener, hãy sử dụng Broadcast Streams.

6.Toán tử ??, !, toán tử 3 ngôi

Trong dart 2.0 trở về sau ?? dùng cho null safety khi muốn gán giá trị cho một giá trị nếu giá trị đó có thể chứa null ví dụ int? b; int a = b ?? 3 => thì b sẽ được gán giá trị là 3 nếu b null và ngược lại sẽ là b nếu có giá trị

!
vừa để kiểm tra giá trị bool trong dart ví dụ

bool isMale = false;
bool isFemal = !isMale; //true

hoặc để chắc chắn giá trị không thể nào có giá trị null

int? a = 3;

int b = a!;

Toán tử 3 ngôi
int a = true ? 3 : 2; ở đây toán tử 3 ngôi sẽ khiến a mang giá trị 3 vì câu lệnh sau dấu ? sẽ thực hiện nếu trước nó là giá trị đúng (True) và ngược lại int a = false ? 3 : 2 thì a sẽ mang giá trị 2
vì câu lệnh trước dấu ? mang giá trị (False) thì câu lệnh sau dấu : sẽ được thực hiện

7.Kể tên một số mode build trong Flutter

Debug mode:
Dùng để tìm và sửa lỗi trong ứng dụng. Nó cung cấp nhiều công cụ và thông tin hữu ích để debug như breakpoints, trình debug, và thông tin log.
Profile mode:
Dùng để phân tích và cải thiện hiệu suất của ứng dụng. Nó cung cấp các công cụ để theo dõi FPS, bộ nhớ, CPU, và các hoạt động khác.
Release mode:
Release mode là chế độ build ứng dụng được tối ưu code về hiệu suất, bảo mật và phù hợp để phát hành cho người dùng cuối ví dụ như tester, người dùng trên chợ ứng dụng

8.Await function là gì?

Await chỉ có thể được sử dụng bên trong các hàm async. Nó tạm dừng thực thi hàm async đó cho đến khi nhận được kết quả từ một Promise.
Await cho phép code chờ đợi kết quả trả về từ các hoạt động bất đồng bộ như gọi API, đọc/ghi file, v.v. trước khi tiếp tục thực thi các câu lệnh tiếp theo.
Điều này giúp tránh các lỗi và đảm bảo tính đúng đắn của dữ liệu khi sử dụng trong các lệnh sau.
Await cũng giúp code trở nên dễ đọc, dễ hiểu và dễ bảo trì hơn, thay vì phải sử dụng các callback phức tạp.

9.Stateless là gì?

Về stateless, nó được định nghĩa là các widget không lưu trữ trạng thái nội bộ. Các ví dụ về widget stateless bao gồm:

Text: Hiển thị một chuỗi ký tự với một kiểu định dạng đơn.
Container: Một widget trong Flutter để căn chỉnh lề, chiều dài, rộng, màu nền, bóng…
Icon: Được sử dụng cho danh sách các biểu tượng material có sẵn và có thể được sử dụng với lớp này.

10.Statefull là gì?

Các widget stateful có khả năng lưu trữ và quản lý trạng thái nội bộ của chúng. Điều này cho phép chúng có thể thay đổi và cập nhật giao diện người dùng dựa trên các tương tác của người dùng.

Một số ví dụ về các widget stateful bao gồm:

Nút bấm (Button): Nút bấm có thể lưu trữ trạng thái được nhấn hoặc không được nhấn, và có thể cập nhật giao diện tương ứng (ví dụ: thay đổi màu sắc, hiển thị tooltip, v.v.) khi người dùng tương tác với nó.

(Checkbox) và (Radio Button): Các widget này lưu trữ trạng thái được chọn hoặc không được chọn, và cập nhật giao diện tương ứng.

Danh sách (ListView): Danh sách có thể lưu trữ và cập nhật trạng thái cuộn, lựa chọn các mục trong danh sách, v.v.

Tóm lại, các widget stateful có khả năng lưu trữ và quản lý trạng thái nội bộ, cho phép chúng đáp ứng và cập nhật giao diện người dùng dựa trên các tương tác của người dùng.

ví dụ về ứng dụng hiển thị số theo các nút bấm (+) (-)

interview dart p2

11.Build context là gì?

BuildContext trong Flutter là một khái niệm rất quan trọng và cốt lõi. Nó đại diện cho một vị trí cụ thể trong cây widget (widget tree) của ứng dụng.

Các chức năng chính của BuildContext bao gồm:

Truy cập thông tin về widget:

**BuildContext cung cấp thông tin về widget hiện tại, như tên, kiểu, thuộc tính, v.v. Điều này cho phép bạn tương tác với widget đó và thay đổi trạng thái của nó.

Truy cập thông tin về cây widget: BuildContext cho phép bạn truy cập và điều hướng trong cây widget. Ví dụ, bạn có thể tìm các widget cha/con, lấy các widget ở vị trí khác trong cây, v.v.

Truy cập các Dependencies: BuildContext cho phép bạn truy cập các dependencies (ví dụ: Theme, Localizations, MediaQuery) được cung cấp cho widget.

Tạo và hiển thị các widget mới: Khi bạn gọi các hàm như Navigator.push() hoặc showDialog(), bạn sử dụng BuildContext để xác định vị trí hiển thị của widget mới trong cây widget.**

12.Vòng đời của stateFul trong fluttter

A StatefulWidget bao gồm các vòng đời sau

createState():

Phương thức này được gọi khi widget Stateful được tạo lần đầu tiên.
Nó trả về một instance của State class, đại diện cho trạng thái nội bộ của widget.
Đây là nơi bạn khởi tạo các biến trạng thái và các dependencies cần thiết cho widget.

initState():

Phương thức này được gọi ngay sau khi State object được tạo.
Đây là nơi bạn thực hiện các khởi tạo và thiết lập ban đầu, chẳng hạn như đăng ký các listeners, lấy dữ liệu từ API, v.v.

didChangeDependencies():

Phương thức này được gọi khi widget phụ thuộc vào một InheritedWidget nào đó thay đổi.
Đây là nơi bạn có thể đăng ký hoặc hủy đăng ký các listeners liên quan đến những phụ thuộc được cập nhật.

build(BuildContext context):

Phương thức này được gọi mỗi khi widget cần được vẽ lại trên màn hình.
Ở đây, bạn xây dựng và trả về cây widget con của widget Stateful hiện tại.
Phương thức này nhận vào một BuildContext để bạn có thể truy cập thông tin về vị trí của widget trong cây widget.

didUpdateWidget(covariant T oldWidget):

Phương thức này được gọi khi widget Stateful nhận được một instance mới, ví dụ khi các thuộc tính của widget thay đổi.
Ở đây, bạn có thể thực hiện các logic cập nhật, chẳng hạn như lưu trữ trạng thái cũ hoặc đăng ký/hủy đăng ký các listeners mới.

setState(VoidCallback fn):

Phương thức này được gọi để thông báo cho Flutter rằng trạng thái của widget đã thay đổi.
Khi gọi setState(), Flutter sẽ gọi lại phương thức build() để vẽ lại widget với trạng thái mới.

deactivate():

Phương thức này được gọi khi widget Stateful bị tách khỏi cây widget, nhưng vẫn tồn tại trong bộ nhớ.
Ở đây, bạn có thể thực hiện các logic dọn dẹp, chẳng hạn như hủy đăng ký các listeners.

dispose():

Phương thức này được gọi khi widget Stateful bị hủy bỏ và sẽ không còn xuất hiện trong cây widget nữa.
Đây là nơi bạn thực hiện các logic dọn dẹp cuối cùng, chẳng hạn như hủy đăng ký các listeners, giải phóng các tài nguyên.