Exam 2021-08-22

Here you find sample answers and marking guidelines to the questions on the exam 2021-08-22.

Point reduction for improper usage of upper-/lowercase characters

As explained in the exam instructions, answers not properly using upper-/lowercase characters will receive point reduction. This time it has only been set to 0.1 points for each answer that do not properly use upper-/lowercase characters, such as answers written with only lowercase characters. Next time this will likely increase.


Start by reading through all questions.

Max score is 30 points.

  • For grade 3, 40% of max score (12 points) is required.
  • For grade 4, 60% of max score (18 points) is required.
  • For grade 5, 80% of max score (24 points) is required.

You are not allowed to use anything else except:

  • The computer you sit at to only answer the questions on this exam.
  • A dictionary to translate to/from English from/to your native language.

Write your answers in either English or Swedish. If you write your answers in Swedish, make sure to not introduce any translation confusement. Write proper sentences (spelling, upper/lower case characters, punctuation, etc.). Answers that do not do this good enough/are vague/are not understandable cannot receive full score on the questions.

Answers that are more or less copies of sample answers given to you or copies of text found somewhere else will be rewarded 0 points. Use your own words to answer the questions.

Good luck!

Question 1 (1p)

Question

In client-side JavaScript, explain when you should use anElement.innerText and when you should use anElement.innerHTML.

Question 2 (1p)

Question

Explain the difference between:

document.querySelector('form').addEventListener('submit', handleSubmission)

And:

document.querySelector('form').addEventListener('submit', handleSubmission())

Question 3 (1p)

Question

Does the code below contain a XSS vulnerability hackers can exploit? Justify your answer.

app.js

// ...
app.get('/sum', function(request, response){
  
  const model = {
    x: request.query.x,
    y: request.query.y,
    sum: request.query.x + request.query.y
  }
  
  response.render("sum.hbs", model)
  
})
// ...

views/sum.hbs

<h1>Sum</h1>
{{{x}}} + {{{y}}} = {{{sum}}}

Question 4 (1p)

Question

Match each HTTP status code with its reason phrase.

Status codes: 200 201 400 401 405

Reason Phrases: Method Not Allowed OK Created Bad Request Unauthorized

All needs to be matched correct to get any points.

Question 5 (1p)

Question

Name three different events that can fire on a webpage, and explain when they fire.

Question 6 (1p)

Question

Carl is assigned the task to design a REST API. To delete movies in a specific genre a specific year, he decides clients should send an HTTP DELETE request to /movies, add the header Content-Type: application/json and in the body of the request add {"year": 2000, "genre": "drama"} (change 2000 and "drama" to desired values).

Is this a good or bad REST API design? Justify your answer.

Note: You don't need to worry about authorization in this question.

Question 7 (1p)

Question

Explain what a docker container and a docker image is.

Question 8 (2p)

Question

Explain to a web developer that knows nothing about scaling web applications how horizontal scaling works, and how you would solve the problems that comes with it. Be detailed.

Question 9 (2p)

Question

Alice is assigned the task to design a REST API clients can use to login and then create new blogposts belonging to that account. She decides that when a user logs in, the client obtains an access token (THE.ACCESS.TOKEN) containing the user's account id, which can be used to act on the behalf of that user. Then when the user wants to create a new blogpost belonging to her own account, the client sends an HTTP POST request to /blogposts with the headers Authorization: Bearer THE.ACCESS.TOKEN and Content-Type: application/json, and in the body pass {"title": "The actual title", "content": "The blogpost text."}.

Is this a good or bad design? Justify your answer.

Question 10 (2p)

Question

Explain what MVC is, which parts it consists of and what each part is used for. Then also explain how web applications use MVC.

Don't write any code.

Question 11 (3p)

Question

Explain what a three-layered architecture is, which parts it consists of and what each part is used for. Then also explain how web applications use a three-layered architecture.

Don't write any code.

Question 12 (1p)

Question

In a three-layered architecture for a web application, is it only in the Presentation Layer we need to think about security vulnerabilities hackers can take advantage of? Justify your answer.

Question 13 (2p)

Question

Explain what a JWT is, which parts it consists of and what each part is used for. Make sure to mention all details so the reader understand why they are secure to use.

Question 14 (1p)

Question

In a three layered architecture, give an example of an implementation detail that should not be exposed to the next layer. Choose whichever layer you want. Justify your answer.

Question 15 (2p)

Question

The function addBlogpost() is in a blogpost repository in the Data Access Layer of a three layered application that stores its resources in a relational database. On the website, users can create their own accounts and then create blogposts belonging to their own account.

function addBlogpost(blogpost, callback){
    
    const query = `
        INSERT INTO blogposts (accountId, title, content) VALUES(?, ?, ?)
    `
    
    const values = [
        blogpost.accountId,
        blogpost.title,
        blogpost.content
    ]
    
    db.query(query, values, function(error, results){
        if(error){
            callback("DB Communication error.")
        }else{
            callback(null, results.insertId)
        }
    })
    
}

What's wrong with the current implementation of the function? Explain how you would solve that problem (in words, don't write any code).

Question 16 (2p)

Question

Describe a case where you need to add CORS support to your web application. Then also describe how you would add support for it (in general, and not in a specific framework).

Question 17 (1p)

Question

Explain what a CORS preflight request is, and give example of when one is needed.

Question 18 (4p)

Question

The function getMovieById() can be used to fetch a movie with a specific id asynchronously from the server like this:

getMovieById(3, function(movie, error){
    if(error){
        // Couldn't fetch the movie.
    }else{
        // Do something with the movie.
        // movie = {id: 3, title: "Hello!", producerId: 123, categoryId: 45}
    }
})

The function getProducerById() can be used to fetch a producer with a specific id asynchronously from the server like this:

getProducerById(5, function(producer, error){
    if(error){
        // Couldn't fetch the producer.
    }else{
        // Do something with the producer.
        // producer = {id: 5, name: "Robin"}
    }
})

The function getCategoryById() can be used to fetch a category with a specific id asynchronously from the server like this:

getCategoryById(7, function(category, error){
    if(error){
        // Couldn't fetch the category.
    }else{
        // Do something with the category.
        // category = {id: 7, name: "Comedy"}
    }
})

Create the function getMovieByIdWithProducerAndCategory(), that fetches a movie with a specific id, and then fetches the producer and the category the movie belongs too, so it can be used like this:

getMovieByIdWithProducerAndCategory(4, function(movie, producer, category, error){
    if(error){
        // Couldn't fetch all three resources.
    }else{
        // Could fetch all three resources.
        // movie = {id: 4, title: "Hello!", producerId: 32, categoryId: 45}
        // producer = {id: 32, name: "Jessie"}
        // category = {id: 45, name: "Horror"}
    }
})

Important details:

  • The callback function should be called only one time.
  • As soon as any function gives an error, the callback function should be called with that error (the other arguments should be null).
  • The data should be fetched as fast as possible (loading times should be minimized).

Question 19 (1p)

Question

The JavaScript function setTimeout() can be used to schedule a call to a function in the future. Example:

setTimeout(function(){
    // The code here in the function runs 1000 ms later.
}, 1000)

The function getInfo() can be used to fetch some info from a server. Sample usage:

getInfo(function(info){
    // This code runs when we have got the info.
})

As you can see, getInfo() is asynchronous, and it might take a few seconds before it has fetched the info from the server and passed it to the callback function.

Your task is to implement the function getInfoOrFail() that works according to the sample usage below.

getInfoOrFail(function(didGetInfo, info){ // didGetInfo is a boolean.
    if(!didGetInfo){
        // The server did not send back info within 3 seconds.
    }else{
        // We got info within 3 seconds.
    }
})

The callback function passed to getInfoOrFail() should only be called once.