Giter Site home page Giter Site logo

alaz / wolt Goto Github PK

View Code? Open in Web Editor NEW
0.0 1.0 0.0 36 KB

Small programming task, home assignment from @woltapp

Home Page: https://wolt.com/

License: GNU General Public License v3.0

Scala 99.24% Shell 0.76%
interview-project scala dropwizard maven testing web-application api integration-testing home-assignment

wolt's Introduction

Home assignment project

TL;DR

Building

mvn compile

Testing

  • Unit tests: mvn test
  • Integration tests: mvn test -P it

Running

mvn exec:java

The main entry point will be http://localhost:8000/venue/hours/human (which should be interpreted as "give me human representation of a venue's open hours"). This endpoint accepts JSON and replies with text/plain per the task description.

Performing requests

Look into test-j Shell script to get an idea on how to invoke requests using curl. Try these:

./test-j example1
./test-j example2
./test-j half

Both time format and an order of days of week are controlled by locale setting (the motivation is explained below) In order to play with it, change locale in src/main/resources/config.yml and then run the requests again.

Notes

The best part of this task is that it is a real-life problem, so that one needs to tackle with trade offs, unclear specifications and guess a lot about all the stuff. There could be made lots of assumptions about the degree an input data could be wrong or what is an acceptable level of tolerance during processing.

The worst part of this task is that it is a real-life problem likely taken from a real production application. As such it has a lot of history behind: an environment, customers, boundary conditions, whatever else. It is impossible to know what was the struggle and what an interviewing team expects to find in an ideal solution. The necessity to guess has risks of missing something super important for interviewers or working around a problem they have never experienced and will likely consider an "overengineering".

  1. Where an input comes from? If the source is under control, then it is viable to perform strict validation of input data and fail fast on any misalignment detected. Otherwise, especially if the source is a human, then some level of tolerance might make sense.
  2. Who is the consumer of a result? Is it a human or another service (or frontend JS code)? In case of the former, it would be a good idea to localize the output and generate responses in various content types. If the latter, the output should be formatted for machine processing. Since the times in the examples are formatted in a very human-friendly manner, I am assuming localization is a good idea and thus I have preparations for i18n throughout the project.
  3. An output format in the task description is weird. On one hand it specifies time in a way which may be identified as English, with AM/PM as a time of day indication. On the other hand, the week starts with Monday, which is quite unusual for English. This conflict has no explanation in the task description and I chose to follow a fair localization approach here, that is both time format and an order of days of week should be chosen based on the locale that is currently specified in the application's configuration file.
  4. Both examples of output make me think that if a day is absent in the input data, then it should be absent in the resulting output. Contrary, in order to have Closed in the output, an input data must contain an empty array of hours. This is not clarified and I have implemented the algorithm in this way along with the test suite.
  5. To make an output even more human-readable, I would propose to skip the first AM/PM as long as they are the same. This way, 8 AM - 10 AM would become 8 - 10 AM. (Not implemented)

I shall be happy for you reviewing both comments in the code and the Git commit messages, as both contain a lot of commentary, including notes on technology choices and algorithm complexity.

Algorithm

Definitely the major complexity is a result of unfortunate selection of an input format that allows for numerous mistakes. The ways the input data could malformed are as follows (and not limited to these cases):

  • opening and closing hours may be not in pairs (e.g. duplicate types);
  • values may be not sorted;
  • ranges may be overlapping;
  • next day may not have a closing hour for the previous one.

It would be extremely interesting to design such an algorithm that recovers as much as possible. I have had an experience of this kind, see here.

In real life I would urge to reconsider the input format, but the best opportunity is not always readily available. For example if there are remote clients of the API, they are likely relying on it. And thus the format change will likely be postponed till the next major version release. WeekScheduleProcessor processor has a method to normalize the flawed format into a more reliable version of it, and its result type shows how a better input version could look like.

Web Application

An application part is mostly a boilerplate. The most interesting here is working around locale in a resource (aka. controller), because the output examples give a hint that it needs to be formatted in a human friendly manner (unlike JDK).

I have provided integration test suite also to make sure the serving layer is working properly.

In general any normal Web application needs so many parts done right and I am describing the ways of improvement further.

What's next

There are a lot of things to improve, but the scope of home assignment task is absolutely insufficient to address them all. See https://12factor.net for inspiration and my short list of proposed enhancemented follows -

  • Response types based on Accepts:
    • HTML, text, JSON.
    • Templating engine to simplify the controller's code.
  • I18n:
    • Closed message is not translated at all in the output. I could use my own scala-i18n of course, but it would be too much bragging I guess.
    • A good Web application should look into Accept-Language and provide translations based on the locale specified in there.
  • Deployment:
    • Produce fat JAR.
    • PORT should be taken from the environment
  • Security:
    • Limit the size of acceptable input JSON. It is now possible to upload garbage of any size.
    • Protect /admin.
  • Production
    • Logging
    • Health checks

License

This code is licensed under GPL.

Why GPL? I have a belief that home assignments based on a real company problem/code are utterly unethical for two main reasons:

  • the scope is usually vast. It is very hard to predict what really was the struggle, because we know neither environment nor customers nor boundary conditions. Trying to guess will eventually result in either missing something they expect to find in the solution or wasting your time to work around problems they have never experienced.

    For example the code of this project contains 510 lines of Scala code alone (not counting YAML, Markdown, Shell and JSON). It is a modest Web application with reasonable code structure, it has unit and integration tests, localization, configuration. And still it is incomplete and not even close to a sane production-ready Web application;

  • a result is immediately available for a company for free. They will look at various solutions, compare them, and copy ideas into their own code improving their service that earns money to them. And interviewers get paid for my time. (I have seen an idea here to offer $100 for home assignments. This looks quite fair to me).

For the reasons outlined above, I highly appreciate when a company spends its resources to create a synthetic task.

The only way to protect my work from stealing it is to (1) license it under GPL; (2) open it to the whole world. Voilà!

wolt's People

Contributors

alaz avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.