Chapter [ ]: Programming and CS Fundamentals

Explain the benefits of test-driven software development; or explain the benefits of unit testing.

TDD

Faster Feedback: Through TDD, your team will have almost immediate feedback on the components they develop and test. This shorter feedback loop allows for much faster turnaround on resolution of defects compared to traditional waterfall methodology where code is tested days or weeks after implementation.

Higher Acceptance: TDD implementation is more likely to match the product owners vision for the user story. The test cases are easily generated from the acceptance criteria without interference from the constraints of the architecture design or programming constructs. TDD guarantees to some degree that the final version will fulfill the needs of the stakeholders as communicated by the product owner.

Avoid Scope Creep: TDD prevents unwarranted design or components to sneak (think gold-platting) into the product. The test cases or unit test drivers define the exact set of required features. TDD makes it easy to identify redundant code, detect and terminate unnecessary engineering tasks.

Customer-Centric: TDD fits nicely into the customer-centric agile process. The iteration can be defined as the implementation of functionality to execute against a pre-defined set of test cases instead of the more traditional set of specifications or problem statement.

Modulation: TDD can lead to more modularized, flexible, and extensible code. The technique requires your team to think of the software in terms of small units that can be written and tested independently and integrated together later.

Unit Testing

Find Software Bugs Early: By adding Unit Tests to the software build process, or as part of the Continuous Integration process, as the code base grows larger, these tests run automagically. When a failure occurs, either the failure is caused by a bug in the code or a problem with the actual Unit Test. Either way, pinpointing the location of failure is easily traced. Since Unit Test failures alert the Development Team before the code is pushed to Testers or Clients, it is still early in the development cycle making the fix less costly than if found later in the development cycle.

Continuous Integration (CI) is the merging of all the developers’ working code into a shared repository several times a day. CI was originally intended as the process of running all Unit Tests in the developer’s local code branch to verify that all tests pass before committing the code to the main repository branch.

Facilitates Change: Unit Tests ensure that the code still functions properly as the code base changes with code refactoring and as the code base grows. Code refactoring is the process of restructuring existing software code without changing its original behavior. Advantages include streamlined code that is both more readable and less complex.

Simplifies Integration: Unit Testing verifies the accuracy of the each Unit. Afterward, the Units are integrated into an application. By testing parts of the application via Unit Testing, later testing of the application during the Integration process is easier due to the verification of the individual Units.

Provides Documentation: Although rarely the sole source of documentation, Unit Tests provide a living documentation of an application. Developers wanting to learn what functionality is provided by a particular unit can refer to the Unit Tests to gain an understanding of the unit’s Application Programming Interface (API). The API specifies a component in terms of their inputs, outputs, and underlying types.

The Limitations of Unit Testing: Manual testing can never be fully replaced by automation. The same is true for the Unit Test portion of your test automation library because it’s nearly impossible to evaluate every single execution path in all but the most basic applications. As such, use of a version control system is critical so that if a later version fails, the version control system can display the list of software code changes since the working version. A version control system also provides an easy to way to revert back to previous versions of your code.

What are hash table collisions? How are they avoided? How frequently do they happen?

Hash table is a data structure that uses a hash function to map elements(keys) to an index. It offers O(1) amortized time in searching, inserting and deleting.

A collision occurs when two or more elements are hashed(mapped) to same value.

For example: Let the hash function be hash(x) = x%10. In this case 25 and 35 would be mapped to same value. Hence a collision occurs.

The best way to avoid collision is to use a good hash function that distributes elements uniformly over the hash table. There also various collision resolution techniques like open hashing, closed hashing, double hashing, etc.

The answer to how frequently does a collision occurs depends on both hash function and input data.

Explain the difference between a compiled computer language and an interpreted computer language.

The difference is not in the language; it is in the implementation.

  • In a compiled implementation, the original program is translated into native machine instructions, which are executed directly by the hardware.

  • In an interpreted implementation, the original program is translated into something else. Another program, called "the interpreter", then examines "something else" and performs whatever actions are called for. Depending on the language and its implementation, there are a variety of forms of "something else". From more popular to less popular, "something else" might be

    • Binary instructions for a virtual machine, often called byte code, as is done in Lua, Python, Ruby, Smalltalk, and many other systems (the approach was popularized in the 1970s by the UCSD P-system and UCSD Pascal)

    • A tree-like representation of the original program, such as an abstract-syntax tree, as is done for many prototype or educational interpreters

    • A tokenized representation of the source program, similar to Tcl

    • The characters of the source program, as was done in MINT and TRAC

One thing that complicates the issue is that it is possible to translate (compile) bytecode into native machine instructions. Thus, a successful intepreted implementation might eventually acquire a compiler. If the compiler runs dynamically, behind the scenes, it is often called a just-in-time compiler or JIT compiler. JITs have been developed for Java, JavaScript, Lua, and many other languages. At that point you can have a hybrid implementation in which some code is interpreted and some code is compiled.

results matching ""

    No results matching ""