Exam 2023-01-14

Here you find sample answers and marking guidelines to the questions on the exam 2023-01-14.


Peter will not visit the exam. If you find any question unclear, ask an exam supervisor (tentavakt in Swedish) to call Peter, and he will try to clarify.

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 any aids except:

  • The computer you sit at to only enter answers to the questions on this exam
  • A dictionary to translate to/from English from/to your native language
  • Pen and paper to sketch with (should not be submitted)

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 will not 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!

HTTP

Question 1 (1p)

Question

Name the method one should use in HTTP when the request is about:

  1. Retrieving a resource
  2. Creating a new resource
  3. Updating a resource

Note: This question is about HTTP when used properly, and has nothing to do with HTML, web browsers, nor websites.

You will get:

  • 0.33 points for each correct name (spelling must be correct)

Sample answer

  1. GET
  2. POST
  3. PUT

Marking guidelines

  • 0.33 points for each correct name (spelling must be correct)

Question 2 (1p)

Question

In HTTP, explain what application/x-www-form-urlencoded is, and when it's used.

Note: This question is about HTTP when used properly, and has nothing to do with HTML, web browsers, nor websites.

Sample answer

application/x-www-form-urlencoded is a name of a data format. It can be used as value for headers in HTTP requests and HTTP responses, for example the Accept header and the Content-Type header.

Marking guidelines

  • 0.5 points for explaining what it is (data format/MIME type)
  • 0.5 points for when it's used
  • -0.1 points for writing something incorrect or confusing

Question 3 (1p)

Question

In HTTP, what would be a good URI one can use to delete the blogpost with id 175?

Note: This question is about HTTP when used properly, and has nothing to do with HTML, web browsers, nor websites.

Sample answer

In HTTP, the URI should identify the resource the request is about, so the URI could for example be /blogposts/175.

Marking guidelines

  • 1 point for a URI only identifying the resource to be deleted, and nothing else
  • -0.25 points for using an id placeholder in the URI (HTTP don't contain the placeholder concept, only some web frameworks do that)

Question 4 (1p)

Question

Write the HTTP status code for the following reason phrases:

  1. Internal Server Error
  2. Not Found
  3. OK
  4. Bad Request

Note: This question is about HTTP when used properly, and has nothing to do with HTML, web browsers, nor websites.

You'll get:

  • 0.25 points for each correct answer

Sample answer

  1. 500
  2. 404
  3. 200
  4. 400

Marking guidelines

  • 0.25 points for each correct answer

HTML

Question 5 (1p)

Question

Place the lines of code below in such order that they form a valid HTML5 document (only place one line of code in each box).

  • <html>
  • <h1>Welcome!</h1>
  • </body>
  • <head>
  • </head>
  • <title>Welcome!</title>
  • <!DOCTYPE html>
  • </html>
  • <body>

Note: All must be correct to get points on this question.

Sample answer

<!DOCTYPE html>
<html>
    <head>
        <title>Welcome!</title>
    </head>
    <body>
        <h1>Welcome!</h1>
    </body>
</html>

Marking guidelines

  • 1 point for all in correct order

Question 6 (1p)

Question

When writing an HTML tutorial on a website, one often wants to write tags like <p> that are shown as text, instead of being interpreted as a paragraph element by the web browser. Explain what you need to do to make the web browser display the text <p> instead of interpreting it as the start tag for a paragraph.

Note: This question is only about HTML, and has nothing to do with Handlebars.

Sample answer

You need to write < and > as their character entities instead, since these characters have special meaning in HTML (they are part of the syntax for tags). So you would write:

&lt;p&gt;

To make the web browser display:

<p>

Marking guidelines

  • 0.9 points for saying < and > needs to be written as their character entities/"escaped"
  • 0.1 points for showing that you know how character entities are written (doesn't need to be perfect)

Question 7 (1p)

Question

Write the name of an HTML tag that can be placed in the <head> element and that causes the web browser to send an HTTP request when it receives the HTML code for that tag.

Note: Just write the name of the tag; do not include < and >.

Sample answer

link

Marking guidelines

  • 1 point for a valid tag name

Example of wrong tags

Some students answered img. That is wrong, because the <head> element should only contain meta information about the webpage, and not content.

Some students answered a. That is wrong for the same reason as img. Also, an <a> element does not cause the web browser to send a HTTP request when it receives the HTML code for it, but when the user clicks on it, so it's also wrong answer for that reason.

Question 8 (2p)

Question

Name 4 different block elements in HTML.

Note: Just write the name of the tag; do not include < and >.

You'll get:

  • 0.5 points for each correct answer (spelling needs to be correct)
  • -0.25 points for each incorrect answer
  • At lest 0 points on the question

Sample answer

  1. h1
  2. p
  3. ul
  4. div

Marking guidelines

  • 0.5 points for each correct answer (spelling needs to be correct)
  • -0.25 points for each incorrect answer
  • At lest 0 points on the question

Question 9 (1p)

Question

If a user comes to a website with the form below and submits it without making any changes to it, what would the URI of the request look like? Write the URI as your answer.

<form action="/sum" method="GET">
   Number 1: <input type="number" name="x" value="123">
   Number 2: <input type="number" name="y" value="456">
   <input type="submit" value="Compute sum!">
</form>

Sample answer

/sum?x=123&y=456

Marking guidelines

  • 0.5 points for correct x name and value (123)
  • 0.5 points for correct y name and value (456)
  • Point reductions for errors:
    • -0.1 points for surrounding value with quotes
    • -0.1 points for using && or . instead of &
    • -0.25 points for missing /sum in the beginning
    • -0.25 points for not having ?

Question 10 (1p)

Question

To make a webpage display some text as a header, you can use the <h1> element:

<h1>Sunny weather this weekend!</h1>

Another solution is to use a <div> element that you then style to look like a header using CSS. Explain why it's better to use the <h1> solution instead of the <div> + CSS solution.

Sample answer

The purpose of HTML is to mark up what type of data different text represents. <h1> will mark the text as a header, so search engines, text to speech tools, etc. know this and can function properly. That information would be lost if you used the <div> + CSS solution instead, so search engines and other tools will not be able to understand that that part of the text on the webpage is a header.

Extra info

<div> has no semantic meaning at all in HTML, and should only be used in those cases we need extra block elements in our code to be able to implement the GUI we want using CSS.

Marking guidelines

  • 1 point for the <div> + CSS solution is missing the semantic meaning of the text

CSS

Question 11 (1p)

Question

Name and describe 2 different CSS properties of your choice except color. For each, provide also an example of a value it can have, and explain the result of using the property with that value.

Sample answer

The CSS property background-color determines which background color the element should have. For example, the value red would give the element a red background.

The CSS property font-size determines how big the text in the element should be. For example, the value 16px would make the text in the element 16 pixels big.

Marking guidelines

  • 1 point for an answer that is largely correct
  • Point reductions for errors:
    • -0.5 points for only one good declaration
    • -0.25 points for no description of the result of applying the value to the property

Question 12 (1p)

Question

What color will the text in the paragraph in the HTML code below have?

<style>
    
    p{
        color: red;
    }
    
    #p{
        color: green;
    }
    
    .p{
        color: blue;
    }
    
</style>

<p>Some text.</p>

Sample answer

green

Marking guidelines

  • 1 point for a correct answer

Question 13 (1p)

Question

Here is some CSS code:

div div#em.p{
  width: 50%;
}

Write HTML code that contains a match for the CSS selector in the code above. Write as little HTML code as possibly (don't write any extra elements or attributes that are not needed).

Note: You should only write the HTML code found in the <body> element (including the <body> element), you should not write the code for an entire HTML document.

Sample answer

<body>
    <div>
        <div id="em" class="p">I'm selected!</span>
    </div>
</body>

Marking guidelines

  • For answers that are close to correct:
    • 0.5 points for <div> in <body>
    • 0.5 points for <div id="em" class="p"> in <div>
    • Point reductions for errors:
      • -0.1 points for each unnecessary HTML element
      • -0.1 points for each unnecessary HTML attribute
      • -0.25 points for each wrong value in/missing HTML attribute
      • -0.5 points for syntax error

Question 14 (1p)

Question

Write a CSS selector that selects the element in the HTML code below that contains the text SELECT ME. The selector should select only that element, and no other.

<body>
    <p class="p">Here is <span class="s">SELECT ME</span> <span>some text</span>.</p>
    <div class="p">Here is some more text, <span class="s">and some more</span>.</div>
    <p>Here is <span class="s">some other</span> text.</p>
</body>

Sample answer

p.p .s

Marking guidelines

  • 1 point for an answer that works

Website

Question 15 (2p)

Question

On a website, when a none-logged in user tries to access a page only logged in users should be able to access, the user is redirected to the login page. When the user has logged in on the login page, she is currently always taken to the start page.

Alice is assigned the task to change this, so the user instead comes to the page she first tried to access (the one she was redirected from) after she has successfully logged in. There exist different ways this functionality can be implemented. Suggest the best way you can think of to Alice.

Sample answer

When redirecting the user to the login page, the web application needs to remember the URI for the page the user was on, so the web application later can redirect the user back to that page using that URI after she has successfully logged in. That URI can be remembered in different ways. The best way is to simply to remember it in a query string parameter when redirecting the user to the login page. That way, no additional data need to be stored neither on the client or the server, and users can bookmark the login page leading to a specific page after having logged in.

Marking guidelines

  • 2 points for storing the "redirect back" URI in a query string parameter

OR:

  • 1.5 points for suggesting another way to store the "redirect back" URI that the server has access to

Question 16 (1p)

Question

On a website containing blogposts spread out over different pages using pagination, the Handlebars code below in a view file is used to show a link to the current page the user is on:

<a href="/projects/pages/{{currentPage}}">{{currentPage}}</a>

The currentPage value is a number that comes from the model when the Handlebars view is rendered, and all works good.

Bob is then assigned the task to add a link to the next page with blogposts. To do that, Bob changes the code above to:

<a href="/projects/pages/{{currentPage}}">{{currentPage}}</a>
<a href="/projects/pages/{{currentPage + 1}}">{{currentPage + 1}}</a>

Will this work? If yes, then state so. If no, then explain what's wrong, and explain what Bob can do to make the code work as it should.

Sample answer

We can't use arbitrary JavaScript expressions in Handlebars expressions, so {{a + b}} in Handlebars doesn't work. Instead, Bob should add currentPage + 1 to the model (in the JS code), for example in a property called nextPage, and then in the Handlebar file use:

<a href="/projects/pages/{{currentPage}}">{{currentPage}}</a>
<a href="/projects/pages/{{nextPage}}">{{nextPage}}</a>

Marking guidelines

  • 0.5 points for explaining what's wrong
  • 0.5 points for suggesting how to solve it

Question 17 (1p)

Question

On a website, give an example of something that is better stored in a cookie than in the user's session.

Sample answer

Since sessions are short lived, they can't be used to remember information about the user that survives for a long time (for example when visiting the website two different days). But with cookies, such information can be remembered for a long time, so if the website is a store where users can put products in their online basket, then storing those products in a cookie instead of the session can be beneficial (if you want that information to be remembered for long).

Marking guidelines

  • 1 point for a valid example

OR:

  • 0.5 points for a valid example that doesn't explain what to store in the cookie

Security

Question 18 (1p)

Question

On a website where only the admin should be able to login and delete resources, the following Express code is used to handle requests for deleting a blogpost with a specific id (request.session.isLoggedIn is true when the user is logged in as the admin, and false otherwise):

//...

app.post('/blogposts/:id/delete', function(request, response){
    
    const id = request.params.id
    
    if(!request.session.isLoggedIn){
        response.redirect('/login')
    }
    
    const query = "DELETE FROM blogposts WHERE id = ?"
    const values = [id]
    
    db.run(query, values, function(error){
        
        if(error){
            response.render("internal-error.hbs")
        }else{
            response.redirect('/blogposts')
        }
        
    })
    
})

//...

Is the code good or bad? If yes, then justify why it's good. If bad, then explain why it's bad, and suggest how the code should change to become better.

Sample answer

The code is bad. If someone sends a POST request to /blogposts/45/delete without being logged in, the blogpost with id 45 will still be deleted, since the code execution doesn't stop at line 8, but the rest of the code in the function is executed as well. A return statement is needed on line 8, or the rest of the code in the function needs to be put in an else statement.

Marking guidelines

  • 0.5 points for explaining the authorization bug that exist
  • 0.5 points for suggesting how to fix the bug

Question 19 (2p)

Question

On a website where the admin can create blogposts, an SQLite table is used to store all the blogposts. The table looks like this (content is not shown, since that one is quite long, and not all rows are shown):

keywordtitlecontentisPublished
htmlHTML is fun!...1
cssCSS is fun too!...0
jsJS is most fun!...0

The idea is that a user should only be able to read the blogposts that have the value 1 for isPublished.

When receiving an HTTP request to send back a blogpost with a specific keyword, it is handled like this:

app.js

app.get('/blogposts/:keyword', function(request, response){
    
    const keyword = request.params.keyword
    
    const query = "SELECT * FROM blogposts WHERE isPublished = 1 AND keyword = '"+keyword+"'"
    
    db.get(query, function(error, blogpost){
        // Let us assume no database error occurred, so we ignore that.
        
        const model = {
            blogpost
        }
        
        response.render('blogpost.hbs', model)
        
    })
    
})

views/blogpost.hbs

<h1>{{blogpost.title}}</h1>
<p>{{blogpost.content}}</p>

As your answer, write a URL a hacker can send to read a blogpost that hasn't been published yet (for example a URL that would send back the blogpost with keyword css).

Sample answer

/blogposts/' OR keyword='css

Marking guidelines

  • 2 points for an answer that largely works
  • -0.5 points for each error in an answer that almost works, such as:
    • Not have inserted single quotes correct, e.g. /blogposts/ -1 OR keyword=css

Question 20 (1p)

Question

On a website where only the admin should be able to create new blogposts, the following code is used (request.session.isLoggedIn is true when the user is logged in as the admin, and false otherwise):

app.js:

//...

app.get('/blogposts/create', function(request, response){
    const model = {
        isLoggedIn: request.session.isLoggedIn
    }
    response.render('create-blogpost.hbs', model)
})

app.post('/blogposts/create', function(request, response){
    
    const title = request.body.title
    const content = request.body.content
    
    const query = "INSERT INTO blogposts (title, content) VALUES (?, ?)"
    const values = [title, content]
    
    db.run(query, values, function(error){
        if(error){
            response.render('internal-server-error.hbs')
        }else{
            response.redirect('/blogposts/'+this.lastID)
        }
    })
    
})

//...

views/create-blogpost.hbs:

{{#if isLoggedIn}}
    <form method="POST" action="/blogposts/create">
        Title: <input type="text" name="title">
        Content: <input type="text" name="content">
        <input type="submit" value="Create">
    </form>
{{else}}
    <p>Error: have to be logged in to see the create blogpost form.</p>
{{/if}}

Is this part of the website implemented in a secure way? Justify your answer.

Sample answer

No, that part of the website is not implemented in a good way; anyone can send a POST request to /blogposts/create to create a new blogpost. Sure, only the admin can retrieve the create blogpost form, but that doesn't stop a hacker from being able to send an equivalent POST request from his own computer.

Marking guidelines

  • 1 point for correct answer

OR:

  • 0.5 points for correct answer and stating other things as weaknesses without explaining how/being incorrect about those

Database

Question 21 (1p)

Question

Below is the table humans found in an SQLite database (not all rows are shown).

idnameage
1Alcie10
2Bob20
3Claire15

Write an SQL query that sets name to Alice for all humans that currently has the name Alcie.

Note: Don't use placeholders, like ?, in your query. You don't need to worry about SQL injections, since this is a pure database question, and has nothing to do with web applications.

Sample answer

UPDATE humans SET name = "Alice" WHERE name = "Alcie"

(in SQLite, when testing for equality, both = and == can be used)

Marking guidelines

  • 1 point for an answer that is largely correct

OR:

  • 0.5 points for a query that contains most required SQL parts, but in wrong order

Point reductions for errors:

  • -0.1 points for updating the name to Alicie (it should be updated to Alice)
  • -0.1 points using Alice in the WHERE clause
  • -0.1 points for not using quotes around strings

Question 22 (1p)

Question

Below is the table humans found in an SQLite database (not all rows are shown).

idnameage
1Alice10
2Bob20
3Claire15

Write an SQL query that deletes all humans that are younger than 18 (those who are 18 should not be deleted).

Note: Don't use placeholders, like ?, in your query. You don't need to worry about SQL injections, since this is a pure database question, and has nothing to do with web applications.

Sample answer

DELETE FROM humans WHERE age < 18

Marking guidelines

  • 1 point for an answer that is largely correct

OR:

  • 0.5 points for a query that contains most required SQL parts, but in wrong order

Point reductions for errors:

  • -0.1 points for using DELETE something FROM, or only DELETE, instead of DELETE FROM
  • -0.25 points for writing JavaScript code that contains a syntax error

JavaScript

Question 23 (1p)

Question

Implement the JavaScript function getProductUpTo(lastFactor), that receives an integer as argument, and returns the product of the integers between 1 and the integer it receives (including 1 and the received integer).

Sample usage:

getProductUpTo(3) // --> 6 (1 * 2 * 3)
getProductUpTo(5) // --> 120 (1 * 2 * 3 * 4 * 5)
getProductUpTo(1) // --> 1

Sample answer

function getProductUpTo(lastFactor){
    
    let product = 1
    
    for(let factor=1; factor<=lastFactor; factor++){
        product *= factor
    }
    
    return product
    
}

Marking guidelines

  • 1 point for an answer that largely works
  • Point reduction for small mistakes:
    • -0.1 points for using global variable
    • -0.1 points for using bad name on variable
    • -0.1 points for product starting on 0
    • -0.1 points for iteration starting on 0 instead of 1

OR:

  • 0.25 points for iterating over correct values

Question 24 (1p)

Question

Implement the JavaScript function areAll5(numbers), that receives an array with numbers and returns:

  • true if all the values in the array is 5
  • false otherwise

Sample usage:

areAll5([3, 7, 1, 8]) // --> false
areAll5([5, 3, 5, 5]) // --> false
areAll5([5, 5, 5]) // --> true
areAll5([]) // --> true

(if the array is empty, then returning true is what makes most sense, so that's how your implementation should work as well)

Sample answer

function areAll5(numbers){
    
    for(const number of numbers){
        if(number != 5){
            return false
        }
    }
    
    return true
    
}

Marking guidelines

  • 1 point for an answer that largely works
  • Point reduction for smaller mistakes:
    • -0.1 points for using global variable
    • -0.25 points for iterating over indexes instead of values

OR:

  • 0.25 points for correctly using the for of loop with good names

Question 25 (2p)

Question

In JavaScript, a movie with a title, a category and a runtime (in minutes) can be represented as an object like this:

const movie = {
    title: "Dumb and Dumber",
    category: "comedy"
    runtimeInMinutes: 106
}

Implement the function getMinutesToWatchMoviesInCategory(movies, category), which receives an array with movie objects and a category, and returns the number of minutes it takes to watch all the movies that has that category.

Sample usage:

getMinutesToWatchMoviesInCategory([
    {title: "Dumb and Dumber", category: "comedy" runtimeInMinutes: 106},
    {title: "Shrek", category: "comedy" runtimeInMinutes: 90},
    {title: "Titanic", category: "drama" runtimeInMinutes: 195},
    {title: "Shrek 2", category: "comedy" runtimeInMinutes: 92},
], "comedy") // --> 288 (106 + 90 + 92)

Sample answer

function getMinutesToWatchMoviesInCategory(movies, category){
    
    let minutes = 0
    
    for(const movie of movies){
        if(movie.category == category){
            minutes += movie.runtimeInMinutes
        }
    }
    
    return minutes
    
}

Marking guidelines

  • 2 points for an answer that largely works
  • Point reduction for smaller mistakes:
    • -0.25 points for iterating over indexes instead of values

Question 26 (1p)

Question

Alice has created the synchronous function add1(number):

function add1(number){
    return number + 1
}

Rewrite this function so the caller of the function receives the incremented number through a callback function instead of as a return value.

Then show that you know how to use the new version of the function by using it to increment 5 to 6, and then log the incremented number in the console using console.log().

Sample answer

function add1(number, callback){
    callback(number + 1)
}

add1(5, function(incrementedNumber){
    console.log(incrementedNumber)
})

Marking guidelines

  • 0.5 points for implementing the function with the callback correct
    • -0.25 points for not defining the callback parameter
  • 0.5 points for using the function with the callback correct