
This video provides an entire overview of the course.
Get a big picture of Kotlin
• Get a Kotlin Overview
• Understand the Evolution of Kotlin
• Learn Where to use Kotlin
Install the following software’s on your Windows system
• Install Java Development Kit ( JDK ) for JVM
• Install IntelliJ IDEA
Install the following software’s on your MAC system
• Install Java Development Kit ( JDK ) for JVM
• Install IntelliJ IDEA
Install the following software’s on your Linux system
• Install Java Development Kit ( JDK ) for JVM
• Install IntelliJ IDEA
Create and run your first Kotlin app in IntelliJ IDEA
• Understand what is main function
• Understand what is a Comment
• Understand How to print a String and numbers
Learn what happens behind the curtain when you compile and run a Kotlin file
• Understand How Kotlin compiler compiles code
• Understand How Byte Code is executed in runtime environment
Explore variables and data types in Kotlin
• Explore how much memory each data type consumes
• Understand the Difference between mutable and immutable values
Get hands-on experience on how to use variables and data types in IntelliJ IDEA
• Understand what are Variables and Data Types
• Learn about Immutable and Mutable Values
Print messages using String templates by applying interpolation
• Understand what are String templates and Interpolation
Explore IF ELSE conditional statements along with IF expressions
• Learn all about conditional If else statements
Explore WHEN conditional statements, Ranges and using WHEN as expression
• Learn all the in and outs of the WHEN conditional statements
Explore various types of Loops in Kotlin along with example
• Use FOR Loop
• Use WHILE Loop
• Use DO WHILE Loop
Learn how to handle exceptions in Kotlin
• Explore try, catch and finally block
• Check out how to organise files in an Kotlin project using Packages
Explore functions in Kotlin
• Understand what is a function
• Understand why we need functions
• Learn How to declare functions
Get hands-on experience on how to use and declare a function in IntelliJ IDEA
• Write programs using functions
Explore what is meant by default parameters
• Assign default values to the formal parameters of functions
Explore the advantages to using Named Parameters to avoid errors
• Learn all about Named Parameters
Implement Tail Recursive functions in Kotlin
• Explore problem statement while using recursions
• Find a solution to avoid Stack Overflow Exception
Get introduced to Object Oriented Programming in Kotlin
• Understand what is a Class
• Learn How to create objects
• Understand the properties and function in a class?
Use primary constructor and init block to initialise properties of a class
• Learn how to use a Constructor
• Understand what is a init block
In this video, we will see how Kotlin has great support for Inheritance.
• Explore why do we need inheritance
• Syntax and basics to implement Inheritance in Kotlin
In this video, we will see how Kotlin supports Interface similar to any other OOPs language
• Explore abstract methods in Interface
• Explore open methods of Interface
• Define abstract property in Interface
Sometimes we create class to hold data. You’ll explore how to create such classes in this video.
• Explore how to compare data of two class objects using data classes
In this video, we will see that Kotlin has its own way to declare static variables and functions.
• What is singleton?
• What is object declaration?
• What is companion object?
In this video, we will learn that an object declaration is a way to define singleton objects in Kotlin which is very similar to Statics in Java.
• Learn how to declare objects
In this video, we will learn that when an object is declared within a class then it is marked companion.
• Explore another way to declare static variables and function in Kotlin.
Explore what is a Lambda expression and Higher-Order Function.
• Check out basics and syntax to declare a Lambda Expression.
• Learn How to pass a lambda to a Higher-Order function
Explore the implementation of Lambda expression and Higher-Order Function.
• Get a hands on demo for implementing Higher order functions and Lambdas
In this video, we will learn what are Closures and how to access a outer scope variable within a Lambda
• Understand that closures are variables defined in outer scope of lambda expression
Explore how to use ‘it’ keyword when we have one parameter in a Lambda expression
• Understand all about the “it” keyword
Explore using ‘with’ and ‘apply’ keyword to initialise a objects properties.
• Explore the difference between ‘with’ and ‘apply’ keywords.
Learn to implement Arrays in Kotlin
• Get Section overview.
• Explore how elements are indexed in an Array.
• Explore different variants of for loop to print out elements of an Array
In this video, we will understand that the most basic component of a Collection framework in Kotlin is a List.
• Learn how to implement mutable and immutable lists.
• Perform basic operations on List such as add, remove, replace and delete all.
In this video, we will understand that Collection framework provides a special method of ‘filter’ to get the desired elements from a Collection.
• Explore how to use ‘filter’ on a list.
In this video, we will learn that The elements of a collection can be modified using ‘map’ function.
• Learn how to create a new Collection by modifying the values from the original Collection.
In this video, we will learn that A Set is a unordered collection of elements that does not support duplicate elements.
• Learn to perform basic operations on Set such as add, remove, replace and clear all.
In this video, we will learn that A Map is a Collection that holds object in the form of key-value pair.
• Learn to perform basic operations on Map such as add, delete, replace and clear all.
In this video, we will see how Kotlin has great support for Nullable types.
• Explore how to handle null values and avoid Null Pointer Exception.
• Implement Safe Calls, Safe Calls with Let and Non-null assertion operator.
In this video, we will learn how Kotlin supports extensions which allow developers to add a function to an existing class without modifying the class itself.
• Understand Extension functions
In this video we will summarise the course
• Course Summary
This video provides an overview of the entire course.
Creating pure functions to solve simple problems
Learn basic Kotlin syntax
Create functions with no arguments
Create functions with arguments
Understanding difference between pure functions and functions with side effects
Create global state
Create functions that interact with global state
Understand the behavior of functions with side effects
Mutable data - source of side effects. Reducing amount of side effects by using immutable data classes
Learn Kotlin data classes syntax
Create immutable data class
Use copy constructor to modify immutable data
Using recursive functions to solve problems
Understand recursion
Break problem into 2 small ones
Implement recursive algorithm
Generating Fibonacci number by given position
Understand problem
Implement solution using recursion
Test solution
Statically typed code is hard to reuse. Generics makes statically typed code reusable.
Learn Kotlin syntax for Generics.
Implement simple data wrapper without generics
Implement improved data wrapper using generics
How to create function without name in Kotlin? Using lambda expression
Learn Kotlin syntax for lambda expressions
Create lambda and assigning it to variable
Understand lambda type signatures
How could we pass functions to another function? Yes using higher-order functions
Learn Kotlin syntax for higher-order functions
Create function that access function as argument
Create function that returns function as argument
How to delay execution until result is needed. Using lazy evaluation.
Create ordinary function that accept ready to use arguments
Improve the function using lambda expressions
Implement sequence generator using lazy evaluation technics
How to create lambda from named function. Using function reference
Create lambda expression from maned function manually
Create lambda expression from named function using function reference
Use function reference in combination with higher-order functions
How to add properties to existing functions. Using Monads.
Understand requirements for Monad.
Create simple monad container
Explore Optional monad from JDK
How to return multiple arguments from function. Using destructive declaration
Create and destructing Pair object
Destruct Pair in lambda expressions
Create classes that supports destruction
How to reduce number of arguments of a function - by using partial application
Understand use case
Implement straight forward approach
Implement reusable extension function
How to express function with multiple arguments only by functions with one argument - using curried functions
Understand use case
Implement straight forward approach
Implement reusable extension function
How to glue two functions together - using forward compose operation
Understand use case
Implement straight forward approach
Implement reusable extension function
How do we store data in list, using functional programming principles
Understand structure of functional list
Implement list
Create and use list
How to make implementation of functional list useful, by adding more operators
Define list of operators we want to implement
Implement Operators using recursion
Use implemented operators together
How we could create restricted classes hierarchy in Kotin - by using sealed classes
Feature syntax description
Look into use cases Use cases
Use with when operator
How we do branching by complex conditions - by using pattern matching techniques
Describe pattern matching
Describe Kotlin limitations
Go through examples
Refresh what we’ve learned so far
Create small functions
Use functional programming techniques
Improve your code by using advanced Kotlin features
How to make concurrent programming easier - by using coroutines.
What is coroutines
Create the project with kotlinx.coroutines library
Use coroutines
Many of basic functional components are not included in standard library
Library description
Exploring Arrow website
Going through available library modules
How to use simple Monads
Creating project
Adding Arrow library dependency
Going through examples of using Option, Either and Ior monads
How we could manage side effects in functional programming - by using IO monad
Monad description
Monad creation
Handle successful execution and failure
How do we use DI pattern in functional style - by using Reader Monad
Monad description
Monad creation
Go through operators
How we could manage side effects in functional programming - by using IO monad
Monad description
Monad creation
Handle successful execution and failure
How do we design our app to leverage functional concepts
Describe JavaFx
Describe unidirectional data flow concept
Design high level components
How do we make JavaFx, Arrow and coroutines work together
Checkout project using git
Implement await extension function for IO monad
Use IO Monad inside coroutines
How do we start implementing our app - by designing interfaces of our components
Introduce middleware in initial design
Showcase UI and functional of the app
Create interfaces
How do we make our components work
Implement UI
Implement state
Implement logic
How to glue this components together
Instantiate components
Late binding
Handle user actions
To do we ensure this components works correctly - by writing tests
Write tests for reducer
Write tests for store
Write tests for middleware
This video provides an overview of the entire course.
Functions can be overly long with additional unnecessary scaffolding. That makes it more difficult to understand what the code is doing. The goal here is to reduce the code to a single line.
Check the function body for conversion
Replace a block body with an expression body
Verify that the function is two lines or less
If cascades can be unnecessarily long with scaffolding, which takes time to understand the code. Replace ifwith when.
Replace a block body with an expression body
Convert an if cascade to a when expression
Verify when the expression runs with no errors
Often when calling a function, the parameters lack detail. Also, overloaded functions can result in a lot of unnecessary duplicated code. Use named arguments to add parameter info and default parameters to reduce the number of overloaded functions.
Add named arguments to the function
Add default parameters to the function
Verify that the amended function works with a different number of parameters
Adding functionality to a class can be a sizable task involving inheriting a new class. Adding an extension function allows more functionality to be added with creating an inherited class.
Define an extensional function
Call the extension function
Verify that there are no syntax errors and the code runs with the expected result
It is common that, after creating a class instance, a number of methods of the object will need to be called. That means the object named will be called a number of times. By using a number of scoping methods, the references to object names can be removed.
Add a with function to remove object names
Use the apply extension for method initialization
Successful calls of with and apply functions, with the expected result
Null pointer exceptions can be catastrophic for applications. Kotlin methods will be provided for removing null pointer exceptions in a graceful and concise manner.
Use the Elvis operator for handling nulls in a concise manner
Use Smart Cast to remove ClassCastException
Run the code to verify solutions and remove the exceptions
Using the standard If condition to check for null makes the code verbose and unnecessarily long. A solution will be provided for handling the null expression in a clearer, more concise way.
Replace the If condition with let to make your code more concise
Combine let with Elvis for returning default values
Run the code and confirm that let returns same result
Removing null elements from a collection is a common situation. But this can involve several operations, making code long, verbose, and open to errors. Provide solutions for removing null elements which are concise and clear.
Apply filterNotNull for removing nulls from a collection
Use the listOfNotNull function to create a null-free collection
Run the code for both solutions to confirm that lists have no nulls
When an object is shared between different threads, its data can be corrupted if the threads try to access it at the same time. Provide solutions to control access to the shared object from multiple threads.
Add the synchronized function to the thread definitions
Replace this function with the Reentrant withLock extension function
Check both solutions and maintain BasicThreadOne access of the shared object
Using a class instance for shared data between multiple threads will cause problems if more than one instance is created. Use a singleton to create a single instance of a class.
Run the class code to confirm multiple list instances
Replace the class with the object singleton
Run the singleton code to check for single list
Classes can consist of multiple constructors, which tend to be verbose and take time for the reader to absorb. Provide a method of initializing classes’ properties in a single line, making the code concise.
Implement a primary constructor for initializing properties
Initialize the properties inside the primary constructor parenthesis
Run the code to check whether the class properties are initialized
Extending a framework class with multiple constructors can be complex and difficult. Provide the Kotlin recommended approach for extending a class with multiple constructors.
Describe how to implement secondary constructors
Describe how to pass secondary constructor parameters to the super constructor
Run code to check whether the super constructor properties are initialized
When providing additional logic to a property that stores a value, recursion can occur, resulting in an exception. Provide a solution to remove recursion issues.
Provide a backing field to the property getter
Provide a backing field to the property setter
Run code to test that recursion has been removed
Creating a sub-class which will be used in a localized place involved an additional amount of code. Provide an alternative solution to using a sub-class.
Use an object expression to create an anonymous object
Override the superclass method in the anonymous constructor
Start the thread to verify that the overridden method executes
When using a class with multiple secondary constructors, additional code will be required for creating instances of the class. Provide an alternative solution to creating class instances using multiple constructors.
Replace secondary constructors with primary constructor and companion object
Add a factory pattern to the companion object
Verify that the factory methods provide the same result as secondary constructors
Using traditional functions can result in unnecessary, similar code. Find an alternative method to defining and calling functions.
Replace the function call with a lambda
Add a function type to the lambda result
Run code to verify that the result is same as the original
Java does not support passing a function to another function as an argument. Find a solution where a function can be passed to another function.
Create a function with a function type as its parameter
Replace the function argument with a lambda expression
Call the function type parameter from inside the function
There can be confusion between read-only versus immutable collections related to thread safety. Create code to check read-only and immutable collections for thread safety.
Write code that checks if read-only contents can be modified
Write code that checks if immutable contents can be modified
Run code to identify which collection is thread-safe
Filtering and modifying the contents of a collection are common operations. Find Kotlin solutions to simplify this.
Implement the Kotlin filter extension function
Implement the Kotlin map extension function
Run code for both functions and check the result collection
The class toString, equals, and hashCode methods are very common methods. But they need to be implemented manually, which involves a lot of additional boilerplate code. Find an alternative method to simplify the creation of the toString, equals, and hashCode methods.
Manually create toString, equals, and hashCode methods to illustrate effort
Replace manual methods with the data class
Run code using the data class to verify the same output
There are a number of functions available which can provide the same result. But the time taken to complete the operation may not be the same. Find the method for recording the time taken for executing a function. Find a way of generating the equivalent Java code to help identify any potential performance issues.
Use the measureTimeMillis function to record elapsed time
Use Kotlin Bytecode tool to display equivalent Java code
Find slow-running function and identify cause from java code
Loading an application with large initialization data can result in slow startup times of the application. This can be mitigated by delaying the loading of the list until required. Find a solution whereby the data can be loaded on demand.
Manually implement a lazy initialization pattern with a backing property
Replace the pattern with the Kotlin lazy delegate
Run code and check that both results are the same
When passing a lambda to a higher order function as an argument, extra methods can be generated and boxing and unboxing can occur, resulting in additional performance overheads. Find a solution which removes the additional methods and any boxing/unboxing that may occur when passing a lambda as a function argument.
Create a capturing lambda expression which creates extra methods in Java
Create a lambda that implements boxing and unboxing in Java
Inline functions and verify the removal of methods, boxing, and unboxing in Java
Creating public properties in a companion object will result in additional getter and setter methods being created. This can make an additional performance overhead. Find a solution which removes the creation of the extra setter and getter methods.
Add a const keyword to public property
Add a @JvmField annotation to the public property
View equivalent Java code to confirm the removal of methods
Running multiple operations, such as chaining filter and map calls on large collections, can result in poor performance. Find a solution to improve performance when running multiple operations on large collections.
Use Kotlin Bytecode tool to identify performance issues
Replace the implementation with a sequence
View equivalent Java code to confirm the removal of temporary lists
When calling Android APIs using Kotlin, additional boilerplate code is required for some simple method calls. The Android Toast function, for example, requires an additional sub-method, context, time duration, and then an apply call. The solution will be to replace Android Toast with the KTX core toast method.
Highlight the issue by demonstrating the Android Toast call
Replace Android Toast with KTX core toast
Run KTX core toast to verify the same output
When making SQLite transactions, a number of calls need to be made in a try-finally harness to ensure that the SQLite transaction is completed. The harness, along with three SQLite transaction calls, adds a significant amount of boilerplate code and complexity. Replace the Android SQLite transactions with the KTX SQLite module.
Demonstrate the problem by executing a SQLite transaction
Replace the Android SQLite transaction with a KTX SQLite transaction
Execute the KTX SQLite transaction code to verify the output
When replacing Android fragments using the FragmentManager, additional methods such as beginTransaction and commit are required. Yet again, boilerplate code! Replace the Android Fragment transaction code with the KTX fragment transaction.
Demonstrate the issue by implementing an Android fragment transaction
Replace the Android transaction with the KTX fragment transaction
Run code to verify that the operation completes the same
Creating certain types of collections such as ArraySet will involve code to manually create a value and then populate the items in the array one at a time, before returning the populated ArraySet. Use the KTX collection module to create an ArraySet with a single method call.
Demonstrate the issue by implementing an ArraySet the Android way
Replace the Android code with the KTX collection arraySetOf method
Run code to verify that the same ArraySet collection is created
When implementing background tasks, the device API level and capabilities will have to be checked before deciding on a solution, which could be JobScheduler, Firebase JobDispatcher, or AlarmManager. The WorkManager will do the API and capability check, along with selecting the correct background implementation.
Implement a worker to populate a collection in a background task
Implement a worker that provides notification updates from the background task
Send data and observe updates from the workers
This video provides an overview of the entire course.
In this video, we will see what are the language features and how does it look like compared to Java.
Who stands behind the language, what are the features
First look at the language syntax
Compared to Java, language is more concise and less verbose
This video explains what are the language features, how does it look like compared to Java.
Explore Kotlin compiler targets
Execute on the JVM
Use Java build tools for compilation
What can you build with Kotlin?
Use of Kotlin in Android apps
Use of Kotlin in web apps
Use of Kotlin in desktop apps
How to setup the IDE?
Install Kotlin plugin
Configure Gradle for Kotlin
Create first Kotlin file
In this video, we will see what the properties in Kotlin are and learn how they are different from Java.
Explore keywords for declaring properties
Learn to declare a read only property, and a mutable property
Understand how to call and initialize properties from Kotlin and Java
What are the functions and function variables in Kotlin?
Learn to declare a function and explore keywords for declaring variables
Explore default visibility modifiers and study the read only and mutable variables
Understand the use of functions in Kotlin and use variables inside the functions
What are default function arguments?
Learn default functions arguments
Annotate functions to be used from Java
Explore calling functions with default arguments
What are named function arguments?
Learn to define named function arguments
Understand how to call them in Kotlin
Explore calling functions with named arguments
What are Control flow structures in Kotlin and how are they different from Java?
Explore If and When statements in Kotlin
Study Do/While loops and For loops
Learn to handle exceptions with try/catch/finally
What are classes and constructors?
Learn to declare a class
Declare primary and secondary constructor
Initialize classes
In this video, we will see which visibility modifiers are available.
Explore Kotlin’s visibility modifiers
Learn the differences between Kotlin and Java
Declare inner classes
What are the Interfaces in Kotlin?
Explore interface declaration
Implement the interfaces
Learn the overriding methods
In this video, we will learn what is object Oriented programming in Kotlin and extending classes.
Explore extending classes
Declare abstract classes
Explore the overriding methods
What is Kotlin’s null safety?
Achieve null safety in Kotlin
Explore operators for dealing with null able types
Understand smart casting
What are compiler generated methods?
Define data classes
Explore hashCode, equals and toString methods generation
Understand equals and reference equals checks
What is object keyword in Kotlin?
Learn to create singletons
Create companion objects
Create anonymous inner classes
What are lambdas and how they improve the readability of the code?
Explore the code without lambdas and its verbosity
Learn about lambda syntax
Defining lambdas
What are the Function types in Kotlin?
Declaring a function type
Invoking function types
Explore member references
What are the useful functions from the standard library API?
Explore the collection extension functions
Learn about functional like programing with collections extension functions
Explore other useful functions
What is the functionality in existing types?
Explore extension functions syntax
Calling extension functions
Calling extension functions from Java
How to invoke lambdas on a “Receiver” object?
Learn about receiver functions syntax
Invoking receiver functions
Explore receiver functions from standard library
What are inline functions and how do they reduce the overhead of lambdas?
Explore inline functions syntax
See how in lining works
Learn about in lining restrictions
What are Generics in Kotlin?
Understand the basics of Generics
Explore Classes and methods with generic type parameters
Putting constraints to generic types
How to avoid Type erasure limitations?
Explore type erasure
Access generic parameter at runtime with reified generics
Implement reified generics
What is operator overloading in Kotlin?
Understand the functioning of operator overloading in Kotlin
Explore syntax for operator overloading
Learn from the examples of overloaded operators with collections
What are delegated properties and what are their benefits?
Reusing code with delegated properties
Explore delegated properties requirements and syntax
Implement delegated properties with Kotlin compiler
What are the differences between Java and Kotlin type system?
Understand the Kotlin base type
Explore List and map interfaces in Kotlin
Use reflection on Kotlin types
In this video, we will understand the options provided by Kotlin for concurrent programming.
Ensuring thread safety
Kotlin uses functions and annotations
Using Java concurrent constructs in Kotlin
The aim of this video is to explain coroutines.
Problems with current state of asynchronous programming
Coroutines are suspend able functions
How compiler compiles coroutines
In this video, we will use library functions to start coroutines.
Explore what is needed to execute suspend able function
Using library functions launch and async
Creating a coroutine from a API that uses callbacks
This video will help you learn from the examples of Coroutine usage in Android.
Adding coroutines to Android Studio project
Using Android coroutine context to launch a coroutine
Exception handling and coroutine cancellation
In this video, we will understand what domain specific languages are.
DSL’s specialize in specific domains
Internal and external DSL’s
Learn from the example of HTML building DSL with Kotlin
The aim of this video is to explain Kotlin features that make building DSLs easy.
Learn about the receiver functions
Explore the extension functions
Understand the infix methods
In this video, you will learn how to use Kotlin to build a validation DSL.
Explaining classes needed for this DSL
Using receiver, extension and infix function
Syntax of validation DSL
Kotlin is a statically typed language whose syntax is more expressive and concise than Java’s. Kotlin has been adopted by Google as a first-class language for developing Android apps. Since then, Kotlin has gained a huge popularity worldwide among developers due to its highly appreciable features therefore it also helps to build amazing applications in an easy and effective way.
This course is an easy-to-follow guide with a step-by-step approach which will get you up and running with Kotlin basics and fundamentals such as variables, data types, string templates, expressions, null values, and loops. You will also learn to design application structures using functional programming concepts and implement business logic using tools provided by Arrow library. Next you will be introduced to using the Android Studio IDE which covers the concepts such as functions, lambdas, properties, object oriented code, safety aspects and type parameterization, Microservices, testing, concurrency which will guide you to write Kotlin’s code to production. Finally you will be mastering to integrate Kotlin in any existing Android project built using C++ or Java.
By the end of the course, you’ll be able to write faster & cleaner code to build your own robust program in Kotlin to make your life easy as a Kotlin developer. Also you will be more proficient in using Kotlin for any kind of app development.
Contents and Overview
This training program includes 2 complete courses, carefully chosen to give you the most comprehensive training possible.
The first course, Learn Kotlin Programming starts by showing you how to set up the Kotlin environment and install Intellij IDEA to write Kotlin code. After that, the course dives into the Kotlin basics and fundamentals such as variables, data types, string templates, expressions, null values, and loops. Moving on, you’ll learn how to write functions in Kotlin. You’ll explore Kotlin as an Object-Oriented Language by exploring interfaces and various Kotlin classes . Next you’ll dive into Functional programming in Kotlin using Lambdas and higher-order functions . Finally, you’ll explore the collection framework and perform operations such as filtering and sorting using Predicates and FlatMaps in Kotlin. By the end of the course, you’ll be able to build your own robust program in Kotlin.
In the second course, Hands On Functional Kotlin demonstrates Kotlin language features and use-cases as well as popular functional programming concepts and techniques. You will learn to design application structures using functional programming concepts and implement business logic using tools provided by Arrow library.
In the third course, Kotlin – Tips, Tricks, and Techniques you will discover new possibilities with Kotlin and improve your app development process. In this course, you will work with interesting tools and techniques on examples which you can adopt straightaway. You will speed up your development with less coding and get faster results. By the end of this course, you will be able to write faster, cleaner code and make your life easy as a Kotlin developer.
In the fourth course, Mastering Kotlin for Android Development you will begin with exploring all the features of Kotlin language that make the language better alternative to Java. It will show you the environment setup, and the difficulty level will grow steadily with the features covered next. Moving on, we’ll introduce you to using the IntelliJ IDE, which plays an integral role in Kotlin development. We’ll cover Kotlin’s basic programming concepts such as functions, lambdas, properties, object-oriented code, safety aspects, type parameterization, and finally concurrency, which will guide you to write Kotlin’s code to production. By the end of the video, you will be proficient in using Kotlin for any kind of app development.
About the Authors
Book of Brains creates and distributes high-quality technology training content. We aim to teach technology the way it is used in industry and the professional world. Our trained team of professionals delivers hands-on workshops and training content for mobile as well web development technologies. We constantly monitor current industry trends and keep our training materials and workshops up to date.
Stepan Goncharov lives in Singapore. He is involved in helping local developers to grow by sharing knowledge and organizing Kotlin Singapore User Group events. He has been engineering apps and games for Android since 2008. He has experience in QA, as a product manager, marketer, blogger, consultant, engineering manager, and much more. He has been involved in the development of apps that nobody uses and apps with millions of users worldwide. He currently works at Grab, actively uses Kotlin and Rx, and spends more and more time contributing to OSS. When he is not recording video courses or organizing events for developers, he travels around South East Asia skiing on a wakeboard.
Nigel Henshaw is a mobile software developer who, as well as providing software development services, loves to share his knowledge through his YouTube channel and website. Nigel originates from New Zealand, where he started out as an electrician. After one too many electric shocks, he wisely decided on a career change. After completing a two-year diploma in Computer Science and Technology at the Auckland University of Technology, Nigel relocated to London for new opportunities. He landed a job as a test engineer with a pioneering tech company called Psion, who were one of the first to develop hand-held devices and mobile operating systems. Before too long, Nigel was transferred to the base porting team and found himself in the midst of porting operating systems and writing device drivers with Symbian OS using C++.
Nigel has experienced many wonderful opportunities through the software industry, working in the UK, Scotland, and Japan. He has held jobs as a software engineer, consultant, project manager, and general manager of a remote development site. In his spare time, Nigel is currently learning Japanese, enjoys cycling and running, and likes to finish off the day by soaking in a Japanese hot spring.
Marko Devcic is a Software Engineer currently working as an Android Developer for Austrian company mySugr in Vienna. He has a Master's degree in Engineering from University of Zagreb in Croatia. Over the years, he has worked with various technologies and languages, mostly C# and Java. He is passionate about technology and software development. He loves reading about programming languages and writing simple and clean code. In his spare time, he writes code for his personal projects, and contributes to open source projects. You can follow him on Github (username deva666). He also likes to write about Kotlin, C#, and programming in general on his web page.