tag:blogger.com,1999:blog-67775735828854072142024-03-04T23:23:55.689-08:00Made Simpleby Amarin PhaosawasdiAmarin Phaosawasdihttp://www.blogger.com/profile/11497556893338926041noreply@blogger.comBlogger11125tag:blogger.com,1999:blog-6777573582885407214.post-70811803662926651442013-07-18T10:13:00.000-07:002013-07-18T21:02:04.728-07:00Functional Programming and Stupid ExamplesSometimes it's hard to see why functional programming is good.<br />
<br />
People say it's elegant, but to understand why, you might have to take a whole online course, read an entire book, decrypt a research paper, or study a whole functional language.<br />
<br />
I've found some nice articles and Q&A threads here and there, but the info is scattered. Also, I'm not happy with the examples given. I wanted something "stupid" and informal.<br />
<br />
This is my good faith effort to summarize the main characteristics and benefits of functional programming. I include examples that favor easier understanding over real-world usefulness, with hope that you'll be able to apply functional programming to your own use cases.<br />
<br />
I will assume you have programming experience and are familiar with the concepts of abstraction and reuse. Also the code used in this post is pseudocode. It just kind of looks like JavaScript so please don't yell at me if you can't run the code. :)<br />
<br />
<h3>
<b>What is functional programming?</b></h3>
<br />
Functional programming means functions are everywhere. For example, functions can be passed as arguments and can be return values.<br />
<br />
A function is something that you "call" to get results. When you call a function with the same parameters, it always returns the same result.<br />
<br />
Data in functional programming is immutable, because if data can change between function calls, the function can't guarantee to return the same result.<br />
<br />
<h3>
<b>Why is functional programming good?</b></h3>
<br />
You would probably agree that reuse is good. Abstraction leads to reuse. In functional programming, there are more ways than non-functional programming to abstract stuff.<br />
<br />
Since there are a lot of ways to abstract stuff, you get to use abstraction a lot. When you use it more, you get better at it.<br />
<br />
When you use abstraction a lot, you tend to think about solving problems in a higher level. Your code looks more like solving a problem than telling the computer to do things. In other words, your code is more declarative.<br />
<br />
In short, I think functional programming makes you a better programmer, and that's why it's good.<br />
<br />
<h3>
<b>Common functional programming features</b></h3>
<br />
When functions are everywhere, these common features follow naturally.<br />
<br />
<b>Functions can be saved to variables.</b><br />
<br />
You would save a number to a variable.<br />
<br />
<script src="https://gist.github.com/amchiclet/3394623a95b8b5076c57.js"></script>
You can save a function to a variable too.<br />
<br />
<script src="https://gist.github.com/amchiclet/86ceb87cbbc73d8b5c8d.js"></script>
<b>Functions as parameters.</b><br />
<br />
You would pass an object as a function parameter.<br />
<br />
<script src="https://gist.github.com/amchiclet/4f0a90afc2c93b6fb83e.js"></script>
You can pass a function to a function as well.<br />
<br />
<script src="https://gist.github.com/amchiclet/49af80649281b78bca20.js"></script>
As you can see, non-functional programming allows you to abstract over data (what kind of meat to cook), but functional programming allows you to abstract over actions (how to cook a given type of meat).<br />
<br />
<b>Functions as return values.</b><br />
<br />
You would return an object from a function.<br />
<br />
<script src="https://gist.github.com/amchiclet/585011906d14e98dc3e9.js"></script>
You can return functions as well.<br />
<br />
<script src="https://gist.github.com/amchiclet/7e0ad9882c5a6558ae5a.js"></script>
<b>Lambdas</b><br />
<br />
Sometimes, you don't need to name all of your values. Instead of this.<br />
<br />
<script src="https://gist.github.com/amchiclet/48168d38439117fd7ff3.js"></script>
You would rather write this.<br />
<br />
<script src="https://gist.github.com/amchiclet/da349dd8a38b0029af9e.js"></script>
Same for functions. Sometimes, you don't need to name all your functions. Instead of this.<br />
<br />
<script src="https://gist.github.com/amchiclet/d92ff0ecbfaa473cb0db.js"></script>
You would rather write this.<br />
<br />
<script src="https://gist.github.com/amchiclet/d41b4ff14a5b59139efd.js"></script>
<b>Closures</b><br />
<br />
When functions can be used everywhere, we need to decide what the function bodies can see.<br />
<br />
It turns out that it's useful when a function can see variables defined outside its body.<br />
<br />
Suppose we want to make some sauce from some ingredient.<br />
<br />
<script src="https://gist.github.com/amchiclet/bcec8754df479c1b2d52.js"></script>
Every time we want to make some secret sauce, we would then have to pass the secret ingredient.<br />
<br />
<script src="https://gist.github.com/amchiclet/66acddef07084a756c4a.js"></script>
But if we can define functions that can see outside variables, we would be able to hide the secret_ingredient.<br />
<br />
<script src="https://gist.github.com/amchiclet/94f79a1c6d66c4b72f42.js"></script>
And if you need to make secret sauce many places in the code, you won't need to pass secret_ingredient along with them.<br />
<br />
Functions coupled with data are called closures. This is another way programmers can hide data. It's called encapsulation, which is another form of abstraction.<br />
<br />
<b>Currying</b><br />
<br />
Let's make dinner.<br />
<br />
Suppose we want to make<br />
1) pork over white rice.<br />
2) fish over white rice.<br />
3) pork over brown rice.<br />
4) fish over brown rice.<br />
<br />
We could write a function like this.<br />
<br />
<script src="https://gist.github.com/amchiclet/70b71634c5d2209fcfea.js"></script>
However, you can see that white rice is used twice and brown rice is used twice. We can refactor the function like this instead.<br />
<br />
<script src="https://gist.github.com/amchiclet/b5ae6ce862200c656c6c.js"></script>
The benefits will be clearer if you made 10 more dishes with white rice. The example above allowed you to not have to use pass white_rice every time you cook white rice dishes.<br />
<br />
Passing one parameter at a time on a multiple argument function, to create new functions along the way, is called currying.<br />
<br />
The function implementation above might look a little weird, but some programming languages support currying, where you don't have to explicitly return a function from a function.<br />
<br />
<script src="https://gist.github.com/amchiclet/800f3f96a2bbc93c06b9.js"></script>
Currying is also another kind of abstraction: abstracting away parameters.<br />
<br />
<b>Recursion</b><br />
<br />
Since data is immutable in functional programming, you can't really loop from i=0 to i=100, because you have no way to increment i.<br />
<br />
However, when you think about it, one of the main reasons we loop, is to process a data structure. We want to do something to each "node" in a data structure. This forces us to think at a higher-level, which is good because it maps better to the problem we're trying to solve than to how a computer works.<br />
<br />
Moreover, when data structures are more complex, recursion generally gives simpler code to reason about. You can easily loop over a list, but what about a tree or a graph?<br />
<br />
The code written with recursion usually doesn't have any "boilerplate code" such as setting up the variable i to have the correct value.<br />
<br />
Recursion is another exercise that forces you to think high-level, which makes you a better programmer.<br />
<br />
<h3>
<b>More features</b></h3>
<br />
In functional programming, you apply the idea of using functions to everything. These are some high level descriptions of other features often found in functional programming. Since I want to keep this post "stupid", I'll not dive into the details of these features.<br />
<br />
<b>Calling functions on types</b><br />
<br />
When you can call functions on types to create new types, you have algebraic data types and generics.<br />
<br />
<b>Determining which function is called</b><br />
<br />
You can create objects with different constructors. At some point, you need to determine which constructor was called to create a given object and extract data from that object. Pattern matching is a nice way to do that. And actually pattern matching has more general uses than this too.<br />
<br />
<b>Lazy evaluation</b><br />
<br />
Since functional programming guarantee that functions called with the same parameters always give the same results, we have freedom in the order of evaluation. In a nutshell, we can be "lazy" and evaluation expressions only if they are used. This has many benefits.<br />
<br />
<h3>
That's it</h3>
<br />
Functional programming gives us more ways to abstract stuff. It also forces us to think at a higher level. These make us better programmers.<br />
<br />
One thing to watch out for is trying to be too clever and apply these abstractions everywhere, even when not needed.<br />
<br />
As an extreme closing example, if you wanted to get 0, you would just write this.<br />
<br />
<script src="https://gist.github.com/amchiclet/fea18504ca7d702944ae.js"></script>
I hope you don't write something like this.<br />
<br />
<script src="https://gist.github.com/amchiclet/f972c9faae86b4bee09e.js"></script>
<br />
<div>
<br /></div>
Amarin Phaosawasdihttp://www.blogger.com/profile/11497556893338926041noreply@blogger.com2tag:blogger.com,1999:blog-6777573582885407214.post-90822444279024218462012-11-23T13:10:00.000-08:002012-11-23T13:20:12.946-08:00All Productivity Systems Are The SameI've been reading here and there about productivity both on the web and on paper. A lot of info out there tend to either:
<ul>
<li>list very specific things to increase productivity (e.g. don't check your email every 10 seconds)</li>
<li>list less specific things to increase productivity (e.g. find a time you can focus and work during that time)</li>
</ul>
<br />
Maybe I haven't looked around enough, but that's kind of the pattern I noticed.<br />
<br />
The way I see it, at the end, it all boils down to 4 things:
<ol>
<li>increase available time</li>
<li>do what's important</li>
<li>do it efficiently</li>
<li>do it sustainably</li>
</ol>
It's up to you to know how to achieve these 4 things in your specific circumstance, and the tips you find online or in books can serve very well as brainstorming tools.<br />
<br />
Several months ago, I mentioned <a href="http://blog.amarinph.com/2012/05/what-is-agile-development.html">what agile was</a>. Now I'm going to take a step back and look at the more generic view of productivity and how several development techniques, as well as day-to-day examples, fall into this framework.<br />
<br />
<b>(1) Increasing Time</b><br />
<br />
A person given 2 hours will be able to watch more episodes of Family Guy than a person given 20 minutes. The example is contrived but I hope you wouldn't argue that more time means a higher probability of getting more work done.<br />
<br />
The main things people do to increase available time is automating or delegating tasks and reducing "waste".
<ul>
<li>Automated testing saves hours of manual testing.</li>
<li>Delegating tasks to developers frees up time for the lead developer to work on important issues.</li>
<li>Having an assistant reduces time needed to keep track of things and context switching.</li>
<li>Disconnecting cable TV saves many hours a day.</li>
</ul>
<br />
<b>(2) Doing what's important</b><br />
<br />
There's not much point in working on something that gives little or no value.<br />
<br />
The main things people do is prioritizing. Now prioritizing isn't the easiest thing to do. Priorities shift a lot and sometimes only somebody else can answer what is important. But there are general fixes. Priority shifts can be fixed by frequent reflection. In the software world, we call this tight feedback loops. As for unknown priorities, you just ask who knows.<br />
<br />
Examples of prioritizing:
<ul>
<li>Asking clients what's the most important feature they want when they can't have all.</li>
<li>Finishing presentation slide contents before making them look beautiful.</li>
<li>Fixing bugs found in unit tests instead of waiting for it to reach production.</li>
<li>Have daily meetings and re-prioritize issues if something comes up.</li>
</ul>
<br />
<b>(3) Doing it efficiently</b><br />
<br />
Once you know what to do, you learn how to do it efficiently.<br />
<br />
The main things people do here is improving skills, leveraging tools, and being healthy.
<ul>
<li>Use IDEs for code editing.</li>
<li>Learn to factor code well.</li>
<li>Learn to set your favorite channel instead of switching channels one by one.</li>
<li>Learn how to use email templates.</li>
<li>Have enough sleep and eat good breakfast. Vitamins also stimulate the brain.</li>
</ul>
<br />
<b>(4) Doing it sustainably</b><br />
<br />
All of the above can be accomplished but for how long? You need to keep yourself motivated.<br />
<br />
This has more science to it than I originally thought. It turns out that our brains are programmed to work in a certain way. There's the emotion part and the logical part. The emotion part favors immediate and positive results. It doesn't care for long term goals. And most importantly in the long run, the emotion part almost always wins. That's why we hit snooze when we know we should wake up and work. And that's why we can force ourselves to wake up early but not for too long.<br />
<br />
If you are a human, your brain works this way. No exception (unless you're not a human). So take advantage of how your brain works.<br />
<br />
An effective way of keeping yourself motivated is to keep enticing yourself with small wins. They are easy to achieve, and you feel good about it right away. A lot of small wins snowball into big wins and that keeps you motivated further.<br />
<br />
Examples of motivation techniques:
<ul>
<li>Daily to-do lists instead of monthly ones.</li>
<li>Working on small and easy tasks when stuck on a more complex one.</li>
<li>Start working out 5 minutes a day instead of an hour a week.</li>
</ul>
<br />
<b>How I got started</b><br />
<br />
I'm not a productivity expert. This is just information I deduced from reading and experience. But so far, what has worked for me is asking myself these questions everyday and tweak my process based on what works well and what doesn't.<br />
<br />
The most important thing was I started small. I listed something that I could finish in 10 minutes and I got it done. The next day, I would add a little more. I accomplished something small and let it snowball.<br />
<br />
It all started from there. And now I've been able to manage much more than before. A LOT more than before.<br />
<br />
Maybe it will work for you too.Amarin Phaosawasdihttp://www.blogger.com/profile/11497556893338926041noreply@blogger.com0tag:blogger.com,1999:blog-6777573582885407214.post-48191900097726473262012-11-13T21:15:00.001-08:002012-11-27T14:38:21.348-08:00Hack the scope, Engineer the solution<br />
<span style="font-family: inherit;">Lately, it seems like startups have become the center of attention. Coworking spaces and tech-meetups have sprung up everywhere. The term "hack" which used to have a negative connotation, is now viewed in more positive light. And given the agile and lean movement, it appears to me that hacking things up sounds like something cool.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">Before I get to my point, it's worth talking about two great companies with different principles.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">After some reading and talking to people, my understanding is that Facebook has the "<a href="http://www.startuplessonslearned.com/2012/02/hacker-way.html">hacker culture</a>", where people try to make things happen as quickly as possible, test it out, and fail fast if it doesn't work. I think video on Facebook was hacked in one day or so.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">On the other hand, Google "engineers" software. If you don't know Jeff Dean, <a href="http://research.google.com/people/jeff/">know him</a> a little bit. The reason I brought up this guy is to give you a peek into the amount of science that goes behind building software at Google.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">This is pure speculation. What I think about the two companies is possibly inaccurate, but that doesn't change what I'm trying to get at. I wanted to talk about hacking versus engineering.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">Given these definitions:</span><br />
<br />
<ul>
<li><span style="font-family: inherit;">hack = come up with something quickly that works</span></li>
<li><span style="font-family: inherit;">engineer = create something based on well-thought and sound principles</span></li>
</ul>
<br />
<span style="font-family: inherit;">When you code, how often do you hack and how often do you engineer?</span><br />
<span style="font-family: inherit;">1) always hack</span><br />
<span style="font-family: inherit;">2) try to engineer, but hack when there are time constraints</span><br />
<span style="font-family: inherit;">3) always engineer</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">Test-driven development has made (1) a viable solution. We can come up with something quickly, and if something needs changing in the future, we have test cases to prevent regressions. I think a lot of startups go with (1) just to validate ideas or create demos for investors.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">In established companies, I would think (2) is what a lot of people do. I do it too. During slow days, I have all the time to think very carefully about the design of the software I'm writing. But when there are tight deadlines, I tend to write something that works, and add a TODO comment to come back and finish it later (if I don't forget).</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">I think governments and financial institutions do (3).</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">Although I do (2) a lot, I'm not really happy with it, because most of the time, there are time constrains. I feel bad when I have code that works but could have been written better if there was a little more time. Well, everybody would write better code given more time, but I recently came to a realization that we can still write good code even with we have the same amount of time.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">It is possible to always engineer software. What we need to do is hack the scope instead. So I'll add (4) hack the scope and engineer the solution.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">So what does this mean? Let me give an example.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">Suppose I need to write a noob-detector. It's a device whose alarm goes off when noobs are around. I have this HUGE third-party library that claims that it implements the best noob-detecting algorithm in the world. However, its API is so complicated that it takes months to learn how to use it properly, and I need it finished this weekend.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">If I went the (2) route, I would randomly tinker with the API until it kind of does what I wanted it to do. At first glance, it seems to work. It detects noobs when I test it. However, I might not be aware that the way I used the library only detects asian noobs. (By the way, asian noobs are hard to find.)</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">But if I went the (4) route, I would see that the scope is too large. I hack the scope instead. There's another library that's fairly simple to use, but uses an inefficient algorithm. Yet, its slowness is tolerable. I loosen the requirement that the software needs to run with the state-of-art algorithm and use this library. With this library, I can write beautiful code that does the right thing. At the end, this version is less buggy, and correct according to the new requirement.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">In a sense, I am tackling the problem as early as possible to save time, and this goes along well with productivity principles.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">Sure it sounds like common sense, but even after writing code for so many years, I still fall into trap (2) all the time. I'm getting better at it though. Hope this helps others as well.</span>Amarin Phaosawasdihttp://www.blogger.com/profile/11497556893338926041noreply@blogger.com3tag:blogger.com,1999:blog-6777573582885407214.post-60664837593173778752012-05-31T21:50:00.000-07:002012-11-13T15:27:33.406-08:00Life at a startupHurray! I've been working at a tech startup for exactly a year already. This is one of the best things that ever happened in my life. Let’s just say it’s a super awesome and fun experience.<br /><br />This post will basically be a condensed note to myself in the future, but it might benefit you as well if you're interested in starting your own company. (Or if you already have a company.)<br /><br />The topics are pretty random and are not ordered in anyway.<br /><br /><h3> startup != consulting != ecommerce</h3><br />I personally don't think opening an online web design firm or selling stuff online is essentially a startup. You might, but that's your opinion.<br /><br />I think startups are companies that try to solve problems for the mass. Facebook for example, changed the way people interact. I don’t have the energy to call everyone of my friends in Thailand everyday, so I learn about them through Facebook. Facebook solved one of my problems.<br /><br />If you have a good vision, then you'll be rewarded when you see your product help people.<br /><br /><h3> When To Hire</h3><br />My company has about 7 roles. At the beginning, the founder had to do all of them. As a result, he was too overwhelmed. That's when the hiring happened.<br /><br />In established companies, you hire on a continuous basis because people leave all the time. However, in early-stage startups, you should hire from needs. If you spend too much time on customer support, you don't have time to improve your product. But if you don't answer customer calls, you'll end up losing business. You need a balance. If you're out of balance, it's probably time to hire.<br /><br /><h3> Environment</h3><br />Before I left my old job, I never thought work environment would be such a big deal, but it actually is. A big part of why I left my old job was that I was in a cube in a room with no windows and I developed wrist, back, and neck pain from sitting in that cube.<br /><br />You don’t have to have a fancy office (and you probably won't have money to pay for an interior designer anyway), but the better-looking office will attract developers.<br /><br />My advice is at least make the office look nice -- nice being if you invited your mom to the office, she wouldn’t complain.<br /><br />Here are some concrete things that are good to have:<br /><br /><table border="1"><tbody><tr><td>computers that are fast enough</td><td>sufficient lighting</td><td>big tables</td><td>private rooms for meetings</td></tr><tr><td>air conditioning + heaters that work well</td><td>clean bathrooms</td><td>earphones</td><td>cupboards enough for everyone</td></tr><tr><td>chairs with neck rests</td><td>microwave(s) and fridge(s)</td><td>big windows</td><td>coffee/tea</td></tr><tr><td>water coolers or ice makers</td><td>coat hangers</td><td><br /></td><td></td></tr></tbody></table><br /><h3> Do I need an accountant?</h3><br />You certainly do, but you don't have to hire one. You only have to know where the money comes and goes so you know if you’re going out of business or not. Oh, and you need to pay tax correctly too. In my company, this is managed by another developer. She said she needed about three courses from a local community college to get from zero to workable knowledge. She spends one day each month for accounting.<br /><br /><h3> Network Admin</h3><br />It's good to have if you can afford one, but probably not. Server/network setup (including contacting the cable company) are skills that programmers can learn easily. It's just not fun when you do it a lot. I remember seeing the founder driving to Chicago (2 hours away) at 8pm to switch a hard disk in the data center.<br /><br />One thing to note is that when you're small, there's not much security concerns to worry about. But once you're big enough to become a target of hackers (the bad type), you might need a network admin, or more of a network security expert.<br /><br /><h3> How to grow? Do I need Sales / Marketing / Advertising?</h3><br />You can probably do it by yourself for the first 10 customers, but if you want to scale, you need people to help. I'm stereotyping but most software developers don't have a gift for marketing.<br /><br />At the first stage of your startup, try to get customers in the most straightforward way. It’s like hacking up a prototype. It doesn’t need to scale yet.<br /><br />This includes cold calling as much target audience as you can. Ask your mom and friends to sign up and spread the word. Go to conferences and make direct connections. Ads don’t make sense yet at this stage. If you have enough income, hire a sales rep to help with this.<br /><br /><h3> Customer Service</h3><br />Again, you won’t need any until you get overwhelmed by calls. We tried outsourcing, but didn’t really work out. We lost the opportunity to know our customers better and improve our product.<br /><br />So I think at an early stage, when you don’t have a lot of numbers to crunch on, the best source of customer feedback is support calls, so you want somebody inhouse.<br /><br /><h3> Administrator (this is different than network admin)</h3><br />A euphemism for “errand runner”. You as the company owner have to do everything from basic plumbing, to lighting installation, to making sure there are stationary and enough napkins. This is not too bad, because these things don’t happen too often. It’s just a little more work than taking care of your own two bedroom apartment with 5 other roommates.<br /><br /><h3> Software Developers</h3><br />Every role is important, but since I like to self-promote what I do, I personally feel that a company needs great software developers.<br /><br />You’ll probably be looking for generalists who are not tied to a specific set of technologies, and don’t mind working on anything (including tedious stuff). You want somebody who can tolerate imperfect code to get things done, and at the same time, feel bad about imperfect code because it's not beautiful.<br /><br /><h3> Perks</h3><br />Many startups can afford to buy their employees all the meals they want, some companies just can’t. But that doesn’t mean you have to be cheap. Once in a while, you can take your employees out. My company buys us lunch once a week. That’s a good perk given the size of our company. As a general rule, be generous with perks if it improves work efficiency and teamwork, and as long as it’s reasonable.<br /><br /><h3> Pay</h3><br />Of course you don’t have 250k to pay your employees, but do research to find what’s a competitive market pay in your area and at least match that. You should never lose a good employee because of your pay was too low. In other words, if you hired the right person, they'll likely work for the job not as much for the pay, as long as the pay can maintain their lifestyle.<br /><br /><h3> Flexible work hours</h3><br />A reasonable way of thinking is: as long as you get the job done, it doesn’t really matter that much what your work hours are. If your employee needs to see the dentist or take his/her cat to the vet, by all means, be flexible and your employees will love the job.<br /><br /><h3> Funding</h3><br />Angel investors and venture capitals (VCs) are not the only sources of seed funding. If you start a business with a market that exists, you will get your first paying customers. You can use the revenue to bootstrap your business.<br /><br />VCs have pros and cons. You are advised by very experienced people, so you have a higher rate of success. On the other hand, since VCs invested and have equity, you have to listen to them and sometimes do something you don’t entirely want to do.<br /><br /><h3> Everybody is involved</h3><br />One of the best things about startups is you have input on anything, be it the processes to use, the tools we use, the color of the lights, which soda to buy, everything.<br /><br />I find it really rewarding when somebody as smart as my company leader asks input from me. If you’re the company leader, you should listen to your employees as much as you can.<br /><br /><h3> Coworkers</h3><br />This is one of the most important things about startups. Of course, you would need somebody with skills. But as importantly, you have to make sure everybody is a great fit culturally.<br /><br />In startups, you can’t afford to hire the wrong person. Make sure that cultural fit is one of the highest priorities. When you don’t have 200 teams, you can’t avoid seeing the wrong person everyday.<br /><br />When interviewing a potential coworker, include questions that will show their personalities. For example, try finding something the candidate totally disagrees and see his/her reaction to that. If the candidate uses strong words like “stupid” or “hate”, that’s a bad sign.<br /><br /><h3> Use open source and open your source when you can</h3><br />Most of the time, open source code is a great way to save cost. Try finding open source libraries as much as you can, but if buying software licenses will save you cost more than the time wasted finding the right open source software, by all means, spend your money on it.<br /><br />You want to look for liberal licenses which don’t force you to release your source code. My favorites are BSD, MIT, and Apache licenses. I’ll blog about the differences one day.<br /><br />And at some point, don’t forget to give back to society and open source what you can. Just be careful not to open source stuff that your competitors can use to kick you out of business.<br /><br /><h3> Have a research mind</h3><br />There’s a lot of knowledge out there you can leverage. Having at least somebody with an MS or preferably higher in your team, who is used to reading research papers, will widen your point of views. We’ve applied solutions from at least 3 papers already in our system and have plans for future directions.<br /><br />Not only research papers, but generally if you’re looking to solve hard problems, a lot of times when you include “site:edu” in your Google searches, you can find out how the academia solves it.<br /><br />Even if you end up using nothing. Just reading for the sake of knowledge is fun enough (if you really enjoy what you do).<br /><br /><h3> Meetings</h3><br />Don’t meet unless you have to. Multiple short meetings is better than one big meeting. Anything over 35 minutes might lose people’s attention.<br /><br /><h3> The end</h3><br />I hope you find this post useful. Feel free to send me comments on what you agree or disagree. I’d love to hear from other people who work at startups too, especially learning what went well and what didn’t.<br /><br />But anyway, happy one year (and 40000+ lines of code) anniversary to me! XDAmarin Phaosawasdihttp://www.blogger.com/profile/11497556893338926041noreply@blogger.com1tag:blogger.com,1999:blog-6777573582885407214.post-31587677457572529942012-05-21T17:51:00.000-07:002012-11-13T15:27:33.401-08:00NoSQL vs SQLI've been exposed to NoSQL for about a year now, and I think I am finally able to describe what it is to other people.<br /><br />NoSQL is a marketing term, well-named to catch buzz, and ill-named to describe what it is.<br /><br />It kind of implies that we should throw SQL away and move to this hip database. Before all the NoSQL fuss, the most popular databases were relational databases, which supported a language called SQL. The marketing idea was to say, we're the opposite team, so we're "NO SQL". I think it worked.<br /><br /><h3 style="text-align: left;"> <b>The Traits</b></h3><br />There are traits that relational databases vs NoSQL databases have. I think viewing them like this gives a better understanding of the differences.<br /><br /><h4> How to Represent Data</h4><br />At the end, a database is a system where you give it a question and it returns results. If you think of it as a map, you give it a key, and it returns a value.<br /><br />A relational database's key is the primary key of the tables you specify.<br /><br />For NoSQL databases, the key can be anything you want (including something like primary keys).<br /><br />What people choose to use as a key depends on their design decisions. For example, <a href="http://research.google.com/archive/bigtable.html">Google's Bigtable</a> specifies the key to be the row name, column name, and timestamp.<br /><br />And you can see that nobody's stopping you from using relational databases to have a table whose primary keys are row name, column name and timestamp.<br /><br /><h4> The API</h4><br />All relational databases I know of, support SQL and some language binding, so that's how you talk to the database.<br /><br />For NoSQL databases, the API can be anything, but usually is some language binding or web service.<br /><br />Note that nothing can stop you from supporting SQL in NoSQL databases. It just usually isn't supported by default by all NoSQL database.<br /><br /><h4> Scalability</h4><br />Relational databases weren't designed from the beginning to be deployed in a distributed environment. They're usually on one computer as one process.<br /><br />So if you want to support some data partitioning like,<br /><br /><ul><li>for row 1 to row 100, I want to contact the database on machine 1</li><li>for row 101 to row 200, I want to contact the database on machine 2</li><li>although they're two database processes running, we actually view it as one logical database,</li></ul>then your application has to be smart enough to do it.<br /><br />But still, that means relational databases <b>*can*</b> scale with the help of application level code.<br /><br />Many NoSQL databases were designed from the beginning to be distributed. This means, you get the partitioning above for free. This is why people say NoSQL databases scale better. It's because you don't need application code to scale.<br /><br />Note that I said <b>*many*</b> NoSQL databases are distributed. A bunch of them aren't, but they're still called NoSQL because they have other NoSQL traits.<br /><br /><h4> Schema</h4><br />Relational databases need a schema and they strictly check that data conforms to that schema.<br /><br />NoSQL databases might or might not have a schema, depending on the design. If you want a schema but the NoSQL database doesn't support it, then you need application level code to do it.<br /><br /><h4> Transaction Guarantees</h4><br />Relational databases have the <a href="http://en.wikipedia.org/wiki/ACID">ACID</a> guarantee (you don't need to know what it is), but it means you can have transactions any way you like it. For example, your transaction could be modifying all the rows in the database in one shot. But note that whenever you make a relational database distributed though application code, you lose this guarantee just like NoSQL databases.<br /><br />Distributed NoSQL databases normally have the <a href="http://en.wikipedia.org/wiki/Eventual_consistency">BASE</a> guarantee. Again you don't need to know the details what it is, but it means that if you have data across two machines, and you do a transaction on this data, then there might be a time lapse where the data in these two machines are not consistent. (They will eventually, but just not immediately.)<br /><br />This relaxed guarantee is a tradeoff between performance and consistency. Technically, it's possible to have ACID guarantees for distributed transactions, but it doesn't perform well. On the other hand, you can have a pretty efficient distributed database if you relax this guarantee.<br /><br />That said, if the transaction only involves data living on one machine in a distributed system, ACID can still be guaranteed. This also means that if the NoSQL database is a non-distributed one, then it can provide ACID guarantees easily, because data is on one machine.<br /><br />So the guarantee boils down to this. If the data you're performing a transaction against is on the same machine, you can provide ACID. If the data is on different machines, but you need to perform a transaction, then there might be some inconsistencies for a short while if you want reasonable performance.<br /><br /><h4> When to Choose Which</h4><br />If you're deciding whether to use a relational database or NoSQL database, consider what traits do you want your database to have.<br /><br /><table border="1"><tbody><tr><td><b>Trait</b></td><td><b>Relational Databases</b></td><td><b>NoSQL Databases</b></td></tr><tr><td>represent data with tables and primary keys</td><td>yes</td><td>maybe</td></tr><tr><td>represent data with anything else</td><td>no</td><td>yes</td></tr><tr><td>sql support</td><td>yes</td><td>maybe</td></tr><tr><td>scalability</td><td>maybe</td><td>yes</td></tr><tr><td>schemas</td><td>yes</td><td>maybe</td></tr><tr><td>transaction on same machine</td><td>yes</td><td>yes</td></tr><tr><td>transaction across many machines</td><td>choose between relaxed guarantees vs efficiency</td><td>choose between relaxed guarantees vs efficiency</td></tr></tbody></table><br />Any thing other than "yes" means you might need to write your own application level support.<br /><br />As you can see with some amount of application level code, relational and NoSQL databases pretty much can support the same things.<br /><br />The reason I see most people use NoSQL is for the non-strict schema and the scalability, which (1) requires a lot of work for application level code to handle, and (2) the current fashion for software is shipping fast (might need to change schema often) and scalable software.<br /><br />Other things that might affect your decisions are: community support for the database, your boss says so, price, installation difficulty. These topics are pretty self-explanatory, so I didn't include them in this post.<br /><div><br />I hope now you have a good answer when the next person asks you why you're using a NoSQL database.</div>Amarin Phaosawasdihttp://www.blogger.com/profile/11497556893338926041noreply@blogger.com2tag:blogger.com,1999:blog-6777573582885407214.post-82880148779250345682012-05-03T10:20:00.000-07:002012-11-13T15:27:33.412-08:00What is agile development?<span class="Apple-style-span" style="background-color: white; font-family: arial, sans-serif; font-size: 13px;">Disclaimer</span><br /><br /><span class="Apple-style-span" style="background-color: white; font-family: arial, sans-serif; font-size: 13px;">- If you want to know how </span><a href="http://en.wikipedia.org/wiki/Scrum_(development)" style="background-color: white; color: #1155cc; font-family: arial, sans-serif; font-size: 13px;" target="_blank">scrum</a><span class="Apple-style-span" style="background-color: white; font-family: arial, sans-serif; font-size: 13px;">/</span><a href="http://en.wikipedia.org/wiki/Extreme_programming" style="background-color: white; color: #1155cc; font-family: arial, sans-serif; font-size: 13px;" target="_blank">XP</a><span class="Apple-style-span" style="background-color: white; font-family: arial, sans-serif; font-size: 13px;">/</span><a href="http://en.wikipedia.org/wiki/Kanban_(development)" style="background-color: white; color: #1155cc; font-family: arial, sans-serif; font-size: 13px;" target="_blank">kanban</a><span class="Apple-style-span" style="background-color: white; font-family: arial, sans-serif; font-size: 13px;"> works, this post is not for you.</span><br /><span class="Apple-style-span" style="background-color: white; font-family: arial, sans-serif; font-size: 13px;">- if you want to know what the </span><a href="http://agilemanifesto.org/" style="background-color: white; color: #1155cc; font-family: arial, sans-serif; font-size: 13px;" target="_blank">agile manifesto</a><span class="Apple-style-span" style="background-color: white; font-family: arial, sans-serif; font-size: 13px;"> is, this is not for you</span><br /><span class="Apple-style-span" style="background-color: white; font-family: arial, sans-serif; font-size: 13px;">- If you want to know how </span><a href="http://www.sei.cmu.edu/library/abstracts/reports/08tn003.cfm" style="background-color: white; color: #1155cc; font-family: arial, sans-serif; font-size: 13px;" target="_blank">CMMI and agile can live together</a><span class="Apple-style-span" style="background-color: white; font-family: arial, sans-serif; font-size: 13px;">, this is not for you</span><br /><span class="Apple-style-span" style="background-color: white; font-family: arial, sans-serif; font-size: 13px;">- If you want to read what </span><a href="http://steve-yegge.blogspot.com/2006/09/good-agile-bad-agile_27.html" style="background-color: white; color: #1155cc; font-family: arial, sans-serif; font-size: 13px;" target="_blank">good and bad agile are</a><span class="Apple-style-span" style="background-color: white; font-family: arial, sans-serif; font-size: 13px;">, this is not for you</span><br /><br /><span class="Apple-style-span" style="background-color: white; font-family: arial, sans-serif; font-size: 13px;">But...</span><br /><br /><span class="Apple-style-span" style="background-color: white; font-family: arial, sans-serif; font-size: 13px;">if you want a high level understanding what agile is about in less than 500 words, keep reading. I'll do my best explaining it concisely.</span><br /><br /><span class="Apple-style-span" style="background-color: white; font-family: arial, sans-serif; font-size: 13px;">I've been lost in the amount of information about agile methods before, so to help you avoid that, you just need to know this.</span><br /><br /><span class="Apple-style-span" style="background-color: white; font-family: arial, sans-serif; font-size: 13px;">Agile is not a process; Agile is a mindset.</span><br /><br /><span class="Apple-style-span" style="background-color: white; font-family: arial, sans-serif; font-size: 13px;">(And may I also add, agile is a buzzword so people can remember it more easily.)</span><br /><div style="background-color: white; font-family: arial, sans-serif; font-size: 13px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br /></div><div style="background-color: white; font-family: arial, sans-serif; font-size: 13px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">If I had to summarize agile software development in one sentence, it would be this.</div></div><div style="background-color: white; font-family: arial, sans-serif; font-size: 13px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br /></div><div style="background-color: white; font-family: arial, sans-serif; font-size: 13px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><b>Try to ship useful, non-buggy software quickly using the simplest process that is still feasible.</b></div><div style="background-color: white; font-family: arial, sans-serif; font-size: 13px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br />By useful, I mean it gives what the user needs. By feasible, I mean meets the constraints imposed by outside entities, such as complying to the law.<br /><br />That's pretty much it. Before I understood this, I got lost in the concrete techniques and buzzwords that people use to improve productivity.</div><div style="background-color: white; font-family: arial, sans-serif; font-size: 13px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br /></div><div style="background-color: white; font-family: arial, sans-serif; font-size: 13px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">For example, test driven development isn't agile. It's just a technique that has proven to improve productivity, and thus falls into the agile mindset.</div><div style="background-color: white; font-family: arial, sans-serif; font-size: 13px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br /></div><div style="background-color: white; font-family: arial, sans-serif; font-size: 13px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">On the other hand, mission critical projects that have hundreds of documents and processes can also be agile as long as those hundreds of documents have the least overhead in order to complete the project.</div><br /><b style="background-color: white; font-family: arial, sans-serif; font-size: 13px;">So how do I "ship useful, non-buggy software quickly using the </b><b style="background-color: white; font-family: arial, sans-serif; font-size: 13px;">simplest process that is still feasible</b><b style="background-color: white; font-family: arial, sans-serif; font-size: 13px;">"</b><br /><br /><span class="Apple-style-span" style="background-color: white; font-family: arial, sans-serif; font-size: 13px;">You can reach this goal just by focusing on one thing: </span><b style="background-color: white; font-family: arial, sans-serif; font-size: 13px;">get early feedback on all activities</b><span class="Apple-style-span" style="background-color: white; font-family: arial, sans-serif; font-size: 13px;">.</span><br /><br /><span class="Apple-style-span" style="background-color: white; font-family: arial, sans-serif; font-size: 13px;">Here are examples.</span><br /><br /><table border="1" style="background-color: white; color: black; font-family: arial, sans-serif; font-size: 13px;"><tbody><tr><td><b>activity</b></td><td><b>feedback</b></td></tr><tr><td>have customer onsite</td><td>know which feature to focus on</td></tr><tr><td>automated test</td><td>know if new code breaks expected behavior</td></tr><tr><td>continuous integration</td><td>know if new code breaks the system build</td></tr><tr><td>daily meetings</td><td>know if your team member needs help</td></tr><tr><td>pair programming</td><td>know if you wrote buggy code or not</td></tr></tbody></table><br /><b style="background-color: white; font-family: arial, sans-serif; font-size: 13px;">When will agile not work?</b><br /><br /><span class="Apple-style-span" style="background-color: white; font-family: arial, sans-serif; font-size: 13px;">The main thing people fail to notice is that they should choose a technique that works for their project and not just use the techniques blindly. Those are the people who hate agile and think it's broken.</span><br /><br /><b style="background-color: white; font-family: arial, sans-serif; font-size: 13px;">Do you want to try agile?</b><br /><br /><span class="Apple-style-span" style="background-color: white; font-family: arial, sans-serif; font-size: 13px;">My workplace just started using agile for almost a year now. As much as I dislike buzzwords and rather just say that we've followed some good practices, some agile techniques work for us and keep us focused.</span><br /><br /><span class="Apple-style-span" style="background-color: white; font-family: arial, sans-serif; font-size: 13px;">The only advice I can give you is, if you want to be more productive and don't really care if you're agile or not, just try out 1-3 popular agile techniques, such as automated testing or daily standup meetings, and see if they work or not. If they don't, just move on.</span><br /><br /><span class="Apple-style-span" style="background-color: white; font-family: arial, sans-serif; font-size: 13px;">If they don't work, you're probably already productive anyway. Plus, by moving on and not blindly following processes, you have the agile mindset already.</span>Amarin Phaosawasdihttp://www.blogger.com/profile/11497556893338926041noreply@blogger.com0tag:blogger.com,1999:blog-6777573582885407214.post-26262319419873057032012-04-02T21:10:00.000-07:002012-11-13T15:27:33.400-08:00Poker at work<br />This post in not mainly about poker.<br /><br />Recently at work, we've been using a humongous third-party open source library. Our quad-core, 64 bit processors + 16 GB RAM computers take about 20 minutes to compile the library from scratch.<br /><br />We wanted to speed up compile time, so we've been considering <a href="http://code.google.com/p/distcc/">distcc</a>, which I believe Google <a href="http://google-opensource.blogspot.com/2008/08/distccs-pump-mode-new-design-for.html">has been using for a while</a>. The concept is pretty nice: just farm out a bunch of compilers.<br /><br />The thing is we only have 4 computers we can use as build machines. Luckily we only have 4 devs, but we expect to grow in the future, so I was curious to know when is a good time to get more build machines.<br /><br />Fortunately, I've played poker before, so I'm kind of familiar with some basic probability. With my limited knowledge, here's what I've got.<br /><br />I'll just make up some numbers.<br /><br />Suppose<br /><ul><li>there are 4 devs including me</li><li>we have 3 build machines</li><li>we all spend 1/5 of our time to compile code</li><li>2 build machines mean 2 times faster the compilation time (and 3 machines mean 3X, you get it)</li><li>2 devs compiling at the same time means twice the time it takes to compile (and 3 devs mean 3X, you get it)</li></ul><b>Problem: If I wanna compile some code, what's the expected compile time?</b><br /><br />We just need to find the <a href="http://en.wikipedia.org/wiki/Expected_value">expected value</a>.<br /><br />Let's enumerate the cases:<br /><ul><li>I'm the only person compiling.</li><li>1 more dev is compiling at the same time.</li><li>2 more devs are compiling at the same time.</li><li>3 more devs are compiling at the same time.</li></ul>The "value" in this case is compilation speed, it will take<br /><ul><li>1/3 times normal compilation time, if I'm the only person compiling.</li><li>2/3 times normal compilation time, if 1 more dev is compiling at the same time.</li><li>3/3 times normal compilation time, if 2 more devs are compiling at the same time. (No speed up.)</li><li>4/3 times normal compilation time, if 3 more devs are compiling at the same time. (Even slower.)</li></ul>We got all the cases and values laid out, now the probability of each case.<br /><br /><b>If I'm the only person compiling</b><br /><b><br /></b><br />The probability that the 3 other devs aren't compiling is: (4/5)(4/5)(4/5).<br /><br />The probability of this case happening is (4/5)(4/5)(4/5) = 0.512<br /><br /><b>If 1 more dev is compiling at the same time</b><br /><br />The probability that another 1 dev is compiling and the other 2 aren't is: (1/5)(4/5)(4/5), but remember that there are several ways this can happen.<br /><br />Dev #2 might be the person compiling while the other aren't, or dev #3 could be the person compiling as well.<br /><br />There are <a href="http://en.wikipedia.org/wiki/Binomial_coefficient">choose</a>(3,1) ways to choose who's compiling and who's not.<br /><br />So the The probability that another 1 dev is compiling and the other 2 aren't is: (1/5)(4/5)(4/5) choose(3,1).<br /><br />The probability of this case happening is (1/5)(4/5)(4/5) choose(3,1) = 0.384.<br /><br /><b>If 2 more devs are compiling at the same time</b><br /><br />The probability that another 1 dev is compiling and the other 2 aren't is: (1/5)(1/5)(4/5) choose(3,2).<br /><br />The probability of this case happening is (1/5)(1/5)(4/5) choose(3,2) = 0.096<br /><br /><b>If 3 more devs are compiling at the same time</b><br /><br />The probability that another 1 dev is compiling and the other 2 aren't is: (1/5)(1/5)(1/5).<br /><br />The probability of this case happening is (1/5)(1/5)(1/5) = 0.008.<br /><br />For each case we multiply its probability with its value.<br /><br /><table border="1"><tbody><tr><td>probability</td><td>compile speed</td><td></td></tr><tr><td>0.512</td><td>1/3</td><td>0.171</td></tr><tr><td>0.384</td><td>2/3</td><td>0.256</td></tr><tr><td>0.096</td><td>3/3</td><td>0.096</td></tr><tr><td>0.008</td><td>4/3</td><td>0.011</td></tr></tbody></table><br />Expected compile speed is the sum of the last column, which is 0.533<br /><br />So it seems with 4 devs and 3 machines, compiling 1/5 of the time, we still gain faster compile speed compared to our normal compile time (0.533 of original compile time).<br /><br /><b>Problem: How many devs can we afford with 3 build machines?</b><br /><br />I can setup an equation and solve it, but it will end up with something like this.<br /><div class="separator" style="clear: both; text-align: center;"></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6qKSBXdtZ49LTy0E4GxMP3QwB9sw5bM8rTgf6kh9F_ZIbeANcIrsoVIo8EssftGiLm1L7P4WWOZPe4dhkXXYfKTTegHGjso-lAbjzsKJBSMygxBpnrTgnAIMauaMeubaHutOG0kc4hyGy/s1600/Picture+23.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="65" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6qKSBXdtZ49LTy0E4GxMP3QwB9sw5bM8rTgf6kh9F_ZIbeANcIrsoVIo8EssftGiLm1L7P4WWOZPe4dhkXXYfKTTegHGjso-lAbjzsKJBSMygxBpnrTgnAIMauaMeubaHutOG0kc4hyGy/s320/Picture+23.png" width="320" /></a></div><div class="separator" style="clear: both; text-align: left;">Where n is the number of devs we need to find. Apparently, I don't know how to solve that equation, and I'm not even sure I got the equation right or not.</div><br />Plugging in some number sounded easier.<br /><br />I kept increasing the number of devs until the expected compile speed became more than 1. Looks like we get about equal performance as soon as we have 11 devs including myself.<br /><br />From that point, every 5th additional dev requires another build machine, which makes sense since the compile load is 0.2.<br /><br />So this is how poker applies to work.Amarin Phaosawasdihttp://www.blogger.com/profile/11497556893338926041noreply@blogger.com0tag:blogger.com,1999:blog-6777573582885407214.post-80630138068267932302012-03-06T17:46:00.000-08:002012-11-18T15:50:17.226-08:00C++ and Subtyping FunQuestion: In the following C++11 program, what lines will fail to compile?<br />
<div>
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjliMwfhgMMJUi8Xj043vLwRGCaXUD7FLKyu7tDjnqDpJp0rEXV5PigrEW8ceWyqutWwzJA2Un_lkHlJcTKbtKoYXNb3P4WvmVjPAOSbByJqgU-r2KLRXxFXFV7bX-iznwfAEv8qw0qlqEV/s1600/test.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjliMwfhgMMJUi8Xj043vLwRGCaXUD7FLKyu7tDjnqDpJp0rEXV5PigrEW8ceWyqutWwzJA2Un_lkHlJcTKbtKoYXNb3P4WvmVjPAOSbByJqgU-r2KLRXxFXFV7bX-iznwfAEv8qw0qlqEV/s1600/test.jpg" /></a></div>
<br />
Answers are colored white below if you want to give a try before highlighting it.<br />
<span class="Apple-style-span" style="color: white;"><br /></span><span class="Apple-style-span" style="color: white;">Answer: 14, 16, 25, 26, 28, 31, 32.</span><br />
<span class="Apple-style-span" style="color: white;"><br /></span><span class="Apple-style-span" style="color: white;">The keyword is subtyping.</span><br />
<span class="Apple-style-span" style="color: white;"><br /></span><span class="Apple-style-span" style="color: white;">Here's the explanation:</span><br />
<span class="Apple-style-span" style="color: white;"><br /></span><span class="Apple-style-span" style="color: white;">If you declare a function to receive type </span><span class="Apple-style-span" style="color: white; font-family: 'Courier New', Courier, monospace;">A</span><span class="Apple-style-span" style="color: white;"> and return type </span><span class="Apple-style-span" style="color: white; font-family: 'Courier New', Courier, monospace;">A</span><span class="Apple-style-span" style="color: white;"> (function </span><span class="Apple-style-span" style="color: white; font-family: 'Courier New', Courier, monospace;">f1</span><span class="Apple-style-span" style="color: white;"> in the example), you're promising that it can receive type </span><span class="Apple-style-span" style="color: white; font-family: 'Courier New', Courier, monospace;">A</span><span class="Apple-style-span" style="color: white;"> or it's subclasses, and return </span><span class="Apple-style-span" style="color: white; font-family: 'Courier New', Courier, monospace;">A</span><span class="Apple-style-span" style="color: white;"> or it's subclasses. The caller will expect to be able to do all of the following:</span><br />
<span class="Apple-style-span" style="color: white;"><br /></span><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="color: white;">a = f1(a);</span></span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="color: white;">a = f1(subclass_of_a);</span></span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="color: white;">superclass_of_a = f1(a);</span></span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="color: white;">superclass_of_a = f1(subclass_of_a);</span></span><br />
<span class="Apple-style-span" style="color: white;"><br /></span><span class="Apple-style-span" style="color: white;">So anything assigned to <span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">f1</span> must be able to do all of the following. Take <span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">ab</span> in line 14 for example, it can only accept <span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">B</span> and its subclasses as a parameter. What if somebody passed in an <span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">A</span>?</span><br />
<span class="Apple-style-span" style="color: white;"><br /></span><span class="Apple-style-span" style="color: white;">How about, line 31? The caller of <span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">f4</span> is expecting <span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">B</span> or its subclass as a return value. What if the function returned <span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">A</span>? That's why line 31 is invalid.</span><br />
<span class="Apple-style-span" style="color: white;"><br /></span><span class="Apple-style-span" style="color: white;">:)</span></div>
Amarin Phaosawasdihttp://www.blogger.com/profile/11497556893338926041noreply@blogger.com2tag:blogger.com,1999:blog-6777573582885407214.post-16861041835959761102012-02-23T19:02:00.000-08:002012-11-13T15:27:33.399-08:00Big whoopSo I made my first (indirect) <a href="http://levent.git.sourceforge.net/git/gitweb.cgi?p=levent/libevent;a=commit;h=a6492cb744f50030a1538857bef9209992cf6306">contribution</a> to a pretty (indirectly) widely used <a href="http://libevent.org/">open source project</a>. This is my first time so it's worth marking the date. :)Amarin Phaosawasdihttp://www.blogger.com/profile/11497556893338926041noreply@blogger.com0tag:blogger.com,1999:blog-6777573582885407214.post-69537184821642098882011-11-15T19:14:00.000-08:002012-11-13T15:27:33.408-08:00MBA: The Good PartsToday I had a chance to talk with one of the co-founders of the company I work at and the CEO/CTO/CFO/[you name it] of another company with 80 people. He's a CS + MBA grad. I have always been curious what people learn in MBA as my dad always said you don't need an MBA to run a company. We ended up having a pretty interesting conversation and I thought it would be good to share.<br /><br />First, he gave me a primer on the stereotypes of people who attend business school. He said 90% of people who go to business school need an MBA next to their name to bump their salary. And the other 10% are people who truly want to understand the art of business better. Clearly he fell into the 10%.<br /><br />He told me that my dad was in fact right. You actually don't need an MBA to run a company.<br /><br />I was curious. Then was it for networking or what?<br /><br />He said no. The most awesome contacts he had weren't the people he met in business school, but were the ones he spent many years together in college and people he met through serendipity.<br /><br />So what was special about MBA?<br /><br />He said MBA gave him the "universal" vocabulary to conduct business. Without it, he wouldn't know what a cash flow statement was. Without it he would look at a product and say something like, "This is nice, let's make it better." without being able to objectively measure "nice" and "better".<br /><br />Not only that, if he hadn't gone to business school, he said he wouldn't have had the confidence to take over and improve a 20-year-old business started by his family.<br /><br />I guess business school doesn't solely consist of people in suits with spiky hair after all. Pretty cool indeed.Amarin Phaosawasdihttp://www.blogger.com/profile/11497556893338926041noreply@blogger.com0tag:blogger.com,1999:blog-6777573582885407214.post-31659654414030800942011-10-16T14:44:00.000-07:002012-11-13T18:21:34.605-08:00A (somewhat) concise explanation of HTTPS / SSL / PKI / Digital Certificates / Blah blah blahMy work has recently forced me to understand HTTPS. It's been an area I've always shied from since 2004 -- I interned at an IT security department. I felt that the more detailed and accurate explanations on the web was a bit too much, so I thought this might be a bit more useful to a group of people. (In particular, I'm hoping this is useful to one of my friends who agreed that the video explanations on YouTube sucked.)<br />
<br />
I'm no security expert, but I just know enough to get my job done. And here's what I have to share, a concise explanation of HTTPS. Topics includes SSL (secure socket layer), PKI (public key infrastructure), digital certificates, digital signatures, hashes, public/private keys, and stuff along those lines.<br />
<br />
Let's start with this spreadsheet.<br />
<span class="Apple-style-span" style="font-family: arial, sans, sans-serif; font-size: 13px;"></span><br />
<table border="0" cellpadding="0" cellspacing="0" class="tblGenFixed" id="tblMain" style="-webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-collapse: collapse; border-left-style: none; border-right-style: none; border-top-style: none; font-size: 13px; table-layout: fixed; width: 0px;"><tbody>
<tr class="rShim"><td class="rShim" style="background-color: white; border-bottom-color: initial; border-bottom-style: initial; border-bottom-width: 0px; border-left-color: initial; border-left-style: none; border-left-width: 0px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: initial; border-top-style: none; border-top-width: 0px; font-size: 13px; height: 0px; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: bottom; white-space: normal; width: 0px; word-spacing: 0px; z-index: 1;"></td><td class="rShim" style="background-color: white; border-bottom-color: initial; border-bottom-style: initial; border-bottom-width: 0px; border-left-color: initial; border-left-style: none; border-left-width: 0px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: initial; border-top-style: none; border-top-width: 0px; font-size: 13px; height: 0px; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: bottom; white-space: normal; width: 120px; word-spacing: 0px; z-index: 1;"></td><td class="rShim" style="background-color: white; border-bottom-color: initial; border-bottom-style: initial; border-bottom-width: 0px; border-left-color: initial; border-left-style: none; border-left-width: 0px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: initial; border-top-style: none; border-top-width: 0px; font-size: 13px; height: 0px; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: bottom; white-space: normal; width: 288px; word-spacing: 0px; z-index: 1;"></td><td class="rShim" style="background-color: white; border-bottom-color: initial; border-bottom-style: initial; border-bottom-width: 0px; border-left-color: initial; border-left-style: none; border-left-width: 0px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: initial; border-top-style: none; border-top-width: 0px; font-size: 13px; height: 0px; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: bottom; white-space: normal; width: 372px; word-spacing: 0px; z-index: 1;"></td></tr>
<tr><td class="hd" style="background-color: #c8c8c8; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: initial; border-left-style: none; border-left-width: 0px; border-right-color: initial; border-right-style: initial; border-right-width: 0px; border-top-color: initial; border-top-style: none; border-top-width: 0px; font-size: 13px; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: bottom; white-space: normal; word-spacing: 0px; z-index: 1;"><div style="font-size: 0px; height: 16px; overflow-x: hidden; overflow-y: hidden; width: 0px;">
</div>
</td><td class="s0" style="background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(204, 204, 204); border-top-style: solid; border-top-width: 1px; color: black; font-family: arial, sans, sans-serif; font-size: 13px; font-style: normal; font-weight: bold; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 3px; padding-right: 3px; padding-top: 0px; text-align: left; text-decoration: none; vertical-align: top; white-space: normal; word-spacing: 0px; z-index: 1;">Term</td><td class="s1" style="background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: initial; border-left-style: none; border-left-width: 0px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(204, 204, 204); border-top-style: solid; border-top-width: 1px; color: black; font-family: arial, sans, sans-serif; font-size: 13px; font-style: normal; font-weight: bold; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 3px; padding-right: 3px; padding-top: 0px; text-align: left; text-decoration: none; vertical-align: top; white-space: normal; word-spacing: 0px; z-index: 1;">Definition</td><td class="s1" style="background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: initial; border-left-style: none; border-left-width: 0px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(204, 204, 204); border-top-style: solid; border-top-width: 1px; color: black; font-family: arial, sans, sans-serif; font-size: 13px; font-style: normal; font-weight: bold; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 3px; padding-right: 3px; padding-top: 0px; text-align: left; text-decoration: none; vertical-align: top; white-space: normal; word-spacing: 0px; z-index: 1;">Reason</td></tr>
<tr><td class="hd" style="background-color: #c8c8c8; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: initial; border-left-style: none; border-left-width: 0px; border-right-color: initial; border-right-style: initial; border-right-width: 0px; border-top-color: initial; border-top-style: none; border-top-width: 0px; font-size: 13px; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: bottom; white-space: normal; word-spacing: 0px; z-index: 1;"><div style="font-size: 0px; height: 16px; overflow-x: hidden; overflow-y: hidden; width: 0px;">
</div>
</td><td class="s2" style="background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: initial; border-top-style: none; border-top-width: 0px; color: black; font-family: arial, sans, sans-serif; font-size: 13px; font-style: normal; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 3px; padding-right: 3px; padding-top: 0px; text-align: left; text-decoration: none; vertical-align: top; white-space: normal; word-spacing: 0px; z-index: 1;">HTTP</td><td class="s3" style="background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: initial; border-left-style: none; border-left-width: 0px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: initial; border-top-style: none; border-top-width: 0px; color: black; font-family: arial, sans, sans-serif; font-size: 13px; font-style: normal; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 3px; padding-right: 3px; padding-top: 0px; text-align: left; text-decoration: none; vertical-align: top; white-space: normal; word-spacing: 0px; z-index: 1;">An application layer protocol for surfing the web.</td><td class="s3" style="background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: initial; border-left-style: none; border-left-width: 0px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: initial; border-top-style: none; border-top-width: 0px; color: black; font-family: arial, sans, sans-serif; font-size: 13px; font-style: normal; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 3px; padding-right: 3px; padding-top: 0px; text-align: left; text-decoration: none; vertical-align: top; white-space: normal; word-spacing: 0px; z-index: 1;">So we have a standard for writing and showing webpages.</td></tr>
<tr><td class="hd" style="background-color: #c8c8c8; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: initial; border-left-style: none; border-left-width: 0px; border-right-color: initial; border-right-style: initial; border-right-width: 0px; border-top-color: initial; border-top-style: none; border-top-width: 0px; font-size: 13px; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: bottom; white-space: normal; word-spacing: 0px; z-index: 1;"><div style="font-size: 0px; height: 16px; overflow-x: hidden; overflow-y: hidden; width: 0px;">
</div>
</td><td class="s2" style="background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: initial; border-top-style: none; border-top-width: 0px; color: black; font-family: arial, sans, sans-serif; font-size: 13px; font-style: normal; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 3px; padding-right: 3px; padding-top: 0px; text-align: left; text-decoration: none; vertical-align: top; white-space: normal; word-spacing: 0px; z-index: 1;">SSL</td><td class="s3" style="background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: initial; border-left-style: none; border-left-width: 0px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: initial; border-top-style: none; border-top-width: 0px; color: black; font-family: arial, sans, sans-serif; font-size: 13px; font-style: normal; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 3px; padding-right: 3px; padding-top: 0px; text-align: left; text-decoration: none; vertical-align: top; white-space: normal; word-spacing: 0px; z-index: 1;">A protocol that wraps other application layer protocols so that it's secure.</td><td class="s3" style="background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: initial; border-left-style: none; border-left-width: 0px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: initial; border-top-style: none; border-top-width: 0px; color: black; font-family: arial, sans, sans-serif; font-size: 13px; font-style: normal; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 3px; padding-right: 3px; padding-top: 0px; text-align: left; text-decoration: none; vertical-align: top; white-space: normal; word-spacing: 0px; z-index: 1;">So we can communicate across the network securely.</td></tr>
<tr><td class="hd" style="background-color: #c8c8c8; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: initial; border-left-style: none; border-left-width: 0px; border-right-color: initial; border-right-style: initial; border-right-width: 0px; border-top-color: initial; border-top-style: none; border-top-width: 0px; font-size: 13px; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: bottom; white-space: normal; word-spacing: 0px; z-index: 1;"><div style="font-size: 0px; height: 16px; overflow-x: hidden; overflow-y: hidden; width: 0px;">
</div>
</td><td class="s2" style="background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: initial; border-top-style: none; border-top-width: 0px; color: black; font-family: arial, sans, sans-serif; font-size: 13px; font-style: normal; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 3px; padding-right: 3px; padding-top: 0px; text-align: left; text-decoration: none; vertical-align: top; white-space: normal; word-spacing: 0px; z-index: 1;">HTTPS</td><td class="s3" style="background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: initial; border-left-style: none; border-left-width: 0px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: initial; border-top-style: none; border-top-width: 0px; color: black; font-family: arial, sans, sans-serif; font-size: 13px; font-style: normal; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 3px; padding-right: 3px; padding-top: 0px; text-align: left; text-decoration: none; vertical-align: top; white-space: normal; word-spacing: 0px; z-index: 1;">HTTP wrapped with SSL.</td><td class="s3" style="background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: initial; border-left-style: none; border-left-width: 0px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: initial; border-top-style: none; border-top-width: 0px; color: black; font-family: arial, sans, sans-serif; font-size: 13px; font-style: normal; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 3px; padding-right: 3px; padding-top: 0px; text-align: left; text-decoration: none; vertical-align: top; white-space: normal; word-spacing: 0px; z-index: 1;">So we can browse the web securely.</td></tr>
<tr><td class="hd" style="background-color: #c8c8c8; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: initial; border-left-style: none; border-left-width: 0px; border-right-color: initial; border-right-style: initial; border-right-width: 0px; border-top-color: initial; border-top-style: none; border-top-width: 0px; font-size: 13px; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: bottom; white-space: normal; word-spacing: 0px; z-index: 1;"><div style="font-size: 0px; height: 16px; overflow-x: hidden; overflow-y: hidden; width: 0px;">
</div>
</td><td class="s2" style="background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: initial; border-top-style: none; border-top-width: 0px; color: black; font-family: arial, sans, sans-serif; font-size: 13px; font-style: normal; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 3px; padding-right: 3px; padding-top: 0px; text-align: left; text-decoration: none; vertical-align: top; white-space: normal; word-spacing: 0px; z-index: 1;">Encryption</td><td class="s3" style="background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: initial; border-left-style: none; border-left-width: 0px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: initial; border-top-style: none; border-top-width: 0px; color: black; font-family: arial, sans, sans-serif; font-size: 13px; font-style: normal; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 3px; padding-right: 3px; padding-top: 0px; text-align: left; text-decoration: none; vertical-align: top; white-space: normal; word-spacing: 0px; z-index: 1;">Ways to scramble data.</td><td class="s3" style="background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: initial; border-left-style: none; border-left-width: 0px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: initial; border-top-style: none; border-top-width: 0px; color: black; font-family: arial, sans, sans-serif; font-size: 13px; font-style: normal; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 3px; padding-right: 3px; padding-top: 0px; text-align: left; text-decoration: none; vertical-align: top; white-space: normal; word-spacing: 0px; z-index: 1;">So Mr. Nosy doesn't know what you and me are talking about.</td></tr>
<tr><td class="hd" style="background-color: #c8c8c8; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: initial; border-left-style: none; border-left-width: 0px; border-right-color: initial; border-right-style: initial; border-right-width: 0px; border-top-color: initial; border-top-style: none; border-top-width: 0px; font-size: 13px; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: bottom; white-space: normal; word-spacing: 0px; z-index: 1;"><div style="font-size: 0px; height: 16px; overflow-x: hidden; overflow-y: hidden; width: 0px;">
</div>
</td><td class="s2" style="background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: initial; border-top-style: none; border-top-width: 0px; color: black; font-family: arial, sans, sans-serif; font-size: 13px; font-style: normal; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 3px; padding-right: 3px; padding-top: 0px; text-align: left; text-decoration: none; vertical-align: top; white-space: normal; word-spacing: 0px; z-index: 1;">Decryption</td><td class="s3" style="background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: initial; border-left-style: none; border-left-width: 0px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: initial; border-top-style: none; border-top-width: 0px; color: black; font-family: arial, sans, sans-serif; font-size: 13px; font-style: normal; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 3px; padding-right: 3px; padding-top: 0px; text-align: left; text-decoration: none; vertical-align: top; white-space: normal; word-spacing: 0px; z-index: 1;">Ways to unscramble data.</td><td class="s3" style="background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: initial; border-left-style: none; border-left-width: 0px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: initial; border-top-style: none; border-top-width: 0px; color: black; font-family: arial, sans, sans-serif; font-size: 13px; font-style: normal; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 3px; padding-right: 3px; padding-top: 0px; text-align: left; text-decoration: none; vertical-align: top; white-space: normal; word-spacing: 0px; z-index: 1;">So you know what I'm talking about.</td></tr>
<tr><td class="hd" style="background-color: #c8c8c8; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: initial; border-left-style: none; border-left-width: 0px; border-right-color: initial; border-right-style: initial; border-right-width: 0px; border-top-color: initial; border-top-style: none; border-top-width: 0px; font-size: 13px; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: bottom; white-space: normal; word-spacing: 0px; z-index: 1;"><div style="font-size: 0px; height: 16px; overflow-x: hidden; overflow-y: hidden; width: 0px;">
</div>
</td><td class="s2" style="background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: initial; border-top-style: none; border-top-width: 0px; color: black; font-family: arial, sans, sans-serif; font-size: 13px; font-style: normal; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 3px; padding-right: 3px; padding-top: 0px; text-align: left; text-decoration: none; vertical-align: top; white-space: normal; word-spacing: 0px; z-index: 1;">Keys</td><td class="s3" style="background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: initial; border-left-style: none; border-left-width: 0px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: initial; border-top-style: none; border-top-width: 0px; color: black; font-family: arial, sans, sans-serif; font-size: 13px; font-style: normal; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 3px; padding-right: 3px; padding-top: 0px; text-align: left; text-decoration: none; vertical-align: top; white-space: normal; word-spacing: 0px; z-index: 1;">Something that can encrypt and decrypt data.</td><td class="s3" style="background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: initial; border-left-style: none; border-left-width: 0px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: initial; border-top-style: none; border-top-width: 0px; color: black; font-family: arial, sans, sans-serif; font-size: 13px; font-style: normal; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 3px; padding-right: 3px; padding-top: 0px; text-align: left; text-decoration: none; vertical-align: top; white-space: normal; word-spacing: 0px; z-index: 1;">So we can encrypt and decrypt data. Duh?</td></tr>
<tr><td class="hd" style="background-color: #c8c8c8; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: initial; border-left-style: none; border-left-width: 0px; border-right-color: initial; border-right-style: initial; border-right-width: 0px; border-top-color: initial; border-top-style: none; border-top-width: 0px; font-size: 13px; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: bottom; white-space: normal; word-spacing: 0px; z-index: 1;"><div style="font-size: 0px; height: 16px; overflow-x: hidden; overflow-y: hidden; width: 0px;">
</div>
</td><td class="s2" style="background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: initial; border-top-style: none; border-top-width: 0px; color: black; font-family: arial, sans, sans-serif; font-size: 13px; font-style: normal; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 3px; padding-right: 3px; padding-top: 0px; text-align: left; text-decoration: none; vertical-align: top; white-space: normal; word-spacing: 0px; z-index: 1;">Symmetric Key</td><td class="s3" style="background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: initial; border-left-style: none; border-left-width: 0px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: initial; border-top-style: none; border-top-width: 0px; color: black; font-family: arial, sans, sans-serif; font-size: 13px; font-style: normal; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 3px; padding-right: 3px; padding-top: 0px; text-align: left; text-decoration: none; vertical-align: top; white-space: normal; word-spacing: 0px; z-index: 1;">A key that can decrypt data that was encrypted by itself.</td><td class="s3" style="background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: initial; border-left-style: none; border-left-width: 0px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: initial; border-top-style: none; border-top-width: 0px; color: black; font-family: arial, sans, sans-serif; font-size: 13px; font-style: normal; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 3px; padding-right: 3px; padding-top: 0px; text-align: left; text-decoration: none; vertical-align: top; white-space: normal; word-spacing: 0px; z-index: 1;">So you and I can use this single key to encrypt and decrypt data.</td></tr>
<tr><td class="hd" style="background-color: #c8c8c8; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: initial; border-left-style: none; border-left-width: 0px; border-right-color: initial; border-right-style: initial; border-right-width: 0px; border-top-color: initial; border-top-style: none; border-top-width: 0px; font-size: 13px; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: bottom; white-space: normal; word-spacing: 0px; z-index: 1;"><div style="font-size: 0px; height: 16px; overflow-x: hidden; overflow-y: hidden; width: 0px;">
</div>
</td><td class="s2" style="background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: initial; border-top-style: none; border-top-width: 0px; color: black; font-family: arial, sans, sans-serif; font-size: 13px; font-style: normal; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 3px; padding-right: 3px; padding-top: 0px; text-align: left; text-decoration: none; vertical-align: top; white-space: normal; word-spacing: 0px; z-index: 1;">Asymmetric Key</td><td class="s3" style="background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: initial; border-left-style: none; border-left-width: 0px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: initial; border-top-style: none; border-top-width: 0px; color: black; font-family: arial, sans, sans-serif; font-size: 13px; font-style: normal; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 3px; padding-right: 3px; padding-top: 0px; text-align: left; text-decoration: none; vertical-align: top; white-space: normal; word-spacing: 0px; z-index: 1;">A key that can only decrypt data that was encrypted by its pair.</td><td class="s3" style="background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: initial; border-left-style: none; border-left-width: 0px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: initial; border-top-style: none; border-top-width: 0px; color: black; font-family: arial, sans, sans-serif; font-size: 13px; font-style: normal; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 3px; padding-right: 3px; padding-top: 0px; text-align: left; text-decoration: none; vertical-align: top; white-space: normal; word-spacing: 0px; z-index: 1;">So it's only half the damage if one key was stolen.</td></tr>
<tr><td class="hd" style="background-color: #c8c8c8; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: initial; border-left-style: none; border-left-width: 0px; border-right-color: initial; border-right-style: initial; border-right-width: 0px; border-top-color: initial; border-top-style: none; border-top-width: 0px; font-size: 13px; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: bottom; white-space: normal; word-spacing: 0px; z-index: 1;"><div style="font-size: 0px; height: 16px; overflow-x: hidden; overflow-y: hidden; width: 0px;">
</div>
</td><td class="s2" style="background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: initial; border-top-style: none; border-top-width: 0px; color: black; font-family: arial, sans, sans-serif; font-size: 13px; font-style: normal; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 3px; padding-right: 3px; padding-top: 0px; text-align: left; text-decoration: none; vertical-align: top; white-space: normal; word-spacing: 0px; z-index: 1;">Public/Private Key</td><td class="s3" style="background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: initial; border-left-style: none; border-left-width: 0px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: initial; border-top-style: none; border-top-width: 0px; color: black; font-family: arial, sans, sans-serif; font-size: 13px; font-style: normal; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 3px; padding-right: 3px; padding-top: 0px; text-align: left; text-decoration: none; vertical-align: top; white-space: normal; word-spacing: 0px; z-index: 1;">An asymmetric key pair such that if one encrypts, the other can decrypt.</td><td class="s3" style="background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: initial; border-left-style: none; border-left-width: 0px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: initial; border-top-style: none; border-top-width: 0px; color: black; font-family: arial, sans, sans-serif; font-size: 13px; font-style: normal; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 3px; padding-right: 3px; padding-top: 0px; text-align: left; text-decoration: none; vertical-align: top; white-space: normal; word-spacing: 0px; z-index: 1;">So I can use one key to encrypt data, knowing that you can use the other key to decrypt data.</td></tr>
<tr><td class="hd" style="background-color: #c8c8c8; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: initial; border-left-style: none; border-left-width: 0px; border-right-color: initial; border-right-style: initial; border-right-width: 0px; border-top-color: initial; border-top-style: none; border-top-width: 0px; font-size: 13px; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: bottom; white-space: normal; word-spacing: 0px; z-index: 1;"><div style="font-size: 0px; height: 16px; overflow-x: hidden; overflow-y: hidden; width: 0px;">
</div>
</td><td class="s2" style="background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: initial; border-top-style: none; border-top-width: 0px; color: black; font-family: arial, sans, sans-serif; font-size: 13px; font-style: normal; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 3px; padding-right: 3px; padding-top: 0px; text-align: left; text-decoration: none; vertical-align: top; white-space: normal; word-spacing: 0px; z-index: 1;">Public Key</td><td class="s3" style="background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: initial; border-left-style: none; border-left-width: 0px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: initial; border-top-style: none; border-top-width: 0px; color: black; font-family: arial, sans, sans-serif; font-size: 13px; font-style: normal; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 3px; padding-right: 3px; padding-top: 0px; text-align: left; text-decoration: none; vertical-align: top; white-space: normal; word-spacing: 0px; z-index: 1;">One key in the Public/Private Key pair that the owner decides to make public.</td><td class="s3" style="background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: initial; border-left-style: none; border-left-width: 0px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: initial; border-top-style: none; border-top-width: 0px; color: black; font-family: arial, sans, sans-serif; font-size: 13px; font-style: normal; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 3px; padding-right: 3px; padding-top: 0px; text-align: left; text-decoration: none; vertical-align: top; white-space: normal; word-spacing: 0px; z-index: 1;">So people can write to me securely (because only I have the private key to decrypt the data).</td></tr>
<tr><td class="hd" style="background-color: #c8c8c8; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: initial; border-left-style: none; border-left-width: 0px; border-right-color: initial; border-right-style: initial; border-right-width: 0px; border-top-color: initial; border-top-style: none; border-top-width: 0px; font-size: 13px; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: bottom; white-space: normal; word-spacing: 0px; z-index: 1;"><div style="font-size: 0px; height: 16px; overflow-x: hidden; overflow-y: hidden; width: 0px;">
</div>
</td><td class="s2" style="background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: initial; border-top-style: none; border-top-width: 0px; color: black; font-family: arial, sans, sans-serif; font-size: 13px; font-style: normal; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 3px; padding-right: 3px; padding-top: 0px; text-align: left; text-decoration: none; vertical-align: top; white-space: normal; word-spacing: 0px; z-index: 1;">Private Key</td><td class="s3" style="background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: initial; border-left-style: none; border-left-width: 0px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: initial; border-top-style: none; border-top-width: 0px; color: black; font-family: arial, sans, sans-serif; font-size: 13px; font-style: normal; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 3px; padding-right: 3px; padding-top: 0px; text-align: left; text-decoration: none; vertical-align: top; white-space: normal; word-spacing: 0px; z-index: 1;">One key in the Public/Private Key pair that the owner decides to keep as a secret.</td><td class="s3" style="background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: initial; border-left-style: none; border-left-width: 0px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: initial; border-top-style: none; border-top-width: 0px; color: black; font-family: arial, sans, sans-serif; font-size: 13px; font-style: normal; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 3px; padding-right: 3px; padding-top: 0px; text-align: left; text-decoration: none; vertical-align: top; white-space: normal; word-spacing: 0px; z-index: 1;">So I can assure people that I was the one who sent the data. (Only I have the private key to encrypt the data. You can verify it by decrypting it with my public key.)</td></tr>
<tr><td class="hd" style="background-color: #c8c8c8; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: initial; border-left-style: none; border-left-width: 0px; border-right-color: initial; border-right-style: initial; border-right-width: 0px; border-top-color: initial; border-top-style: none; border-top-width: 0px; font-size: 13px; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: bottom; white-space: normal; word-spacing: 0px; z-index: 1;"><div style="font-size: 0px; height: 16px; overflow-x: hidden; overflow-y: hidden; width: 0px;">
</div>
</td><td class="s2" style="background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: initial; border-top-style: none; border-top-width: 0px; color: black; font-family: arial, sans, sans-serif; font-size: 13px; font-style: normal; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 3px; padding-right: 3px; padding-top: 0px; text-align: left; text-decoration: none; vertical-align: top; white-space: normal; word-spacing: 0px; z-index: 1;">Hash</td><td class="s3" style="background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: initial; border-left-style: none; border-left-width: 0px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: initial; border-top-style: none; border-top-width: 0px; color: black; font-family: arial, sans, sans-serif; font-size: 13px; font-style: normal; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 3px; padding-right: 3px; padding-top: 0px; text-align: left; text-decoration: none; vertical-align: top; white-space: normal; word-spacing: 0px; z-index: 1;">A small computed number that represents a bigger chunk of data, such that even the smallest change to the big chunk of data can result in a different hash.</td><td class="s3" style="background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: initial; border-left-style: none; border-left-width: 0px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: initial; border-top-style: none; border-top-width: 0px; color: black; font-family: arial, sans, sans-serif; font-size: 13px; font-style: normal; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 3px; padding-right: 3px; padding-top: 0px; text-align: left; text-decoration: none; vertical-align: top; white-space: normal; word-spacing: 0px; z-index: 1;">So if you knew this data is supposed to have hash X, but you computed the hash from the actual data and got Y, it means somebody changed the data.</td></tr>
<tr><td class="hd" style="background-color: #c8c8c8; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: initial; border-left-style: none; border-left-width: 0px; border-right-color: initial; border-right-style: initial; border-right-width: 0px; border-top-color: initial; border-top-style: none; border-top-width: 0px; font-size: 13px; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: bottom; white-space: normal; word-spacing: 0px; z-index: 1;"><div style="font-size: 0px; height: 16px; overflow-x: hidden; overflow-y: hidden; width: 0px;">
</div>
</td><td class="s2" style="background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: initial; border-top-style: none; border-top-width: 0px; color: black; font-family: arial, sans, sans-serif; font-size: 13px; font-style: normal; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 3px; padding-right: 3px; padding-top: 0px; text-align: left; text-decoration: none; vertical-align: top; white-space: normal; word-spacing: 0px; z-index: 1;">Digital Signature</td><td class="s3" style="background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: initial; border-left-style: none; border-left-width: 0px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: initial; border-top-style: none; border-top-width: 0px; color: black; font-family: arial, sans, sans-serif; font-size: 13px; font-style: normal; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 3px; padding-right: 3px; padding-top: 0px; text-align: left; text-decoration: none; vertical-align: top; white-space: normal; word-spacing: 0px; z-index: 1;">A hash encrypted by the private key.</td><td class="s3" style="background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: initial; border-left-style: none; border-left-width: 0px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: initial; border-top-style: none; border-top-width: 0px; color: black; font-family: arial, sans, sans-serif; font-size: 13px; font-style: normal; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 3px; padding-right: 3px; padding-top: 0px; text-align: left; text-decoration: none; vertical-align: top; white-space: normal; word-spacing: 0px; z-index: 1;">So you know that the hash itself is not changed (only I can encrypt the hash with my private key).</td></tr>
<tr><td class="hd" style="background-color: #c8c8c8; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: initial; border-left-style: none; border-left-width: 0px; border-right-color: initial; border-right-style: initial; border-right-width: 0px; border-top-color: initial; border-top-style: none; border-top-width: 0px; font-size: 13px; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: bottom; white-space: normal; word-spacing: 0px; z-index: 1;"><div style="font-size: 0px; height: 16px; overflow-x: hidden; overflow-y: hidden; width: 0px;">
</div>
</td><td class="s2" style="background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: initial; border-top-style: none; border-top-width: 0px; color: black; font-family: arial, sans, sans-serif; font-size: 13px; font-style: normal; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 3px; padding-right: 3px; padding-top: 0px; text-align: left; text-decoration: none; vertical-align: top; white-space: normal; word-spacing: 0px; z-index: 1;">Public Key Infrastructure (PKI)</td><td class="s3" style="background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: initial; border-left-style: none; border-left-width: 0px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: initial; border-top-style: none; border-top-width: 0px; color: black; font-family: arial, sans, sans-serif; font-size: 13px; font-style: normal; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 3px; padding-right: 3px; padding-top: 0px; text-align: left; text-decoration: none; vertical-align: top; white-space: normal; word-spacing: 0px; z-index: 1;">A group of technologies to help verify public keys.</td><td class="s3" style="background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: initial; border-left-style: none; border-left-width: 0px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: initial; border-top-style: none; border-top-width: 0px; color: black; font-family: arial, sans, sans-serif; font-size: 13px; font-style: normal; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 3px; padding-right: 3px; padding-top: 0px; text-align: left; text-decoration: none; vertical-align: top; white-space: normal; word-spacing: 0px; z-index: 1;">So that you know that the public key is actually mine and not an impersonator.</td></tr>
<tr><td class="hd" style="background-color: #c8c8c8; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: initial; border-left-style: none; border-left-width: 0px; border-right-color: initial; border-right-style: initial; border-right-width: 0px; border-top-color: initial; border-top-style: none; border-top-width: 0px; font-size: 13px; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: bottom; white-space: normal; word-spacing: 0px; z-index: 1;"><div style="font-size: 0px; height: 16px; overflow-x: hidden; overflow-y: hidden; width: 0px;">
</div>
</td><td class="s2" style="background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: initial; border-top-style: none; border-top-width: 0px; color: black; font-family: arial, sans, sans-serif; font-size: 13px; font-style: normal; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 3px; padding-right: 3px; padding-top: 0px; text-align: left; text-decoration: none; vertical-align: top; white-space: normal; word-spacing: 0px; z-index: 1;">Certificate Authority (CA)</td><td class="s3" style="background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: initial; border-left-style: none; border-left-width: 0px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: initial; border-top-style: none; border-top-width: 0px; color: black; font-family: arial, sans, sans-serif; font-size: 13px; font-style: normal; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 3px; padding-right: 3px; padding-top: 0px; text-align: left; text-decoration: none; vertical-align: top; white-space: normal; word-spacing: 0px; z-index: 1;">Somebody who you trust.</td><td class="s3" style="background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: initial; border-left-style: none; border-left-width: 0px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: initial; border-top-style: none; border-top-width: 0px; color: black; font-family: arial, sans, sans-serif; font-size: 13px; font-style: normal; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 3px; padding-right: 3px; padding-top: 0px; text-align: left; text-decoration: none; vertical-align: top; white-space: normal; word-spacing: 0px; z-index: 1;">So you can believe anything that the CA digitally signed.</td></tr>
<tr><td class="hd" style="background-color: #c8c8c8; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: initial; border-left-style: none; border-left-width: 0px; border-right-color: initial; border-right-style: initial; border-right-width: 0px; border-top-color: initial; border-top-style: none; border-top-width: 0px; font-size: 13px; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: bottom; white-space: normal; word-spacing: 0px; z-index: 1;"><div style="font-size: 0px; height: 16px; overflow-x: hidden; overflow-y: hidden; width: 0px;">
</div>
</td><td class="s2" style="background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: initial; border-top-style: none; border-top-width: 0px; color: black; font-family: arial, sans, sans-serif; font-size: 13px; font-style: normal; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 3px; padding-right: 3px; padding-top: 0px; text-align: left; text-decoration: none; vertical-align: top; white-space: normal; word-spacing: 0px; z-index: 1;">Digital Certificate</td><td class="s3" style="background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: initial; border-left-style: none; border-left-width: 0px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: initial; border-top-style: none; border-top-width: 0px; color: black; font-family: arial, sans, sans-serif; font-size: 13px; font-style: normal; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 3px; padding-right: 3px; padding-top: 0px; text-align: left; text-decoration: none; vertical-align: top; white-space: normal; word-spacing: 0px; z-index: 1;">A document containing my public key, digitally signed by a CA.</td><td class="s3" style="background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: initial; border-left-style: none; border-left-width: 0px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: initial; border-top-style: none; border-top-width: 0px; color: black; font-family: arial, sans, sans-serif; font-size: 13px; font-style: normal; letter-spacing: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 3px; padding-right: 3px; padding-top: 0px; text-align: left; text-decoration: none; vertical-align: top; white-space: normal; word-spacing: 0px; z-index: 1;">So I can give it to you and you can verify if it's really me or not.</td></tr>
</tbody></table>
<br />
Now that all the terms are hopefully understood. Here's basically how HTTPS works. I'll call this protocol Mini-HTTPS because a lot of detail is skipped and is not exactly HTTPS. However, understanding Mini-HTTPS will definitely help you understand HTTPS if you want to.<br />
<ol>
<li>A user downloads Chrome. Chrome comes with a lot of digital certificates from CA's you trust. You trust them so much that you allow them to be shipped with Chrome. The digital certificates contain the CA's public key and is signed by the CA itself.</li>
<li>You open Chrome and go to https://plus.google.com.</li>
<li>Chrome detects that the URL starts with "https" so it needs some security checking.</li>
<li>Chrome sends, "verify yourself" to the server.</li>
<li>The server replies with, "here's my digital certificate, along with its hash encrypted by a well known CA (digitally signed)" It's like when you were a kid, if your Dad says you can trust somebody, you believe him.</li>
<li>Chrome verifies the certificate.</li>
<ol>
<li>It tries to decrypt the digital signature (the hash encrypted by the CA) in the certificate. Chrome can do this because Chrome has the CA's public key from (1).</li>
<li>If it can decrypt it, it means that the CA really signed this (because only the CA has the private key to sign this.)</li>
<li>Since the CA really signed the certificate, it knows that the server can be trusted. Otherwise, the server wouldn't be able to get a signature from the CA.</li>
<li>The resulting decrypted hash is untampered for sure because otherwise it wouldn't be able to decrypt it successfully.</li>
<li>It computes the certificate's hash by itself and expects to get the same hash as the decrypted hash from (6.4). If they're different, it knows the certificate has been tampered with.</li>
<li>It now trusts the the server is really https://plus.google.com because its certificate is "CA approved" and untampered with.</li>
</ol>
<li>Since Chrome trusts the server, it can confidently use the server's public key shipped with the certificate.</li>
<li>Chrome creates a symmetric key to be used for the entire session. It doesn't use asymmetric keys because it's more expensive. A one time symmetric key would be secure enough because if the key was stolen, only this session will be affected.</li>
<li>It encrypts the symmetric key with the server's public key and sends it to the server. (Only the server can see this symmetric key because only the server has the private key.)</li>
<li>This symmetric key is used to encrypt normal HTTP traffic through out this session (session is defined as "everything until the client says it's done").</li>
<li>When the client is done with this session, it sends "close session" to the server.</li>
<li>No more HTTP encryption between the client and server beyond this point.</li>
</ol>
Hmmm, maybe that wasn't too concise, but I think it was a good shot. Let me know if I can make anything clearer.Amarin Phaosawasdihttp://www.blogger.com/profile/11497556893338926041noreply@blogger.com0