Hacker News new | ask | show | jobs
by dougireton 3361 days ago
Developers who insist that their favorite technology is the best vs. what's the best for the task at hand, what technology will the team as a whole be successful with.

Developers who don't have empathy for less experienced team members; who can't/won't mentor well.

4 comments

Meh, takes me back to a couple years ago when the MEAN stack was all the rage, I was pointing out flaws/problems which would arise from:

- Mongo not having a schema, relations - Angular having a fundamentally flawed update system

But of course the argument was that 'MEAN is what everyone is using, its easy to find MEAN developers'.

Sure, if you mean it's easy to find kids who learnt how to make apps, via a MEAN stack, over a couple months as their first ever tech and now are ready to work for very cheap.

Of course it's never cheap - what you save on quality you make up in quantity.

The amount of developer time wasted writing migration scripts, debugging silly problems because of no schema, data loss (at least they took my advice on automating backups!), not to mention a ton of frontend issues - was staggering.

Yes, this was a 6 month old startup with about 6 fresh college "engineers".

Experienced developers have a favorite for a reason, usually they've been bitten by other ones - I would say don't trust a developer who pushes a certain tech without giving a reason beyond that they are familiar with it.

For example, I've found javascript a painful language to work with (although that's starting to change with all the latest revisions to the spec) - but it makes no sense to push for a different language when half the app is already written and all the devs know javascript.

Using Mongo as a db on the other hand I wouldn't suggest ever, data integrity is way too important to use a (badly implemented) cache as a database.

There are much better technologies out there that give you everything that Mongo tries to provide, and faster too.

You sound like my twin. Wait, are you me?

Seriously, I was surprised to find that Splunk uses Mongo. Given its performance and reliability with Splunk, I'm willing to give Mongo another chance given the right conditions (given that someone on my team has significant experience administering it).

I'm relatively new to Mongo and I've only used it in C#.

But a few points:

I would only use Mongo as a backing store for a micro service. All access would be through one service that enforced business rules, data integrity, and would be responsible for exposing business objects/aggregate roots.

App servers are a lot cheaper/easier to scale than database servers. By keeping all of the logic in the business tier, it's a lot easier to scale/load balance.

See, what you just posted is a typical response which tries to justify Mongo, even though you yourself have little experience with it!

Fine, I'll bite:

> All access would be through one service that enforced [rules, integrity]

That's a very good idea; you just described what a database is. Now why take it upon yourself (and team) to reimplement that yourself when there exist quite a few that have had thousands of programmer years scrutinizing every detail to create the most robust and optimized systems... these are much better programmers than you or I for this job, these guys eat shit and live databases.

> App servers are a lot cheaper/easier to scale than database servers. By keeping all of the logic in the business tier, it's a lot easier to scale/load balance.

Ah there it is, the typical FUD, by moving everything out of the 'database', you can scale.

Nope, that's not true.

The only thing that doesn't scale easily with a database server is joins - In all other cases it's possible to (even with an rdbms) scale infinitely via sharding. In fact there are many implementations that do so, and they are usually faster than Mongo.

Now onto joins, these get implemented in the "app server" by the inexperienced developer in 2 ways:

A. Real joins using normalized data

1. generates a ton of network congestion from getting the data

2. ton of cpu because because json decoding/encoding

3. ton of cpu because scripting languages vs optimized C

4. the use of O(shit) algorithms to make the joins

5. inconsistencies when things fail like network or disk or shutdown

B. Redundant data

1. use a ton of memory/disk

2. create deferred overheads in order to keep things sync

3. despite that, end up with inconsistent data all over the place

4. wont actually be faster or scalable(!!!)

In both cases they end up creating a bottleneck once you start caring about concurrent access not messing up your data.

Watching Mongo evolve is like watching the past 30 years of rdbms - which started out as flat text files which were 'fast and simple' - gaining indexes, efficient datastructures, foreign keys, disaster recovery etc.

But it's all good, and I can't complain, I make a killing putting out fires caused by badly architected systems.

A. Real joins using normalized data

Then you end up denormalizimg your data anyway in the business layer anyway because most real world applications work with denormalized data and being a good DDD person you work with "aggregate roots". With Mongo you can store and load the whole aggregate root as is without the whole "object relational impedance mismatch".

1. generates a ton of network congestion from getting the data 2. ton of cpu because because json decoding/encoding 3. ton of cpu because scripting languages vs optimized C

I don't use scripting languages. I use C#.

4. the use of O(shit) algorithms to make the joins

If you're doing a lot of joins with a non relational database, you're doing it wrong. You should be Store the whole object hierarchy as one document.

If I'm doing joins. I'm using Linq which should be doing joins based on hashes.

5. inconsistencies when things fail like network or disk or shutdown

Again you should be storing the whole document with the relationships.

B. Redundant data 1. use a ton of memory/disk 2. create deferred overheads in order to keep things sync 3. despite that, end up with inconsistent data all over the place

You're doing it wrong you're using a non relational database like a relational database.

4. wont actually be faster or scalable(!!!) In both cases they end up creating a bottleneck once you start caring about concurrent access not messing up your data.

If you use it like an RDMS it won't be. But if you're storing all of the related data as a document, using good algorithms when you have to join, it is faster. How much time do OO programmers spend denormalizing data and using bloated ORMs?

Sounds like you're married to the fact that data should be an [object].

> How much time do OO programmers spend denormalizing data and using bloated ORMs?

OO programmers that try to make data into objects sure. Those are the same programmers that love document based datastores because they don't have to think about their data - just get a nice "object" which fits their "everything must be an object" programming mindset.

Thing is, data is relational, and data isn't an object.

It's much better to use views of data, eg. "get me what I need to display a listing page in an eshop" - which entails getting the price, photos, title, description, delivery cost etc. - in a single list that you can then use - the database can do this for you - and all the underlying details are abstracted away, better yet - your app server will never have to CARE that at some points product.photos changed from being a simple array of strings to a fully fledged table - because the view remains the same.

> Again you should be storing the whole document with the relationships.

Okay so you're saving the entire list of 'followers' of a user inside the user document

What happens when you have a really popular user with a million followers...

What do you do when you update a user who happens to follow thousands of other users...

Oh you don't do it like that in that case? I guess... you're now relational.

Denormalization only helps with performance up to a certain degree, and in fact what you save on read access you pay dearly in update access or stupidly huge extra storage/memory.

Thing is, data is relational, and data isn't an object

Only if you are more concerned with the data first approach instead of thinking about the domain first.

It's much better to use views of data, eg. "get me what I need to display a listing page in an eshop" - which entails getting the price, photos, title, description, delivery cost etc. - in a single list that you can then use - the database can do this for you - and all the underlying details are abstracted away, better yet - your app server will never have to CARE that at some points product.photos changed from being a simple array of strings to a fully fledged table - because the view remains the same.

It's only "much better" until everyone wants there own one off view that has to be kept in sync with the code and reverting/branching/versioning has to keep in sync with what the hundreds of brittle views, stored procedures, etc. that are being created. Instead of treating the data store like a dumb data store. By putting as much logic in the business later as possible. I can not only branch, version, etc. I can completely unit test my whole application and mock out the data store.

Okay so you're saving the entire list of 'followers' of a user inside the user document What happens when you have a really popular user with a million followers... What do you do when you update a user who happens to follow thousands of other users...

Mongo best practices are to think about the orthoganility of your relationships - one to few, one to many, or "one to quintillions" and choose whether to embed based on that.

But going back to thinking in terms of DDD an aggregate roots, a user would be an entity, an address of the user would be a value type that belongs to the user - embed it into the document. A user's followers would be entities, that would be a related object that should be able to change independently. In that case use Mongo references.

and all the underlying details are abstracted away, better yet - your app server will never have to CARE that at some points product.photos changed from being a simple array of strings to a fully fledged table - because the view remains the same.

If I'm changing the representation of the data. I still have to change it somewhere - whether the database -- where you don't have proper versioning, branching, source control -- or the app server. If you're changing the representation in the app server in more than one module/microservice, you're doing it wrong. With a microservice/module, I can still represent the data as old clients expect by versioning the API and have much better tooling than have five different versions of the view that never die.

Flip side with the mentorship thing is not blocking out the senior dev's time to do the mentoring.

If the senior dev is supposed to mentor his junior teammates with no impact on the number of story points he grinds through then it's not reasonable for him to relish the thought of spending time peering with colleagues that he'll have to make up after hours.

> Developers who insist that their favorite technology is the best vs. what's the best for the task at hand, what technology will the team as a whole be successful with.

But we operate in a marketplace that wants to hire people based on their tech stack. So to keep their skills up they have to push for their stack.

Unfortunately, this describes a substantial percentage of "10x" engineers...
Despite your use as a pejorative, 10x is real. Developers who pound out mountains of spaghetti in whatever stack they want ignoring maintainability and best practices? I've heard the phrase "cowboy coders", or asshole works too.
Perhaps we ought to normalize the scale and call the other variety 0.1x engineers.