Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
ihollander committed Jun 9, 2021
0 parents commit 746742b
Show file tree
Hide file tree
Showing 549 changed files with 27,848 additions and 0 deletions.
49 changes: 49 additions & 0 deletions 00-welcome/00-welcome-to-technical-interview-preparation/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Welcome to Technical Interview Preparation

In addition to preparing a portfolio of awesome projects to show off to your
future employer, you’ll also need to be prepared for technical interviews. In
this course, we’ll help you prepare by asking you to solve a series of problems
on algorithms and/or data structures. You may find some problems easy and others
incredibly difficult. Don’t worry - this is normal. It takes time to get used to
solving these types of problems.

Before we get into how to approach progressing through this section, let’s talk
about the two types of technical interviews.

## Two Types of Technical Interviews

Your technical interview may be held asynchronously or synchronously. During an
asynchronous technical interview, you may be asked to solve algorithmic problems
in a timed environment by yourself. For a synchronous interview, you will likely
be asked to whiteboard and solve the problem in front of your interviewer.

Async technical interviews typically require candidates to problem solve alone.
Once the solution is submitted, the hiring team will review your solution and
determine whether you should move forward in the hiring process. At this point,
they’ll likely require that most or all problems be solved and will also
consider the quality of the solution/s.

During synchronous interviews, the interviewer is likely looking to see how you:

- Work in a team
- Handle feedback
- Talk technically
- Handle obstacles
- Approach solving a problem / think
- Evaluate different approaches to solving a problem and make decisions

At this stage, you may be able to move forward in the hiring process if you
demonstrate good communication skills, logical thinking, perseverance, calm
under pressure, and graciousness towards your interviewer’s feedback even if you
are unable to solve the problem. Asking good questions to fully understand the
problem or get unstuck are normally welcome. Interviewers also typically expect
you to come up with your own test cases to ensure the problem is actually
solved. This portion of the interview might require you to largely solve the
problem alone on a whiteboard or IDE, or through pair programming where the
interviewer is either the driver or navigator. Many interviewers are forgiving
of syntax errors, and they generally don’t expect you to have every piece of the
core language memorized.

In this course, we will be preparing you for both types of interviews, so it’s
important to take the time to solve as many problems as you can alone and to
complete the paired assignments, if applicable.
124 changes: 124 additions & 0 deletions 00-welcome/01-algorithmic-problem-solving/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
# Algorithmic Problem Solving

An algorithm is just a procedure that solves a problem. If you’re wondering if
that’s any different from the work you’ve already been doing, we’ve got good
news: It’s not!

In this reading, we’ll go over the importance of solving such problems and how
to approach coming up with solutions.

## Why Solve Algorithm Problems?

Working through these challenges will not only help you during the technical
interview process, it will also help you become a better programmer. Learning
how to break apart a problem into pieces you can understand and then code a
solution for is a vital skill, as is learning to think about the different types
of inputs - or test cases - your solution must account for.

As you grow as a developer, you’ll find yourself leaning on these skills more
and more, especially as your work becomes more challenging. These skills will
truly help you in any and every project you take on.

## How to Solve a Problem

Two mistakes many programmers make are to jump into code too fast or to start
thinking about code optimization too early. Both of these mistakes can greatly
increase the amount of time it takes to solve a problem and increase
frustration. To avoid this, here are the steps we recommend taking:

### 1. Spend Time Understanding the Problem

Before you dive into solving the problem, take the time to read it and describe
it in your own words. You might find it useful to rewrite the problem before
moving on.

If you have been given test cases, look at each one, apply your understanding of
the problem to them to determine what the answer is, and then check if your
answer matches the actual answer (e.g. work it out on paper or in your head, no
code necessary here). If your answer doesn’t match, you need to spend more time
understanding the problem.

### 2. Write Your Own Test Cases

Now that you understand the problem and why the answers to the test cases are
what they are, you’re ready to write your own test cases! We are not
recommending that you write test suites in Rspec or Jest. Instead, you simply
print the result of calling your solution method and compare it to the answer
you expected.

Be aware that algorithm problem descriptions rarely provide all of the test
cases you need to account for, so it’s incredibly important that you also come
up with your own. This is true when using online platforms, such as Leetcode and
HackerRank, as well as during interviews.

### 3. Pseudocode

Remember how we asked you to check your understanding of the problem by going
through the test cases and then writing your own tests? Congratulations! This
means that on some level, you know how to solve the problem. Before you start
coding, write pseudocode, which is just a plain description of how to solve the
problem. For example, the pseudocode for copying only numbers from one array to
another might look like this:

```
initialize empty array called result
iterate over each item in the input array:
if element is a number:
push item onto result
return result
```

Note that different people write pseudocode differently. The key is to make it
easy to understand yourself and explain to others - this is the map to the code
you’re about to write! I often paste my pseudocode into my workspace as
comments, and then code each piece alongside the matching comment.

You can also test this procedure against the test cases before writing any code.
Validating and rewriting pseudocode will likely save you time. You might also
wish to think about additional solutions: there’s always more than one way to
solve a problem.

### 4. Code!

Now that you have a map, convert it to code!

At this point, the goal is to make it work: pass those test cases! If you’re
having a hard time getting all of the test cases working, check that your
pseudocode actually solves for all of those cases and then check that your code
does what the pseudocode says it should.

### 5. Make It Clean and Readable

Once your solution is well, a solution, it’s time to refactor your code so that
it’s easy to read, not just for you but also for others. Use well-named
variables and convert blocks of code to methods when necessary. If you find any
unneeded or redundant code, delete it.

Don’t forget to test your code again!

### 6. Optimize?

Don’t optimize your code for time or space complexity (e.g. how long it takes to
run or how much memory it’s using) unless you absolutely need to. There are
three major situations that call for optimization:

- The solution is hanging on certain test cases, and therefore cannot pass since it’s taking too long
- You were asked to do so
- You think it would be fun to try

### Conclusion

We hope these steps help you solve the problems you’re about to encounter.
Remember, they can be applied to all types of problems, including building web
apps. Don’t be afraid to spend more time thinking and planning than coding. Take
it from those of us who have been coding for years: we often spend more time
thinking, talking, and writing than we do coding.

Before we go, we’d like to leave you with some final tips:

- Talk to yourself while you code: think out loud
- Consider recording your screen and voice as you solve a problem so you can
review your performance
- Take your time and be patient with yourself!
16 changes: 16 additions & 0 deletions 00-welcome/02-a-note-on-testing/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# A Note on Testing

If we have made a test suite available for a problem, please refrain from
looking at or running those tests until you have:

- Passed the tests given in the README
- Passed the tests you wrote yourself

This will give you a chance to think through the problem and write your own test
cases, which is a skill you’ll need when interviewing.

After you run our tests, you might notice that you missed some test cases: this
is a good thing - it’s a chance for you to learn and grow as a programmer. You
won’t always think of all of the necessary test cases, but as time goes by,
you’ll get better and better at thinking of all of the possible inputs that need
to be solved for before a solution can be considered complete.
54 changes: 54 additions & 0 deletions 00-welcome/03-problem-solving-tips/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Problem-Solving Tips

If you’re stuck, ask yourself these questions to see if they help you get
unstuck:

- Have I solved a similar problem before? How can I use that knowledge to solve
this one?
- Can I break this problem down into smaller problems that are easier to solve?
- Would it help to draw a picture or diagram of the problem?
- Which inputs might this method receive? Do my test cases cover the edge cases?
- Should I draw a table that maps inputs to outputs? Your test cases will then
mirror that table! The process of drawing the table might also reveal a
pattern, which you can then use to solve the problem.

- Example table for a problem where an Array of distinct values must be returned:

| Input | Output |
| ------------------- | ------------- |
| [1, 2, 2, 3] | [1, 2, 3] |
| [] | [] |
| [4] | [4] |
| [3, 2, 2, 10, 2, 7] | [3, 2, 10, 7] |

- Do I really understand the problem? You can prove this to yourself by solving
it on paper without thinking about code.
- Can I talk to someone about this and explain my thinking?
- Sometimes the act of talking to someone even if they don’t say anything
helps you get unstuck. It forces you to explain the problem in more
understandable language.
- What information is available to me in this problem? What additional
information can I derive?
- If you have experience writing or deriving mathematical equations, this is a
similar process: list which variables and mathematical operations are
available and then the additional information that can be derived from that.
- If you have experience creating artwork, this is similar to the process of
understanding what tools you have available to you and how you can use them,
e.g. what colors are in my palette and how can I mix them? Or I have a
string, tape, and a pencil, and I need to draw a circle - how do I do that?
- Example: For a problem where an Array of distinct values must be returned,
some of the information available includes: the Array itself, each element
in the Array, its length, and the index of each item. You can find a list of
Array operations available by looking at the documentation.
- Can or should I create additional data to help me solve the problem? What do I
need to keep track of for my solution to work?
- Consider adding variables and ask yourself which data structures are
required and how they might help.
- Example: For a problem where an Array of distinct values must be returned,
you might think about using an additional Array or a Hash (aka POJO/Object
in JavaScript or Dictionary in Python) or a Set.
- Have I taken care of myself today? Do I need to eat? Am I hydrated? Am I
rested? Do I need to move my body?
- You’ll be surprised how much better your brain works after eating a good
meal, drinking water, resting and/or exercising! Don’t let yourself get
[hangry](https://www.merriam-webster.com/dictionary/hangry)!
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Gemfile.lock

node_modules/
package-lock.json
53 changes: 53 additions & 0 deletions 01-week-1--starter-algorithms/00-day-1--reverse-a-string/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Day 1: Reverse a String

For this task, you'll need to reverse a string. Your method will receive one argument, a string, and be expected to output that string with its letters in reverse order.

```
Input: "hi"
Output: "ih"
Input: "catbaby"
Output: "ybabtac"
```

**Do not call any type of built-in reverse method!**

Please solve the problem using iteration.

Use the language of your choosing. We've included starter files for some languages where you can pseudocode, explain your solution and code.

## Before you start coding:

1. Rewrite the problem in your own words
2. Validate that you understand the problem
3. Write your own test cases
4. Pseudocode
5. Code!

**_And remember, don't run our tests until you've passed your own!_**

## How to run your own tests

### Ruby

1. `cd` into the ruby folder
2. `ruby <filename>.rb`

### JavaScript

1. `cd` into the javascript folder
2. `node <filename>.js`

## How to run our tests

### Ruby

1. `cd` into the ruby folder
2. `bundle install`
3. `rspec`

### JavaScript

1. `cd` into the javascript folder
2. `npm i`
3. `npm test`
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "reverse_string",
"version": "1.0.0",
"description": "reverse a string",
"main": "reverse_string.js",
"dependencies": {
"jest": "^26.6.3"
},
"devDependencies": {},
"scripts": {
"test": "jest"
},
"repository": {
"type": "git",
"url": "none"
},
"author": "flatiron",
"license": "ISC"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
function reverseString(str) {
// type your code here
}

if (require.main === module) {
// add your own tests in here
console.log("Expecting: 'ih'");
console.log("=>", reverseString("hi"));

console.log("");

console.log("Expecting: 'ybabtac'");
console.log("=>", reverseString("catbaby"));
}

module.exports = reverseString;

// Please add your pseudocode to this file
// And a written explanation of your solution
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
const reverseString = require('../reverse_string');

test("can handle an empty string", () => {
expect(reverseString("")).toBe("");
});

test("can handle a single character", () => {
expect(reverseString("a")).toBe("a");
});

test("can handle two characters", () => {
expect(reverseString("ab")).toBe("ba");
});

test("can handle three characters", () => {
expect(reverseString("cat")).toBe("tac");
});

test("can handle many characters", () => {
expect(reverseString("sham-meow")).toBe("sham-meow".split("").reverse().join(""));
});
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--require spec_helper
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

source "https://rubygems.org"

git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }

gem 'rspec'
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
def reverse_string(str)
# type your code in here
end

if __FILE__ == $PROGRAM_NAME
puts "Expecting: 'ih'"
puts "=>", reverse_string('hi')

puts

puts "Expecting: 'ybabtac'"
puts "=>", reverse_string('catbaby')

# Don't forget to add your own!
end

# Please add your pseudocode to this file
# And a written explanation of your solution
Loading

0 comments on commit 746742b

Please sign in to comment.