Hit a little snag while initializing boot2docker:
1 2 |
|
lsof shows it’s CrashPlan conflicting:
1 2 3 |
|
Seems like Docker will be changing their default port soon. In the meantime, here’s how to change CrashPlan backup service’s port on OS X:
Hit a little snag while initializing boot2docker:
1 2 |
|
lsof shows it’s CrashPlan conflicting:
1 2 3 |
|
Seems like Docker will be changing their default port soon. In the meantime, here’s how to change CrashPlan backup service’s port on OS X:
A brief discussion of the check digit algorithm for matriculation numbers / NUSNET IDs prefixed by either U or A, accompanied by a JavaScript implementation and a client-side calculator.
Initiated due to a collaboration with Camillus on a bookmarklet which involved mapping NUSNET IDs to matriculation numbers for use with a [redacted] endpoint – I initially helped with the U prefix case, as it is more familiar to old farts like me.
Various equivalent forms of the algorithm have been discussed under NUS Matriculation Number Checkdigit, NUS Matriculation Number Checkdigit 2 and Validate Your NUS Undergraduate Matric Number. Also, there is a server-side NUS Matric Resolver by Huy Nguyen and a Matric.js gist by Joel Low.
Though correct, most of them involve extraneous steps, especially for U-prefixed matriculation numbers. It kinda bugged me, so I worked out a more elegant formulation during a short plane ride last week.
For U-prefixed NUSNET IDs such as u0906931
, discard the third digit – u0906931, resulting in u096931
, which is the corresponding matriculation number without its check digit.
Let the last 6 digits be d1 to d6. Compute the weighted sum s = w1 × d1 + … + w6 × d6 using the corresponding weights:
Prefix | w1 | w2 | w3 | w4 | w5 | w6 |
---|---|---|---|---|---|---|
U | 0 | 1 | 3 | 1 | 2 | 7 |
A | 1 | 1 | 1 | 1 | 1 | 1 |
Find check digit corresponding to the remainder of the weighted sum divided by 13 (sum modulo 13):
Remainder | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Check Digit | Y | X | W | U | R | N | M | L | J | H | E | A | B |
The weights for A-prefixed matriculation numbers are all 1, i.e. the weighted sum is simply equal to the sum of the digits themselves, so their specific algorithm could be simplified further. However, it is formulated like this to unify the algorithms for both current prefixes, as well as possibly accommodate future prefixes with different weights.
If this scheme and blog post are somehow still surviving in the far future, you would have to use all 7 digits instead of the last 6, when there have been over 1 million NUS undergraduates since 2010.
Historical note: The U prefix applied to undergraduates from AY2009/10 and before; the A prefix applies to undergraduates from AY2010/11 and after.
Could come in handy for quickly finding project mates’ matriculation numbers.
When you come to a fork in the road, take it!
Yogi Berra
Q1: How much control and authority would you have given to this fourth voice in our choice of platforms (HTML5/native iOS)?
Given that it was both the fourth voice and the sole coder who would be implementing the bulk of the code, they should have the most say, as they are the ones who understand best and have to bear most of the brunt of this particular platform choice.
That said, I gathered that the fourth voice was leaning more towards iOS since it was the platform he had greater familiarity with, while I assume the other coder was not so keen on picking up a new platform, and vice versa. I think that if the one who is more experienced with their preferred platform sets up some boilerplate code which others can learn by example from, and is ready to give pointers where needed, picking up a new platform could be approximated as a fixed cost.
Hence, for pragmatic reasons, given that the fourth voice would be spending say about 40% of the time the other coder would be spending on this project, it would probably have been more efficient to let the fourth voice have their choice of platform, as the other coder has more time to get up to speed on the platform, and then the actual coding workload would be spread more evenly.
Also, I feel that since the fourth voice is going out of their way to help another group, he should be given some sense of ownership in the project as well, instead of being treated more like just a helping hand. There is always the fear that he might bail when the going gets tough, but if you were in such dire straits already, it might be better to err on the side of trust instead of alienating him and risk losing someone who can potentially help to save your project.
Q2: With the deadline just 2 weeks away, how would you, as project manager, have resolved this problem if it were to occur within the team?
Putting myself into the project manager’s shoes is pretty hard, as it is quite inconceivable to have allowed the problem to drag on for so long in the first place, or even have let it become a problem in the first place. I suppose that this originally might have also been a way to hedge their bets, since they were not sure of the commitment level for their external help. However, the same answer applies whether the deadline was just 2 weeks away, or 7 weeks away.
If the contention is too personal, and you do not want to be the one to make the hard decision, then flip a coin and leave it up to fate. Any choice is better than none. The point is to get from idea to product as quickly as you can. The choice of platform is not going to affect the validation of your product much, if at all, at that stage. Evaluating platforms by building separate prototypes would be more appropriate for a bigger company, which had the resources to spare.
Q3: What are some of the issues that we presented that could have happened to any team? List down 3, and talk about how you would have resolved these issues.
Putting off tough decisions
Nobody likes to be the one to make them, which is why you need to have a project manager who is willing to put their foot down when it matters, and trust in their decisions even when you might not be on the side which agrees with them.
Much of the time, if the decision is contentious, there are probably good reasons for both sides of the argument. Even if it turns out in hindsight that going the other way might have been better, the margin would not be that big anyway, and making the decision early would have made up for it by saving time that could be put towards making other aspects better.
Wasting resources
Unless you have prescient vision, some waste is probably inevitable. Taking an Agile / Lean approach helps to minimize waste by failing fast, so that you can recognize that a change of direction is warranted as soon as possible. This could be a change of direction for the whole project, or all the way down to individual implementation details. Having smaller iterative development phases lets you make these course corrections en route, instead of only realizing near the end that you are hopelessly off course.
Making technology decisions
This is distinct from the tough decisions above, which refer more towards decisions which have some degree of interpersonal conflict involved. Even though in the case presented, one of these tough decisions did involve a technology decision, technology decisions are generally not this bloody, editor wars aside.
However, especially in more developer-heavy teams, it’s easy to fall prey to what I’m going to call “Shiny New Framework Syndrome”. For example, in Assignment 1, the general consensus in my team was: Why stick to what we know? Let’s try some stuff none of us have any experience with so that we have a learning experience!“. It was a learning experience indeed.
New frameworks and tools are interesting, but despite their advertised promise, they are never going to just drop right into place and solve all your problems. We would like to think that we are aware of the costs involved in trying out new technology and can account for it, but we all know how developers usually are with estimates.
Also, it is sometimes easy to get caught up in cross-comparing frameworks so that you can pick the perfect one for your project. Next thing you know, you’re writing a comprehensive benchmark to help you pick.
Just pick one and get some real work done. This is a reminder to myself as well – I have definitely been guilty of Shiny New Framework Syndrome on various occasions too.
How to Win Friends and
Influence PeopleGet Laid
Certainly an attention-grabbing way of starting of the presentation on Momo, especially to a class mostly full of guys. Definitely the most entertaining presentation of the evening as well. In fact, the entertaining points stuck in my memory so much, that I was hard-pressed to find the most important three points, but here goes:
Momo being a “magical tool to get laid (约炮神器)”
In all seriousness, this is an important point. It was mentioned as such in a popular viral video with 5+ million hits, and apparently that is its common reputation – as an app for casual hook-ups, despite its founders maintaining that it can lead to serious relationships and even marriages.
Such startups tap on very primal (and social) needs, and though “magical tool” may be hyperbolic, a service that even approached that magical status could be very lucrative indeed. The fact that Momo received $40 million in series B funding, with a market valuation of over $100 million, and big names like Alibaba Group and Netease and Sina Corp veterans being involved, points to their belief in this.
Chinese prostitutes learning how to use Momo to attract clients
In fact, there was a leaked video of someone lecturing Chinese prostitutes on how to use social services like Momo and WeChat to attract and retain customers, and during the Q&A session, someone who had used Momo before mentioned that they had received a lot of “spam” from said prostitutes selling their services.
Well, one man’s spam is another man’s happy ending. Seems like Momo has commendably managed to capture every segment of their market – if you used Momo, one way or another, you would be able to get laid, no matter your social skills.
Momo’s technical implementation
I think it showed the depth the team went into, that they actually did packet sniffing to figure out what technologies Momo uses behind the scenes.
Most of stack is pretty run-of-the-mill as far as mobile location-based apps go, and it uses the XMPP standard, which other chat apps like LINE, WeChat, and WhatsApp also leverage. Google Hangouts is the notable exception among popular recent chat apps, having its own proprietary protocol. However, it is Google, which can afford to develop its own.
As for other startups, this is important as it shows that technical implementation is probably one of the smaller concerns, and most apps in the space are using mostly the same underlying technology.
XMPP has many free and well-honed libraries and server implementations, so it is relatively trivial technically to put together all these similar chat apps – the important difference is their focus.
Of course, this would not be a fair application critique, if I had not actually tried out the app myself. I put up a reasonably nice picture, and in the past few hours I’ve had a total of.. 1 female, aged 20, contacting me – with 2 smilies. Whoopie doo.
Just want to add that I’m very thankful for our evaluators’ feedback on our presentation.
John and Shubham had kindly offered to take on my part of the presentation, or even the full presentation, and honestly I was sorely tempted. After all, many other teams were presenting with less than their full complement, and there were good reasons to, given the presentation format.
However, as mentioned in What I Hope to Learn in CS3216, I wanted to face down my fears regarding presentations, and I’m really glad I did.
Was still horribly nervous (could everyone tell?) while speaking, but I’m very encouraged by the positive feedback regarding my sections – it really made my day! [=
The talk on growth hacking by Bjorn Lee, co-founder of Stickery was rather refreshing, especially after all the engineering-focused talks we’ve been having.
I found his section on forum seeding one of the most applicable for our app, if we’re going to be taking it beyond the first assignment. Perhaps not quite the way they did it, but there are very relevant communities for our initial target audience (women), like CozyCot and Flowerpod, which could be useful for marketing.
Another thing that struck me was how they gathered really high-quality feedback from mothers. Similar to them, our team is made up of all guys, so we may not have a first-hand understanding of our target market, but we can certainly try to make up for that by going out there and talking to our users, which should be easier now that our app’s at an MVP(ish) stage.
On a related note, I’ve been researching on BillPin for Monday’s presentation, and they pulled off an impressive growth hack back in April by buying over another bill-splitting service, BillMonk.
It’s rare to see a 6 month old startup acquiring an 8 year old rival with around 50 times the number of users. Not only did they get an instant massive boost to their user base, but also gained some buzz from the usual tech news websites, and valuable usage data.
Probably not something we can mimic directly, but their clever and unorthodox approach aptly illustrates how far you could move beyond the mold in order to acquire traction.
Note: Results may vary, depending on distance from your Git servers. In my
completely unscientific benchmarks using time
, after the following steps,
git pull
went from ~5s, using GitHub, to ~0.1s, using EC2 on AWS Singapore.
1 2 3 4 |
|
5 seconds just to tell you that your Git repository is already up-to-date? Unacceptable.
In Singapore, the round-trip time to github.com is ~250ms. Establishing an SSH
connection every time you perform a Git operation costs many round-trips, but
you can keep them around and reuse them with the following lines in
~/.ssh/config
:
1 2 3 |
|
ControlMaster auto
enables the sharing of multiple SSH sessions over a single
network connection, and auto-creating a master connection if it does not already
exist.
ControlPath /tmp/%r@%h:%p
specifies the path to the control socket used for
connection sharing. %r
will be substituted by the remote login username, %h
by the target host name and %p
by the port.
ControlPersist yes
keeps the master connection open in the background
indefinitely.
With this, git pull
goes down to ~1s, a 5x improvement. Of course, this speeds
up your other repeated SSH connections too!
For sub-second Git remote operations, you’re going to need a server with low
latency. (Imagine, when physically working together, you could git pull
the
very moment someone says “Pushed!”.)
However, you can still have all the niceties GitHub provides, by automatically pushing to GitHub from your server. There are several alternatives for keeping GitHub updated, like using cron jobs or multiple remotes, but I think using a post-receive hook is the most elegant solution.
On your server, set up a GitHub deploy key:
1 2 |
|
Go to your target repository’s Settings –> Deploy Keys –> Add deploy key and paste the public key in and submit. Then you can mirror your repository:
1
|
|
To automatically to mirror to GitHub after you’ve pushed, set up a
Git hook at
hooks/post-receive
:
1 2 |
|
Your Git client won’t disconnect till the script has completed, so a simple
git push --mirror
would defeat the purpose of setting this up, since you’d be
adding on GitHub’s latency to your pushes again. So, we background the process
and keep it running after logging out using
nohup, and redirect all I/O streams to
/dev/null
to prevent SSH from hanging on logout.
Make the hook executable:
1
|
|
Now you can use your new Git mirror locally. Assuming you have added the server’s private key to ssh-agent:
1
|
|
You could clone it:
1
|
|
Or change your existing repository’s remote:
1
|
|
Taken alone, using the Git mirror brings git pull
down to ~1.2s. When combined
with SSH connection sharing:
1 2 3 4 |
|
0.1s Git remote operations. Awesome.
Throw together a bunch of awesome hackerish people who love to solve problems and build stuff, and you’re pretty much guaranteed to learn bucketloads – even in unexpected areas.
I try to learn as much as possible from every experience, so my short cop-out answer would be: keeping an open mind and not set too many mental boundaries on what I hope to learn.
That said, there are a few specific aspects in which I hope to learn more:
Working with Others: Discussed with a friend the merits of joining CS3216 vs. working hard on external projects myself, or with others. Flying (semi)solo does have its perks, but having the opportunity to work with a diverse set of people who share the same kind of dreams is probably a better way to level-up together. Rather like an MMORPG.
Product and UX design: I’d like to understand more deeply what users need and want. Being good at both designing and developing is so rare that finding such people is often compared to hunting unicorns. Lofty goal to work towards perhaps, but any efforts I put towards getting better at design would help me be a more well-rounded developer. Since CS3216 isn’t just for pure coders, I hope to have the chance to work with a good designer or two – I think I’d learn a lot.
Presentation and Pitching: Not my strongest suit, and something I’ve to face my fears in. Just gotta keep at it, and believe.
Writing and Blogging: Well, it’s part of the requirements, but more than that, I do hope it serves as a jumpstart to return to blogging more and finding back my personal writing voice. That’s partly why I got a whole new domain dedicated solely to blogging – interrobeng.com. Not just because it’s an obscure typographic pun. Really.
All that and of course, a lot of chances to practice and hone my craft, on the long road towards mastery. Bring it on.