Playing together at Factorio is the best tech interview we've ever done

Lately, a lot of copies have been broken around technical interviews. Obviously, inverting a binary tree on a board has little to do with the practical skills of a real programmer. The primitive Fizzbuzz is still the most effective test. As a result, the attention to open source projects has increased, but it turned out that this is also not a very good indicator , because most professionals do not have time for them.



We have the most effective coding interview at our company today - it's usually some kind of homework for a few days in which the candidate is asked to fix a bug or implement a small feature. This is not good because it takes a long time and the person can get outside help (or google if the feature is common enough). On the other hand, some large companies have instead doubled the number of whiteboard (and algorithm) interviews, exposing future engineers to hours of online programming sessions with varying levels of invasive surveillance.



All of these interview techniques don't match a very simple metric: playing Factorio together... Going through the entire Factorio cycle is a near-perfect indicator of how well a person is at solving common technical problems. You can even customize the progress of the game based on the future position to better understand how the candidate will handle their role.



Factorio?



Factorio is an automation game. This trailer will probably be the best introduction , but essentially your job is to build an automated plant capable of launching a rocket into space.



Starting from scratch. You mine iron ore and stone by hand, build a smelter to smelt ore into iron plates, from which you can craft an automatic solid fuel drill. You can independently pick up iron ore from the drill and put it in the smelter, but it is more efficient to use an automatic conveyor. Then you can use the resulting iron to make another drill that automates coal mining. Then a conveyor is built to collect coal and a conveyor to transfer it to the drill. This tiny factory produces iron plates that can be used to make a third drill - and start mining copper ore, which allows you to craft copper plates, and from them you can make copper wire, which is necessary for a submersible pump. Combined with a steam boiler and steam engine, this gives us our first electricity.It can be used for a research center and the invention of new technologies such as an assembly machine. Once you unlock the assembly machines, you can use the hand-made wire to create an assembly machine that will automatically manufacture those wires.



In the end, you will unlock trains, robots and logistics systems that will help you deal with the growing logistics complexity of the game. Well, in the end you can launch a rocket into space.



Choice of direction



The game starts with no goal and almost no direction. The lead programmer should be able to learn the UI and define a goal, and then develop a plan to achieve it. The junior is expected to correctly complete the tasks set by the lead developer. The trainee is supposed to work with a mentor, but the junior should be able to fix underlying issues with their code on their own before asking for help from the senior. Middle must be able to work independently as soon as he is given an assignment, but he is not expected to do architectural design.



Specific expectations can be formulated as follows:



  • The trainee usually needs to be able to place a blueprint and connect it to something else, such as an ore deposit.

  • , . , .

  • , ( ) .

  • , , .




The most important aspect of software development is teamwork. This means coordinating with other people, meeting the needs of other people's projects, and collaborating with the team, rather than working on your own when you refuse to change your design to help integrate it with someone else's work. Naturally, such situations arise all the time in Factorio, because standard blueprints are limited to physical space. As a result, you need to carefully study the actions of other people, and sometimes adjust your design to fit within the size limits or adapt to some other people's drawing that took up more space than expected.



If the player withdraws into himself, starts doing everything himself or silently fixes problems, this will quickly incur the wrath of the team for the same reasons that colleagues are angry with cowboy programmers. Fortunately, Factorio has a built-in equivalent git blame



: it shows the last player to change any entity. Thus, if someone put a crutch on and did not inform the team about the problem, then when this crutch finally breaks, everyone will know who is to blame. If you want to win, you have to work closely with your teammates.



Debugging



Debugging is one of the main skills for a programmer. This is perhaps the most obvious parallel between Factorio and actual software development. Something can break very far from the actual source of the problem. The ability to quickly figure out a real problem is a critical skill, and the process of thinking is almost identical to tracking down the cause of a real program failure. If the picker stops working, you must first check the outgoing flows. Then check which ingredient is missing at the entrance. Then, trace the ingredient through the factory to find out where it is produced. And repeat the process over and over again, until nausea.



Debugging in Factorio gets complicated quickly. As soon as you build an oil refinery, you will engage in cracking, where there are three different pipes at the exit (fuel oil, diesel fuel and associated petroleum gas), and if any of them for some reason stalled, then the whole refinery stops working.



There have been times when the entire plant stopped because you started researching something that didn't require yellow science. As a result, you stopped using drone frames, which were no longer supplied with electric motors, where lubricant was used, for the production of which fuel oil was taken. As a result, the outlet pipe at the refinery stalled, which caused you to run out of associated petroleum gas (petrolium), which stopped the production of plastic. As a result, the production of the signal red wire was stopped - and the entire factory was out of order. Experienced players anticipate such scenarios and implement self-balancing oil cracking to ensure that the system is always balanced. Such a plant will stop only when the outlet pipe with associated gas is blocked.If a good programmer is given a broken oil refinery, they can usually trace the problem back to the source, understand what happened, and quickly try to find a solution. On the other hand, if a person just plops a couple of new tanks on the ground for no good reason (he is absolutely sure that the lubricant will always be needed), then this is a big red flag on the methods of solving problems in his programs.



Situations like this allow Factorio to accurately mimic the complex interdependencies that programmers typically deal with. The difficulty increases as new concepts are added to the gameplay. This is very similar to the increase in complexity from additional layers of abstraction in debugging a crash that could have occurred deep within one of the frameworks you are using.



Code Review



Often the original design needs to be tweaked to improve performance or throughput. Good programmers will not only accept criticism of their designs, but they will also take it into account in future work. If they disagree with the change, they will provide a specific explanation so that the team can more accurately reflect on the pros and cons of the proposed change.



Resisting feedback for no good reason is a well-known red flag. In addition, the programmer who is reluctant to accept the proposed changes and refuses to adjust future projects accordingly, causes caution. As a result, he will have to constantly be reminded of the need to adhere to some standard way of solving the problem. At the same time, the person does not explain why he does not like the proposed method. This is potentially a ticking time bomb for an organization because, unattended, he can quickly accumulate technical debt for his colleagues. These kinds of problems are almost impossible to grasp in a traditional interview, only during an internship.



Coding style and frameworks



Failure to follow advice is only part of a much larger problem when the programmer is unable to integrate properly into the existing structure. There are many ways to build a factory in Factorio, and each requires standard build methods. Failure to adhere to standards will quickly slow down the entire factory, often in subtle ways that are not obvious to the unwary developer.



The design of the main belt conveyor includes 4-8 conveyors, divided into two sections (for underground conveyors). It is placed in the center of the factory and all production takes place perpendicular to the belt. This design relies on several rules, violation of which can lead to complete chaos. First, you should always use a separator at the exit of the conveyor. You should never redirect an entire tape: empty space for another tape means you lose an entire pipeline of resources, even after an upgrade. Second, all factories must scale perpendicular to the main conveyor. Failure to scale quickly will result in either a huge waste of space or an inability to scale the production line because it is surrounded by other production lines.





Logistics network



There are different ways to build logistics networks. The easiest one is with passive supply chests. But there is another method - filter storage chests, which solves the garbage problem. Both methods require the correct placement of the restraints in the right places. Passive supply chests are usually limited by the chest space. You need to put a manipulator to the storage chests to connect the chest to the logistics network. And provide at least N items before installing the manipulator. If you forget about these steps, huge resources will be wasted. If a programmer constantly forgets about output limiters, it is a red flag that a person is careless about performance in real applications.



In other cases, the team may use pre-designed blueprints, such as a nuclear reactor design or a robotic drone factory (bot factory). They can be extremely difficult, but if you make an effort and figure it out, then they are extremely time-saving. Beware of candidates who do not want to customize a new element in the factory simply because they cannot trace complex control logic. Or who gives up trying to figure out the algorithm for the functioning of such a plant, despite the obvious advantages of drones over conveyors. Suboptimal drone plant design, source









Multithreading



Trains in Factorio are a direct analogue of multithreading: one train is one thread of execution, and each train intersection or stop is a place in memory where two threads can potentially write at the same time. Traffic lights are locks (or mutexes). All the bugs in the railroad network manifest themselves in the same way as the race condition in software, because they are literally the physical race condition. All tradeoffs apply here too - blocking too long decreases bandwidth. Improper design of traffic lights usually causes deadlocks, just like in software, because the end result is a cyclic interlocking dependency. The most common deadlock is when a train is too long and unexpectedly blocks a second intersection while waiting to enter the first.This second intersection then prevents another train from leaving, preventing the first intersection from being unblocked.



The number of tracks in the rail network corresponds to the number of CPU cores. It is difficult to scale a single track to more than a few lanes because the capacity of the entire system is very quickly limited, even with waiting areas. The most common design is a two-lane design, one lane to each side. This is where capacity problems will arise when it becomes necessary to constantly unload trains. Therefore, large rail networks have a minimum of four lanes, with the outer two acting as bypass tracks to avoid crossings whenever possible.



Traffic light problems in these systems can manifest themselves in a fantastic amount of time. A single missed traffic light on the same rail network once caused a deadlock after working correctly for two weeks . Likewise, in programs, the race condition can only appear once a month, when high concurrency of threads arises under heavy load.



Scaling



As with software, Factorio's production scaling introduces new challenges to the original blueprint design and often requires a complete overhaul to maximize productivity, with the installation of productivity modules and speed modules with beacons. Conveyors become a performance bottleneck even at maximum belt speed, forcing ways to split structures so that more belts can be inserted later, or to divide factories into modules.



Managing the logistics network itself becomes a logistics challenge at the end of the game due to the number of problems that expansive drone networks cause. Typically, you need to start segmenting the supply chain and either use trains to transport goods between segments, or build request and supply chests that will transfer goods across borders.



At the end of the game, train management requires a move from push architecture to pull architecture because push architecture cannot handle high bandwidth. This inevitably leads to the use of the Train Limit function and learning how to use logical networks to encode the basic logic so that the station requests a train only when it is really ready to completely fill it with resources, instead of the usual game tactics at the beginning of the game, when a bunch of trains are simply given the command to go. for iron. The new scheme minimizes the number of trains while ensuring that all stations on the network are served.



It often happens that the constraints on the input lines to the assembly machine and the speed limits of the manipulator require redesign of the factories around, just as high-speed computing requires knowledge of the bottlenecks in the CPU. These bottlenecks are almost never a problem until you reach a certain scale, but after that they start to limit performance.



Microservices and modules



Eventually, factories become so huge that they have to abandon a simple design with a main conveyor belt or spaghetti design and move to a more scalable structure. To reach the mega level, factories usually use either a train system or a modular system that roughly corresponds to microservices or plug-in architecture.



The train-based mega-base is sometimes referred to as a "city-block" design, where trains around the plant blocks control all entrances and exits. In this way, each individual block is isolated from all others, since all inputs are "clean" in the sense that they come from the rail network. This is almost identical to the architecture of microservices (over HTTP) or interprocess communication (IPC), with similar potential problems due to I / O delays, since results cannot be received all the time, they must be sent in "packets" or trains over the rail network.



The modular architecture tries to maintain some semblance of the main conveyor, but instead separates the belts at the factory and uses modular blocks that accept standard inputs and standard outputs. Sometimes this can be achieved entirely with drones, but usually materials have to be transported over long distances by conveyor belt. This is very similar to the module system for a monolithic application, with the same tradeoffs.



These megabases represent the top tier of the default Factorio server. Of course, there are many mods that make the game much more difficult.



Distributed systems



Space Exploration  is a completely reworked version of Factorio for space colonization. Here planets become resource constrained, requiring players to colonize other worlds and use rockets to transfer resources between planets. Due to the huge delay in the delivery of materials between planets, the coordination of these bases leads to problems similar to a globally distributed database system. Even in the logical network, you have to struggle with latency, because the automatic system loses sight of the elements that are launched but have not yet reached the target planet. If this is not taken into account, there are duplicate queries for all the required elements. Distributed systems face exactly the same problem when trying to ensure consistency between nodes.



Output



Overall, the software industry has no idea how to find and hire the best developers. Probably playing Factorio together was the best technical interview we've ever done. And this confuses us a lot . This interview is wildly impractical, taking over 20 hours in multiplayer the first time, or 8 hours for a team of experienced players. What can be learned from this? I do not know. We certainly can't switch to Factorio as an interview method - just as well just give the candidate homework.



But that's better than a whiteboard interview.



All Articles