This repository holds technical interview questions for the Senior Android Developer position which has been was asked from me or I usually ask from other candidates. Feel free to contribute and improve it.
- General questions
- Object Oriented Programming
- Java Programming
- Android Foundation
- Android UI Design
- Software Architecture Design
- Testing
- License
-
Why do you consider yourself a Senior Developer? Who is a senior developer? What is the definition of being a Senior Developer?
- Being senior is mostly about sharing, your knowledge, experience, time, ...
- Jira
- asana
- Trello
-
- Abstraction
- Encapsulation
- Inheritance
- Polymorphism
-
public
: modifier is widely-used on classes, variables, constructors and methods to grant access from any class and method anywhere.private
(by default) : variables, methods, constructors or inner classes are only visible to its' containing class and its' methods.protected
: can be used on variables, methods and constructors therefore allowing access only to subclasses and classes that are inside the same package as protected members' class.
-
- Overload (one method with different signature)
- @Override
-
- An interface can extends multiple interfaces.
- A single class can also implement multiple interface.
-
- static members belong to the class instead of a specific instance.
-
- Static methods cannot be overridden because they are not dispatched on the object instance at runtime.
-
- Constructors are not members of classes and only members are inherited.
-
- Creational patterns
- Builder
- Factory
- Singleton
- Monostate
- Fluent Interface Pattern
- Structural patterns
- Adapter
- Decorator
- Facade
- Behavioural patterns
- Chain of responsibility
- Iterator
- Strategy
- Creational patterns
-
View Holder
uses SingletonIntent
uses FactoryBroadcast Receiver
uses ObserverView
uses Composite- Media FrameWork uses Façade
Toast.makeText()
uses Factory
- Using is vs has rule (Cat is an Animal / Person has a Job)
- Single responsibility principle:
- A class should have only a single responsibility (i.e. only one potential change in the software’s specification should be able to affect the specification of the class
- a class should have only one single responsibility
- One chef cannot run the whole restaurant
- Open/closed principle:
- A software module/class/method should be open for extension but closed for modification.
- any software entity should be open for extension but closed for modification.
- Trying new shoes doesn’t require you to saw your feet off.
- Liskov substitution principle:
- Objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program
- Interface segregation principle:
- Clients should not be forced to depend upon the interfaces that they do not use.
- many client-specific interfaces are better than one general-purpose interface.
- Dependency inversion principle:
- Program to an interface, not to an implementation.
- The high-level module must not depend on the low-level module, but they should depend on abstractions. one should “Depend upon Abstractions. Do not depend upon concretions.
- You wouldn’t wire a lamp directly to your house.
- to avoid multiple implementations of the constructor for setting different fields in a class.
-
What are the types of GoF (Gang of Four) design patterns? Provide examples.
- Creational
- Structural
- Behavioral.
-
- Sparse arrays can be used to replace hash maps when the key is an Integer or a Long (HashMap <Integer, V>).
- is made to be memory efficient than using the regular HashMap
- It is generally slower than a traditional HashMap
-
- two different implementations of the List interface
- LinkedList implements it with a doubly-linked list.
- ArrayList implements it with a dynamically re-sizing array.
- LinkedList is better for working with stacks mostly, or when working with buffers.
- ArrayList is best for working with indexes.
-
What is the difference between HashSet, HashMap and Hashtable? How do they behave in a multi-threaded environment?
-
Hashtable is basically a data structure to retain values of key-value pair.
- It does not allow null for both key and value. It will throw NullPointerException.
- Hashtable does not maintain insertion order. The order is defined by the Hash function. So only use this if you do not need data in order.
- It is synchronized. It is slow. Only one thread can access in one time.
- HashTable rea thread safe.
- HashTable uses Enumerator to iterate through elements.
Hashtable<Integer,String>; myTable = new Hashtable<Integer,String>(); myTable.put(1, "John"); myTable.put(2, "Cena"); myTable.put(3, null); /* NullPointerEcxeption at runtime*/ System.out.println(myTable.get(1)); System.out.println(myTable.get(2)); System.out.println(myTable.get(3));
-
Like Hashtable it also accepts key value pair.
- It allows null for both key and value.
- HashMap does not maintain insertion order. The order is defined by the Hash function.
- It is not synchronized. It will have better performance.
- HashMap are not thread safe, but you can use Collections.synchronizedMap(new HashMap<K,V>())
HashMap<Integer,String> myMap = new HashMap<Integer,String>(); myMap.put(1, "First"); myMap.put(2,"Second"); myMap.put(3, null);
-
HashSet does not allow duplicate values.
- It provides add method rather put method.
- You also use its contain method to check whether the object is already available in HashSet. HashSet can be used where you want to maintain a unique list.
HashSet<String> mySet = new HashSet<String>(); mySet.add ("First"); mySet.add ("Second"); mySet.add ("Third"); if(mySet.contains("First")){ System.out.println("The Set already contains First"); }
-
-
- Deadlock describes a situation where two or more threads are blocked forever, waiting for each other.
-
- Breaking circular wait condition: In order to do that, you can make arrangements in the code to impose the ordering on acquisition and release of locks.
- Avoid Nested Locks: This is the most common reason for deadlocks, avoid locking another resource if you already hold one. It’s almost impossible to get a deadlock situation if you are working with only one object lock.
- Lock Only What is Required: You should acquire lock only on the resources you have to work on, if we are only interested in one of its fields, then we should lock only that specific field, not complete object.
- Avoid waiting indefinitely: You can get a deadlock if two threads are waiting for each other to finish indefinitely using thread join. If your thread has to wait for another thread to finish, it’s always best to use join with the maximum time you want to wait for the thread to finish.
-
- A program in execution is often referred to as Process. A thread is a part of the process.
- A process consists of multiple threads. A thread is the smallest part of the process that can execute concurrently with other threads of the process.
- A process is sometimes referred to as “Task”. A thread is often referred to as a “Lightweight” process.
- A process has its own address space. A thread uses the process’s address space and shares it with the other threads of that process.
- A thread can communicate with other threads (of the same process) directly by using methods like wait(), notify(), notifyAll(). A process can communicate with another process by using inter-process communication (IPC/AIDL).
- New threads are easily created. However, the creation of new processes requires duplication of the parent process.
- Threads have control over the other threads of the same process. A process does not have control over the sibling process, it has control over its child processes only.
-
- Foldables screens
- 5G networks
- Smart Reply in notifications
- Dark Theme
- Gesture navigation
- Settings Panels
- Sharing shortcuts
- Privacy for users -> more control over location permission
- Security
- Camera and media -> Dynamic depth for photos
- Connectivity
- ART optimizations
-
- Using StringBuilder and StringBuffer/StringBuilder
-
- The string is an immutable object. StringBuffer is a mutable object.
- StringBuffer is synchronized whereas StringBuilder is not synchronized.
- Stronger type checks at compile time. A Java compiler applies strong type checking to generic code and issues errors if the code violates type safety.
- Yes!
- Cyclic dependencies without any live external reference are also eligible for GC.
- Resizable: Array is static in size that is fixed length data structure, One can not change the length after creating the Array object. ArrayList is dynamic in size.
- Multi-dimensional: Array can be multi dimensional , while ArrayList is always single dimensional.
- Primitives: ArrayList can not contains primitive data types (like int , float , double) it can only contains Object while Array can contain both primitive data types as well as objects.
- ThreadPool: represents a group of worker threads that are waiting for the job and reuse many times.
- Using ThreadPool minimizes the overhead due to thread creation. Thread objects use a significant amount of memory, and in a large-scale application, allocating and deallocating many thread objects creates a significant memory management overhead.
- Strong Reference: is the default Reference Object of a type/class
- Weak Reference: When an object in memory is reachable only by Weak Reference Objects, it becomes automatically eligible for GC.
- Soft Reference: Object is basically a weak Reference Object that remains in memory a bit more: normally, it resists GC cycle until memory is available and there is no risk of OutOfMemoryError
- synchronized: is one of the tools that make your code thread safe.
- synchronized methods can't be called in the same time from multiple threads.
- transient: modifier tells the Java object serialization subsystem to exclude the field when serializing an instance of the class
- volatile: modifier tells the JVM that writes to the field should always be synchronously flushed to memory, and that reads of the field should always read from memory.
- Use AtomicInteger.
- New, Runnable, Blocked, Waiting, TimedWaiting, Terminated.
- Make it immutable.
- NO
- In Java all primitives and objects are passed by value, meaning that their copy will be manipulated in the receiving method. But there is a caveat - when you pass an object reference into a method, a copy of this reference is made, so it still points to the same object! This means, that any changes that you make inside this object are retained, when the method exits.
- Initialization: is the process of the memory allocation, when a new variable is created.
- Instantiation: is the process of explicitly assigning definitive value to a declared variable.
- All objects are allocated on the heap area managed by the JVM. As long as an object is being referenced, the JVM considers it alive. Once an object is no longer referenced and therefore is not reachable by the application code, the garbage collector removes it and reclaims the unused memory.
- The Java volatile keyword is used to mark a Java variable as "being stored in main memory", and not from the CPU cache.
- keyword is used in serialization. If you define any data member as transient, it will not be serialized.
-
- power enum
-
- Android runtime (ART) is the managed runtime used by applications and some system services on Android.
- Dalvik is the predecessor of ART
- ART as the runtime executes the Dalvik Executable format and Dex bytecode specification.
-
- intent: is a message-passing mechanism between components of android except for Content Provider
- Sticky Intent: Sticks with Android, for future broadcast listeners
- Pending Intent: Will be used when someone wants to fire an intent in the future and maybe at that time the app is not alive anymore.
-
- Parcelable which is better for Android apps than Serializable which uses reflection
-
- Threads
- Async tasks
- Services
- Kotlin Coroutines
-
- IntentService is used for short tasks and a Service is for long ones
- IntentService runs in the App process but Service runs in a separate process.
-
- standard (default): The system always creates a new instance of the activity in the target task and routes the intent to it.
- singleTop: If an instance of the activity already exists at the top of the target task, the system routes the intent to that instance through a call to its onNewIntent() method, rather than creating a new instance of the activity.
- singleTask: The system creates the activity at the root of a new task and routes the intent to it. However, if an instance of the activity already exists, the system routes the intent to the existing instance through a call to its onNewIntent() method, rather than creating a new one.
- singleInstance: Same as "singleTask", except that the system doesn't launch any other activities into the task holding the instance. The activity is always the single and only member of its task.
- ProgGuard is a free obfuscation tool and DexGuard is the enterprise version of ProGuard.
- simply respond to broadcast messages from other applications or from the system itself
- must be Created and Registered within manifest or programmatically
- Activities: They dictate the UI and handle the user interaction to the smartphone screen.
- Services: They handle background processing associated with an application.
- Broadcast Receivers: They handle communication between Android OS and applications.
- Content Providers: They handle data and database management issues.
- Intents: Communication between the above-mentioned components is through Intents.
- Intents define the intention of an Application. S simple message object which is used to transfer data between activities.
- explicit intent: used to launch a specific application component
- implicit intent: specifies an action that can invoke any app on the device able to perform that action
- A Service is an application component that can perform long-running operations in the background and does not provide a user interface.
- a component can bind to a service to interact with it and even perform interprocess communication (IPC) if it is running in a separate process
- Binding services
- Using Callbacks interfaces
- They encapsulate data and provide it to applications through the single ContentResolver interface.
- Used for providing the content between applications
- A content provider is only required if you need to share data between multiple applications.
- The adapter is an interface whose implementations provide data and the display of that data done by the ListView/RecyclerView.
- ListViews and RecyclerView do not actually contain any data themselves. They are just a UI without data in it.
- They are both instances of Context , but the application instance is tied to the lifecycle of the application, while the Activity instance is tied to the lifecycle of the Activity.
- They have access to different information about the application environment.
- ~500kb
- TransactionTooLargeException may be thrown by the system.
-
- 9 Patch images are stretchable, repeatable images reduced to their smallest size
-
- Android Jetpack
- Retrofit2
- RxJava / RxAndroid
- Dagger2
- Timber
- Koin
- Picasso / Glide
- Gson
-
- Object-relational mapping is a technique (a.k.a. design pattern) of accessing a relational database from an object-oriented language
-
- Room
- DBFlow
- OrmLite
- Realm
-
- A library for reactive programming
- Works like wireframe between different layers and creates pipelines of data
-
- to avoid too much logic code in the UI layer and god activities
- reusable code that's easier to test
- avoid duplicated code between common views
- Easier to maintain
- we can test logic without using instrumentation tests
-
- Because we want to decouple the code from the implementation view.
- We want to abstract the framework used to write our presentation layer, regardless of any external dependency.
- We want to be able to easily change the implementation of view if needed.
- We want to follow the SOLID dependency rule to improve unit testability and in order to follow the dependency rule, high-level concepts (such as the presenter implementation) can't depend on low-level details (like the implementation view).
-
- following SOLID Dependency inversion principle
According to this concept a class should not configure its dependencies statically but should be configured from the outside = Inversion of Control
- useful for decoupling the whole system
- allow easier unit testing
- much easier moving things around and keeping classes small and simple
- help wiring different elements
In Clean Architecture by Robert C. Martin the dependency rule points strictly from the outermost layer/ring to the innermost.
-
- Unit testing involves breaking your program into pieces and subjecting each piece to a series of tests.
- These tests can run on a Continues Integration (CI) (namely GitHub actions, Circle Ci, or Travis Ci) and keep the code quality
-
- Hard dependencies, static methods.
Copyright 2020 Mohsen Mirhoseini Argi
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.