Wednesday, April 25, 2012

Tour de Babel

**This post is from: here.

This is my whirlwind languages tour — the one I was going to write for the Amazon Developers Journal this month, but couldn't find a way to do it that was... presentable.
For one thing, I lapse occasionally into coarseness and profanity here, so it wasn't appropriate for an official-ish Amazon publication. Instead, I'm stuffing it into my blog, which nobody reads. Except for you. Yep, just you. Hiya.
For another, it's really a work in progress, just a few snippets here and there, not polished at all. Another great reason to make it a blog entry. Doesn't have to be good, or complete. It's just what I've got today. Enjoy!
My whirlwind tour will cover C, C++, Lisp, Java, Perl, (all languages we use at Amazon), Ruby (which I just plain like), and Python, which is in there because — well, no sense getting ahead of ourselves, now.

C

You just have to know C. Why? Because for all practical purposes, every computer in the world you'll ever use is a von Neumann machine, and C is a lightweight, expressive syntax for the von Neumann machine's capabilities.
The von Neumann architecture is the standard computer architecture you use every day: a CPU, RAM, a disk, a bus. Multi-CPU doesn't really change it that much. The von Neumann machine is a convenient, cost-effective, 1950s realization of a Turing Machine, which is a famous abstract model for performing computations.
There are other kinds of machines too. For instance, there are Lisp Machines, which are convenient 1950s realizations of Lisp, a programming language notation based on the lambda calculus, which is another model for performing computations. Unlike Turing machines, the lambda calculus can be read and written by humans. But the two models are equivalent in power. They both model precisely what computers are capable of.
Lisp Machines aren't very common though, except at garage sales. von Neumann machines won the popularity race. There are various other kinds of computers, such as convenient realizations of neural networks or cellular automata, but they're nowhere as popular either, at least not yet.
So you have to know C.
You also have to know C because it's the language that Unix is written in, and happens also to be the language that Windows and virtually all other operating systems are written in, because they're OSes for von Neumann machines, so what else would you use? Anything significantly different from C is going to be too far removed from the actual capabilities of the hardware to perform well enough, at least for an OS — at least in the last century, which is when they were all written.
You should also know Lisp. You don't have to use it for real work, although it comes in quite handy for lots of GNU applications. In particular, you should learn Scheme, which is a small, pure dialect of Lisp. The GNU version is calledGuile.
They teach Scheme at MIT and Berkeley to new students for a semester or two, and the students have absolutely no clue as to why they're learning this weird language. It's a lousy first language, to be honest, and probably a lousy second one too. You should learn it, eventually, and not as your first or second language.

It's hard, though. It's a big jump. It's not sufficient to learn how to write C-like programs in Lisp. That's pointless. C and Lisp stand at opposite ends of the spectrum; they're each great at what the other one sucks at.
If C is the closest language to modeling how computers work, Lisp is the closest to modeling how computation works. You don't need to know a lot of Lisp, really. Stick with Scheme, since it's the simplest and cleanest. Other Lisps have grown into big, complex programming environments, just like C++ and Java have, with libraries and tools and stuff.That, you don't need to know. But you should be able to write programs in Scheme. If you can make your way through all the exercises in The Little Schemer and The Seasoned Schemer, you'll know enough, I think.

But you choose a language for day-to-day programming based on its libraries, documentation, tools support, OS integration, resources, and a host of other things that have very little to do with how computers work, and a whole lot to do with how people work.
People still write stuff in straight C. Lots of stuff. You should know it!

C++

C++ is the dumbest language on earth, in the very real sense of being the least sentient. It doesn't know about itself. It is not introspective. Neither is C, but C isn't "Object-Oriented", and object orientation is in no small measure about making your programs know about themselves. Objects are actors. So OO languages need to have runtime reflection and typing. C++ doesn't, not really, not that you'd ever use.
As for C: it's so easy to write a C compiler that you can build tools on top of C that act like introspection. C++, on the other hand, is essentially un-parseable, so if you want to write smart tools that can, for example, tell you the signatures of your virtual functions, or refactor your code for you, you're stuck using someone else's toolset, since yousure as heck aren't gonna parse it. And all the toolsets for parsing C++ out there just plain suck.
C++ is dumb, and you can't write smart systems in a dumb language. Languages shape the world. Dumb languages make for dumb worlds.
All of computing is based on abstractions. You build higher-level things on lower-level ones. You don't try to build a city out of molecules. Trying to use too low-level an abstraction gets you into trouble.
We are in trouble.
The biggest thing you can reasonably write in C is an operating system, and they're not very big, not really. They look big because of all their apps, but kernels are small.
The biggest thing you can write in C++ is... also an operating system. Well, maybe a little bigger. Let's say three times bigger. Or even ten times. But operating system kernels are at most, what, maybe a million lines of code? So I'd argue the biggest system you can reasonably write in C++ is maybe 10 million lines, and then it starts to break down and become this emergent thing that you have no hope of controlling, like the plant in Little Shop of Horrors. Feeeeeed meeeeeee...
If you can get it to compile by then, that is.
We have 50 million lines of C++ code. No, it's more than that now. I don't know what it is anymore. It was 50 million last Christmas, nine months ago, and was expanding at 8 million lines a quarter. The expansion rate was increasing as well. Ouch.
Stuff takes forever to do around here. An Amazon engineer once described our code base as "a huge mountain of poop, the biggest mountain you've ever seen, and your job is to crawl into the very center of it, every time you need to fix something."
That was four years ago, folks. That engineer has moved on to greener pastures. Too bad; he was really good.
It's all C++'s fault. Don't argue. It is. We're using the dumbest language in the world. That's kind of meta-dumb, don't you think?
With that said, it is obviously possible to write nice C++ code, by which I mean, code that's mostly C, with some C++ features mixed in tastefully and minimally. But it almost never happens. C++ is a vast playground, and makes you feel smart when you know all of it, so you're always tempted to use all of it. But that's really, really hard to do well, because it's such a crap language to begin with. In the end, you just make a mess, even if you're good.
I know, this is Heresy, with a capital-'H'. Whatever. I loved C++ in college, because it's all I knew. When I heard that my languages prof, Craig Chambers, absolutely detested C++, I thought: "Why? I like it just fine." And when I heard that the inventor of STL was on record as saying he hated OOP, I thought he was cracked. How could anyone hate OOP, especially the inventor of STL?
Familiarity breeds contempt in most cases, but not with computer languages. You have to become an expert with abetter language before you can start to have contempt for the one you're most familiar with.
So if you don't like what I'm saying about about C++, go become an expert at a better language (I recommend Lisp), and then you'll be armed to disagree with me. You won't, though. I'll have tricked you. You won't like C++ anymore, and you might be irked that I tricked you into disliking your ex-favorite language. So maybe you'd better just forget about all this. C++ is great. Really. It's just ducky. Forget what I said about it. It's fine.

Lisp

(I'm betting this next section will astonish you, even if you've been here a while.)
When Amazon got its start, we had brilliant engineers. I didn't know all of them, but I knew some of them.
Examples? Shel Kaphan. Brilliant. Greg Linden. Brilliant. Eric Benson. Independently famous in his own right, before he ever even came to Amazon. Also brilliant.
They wrote the Obidos webserver. Obidos made Amazon successful. It was only later that poop-making engineers and web devs, frontend folks mostly — schedule-driven people who could make their managers happy by delivering crap fast — it was only later that these people made Obidos bad. Clogged the river, so to speak. But Obidos was a key cornerstone of Amazon's initial success.

The original brilliant guys and gals here only allowed two languages in Amazon's hallowed source repository: C and Lisp.
Go figure.
They all used Emacs, of course. Hell, Eric Benson was one of the authors of XEmacs1. All of the greatest engineers in the world use Emacs. The world-changer types. Not the great gal in the cube next to you. Not Fred, the amazing guy down the hall. I'm talking about the greatest software developers of our profession, the ones who changed the face of the industry. The James Goslings, the Donald Knuths, the Paul Grahams2, the Jamie Zawinskis, the Eric Bensons. Real engineers use Emacs. You have to be way smart to use it well, and it makes you incredibly powerful if you can master it. Go look over Paul Nordstrom's shoulder while he works sometime, if you don't believe me. It's a real eye-opener for someone who's used Visual Blub .NET-like IDEs their whole career.
Emacs is the 100-year editor.
Shel, Eric, Greg, and others like them that I wasn't fortunate enough to work with directly: they didn't allow C++ here, and they didn't allow Perl. (Or Java, for that matter). They knew better.
Now C++, Java and Perl are all we write in. The elders have moved on to greener pastures too.
Shel wrote Mailman in C, and Customer Service wrapped it in Lisp. Emacs-Lisp. You don't know what Mailman is. Not unless you're a longtime Amazon employee, probably non-technical, and you've had to make our customers happy. Not indirectly, because some bullshit feature you wrote broke (because it was in C++) and pissed off our customers, so you had to go and fix it to restore happiness. No, I mean directly; i.e., you had to talk to them. Our lovely, illiterate, eloquent, well-meaning, hopeful, confused, helpful, angry, happy customers, the real ones, the ones buying stuff from us, our customers. Then you know Mailman.
Mailman was the Customer Service customer-email processing application for ... four, five years? A long time, anyway. It was written in Emacs. Everyone loved it.
People still love it. To this very day, I still have to listen to long stories from our non-technical folks about how much they miss Mailman. I'm not shitting you. Last Christmas I was at an Amazon party, some party I have no idea how I got invited to, filled with business people, all of them much prettier and more charming than me and the folks I work with here in the Furnace, the Boiler Room of Amazon. Four young women found out I was in Customer Service, cornered me, and talked for fifteen minutes about how much they missed Mailman and Emacs, and how Arizona (the JSP replacement we'd spent years developing) still just wasn't doing it for them.
It was truly surreal. I think they may have spiked the eggnog.
Shel's a genius. Emacs is a genius. Even non-technical people love Emacs. I'm typing in Emacs right now. I'd never voluntarily type anywhere else. It's more than just a productivity boost from having great typing shortcuts and text-editing features found nowhere else on the planet. I type 130 to 140 WPM, error-free, in Emacs, when I'm doing free-form text. I've timed it, with a typing-test Emacs application I wrote. But it's more than that.
Emacs has the Quality Without a Name.

We retired Mailman. That's because we have the Quality With a Name — namely, Suckiness. We suck. We couldn't find anyone who was good enough at Emacs-Lisp to make it work. Nowadays it would be easy; Amazon's filled up with Emacs Lisp hackers, but back then, CS Apps couldn't get the time of day from anyone, so they did what they could with what they had, and there weren't enough Emacs-Lisp folks. For a while, they even had Bob Glickstein on contract, the guy who wrote the O'Reilly "giraffe" book Writing Gnu Emacs Extensions, sitting there writing Gnu Emacs Extensions for Mailman in this little office in the Securities building.
CS Apps was Amazon's first 2-pizza team, you know. They're completely autonomous — then and now. Nobody talks to them, nobody helps them, they build everything themselves. They don't have web devs, they don't have support engineers, they don't have squat, except for rock-solid engineers and a mentoring culture. And that's all they've ever needed.
But they had to retire Mailman. Alas. Alackaday. And I still get to hear about how much people miss it. At parties, even.
I think there may still be more Lisp hackers, per capita, in CS Apps than in any other group at Amazon. Not that they get to use it much, but as Eric Raymond said, even if you don't program in it much, learning Lisp will be a profound experience that will make you a better engineer for the rest of your life.
Religion isn't the opiate of the masses anymore, Karl. IDEs are.

Java

Java is simultaneously the best and the worst thing that has happened to computing in the past 10 years.
On the one hand, Java frees you up from many mundane and error-prone details of C++ coding. No more bounds errors, no more core dumps. Exceptions thrown point you to the exact line of code that erred, and are right 99% of the time. Objects print themselves intelligently on demand. Etc., etc.
On the other hand, in addition to being a language, a virtual machine, a huge set of class libraries, a security model, and a portable bytecode format, Java is a religion. So you can't trust anyone who loves it too much. It's a tricky business to hire good Java programmers.
But Java really has been a big step forward for software engineering in general.
Going from C++ to Java isn't just changing syntax. It's a shocking paradigm shift that takes a while to sink in. It's like suddenly getting your own Executive Assistant. You know how VPs always seem to have all this time to be in meetings, and know how the company's running, and write cool documents, and stuff like that? VPs tend to forget that they're actually TWO full-time people: their self and their EA. Having an EA frees you up to think about the problemsyou need to solve; not having one forces you to spend half your time on mundane tasks. Switching to Java turns you into two programmers — one taking care of all this stuff that you no longer have to think much about, and another one focused on the problem domain. It's a staggering difference, and one you can get used to in a real hurry.
As Jamie Zawinski said in his famous "java sucks" article: "First the good stuff: Java doesn't have free(). I have to admit right off that, after that, all else is gravy. That one point makes me able to forgive just about anything else, no matter how egregious. Given this one point, everything else in this document fades nearly into insignificance."
Jamie's article was written in 1997, which in Java years is a long time ago, and Java has improved a lot since he wrote it; some of the things he complains about are even fixed now.
Most of them aren't. Java does still kind of suck, as a language. But as Jamie points out, it's "the best language going today, which is to say, it's the marginally acceptable one among the set of complete bagbiting loser languages that we have to work with out here in the real world."
Really, you should read it.
Java is truly wonderful along almost every dimension except for the language itself, which is mostly what JWZ was griping about. But that's a lot to gripe about. Libraries can only get you so far if your language sucks. Trust me: you may know many, many things better than I do, but I know that libraries can't really save a sucky language. Five years of assembly-language hell at Geoworks taught me that.
Compared to C++, Java as a language is about even. Well, scratch that, it's a lot better, because it has strings, oh man, how can you use a language with lousy string support.

But Java's missing some nice features from C++, such as pass-by-reference(-to-stack-object), typedefs, macros, and operator overloading. Stuff that comes in handy now and again.
Oh, and multiple inheritance, which now I've come to appreciate in my old age. If you think my Opinionated Elf was a good counterpoint to polymorphism dogma, I've got several brilliant examples of why you need multiple inheritance, or at least Ruby-style mixins or automatic delegation. Ask me about the Glowing Sword or Cloak of Thieving sometime. Interfaces suck.
Gosling even said, a few years ago, that if he had to do it all over again, he wouldn't have used interfaces.
But that's just exactly what the problem with Java is. When James said that, people were shocked. I could feel the shock waves, could feel the marketing and legal folks at Sun maneuvering to hush him up, brush it off, say it wasn't so.
The problem with Java is that people are blinded by the marketing hype. That's the problem with C++, with Perl, with any language that's popular, and it's a serious one, because languages can't become popular without hype. So if the language designer suggests innocently that the language might not have been designed perfectly, it's time to shoot the language designer full of horse tranquilizers and shut down the conference.
Languages need hype to survive; I just wish people didn't have to be blinded by it.
I drank the OOP Kool-Aid, I regurgitated the hype myself. When I started at Amazon, I could recite for you all the incantations, psalms, and voodoo chants that I'd learned, all in lieu of intelligence or experience, the ones that told me Multiple Inheritance is Evil 'cuz Everyone Says So, and Operator Overloading Is Evil, and so on. I even vaguely sort of knew why, but not really. Since then I've come to realize that it's not MI that sucks, it's developers who suck. Isucked, and I still do, although hopefully less every year.
I had an interview candidate last week tell me that MI is Evil because, for instance, you could make a Human class that multiply-inherits from Head, Arm, Leg, and Torso. He was both right and wrong. That MI situation was evil, sure, but it was all him. Stupid from a distance, evil if he'd made it in through the front door.
Bad developers, who constitute the majority of all developers worldwide, can write bad code in any language you throw at them.
That said, though, MI is no picnic; mixins seem to be a better solution, but nobody has solved the problem perfectly yet. But I'll still take Java over C++, even without MI, because I know that no matter how good my intentions are, I will at some point be surrounded by people who don't know how to code, and they will do far less damage with Java than with C++.
Besides, there's way more to Java than the core language. And even the language is evolving, albeit glacially, so there's hope. It's what we should be using at Amazon.
You just have to be careful, because as with any other language, you can easily find people who know a lot about the language environment, and very little about taste, computing, or anything else that's important.
When in doubt, hire Java programmers who are polyglots, who detest large spongy frameworks like J2EE and EJB, and who use Emacs. All good rules of thumb.

Perl

Perl. Where to start?
Perl is an old friend. Perl and I go way back. I started writing Perl stuff in maybe 1995, and it's served me well for nearly a decade.
It's like that old bicycle you've put 100k or 200k miles on, and you'll always have a warm fuzzy spot for it, even though you've since moved on to a more modern bike that weighs 5 lbs and doesn't make your ass hurt so much.
Perl is popular for three reasons:
  1. You can get stuff done really fast in Perl, which is what really matters, in the end.
  2. Perl has the best marketing in the world. You could write a book about how brilliant their marketing is. Sun has marketed Java with money, and Perl is almost keeping up, popularity-wise, purely on the on sheer marketing brilliance of Larry Wall and his buddies. Folks at Harvard Business School should study Perl's marketing. It's astonishing.
  3. Until roughly, oh, now, it had no real competitors.
There are "better" languages than Perl — hell, there are lots of them, if you define "better" as "not being insane". Lisp, Smalltalk, Python, gosh, I could probably name 20 or 30 languages that are "better" than Perl, inasmuch as they don't look like that Sperm Whale that exploded in the streets of Taiwan over the summer. Whale guts everywhere, covering cars, motorcycles, pedestrians. That's Perl. It's charming, really.
But Perl has many, many things going for it that, until recently, no other language had, and they compensated for its exo-intestinal qualities. You can make all sorts of useful things out of exploded whale, including perfume. It's quite useful. And so is Perl.
While all those other languages (Lisp and Smalltalk being particularly noteworthy offenders) tried to pretend that operating systems don't exist, and that lists (for Lisp) or objects (for Smalltalk) are the be-all, end-all of getting shit done, Perl did exactly the opposite. Larry said: Unix and string processing are the be-all, end-all of getting shit done.
And for many tasks, he was absolutely right. So Perl is better at Unix integration and string processing than any language on the planet, save one, and that one only arrived on the scene recently, from the land of Godzilla. I'll get to that one later.
Sadly, Larry focused sooooo hard on Unix integration and string processing that he totally forgot about lists and objects until it was far too late to implement them properly. In fact, a few key mistakes he made early on in Perl's... well, I hesitate to use the word "design" for whale guts, but let's call it Perl's "lifecycle" — those mistakes made it so hard to do lists and objects correctly that Perl has evolved into a genuine Rube Goldberg machine, at least if you want to use lists or objects.
Lists and objects are pretty farging important too, Larry!
Perl can't do lists because Larry made the tragically stupid decision early on to flatten them automatically. So (1, 2, (3, 4)) magically becomes (1, 2, 3, 4). Not that you ever want it to work this way. But Larry happened to be working on some problem for which it was convenient on that particular day, and Perl's data structures have been pure exploded whale ever since.
Now you can't read a book or tutorial or PowerPoint on Perl without spending at least a third of your time learning about "references", which are Larry's pathetic, broken, Goldbergian fix for his list-flattening insanity. But Perl's marketing is so incredibly good that it makes you feel as if references are the best thing that ever happened to you. You can take a reference to anything! It's fun! Smells good, too!
Perl can't do objects because Larry never reeeeally believed in them. Maybe that's OK; I'm still not quite sure if I believe in them either. But then why did he try adding them? Perl's OO is a halfhearted add-on that never caught on with the Perl community. It's just not as inspired as the string-processing or Unix integration stuff.
And of course, Perl has plenty of other crackpot design features. Take its "contexts", for instance, which are a horrid outgrowth of Larry's comical decision to have N variable namespaces, dereferenced by sigils, which he sort of copied from shell-script. In Perl, every operator, every function, every operation in the language behaves randomly in one of six different ways, depending on the current "context". There are no rules or heuristics governing how a particular operation will behave in a given context. You just have to commit it all to memory.
Need an example? Here's one: accessing a hash in a scalar context gives you a string containing a fraction whose numerator is the number of allocated keys, and the denominator is the number of buckets. Whale guts, I'm telling you.
Like I said, though — until recently, nothing could get the job done like Perl could.

Ruby

Every 15 years or so, languages are replaced with better ones. C was replaced by C++, at least for large-scale application development by people who needed performance but desperately wanted data types too. C++ is being replaced by Java, and Java will doubtless be replaced with something better in seven years — well, seven years after it finishes replacing C++, which evidently hasn't fully happened yet, mostly because Microsoft was able to stall it before it became ubiquitous on the desktop. But for server-side applications, C++ is basically on its way out.
Perl will be gone soon, too. That's because a new language called Ruby has finally been translated into English. Yep, it was invented in Japan, of all places — everyone else was as surprised as you are, since Japan's known for its hardware and manufacturing, but not for its software development. Why, is anyone's guess, but I'm thinking it's the whole typing thing; I just can't imagine they were able to type fast enough before, what with having an alphabet with ten thousand characters in it. But Emacs got multibyte support a few years ago, so I can imagine they're pretty dang fast with it now. (And yes, they use Emacs — in fact Japanese folks did the majority of the Mule [multibyte] support for Emacs, and it's rock-solid.)
Anyway, Ruby stole everything good from Perl; in fact, Matz, Ruby's author (Yukihiro Matsumoto, if I recall correctly, but he goes by "Matz"), feels he may have stolen a little too much from Perl, and got some whale guts on his shoes. But only a little.

For the most part, Ruby took Perl's string processing and Unix integration as-is, meaning the syntax is identical, and so right there, before anything else happens, you already have the Best of Perl. And that's a great start, especially if you don't take the Rest of Perl.
But then Matz took the best of list processing from Lisp, and the best of OO from Smalltalk and other languages, and the best of iterators from CLU, and pretty much the best of everything from everyone.
And he somehow made it all work together so well that you don't even notice that it has all that stuff. I learned Ruby faster than any other language, out of maybe 30 or 40 total; it took me about 3 days before I was more comfortable using Ruby than I was in Perl, after eight years of Perl hacking. It's so consistent that you start being able to guess how things will work, and you're right most of the time. It's beautiful. And fun. And practical.
If languages are bicycles, then Awk is a pink kiddie bike with a white basket and streamers coming off the handlebars, Perl is a beach cruiser (remember how cool they were? Gosh.) and Ruby is a $7,500 titanium mountain bike. The leap from Perl to Ruby is as significant as the leap from C++ to Java, but without any of the downsides, because Ruby's essentially a proper superset of Perl's functionality, whereas Java took some things away that people missed, and didn't offer real replacements for them.
I'll write more about Ruby sometime. I need to be inspired first. Read Why the Lucky Stiff's (poignant) guide to Ruby.That is an inspired piece of work. Really. Read it. It's amazing. I don't understand the kind of mind that could produce it, but it's funny, and poignant, and all about Ruby. Sort of. You'll see.

Python

Well gosh, what about Python, a nice language that has patiently been waiting in the wings for all these years? The Python community has long been the refuge for folks who finally took the red pill and woke up from the Perl Matrix.
Well, they're just like the Smalltalk folks, who waited forever to replace C++, and then Java came along and screwed them royally, and permanently. Oops. Ruby's doing exactly that to Python, right now, today. Practically overnight.
Python would have taken over the world, but it has two fatal flaws: the whitespace thing, and the permafrost thing.
The whitespace thing is simply that Python uses indentation to determine block nesting. It forces you to indent everything a certain way, and they do this so that everyone's code will look the same. A surprising number of programmers hate this, because it feels to them like their freedom is being taken away; it feels as if Python is trampling their constitutional right to use shotgun formatting and obfuscated one-liners.3
Python's author, Guido Van Rossum, also made some boneheaded technical blunders early on — none quite as extravagant as Larry's blunders, but a few were real doozies nonetheless. For instance, Python originally had no lexical scoping. But it didn't have dynamic scoping either, and dynamic scoping may have its share of problems, but it at least sort of works. Python had NOTHING except for global and local (function) scope, so even though it had a "real" OO system, classes couldn't even access their own damned instance variables. You have to pass a "self" parameter to EVERY instance method and then get to your instance data by accessing it through self. So everything in Python is self, selfself, selfselfself, selfSELFselfSELF__SELF__, and it drives you frigging nuts, even if you don't mind the whitespace thing.
Etc.
But in my opinion, it's really the frost thing that killed Python, and has prevented it from ever achieving its wish to be the premier scripting language, or the premier anything language, for that matter. Heck, people still use Tcl as an embedded interpreter, even though Python is far superior to Tcl in every conceivable way — except, that is, for the frost thing.
What's the frost thing, you ask? Well, I used to have a lot of exceptionally mean stuff written here, but since Python's actually quite pleasant to work with (if you can overlook its warts), I no longer think it's such a great idea to bash on Pythonistas. The "frost thing" is just that they used to have a tendency to be a bit, well, frosty. Why?
Because they were so tired of hearing about the whitespace thing!
I think that's why Python never reached Perl's level of popularity, but maybe I'm just imagining things.

Coda

That was the ADJ article I really wanted to write. Or at least something like it. For some reason, though, my true feelings only seem to come out during insomniac attacks between 3am and 6am. Time for bed! 2 hours 'til my next meeting.

chinese version: here
Read more ...

Friday, April 20, 2012

The 10 rules of a Zen programmer


UPDATE: You want a book on Zen Programming? Click here.
On a rainy morning I found myself sitting on the desk thinking about efficient working. Before I started as a freelancer I had some days were I worked lots but could look only back on a worse outcome.
I started with Zen practice back in 2006. What clearly came to my mind before a good while was: the old Zenmasters alredy knew before hundreds of years, how today programmers should work. Even when I don’t like these “be a better programmer” posts, I want to outline some of my thoughts from that morning. It shall serve me as a reminder, but if you have some ideas about it, feel free to comment.

1. Focus

If you have decided to work on a task, do it as well as you can. Don’t start multiple things at the same time. Do only one thing at one time. You’ll not become quicker, just you work multithreaded. If you work multithreaded you’ll become exhausted, make more errors and lose time to jump from one task to another. This is not only about programming, this is a general tip.
Kodo Sawaki says: if you need to sleep, sleep. Don’t plan your software when you try to sleep. Just sleep. If you code, code. Don’t dream away – code. If you are so tired that you cannot program, sleep. Even known multitaskers like Stephan Uhrenbacher meanwhile have decided to work singlethreaded . I have made a similar experience to Stephan and finally I wrote Time & Bill , a time tracking tool. Goal was to track my time so easily that I even do it for small tasks like a phonecall. Now I can create a few stopwatches at the beginning of the day and track my time with only one click. The outcome was a disaster: sometimes I just worked a few minutes on a task until I moved on to the next one. Now I am better. Similar to the Pomodoro technique I plan a few time slots and concentrate on them. No chatting, no sleeping, no checking out of a new great game on the Appstore.
Time & Bill Zeiterfassung

2. Keep your mind clean

Before you work on your software, you need to clean up your memory. Throw away everything in your mind for the time being. If you have trouble with something, don’t let it influence you. It is mostly the case that trouble will go away. If the trouble is so heavy that you can’t let it go, don’t work. Try to clear things up. But when you start working, let the outer world shape away.
Something exciting on the mailinglist? Leave it there. You can follow the exciting stuff again – later. Shutdown what fills your mind with shit: close Twitter, Facebook, your E-Mails. You should even mute the ringing of you mobile and leave it in your pocket. You can say it is similar to item #1, focus. But there is one more restriction: don’t use that tools before work or at lunch.They connect you with the outer world and probably bring up some new trouble or things which require you attention.
Think like this: at most times your mind is pretty clean when you wake up at the morning. If it is not, some sports helps (I do long distance running). If you feel clean and refreshed, go to work and work as well as you can. When you leave your work then you can fill up your mind with clutter. You’ll see it is not so much fun if you have a full working day behind you. Twitter and Co are consuming much of your energy. Do not think: it is just a minute. It is not.
You know it already.

3. Beginners mind.

Remember the days were you were a beginner. Or memorize, if you still are one. You have never learned enough. Think of yourself as you were a beginner, every day. Always try to see technologies from a beginners mind. You can accept corrections to your software better and leave the standard path if you need it more easily. There are some good ideas even from people who don’t have your experience.
Was there ever a software build twice, the same way? Even if you copy software it is somehow different.

4. No Ego.

Some programmers have a huge problem: their own ego. But there is no time for developing an ego. There is no time for being a rockstar.
Who is it who decides about your quality as programmer? You? No. The others? Probably. But can you really compare an Apple with a Banana? No. You are an individual. You cannot compare your whole self with another human being. You can only compare a few facettes.
A facet is nothing what you can be proud of. You are good at Java? Cool. The other guy is not as good as you, but better with bowling. Is Java more important than bowling? It depends on the situation. Probably you earn more money with Java, but the other guy might have more fun in life because of his bowling friends.
Can you really be proud because you are a geek? Programmers with ego don’t learn. Learn from everybody, from the experienced and from the noobs at the same time.
Kodo Sawaki once said: you are not important.
Think about it.

5. There is no career goal.

If you want to gain something and don’t care about your life “now”, you have already lost the game. Just act as well as you can, without looking at the goal you might reach after a long time.
Working for 20 years to become a partner? Why aren’t you working as hard as possible just because it is fun? Hard working can be fun. A day without work is a day without food is a Zen saying.
There is no need to start happiness after 20 years. You can be happy right now, even when you are not a Partner or don’t drive a Porsche. Things change to easily. You can get sick. You can get fired. You can burn out (if you follow all these items I guess likeliness is low).
Until these bad things happen, just work as well as you can and have fun with doing it. No reason to look at the gains of the collegs. No reason to think about the cool new position which you didn’t get.
After all, you will reach something. You’ll end up with nice memories, maybe a good position – and 20 excellent years. Every day is a good day.
If you ever come to the point were you think that working at your company is no fun at all you must leave immediately. NEVER stay at a company which does take away the happiness in your live. Of course, this is only possible in the rich countries, were people have the choice to go away. But if you are living in such an good environment, do it. Go away without regret. You have no time to waste, you are probably dead tomorrow.
When you have no career goal going away is easy.
Zen Programmer Enso

6. Shut up.

If you don’t have anything to say, don’t waste the time of your colleagues. This doesn’t make you look wimpy. Everyday you work you need to try not getting on someones else nerves. Imagine if everybody would try this – what a great working place would that be? Sometimes it is not possible. Try hard, you will like it.
If you don’t develop an ego it is pretty easy to shut up and care on the things you have something to tell. Don mix up your ego with your “experience” and always remember: you are a beginner. If somebody has a good idea, support the idea.

7. Mindfulness. Care. Awareness.

Yes you are working. But at the same time you are living and breathing. Even when you have some hard times at work you need to listen to the signs of your body. You need to learn about the things which are good for you. This includes everything, including basic things like food. You need to care for yourself and for everything in your environment – because after all, the water you drink is the water which runs in the river. Because you are living only for yourself. You live alone and you’ll die alone. World goes on, even without you.
Avoid working situations you don’t like. Avoid working for free if it means you will have no fun and keeps you away from your bed. Let go what doesn’t make you happy. Working for free sounds is just theory? Consider the people doing Open Source in their prime time. If you have subscribed to some projects mailinglist you probably know what heat there is (sometimes). If you don’t have fun with that – stop doing it. I know a bunch of people who work in an Open Source environment they don’t like. Again with Time & Bill I have tracked the time I spend in 0pen Source projects and was surprised how much time I lose there – esp. on projects I didn’t like so much.
Having this in mind, some people think they are only happy when they have prime time and can spend the evening with an xbox and some beer. While this is a good idea from time to time, it is not necessary that the whole time in your life is “fun”. If you can avoid situations you don’t like, avoid them (like I said above). But sometimes there is need to something really shitty. Like for example manually copy/pasting stuff from your managers Excel sheet into phpmyadmin. This can take you days, and it is really boring. It is no fun, but sometimes you need to do such stuff. You cannot always quit your job when you got a boring task. Zen Monks are not to shy with their work too. They get up at 4am (sometimes earlier, sometimes later, depends on the convent) and start meditation and work (they even consider work meditation practice). They have stuff to do like cleaning the toilets. Or working in the garden. Or as a Tenzo, they cook. They do it with all the care they can get. Whatevery they do, they do it without suffering and they are (or should be) happy, because every second, even the second where they are cleaning toilets, is a second of their life.
That being said: stop crying, if you need to copy/paste excel. Just do it. Don’t waste your energy with such things, they will pass. Become the best excel copy/paster out there instead.
If you suffer a heart attack, people will probably say: “uh yes, he really worked too much, he even worked for me for free at night”. Nobody can guide you to the other world. This last step is taken by us alone. You cannot exchange anything in this world. Not even a fart. So it is up to you to take care, in every second. If you die, you die. But when you live you live. There is no time to waste.
“Care” is a huge word in zen buddhism (and I think in every form of buddhism). I cannot express everything which needs to be said. it is difficult to understand the different meanings of “care”. Propably you are better with the word “awareness”. You must be aware of what you do, in every second of your life. You must be mindful in your life. Otherwise you waste it. But, of course, it is up to you to do so, if you like.

8. There is no Boss

Yes, there is somebody who pays you. There is somebody who tells you what needs to be done. And he can fire you. But this is no reason to give up your own life or to become sick of your work. Finally your Boss has no control about you. It can even be doubted that you have control about you – but don’t lets go down this path.
Back to your Boss: he can make your life worse if you allow him to do so. But there is a way out. Say “No” if you need to do something which makes you sick or is against your ethics. What will happen? In worst case he will fire you. So what? If you live in western nations and if you are a coder (which is very likely when you read this) you’ll get another job.Lotus Buddha by Jim Wisniewski
I don’t mean to say “No” to tasks like copying CSV Data to HTML. I am speaking of 80 hours weeks and you feel your body breaks. Or if you feel that your kids could need some attention too. Or if you are forced to fire people just because your Boss doesn’t like them. Or if you are a consultant and get the job to develop software for nuclear plants (some might say it is perfectly fine to work for nuclear power companies – it is against my ethics and serves as an example) or for tanks. You can say “No”.

9. Do something else

A programmer is more than a programmer. You should do something which has nothing to do with computers. In your primetime, go sailing, fishing, diving. Do meditation, martial arts or play Shakuhachi. Whatever you do, do it with all the power you have (left). Like you do at your worktime. Do it seriously. A hobby is not just a hobby, it’s expression of who you are. Don let anybody fool you, when he says hobbies are not important. Nowadays we can effort having hobbies. I have recorded several CDs and wrote fantasy books (the latter one unpublished, I must practice more). These things have made me to the person I am now, and finally they have led me to Zen and this blog post. These days I practice Zen Shakuhachi. It is a very important aspect to my daily life.

10. There is nothing special.

A flower is beauty. But it’s just a beauty flower – nothing more. There is nothing special around it. You are a human who can program. Maybe you are good. There is nothing special around you. You are of the same kind as I am or all the others on this planet.
You need to go in the loo and you need to eat. Of course you need to sleep. After (hopefully) a long time you will die and everything you have created will be lost. Even pyramids get lost, after a long time. Do you know the names of the people who build up a pyramid? And if you do, is it important that you know? It’s not. Pyramids are there, or not. Nothing special.
Same goes to your software. The bank is earning money with your software. After you leave, nobody remembers you. There is nothing wrong around it. It is the flow of time. Nothing you should be worried about it. If you are living after the first 9 rules, you’ll see that this last project was a good and funny project. Now it’s simply time to go on and concentrate on something else.
If your comapany closes because of financial problems, no problem. Live will go on. There is no real need for a xbox, a car or something else. Most people on this planet live in deepest poorness. They don’t care on a xbox, because they would be glad to get some food or even water.
So… why exactly are you special? Because you had the luck to be born in the western territory? Because you can code? No, there is nothing special around it. You can let go you ego and live freely. Enjoy the colors and the smell of flowers around. Don’t be too sad when the winter comes and don’t be too happy when spring comes back. It is just a flow. Keep it in mind when somebody denies your application. Because the company is not so special that you need to be worried about the job.

Disclaimer

I am not a Zen monk. I am just practicing and learning. Please ask your local Zen monk if you feel there is something you need to understand deeper. Of course I can try to answer on this blog, but well, I am just a beginner. Anyway I am glad about your comment and if you would send a tweet with this pages url if you liked this post. Thanks for reading!

The Zen Programmer Book

Due to the high interest of this blog post I have decided to publish a book on Zen Programming. Click here for more information . If you want to stay up to date with the books progress, please subscribe to this mailinglist. Only Zen Programming news will be sent in irregular intervals. You can unsubscribe at any time.
from: here
Read more ...

王淮在 Facebook 的十点经验总结




文章作者:王淮


我是2007年初加入Facebook, 那时大概150人; 2011年9月底离开, 当时3200多人. 经历了很多稀奇古怪但影响很大的项目, 像Application Platform, Social Ads, News Feed, Gift Shop, Facebook Credits等等. 碰到的很多的问题都是全新的, 规模是互联网历史上最大的. 当时的心惊肉跳现在回想起来是很让人怀念的旧时光. 到我离开Facebook的时候, 我负责支付安全和工具研发部门还有部分的支付后台研发组.

现在我在全职做天使投资, 给看对眼的团队在早期产品技术团队搭建给予一些力所能及的帮助. 有兴趣的朋友可以关注我的微博@王淮Harry哥.

在Facebook的这些年让我学习感悟了很多东西, 很多东西溶在血液中, 现在我换了时间来思考最值得分享的10点经验和大家分享. 希望能给创业的朋友一些启发.

在我们开始之前, 先来一段免责声明.


  1. 这里所有的东西都是从我自己的亲身体会和实践中获得的. 不一定都是新的, 但都是真实的.
  2. 所有的这些在Facebook的文化下能有效. 但不代表对你的公司一定有效. 好的种子还要有合适的土壤.
  3. 不是所有的点都对你有用. 但有一点对你有用, 我就开心了. 


OK. 我们开始吧.

1  坚持你的远见, 但灵活的把握细节

作为领导者, 在远见上你只有依靠自己, 至少在你自己负责的业务范围之内. 你是老板, 意味着整个公司; 你是经理, 意味着整个部门. 为你卖命的兄弟姐妹们是依靠你来给他们提供远见. 什么是远见? 就是对最终状态的一种描述。是让你的团队在疯狂的飞行之后最终着陆的地方。 是辛辛苦苦忙忙碌碌之后的新生活。它是北极星,它来指明方向。举一个例子,当我一开始建立支付安全部门的时候,我们只有人工规则引擎. 规则是人写的. 一条人工规则是有少数变量的简单逻辑,比如“如果 (注册在30天之内 和 支出大于100美元 和 是首次支付 和 用户来自印度尼西亚),那么 (拒绝交易)” 但这里有个问题 - 人写的东西容易出错. 人很难有效的处理10个以上的变量. 我们需要一个更有可扩张性(scalable)的解决方案. 我们希望把很多事情自动化, 让机器人做更多机器擅长的事情。因此我们建立了一个共识 – 将我们绝大部分的规则逐步替换为机器学习获得的判断模型。这一远见让我们组新加了一位机器学习领域的博士和另一位之前有过机器学习体系开发经验的工程师。 赌注巨大,但是一个更好的未来需要下这个注。

但你需要对细节灵活把握, 永远都有条条大路通罗马. 你需要给团队足够的空间来施展拳脚,只要他们在朝着正确的方向以合适的速度前进。另一个故事:在classification算法上一度我对决策树的兴趣 比回归要大。但玩算法的工程师告诉它们之间的差别可以忽略。我可以坚持己见(当时我是真心觉得决策树要更合适)但我信任他并让他放手去选合适的算法。同设 计师(Facebook的整个研发有设计师, 产品经理, 工程师三类物种) 合作的过程中也有趣事发生,他们对于字体,颜色,行距等等都很龟毛。我通常都会忍让, 只要服务于产品的主要功能。我们精力有限, 吵架要选择正确的战争,关乎全局的战争,而不是纠缠于某个局部战斗。

2 只和最好的人合作

一流的牛人只愿意和牛人厮守。他们聚在一起会更牛逼。一流人才无法容忍二流的人. 那什么是“最好的人”?我的理解是能够尽其所知, 用其所长, 学其所不能, 从而迅速完成目标并远超期望. 他们的本能是挑战自己, 超越别人的期望,超越自己的期望. 对他们来说,仅仅足够好是不够好.



只有一流人才组成的团队有很多好处。

(1) 这让你更加愿意委托. 从我的经验来看, 牛人不会轻易信任不熟悉的人. 如果你还没有证明自己和他们一样出色甚至更出色, 他们宁愿自己独立工作劳累死也不愿接受你的帮助. 因为他们担心你会搞砸. 但当你证明自己之后, 他们会信任你, 放心的把事情交给你一起合作。一个互帮互助的牛逼团队才能做到1+1远大于2.

(2) 通过艰巨任务的完成牛人们互设榜样. 你会想”牛, 这哥们竟然能把这玩意做出来了, 咱得加油了”. 这种peer pressure合理的利用可以大幅度的提高工作表现并在团队中形成良性循环。

(3) 牛人们喜欢互相挑战. 我记得一位工程师总监立下赌约 – 如果我们在规定时限之前完成网站翻译平台所需的代码修改,他将把头发染成蓝色. 这样的挑战把“枯燥”的工作变成了挑战性游戏。在玩游戏中写程序比纯粹的写程序要有趣得多. 当然我们也有很多更加认真的挑战. 因为牛人们天生(贱命, 哈)容易对挑战上瘾, 不管是挑战别人还是接受挑战.

(4) 牛人们相互学到很多. 每个牛人都有自己牛的地方. 彼此有很多的互补. 如果Facebook不是有很多东西可以学习的话我不会呆4年多。对缺乏经验的人来说,这点很给力. 我们雇佣非常聪明的毕业生(潜在牛人),这些人希望引爆自己来证明他们的牛逼之处。他们不愿到一个舒适无挑战的公司过日复一日的生活。他们想学很多来丰富 他们的经验,完成不可能完成的任务并在他们的职业生涯上前进。他们想要证明“yes, we can”。和其他牛人一起才能更容易的实现这些。



你不想要二流的人但如何远离他们?首先,慢点招人 (Hire Slow). 在招人的标准上固执一点. 训练你的面试人员让他们明白他们需要招(某些方面)比他们更强至少不会拖后腿的人, 如果不是, 拒绝平庸, 不要屈就. 我曾好几次在招聘决策会议上发现黄金履历者无法拿到Offer, 只因为某个面试官觉得这人无法给他深刻印象没有让他惊讶。但在另外一些例子当中,那些获得一致通过的候选人仍被放弃因为大家都只是觉得他仅仅符合要求而已, 没有出彩的地方. 在招人问题上,绝大多数情形下,你要小心不要冒进.(顺便提一下我们也会雇用那些没有全票通过的候选人, 只要有一两票是强烈推荐 – 因为对于已有员工的强烈推荐你是不应轻易忽视的, 这时可以冒险)其次,炒鱿鱼要快 (Fire Fast). 使用二流人才就像服用慢性毒药, 一天一点, 迟早咯屁. Facebook要求所有的管人经理对于员工的表现要特别敏感. 经理发现员工分配的任务或者答应的事情经常没有做到, 如果是客观原因, 一定要尽力帮助解决; 如果判断为人才质量为题, 走法律允许的程序迅速将人炒掉. 我见过几次炒的比较慢, 那对团队造成的负面作用可不是闹着玩的。

3 树立高的期望值并加以衡量

作为领导者,你需要设定足够高但仍合理的期望. 足够高使得你的团队不会感到无聊。仍合理使得他们不至于油尽灯枯。你要给他们创造一段经历使得在旅程结束时,他们回过头来看会说 – “他妹的, 我都没想到我居然做到了这个. 这个屌爆了.” 在Facebook, 和其他硅谷高技术公司一样,期望同薪酬相结合. 每半年Facebook都有5-6个公司级的大目标, 所有人的奖金算法中都会考虑该目标的完成情况. 因此树立明确的期望本身就至关重要。



另外, 你需要找到一个不容争辩的途径来衡量期望. 我花了大量时间和团队一起制定下季度里最重要的3-5个目标并有数据化的衡量指标 (一个目标背后可以有多个指标)。根据工作量把目标分别委派给单个或多个攻城狮,或者让他们自己揽。在这一情况下,我们不仅有可衡量的目标,使得我们可以 迅速地说出来我们在做什么做到哪了,同时也知道每个具体目标后面的负责人是谁。团队的表现和个体表现挂钩, 所以他们失败了我即不成功. 例如, 当年我们团队最大的成果就是在一年时间里,通过每季度不同的指标,让信用卡支付的投诉率降低了75%.

有一点要强调的是﹣期望还是要基于现实要合理. 在你只有10%的市场份额的时候却幻想10几倍的收入增长无疑不现实. Steve Jobs乔老爷是这方面的老手, 非常善于推动他的团队超越潜能但同时也榨干他们(虽然他们后来还是为他们所做到的而自豪一辈子)99.9%的领导者不是乔老爷, 也不需要是。更可行的是在团队的真实极限中找到一个可持续性的驱动来激励团队超越自我.

4 重视数据而不盲从数据

决定产品方向时, 要的是想象力, 激情和胆量, 而不是数据. 数据能让你的团队沿着正确的方向前进而不出轨, 也有助于产品从“一开始是什么样”到“最后应该是什么样”的逐渐优化成型. 但数据不能帮你决定方向. 举个例子, 当我们在人工智能(机器学习)上压上我们团队所有的资源的时候, 我们忐忑不安. 但是我们坚信一点, 现有的基于人工规则引擎的防欺诈系统会很快成为死胡同, 因为它太死板而且不易规模化以处理大数据。所以, 就像在电影指环王中Frodo明知通向Mordor的道路很黑很冷很危险, 但那是一条他必须要选择去走的路; 我们选择了在机器学习上压上所有的宝。失败, 整个团队会很难看; 但我们决定走艰难但我们认为是正确的路. 这种思路同样应用在如何设计用于用户报告(外部工具)和案例审查(内部工具)的工具来应对潜在的欺骗行为。 我们最后决定的方向是”进行自动处理”和”建立反馈机制”。直接抛给人工来处理总是很容易被选的一条路, 因为只要建立一个人多人傻的客户支持团队即可. Lame! 我们希望通过自动处理来解决大部分的欺诈案例,而把精力则放在那些确实需要单独处理的特殊案例上, 同时把从业务支持团队(即客户支持部门)的处理意见自动采集并集成到下一轮的机器学习中去。由此, 我们的机器判断会越加精确和聪明且与时俱进.



但你不能忽视数据。没有数据的支撑而一味靠直觉走黑路, 很容易走岔道, 甚至大错特错。有一段时间我们认为爬 行工具(通过分析关联的cookie,信用卡)可能可以找到很多欺诈的同伙。通过实验结果却发现, 这种预期是否成立很大程度上取决于当前流行的欺诈行为的特点. 比如, 当失窃或贩卖信用卡的案例非常普遍的时候,关联分析是一种有效的方法。但如主要情况是帐户被黑或小宝们冒用妈妈的信用卡去网游消费时,关联分析就作用不 大。直觉在现实前面碰了一脸的灰。 不过幸运的是我们很快意识到这点且把这个项目叫停了, 所以没有浪费太多的资源。

另外, 顺带提一下A/B测试。A/B测试并不会告诉你去做什么产品,但它可以帮你确定实现产品时的哪个细微版本更能揪住用户大爷们的心.

5 避免无谓的时间浪费

刚进Facebook做工程师的时候,我非常享受那种日夜泡在码海中的感觉。后来慢慢的承担的项目责任越来越大越来越多,写代码的时间越来越少(但 绝大多数时候仍占大头). 有时候更多的是把时间花在决定产品的方向和设计上。很多事情是和产品经理设计人员一起搞的. 但在Facebook攻城狮们有很大的发言权甚至有些时候是拍板的权力。Facebook希望攻城狮们有王者风范. Facebook希望攻城狮能决定自己要做什么应该做什么, 而不是总是”被决定”做什么(一种流行的说法是,write your own job description). 因此,我花了大量的时间在思考这些问题 – 哪些功能需要添加,哪些功能需要删掉,需要开始或停掉哪些测试,我们正在流血流汗的是不是现在最最最重要的问题, 我们是该花时间优化用户交互流程呢, 还是减少出错率, 还是让系统更快, 等等。这些问题很伤脑筋, 答案经常不确定, 比一个劲码到手抽筋要难. 但这些问题很重要, 甚至可能决定了你熬的日日夜夜究竟有没有必要. 建议所有的工程师思考思考代码之外的这些问题, 团队领导者就更有必要了. 当然, 攻城狮的大多数时间还是应该花在代码上.

那究竟哪些时间不应该被浪费呢?

很多, 但我只举两个我认为最重要的例子。

邮件。不是所有邮件都发而平等。有些邮件纯粹打酱油的. 有些邮件是不需要马上处理的. 我尝试使用过滤规则来踢掉打酱油的邮件, 突出需要马上处理的重要邮件。对此,分享两点。

1) 建立一个适合你的邮件过滤系统. 我会对重要和紧急的邮件做即刻回复,而暂缓处理那些可以等到晚上再回复的邮件(尤其是发自我自己的团队,产品经理,兄弟连和顶头的不顶头的上司们的邮 件)。但是,我要确保在我挣扎的爬到床上之前,把这些邮件全部处理掉, 读的读, 回的回。对于那些仅供参考的邮件,过滤系统会将其塞到某个固定的角落,我隔三差五去瞅瞅。此类邮件诸如某酒鬼询问Napa Valley哪个酒窖比较正点等等. 这些邮件通常比较有趣, 挖的坑很大很深所以也很耗时间, 我通常不跳或者不马上跳。



2) 广而告之你的个人邮件处理策略. 我让我身边的战友们知道我是如何处理邮件的, 并把这个政策放到我所有的邮件末端。如是说 – “正在尝试个人邮件处理策略-为了戒掉Email瘾, 我将强迫自己每隔三小时或以上查看一次Email,急事请电话/短信/IM我” 这么做更多的是让别人明白不要指望马上得到回应. 其实我查email比每3小时要频繁, 但至少不用马上逼得去回每个email了, 我可以憋着悠着点. 因为如果真的很急, 我的iPhone应该已经响过了. 而且, 批量处理真的效率要高很多. 不骗你.



会议。开会太容易变成一群人互相在扯对方的蛋. 浪费时间而且开完后发现没有结论且很蛋疼. 但开会对于teamwork很多时候是必要的. 如何主持会议是门学问, 这里不细谈. 不过, 你不可能也不需要参加每个邀请你的会议。当你认为你参加某会议于己于人都无太多价值的时候, 建议你考虑不去。如果想要有礼貌一点, 那就写个email问问主持人你是否可以缺席. 通常当你想过这个问题决定发这样的邮件时,答案通常都会是yes。有些时候我也会很可耻的让我的产品经理替我去开会。当然,我会鼓励他也争取不要去。Only make the meetings you really have to. 同样, 我要求我自己的团队在组织和参加会议的时候要慎重,也经常问他们想想看自己花在会议上的时间是不是多了。一个做法是把可能的会议都整合在一起。有一个例 子。早些时候, 我们会经常收到来自支持团队的比较随意的会面请求。这让攻城狮的一天被会议分割得支离破碎. 写代码的都知道没有3-4个小时的连续时间是不容易高潮的. 而且这种会议通常效率很低. 于是,我们改变了做法,每周安排固定的答疑时间(office hour)和支持团队嗑想法然后follow up。当然, 紧急的问题另当别论应当马上处理.



有一个被经常忽略的原则 – 有意识地去思考哪些事情不应该做并且马上不做。例如,哪些是无谓的争论可以避免介入,哪些功能可以放弃,哪些关系不应该发展, 哪些人应该开掉, 等等。我经常问自己一个很简单的问题,我现在正在做的是否对我的目标很重要。如果你清楚自己正在做的和自己想要的,答案会明了。Go for it.

6 增进亲密感是减少紧张关系的有效方式

工程师和支持团队之间有着纠结的合作竞争关系(注意, 合作在前)。互 联网技术公司中很多人(尤其是聪明人)总是期望工程师对所有问题给出一个让人会心一笑的解决方案。但现实是,不是每一个问题都可以或者应该在技术框架下解 决。对于一些具体的问题, 客户支持和运营部门会有一些非常深刻独到的见解. 工程师未必行. 毕竟很多见解需要不同的专业知识, 依靠实地经验。没错, 工程师可以在代码中自动log大量的原始数据,但从原始数据中提炼可靠的判断却并不总能如愿. 和很多其他公司的客户或支持部门不同, 我们的支持部门招募了质量相当好的员工(很多来自美国名校 – 在我直接接触的反欺诈支持组20来人中就有3名斯坦福校友)。因此,当两群都很聪明的人观点相左时,该听谁的呢? 紧张关系再所难免。



不同的工程师团队也存在着合作竞争关系。 反垃圾邮件、安全和反欺诈(我的团队)这几个团队之间存在密切的工作协作关系。这些团队也都尽可能地相互学习,分享经验和技术。但是,有时候各团队独立处理类似但不同的一些问题时,都试图向对方推销自己的解决方案和理念。



如何让合作竞争保持在一种健康有序的状态? 我觉得关键是促进人与人之间的亲密感。把 人搞近了, 事情就容易了. 我花大量时间用在建立和其他团队的关系上面。例如两周一次或者一月一次和其他团队老大们的1对1碰头会。越相关的团队, 头碰得越频繁. 我自己或者我的团队成员会有选择性的经常参加一些其他团队的会议 (我们称之为Friends & Family meeting)。当为一个共同的大项目工作时,我曾安排不同的部门成员(工程师、支持、数据分析、金融财务)坐到一起进行项目冲刺。这是拉近相互之间距 离的非常有效的一个做法, 尤其对于减少扯皮的机会. 因为互相之间经常会请或被请喝咖啡 (可称之为“咖啡外交”). 我也会经常和一些人约定吃工作午餐, 经常聊的是家常, 增的是感情。有的时候一次长距离的散步也更能让人畅所欲言。而这样的紧密关系,在我们面对一个极具挑战性的项目的关键时刻,会帮助大家紧紧的抱团闯关.

7 习惯委托, 但不要盲目, 请谨慎

分配任务委托别人的重要性比较容易理解. 因为你不是超人, 不能端茶倒水什么都做吃喝拉撒什么都管. 有些时候, 你往往还不是最适合的人选. 当团队一大事情一多, 你一定要学会委托别人来负责合适的任务. 对有些领导者而言, 委托别人一个重要的目标可能不是很放心, 觉都睡不好; 但我非常习惯委托别人, 有时候可能太习惯了. 这是我一位前老板给我指出来的一个问题. 有一次我给一位组员分配了一个既有技术难度又有协调挑战的难题. 进程比较缓慢. 但我给了他太多的时间空间来折腾, 而事实上他在某些方面需要一些加强, 有些方面需要我更多的主动的帮助. 我老板指出来, 如果我要让别人随便折腾的话, 前提是我需要有足够的信心.  我需要有事实来逐渐证明我的决定是正确的. 需要谨慎委托. 因为如果项目失败, 对他而言, 最终负责的人还是我, 不是别人. 所以我不能以别人不行来给失败的委托埋单.



如果你有一个重要的任务需要委托给别人, 你要么

1) 已经对此人非常了解. 知道他战斗力非凡可以搞定; 或者相信他可以迅速学习提高打鸡血搞定;

要么

2) 需要在一开始手把手教他, 时不时问他, 直到你对他有足够的信心.



具体我是这么做的. 项目开始时, 我让被委托人给我一个整体计划以及几天内可以完成的任务. 一开始经常会面跟进, 然后确定后几天的任务. 根据每次完成状况来估计他能不能”高快狠”地完成最终的目标. 信心逐渐建成后可以减少关于该项目的细节讨论. 此时的委托可以放得更开. 但有一点要注意, 如果跟的太紧的话, 可能让人觉得你对他不放心, 他也会做得畏首畏尾, 这可能比盲目的委托还更差. 所以在委托和谨慎之间, 有一个微妙平衡.



我觉得在这一点上我还要加强. 这里也和大家提个醒.

8 意见反馈应该一个持续性的, 而不是一年一次或两次的活动

一年一度或两度的意见反馈在硅谷公司是非常常见的. 它的目的不是设置起来给员工难堪, 让他们互相责难的. 它的目的是希望员工对自己对他人有更全面的认识, 以助进步. 意见反馈有自我反馈和同事反馈两部分. 自我反馈是自己评定自己, 完成了哪些目标, 错失了哪些目标, 哪些方面做好了, 哪些方面还待进步. 但由于是自己踢球兼裁判, 难免有偏颇. 同事反馈, 就像一枚镜子, 让你看到180度之外的自己. 在Facebook, 360度的正式意见反馈是一年两次, 并且和薪酬挂钩. 但近年来, 意见反馈和薪酬评定逐渐分开. 比如我做的一件事就是季度性的意见反馈, 时间和正式评定错开. 在那几天中, 我请求所有相关组的同事在自愿的前提下给我写写关于我直属组员的意见反馈, 短短几句都行. 我会收集, 综合, 最后在1-1碰头会时反馈给我的组员.

如果需要等半年才来收集意见的话, 很多相关故事早以忘得一干二净. 故事越久远, 记忆越模糊, 意见越空洞, 说了等于没说. 而且, 意见反馈和薪酬绑在一起, 正常人(即使是牛人)都会很自然的把心眼更多的放到薪酬上, 而不是意见本身.

除了季度性的轻型意见反馈, 日常的意见反馈如果有的话应当立马传递. 趁热打铁效果更好.

如何有效传递整理好的意见也很重要. 有句话是说”it’s not what you say that matters, it’s how you say it“. 我没那么极端, 我觉得如何传递意见也同样重要. 有两种方式我都试过, 不确定哪种更有效. 这里都谈一谈. 一种是以问为主逐渐深入促其思考, 比如”how did you think about the meeting you hosted yesterday”; 另外一种是赤裸裸的直入主题, “hey, let’s talk about the meeting you held yesterday”, 然后开始谈我自己的感觉. 不管哪种方式, 一定要给对方一个解释自己行为的机会; 永远假设并告诉他我相信他的意愿是好的. 为了避免陷入”你昨天做了xxx” “没有, 我做的是yyy” “我觉你是做了xxx”的死循环式的争论, 我首先争取和他们在”我们感知的即是事实”这一点上达成共识. 基于这点前提, 我们把讨论的重点放在如何做能改变别人的感受最后让事情能顺利完成, 毕竟大多数重要的事都有很多人一同协作完成. 当他们认识到自己想要改进某个方面的时候, 如何改是一个相对容易很多的问题 – 聪明人一向能够找出改进的办法, 我所做的就是配合他们做头脑风暴. 最终谈话的目的是产生一个下次如何能做的更好的具体方案.



关于有效传递意见反馈, 另有4点提一下.

1) 意见反馈不见得都是负面的. 它可以是别人的一个长处. 你很欣赏. 你希望他这方面坚持做, 做得更多. 比如一句”hey, I really love your weekly summary email with the key metrics at the top. Please keep them coming”可能产生很好的激励效果.

2) 意见反馈必须摆事实和讲道理. 如果你只是告诉别人他很烂, 但不说什么时候浪过了以及为什么, 除了给他添点火气之外无他用. 所以我在相关人员包括自己写意见反馈的时候要求提供实例. 比如一句 “I think he could make meetings transparent and shorter by having an agenda, like the weekly data review meeting on last Friday”比”his meeting is too long”更有血有肉有效.

3) 意见反馈必须是可操作的. 让人无从下手的意见意义不大. 如果在提意见的同时提出一个方案以供参考就有意义的多. 但注意, 绝不能是命令的方式 (那是中青宝…). 比如前面的例子”I think he could make meetings transparent and shorter by having an agenda sent ahead of time…”就很容易操作.

4) (个人偏好) 在最近的两个评价周期中, 我给15个左右的同事(一半不直属我)写过意见反馈. 我把我写的直接分享给他们. 出于这种想法, 在我下笔时就少了很多冲动. 因为他们会读, 所以我无法做到背后捅刀. 因为他们要读, 所以我需要写得有意义, 容易理解, 并且加上很多例子. 并且, 我欢迎他们和我直接讨论. 如此一来, 他们也明白我写这些反馈的一片苦心是为了他们进步.

9 你可以比你想象的做得刚好

这不是说说而已. 我自己就有一个亲身的例子. 我们曾经认为把一个高得离谱的欺诈率降到所允许的范围内会很难. 的确很难. 但想想看我们最终牛逼了一把, 把它降到了比允许上限的一半还要低. 感觉很爽. 很长一段时间内整个团队士气高昂信心爆棚做事像开了外挂.

牛人们总是不断的超越自己. 给他们一个离谱的目标, 配以应有的工具, 适当的帮助, 足够的信心还有一定的时间, 他们会让你大吃一惊, 也会让自己大吃一惊. 这一点, 乔帮主是行家, 屡试不爽.

但做到这一点有一个前提 - 不能害怕犯错. 如果犯错是被要严惩的失败是不允许的话, 牛人们只能在框框中被圈养, 没有办法实现突破. 有一句话我经常挂在嘴上”ask for forgiveness, not for permission“. 在Facebook, 大胆行事犯错是容易被原谅的.

但反过来, 有一点要小心, 就像第7点所说的 – 你不能随便把一个离谱的目标交给一个人, 然后期待他来给你惊喜. 盲目带来的可能是惊吓. 你需要真正的牛人, 至少是潜在牛人. 而作为一个领导者, 你的一个任务是帮助他们, 鼓励他们, 来引爆自己的潜力点. Facebook不缺此类待引爆的牛人.

10 不要过多设计或者过早优化

有些工程师有一股出于本能的冲动想把自己的程序规模化, 甚至在这些程序还没看到大规模使用的曙光之前. 我在Facebook开始的时候, 也是冲动型工程师一杯. 但经历过几次失败的产品之后, 我牢记了这个教训. 不要过多设计或者过早优化. 把核心功能设计的简单精炼. 只有在看到产品有被大规模使用的趋势后, 才来增加功能或增加规模量. 有一个我做的产品使用的上限是200万月用户(当时Facebook整个月用户群是4000万左右), 但我的实现已经做了很多额外的功来满足更多的用户. 做的时候感觉很爽(感觉自己很牛, 感觉再多人用产品也不会崩溃), 之后感觉很惨.

但这一点不一定能适用于架构上的工作. 比如Friendster这个网站的失败就是其基础架构的性能长期无法应对急速增长的用户以致网站很慢甚至崩溃. 在用户增长高潮来临之前, 你应该已经在架构上做了足够多的前戏. 否 则搞不好就要像Friendster收摊子散伙. 但同时也要意识到, 你所看到的用户访问模式, 你的网站功能, 在你只有10万用户的时候, 可能和你有1亿用户的时候会很不一样. 所有太多太早太频繁的架构上的大动作可能会适得其反. 这一点上, 你要小心判断.

结语:

在Facebook的4年半很好玩. 我学到的感受到的远多于以上的十项. 但希望这个分享能对朋友们有点帮助. 同时祝所有的朋友在自己现在扮演的角色上都有好运.

FROM: HERE
Read more ...