← Academy Blog

Training marathon 2022

Translated into:

Join 2022 Binary Studio Academy entrance test prep marathon! Check our weekly blog posts with sample questions, answers, and detailed explanations.

  • [.NET] What type should return this method?
    public static {ReturnType} GetNums()
    {
        var number = 0;
        while (true)
        {
            if (number > 5)
                yield break;
            yield return number++;
        }
    }

    a) void
    b) IEnumerable<int>
    c) List<int>
    d) int
    e) object

    Expand the correct answer with an explanation

    This method uses two special keywords yield break and yield return. The method in which such keywords are used is called an iterator.

    The iterator can be named (as in our case) or unnamed. An unnamed iterator is declared for the class by defining the GetEnumerator() method. In this case, instances of this class can be used directly in foreach or linq operations.

    The difference between an iterator and a regular method is that the method returns a single value with return, and the iterator returns several (or none at all). An iterator will return as many values as the yield return is called. The yield return call can be written several times in a row or, as in the task, use a loop. The yield break keyword means that no more elements do need to be returned, even if the more yield return follow. Stopping an iterator using a yield break is optional. For example, we can rewrite the code from the task like this:

    while (number < 5)
    {
        yield return number++;
    }

    Also interesting is the interception of errors in the iterator. The yield keyword cannot be used inside a try-catch block. Instead, you must first get the value to return, and only then call the yield, for example:

    foreach (var item in data)
    {
        try
        {
            result = PrepareData(item);
        }
        catch (Exception ex)
        {
            Console.Error.WriteLine(ex.Message);
            continue;
        }
        yield return result;
    }

    The previous paragraph already mentioned where you can use the result that the iterator returns – in the foreach construction and for linq operations. Therefore, the value returned by the iterator must be an IEnumerable interface. Typification for IEnumerable must correspond to the type that returns by yield return. УIn our case it is IEnumerable<int>.

    Correct answer: b) IEnumerable<int>.

  • [JS/Mobile] What will be printed on the console?

    a)

    for (var i = 0; i < 5; i++) {
      setTimeout(() => console.log(i), 1);
    }

    b)

    for (let i = 0; i < 5; i++) {
      setTimeout(() => console.log(i), 1);
    }

    a) a) 0 1 2 3 4; b) 5 5 5 5 5
    b) a) 5 5 5 5 5; b) 0 1 2 3 4
    c) a) 5 5 5 5 5; b) 5 5 5 5 5

    Expand the correct answer with an explanation

    First we need to understand what is the difference between var and let. The scope of a variable declared with var is its current execution context. Which can be limited to the function or be global to variables declared outside the function. However, var has one weakness. Let's take a look at the example below.

    var greeting = 'say hi';
    var times = 4;
    
    if (times > 3) {
      var greeting = 'say Hello instead';
    }
    
    console.log(greeting); // "say Hello instead"

    As you can see, since the times > 3 condition returns true, the value of the greeter variable is redefined as say Hello instead. If you unconsciously use greeting elsewhere in your code, you will get unpredictable results. This can cause a lot of bugs in your code. This is why there is a need for let and const.

    let has block scope. A block is a piece of code delimited by curly braces {}. Everything inside the curly braces belongs to the block. Thus, a variable declared in a block with let will only be available within that block. Let's now look at another example.

    let times = 4;
    
    if (times > 3) {
      let greeting = 'say Hello';
      console.log(greeting); // "say Hello"
    }
    
    console.log(greeting); // ReferenceError: greeting is not defined

    From this example, we can see that trying to use greeting outside of a block (the curly braces within which the variable was defined) will return an error, since let is block scoped.

    So, back to the task. Since setTimeout is executed asynchronously, and one millisecond is a very long time for a computer, the passed callback will be called after the loop has completed.

    In the case of a, the variable i is declared with the var keyword, so it is global. It will be overwritten every iteration, and when setTimeout is called, it will have its last value of 5, so 5 5 5 5 5 will be sequently printed to the console .

    In the case of b, the variable i is already declared via let and has block scope. It means that it’s only available in the scope of the for loop. During each iteration, the variable will have a new value, and after the code executing, 0 1 2 3 4 will be displayed in the console.

    Therefore, the correct answer is a) 5 5 5 5 5; b) 0 1 2 3 4

  • [QA] How many test cases are required to achieve 100% decision coverage?
    function WhatIsGreater(a, b) {
      let result;
      if (a > b) {
        result = 'a is greater than b';
      }
      if (b > a) {
        result = 'a is less than b';
      } else {
        result = 'friendship :)';
      }
      return result;
    }

    a) 1 test is enough
    b) 2 tests are required for full coverage
    c) The required number of tests cannot be determined due to lack of information
    d) Requires 3 tests

    Expand the correct answer with an explanation

    To answer this question you need to know the basics of flowcharts. Flowcharts use special shapes to represent different types of actions or steps in a process.

    Process Code

    Thanks to the flowchart, we can clearly see how our code works and analyze how many tests are needed to achieve 100% Decision/Branch coverage. The main aim of the Decision/Branch coverage is to cover all the branches at least once (true and false). That is, you need to find and cover a minimum number of ways.

    Picture of our code as a flowchart:

    Our Code

    So we have 3 branches, the number of test cases for which is 3:

    1. The first - checks that if WhatIsGreater (2, 1), then as a result of execution if (a> b) we get 'a is greater than b'.
    2. The second - makes sure that if WhatIsGreater (1, 2), the program will pass if (b> a) and the result will be 'a is less than b'.
    3. The third test case - checks that in other cases the result is 'friendship :)'. That is, if the parameters are the same WhatIsGreater (2, 2), we get 'friendship :)'.

    To achieve 100% decision coverage we need 3 test cases.

  • [.NET] Which line execution will cause an error?
    namespace BSA2021
    {
      class Program
      {
        static void Main()
        {
          var array = new string[] { "Welcome", "to", "Binary", "Studio", "Academy" };
    
          var a = array[..0];
          var b = array[2..^0];
          var c = array[^0];
        }
      }
    }
    

    a) 9
    b) 10
    c) 11
    d) No runtime errors

    Expand the correct answer with an explanation

    The task contains a small program that consists of an array of strings and actions on this array. Array actions are performed using indexes and ranges. Consider them in more detail:

    The index indicates the ordinal place of an element in the sequence. The index can be specified as either counting from the beginning of the sequence or from its end. In the first case, the index of the first element is 0, the second – 1, the third – 2, and so on. The last element has the index array.Length - 1. A special operator ^ is used to subtract an element from the end of the sequence. The last element will have the index ^1, the penultimate – ^2, and the first – ^array.Length. The index written as ^0 will correspond to the length of the array.

    The range specifies some part of the sequence bounded by two indexes. The .. operator is used to determine the range. The index of the beginning of the range is specified on the left of the operator, and the end – on the right. An element with an index corresponding to the beginning of the range is included in the range. And the element with the end index – no. In the range it is possible not to specify the index of the beginning and the end, then the initial index will be considered as 0, and the final as ^0.

    Now let's look at the execution of the program. On the seventh line, an array of lines of five elements is created correctly. On the 9th line, we take a range that starts with the first element and ends with the same first element, ie the variable a will contain an empty array of strings. On line 10 we take the range from the third to the last element, ie the variable b contains {"Binary", "Studio", "Academy" }. The 11th line has an assignment to a variable of the only one element from the array, which is on position ^0, in other words on position array.Length. Here we have an executing error IndexOutOfRangeException.

    Correct answer: b) Line 11.

  • [.NET] IDOR prevention tool (don’t be afraid of the name, the task itself is fun)Weekly Challenge

    Intro

    There is a vulnerability called insecure direct object reference (IDOR) in cybersecurity. In simple words, it’s the vulnerability when a user can access data they actually aren’t supposed to access. Usually, it happens when an application shows identifiers of internal objects in a simple form. For example, https://medium.com/@elon/posts/82048f77 or even just https://medium.com/@elon/posts/1

    Let’s imagine that it is your post by this link. If you are curious enough, you’d probably try to substitute some symbols in the GUID value in the first case or 1 with 2 in the second case to see what’ll happen.

    On the other hand, there can be an endpoint like this: https://medium.com/@elon/posts/PII6xnIiNeyv. In this case, you have no idea what value to use instead of that long ID to try your luck.

    But as a programmer, you might assume that it’s not just random letters and digits. And you will be right. Actually, it’s an encrypted GUID value.

    Task

    Create a simple application (Web API) to integrate this encryption/decryption. Use the following classes:

    Model:

    public class Resource
    {
        public Guid Id { get; set; }
        public string Name { get; set; }
    }

    Service:

    public class ResourceService
    {
        private static readonly List<Resource> Resources = new();
    
        public Guid Add(string name)
        {
            var resource = new Resource
            {
                Id = Guid.NewGuid(),
                Name = name
            };
    
            Resources.Add(resource);
            return resource.Id;
        }
    
        public Resource Get(Guid id)
        {
            var resource = Resources.FirstOrDefault(x => x.Id == id);
            return resource;
        }
    }

    Controller:

    [Route("api/[controller]")]
    [ApiController]
    public class ResourcesController : ControllerBase
    {
        private ResourceService _resourceService;
    
        public ResourcesController()
        {
            _resourceService = new ResourceService();
        }
    
        [HttpGet("{id}")]
        public Resource Get(Guid id)
        {
            return _resourceService.Get(id);
        }
    
        [HttpPost]
        public Guid Post([FromBody] string name)
        {
            return _resourceService.Add(name);
        }
    }

    If you create a simple ASP.NET Core Web API application and use these classes, you’ll have two endpoints for adding and retrieving the resource. The main catch here is that you need to update some code to comply with these requirements:

    • When you create a new resource, you need to get the id of that newly created resource in the encrypted form (not a plan GUID):
      • POST-request: /api/resource with body: "My new resource's name"
      • Response: PII6xnIiNeyv-Vxy
    • When you retrieve the resource by its id, you need to pass it in the encrypted form
      • GET-request: /api/resource/PII6xnIiNeyv-Vxy
      • Response:
    {
      "id": "82048f77-9995-4287-bc0d-471ca3c394b3",
      "name": "My new resource's name"
    }

    There are multiple ways to do this task:

    1. Plain and simple (encrypt and decrypt in every controller)
    2. Using ASP.NET Core middleware
    3. Using ASP.NET Core filters
    4. Custom JSON converters
    5. I’m pretty sure there are others

    Some of those may seem tricky, so you try to move one by one. It’s ok if you use just the first approach, but it’s an excellent opportunity to learn a lot in the ASP.NET Core while trying other ones.

    Feel free to use any kind of encryption.

    Expand the correct answer with an explanation
  • [JS/Mobile] What will this code display?
    const obj = {
      a: 1,
      b: function () {
        return this.a;
      },
      c: () => this.a,
    };
    console.log(obj.b());
    console.log(obj.с());

    a) 1 1
    b) undefined undefined
    c) 1 undefined
    d) null null

    Expand the correct answer with an explanation

    Before analyzing this example, we need to understand what is mean a call point, context, and arrow functions.

    Execution point — this is the place in the code where the function was called (not where it was declared). We need to explore the point of call to answer the question: what does this mean?

    In general, finding a call point is like "finding where the function is called from", but this is not always so easy, as certain coding patterns can be misleading about the real call point.

    It's important to think about the call stack (the stack of functions that were called to bring us to the current code execution point). The call point we are interested in is in the call before the currently performed function.

    Execution context — is a concept that describes the environment in which the code runs. The code is always executed within some context

    Стрілочна функція (arrow function) — it is a simple and concise syntax for creating functions, which is often better than the usual Function Expression

    Long story short

    let func = (arg1, arg2, ...argN) => expression;

    Is the same that

    let func = function (arg1, arg2, ...argN) {
      return expression;
    };

    However, in addition to the syntax of writing, there are also important differences that we will talk about later, but all in turn.

    Now let's look at how the call point affects what will be in this when the function is executed.

    There are 4 rules:

    • default binding;
    • implicit binding;
    • explicit binding;
    • tight binding;

    In our example, we consider implicit binding. Let's analyze the following code:

    function foo() {
      console.log(this.a);
    }
    
    var obj = {
      a: 2,
      foo: foo,
    };
    
    obj.foo(); // 2

    First, note the way in which the function foo() was declared, and then later added as a reference in obj. Whether foo() was first declared in obj or added later as a reference (as in the code above), neither function is actually "contained" in the obj object.

    However, the call point uses the obj context to refer to the function, so it can be said that the obj object "owns" or "contains" a function reference at the time the function is called.

    Whatever name you choose for this template, when foo() is called, it is preceded by an object reference to obj. When there is a context object to reference a function, the implicit binding rule states that this is the object that should be used to bind this to the function call.

    Since obj is this for calling foo() ,this.a is the same with obj.a.

    Based on this, we can answer the first part of our task

    const obj = {
      a: 1,
      b: function () {
        return this.a;
      },
      c: () => this.a,
    };
    console.log(obj.b()); // 1

    Do you think we will get the same result when we write console.log(obj.c());? If your answer is no, then you are absolutely right.

    The case in context. Unlike other functions, arrow functions do not have their own context. In practice, this means that they inherit the essences of this and arguments from parent functions. The anonymous function b () has its own context, which it intercepts in obj. And in c () the arrow function remembers its context at the time of creation and accordingly when calling this function it will refer to it. So we get a window.

    However, you may ask, "But why was there a window at the time the context was created and not the object inside which it was declared as a method?"

    The arrow function at the time of creation looks for the closest context to it and remembers it, and it is the same as in the case of a simple assignment inside obj.

    Summarizing all that is written above, we highlight two main theses.

    Thesis 1

    For functions declared with function f () {}, this is calculated at the time of the call and is equal to the object before the point. If there is no such object - then this will point to the global context (window). However, this does not apply to strict execution.

    Thesis 2

    For arrow functions this is determined at the time of their creation and never changes again

    So, the correct answer is:

    const obj = {
      a: 1,
      b: function () {
        return this.a;
      },
      c: () => this.a,
    };
    console.log(obj.b()); // 1
    console.log(obj.с()); // undefined
  • [JS/Mobile] GalleryWeekly Challenge

    Implement logic that will allow you to make the slide active by clicking on it (add the active class).

    Slider

    Source Code

    Expand the correct answer with an explanation
  • [QA] One part of QA`s work is requirements testing. Analyze the requirements below. What do you think is wrong with them?
    1. The system should be user-friendly and accessible.
    2. There should be a way to authenticate.
    3. Create a support system with live chat, contact form and help for authorized users.
    4. An unauthorized user can use the chat and contact form.
    5. A student will log into the system by providing his username, password, and other relevant information.
    6. Each page of the system will load in an acceptable time-frame.
    Expand the correct answer with an explanation

    Poor written requirements create a risk that the developer, QA, PO and end-user can expect different performance from the functionality.

    When testing the requirements, we must pay attention to:

    • unambiguous requirements and their completeness - everyone should understand the requirements equally;
    • consistency;
    • the need for requirements and the possibility of their implementation;
    • the ability to verify the established requirements after their implementation.
    1. The system should be user-friendly and accessible

    Convenient for whom and what does affordable mean? The requirements lack clarity and unambiguity. Different people perceive and interpret these words differently.

    1. There should be a way to authenticate.

    In this case, it is also not clear what the authentication method should be - e-mail and password, sending a temporary code to an e-mail address or a one-time password via SMS. The options are different. The requirements should be clear. It is also important to be sure that the requirements are really necessary and can be implemented.

    1. Create a support system with live chat, contact form and help for authorized users.

    Imagine how many options and tasks there can be in this case? Online chat support, phone support, 24-hour email support, help pages on the website… The requirements should reflect the functionality that the user really needs. Make sure that the requirements are essentially clear and concise, but at the same time able to convey all the needs.

    1. An unauthorized user can use the chat and contact form.

    This requirement conflicts with the previous one, which states that the support system should be available to authorized users. The requirements should not be contradictory or conflicting. It is necessary to clearly understand how the system should behave in a given case.

    1. A student will log into the system by providing his username, password, and other relevant information.

    By "other necessary information" the customer, developer and tester can mean different things. One of the criteria for good documentation - unambiguity - is the same perception of the requirements of all team members, there should be no differences in interpretation.

    1. Each page of the system will load in an acceptable time-frame.

    Problems with this requirement: each page means that there can be many pages, which will lead to an explosion of the testing efforts. It is important to be able to check all the established requirements after their implementation.

    In addition, the page should be loaded in a reasonable time, and what are the acceptable deadlines? Acceptable for whom?

    It is necessary to specify which pages are meant by "student registration and enrollment pages", as well as to indicate an acceptable time interval, for example, 5 seconds.

  • [QA] The database has a Contact table, which stores: the username, birth date, and city where the user lives.Weekly Challenge

    QA Table

    This week's tasks:

    1. Display the (Name) and date of birth (BirthDate) of all contacts with the second letter "a" in the name. Sort the sample by descending date of birth (BirthDate).
    2. In the Contact table in Lena contact change the values: BirthDate = 1987-10-08 and UsrAdressLiving = Харків.
    3. Add a new contact to the Contact table: Name = Alex, BirthDate = 1986-10-08, UsrAdressLiving = Київ.
    Expand the correct answer with an explanation
  • [.NET] What will be the result of executing this code?
    class Program
    {
        static void Main(string[] args)
        {
            First first = new Second("some item");
            First another = new Third();
        }
    }
    class First
    {
        public First()
        {
            Console.WriteLine("First created");
        }
    }
    class Second : First
    {
        private Second()
        {
            Console.WriteLine("Second created");
        }
        public Second(string item)
        {
            Console.WriteLine("Second created with Item: {0}",  item);
        }
    }
    class Third : Second
    {
        public Third()
        {
            Console.WriteLine("Third created");
        }
    }

    a) First createdSecond created with Item: some itemFirst createdThird created
    b) Compilation error
    c) Second created with Item: some itemThird created
    d) Runtime error

    Expand the correct answer with an explanation

    Given in the task program is built from three classes and from the call of the constructors of these classes in Main(). The inheritance mechanism is used for classes and the following hierarchy is defined: from the base class First inherits the class Second, which, in turn, has a descendant – the class Third. When we create an instance of a class that has a parent class, the parent class constructor is called first. By default, a constructor without parameters will be called for the parent class. The base() keyword is used to explicitly call the required constructor.

    The First class has a single constructor without parameters, which prints the string "First created" in the console.

    The Second class has two constructors. One of them has no parameters and prints the string "Second created", and its access level is defined as private, so it is only available for calling "inside" this class. Another constructor has an item parameter and prints the message "Second created with Item: {0}". Both of these constructors implicitly call the First() constructor.

    The Third class has a single parameterless constructor that prints "Third created" in the console. However, since there is no explicit call to the batik constructor with parameters, the private constructor Second() will be called. This will cause a CS0122 compilation error.

    Correct answer: b) Compilation error.

  • [.NET] Create a Web API application with a static in-memory database (meaning you should have one instance of this database throughout the whole application) with 20 elements max. An element must have the following fields - Id(unique), Name and CreationDate. Other fields are up to you.Weekly Challenge

    Web API should allow users to do the following:

    1. Update an element in the database using Id
    2. Add an element to the database. Keep in mind that we have a maximum of 20 elements in our database.
    3. Get a new data structure which will consist of two lists and a field containing a date. The structure should be built like this: user sends a date to the endpoint and using this date we split our list into two - first one with elements created before this date and the second one with elements created after. Date field should contain the date that was sent by a user.
    4. Delete an element from the list by Id
    Expand the correct answer with an explanation
  • [JS/Mobile] What will someVariable be equal to?
    function func() {
      return this;
    }
    
    const outerObj = {
      value: 10,
      innerObj: {
        value: 20,
        method: func,
      },
    };
    
    const target = outerObj.innerObj;
    const someVariable = target.method();

    a) window
    b) outerObj
    c) innerObj
    d) undefined

    Expand the correct answer with an explanation

    To properly answer this question, we need to know at least a little about how the this keyword in JavaScript works, so we'll take a quick look at that now.

    What is “this”?

    Typically, an object method requires access to the information stored in the object in order to perform some action on it (according to the purpose of the method).

    For example, the code inside user.sayHi() might need the username stored in the user object.

    To access information within an object, a method can use the this keyword.

    For example:

    const user = {
      name: 'Tanya',
      sayHi: function () {
        return this.name;
      },
    };
    
    user.sayHi(); // 'Tanya'

    Here, when the user.sayHi() code is executed, the value of this will be user (a reference to the user object).

    Using this allows you to create generic functions that work correctly as methods on various objects. This is the power of this - the value of this keyword is calculated when the code is executed and depends on the context.

    Understanding what this is equal to in a particular case is quite simple: this is the object before the dot. For example, when obj.f() is called, the value of this inside f is obj.

    function sayHi() {
      console.log(this.name);
    }
    
    const user = {
      name: 'Tanya',
    };
    
    const admin = {
      name: 'Misha',
    };
    
    user.f = sayHi;
    admin.f = sayHi;
    
    // function calls below have different this values
    // "this" inside the function is a reference to the object specified "before the dot"
    user.f(); // Tanya (this == user)
    admin.f(); // Misha (this == admin)
    
    admin['f'](); // Misha (unimportant way to access the method - through a dot or square brackets)

    If we call the function without an object before the dot, we get undefined (if we work in "use strict" mode), or a global object (if "use strict" mode is not activated). In the browser environment, the global object is the window object.

    function sayHi() {
      console.log(this);
    }
    
    sayHi(); // undefined or global object

    There are some other ways to explicitly tell a function which object it should consider this during its execution. The methods call, apply and bind.

    Now let's move on to the task

    Right from the start, we have a func function that simply returns this. We already know that this can be different and its value will depend on how we call this function.

    function func() {
      return this;
    }

    Next, we create an object in which the object inside is nested. And already to this nested object we add our function as a method.

    const outerObj = {
      value: 10,
      innerObj: {
        value: 20,
        method: func,
      },
    };

    An nested object is a full-fledged object like any other, it can also have its own methods and properties. Our code could look like this:

    const innerObj = {
      value: 20,
      method: func,
    };
    
    const outerObj = {
      value: 10,
      innerObj: innerObj,
    };

    Next, we create a new target variable and specify that it is equal to our nested object. Okay, now we have 2 variables that point to the same nested object.

    const target = outerObj.innerObj;

    If you didn't know, JS objects is a complex data type, and unlike primitive types such as number or term, objects are assigned and are copied at the link. In other words, the variable does not store the "value of the object", but the "link" (address in memory) of this value. Therefore, copying such a variable or passing it as an argument to a function copies the reference, not the object itself. All operations using copied links (for example, adding or deleting properties) are performed with the same object.

    That is, in our case, target is the same innerObj, and not a copy of it. It's just that now we have 2 paths to its properties and methods - outerObj.innerObj and target. Take a close look at this code if you don't really understand what I'm talking about:

    const outerObj = {
      value: 10,
      innerObj: {
        value: 20,
        method: func,
      },
    };
    
    const target = outerObj.innerObj;
    
    target.value = 0;
    console.log(outerObj.innerObj.value); // 0
    // because 'target' is just a reference to the same innerObj object, not a copy of it

    Okay, with that figured out, what do we have next?

    const someVariable = target.method();

    And then we just call target.method(), where method is our func function that returns this. this is equal to the object before the dot, in which case the object before the dot is target. But, as we understood above, target and innerObj are not just two identical objects or two copies - they are the same object. Therefore, we have someVariable, target and outerObj.innerObj are all references to a single object in memory.

    The correct answer - innerObj.

  • [JS/Mobile] Create a drop-down block with application icons like Google`s.Weekly Challenge

    Google Bar

    The main stages of the task:

    • create a button that will open / close the block with applications;
    • create the block itself with application icons;
    • implement a custom scrollbar for this block;
    • polish the styles so that everything looks like in the original.

    The less your button and block differ from the original one, the better you managed to complete the task! Ideally, they can be generally identical, with all styles and hover effects. But if you manage to complete only a part of these tasks, it will already be very useful for you!

    What can and should be done to complete the task:

    • check out this menu in Google, see how it works;
    • use dev-tools to look inside - how it's done, how images for menu items are exposed, how images from there or even CSS code can be reused to complete the task;
    • use google - how to make a custom checkbox, how to make a custom scrollbar and everything else you need;
    • use only HTML, CSS and images.

    What NOT to do:

    • do not use JS or any CSS libraries.

    You can try to complete this challenge from scratch, or use this billet where we already have:

    • general markup and styles;
    • the block itself with application icons.

    In this case, you will only need:

    • create a button that will open / close the block with applications;
    • finalize the positioning of the block and make it react to the button;
    • add a custom scrollbar for this block;
    • add hover, focus style for the button.
    Expand the correct answer with an explanation
  • [QA] What is verification?
    1. Verify that the software is implemented according to the design.
    2. Verify that the software meets the customer's requirements and expectations.
    3. Verify that the software meets user requirements and expectations.
    4. Verify that the software is implemented according to the expected requirements.
    Expand the correct answer with an explanation

    Let's remember what Verification and Confirmation are.

    Verification. It answers the question "Does the functionality work as required?". Verification - the process of evaluating the system and its components in order to compare the results of the current stage of development with the initial conditions. It is the implementation of tasks, goals, deadlines for product development, and compliance with standards.

    Validation. It answers the question: "Do we expect what the user expects?". We make sure that the developed software meets certain business requirements and user needs.

    The correct answer is: Verify that the software is implemented according to the expected requirements.

  • [QA] This week we will practice prioritizing test cases. Testing deadlines are often tight. In such cases, there is a risk of missing testing of some important features. Therefore, it is important to prioritize each test when documenting it.Weekly Challenge

    Object:

    Internet-shop

    Status:

    At the development stage, but ready: the main page with promotional products; catalog; product cards with a photo (with the possibility of zoom); product pages; search; filters (price, manufacturer); sorting by price; shopping cart page with the ability to change the quantity of products, delete products; ordering page; integration with the payment system, sending an e-mail letter with order details.

    Customer requirements:

    • The user should see promotional products on the main page.
    • The product card preview must contain:
      • photo
      • price
      • “Add to cart” button.
    • After clicking on the card, the product page opens with:
      • description
      • price
      • photo
      • the ability to add the product to the cart.
    • The user must have the option in the cart:
      • remove the product
      • change its quantity
      • have a button "Order".
    • On the ordering page should be the choice of payment type:
      • online payment by card
      • cash on delivery
      • and one type of delivery - self-pickup at the post office.
    • Also on the order page must be:
      • “Email” field
      • “Phone Number” field
      • “Buy” button.
    • If the user has chosen to pay by card, then after clicking on the "Buy" button, the system redirects to the payment page, where the user needs to enter bank card details.
    • After placing an order, a letter with the details of the order should be sent to the user's e-mail box.

    It is important for the customer that the user at least has the opportunity to order the product.

    The classification of test case priorities that we will use:

    • High priority: These test cases cover the critical function of the application, defect prone modules and modules that have undergone recent changes.
    • Medium priority: These test cases include negative test scenarios. Field validations, error message generation test cases are included under this category.
    • Low priority: These test cases cover the remaining functionality of an application (includes UI and less defect prone modules).

    Prioritize the following checks:

    1. Display promotional items on the main page.
    2. Display the corresponding product category on the page of the selected category from the product catalog.
    3. Sort by price.
    4. Display relevant products on the user's screen after searching.
    5. Filtration by price, manufacturer.
    6. Ability to zoom in/out the photo in the product card.
    7. Display product description, price.
    8. Adding the product to the cart, removing the product from the cart.
    9. Correspondence of the product price in the shopping cart to that specified in the product card.
    10. Validation of the fields “Email” and “Phone number” on the ordering page.
    11. Go to the online card payment page.
    12. Go from the shopping cart to the ordering page after clicking on the "Order" button.
    13. Receiving a letter with order details by email.
    Expand the correct answer with an explanation
  • [.NET] What will this code display?
    namespace BSA2021
    {
        struct Point
        {
            public int X;
            public int Y;
        }
    
        class Program
        {
            static void Main()
            {
                CreatePoint(out Point point);
                ResetPoint(in point);
                IncreasePoint(ref point);
    
                Console.WriteLine($"({point.X};{point.Y})");
            }
    
            static void ResetPoint(in Point point)
            {
                point.X = 1;
                point.Y = 1;
            }
    
            static void CreatePoint(out Point point)
            {
                point.X = 2;
                point.Y = 2;
            }
    
            static void IncreasePoint(ref Point point)
            {
                point.X *= 3;
                point.Y *= 3;
            }
        }
    }

    a) (3;3)
    b) (6;6)
    c) (0;0)
    d) Runtime error
    e) Compillation error

    Expand the correct answer with an explanation

    Let's consider what "consists" of the program in question. It is built from a simple structure and from calls of three methods to perform actions on this structure. The difficulty is that the structure, like int, is stored in the stack and is a value type. And also that methods of action over structure keywords (in, ref, out) that serve as modifiers of parameters are used. Without the use of these modifiers, a new copy of the variable data stored in the stack is always passed to the method. Consider in detail these modifiers:

    The ref keyword indicates that the argument is passed by reference, not by value. So any change in the value of this argument within the method will change the corresponding argument with which the method was called. Also, using this keyword requires that the variable be initialized before using it as a parameter otherwise, there will be a CS0165 compilation error.

    The out keyword also indicates that the argument is passed by reference. This argument is called the "output parameter" of the method and, unlike ref, does not require prior initialization of the parameter. Instead, within a method, the argument must be initialized within that method otherwise, a CS0177 compilation error occurs.

    In - specifies the parameter passed by the link, but within the method, it is forbidden to change it. This keyword is typically used when memory-intensive structures need to be passed inside a method. When trying to change this parameter there is a compiling error CS8332 – inability to change readonly variable. There is also a need to pre-initialize the variable passed as a parameter.

    Now let's analyze the call of each method from Main(). The first is the CreatePoint() call. Its parameter is marked as out, so the condition for initialization within the method is imposed. A structure is considered as initialized when all its fields are initialized – so there are no errors, and the point has the value of (2; 2). Next is the ResetPoint() call with the in parameter. Within this method, this parameter is assigned, so we have a CS0165 compilation error.

    Correct answer: e) compilation error.

  • [.NET] CalculatorWeekly Challenge

    Create a calculator that can be used like this:

    var result = 5.Add(10).MultiplyBy(2);
    // or
    result = new Calculator(5).Add(10).MultiplyBy(2).Equals();
    
    Console.WriteLine(result); // 30

    It may look a little bit different depending on the implementation, but the main idea is to use methods to perform operations in a chained way (calling one after another).

    • Implement 4 basic methods (detailed signature omitted for flexibility of your solutions):
      • Add()
      • Subtract()
      • MultiplyBy()
      • DivideBy()
    • Feel free to add other intricate methods to make your calculator more comprehensive.

    There are at least 2 possible ways to handle this task. But we encourage you to try others also. Use hints if stuck:

    • First hint This one implies ‘extending’ 😉 functionality of known types
    • Second hint Also, there is one that presumes diving into the topic of design patterns (especially those related to building stuff 🏗️)

    Feel free to come up with your own approaches.

    Do not forget that we’re building software for common users, that may make mistakes: enter strings instead of numbers, divide by 0, and so on. Allow users to use not only integers, but also float numbers. Try to handle as many edge cases as possible to stabilize your implementation.

    Expand the correct answer with an explanation
  • [JS/Mobile] Which line was missed?

    A young programmer was engaged in code refactoring. He decided to wrap the function of a third-party library that accepts a callback in a promise, but he made a mistake. Specify which line was missed:

    // before
    someFunc((err, res) => {
      if (err) {
        console.log(err);
      } else {
        console.log(res);
      }
    });
    
    // after
    1 const someFuncPromise = () =>
    2   new Promise((resolve, reject) => {
    3     //
    4     someFunc((err, res) => {
    5       if (err) {
    6         console.log('Error');
    7         //
    8       }
    9       resolve(res);
    10      console.log('Sucess');
    11      //
    12    });
    13  });

    a) return cb() - 7th line
    b) if - 3rd line
    c) return reject(err) - 7th line
    d) else - 7th line
    e) return - 11th line

    Expand the correct answer with an explanation

    To solve this problem, first of all, we need to understand how the callback that passed to the third-party function library should work. It takes two parameters, err and res , and then an if block checks if the condition is true. In JavaScript, all values are truthy unless they are defined as falsy. It means that all values except false, 0, "", null, undefined, and NaN are truthy. So in our case, if we get an error, it will be logged to the console. If there is no error, then execution will go to the else block and then the console will log the value of res.

    During refactoring the function was wrapped in a "promise", which is supposed to end its lifecycle in one of the following states: fulfilled (via calling resolve()) or rejected (via calling reject()).

    Let’s dive into detailed code flow:

    • If we do not have an error, the first condition if (err) will return false and then execution will go to the next block and resolve and console.log ('Sucess') will be executed.
    • In case of an error the condition if (err) will return true. Because of this, ‘Error’ will be logged to the console, but the function will not be affected in any way - the promise will be successfully resolved and the "successful" console.log will work.

    So, firstly, we should follow the logic of working with promises and call reject(err) in case of error.

    And secondly, we should not forget that functions resolve and reject change the state of the promise, but do not stop it, because of this the console will still log the message "Success".

    So the full correct answer should be: return reject(err) 7th line.

  • [JS/Mobile] Searching characters from The Game of Thrones v2Weekly Challenge

    Today we’re gonna improve our last week challenge and add some new features.

    • Let’s add an ability to select favourite characters.
    • Also let’s improve our UI a bit and add loader indicator during data fetching.

    Here is a repo to start with.

    Expand the correct answer with an explanation
  • [QA] Retesting or Regression?

    Think and answer what suggestions are related to the Retesting and what suggestions are related to the Regression:

    1. Goal of this test is to make sure that adding new code, improving or fixing bugs do not make instability or discrediting software functionality
    2. During this testing testers check that all test cases that were failed during the last testing, are passed after bug fixing.
    3. This testing is not included checking bugs.
    4. This type of testing guarantees that changes in the code will not affect the functionality of the system.
    5. This testing can be automated.
    6. This type of testing is carried out after fixing the defects.
    7. Test cases that failed generically are subjected to this type of testing.
    8. Test cases that passed generically are subjected to this type of testing.
    Expand the correct answer with an explanation

    Retesting - the type of testing when testers check that all test cases that were failed during the last testing, are passed after bug fixing.

    Regression testing - the goal of this test is to make sure that adding new code, improving or fixing bugs do not make instability or discrediting software functionality. This testing is not included checking bugs. Regression testing can be automated.

  • [QA] This week the task is to find bugs and create bug reports. The screen shows a simple login form. The user opened the site, went to the login form, didn’t enter an email address, but entered a password.Weekly Challenge

    Find bugs on this screen and create bug reports.

    Register form

    Expand the correct answer with an explanation
  • [.NET] Which of the catch blocks will be involved as a result of this code execution?
    static void Recursive()
    {
        Recursive();
    }
    
    try
    {
        Recursive();
    }
    catch (InsufficientMemoryException)
    {
        // block 1
        throw;
    }
    catch (OutOfMemoryException)
    {
        // block 2
        throw;
    }
    catch (StackOverflowException)
    {
        // block 3
        throw;
    }
    catch (Exception)
    {
        // block 4
        throw;
    }

    a) block 1
    b) block 2
    c) block 3
    d) block 4
    e) no block will be involved

    Expand the correct answer with an explanation

    First of all, let's remember how try…catch construct works in the presence of several catch blocks: when an exception occurs, a consistent comparison of the catch block argument type with the error object type is performed sequentially from the top. And if the type of argument matches the type of error, or if it presents in base classes of error class - the catch block is executed. The following blocks are ignored. By the way, in catch blocks the type of argument cannot be repeated. The throw constructions in the middle catch cause the error to be "passed to a higher level", and even if there is another block after the current catch block that can intercept this error by its type, it will not be executed.

    Now let's analyze what exceptions each block is intended for:

    InsufficientMemoryException – an exception indicates that the available memory was found to be insufficient. This exception occurs only when the MemoryFailPoint object is explicitly used. Is a derived type from OutOfMemoryException.

    OutOfMemoryException – reports that there is not enough memory to continue executing the program. An exception occurs either when the maximum length value for the StringBuilder is exceeded, or when the CLR cannot allocate enough continuous memory to perform an operation (object creation, method call, etc.). This error is related to heap.

    StackOverflowException – occurs when the runtime stack overflows because it contains too many nested method calls. If this error is not explicitly thrown (through throw), it cannot be intercepted by try…catch.

    Exception – base type for all exceptions. Used to declare a catch for any error. Now let's consider what occurs in the try block: the Recursive() method is called. This method doesn’t use MemoryFailPoint and doesn’t create or modify objects, so blocks 1 and 2 will not be involved. Instead, the method produces uncontrolled recursion, which will overflow the stack and cause the StackOverflowException generated by the system. Therefore, blocks 3 and 4 will also not be involved.

    Correct answer: e) no block will be involved.

  • [.NET] In this weekly challenge, you will need to create a Web API with in-memory database (aka List of items) containing 20 items.Weekly Challenge

    An item must contain Name and CreationDate fields, everything else is up to you. Web API should allow users to retrieve data in the following representations:

    1. Get the first 5 items ordered by Name in alphabetical order;
    2. Get the first 5 items ordered by CreationDate in descending order;
    3. Get all items with Name longer than 5 characters

    P.S. Feel free to use third-party libraries to create realistic fake data or create data themed on things you are interested in P.P.S You can use Postman or some other tool to test out your application.

    Expand the correct answer with an explanation
  • [JS/Mobile] How much 1 is displayed in the console?
    const func = (x) => {
      switch (isNaN(x) || x) {
        case null: {
          console.log(1);
          break;
        }
        case undefined: {
          console.log(1);
        }
        case NaN: {
          console.log(1);
          return;
        }
        case false: {
          console.log(1);
        }
        case true: {
          console.log(1);
        }
        default:
          break;
      }
    };
    
    func();

    a) 1
    b) 2
    c) 3
    d) 4

    Expand the correct answer with an explanation

    In order to answer this question correctly, we need to understand how to work with the switch operator, how function parameters are passed as well as how the isNaN function and the OR operator (||) work.

    Firstly, it is necessary to understand what value will be in the parameter x. Since no parameters were passed to the function when it was called, the default value - undefined will be used. This can be easily checked by following piece of code.

    const f = (arg) => console.log(arg === undefined);
    
    f();

    Next, we should understand how the switch operator works. This operator evaluates the value given to it and executes the code associated with the corresponding case clause and, what is important to remember, all the following statements will be executed as well. This can be easily checked by executing the following code:

    switch (2) {
      case 1:
        console.log('1');
      case 2:
        console.log('2');
      case 3:
        console.log('3');
      default:
        console.log('default');
    }

    The result in console will be:

    2
    3
    default

    There are 3 ways to stop the execution of all case clauses - break, return, throw.

    • break - stop execution of all subsequent case clauses, and continue execution of function.
    • return - stop execution of all following case clauses, and return value from function.
    • throw - stop execution of all case clauses and throw an error.

    So, if we rewrite the code above using break we will get a completely different result:

    switch (2) {
      case 1:
        console.log('1');
        break;
      case 2:
        console.log('2');
        break;
      case 3:
        console.log('3');
        break;
      default:
        console.log('default');
    }

    Result in console:

    2

    On the next step we should determine the value that the isNaN function will return. To understand this, we must first understand what NaN is. NaN - represents a value that could not be converted into a number (Not-a-Number), such cases may occur when:

    • Number cannot be parsed (Number('foo'))
    • A mathematical operation is performed that does not result in a real number (Math.sqrt (-1))
    • The operator of the mathematical operation is NaN (7 * NaN)
    • The result of the expression is indefinite (0 * Infinity)
    • Any operation that includes a string and is not an add operation ('foo'/ 5)

    The isNaN function converts the value passed to it into a number and checks if this value is NaN.

    console.log(isNaN('55')); // false
    console.log(isNaN(undefined)); // true

    The last thing we need to know to solve this problem is the behavior of the operator OR (||). This statement returns the second value only when the first is falsy.

    console.log(false || 'shown'); // 'shown'
    console.log(true || 'not shown'); // true

    Now, we can say that in the function the parameter x has the value undefined. The isNaN function will return true, because this value cannot be converted to a number. So, the || operator will also return true because this value is truly. This means that the following clause is executed

    case true: {
      console.log (1);
    }

    and since there is no operator that would stop the execution of case clause, the default is also executed (although it does not output anything in this task). So the console will display:

    1

    The correct answer is - 1.

  • [JS/Mobile] The challenge for this week will be to implement the app for searching characters from The Game of Thrones.Weekly Challenge

    The data about the characters we will get from this API.

    View Example Example

    To simplify the task, we have prepared a boilerplate for you where you will have to add only getting the data about the characters from the API. So, clone the boilerplate repository and read the description.

    Expand the correct answer with an explanation
  • [QA] During testing of a healthy food application, 200 critical bugs were found in the first 20 sprints. Over the next 20 sprints without changing the QA team and approach to testing, 25 critical bugs were found, but customers began to complain about various bugs they found while using the new versions. Which of the principles of testing is clearly observed in this example?

    a) Exhaustive testing is impossible
    b) Pesticide paradox
    c) Testing depends on context
    d) Absence-of-errors is a fallacy
    e) Users always complain

    Expand the correct answer with an explanation

    Let's recall 7 principles of testing

    Testing shows the presence of defects, not their absence

    The testing process does not confirm that any software is completely correct and completely free of problems. Testing helps to significantly reduce the number of undetected defects hidden in the software, but finding and solving these problems is not in itself proof that the software or system is 100% problem-free.

    Comprehensive testing is not possible

    No matter how much we want to believe or wish it to be true (!), To test EVERYTHING - all combinations of input data and preconditions are absolutely impossible. For the simplest functionality, this is more realistic, but such testing would be very inefficient and extremely expensive.

    Early testing saves time and money

    Everything is simple here. The fewer stages of development the bug lives on, the cheaper it is for the project. The cheapest bug is a bug found at the idea stage, the most expensive is a bug found by the end user.

    Defects are grouped together

    The largest number of bugs is usually concentrated in several problematic modules of the program

    Testing depends on the context

    The application usage context will determine the types and kinds of testing. For example, the cloud version of the application requires load testing from thousands of users, but the standalone version, which is installed by the user on his computer - no.

    The absence of errors is misleading

    If your software or system is unusable (or does not meet the wishes of users), it does not matter how many defects are found and fixed - they are still unusable. So in that sense, it doesn't matter how trouble-free or error-free your system is; if usability is so poor that users can't navigate, and / or it doesn't meet business requirements, it has failed despite a few mistakes.

    The pesticide paradox

    This is based on the theory that when you repeatedly use pesticides in crops, the insects end up producing immunity, making it ineffective. Similar to testing, if the same tests are performed continuously, then - although they can confirm that the software is working - in the end they will not be able to find new problems. It is important to continue to review your tests and change or supplement your scenarios to prevent the pesticide paradox - perhaps by using different testing methods, techniques and approaches in parallel.

    The correct answer is the paradox of the pesticide :)

  • [QA] This week`s task is oriented towards practicing your QA skills and solving quite easy, at the first glance, task. Our goal is to test the elevator in the high-rise building with offices. There are 10 floors in total. The elevator has a load capacity of up to 500 kg.Weekly Challenge

    Hint: we expect to see different types of testing applied

    Expand the correct answer with an explanation