299 karma · joined September 10, 2010
Some schools give good industrial training; some are still bemused that machines exist that perform the computations that are so fascinating to study in the abstract. We need both. It's true that schools can't manufacture stars, but they can help train those with latent ability, just as Real Madrid players are certainly helped by coming up through smaller teams.
Likewise, some places (YC startups, or forward-looking splinter groups in larger industry) need rock stars who can do a lot; but there's a huge swathe of megacorps that just need warm bodies that can tab-complete API calls; the problem with debates like this is that arguments are so rarely anchored by a clear context. Are we doomed to always argue straight past one another?
Source or binary, you are still embracing their description of tasks for an automated machine to perform very rapidly.
If you are wary of what they have done, it's true that source is somewhat more accessible to examine than machine code, but for any non-trivial program source is still quite expensive to evaluate.
http://www.kalzumeus.com/2012/01/23/salary-negotiation/
I've tried to use this same reframing approach when working with people to estimate a software schedule (for complex projects with external promises). Basically, if you can establish that engineering is about tradeoffs -- such as between runtime and memory footprint and code size and small vs large values of N and so on -- then certainly human development time is another resource subject to tradeoffs, where we should identify alternate scenarios and try to aim for the optimal one.Finding ways to talk to people in terms that resonate is tricky -- and often almost a matter of bridging micro-cultures, where subtle tribal affinity signals are needed to gain trust -- so I was impressed that Patrick could break down salary negotiation in a way that didn't seem skeezy to people who just want to build great things and not worry they are getting shafted.
That sounds horrible. Did you mention your concerns to the people who owned those meetings, in a way that made it clear you were trying to help improve them?
I've had success several times with this in BigCo, with various satisfactory outcomes:
1. "You're right, this meeting is BS! But it has to happen for various reasons X Y Z -- since you don't care about this area you don't need to come, we'll grab you if we need you."
2. "You're right, and other people feel tuned out as well, so let's try cutting it to 10 minutes / mailing out an agenda beforehand / starting exactly on time."
3. "You're right, this is an inefficient way to gather state so we're going to just swing by each person 1-on-1."
4. "You're right, this team is too big so we're splitting in 2/3 smaller groups"
http://neugierig.org/software/blog/2012/05/new-project.html
(Congrats, Evan!)* Concurrency. It's easy to introduce race conditions, livelocks, or deadlocks without even knowing. They are often difficult to observe or reproduce, and it takes a lot of hard-won experience to become sufficiently critical of your own incompetence. On the other hand, the tools are improving here (helgrind, relacy, threadsanitizer).
* Exception-safety. I don't mean in the weak sense of "won't leak resources" but in the stronger sense of leaving the system in a consistent state after an exception. Again, it's difficult to analyze or induce all the different code paths that might occur, and difficult or expensive (depending on your starting point) to roll back your mutations. Again, there are tools that help with this, like STM or cheap persistent data structures (so you can do a bunch of mutation that is only committed atomically at the end).
Are there others? Can the progress in these domains shed light on how to make crypto safer?
That's one of the hilarious things about linkedin attributes; people accrue tags that have vastly different importance depending on context. But hey, it's hard to say no to someone else vouching for my Computer Animation trait, whatever that means. It has the same sort of vague benefit with negligible cost situation as friend graphs. This is why I like your idea of careful scarce allocation, vs. limitless accrual. Information is only meaningful inasmuch as it represents choice.
The risk is small with simple declarative tests ("the output of f(x) == y") but with complicated systems with large state spaces, you start writing combinatorial tests to try to cover more of the space and incur a bigger risk your test code is buggy.
Few things are as frustrating as fixing a bug that should have been caught by a test and realizing the test wasn't actually working correctly. This is even more acute when working on code where speed is important (where performance is correctness, in other words) and you realize a test has been measuring the wrong things, such as asynchronous runtime showing up in the wrong place.
TDD has always seemed more like a useful tactic to be applied to certain kinds of problems than as a silver bullet.
Valve provides an interesting contrast here: with Steam/GreenLight they run a scaleable distribution channel for large numbers of small indies, taking a percentage without making particular and huge bets. It's like an index fund vs. managed fund, where the latter does intense research into specific options. Often that research in anchored in comparative analysis where someone has proven a juicy market exists (ex: Guitar Hero having a million clones in its wake).
I have struggled to find the right ways to think about the phenomena underlying the shared memory abstractions. The limited visibility makes this harder than understanding other aspects of software. You can run instrumented simulations like cachegrind; you can query arcane CPU performance counters (Intel's Nehalem optimization guide was eye-opening regarding how much goes on inside vs. what you might learn in an undergrad CPU design class) -- but at the end of the day you have to be guided by experimentation and measurement. And so many times those leave us with no good theories to explain the observed behavior.
(War story, feel free to skip: One time we were trying to speed up a datafile parser by any means possible -- which was already split into a producer-consumer thread pair, one thread running the unfortunately complex grammar and producing a stream of mutation commands, the other thread consuming that and building up in-memory state. The engineer working on this found that adding NOPs could speed this up, and he measured and charted a range of # of NOPs and chose the best one. Our best guess was "something to do with memory layout?" The outcome of the story was that we tore out a bunch of abstraction layers and ended up with a simpler, single-threaded parser that didn't need such heroic and bizarre efforts, but it also left us feeling a bit of vertigo with regard to memory hierarchy behavior.)
Your pointing out that the shared memory abstraction is backed by message-passing between hardware components (which each represent concurrent processes) is really interesting - thanks!
On the other hand, they are a single point of failure. When someone succeeds from outside in pushing the dictator out, chaos ensues. Some will thrive under the ensuing autonomy as they see room to advance their own agenda, but many of the most talented will move on if they perceive that the team is in a degraded state. Worst of all, being a trusted minion of the prior dictator leaves you with a suspect role when a new dictator grabs the throne. Experiencing this is somewhat painful and complicates your weighted decision heuristic for what to do with the rest of your life. Will things get better? How long do I wait? Could I possibly reinvent myself to the degree that e.g. patio11 was able? etc.
std::list <person*> people;
You're right that the instantiated list entry (what the article calls "helper") will directly include a value, but the value here is a pointer to a person, not a person.http://blog.pinboard.in/2011/11/the_social_graph_is_neither/
However, they typically don't include the full game data; you have to use them with data from the free trial versions or contributed by the public mod community (something else Id really helped foster). Does anyone know if this is necessary for them to retain rights to the IP?
Versions (and Time Machine history) are good steps to part of this, in that they are easily available and understandable, but they don't solve the collaboration aspect. How do you diff and merge your local changes into the NEW_final_v2_UPDATED.xls that was emailed to you? I'd summarize the problems as:
- identfying & organizing versions of the same document in ways manageable by normal humans (i.e. not a set of variably-named files spanning email attachments and shared folders, nor a graph of nodes identified by 20-byte hashes, nor a rigid interface to a versioned-file server)
- diffying & merging non-text document types (images, audio, spreadsheets)
I agree this would be a valuable problem to solve well!