Tumgik
cloudandcode · 7 years
Text
Ruby Notes
Ruby
Credit goes to the Ruby Essential Training course at Lynda.com. Many thanks to Kevin Skoglund for his amazing work!
Single Ruby Command
ruby -e 'puts 123'
puts - prints a value and appends a newline to the end
print- prints a value and DOESN'T append a newline to the end
IRB - Interactive Ruby Shell
irb - to begin
Nil
nil is essentially null. You can test if a value is nil with ?
x = nil x.nil? # true
Ruby Information - Docs
ri is almost like using man in Unix. It stands for Ruby Information.
e.g. ri upcase
Ruby Objects
There are no real primitives. Primitives don't have a common relationship to each other. In Ruby, everything is an object.
Variables Scoping
$var # Global @@var # Class @var # Instance var # Local var # Block
The class method
You can see the class that an object belongs to by using the class keyword.
1234.class # Fixnum 12489010941.class # Bignum '1234'.class # String
Number methods
round - rounds up
to_i - casts as int
floor - rounds down
ceil - similar to round
String interpolation and methods
Only works with double quotes.
a = 5 puts "value of a is #{a}" puts "#{5 + 5}"
reverse
capitalize
upcase
downcase
length
to_s – cast as String
Can use chaining
"Hello".reverse.upcase.length
Arrays
arr = [1, 2, 3] arr[1] # 2 arr << 4 # 1, 2, 3, 4 arr.clear # [] arr.inspect # "[1, 2, 3, 4]" puts arr.inspect # [1, 2, 3, 4] arr.to_s # "[1, 2, 3, 4]" arr.join # "1234" arr.join(', ') # "1, 2, 3, 4" "1,2,3,4".split(',') # [1, 2, 3, 4] arr.reverse # [4, 3, 2, 1] arr.sort # [1, 2, 3, 4] arr2 = [1, 2, 2] arr2.uniq # [1, 2] arr2.insepct # [1, 2, 2] arr2.uniq! # [1, 2] arr2.inspect # [1, 2] arr3 = [3, 4, 5, 6] arr3.delete_at(1) # [3, 5, 6] - returns deleted index arr3.delete(5) # [3, 6] - searches array for term, not index! arr3.push(7) # [3, 6, 7] - adds to end of array. Same as << arr3.pop # [3, 6] - removes and returns last index arr3.shift # [6] - removes and returns first index arr3.unshift(2) # [2, 6] - adds to beginning of array arr3 + [8, 9] # [2, 6, 8, 9] arr3 - [8, 9] # [2, 6] arr3 - [6] # [2] same as delete
Hashes
Unordered, object-indexed collection of objects, aka key-value pairs. We can never count on a hash being in any particular order.
person = {'name' => 'ben', 'age' => 37} person['name'] # ben person.index('ben') # name person.keys # name, age person.values # ben, 37 person.length # 2 person.size # 2 person.to_a # [["name", "ben"], ["age", 37]] changes to array person.clear # {} person = {}
Symbols
A symbol is a label that is used to identify a piece of data.
:someSymbol # declares a symbol
A symbol gets stored in memory one time, whereas a string gets stored in memory many times. Below you can see that a new object is not created for symbol, but it is for string.
"test".object_id # id-1 "test".object_id # id-2 :symbl.object_id # id-3 :symbl.object_id # id-3
Symbols are designed to be used in hashes, because they conserve memory. So if you are looping and creating 10 new Person objects, and each of them has a key labelled "name", then if you use a String, 10 places will be created in memory, but if you use a Symbol, then only one place will be created in memory, and it will be reused 10 times.
Boolean Methods
x = 5 x.nil? # false x.between?(2, 6) # true y = [1, 2, 3] y.empty? # false y.include?(3) # true z = {:a => 1, 'b' => 2} z.has_key?(:a) # true z.has_value(2) # true
Ranges
Ranges are a run of numbers from start to end.
1..4 # Inclusive - 1, 2, 3, 4 1...4 # Exclusinve - 1, 2, 3 1..10.class # Error (1..10).class # Works! Range x = 1..5 x.first # 1 x.begin # 1 x.last # 5 x.end # 5 y = [*x] # [1, 2, 3, 4, 5]
Be careful with exclusive Ranges. Here's why:
x = 1...4 x.end # 4 x.include?(4) # false x.include?(3) # true
You can also create alphabetic ranges:
alpha = a..d z = [*alpha] # a, b, c, d
Constants
Constants are similar to variables in that they are not true objects, but they do point to objects.
Declare constants with full upper case, or with an upper case first letter
TEST = 5 Name = 'Ben'
That said, if you perform an assignment on them, Ruby will issue a warning, but it WILL perform the assignment
TEST = 6 # Warning TEST # 6
Conditionals
if boolean ... end if boolean ... elsif boolean ... else ... end
Tabs are not used by Ruby. They're just there for our benefit.
You can also have a one liner
x = true puts 'hello' if x # hello
Unless
Unless is the same as if !boolean
unless boolean ... elsif boolean ... end
Case
case when boolean ... when boolean ... else ... end
Or you can use the following syntax
case test_value when value ... when value ... else ... end
Ternary
boolean ? code1 : code2 puts x ==1 ? 'one' : 'not one'
Or
Same as Javascript
x = y || z
If y doesn't exist, default to z
Xor
unless x already has a value, set it to y
unless x x = y end x || = y
Loops
Same as a while loop.,
loop do ... end
We use the following to control the loop
* break - Terminate the whole loop * next - Jump to next iteration of the loop * redo - Restart this loop * retry - Start the whole loop over
e.g.
x = 0 loop do x += 2 break if x > 6 puts x end # 2, 4, 6
While
This simply has the break condition built into it.
while boolean ... end
Until
until = While it is not true
until boolean ... end
You can also use these in one liners
x = 0 puts x+=2 while x < 10 puts x+=2 until x > 20
Iterators
Iterators are similar to loops, except that they traverse a fixed set of data. We know where the starting point and ending point is. An iterator says "For each one of these things, do this process".
Similar to map, forEach in JS.
Instead of writing
x = 0 while x < 5 x ++ puts 'Hello' end
We can use:
5.times do puts "Hello" end 1.upto(5) {puts 'Hi'} 5.downto(1) {puts 'Hi'} (1..5).each {puts 'Hi'}
We also have access to the value
1.upto(5) do |i| puts "Hello" + i.to_s end
We can also use for, which is the same as an each
veggies = ['brocolli', 'carrot', 'yam'] for veg in veggies puts veg.capitalize end # Brocolli, Carrot', Yam
We can still use break, next, redo, and retry with Iterators. Although redo and retry are more useful.
retry says go back to the beginning of the set
List of Iterators
Ints/floats - times, upto, downto, step
Range - each, step
String - each, each_line, each_byte
Array - each, each_index, each_with_index (each item with its index)
Hash - each, each_key, each_value, each_pair
Code Blocks
The most common code block methods are:
If you use ! with any of these, they update the values in-place. e.g. merge!
find
merge
collect
sort
inject
Find
We use various find methods to find objects inside a dataset.
find/detect
find_all/select
any?
all?
delete_if - find something, and then delete it, all in one step
E.g's:
(1..10).find {|i| i == 5} # 5 (1..10).find {|i| i % 3 == 0} # 3 Only returns first instance of (1..10).detect {|i| i == 5} # 5 (1..10).detect {|i| i % 3 == 0} # 3 Only returns first instance of (1..10).find_all {|i| i % 3 == 0} # 3, 6, 9 Returns all instances of (1..10).select {|i| i % 3 == 0} # 3, 6, 9 Returns all instances of (1..10).any? {|i| i % 3 == 0} # true. returns true if is true # for ANY inside the set (1..10).all? {|i| i % 3 == 0} # false. returns true if is true # for ALL inside the set [*1..10].delete_if {|i| i % 3 == 0} # same as filter in Javascript
Merge
Is used for merging Hashes together. ONLY used with Hashes. Merge does not change original values, unles you use !. If you use .merge!, original values get overwritten.
h1 = {'a' => 1, 'b' => 555} h2 = {'b' => 2, 'c' => 3} h1.merge(h2) # {"a"=>1, "b"=>2, "c"=>3}
Above we've used it just as a one-liner. If we define a code block, that will only be called if there is a conflict - e.g. b
h1.merge(h2) {|key, old, new| old} # old value gets used h1.merge(h2) {|key, old, new| new} # new value gets used h1.merge(h2) {|key, old, new| new * 2} # new value gets used h1.merge(h2) do |k, o, n| if old < new old else new end end
although we could write this as
h1.merge(h2) {|k, o, n| o < n ? o : n}
Collect / Map
Collect and Map are exactly the same. Multiple names for the same thing. Yuchk...
Works with arrays, hashes, and ranges.
Works the same as Javascript map, except that you have to specify the return value for non matches. E.g.
arr = ['a', 'b', 'c'] arr.map {|val| val.capitalize if val == 'b'} # returns [nil, 'B', nil] - not what you'd expect, right? arr.map {|val| val == 'b' ? val.capitalize : val}
RULE 1: Number of items in = number of items out RULE 2: Even though it works with Hashes and Ranges, it always outputs an array
NOTE: If you use puts in a Collect/Map, then the return array will be filled with nils, because puts always returns nil.
Sort
With sorts, we use the comparison operator <=>. This allows us to compare two values.
a <=> b 1 <=> 2 # -1
Returns -1 if a < b Returns 0 if a = b Returns 1 if a > b
When used with sort,
Move left if a < b Stay in place if a = b Move right if a > b
arr = [3, 5, 2, 1] arr.sort {|v1, v2| v1 <=> v2} # 1, 2, 3, 5 arr.sort # 1, 2, 3, 5 arr.sort {|v1, v2| v2 <=> v1} # 5, 3, 2, 1 arr.sort.reverse # 5, 3, 2, 1
If we just want to sort by one measurement, we can use sort_by
arr = ['cayla', 'daniel', 'adam', 'ben'] arr.sort_by {|name| name.length} # ["ben", "adam", "cayla", "daniel"]
You can sort hashes, but Ruby turns them into an array.
hash = {'a': 5, 'b': 3, 'c': 1} hash.sort {|v1, v2| v1[1] <=> v2[1]} # [[:c, 1], [:b, 3], [:a, 5]]
Inject (Accumulator)
Similar to Javascripts Reduce method.
By convention, the variable that holds the accumulated value is called memo.
(1..10).inject{|memo, n| memo + n} # 55 (1..10).inject(100){|memo, n| memo + n} # 155 init val of memo is 100
Be careful about the return value of memo though. E.g.
(1..10).inject{|memo| memo * n if n != 3} # Error!
When n hits 3, then the entire code block is invalidated and does not run, so nil is returned. Then on the next iterateion, memo is nil and Ruby tries to multiply it by the next value in the Range, which generates and error.
puts also returns nil, so be careful.
(1..10).inject{|memo| puts memo + n; memo}
This says the final value should be memo. It's the only time you get to use semicolon.
Defining and Calling Methods
In other languages, these are called functions, but in Ruby, they're called methods.
def some_name puts 'Hello there' end some_name # Hello there
Modules
Import a file with require. You can require a file in irb.
Return Values
In a method code block, Ruby uses the last line of code as the return value. But we can also use the return keywords.
All methods have a return value, even if its just nil.
Classes
Class name are upper camelCase.
class SomeName ... end
full e.g.
class Person def yell return "Hey!" end end ben = Person.new puts ben.yell.downcase
Attributes
Attributes are values that will persist inside of an instance.
We use instance variables @instance_var as attributes inside of classes.
You never have access to instance variables outside of the class. The class methods have access to them, but outside, we don't.
class Person def set_noise @noise = 'yell' end def yell @noise end end ben = Person.new puts ben.yell
Even though @noise is set inside of another method, it has global scope.
Reader/Writer Methods
This is Ruby's naming take on getter/setters.
class Animal def noise=(noise) @noise = noise end def noise @noise end end cow = Animal.new cow.noise = "Moo!" puts cow.noise # Moo!
Ruby figures out by the arguments which one is which.
Attribute Methods
If you have a large class with lots of attributes, you can use the Attribute methods that Ruby provides to more efficiently set and get attribute values.
attr_reader - creates a reader method
attr_writer - creates a writer method
attr_accessor - creates both a reader and a writer method
The following are the same:
attr_writer :name def name @name end attr_writer :name def name=(value) @name = value end attr_accessor :name def name @name end def name=(value) @name = value end
You can use these to create getter and setter methods for multiple attributes by separating attribute names with commas. E.g.
attr_accessor :name, :age, :weight
Full example
class Animal attr_accessor :name attr_reader :age attr_writer :opinion end cow = Animal.new cow.opinion = "Moo"
Initialize
Use the initialize function name as a constructor in Ruby
class Animal def initialize(val1, val2) @val1 = val1 @val2 = val2 end end cow = Animal.new('bovine', 555)
Class Methods
A class method is a method that can be called on the class, even without an instance of the class.
We can call methods directly on the class.
An example of a class method is cow = Animal.new. Even though there is not yet an instance, we can call new.
class Animal def self.talk puts 'Hello' end end cow = Animal.talk
Class Attributes
Class attributes store values that apply to the class generally.
class Animal @@species = 'bovine' def self.talk puts "Hello #{@@species}" end end cow = Animal.talk
Overloading Methods
Ruby will know which method you want to use based on there being or not being params.
class Animal def self.species @@species end def self.species(arg='') @@species = arg end end Animal.species('froggy') puts Animal.species
Inheritance
Bestowal of methods and attributes of another class.
Ruby terminology is to call the Parent the Superclass and to call the Child the Subclass.
To make a class a Subclass - so that it inherits the variables and methods of another class, use the < sign.
In Ruby, we can inherit from one and only one Superclass. That means that we do NOT have multiple inheritance.
class Animal ... end class Cow < Animal ... end
Subclass overwriting
You can overwrite methods in the Parent class just be redefining them in the Child as long as they have the same name. You can also do this for the core Ruby language:
class Array def to_s self.join(', ') end end
Super
Super is a method that calls the function of the same name in the Parent Class.
class Animal def self.eat puts 'Lets eat' end end class Cow < Animal def self.eat super puts 'Lets eat again' end end Cow.eat
Modules
Modules are wrappers around Ruby code, but that CAN'T be instantiated. You can never have an instance of a module. Instead, we use Modules in conjunction with our classes.
Namespaces
Namespacing allows us to have class names that don't conflict.
We use Modules to namespace Ruby classes to ensure there is no naming conflict that arises.
module Life class Animal def self.eat puts 'Lets eat' end end end Life::Animal.eat
Use the :: to indicate the class belongs to a specific module.
Mixins
We can import blocks of code to our classes using Modules.
module Life attr_accessor :name, :species def breathe puts 'Remember to breathe' end end class Animal include Life end cow = Animal.new cow.breathe
Load, Require, Include
load uses relative and absolute paths to load in an external file.
include is only for bringing Modules in as mixins. It has NOTHING to do with files.
require is the same as load, but if you have already required a file once in the context, it will not load it in again. It keeps track of which files have been loaded, so that it doesn't duplicate the task.
If you want to refresh the code and bring something in a second time, use load, but usually you should just use require.
0 notes
cloudandcode · 7 years
Text
Benefits of Immutability
"Maximum reliance on immutable objects is widely accepted as a sound strategy for creating simple, reliable code." - source - Oracle
But first, a joke...
Definition of an Immutable Object
"In object-oriented and functional programming, an immutable object is an object whose state cannot be modified after it is created." – Source - Wikipedia
Example of a Mutable Object
let username = 'Ben' username = 'Charles'
Example of an Immutable Object
const username = 'Ben' username = 'Charles' Uncaught TypeError: Assignment to constant variable. at <anonymous>:1:10
Understanding Immutability in Javascript - Under the Hood
In JavaScript, only Objects and Arrays are mutable, not primitive values - e.g. Strings and Numbers, which are immutable.
Immutability in this case means that the place in memory where the string is stored in will not be modified.
let a = 'hello' a = a + ' world' console.log(a) // hello world
What's happening
The existing value of a is retrieved from memory
"World" is appended to the existing value of a
The resultant value is then allocated to a new block of memory
a object now points to the newly created memory space
Previously created memory space is now available for garbage collection.
source - MDN Glossary
Javascript Native Objects that are Mutable
Objects
Arrays
Functions
Classes
Sets
Maps
Javascript Primitive Data Types that are Immutable
String
Number
Boolean
Null
Undefined
Symbol
source
Symbol is used to make object properties that are anonymous. This data type is used as the key for an object property when the property is intended to be private, for the internal use of a class or an object type.
source - MDN Glossary
We will deal with const and Object.assign later in the talk.
Benefits of Immutability
Immutable objects:
are thread safe
are simpler to construct, test, and use
avoid temporal coupling
avoid side effects
avoid identity mutability issues
avoid invalid state
increase predictability
improve performance *
enable mutation tracking
provide failure atomicity
are much easier to cache
prevent NULL references, which are bad
* - debatable
1. Immutable Objects are Thread Safe
Immutable objects are thread safe. This means that multiple threads can access the same object at the same time without clashing with one another.
If no object methods can modify its state, no matter how many of them and how often they are being called parallel — they will work in their own memory space in stack.
In Javascript, Thread Safety is usually not an issue since the Browser is single threaded, meaning that only one command (of your code) is executed at a time.
That said, multi-threading is possible with Web Workers, which spawn real OS-level threads.
However, since web workers have carefully controlled communication points with other threads, it's actually very hard to cause concurrency problems. There's no access to non-threadsafe components or the DOM. And you have to pass specific data in and out of a thread through serialized objects. So you have to work really hard to cause problems in your code.
That said, MDN themselves provide an example of a threading error using Web Workers, so it's possible.
source MDN
2. Immutable Objects are Simpler to Construct, Test, and Use
Mutable objects can have different internal states throughout their lifetime, all of which need to be tested explicitly.
Imagine having to test the following:
let request = new Request() let updateComments = comments => { request.method = "PUT" request.payload = comments sendXHR(request) } let fetchPosts = () => { request.method = "GET" return sendXHR(request) // payload may have been set by updateComments } let sendXHR = request => { $.ajax(request) }
If request is mutable, then by the time it gets to sendHXR, you're not really sure what's in it. You have to write lots of extra tests to check and verify its internal state.
If request was immutable, there would be no such uncertainty.
3. Immutable Objects Avoid Temporal Coupling
Temporal Coupling occurs when two actions are bundled together into one module just because they happen to occur at the same time.
source - Wikipedia
let request = new Request(url) request.method = "POST" let first = request.send() request.body = payload let second = request.send()
This code works. However, you must remember that the first request should be configured before the second one may happen. If we decide to remove the first request from the script, we will remove the second and the third line, and won't get any errors from the compiler:
let request = new Request(url) // request.method = "POST" // let first = request.send() request.body = payload let second = request.send()
Now the script is broken although it compiled without errors. This is what temporal coupling is about - there is always some hidden information in the code that a programmer has to remember. In this example, we have to remember that the configuration for the first request is also used for the second one, and that the second request should always stay together and be executed after the first one.
If the Request class were immutable, the requests would not be coupled, and removing one will not stop the other from working.
const post = new Request(url, "POST") const first = post.send() const second = post.send(payload)
4. Immutable Objects Avoid Side Effects
A function or expression is said to have a side effect if it modifies some state outside its scope or has an observable interaction with its calling functions or the outside world besides returning a value.
source
In the following code, we only intended to send requests to 2 URLs, but another part of the app added a url, and now a side effect has occurred where an unexpected & unwanted request is being sent. If urls was immutable, this could not have happened.
let urls = ['cred.com', 'loans.com'] // Some other part of the app makes an unexpected addition urls.push('refi.com') for (let i = 0; i < urls.length; i++) { sendXHR(urls[i]) }
XKCD - Side Effects
5. Immutable Objects Avoid Identity Mutability Issues
In my research, I found 2 different opinions on what Object Identity means.
* Reference Identity - the identity of an object is what address it points to in memory * Value Identity - the identity of an object consists of the values it contains.
Equality
i.e. With regard to Reference Identity, 2 objects are considered equal if they both point to the same place in memory. Re Value Identity, 2 objects are considered equal if they contain the same values.
source - Oracle
For the purposes of this lecture, I'm only going to deal with Value Identity.
Identity mutability issues
In certain situations, you may want to use an Object Identity as a key in a Map (key value pairs). If this object is mutable, and its identity changes, it will no longer be usable as a key in that Map.
let d1 = new Date() let guests = {} guests[d1] = "Value" console.log(guests[d1]) // Value d1.setDate(d1.getDate() + 1) // Changed by something else console.log(guests[d1]) // Undefined
If using a Date object as a key is unpalatable to you, then consider if we were to use an object property as the key.
e.g.
let person = new Person({id: 1234, name: "Ben"}) let guests = {} guests[person.id] = "Ben Grunfeld" person.id = "4321"
6. Immutable Objects Avoid Invalid State
Ensuring that a mutable object maintains a valid state can be extremely difficult. Imagine we have a rate (e.g. APR) that has a minimum and a maximum, and that the current value must stay between those two limits.
let rate1 = new Rate({min: 1, max: 100, current: 50}) rate1.max = 45
The object is now in an invalid state. Of course, we can enforce coding standards by convention, but it's hard to know how other parts of the application will use our code and if they will follow our conventions. If our object is mutable, then we have to start checking validity both in the constructor (when the object is created) and on any mutation.
Here is an incomplete list of rules to ensure valid state when using mutable objects:
Rule 1: Always re-validate every rule to ensure the correctness of an object.
Rule 2: You must always validate before mutating.
Rule 3: The second rule doesn't need to be followed in a constructor. In a constructor you are always allowed to mutate and then validate afterwards.
Rule 4: If there is a way to fix an invalid object, you are allowed to mutate and validate even outside of a constructor.
Rule 5A: Mutable objects must have some kind of notification mechanism when they change.
Rule 5B: Mutable objects must have a Copy function that can create deep copies of an object.
Rule 6A: Every mutable object we return must have a changed event that gets fired when an object was mutated.
Rule 6B: Never return mutable objects directly. Return defensive copies instead.
Rule 6C: Don't allow access to internal mutable objects at all.
Rule 7: Events can only be used if there is a way to fix an invalid object. If there is no way to fix an invalid object, use defensive copies.
Rule 8: If your mutable objects are accessed by multiple threads (mutable shared state) you also must add synchronization primitives to avoid race conditions that can bring an object into an invalid state.
Bonus Rule: Just because every method of an object has synchronization primitives doesn't mean it is thread-safe. Because of this, you probably want to ignore Rule 8.
Agreeing on a set list of such rules inside of a large engineering team is difficult (to say the least). As the saying goes, "2 programmers, 3 opinions". Educating new devs in the above rules and enforcing/ensuring that they are ALL implemented becomes a big headache really quickly, and I'd argue that it borders on being impossible. People make mistakes, especially when things are complex - it's simply human nature.
Alternatively, when using truly Immutable objects, there are only two rules for ensuring valid state.
Rule 1: All validation logic must be contained in the constructor.
Rule 2: The constructor must be used when instantiating an object.
Now that is MUCH simpler, and easier to agree upon and enforce in a large engineering team.
source
7. Immutable Objects Increase Predictability
Needing to know the contents of an object
If you don't truly know what the contents of the object you're working with are, it becomes much harder to predict what will happen.
Combining immutable objects with pure functions
If your object is immutable, and is passed to a pure function, as soon as it executes once correctly, you know that it will work the same way forever.
8. Immutable Objects Help Improve Performance
Arguments that immutability hurts performance:
Creating new objects in memory is more expensive that mutating existing ones
Defensive copying (making a complete copy of an object and implementing changes on the copy instead of the original) creates a lot of garbage which would be avoided by mutating existing objects
Oracle's rebuttal
"Programmers are often reluctant to employ immutable objects, because they worry about the cost of creating a new object as opposed to updating an object in place. The impact of object creation is often overestimated, and can be offset by some of the efficiencies associated with immutable objects. These include decreased overhead due to garbage collection, and the elimination of code needed to protect mutable objects from corruption."
source
Arguments that immutability improves performance
Performance is largely a Productivity metric in a non-trivial codebase - i.e. developer performance
With an increase to productivity and (thread) safety can often come an increase to practical performance, if only because the developers have more time to tune and optimize their code without being swarmed by bugs.
source
Regarding Immutable.js' performance
Some people claim that Immutable.js is actually much faster than native Javascript in some circumstances.
source
Immutable-focused libraries such as Immutable.JS have been designed to overcome the issues with immutability inherent within JavaScript
In particular, immutably manipulating large, complex data sets, such as a nested Redux state tree, can generate many intermediate copies of objects, which consume memory and slow down performance as the browser’s garbage collector fights to clean things up. Immutable.JS avoids this by cleverly sharing data structures under the surface, minimizing the need to copy data.
source
9. Immutable Objects Enable Mutation Tracking
One of the more complicated operations in Javascript is tracking if an object changed.
Subscribing to data events throughout your application creates a huge overhead of book-keeping which can hurt performance, sometimes dramatically, and creates opportunities for areas of your application to get out of sync with each other due to easy to make programmer error.
source
However, if you keep your state immutable you can just rely on oldObject === newObject to check if state has changed or not. This is way less CPU demanding.
source
10. Immutable Objects Provide Failure Atomicity
"Failure atomicity" means that if a method threw an exception, the object should still be usable afterwards.
When using Immutable objects, failure atomicity happens by default, since the object's state cannot be modified.
Example of lack of failure atomicity when working with mutable objects
let size = 3 let data = 'abc' while (size > -2) { data.repeat(--size) } // Uncaught RangeError: Invalid count value
After this code runs, the size object will be left in an inconsistent (negative) state, causing any future method invocations on the object to fail.
Now lets try the same example using immutable objects
const size = 3 const data = 'abc' function repeater(num) { console.log(data.repeat(size - num)) console.log(num) if (num > 5) return repeater(num + 1) } repeater(0)
You still get the error, but size is in a consistent and usable state
After an object throws an exception, it is generally desirable that the object still be in a well-defined, usable state, even if the failure occurred in the midst of performing an operation. This is especially true for checked exceptions, from which the caller is expected to recover. Generally speaking, a failed method invocation should leave the object in the state that it was in prior to the invocation. A method with this property is said to be failure atomic.
There are several ways to achieve this effect. The simplest is to design immutable objects. If an object is immutable, failure atomicity is free. If an operation fails, it may prevent a new object from getting created, but it will never leave an existing object in an inconsistent state, because the state of each object is consistent when it is created and can’t be modified thereafter.
For methods that operate on mutable objects, the most common way to chieve failure atomicity is to check parameters for validity before performing the operation (Item 38). This causes any exception to get thrown before object modification commences.
source
11. Immutable Objects are Much Easier to Cache
You can freely share and cache references to immutable objects without having to copy or clone them; you can cache their fields or the results of their methods without worrying about the values becoming stale or inconsistent with the rest of the object's state.
If an object is mutable, you have to exercise some care when storing a reference to it
source
12. Immutable Objects Prevent NULL References, Which Are Bad
Tony Hoare once said: I call it my billion-dollar mistake. It was the invention of the null reference in 1965.
source
One reason why null references are evil is that you cannot see if a function could return null or not. There are many others.
source2
So, let's just agree for the moment that null is bad.
Nulls can creep into your code and cause havoc. E.g.
let user1 = {name: 'Ben'} function greet(user) { return `Hello there ${user.name}` } // Unintended mutation from another part of the app // attempting to update the user1 object user1 = fetch(user) // error occurs and returns null greet(user1) // Uncaught TypeError: Cannot read property 'name' of null
Enforcing Immutability by Convention
Some developers may try to enforce immutability in their code by convention, but this approach has several problems regarding the capabilities and limitations of the language.
The Problem with Using Defensive Copying for Immutability
If Javascript, we can use Object.assign to perform defensive copying. As noted above, the problem is that extensive use of defensive copying has a significant performance cost, which is why it's best to use optimized libraries like Immutable.js that mitigate these issues.
const a = { name: "Ben"} const b = Object.assign({}, a)
The Problem with Using const for Immutability
[const] does not mean the value it holds is immutable, just that the variable identifier cannot be reassigned.
source
The problem is that const creates a read-only variable, although if the variable is an object or an array, its properties are still mutable.
const a = 5 a = 6 // Uncaught TypeError: Assignment to constant variable. const b = { name: "Ben" } b.name = "Bob" // Works without error const c = [1, 2, 3] c[0] = 5 // Works without error
The Problem with Using Object.freeze for Immutability
[Object.freeze] prevents new properties from being added to it; prevents existing properties from being removed; and prevents existing properties, or their enumerability, configurability, or writability, from being changed, it also prevents the prototype from being changed.
That sounds great! The variable can still be reassigned, but if we use Object.freeze together with const, we should be moving in the right direction... Nope!
The problem is that Object.freeze is shallow, meaning that if a frozen object contains other mutable objects, then it will not be truly immutable.
To ensure that it is truly immutable, every property needs to be recursively frozen (deep freeze), which can get dangerous. If an object contains cycles (circular reference), then an infinite loop will be triggered.
Another danger is that if you recursively freeze everything in the object without knowing exactly what's in there, you may freeze something that should be frozen e.g. the window object.
source
Conclusion
Use Immutable.js. You get all of the benefits listed above, but the dangers of doing immutability yourself and the performance costs associated with techniques like defensive copying are mostly, if not entirely mitigated.
Other Sources
Objects Should be Immutable
Three Benefits of Using Immutable Object
Why is immutability so important(or needed) in javascript?
About Thread Safety in Javascript
Mutability vs Immutability re Valid State
IMB - To mutate or not to mutate
Null References: The Billion Dollar Mistake
0 notes
cloudandcode · 7 years
Text
React Interview Questions
General React Theory Questions
What is React, who developed it, and how is it different from other frameworks?
React is a JavaScript library that was developed by Facebook for building User Interfaces (UI's). This corresponds to the View in the Model-View-Controller (MVC) pattern.
React uses a declarative paradigm that makes it easier to reason about your application, and React computes the minimal set of changes necessary to keep your DOM up-to-date.1 2
How do you tell React to build in Production mode and what will that do?
Typically you’d use Webpack’s DefinePlugin method to set NODE_ENV to production. This will strip out things like propType validation and extra warnings.
Explain what JSX is and how it works
React components are typically written in JSX, a JavaScript extension syntax allowing quoting of HTML and using HTML tag syntax to render subcomponents. HTML syntax is processed into JavaScript calls of the React framework. Developers may also write in pure JavaScript.
Explain how the One-Way Data Flow works
In React, data flows from the parent to the child, but not the other way around. This is designed to alleviate cascading updates that traditional MVC suffers from.
Properties, a set of immutable values, are passed to a component's renderer as properties in its HTML tag. A component cannot directly modify any properties passed to it, but can be passed callback functions that do modify values. This mechanism's promise is expressed as "properties flow down; actions flow up".
What are the differences between React in ES5 and ES6? What are the advantages/disadvantages of using ES6?
Syntax
Creating React Components the ES5 way involves using the React.createClass() method. In ES6, we use class SomeModule extends React.Component{}
Autobinding
React in ES5 has autobinding, while React in ES6 does not. For that reason, we have to use bind to make this available to methods in the constructor.
// React in ES5 var thing = { name: 'mike', speak: function(){ console.log(this.name) } } window.addEventListener('keyup', thing.speak)
In the above code, if we call thing.speak(), it will log mike, but pressing a key will log underfined, context of the callback is the global object. The browser’s global object – window – becomes this inside the speak() function, so this.name becomes window.name, which is undefined.
React in ES5 automatically does autobinding, effectively doing the following:
window.addEventListener('keyup', thing.speak.bind(thing))
Autobinding automatically binds our functions to the React Component instance so that passing the function by reference in the render() works seamlessly.3
But in ES6, we need to make the context of this available to the sayHi method by using bind.
export class App extends Component { constructor(props) { super(props) this.state = { name: ben, age: 37 } this.sayHi = this.sayHi.bind(this) } sayHi() { console.log(this.state.name) } }
Explain the Virtual DOM and how React renders it to the actual DOM.
React creates an in-memory data structure cache, computes the resulting differences, and then updates the browser's displayed DOM efficiently.
How does transpiling with Babel work?
Babel transpiles React code to plain vanilla Javascript that is cross browser compliant.
What is the difference between React's Router and Backbone's Router?
When a route is triggered in Backbone's router, a list of actions are executed. When a route is triggered in React's router, a component is called, and decides for itself what actions to execute.
Differences:
If you used Backbone's Router with React, it would have to manually mount and unmount React components from the DOM regularly. This would cause havok.
Backbone's router demands that you create a flat list of routes (/users/:id, /users/:post, users/list).
React uses Higher Order Components (HOC's) that have children define sub routers. E.g.
<Router history={browserHistory}> <Route path="/" component={MainApp}> <Route path="contact" component={Contact}/> <Route path="posts" component={Posts}> <Route path="/user/:userId" component={UserPage}/> </Route> <Route path="*" component={NoMatch404}/> </Route> </Router>
LifeCycle Questions
Explain the stages of a React Component's lifecycle
Mounting
These methods are called when an instance of a component is being created and inserted into the DOM.
constructor()
componentWillMount()
render()
componentDidMount()
Updating
An update can be caused by changes to props or state. These methods are called when a component is being re-rendered.
componentWillReceiveProps()
shouldComponentUpdate()
componentWillUpdate()
render()
componentDidUpdate()
Unmounting
This method is called when a component is being removed from the DOM.
componentWillUnmount()
Explain the lifecycle methods, when they occur, and how you would use each of them
Mounting
constructor - The constructor for a React component is called before it is mounted. If you don't call super(props) in the constructor, this.props will be undefined. You should initialize your state here too.
componentWillMount - invoked immediately before mounting occurs. It is called before render, therefore setting state in this method will not trigger a re-rendering. Avoid introducing any side-effects or subscriptions in this method.
render - creates a tree of React elements. When called, it examines this.props and this.state and returns a single React element. This element can be either a representation of a native DOM component, such as <div />, or another composite component that you've defined yourself. Returning null or false indicates that you don't want anything rendered.
componentDidMount - invoked immediately after a component is mounted. Ideal place for network requests (e.g. AJAX). Setting state in this method will trigger a re-rendering.
componentWillReceiveProps - is invoked before a mounted component receives new props. This is a good place to update the state in reponse to changes in props. Calling setState generally doesn't trigger componentWillReceiveProps.
Updating
shouldComponentUpdate - allows you to decide if you wish to re-render the component when new props or state are received. Invoked before rendering when new props or state are being received. Defaults to true. Not called on initial render or on forceUpdate. If shouldComponentUpdate returns false, then componentWillUpdate, render, and componentDidUpdate will not be invoked. Returning false does not prevent child components from re-rendering when their state changes.
componentWillUpdate - invoked immediately before rendering when new props or state are being received. Cannot call setState here and is not called on initial render. If you need to update state in response to a prop change, use componentWillReceiveProps.
componentDidUpdate - invoked immediately after update occurs. Operate on the DOM in this method and make network requests here, if needed, but compare to previous props & state. Not called for the initial render.
Unmounting
componentWillUnmount - invoked immediately before a component is unmounted. Perform cleanup here, e.g. invalidating timers, canceling network requests, or cleaning up any DOM elements that were created in componentDidMount.
Explain how setState works
setState(updater, callback)
setState takes 2 arguments, an updater and a callback that gets executed once setState has completed.
The updater can either be a function or an object. Both are executed asynchronously. If it is a function, it takes the form:
setState((prevState, props) => { return newState })
If you supply an object to setState instead of the above function, then that will become the new state.
What happens when you call setState? AKA explain how Reconciliation works.
When setState is called, the object returned from the updater becomes the current state of the component. This will begin the process of reconciliation, which aims to update the UI in the most efficient way possible, according to the reconciliation algorithm.
React diffs the previous root element to the new root element. If they are are of different types (<article> vs <section>), React will tear down the old tree and create a completely new one. If they are the same type, only the changed attributes will be updated.
When tearing down a tree, old DOM nodes are destroyed and componentWillUnmount is called on them. When building up a new tree, new DOM nodes are inserted into the DOM.
The core idea of reconcialiation is to be as efficient as possible on the UI by only making updates where absolutely necessary.
What is the difference between forceUpdate and setState? Do they both update the state?
setState causes your app to update when props or state have changed. But if your app relies on other data, you can force an update (render) with forceUpdate.
Calling forceUpdate will cause render to be called on the component, skipping shouldComponentUpdate. This will trigger the normal lifecycle methods for child components, including the shouldComponentUpdate method of each child. React will still only update the DOM if the markup changes.
Use of forceUpdate should be avoided as much as possible. Use state and props instead.
What is the second argument that can optionally be passed to setState and what is its purpose?
The second argument is a callback that gets executed once setState has completed.
In which lifecycle event do you make AJAX/Network requests and why?
Use componentDidUpdate or componentDidMount. If you use componentWillMount, the AJAX request could theoritically resolve before the component has mounted. Then you would be trying to call setState on a component that hasn't mounted, which would introduce bugs. Secondly, componentWillMount might get called multiple times per render by React's reconciliation algorithm for performance reasons. That would cause multiple AJAX requests to get sent.
Feature Specific Questions
What’s the difference between an Element and a Component in React?
An element is a representation of something in the UI, which will usually become HTML, e.g. <a>, <div>, etc.
A component is a function or class that accepts input and returns an element or other components.
What is the difference between Class Components and Stateless Functional Components (aka Pure Functional Components, etc)? When would you use one over the other?
If your component needs to work with this.state, or this.setState, or lifecycle methods, use a Class Component, otherwise use a Stateless Functional Component.
What is the difference between createElement and cloneElement?
createElement creates a new React element. cloneElement clones an existing React element.
What are refs in React and why are they important?
Refs are an escape hatch from React's declarative model that allow you to directly access the DOM. These are mostly used to grab form data in uncontrolled components. (In uncontrolled components, data is handled by the DOM itself, instead of via the React components, which is controlled).
Avoid using refs for anything that can be done declaratively.
You may not use the ref attribute on functional components because they don't have instances.
Give a situation where you would want to use refs over controlled components
Managing focus, text selection, or media playback.
Triggering imperative animations.
Integrating with third-party DOM libraries.
What are keys in React and why are they important?
Keys help React become more efficient at performing updates on lists.
What is the difference between a controlled component and an uncontrolled component?
In uncontrolled components, data is handled by the DOM itself. In controlled components, data is only handled by the React component.
In HTML, form elements such as <input>, <textarea>, and <select> typically maintain their own state and update it based on user input. In React controlled components, mutable state is typically kept in the state property of components, and only updated with setState.
This means that state is the single source of truth. So if you wanted to change the value of an <input> box, you would call setState every time the user pressed a key, which would then fill input with the new value of state.
In uncontrolled components, we usually use refs to grab the data inside of form fields.
What are High Order Components (HOC's) and how would you use them in React?
HOC's aren't just a feature of React, they are a pattern that exists in software engineering.
A higher-order component is a function that takes a component and returns a new component.
Whereas a component transforms props into UI, a higher-order component transforms a component into another component.
An HOC doesn't modify the input component, nor does it use inheritance to copy its behavior. Rather, an HOC composes the original component by wrapping it in a container component. An HOC is a pure function with zero side-effects.
The wrapped component receives all the props of the container, along with a new prop, data, which it uses to render its output.
What is the difference between using extend, createClass, mixins and HOC's? What are the advantages and disadvantages of each?
Mixins
The point of mixins is to give devs new to functional programming a way to reuse code between components when you aren’t sure how to solve the same problem with composition. While they aren't deprecated, their use is strongly not recommended. Here's why 1:
Mixins introduce implicit dependencies
Mixins cause name clashes
Mixins cause snowballing complexity
HOC's - above
Extends
Mixins are possible, but not built-in to React’s ES6 API. However, the ES6 API makes it easier to create a custom Component that extends another custom Component.
ES6 classes allow us to inherit the functionality of another class, however this makes it more difficult to create a single Component that inherits properties from several mixins or classes. Instead, we need to create prototype chains.
How does PropType validation work in React?
PropTypes allow us to supply a property type for all of our different properties, so that it will validate to make sure that we're supplying the right type.
This is kind of like strong typing in Java (e.g. int, char, string, obj, etc).
If you use an incorrect type, or the value is required but you don't have it, React will issue a warning, but won't crash your app.
Why would you use React.Children.map(props.children, () => ) instead of props.children.map(() => )
It’s not guaranteed that props.children will be an array. If there is only one child, then it will be an object. If there are many children, then it will be an array.
<Parent> <Child /> </Parent>
vs
<Parent> <Child /> <Cousin /> </Parent>
Describe how events are handled in React
In order to solve cross browser compatibility issues, your event handlers in React will be passed instances of SyntheticEvent, which is React’s cross-browser wrapper around the browser’s native event. These synthetic events have the same interface as native events you’re used to, except they work identically across all browsers.
Where does a parent component define its children components?
Within the render method
Can a parent component access or read its children components properties?
Yes
How do you set the value of textarea?
In React, a <textarea> uses a value attribute instead. This way, a form using a <textarea> can be written very similarly to a form that uses a single-line input.
What method do you use to define default values for properties?
In ES6 classes
SomeModule.defaultProps = {name: 'Ben', age: 36}
In Stateless Functional Components, just use ES6 named params.
export const SomeModule = ({name="Ben", age=36}) => { return ( <div>{name}, {age}</div> ) }
What does it mean when an input field does not supply a value property?
That you're using an uncontrolled component.
Sources
A lot of this information was learned and borrowed from the following:
https://www.lynda.com/React-js-tutorials/React-js-Essential-Training/496905-2.html
https://www.toptal.com/react/interview-questions
https://tylermcginnis.com/react-interview-questions/
https://www.codementor.io/reactjs/tutorial/5-essential-reactjs-interview-questions
0 notes
cloudandcode · 7 years
Text
Webpack Tutorial
Webpack is a build tool that allows us to take all of our assets independencies and turn them into a production ready bundle. All of our files are considered modules and we tell webpack to load those modules and require them when we configure our project.
This from the Webpack npm page:
webpack is a bundler for modules. The main purpose is to bundle JavaScript files for usage in a browser, yet it is also capable of transforming, bundling, or packaging just about any resource or asset.
Credit
Credit to Lynda.com for much of this information - although their version is a little outdated - there are some errors that their code now produces since, which I have found fixes to.
Special thanks to Eve Porcello for her wonderful course, which can be found at https://www.lynda.com/Webpack-tutorials/Learn-Webpack-Basics/483222-2.html
Example Code
Examples of nearly all of the concepts below are available at: https://github.com/bengrunfeld/webpack-examples
Difference Between Webpack, Gulp, and Grunt
Webpack is a module bundler. Gulp and Grunt are task runners.
While Webpack can transpile and modify code, there are some things Gulp and Grunt can do that Webpack can't, but these tasks can be performed by using npm scripts in your package.json with much less code.
Using the Webpack CLI
In the following code, webpack takes entry.js as the input, and outputs the file to ./dist/main.bundle.js
webpack entry.js ./dist/main.bundle.js
Using the Webpack Config File
To save your configuration to a file, create webpack.config.js. The file below will output the bundled code to dist/main.bundle.js
let path = require('path') module.exports = { entry: './src/entry.js', output: { path: path.join(__dirname, 'dist'), filename: 'main.bundle.js' } }
Using the -w flag
If run webpack -w, it will watch the entry point that you provided, and if anything changes in it, it will rebundle your package.
Loaders
Webpack loaders load and perform transformations on files. Typically use cases for loaders are JSX and ES6. JSX isn't supported natively in browsers, and not all features of ES6 are supported across all browsers, so both need to be transpiled into plain vanilla Javascript in order for them to run smoothly. We use loaders for this.
In most cases, we use Babel (babel-loader) to perform this transpilation step.
npm install babel-loader babel-core babel-preset-es2015 babel-preset-react --save-dev
let path = require('path') module.exports = { entry: './src/entry.js', output: { path: path.join(__dirname, 'dist'), filename: 'main.bundle.js' }, module: { loaders: [ { test: /\.js$/, exclude: /(node_modules)/, loader: 'babel', query: { presets: ['es2015', 'react'] } } ] } }
In Babel 6, you have to opt-in for any transpilation steps. So you have to specify what you want to transpile using presets. Note the query object that has presets for es2015 and react.
We also have to set up a .babelrc file
{ 'presets': [ 'es2015', 'react' ] }
If you receive a deprecation warning for using babel-loader, it's a known bug and they're trying to fix it.
Simply set process.noDeprecation = true in the main part of the file (i.e. outside of module.exports) and all will be well.
Loading CSS with Webpack
When you load CSS as a module in your code, Webpack will only bundle the styles that your app uses. To do this, you need to require the CSS file in your JS code.
First you need to install dependencies.
npm install style-loader css-loader --save-dev
Then add a css loader to your webpack.config.js
module: { loaders: [ { test: /\.css$/, loader: 'style-loader!css-loader' } ] }
Then require the css file inside of your Javascript
require('./dist/style.css')
Loading SASS with Webpack
We can use Webpack loaders to transpile SASS (*.scss).
npm install sass-loader node-sass --save-dev
Then just change the CSS loader to the following in your webpack.config.js
{ test: /\.scss$/, loader: 'style-loader!css-loader!sass-loader' }
And of course in your Javascript files, change the file extensions in the require statements to scss
require('./style.scss')
Loading Images with Webpack
We use url-loader with Webpack to load images. Webpack in-lines a URL to the image bundle and then returns it from require. We wanna do this because in-lining images will reduce the number of HTTP requests which will speed up our applications a lot.
npm install url-loader file-loader --save-dev
Then in your SASS file, you just load an image as usual, e.g. background: url(mypic.jpg).
To enable in your webpack.config.js:
{ test: /\.(png|jpg)$/, loader: 'url-loader?limit=20000' },
The limit=20000 just means that if the image size is greater than 20kb, then use the loader to create a direct url to the image asset.
Code Splitting
Code splitting is the idea of using multiple entry points for better performance optimization. So if someone loads the contact us page, they do not receive the code for about us as well. They only receive the code that they need to load that page.
This way, separate bundles are created for different pages. So we will only load the code that we need.
For example, say you have home.html that calls home.js which in turn requires messages.js.
And you also have blog.html that calls blog.js which in turn requires posts.js
The following webpack config file will cause 2 bundles to be created - home.bundle.js and blog.bundle.js. home will only have the code that it needs, and blog will only have the code that it needs.
entry: { home: './src/home', blog: './src/blog' }, output: { path: path.join(__dirname, 'dist'), filename: '[name].bundle.js' },
Common Chunks Plugin
The CommonsChunkPlugin will look for reused code and will create a separate bundle with common code. Then we'll load the common code into the page first and load in page specific code after that.
To use it in your webpack.config.js
let CommonsChunkPlugin = require('./node_modules/webpack/lib/optimize/CommonsChunkPlugin') entry: '', output: '', module: { loaders:[] }, plugins: [ new CommonsChunkPlugin('commons', 'commons.bundle.js') ]
commons.bundle.js will now be added to dist and it will have any code that is common inbetween home and blog. So, home.bundle.js is code just for the home page. blog.bundle.js is code just for the blog page.
Then you need to call commons.bundle.js via script tags in all the html files that need access to it. In our example - home.html and blog.html.
Creating a Vendor Bundle
webpack.config.js
entry: { home: './src/home', blog: './src/blog', vendor: ['jquery', 'react', 'react-dom'] }, output: {}, module: {}, plugins: [ new CommonsChunkPlugin({name: 'vendor', filename: 'vendor.bundle.js'}) ]
This will create a bundle of all our vendor code, in the above example, specifically jquery, react, and react-dom.
You then need to change the <script src=""> tags to vendor.bundle.js in your html pages.
Hot Reloading with Webpack Dev Server
Webpack offers a dev server that will immediately re-transpile and bundle your code every time it detects a change. It will also allow you to view your project at a local url like localhost:3000.
In our webpack.config.js
entry: './dist/app.js', output: { path: path.join(__dirname, 'dist'), filename: 'main.bundle.js' }, devServer: { inline: true, contentBase: './dist', port: 3000 },
In our package.json
"scripts": { "build": "webpack", "start": "webpack-dev-server" },
Now, if you make a change to any of the files that are being watched, webpack dev server will recompile.
0 notes
cloudandcode · 7 years
Text
Node.js Tutorial Notes
Node.JS
Node.js is an open-source cross platform runtime environment for server-side and networking applications. It's built on top of Chrome's Javascript Runtime, the V8 Engine. Applications for Node are written in JavaScript.
Docs
https://nodejs.org/api/
Credit
Credit to Lynda.com for their fantastic courses that helped me put together much of this information.
Working with Modules
In Node, files and modules are the same thing. E.g. in Python, you need a folder with __init__.py in it to be classified as a module. You DON'T need that in Node. It's all just files.
file1.js:
exports.myText = 'how are you?';
file2.js:
var file1 = require('./file1.js'); console.log('hello, ', file1.myText);
Async
Node.js is single-threaded. All of the users are sharing the same thread. Events are raised and recorded in an event queue and then handled in the order that they were raised.
Node.js is asynchronous, which means that it can do more than one thing at a time. This ability to multitask is what makes Node.js so fast.
The Global Object
<object> The global namespace object.
In browsers, the top-level scope is the global scope. That means that in browsers if you're in the global scope var something will define a global variable. In Node.js this is different. The top-level scope is not the global scope; var something inside an Node.js module will be local to that module.
Every node js file that we create is it's own module. Any variable that we create in a node js file, is scoped only to that module. That means that our variables are not added to the global object the way that they are in the browser.
Get Current Directory and Filename
These will give you the current directory and current filename:
console.log(__dirname) console.log(__filename)
You can also use the inbuilt path module for extra features re paths.
var path = require('path') console.log(path.basename(__filename))
This will pluck the base filename from a full path.
We can also use the path module to create path strings. The path.join() function can be used to join strings together in a path.
var pathString = path.join(__dirname, 'src', 'js', 'components') // if you log this, it comes out [full static path]/src/js/components
The .js Extension
You can leave off the .js extension in the command line when calling files and in require statements, because it's assumed by Node
So instead of:
node index.js
You can do
node index
The Process Object
Allows us to interact with information about the current process.
We can use the process object to get environment information, read environment variables, communicate with the terminal, or parent processes, through standard input and standard output. We can even exit the current process. This object essentially gives us a way to work with the current process instance. One of the the things that we can do with the process object is to collect all the information from the terminal, or command prompt, when the application starts.
All of this information will be saved in a variable called process.argv which stands for the argument variables used to start the process.
So if you call a node file with
node index --user Ben --password whyH3ll0
And you console.log(process.argv), the above flags and values will be printed in their data structure.
Another feature of the process object is standard input and standard output. These two objects offer us a way to communicate with a process while it is running.
process.stdout.write - uses the standard output to write things to the terminal. console.log uses this.
process.stdin.on('data', callback) - uses the standard input to accept data from the user and fire a data event (i.e. data event is where a user enters something via the terminal and hits enter).
To exit a process use process.exit()
You can use process.on('exit', () => {}) to catch the exit event and then do something.
process.stdout.cleanLine() - will clear the current line in the terminal
process.stdout.cursorTo(i) - will send the cursor to position i on the current line.
The Util Module
The util.log method is similar to console.log, except it adds a data and a timestamp. Cool!
let util = require('util') util.log('An error occurred')
The Event Emitter
The Event Emitter is Node.js's implementation of the pub/sub design pattern, and it allows us to create listeners for an emit custom Events.
let events = require('events') let emitter = new events.EventEmitter() emitter.on('customEvent', (message, status) => { console.log(`${status}: ${message}`) }) emitter.emit('customEvent', 'All is good', 200)
Inheriting the Event Emitter into an Object
The utilities module has an inherits function, and it's a way that we can add an object to the prototype of an existing object.
let EventEmitter = require('events').EventEmitter let util = require('util') let Person = (name) => { this.name = name } util.inherits(Person, EventEmitter)
If we now create a new instance of a Person, it will have an on and emit function.
Creating Child Processes with Exec
Node.js comes with a child_process module which allows you to execute external processes in your environment. In other words, your Node.js app can run and communicate with other applications on the computer that it is hosting.
let exec = require('child_process').exec exec('ls', (err, stdout) => { if (err) { throw err } console.log(stdout) })
Creating Child Processes with Spawn
spawn is similar to exec, but it is meant for ongoing processes with larger amounts of data. exec is good for small singular commands.
let spawn = require('child_process').spawn let cp = spawn('node', ['myFileToRun']) cp.stdout.on('data', (data) => { console.log(`STDOUT: ${data.toString()}`) }) cp.on('close', () => { console.log('finished') process.exit() })
Working with the File System
Node allows you to work with the file system via asynchronous or synchronous commands. All synchronous commands are suffixed with Sync, e.g.
let fs = require('fs') console.log(fs.readdirSync('./'))
If you wish to use the Async version, then just leave off the Sync at the end.
let fs = require('fs') fs.readdir('./', (err, files) => { if (err) { throw err } console.log(files) })
File Streams
readFile buffers all of the data from a file, so if it gets too big, you could have a memory overflow or develop system slowdown or any number of problems.
For large files, it's better to use streams, which just grab small chucks of the file at a time and allow you to do work with them individually.
let fs = require('fs') let stream = fs.createReadStream('./status.log', 'UTF-8') let data = '' stream.once('data', () => { console.log('Started Reading File') }) stream.on('data', (chunk) => { data += chunk }) stream.on('end', () => { console.log(`Finished: ${data.length}`) })
Writable File Streams
Just like we can have readable file streams (above), we can also use file streams to write to files, chunk by chunk. If the filename does not exist, Node will create a file of that name.
let fs = require('fs') let stream = fs.createWriteStream('./status.log') stream.write('Some text here' + whateverElse)
The HTTP/S Module
If you're working with HTTPS, then you'll need to use The HTTPS Module. Both HTTP and HTTPS modules have a request method that takes options, and fire a callback function once the request has started. The res response object implements the stream interface.
let https = require('https') let option = { hostname: 'en.wikipedia.org', port: 443, path: '/wiki/Piracy', method: 'GET' } let req = https.request(options, (res) => { res.setEncoding = 'UTF-8' console.log(res.headers) console.log(res.statusCode) res.on('data', (chunk) => { console.log(chunk, chunk.length) }) }) req.on('error', (err) => { console.log(err) }) req.end()
Creating a Web Server
We use the http.createServer method of the http module to create a webserver. Every reqeust sent to this server will cause the method's callback function that we define to be invoked.
let http = require('http') let server = http.createServer((req, res) => { res.writeHead(200, {'Content-Type': 'text/plain'}) res.end('Output text') }) server.listen(3000) console.log('Listening on port 3000')
The req object that we receive as an argument to this method will contain information about the requested headers, any data that is going along with the request, as well as information about our user, like their environment and so on.
The other argument that we'll be adding here is going to be our response res object. So, we will have a blank response object also sent to this request function, and it's going to be our job to complete the response. We will do so by writing the response headers. So I'm going to use the res.writeHead method to complete our response headers. The first argument that we add to this method is going to be our response status code. 200 means that we have a successful response.
The second argument represents a JavaScript literal of all the headers that I am going to add to this response.
res.end can be used to end our response, and we will send "Output Text". Finally we need to tell this server instance what IP and port it should be listening for incoming requests on.
server.listen is a function that we can use to specific the IP address and incoming port for all of our web requests for this server. I'm going to add (3000), telling this server to listen to any requests on this local machine for port 3000.
Making an API
To make an API, you filter URL's and HTTP methods with if (req.url === '/') and if (req.method = 'GET'). Then you can use regular JS to create a response and return it back.
0 notes
cloudandcode · 8 years
Text
Dealing with Stress
We programmers are very brittle creatures. Our clients and project stakeholders expect us to perform like geniuses every single day, and to deliver impossible tasks in alarmingly short periods of time, at low cost to boot.
Our view of ourselves, and indeed the community's view of us, is TIGHTLY COUPLED to the results of these projects and the perceived quality of output.
But such a reality can NEVER be upheld, since the projects inevitably become increasingly complex while the expectations rise and the time frames become shorter.
To add pressure to this system, we are expected to earn quite a lot on a regular basis, and supply this money to demanding significant others (e.g. wives, girlfriends, boyfriend, husbands) and in the extreme case, children and dogs.
Our stress increases by exponential proportions every time a new stone of responsibility is added to this backpack of burden that we carry, and eventually we snap and break down. No system, whether biological or digital, can uphold infinitely increasing strain.
But there is a solution - a savior from this insanity, and like all impressive sounding things, it's difficult to accomplish.
You must create an island of peace in the storm - a mental place where stress cannot touch you, and then defend that island from people who would want to take it away from you (e.g. aforementioned significant others).
This island sits in the eye of the storm, where there is tranquility, and from it you can safely watch the storm rage and destroy all in its path. Everything can burn, all the projects can fail, the business can stop making money, and THAT IS OK! You are OK.
By staying on this island, you are LOOSELY COUPLED from the community's perception of you, from the outcome of your projects, maybe even from the success or failure of your marriage or relationship.
Everything can burn, but you are at peace. Because the truth is, none of us have true control over this world, so pressuring ourselves to somehow exert control is a pointless endeavor.
This is the true meaning of "laughing in the face of death", which the artistic genius Oda portrays in his "Execution of Luffy" scene (Youtube link below).
youtube
I am not saying "Don't try". Trying is always important. What I'm saying is that the result is not a reflection of you.
youtube
So yes, sometimes we must be lobsters and find a rock to hide under and grow a new shell, coming back as larger and stronger lobster-people. These are growth points and are critical to our progression through life. But sometimes, we need to laugh in the face of death, which is how we deal with extended periods of stress, on a regular basis, in between visits to the sheltering rock.
0 notes
cloudandcode · 8 years
Text
NPM and Webpack setup for React App
package.json
{ "name": "react-redux-example-app", "version": "0.0.1", "description": "Example app showing simple usage of React and Redux", "main": "index.js", "scripts": { "start": "./node_modules/.bin/webpack-dev-server" }, "repository": { "type": "git", "url": "git+https://github.com/bengrunfeld/react-redux-example-app.git" }, "keywords": [ "react", "redux", "webpack" ], "author": "Ben Grunfeld", "license": "MIT", "bugs": { "url": "https://github.com/bengrunfeld/react-redux-example-app/issues" }, "homepage": "https://github.com/bengrunfeld/react-redux-example-app#readme", "devDependencies": { "babel-cli": "^6.22.2", "babel-core": "^6.22.1", "babel-loader": "^6.2.10", "babel-preset-es2015": "^6.22.0", "babel-preset-latest": "^6.22.0", "babel-preset-react": "^6.22.0", "babel-preset-stage-0": "^6.22.0", "copy-webpack-plugin": "^4.0.1", "css-loader": "^0.26.1", "node-sass": "^4.5.0", "sass-loader": "^5.0.1", "style-loader": "^0.13.1", "webpack": "^2.2.1", "webpack-dev-server": "^2.3.0" }, "dependencies": { "react": "^15.4.2", "react-dom": "^15.4.2", "react-icons": "^2.2.3", "react-router": "^3.0.2" } }
webpack.config.js
var CopyWebpackPlugin = require('copy-webpack-plugin'); var path = require('path'); var webpack = require('webpack'); module.exports = { entry: './src/js/index.js', output: { path: path.join(__dirname, 'dist'), filename: '[name].bundle.js', }, devServer: { inline: true, contentBase: path.join(__dirname, 'dist'), port: 3000 }, plugins: [ new CopyWebpackPlugin([ { from: 'src/index.html' } ]) ], module: { loaders: [ { test: /\.scss$/, exclude: /(node_modules)/, loader: 'style-loader!css-loader!sass-loader' }, { test: /\.js$/, exclude: /(node_modules)/, loader: 'babel-loader', query: { presets: ['es2015', 'react'] } } ] } }
0 notes
cloudandcode · 8 years
Text
React-ES6 Notes
React with ES6
JSX Elements
In a JSX element, you can give a value to a property by using a string or an object. E.g.
<h1 id="main-title" style="{{color:">Text</h1>
Using Babel
You can use the in-browser transpiler, or you can use it from the CLI or from a module loader like Webpack.
Babel CLI
.babelrc
{ presets: ['latest', 'react', 'stage-0'] }
CLI Command
babel ./src/index/js --out-file ./dist/bundle.js
Using Webpack
Webpack config describes everything we want to do to our files so that they're ready for production.
Stateless Functional Components
We can create Components using functions. Stateless functional components are functions that take in property information and return JSX elements. Stateless components cannot access this so properties are passed directly into the function. Also, local methods need to be removed, and put into their own functions.
It's typically a good idea to use stateless components, whenever possible. Stateless components offer a functional way to work with components, and, also, the React team has hinted that there may be some performance benefits of using these functions, rather than using createClass, or ES6 classes.
When and why to use Stateless Functional Components:
https://hackernoon.com/react-stateless-functional-components-nine-wins-you-might-have-overlooked-997b0d933dbc#.sywh6s2za
Default Props
An optional but very useful feature is default properties. When we set up defaults, we can use the default values if another value is not provided.
Default Props with React.CreateClass
const SomeModule = React.CreateClass({ getDefaultProps() { return { name: 'Ben', age: 36 } } })
Default Props with ES6 Classes
class SomeModule extends React.Component{ render() { return ( <div>{name}, {age}</div> ) } } SomeModule.defaultProps = {name: 'Ben', age: 36}
Default Props with Stateless Functional Components
const SomeModule = ({name="Ben", age=36}) => ( render() { return ( <div>{name}, {age}</div> ) } }
Proptypes
PropTypes allow us to supply a property type for all of our different properties, so that it will validate to make sure that we're supplying the right type.
This is kind of like strong typing in Java (e.g. int, char, string, obj, etc).
const SomeModule = React.CreateClass({ propTypes: { name: React.PropTypes.string } })
Proptype IsRequired
const SomeModule = React.CreateClass({ propTypes: { name: React.PropTypes.string.isRequired } })
Proptype warnings, not errors
If you use an incorrect type, or the value is required but you don't have it, React will issue a warning, but won't crash your app.
Checking for Dates or Custom Types
todaysDate: React.PropTypes.instanceOf(Date),
State with ES6 Classes
When workin with ES6 Classes, we no longer use getInitialState, but rather the following:
export class App extends Component { constructor(props) { super(props) this.state = { name: ben, age: 36 } } }
React Router
Install with: npm install react-router --save
Usage
import { Router, Route, hashHistory } from 'react-router' import { DaysList } from './days_list' import { SomeModule } from './module1' render( <router history="{hashHistory}"><route path="/" component="{DaysList}"></route><route path="*" component="{SomeModule}"></route></router>, document.getElementById('main') )
path='/' is for home directory, while path='*' is a wildcard.
Get Current URL Pathname
If you are in a component that gets called by the above code - you can check what the current URL path name is in the Browser address bar:
this.props.location.pathname
You can test with an if statement:
if (this.props.location.pathname === '/') { <rendercomponent1></rendercomponent1> } else { <rendercomponent2></rendercomponent2> }
The Link Component from React Router
Usage:
import { Link } from 'react-router' export const Menu = () => <nav classname="menu col-xs-5"><link to="/" activeclassname="selected">Home <link to="other" activeclassname="selected">Other </nav>
Forms
htmlFor
In React, for is a reserved work, so we can use htmlFor inside of a label.
<label htmlfor="date">Date</label>
defaultValue
We can specify a default value for react for fields with defaultValue
<input id="date" type="date" defaultvalue="{this.props.date}"> SomeModule.defaultProps = {date: '6/7/2016'}
refs
We use refs to grab the data directly from the form. This indicates that we are using an uncontrolled component. It's usually best to use controlled components.
class myForm extends Component { logMe = () => console.log('Date:', this.refs.date.value) render() { return (<input id="date" type="date" ref="date">) } }
refs in a stateless functional component
In a stateless functional component, we don't have access to this, so we need to use callbacks to be able to grab the form values.
const DaysRow = ({today}) => { let _firstName const showInput = () => { console.log('hello', _firstName.value) } return ( <input type="text" name="firstName" ref="{input"> _firstName = input}/> ) }
Controlled vs Uncontrolled Components
In a controlled component, form data is handled by a React component. The alternative is uncontrolled components, where form data is handled by the DOM itself.
Making this accessible
If you are using ES6 classes and you want to use a function by calling this.sayHi(), then you'll need to make this accessible in the constructor.
constructor(props) { super(props) this.sayHi = this.sayHi.bind(this) }
Calling a parent function in a stateless functional component
In the parent
logData = (data) => console.log('From child', data) <somemodule logdatafromparent="{logData}" in the child export const daysrow="({logDataFromParent})"> { const sendToParent = (data) => { logDataFromParent(data) } sendToParent('Hello from child') }
0 notes
cloudandcode · 9 years
Text
Common App Engine Bugs and Problems
Here are some common bugs I ran into using Google App Engine.
Another transaction by user is already in progress for app
Error 409: --- begin server output --- Another transaction by user <USER> is already in progress for app: <App ID>, version: 1. That user can undo the transaction with "appcfg rollback". --- end server output ---
Problem: While making a deploy, your or another User quit unexpectedly. Instead of dealing with this like a responsible adult, App Engine shits itself and refuses to play nice until you make a rollback command.
Solution: (assuming you're using Python) In you project directory, issue the following command:
appcfg.py rollback .
Also, sometimes there can be in issue with the cookies that App Engine stores in your home directory. One way of dealing with this is by deleting them.
rm ~/.appcfg_cookies rm .appcfg_oauth2_tokens
Or you can take the simpler, less scorch-earthy approach, and just use the inbuilt --no_cookies flag, like so:
appcfg.py update . --no_cookies
This application does not exist
Error 404: --- begin server output --- This application does not exist (app_id=u'<APP_ID>'). --- end server output ---
Problem: The value you have in app.yaml for application is different to the identifier of your app. They must be the same.
Solution: Change the value for application to be identical to your application identifier, which you can find in your App Engine console.
Go to https://appengine.google.com/
Click on the link to your app
In the sidebar, under Administration, click on Application Settings
Copy the value for Application Identifier to your clipboard
Go to your project's app.yaml file
Replace the value for application in app.yaml with the value you copied to your clipboard
Raise a glass of decent whiskey and toast to my good health
WARNING util.py:126 new_request() takes at most 1 positional argument (6 given)
Basically, this seems to be a bullshit bug on AppEngine's side that they haven't figured out how to solve since 2013.
I've confirmed the message is harmless so you can safely ignore it. We are working on a fix and should get one in to 1.8.4. answered Aug 12 '13 at 22:53 - coto
http://stackoverflow.com/questions/18126157/appengine-warning-during-python-app-update
As I come across more other common App Engine bugs, I'll update this post.
If you found this article helpful, please leave a Thank you comment below.
0 notes
cloudandcode · 10 years
Text
Today’s VIM Lesson
Today I had an awesome lesson with one of the DevOps guys at my work about VIM.
Here's my cheatsheet from the session:
VIM CHEATSHEET
. - redoes your last command (use with indenting blocks of code)
a - insert after cursor
Shift a - Insert at end of line
Shift i - Insert at beginning of line
Shift d - Cuts from where your cursor is to the end of line
Shift y - Same as shift D but copies
yy - copies an entire line (paste with p)
dd - does the same thing as yy, but cuts
:cq - exits with an error status (will cancel a commit)
:vsp - vertical split * move to the other split - Ctrl w, then l/h
:sp - horizontal split * move to the other split - Ctrl w, j/k
FIND AND REPLACE
:1,15s/this/that/g
on line 1 - 15, swap this with that, recurring.
Without g, it only does it once per line
:%s/this/that/g
same as above, but many times per line
make selection. type :. then rest of find/replace command
e.g. :'<,'>s/foo/bar/g
SELECT ANYTHING IN BRACKETS (not < or >)
place cursor inside quotes * vi" (inside "") * what it does: visual, inside, quotes
di" (inside "") * same as above but delete
ci" (inside "") * same as above but cut, then go into insert mode
0 notes
cloudandcode · 10 years
Text
Google App Engine Development Server Error: There are too many files in your application for
UserWarning: There are too many files in your application for changes in all of them to be monitored. You may have to restart the development server to see some changes to your files.
Link to Bug: https://code.google.com/p/googleappengine/issues/detail?id=9300
Solution
Step 1: Get the file watcher to ignore directories you don't want it to watch
In terminal (or just use the text editor of your preference. I use Vim)
vi /Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/tools/devappserver2/mtime_file_watcher.py
Go to line 106 and add in the following line of code after the for statement
if '/node_modules/' in dirname or '/lib/' in dirname: continue
If there are other directories that you want to ignore, just follow the above format and add them in.
So your code should look like this:
for dirname, dirnames, filenames in os.walk(self._directory, followlinks=True): if '/node_modules/' in dirname or '/lib/' in dirname: continue if self._quit_event.is_set(): raise ShutdownError()
Make sure you don't make a mistake with the spacing by doing a copy paste. Python hates that.
Step 2: Exclude directories from uploading
This will stop the directories you specify from uploading when deploying
vi app.yaml skip_files: - ^(node_modules/.*)
Many thanks to Johann du Toit for this solution.
Credit: johanndutoit.net/app-engine-too-many-files/
0 notes
cloudandcode · 10 years
Text
Helping Very Poor People Make More Money With Cardboard Signs
I just came up with a way that homeless and very poor people can make more money with donations as they stand on street corners with cardboard signs.
Currently, the signs don't engage people, but rather attempt to garner sympathy, so you'll have a sign that says something like "Lost everything, please help". While this tugs at the heartstrings, it does not provide something that many potential donors believe is worth exchanging for money.
Solution: Create a sign generator that makes cardboard signs that contain riddles, quizzes, puzzles, trivia and math problems, requesting a donation if the donor can't solve it by the time they reach the lights.
E.g.1 "Who is the president of Estonia. If you don't know, you should pay me $2"
E.g.2 "What is 4 x 237. You should donate $3 to me if you can't solve it"
This fully engages the driver, provides a form of entertainment which is worth an exchange of money, and elevates the stature of the person requesting donations.
It also improves the requestor's chance of receiving a donation.
0 notes
cloudandcode · 10 years
Text
New Years Resolutions 2015
Here are my New Year's Resolutions for 2015:
Lose weight. Ideal is 185 pounds. Work out regularly. Record progress.
Play 15 minutes of Ukelele a day
Learn how to draw and begin publishing satirical and political cartoons
Improve math skills. Go over math notes. Take a statistics course
Improve programming skills and learn how to be a SysAdmin. Read lots of books (e.g. The Pragmatic Programmer, Software Craftsmanship, etc)
Make a new cheese every week
Video chat with family members once a month
Run an 'intro to programming' course
0 notes
cloudandcode · 10 years
Text
My Laughable Words of Wisdom
This is a letter I wrote to my siblings regarding the progression of technology (specifically Machine Learning), and what they can do about it.
Hi All,
You know that one friend that you have who has a mid-life epiphany, and then sends you an annoying email telling you how you should live your life and raise your kids?
Well, this isn't one of those, but if I ever had a moment like that, it would probably be now. That said, I beg your attention!
So I wanted to talk to you about a topic I'm researching, which is the direction my career will be going in during 2016. It's called Machine Learning.
Basically what it means is that you teach a computer program to learn.
Funnily enough, you all use a Machine Learning program almost every day. Every time you go onto LinkedIn, check out a product on Amazon, look up something on Ebay or, of course, search for something on Google, you are using a Machine Learning program.
Those ones specifically learn what you're searching for and then try to suggest something you might like.
As to how "good" (accurate/successful) these Machine Learning programs are right now, the latest ones can predict a cancer patients chance of survival as well as an experienced Pathologist. Basically, they're already very advanced and quite soon they'll be used in every type of industry.
Generally speaking, Machine Learning programs are quick to write (a few months to a year and at most 2), and can be applied to almost ANYTHING. Psychology, engineering, face recognition, creative writing, etc etc etc.
Okay, so who gives a rats nut-sack?
Well, the major way that this affects us is that as Machine Learning programs get introduced to more industries, many of the traditional jobs that were previously done by humans get replaced by the Machine Learning program.
A great example of this is accounting. Imagine a program that has learned how to be a great accountant, and instead of a bookkeeper doing your books, the Machine Learning program activates and your numbers are ready for submission to the tax department in a matter of seconds. Soooo..... you don't really need an accountant anymore. Well, at least not for bookkeeping.
So what happens to the bookkeeper/accountant? Well, their employment prospects aren't looking so good anymore. Like, really not good.
Well, that was interesting! But again, there's not much I can really do about that, so why should I care?
Actually, there is something you can all do about this.
All of you love your children, and you all want them to have great jobs when they grow older and to be able to sustain themselves. Machine Learning programs reduce their ability to get successfully employed and receive a decent to high wage. But there's a way around this!
If all your kids study a few hours of computer science a week, their chances of being able to navigate this scary scenario go up unimaginably. Even better, most of them are at the perfect age to start learning!
The ideal age to start learning computer science is 12-14 years old. By the time they're ready to hit the workforce, they'll have a full suite of computer skills to deal with the future reality.
Of course they can still go on to be the doctors, lawyers & psychologists that all Jewish parents dream of their children becoming, but their knowledge of programming will allow them to get past the giant barrier the Machine Learning will undoubtedly pose.
Computer Science is a massive subject, and it's easy to feel lost when looking at it, especially when considering where to start the journey. Luckily, I can provide a little guidance in this area.
Unix is the operating system that most Computer Science is based on. It's different to Windows, and all programmers work with it. E.g. all of "the Cloud" that you've heard so much about is built on Unix.
Unix goes by many names: Linux, Red Hat, Ubuntu, etc etc, but they're all really the same thing. It's free to download, easy to install and start playing with, and provides the perfect starting place for your children to begin learning Computer Science.
Here is the link to the Unix course that I learned from: http://www.lynda.com/Mac-OS-X-10-6-tutorials/Unix-for-Mac-OS-X-Users/78546-2.html
I promise you that if your children start learning Unix now, they will thank you for it in 10 years when things in the workforce become even harder than they are today.
When you consider the power of Machine Learning, the future can be quite a scary thing, but with a little planning and regular effort, many of its challenges can be beaten before they become serious issues.
Below is a video that demonstrates Machine Learning. Go to the link and click the play button.
Much love from the USA,
Ben
Example of Machine Learning - it's a video, so you have to press the PLAY button http://www.ted.com/talks/jeremy_howard_the_wonderful_and_terrifying_implications_of_computers_that_can_learn
0 notes
cloudandcode · 10 years
Text
Front End Developer Interview Questions
Many of the questions listed below have been taken from Darcy Clarke's excellent list of Front End Developer Interview Questions. That said, there are also several questions I've run into myself in interviews.
General Web Questions
What UI, Security, Performance, SEO, Maintainability or Technology considerations do you make while building a web application or site
UI:
Constraint vs Freedom: How much do you let the user do (guided wizard vs adobe photoshop-like app)
Direct on-canvas vs form-based editing
Navigation and progress tracking (e.g. step 1 of 5 done)
touch/swipe vs clicks
links: 1, 2
Security:
User authentication
Server authentication (uses SSL & checks if the internet name in the certificate is the matches the internet name of the server)
Is RBAC (Role Based Access Controls) needed
Secure transmission (SSL/TLS)
Firewalls
Validate user input
What access does the user have to your data
links: 1, 2
Performance
Number/size of external resources
Optimize images
Optimize code
Placement of script blocks
Minimize cookie size, eliminate dead cookies
Low-bandwidth options
links 1, 2, 3, 4
SEO
Content on your page relevant to your targeted keywords
Title, meta-description, meta-keywords, h1 - content rich
Pretty url's
Use of 301 redirects
Get rid of 404's, 500's,
links: 1, 2, 3, 4
Maintainability
Very tight, issue specific commits
Helpful commenting
Informative use of Github tools - issues, PR's, milestones
links: 1, 2
Technology
What browsers, devices, screen resolutions should you be targeting
Responsiveness, etc
What is the difference between SSL and TLS, HTTP and HTTPS
TLS is the new name for SSL. Namely, SSL protocol got to version 3.0; TLS 1.0 is "SSL 3.1".
The name was changed to TLS to avoid any legal issue with Netscape, so that the protocol could be "open and free"
HTTPS is HTTP-within-SSL/TLS.
If you have 5 different stylesheets, how would you best integrate them into the site?
Use LESS/SASS and @import other modularzied stylesheets
Concatenate them into a smaller number of files
Remove duplicates/unused selectors
Compress/minify the CSS
link: 1, 2, 3, 4
Can you describe the difference between progressive enhancement and graceful degradation
Degrading Gracefully means looking back whereas Enhancing Progressively means looking forward.
Graceful Degradation is the practice of building your web functionality so that it provides a certain level of user experience in more modern browsers, but it will also degrade gracefully to a lower level of user in experience in older browsers. USE CASE: Sites targeted at older versions of IE, used by big companies that are locked in to older tech.
Progressive Enhancement is similar, but it does things the other way round. You start by establishing a basic level of user experience that all browsers will be able to provide when rendering your web site, but you also build in more advanced functionality that will automatically be available to browsers that can use it. USE CASE: Sites targeted to developers, who are constantly updating their browsers and trying the latest tech.
In either case, you test for a feature that doesn't have complete support across all browsers/versions, and then apply it or an alternative.
Graceful Degradation starts from the status quo of complexity and tries to fix for the lesser experience whereas Progressive Enhancement starts from a very basic, working example and allows for constant extension for future environments.
How would you optimize a websites assets/resources
Reduce the number of requests
Reduce the overall size of the content
Promote parallelization (i.e. simultaneous download of assets - if IE, use domain sharding.)
Lazy load images - use blank png as base image, then use JS to swap image when other image is fully loaded
Prefetch resources
Use a framework that employs a virtual-dom (React/Flux, Tw. Flight, Elm, Mecury)
You want to concatenate and minify your JS/CSS, so there is only one file to fetch from the server.
You also want to re-consider heavily using a client-side MV* (e.g. Backbone), because you can end up downloading lots of data, thus slowing down the site.
Code techniques:
Compress/minify code
Concatenate files into a smaller group of files
Remove duplicates and unused selectors/code
Prefetch resources using rel="prefetch" OR have a hidden div containing the resource (img), as browser will only download a resource if it hits it in the HTML.
Consider downloading files in parallel (for IE only) link
Use CSS sprites
Infrastructure Techniques
Consider using a CDN
Leverage browser caching (use .htaccess)
Leverage proxy caching
Tech Specific
HTML
HTML5 Lint
Separate style and functionality from structure
CSS
Use LESS and @import other modularzied stylesheets
Javascript
Adhere to JS Optimization rules
Parse/compress with UglifyJS
Images
Use compression
Use CSS sprites
Traditionally, why has it been better to serve site assets from multiple domains
"Domain Sharding" is the practice of creating multiple sub-domains so that the number of resources downloaded in parallel is increased.
Browsers limit the number of downloads that occur in parallel by the number of host names that are involved. So spreading assets equally across multiple sub-domains uses only a single hostname and enables a larger number of assets to be d/l'd in parallel.
Because of the adoption of SPDY, domain sharding may hurt performance rather than help it.
Exceptions
Flash loading external data (XML, etc)
JavaScript manipulating or communicating with a page inside an iframe
JavaScript fetching a file via XMLHttpRequest
Other technologies such as Java applets or Silverlight fetching external data
Downsides with Mobile
Network connections that breach the recommended limit come with a setup overhead - there's a DNS Lookup, a TCP 3-way handshake and a TCP slow start. This causes a higher latency with mobile users than desktop users. The setup overhead also uses more CPU, memory, and battery power - all important considerations with Mobile.
Modern mobile browsers implement HTTP pipelining and don't observe HTTP 1.1 connection rules.
SDPY as an exception
SPDY supports concurrent requests (send all the request headers early) as well as request prioritization. Sharding across multiple domains diminishes these benefits. SPDY is supported by Chrome, Firefox, Opera, and IE 11. If your traffic is dominated by those browsers, you might want to skip domain sharding. On the other hand, IE 6&7 are still somewhat popular and only support 2 connections per hostname, so domain sharding is an even bigger win in those browsers.
links: 1, 2, 3, 4
What tools do you use to test your code's performance
I've used Jasmine
Test Framework: Responsible for defining syntax for test spec structuring BDD/TDD
Mocha, Jasmine
Test Runner: Responsible for running and displaying results of unit test framework in either CLI or Browser.
Karma, Mocha CLI, Jasmine CLI/Browser
Assertion Library: Responsible for validating input/output in boolean fashion. Typically used to make tests more human readable.
Chai
Test Doubles
SinonJS
Acceptance Tests
CucumberJS
NightwatchJS
What are the differences between Long-Polling, Websockets and SSE
Regular AJAX Polling: Javascript requests a file from the server at regular intervals (e.g. 1 second apart).
AJAX Long Polling: Javascript requests a file from the server, but the server does not respond until there is new information. As soon as the server responds, the client immediately sends another request to the server, restarting the request.
HTML5 Server Sent Events (SSE)/EventSource: Javascript opens a connection to the server. The server sends an event to the client when there is new information available. There is real-time traffic from the server to the client, but it's not possible to connect to the server with a server from another domain.
HTML5 Websockets: Javascript opens a connection to the server. The server and client can send each other messages when new data (on either side) is available. With WebSockets it is possible to connect with a server from another domain. It's also possible to use a third party hosted websocket server.
Comet: Comet is a collection of techniques prior to HTML5 which use streaming and long-polling to achieve real time applications.
Explain the importance of standards and standards bodies
The goal of creating web standards, such as the HTML standard, was to eliminate the differences in feature support across browsers and formalize de facto standards, enabling developers to create sites that work similarily across all browsers. Standards bodies such as the World Wide Web Consortium (W3C) were created as forums to establish agreement across the industry and among vendors.
What is FOUC? How do you avoid FOUC
A Flash Of Unstyled Content (FOUC) is an instance where a web page appears briefly with the browser's default styles prior to loading an external CSS stylesheet, due to the web browser engine rendering the page before all information is retrieved. The page corrects itself as soon as the style rules are loaded and applied.
To avoid FOUC, place all scripts at the bottom of the page. Possibly hide all content on the page until the styles have loaded.
A graceful way to do this is to use a loading spinner (e.g. Audi)
Do your best to describe the process from the time you type in a website's URL to it finishing loading on your screen
Assuming the simplest possible HTTP request, no proxies and IPv4:
Browser checks cache; if requested object is in cache and is fresh, skip to #9
Browser asks OS for server's IP address
OS makes a DNS lookup and replies the IP address to the browser
Browser opens a TCP connection to server (this step is much more complex with HTTPS)
Browser sends the HTTP request through TCP connection
Browser receives HTTP response and may close the TCP connection, or reuse it for another request
Browser checks if the response is a redirect (3xx result status codes), authorization request (401), error (4xx and 5xx), etc.; these are handled differently from normal responses (2xx)
If cacheable, response is stored in cache
Browser decodes response (e.g. if it's gzipped)
Browser determines what to do with response (e.g. is it a HTML page, is it an image, is it a sound clip?)
Browser renders response, or offers a download dialog for unrecognized types
Cross Browser Questions
How do you ensure a front-end looks the same across multiple browsers
Set benchmarks of how you want your site to respond
e.g. load time under 5 seconds, hover states < 100ms, etc
Use PageTest to check
Set the expectation that not all broswers will have the exact same experience. Some browsers will perform better than others.
In some browsers <IE8, you may need to turn off some features
Develop according to best practices
Use plugins and libraries that are performance optimized
Keep DOM manipulation to a minimum when possible
Write styles that avoid visual changes that affect the page as it loads
Use feature detection with Modernizr
Perform regular testing and QA for performance as well as visual issues
Cross-Browser Automated Testing Tools
Functionality: Selenium
Appearance: Browsera
HTML5
What is the DOCTYPE and what does it do
The DOCTYPE tag is an instruction to the web browser about what version of HTML the page is written in. It can trigger Quirks mode, or Strict mode.
What is Quirks Mode
Quirks Mode forces the browser to adhere to older rules of CSS. Normally, Strict mode is used.
Explain what "Semantic HTML" means
Semantic HTML clearly describes the intention of the programmer (its meaning) to other developers and machines (e.g. the browser, Google) reading the code. E.g. Different content contained in the same <section> tag was intended to be thematically related.
What is the difference between session storage, local storage and cookies
Local Storage, Session Storage and Cookies are all client storage solutions.
Session data is held on the server where it remains under your direct control. Session Storage (as the name persists) is only available for the duration of the browser session (and is deleted when the window is closed) - it does however survive page reloads.
Cookies are slow, insecure (sent over the server), and limited to about 4KB of data.
Local Storage, or Web Storage stores key name pairs locally within the browser, and is faster, more secure (not sent over the server) and has a limit of 5MB of data.
There is also WebSQL and IndexedDB - local browser databases. WebSQL is no longer supported, and IndexedDB is supported in most browsers, but still a contentious issue.
What is the difference between XHTML and HTML5
XHTML does not have good browser support
HTML5 uses more semantic code
IE and other user agents cannot parse XHTML as XML
HTML5 has offline storage
Explain an HTML5 tag you've used
<time>.
What are HTML5 Web Workers
When executing scripts in an HTML page, the page becomes unresponsive until the script is finished.
A web worker is a JavaScript that runs in the background, independently of other scripts, without affecting the performance of the page. You can continue to do whatever you want: clicking, selecting things, etc., while the web worker runs in the background.
Explain HTML5 Geolocation
The HTML Geolocation API is used to get the geographical position of a user.
Since this can compromise user privacy, the position is not available unless the user approves it.
CSS
What is the difference between 'hidden' and 'display: none'
display: none; - tag will not appear on page at all. No space will be allocated between other tags.
visibility: hidden; - tag is not visible, but space is allocated for it on the page.
What is a CSS pre-processor and how does it work
A CSS preprocessor allows you to use more complex logic like variables, extends, mixins and even loops. The pre-processor then compiles the code into valid css, and may also remove duplicates / dead code, and minify it.
What are the dangers of using a CSS pre-processor
Mixins and extends can hurt maintainability of code, since you have to search for the original styles.
Handing the project to a developer that uses raw CSS - they may not know LESS/SASS
What are floats, and what are the considerations in using them
Make content appear side by side, LTR or RTL.
Parents of floated elements may collapse
Need to apply special css with :after. i.e. clear:both
Problematic with coding email templates
What does the box-sizing CSS property do
The box-sizing property is used to tell the browser what the sizing properties (width and height) should include. e.g. Should they include the border-box or just the content-box?
JAVASCRIPT
What is the difference betwen Event Bubbling and Event Capturing
Bubbling - When the event of a child element is triggered even though only the parent is clicked/activated. Hence the event bubbles up to the surface.
Capturing - older, not used.
Only the bubbling model is supported by all major browsers.
diff between properties and attributes
Attributes are defined by HTML. Properties are defined by DOM.
diff between == and ===
== compares equality but === compares type as well as equality.
"abc" == new String('abc'); // true "abc" === new String('abc'); //false
Explain the DOM
DOM stands for Document Object Model. It is the document that defines the structure, styling, and functionality of your web page.
Explain the css box model
The CSS box model is essentially a box that wraps around HTML elements, and it consists of: margins, borders, padding, and the actual content.
Explain ajax
AJAX stands for Asynchronous Javascript And XML, and it allows you to update parts of a web page without reloading the whole page.
What types of data does ajax transfer
A XMLHttpRequest can transfer anything, but because there is no byte array in Javascript, you can only use strings, numbers, etc. So everything you get/receive is text - which can then be parsed as JSON, XML, etc.
what is chaining in jQuery
Chaining allows us to run multiple jQuery methods (on the same element) within a single statement.
Explain the Event Loop/Event Process in JS
The browser has inner loop, called the Event Loop, which checks the queue and processes events, executes functions etc.
E.g. If the browser is busy processing your onclick, and another event happened in the background (like script onload), it appends to the queue. When the onclick handler is complete, the queue is checked and the script is executed.
Explain JS Closures
A closure is a function having access to the parent scope, even after the parent function has closed.
Clojures make it possible for Javascript function to have private variables.
Explain Javascript Prototypes
Every JavaScript object has a prototype. The prototype is also an object. All JavaScript objects inherit their properties and methods from their prototype.
The Object.prototype is on the top of the prototype chain. All JavaScript objects (Date, Array, RegExp, Function, ....) inherit from the Object.prototype.
Why is it important to use the var keyword in JS
If you don't use the var keyword, a variable assumes a global scope if it is used inside of a function, which we don't want.
What aggregation tools have you used before
?
What are the concerns with using Global variables and when should you use them
The main issue with globals is that they can cause variable naming conflicts. Therefore, it is best to avoid globals when they are not actually needed.
More issues with globals: 1
Explain Require.JS and AMD
RequireJS is a JavaScript file and module loader. RequireJS uses the require function to load any other scripts you define.
Coding Tests
These are tests I've been given in interviews. You should really know how to do all of these backwards.
Write a Palindrome checker - link
Write a Bubble Sort program - link
Write a FizzBuzz program - link
Code a center-aligned floating Navigation Bar
Select a DOM element using raw Javascript (no jQuery allowed) and then attach an event to it
4 notes · View notes
cloudandcode · 10 years
Text
7 Steps to Take Before You Start Squashing Web App Bugs
Before you go to someone to ask for help with a Web App bug, do the following, and avoid making yourself look like a horse's ass:
Check if you are properly logged in, or connected to the necessary VPN
Make sure you're not viewing a cached version of the page
Open dev tools and check errors in Console/Network tabs
Make sure you have the most recent version of master
Ensure all dependencies are up to date
Recompile the code (just to be sure)
Check error and server logs
This post was sponsored by the School of Hard Knocks (SHK)
2 notes · View notes
cloudandcode · 10 years
Text
Design rules in a Backbone-Marionette App
Separation of Concerns in Backbone-Marionette
MODELS
Should:
Return information about the data
Bundle different aspects of the data together for easier consumption by the controller
Provide filters for the data
Should Not:
Create/Instantiate Collections - collections should instantiate Models
Create/Instantiate Views - controller should do this
VIEWS
Should:
Manipulate the DOM
Handle user interactions
Should Not:
Create/Instantiate views - controller should do this
CONTROLLERS
Should:
Create views
Set regions
Refresh regions
Filter results
Load/halt extra services - e.g. loading spinner, modal, etc
Should Not:
Directly Manipulate DOM - views should do this
Marionette Usage
Models
Callbacks - manage callbacks in a safe Async manner
Object - if you're going to create a Class and want it to have initialize and events, use Object
Views
Behavior - handle user interactions via a View in a decoupled way. Can apply to Model or Collection events as well. A set of behaviors can be grouped together.
Behaviors - attaches your Behavior instances to a given View, especially if they are in their own file in a different folder.
Callbacks - manage callbacks in a safe Async manner
View.bindUIElements - Instead of having jQuery selectors hanging around in the view’s code you can define a ui hash that contains a mapping between the ui element’s name and its jQuery selector. Afterwards you can simply access it via this.ui.elementName
CollectionView - will loop through all of the models in the specified collection, render each of them using a specified childView
CompositeView - used to wrap a CollectionView and an ItemView in a template that you decide. See the difference below.
ItemView - An ItemView is a view that represents a single item
Object - if you're going to create a Class and want it to have initialize and events, use Object
Controllers
Controller - While this Marionette object has no relation to the MVC design pattern, it is probably the best to use for the MVC Controller.
Callbacks - manage callbacks in a safe Async manner
Regions - display a View at a specified point in the DOM, allowing different Views to easily be swapped in and out from that point in the DOM.
Object - if you're going to create a Class and want it to have initialize and events, use Object
Regions - manage, show and destroy Views in your application
RegionManager - manage a number of Region objects within an application
Renderer - the render method renders a template with or without data
TemplateCache - caches templates for fast retrieval
FAQ
CollectionView vs CompositeView
Let this help you decide which is more appropriate to use:
A CollectionView is for rendering a repeating list of models, each of which has the same representation/template.
A CompositeView is for rendering a repeating list of models as well, but also to render some view/template which wraps the list.
Links to other explanations of CompositeView:
http://lostechies.com/derickbailey/2012/04/05/composite-views-tree-structures-tables-and-more/
http://stackoverflow.com/questions/22583429/backbone-marionette-composite-view
Region vs LayoutView
A Region can be used to display a LayoutView. A layout will also contain regions. This creates a nested hierarchy that can extend infinitely.
A Region displays a View at a specified point in the DOM, allowing different Views to easily be swapped in and out from that point in the DOM.
A LayoutView extends from ItemView, meaning that it is designed to render a single template. The difference between a LayoutView and an ItemView is that the LayoutView contains Regions.
When you define a LayoutView, you give it a template but you also specify Regions that the template contains. This allows you to display other Views in the Regions that the LayoutView defined.
Links to other explanations of CompositeView:
http://lostechies.com/derickbailey/2011/12/12/composite-js-apps-regions-and-region-managers/
http://stackoverflow.com/questions/10521266/whats-the-difference-between-a-marionette-layout-and-a-region
2 notes · View notes