Interview Questions
19 Dec 2019In this post I would like to outline some of my experience as a technical interviewer with candidates and what I like to ask most of the cases. This won’t be me answering some interview questions that you can find with simple Google search, even though I don’t know why most candidates won’t look for them before showing up in an technical interview. I will try to answer my own concepts though.
1). Solid principles and design patterns
When we are talking about solid principals and design patterns usually candidates rarely know some of them. I have to note here that mentioning only the singleton pattern is by no means any sufficient answer and not that it is used only for database connection abstraction. The truth is I don’t know them either by definitions as I go by the role better to understand than to memorize. But, however one should posses the ability to recognize some of the code structure and understand what the component does rather than drill down in the code to get the general idea. That’s why we build them and why we are trying to implement them in order to absorb knowledge and follow some rules we’ve all agreed on. In most of developers’ code regardless of the languages you can find some “if-else” statements coupled with some database queries. When we would have than in a function it is the first indicator of lacking design patterns concepts.
One way to do is to compare the facade and factory pattern, the first one that would be a shortening of a bigger code structure underneath and is the most preferable way in case when you want to create a new object, instead write a static method that would build up that object and call upon the methods that are enforced by the interface your class implements. The factory on the other side would just give an object back upon some conditioning so instead of having the if-else and even worse duplicating that piece of code in different place abstract it into a class that will do only that.
The other one we would use is an observer pattern, having an event that would be wrapped around couple of listeners that will be called. Each of these listeners would implement a method enforced again by an interface of each of these listeners/classes which can be of-course of different type satisfying the polymorphism and making sure that after adding a new listener you would have to implement that method. The loop of those listeners when the event is fired and pointing to this interface method would allow us to easily extend the business logic with new listener and only write code in this new class’s method and in this way we won’t need to go into the main business model where this loop is happening and possible some other stuff, but just new class and write code in the method. This is maybe the most significant point in writing code that would be easily expendable and closed for modification (based on solid) that we won’t spend too much time understanding the if-else and grow the functions and classes, but horizontally adding more classes keeping the main logic intact-ed. This will result in writing less unit tests as well and will bring more assurance of the unbreakableness of our code.
Another point is using the abstract classes with enforcing the implementation of abstract method in child classes, but making sure that you would prefer composition over inheritance. You really don’t what to create objects that having more levels of inheritance just in order to get some piece of information, this chain makes more sense only as a component to satisfy larger business logic. This is lately more preferably in newer programming languages avoiding the nesting of more chain classes and instead having implementations and traits. The main idea is also about knowing what goes in the function and what goes out with using type hints (strong types) as well as type hint interfaces instead of actual objects.
The pub/sub pattern as opposite to the observer pattern would give us async operations and we would use a message broker with queuing system. When a question would be asked how would you handle 100K records in a loop and do a work for them, like sending a notification would you do them in a single request or would you break them in more chunks and do bulk operations. Of-course having bulk operations is preferable way to do it as updating that many records and having in mind that each of them might have a third party interaction, fetching data with curl ect, so having queues would be beneficial of better managements re-tries, fall-backs and having things done a lot more quicker and efficient.
Another point I would like to bring is the structure of the code and writing more generic code. This is closely related to the architectural concepts of the product as I believe that well structured components are easily moved out from the main code-base into another service for better scalability and re-usability. But we won’t be able to write more general code if we don’t get involved more deeply into design patterns.
2). Front-End state management
What kind of application would you use state management system on your front-end? There are many new FE frameworks today and mostly the applications are split into FE and BE parts with using some FE to intercept and BE only sending the json. There are some candidates that have written vanilla JavaScript even writing prototype inheritance but keeping up with then newly framework in JavaScript world is not an easy task. Having experience with framework such as Vue, React or Angular is very good but keeping the code structured into actions, mutations, store is also very important. Otherwise working only with JavaScript usually developers are left with on document ready jQuery and lots of functions and as much as they are immutable having in mind that we need a switch to data driven approach instead of manipulating the DOM and attaching events once it is rendered. Your application might have lots of forms, inputs from your users or simple creating a data that you would use in some other service and it is highly recommended that you would do it using a FE framework. It would be nearly an impossible task to do it with pure JavaScript, but on the other hand you still want to keep the using object oriented approach in your code. Usually I would like to know how functional programming is implemented beyond map, filter, reduce and this discussion might as well be for both BE and FE. Closures, promises as well, sending async requests to the BE which will load the page on FE a lot faster. In todays world all the request must be async or model your endpoints in a way that they don’t need to talk to each other in rare cases sending additional request on promise resolved success. How one would make the FE real-time as everything should happen instantly that would bring up the usage of web sockets and nodeJs.
3). Caching, benefits over load balancing and load balancer only due to availability zones
What of the most interesting questions to be asked is if you would prefer load balancing over caching and why? Of-course the best answer in tech interviews is depends and than you somehow elaborate things that you’ve worked on, but here I would get the sense of the developer’s experience mainly with caching. My perspective is that in today’s web world everything is cached and hitting some service/server with millions of request won’t last long, even more what is your read/write ratio. This is also closely related to the SOA architecture and using the queues other than making your users’ requests less resourceful. In most cases your product will have to be split and you will end up with having a read cluster for your users that will read cached data rather than hitting the database and invalidate that cache in timely fashion or upon user action immediately through the queue system. All the other services will eventually sync data through the other services in your network and refresh the caching system. It is interesting today as using Redis, Varnish, Elastic-search that you can scale easily with amazon web services can be much beneficial to have your product highly performant and making a service that would sync your data to these tools is not that much of problem, each of the programming languages has library that offer more than enough in terms of functionality for better user experience. Moving your read clusters to AWS might be also a good idea to make sure that load balancing is performed not just to split the traffic on your servers but also due to high availability in case of a crash of some of the servers in one of the Geo locations, so your devops might want to put one server in one zone (europe) and other in other zone (us) and depending on the traffic in those zones make additional node cluster in that zone, but re-routing the traffic one some of those zones is down.
4). Discussion about SOA
Instead of jumping through hops one should cache the data on the service and invalidated on demand, but having in mind a proper race condition resolution. One resource might get deleted in one service and due to that because it was used in other service which might be affecting hundreds of rows/data. I still strongly believe even though it is much easier to keep to manage a monolith I would opt for a service oriented architecture and move the complexity in the background. The biggest challenge is of-course designing your processes/consumers and making sure what function goes to what consumers without interference with other ongoing processes. It is also very important of designing what should be a GET and what a POST request between the services and how you would move the data around. In case of single application you would use the message broker to offload some of the work from the main process and for the user not to wait, but in SOA you would use the queues as well for moving data around your services, duplicating, invalidating cache ect. You would probably end-up with a load balancer over your reading servers and the other services give more cpu or ram on demand. Also depending on the nature of the task might be a better choise to use nodejs for non-blocking tasks even though the other languages offer async/await packages , as well as queues based packages for concurrent processing. Async operations are single threaded so will take advantage of the cpu idle time while waiting for a response, possible achieving occupying multiple cpus with mutlipe requests and gather them with callback, while the concurrent/parallel with the queues can swamp all the cpus with work on independent tasks.
5). Immutability public protected private
One interesting question that is usually asked is the public vs protected vs private methods and most of them half-know it in terms of accessibility, whey then again why bother just keep everything public who cares right. Well the thing is that sometimes I would like to enforce the usable of a piece of code wrapped around a private method and make sure that the logic goes through there and even make it final so it can’t be overridden. That would mean that when I get a new version of this class or component I know that other developers won’t just easily append if-else where they want but keep it strictly and make sure they override what needs to be overridden with keeping backwards compatibility.
Those are also other topic of discussions, for one last thing this is a screen-shot of rules to live by in code reviews