Flutter Interview Questions and Answers

In this article, you’ll work through a series of Flutter and Dart job interview questions and answers. By Jonathan Sande.

Leave a rating/review
Save for later
Share
You are currently viewing page 4 of 5 of this article. Click here to view the first page.

Question 5

What types of tests can you perform?

[spoiler title="Solution"]
There are three main kinds of tests: unit tests, widget tests and integration tests. Unit tests are all about checking the validity of your business logic. Widget tests are for making sure UI widgets have the components that you expect them to. Integration tests check that your app is working as a whole.

One additional type of test that is not as well known is a golden test. In a golden test, you have an image of a widget or screen and check to see that the actual widget matches it.

Learn more about testing in the Flutter Cookbook docs and more on golden tests from the Medium article, Flutter: Golden tests — compare Widgets with Snapshots.

Also, raywenderlich.com has an article about Flutter unit testing.
[/spoiler]

Senior Written Questions

Question 1

Demonstrate Dart isolate communication using ports by completing the following steps:

  1. Give a function called downloadAndCompressTheInternet() to a new isolate.
  2. Have it return the value 42.

[spoiler title="Solution"]

import 'dart:isolate';

void main() async {
  // 1
  final receivePort = ReceivePort();
  // 2
  final isolate = await Isolate.spawn(
    downloadAndCompressTheInternet,
    receivePort.sendPort,
  );
  // 3
  receivePort.listen((message) {
    print(message);
    receivePort.close();
    isolate.kill();
  });
}

// 4
void downloadAndCompressTheInternet(SendPort sendPort) {
  sendPort.send(42);
}

In this code, you:

  1. Create a port for receiving data from the new isolate.
  2. Create a new isolate, give it some work to do and provide it a means to send data back.
  3. Listen for any data message that the new isolate sends, then get rid of the isolate.
  4. Send the data back using the port that the main isolate is listening to.

The internet decompression algorithm is still under development. :]

Read Coding With Joe's article, Dart Fundamentals — Isolates, to learn more about isolate communication.
[/spoiler]

Question 2

You have two tree data structures, where random integers are nodes in the tree. The numbers don't have to be unique, nor are they sorted in any logical way. Both trees are an arbitrary number of levels deep. Write an algorithm to identify any numbers in the first tree that are not in the second.

Here's an example:

Diagram showing two tree data structures containing random numbers

The algorithm should identify that the number 1 is in the first tree, but not in the second.

[spoiler title="Solution"]
First define the nodes in the tree:

class Node {
  int data;
  List<Node> children;

  Node(this.data, {this.children});
}

Add the logic to search the tree recursively, looking for unique integers:

class UniqueTreeItems {
  final Set<int> _uniqueIntegers = HashSet<int>();

  Set<int> search(Node tree) {
    _addInOrder(tree);
    return _uniqueIntegers;
  }

  void _addInOrder(Node node) {
    _uniqueIntegers.add(node.data);
    if (node.children == null) return;
    for (final child in node.children) {
      _addInOrder(child);
    }
  }
}

Set up the test data:

final treeOne = Node(1, children: [
  Node(4, children: [
    Node(10),
    Node(12),
  ]),
  Node(3, children: [
    Node(3),
    Node(10),
    Node(1),
  ]),
]);

final treeTwo = Node(4, children: [
  Node(10),
  Node(3),
  Node(12),
]);

Filter out any integers from Tree 1 that are also in Tree 2:

void main() async {
  final uniqueOne = UniqueTreeItems().search(treeOne);
  final uniqueTwo = UniqueTreeItems().search(treeTwo);
  final answer = uniqueOne.where((element) => !uniqueTwo.contains(element));
  answer.forEach(print); // 1
}

The answer is 1.
[/spoiler]

Senior Verbal Questions

Question 1

What are the pros and cons of different state management solutions?

[spoiler title="Solution"]
While there are countless varieties, some of the more popular state management solutions include BLoC, ChangeNotifier with Provider, Redux, MobX and RxDart. These are all appropriate for medium- to large-scale apps; if you're only making a quick demo app, then a stateful widget is often enough.

Instead of listing the pros and cons of each state management option, it's more useful to look at the situations where a certain class of solutions is a better fit. For example, for someone who's overwhelmed with the sheer number of options, it's important to choose a solution that's easy to grasp, mentally. ChangeNotifier with Provider or MobX would be a good choice, because it makes sense to directly call methods on the state class in response to events.

If you're heavily reliant on streams, such as with a Firebase API, then it's natural to choose a stream-based solution like BLoC or RxDart.

And if you need undo/redo functionality, then you'd want a solution like BLoC or Redux that handles immutable state well.

In the end, a lot of it comes down to personal preference. You can find links to more information about the most popular state management systems in Flutter's' list of state management approaches.

There are also articles about BLoC and Provider with ChangeNotifier here on raywenderlich.com.
[/spoiler]

Question 2

How would you design an app to control an elevator?

[spoiler title="Solution"]
This question tests your analytical skills, organization and use of SOLID principles.

Here's one possible answer:

  1. First, determine what the core functionality is: things like opening and closing the doors, moving up and down to different floors, calling for help and coordinating with other elevators. This is your business logic. Drawing a diagram may help.
  2. Implement the business logic in Test Driven Development (TDD) style. That is, write a failing test, write just enough business logic code to make it pass, refactor and then do it all again with another test.
  3. In the beginning, it doesn't matter if you have physical buttons or a Flutter-powered touch screen. It doesn't matter what the elevator looks like or where it is. It doesn't matter what the emergency call system is. You should abstract these external factors behind interfaces that you can mock out during development.
  4. Once you've completed the core logic, you can work on implementing each of the components that you previously only represented with an interface. For the UI, you'll need to set up a state management system that takes in events like button pushes or arrivals and then updates the state, which could result in lighting a button number or updating a screen. You'll also need to implement the services that interact with the system for making an emergency call or the hardware that opens the doors.
  5. Safety is obviously extremely important for elevators, so in addition to testing the core business logic and the various system components in isolation, you'll also need to do thorough integration testing. For an elevator, that will involve manual testing by robots and/or humans.

[/spoiler]