Thursday, December 17, 2015

Programming Misc



https://stackoverflow.com/questions/65718/what-do-the-numbers-in-a-version-typically-represent-i-e-v1-9-0-1
In version 1.9.0.1:
  • 1: Major revision (new UI, lots of new features, conceptual change, etc.)
  • 9: Minor revision (maybe a change to a search box, 1 feature added, collection of bug fixes)
  • 0: Bug fix release
  • 1: Build number (if used)—that's why you see the .NET framework using something like 2.0.4.2709
You won't find a lot of apps going down to four levels, 3 is usually sufficient.
https://docs.cloudfoundry.org/devguide/deploy-apps/blue-green.html
Blue-green deployment is a technique that reduces downtime and risk by running two identical production environments called Blue and Green.
At any time, only one of the environments is live, with the live environment serving all production traffic. For this example, Blue is currently live and Green is idle.
As you prepare a new version of your software, deployment and the final stage of testing takes place in the environment that is not live: in this example, Green. Once you have deployed and fully tested the software in Green, you switch the router so all incoming requests now go to Green instead of Blue. Green is now live, and Blue is idle.
This technique can eliminate downtime due to application deployment. In addition, blue-green deployment reduces risk: if something unexpected happens with your new version on Green, you can immediately roll back to the last version by switching back to Blue.
http://www.qulice.com/
Qulice is a static analysis quality control instrument for Java projects. It combines a few static analysis tools and pre-configure them. You don't need to use and configure them individually any more.

https://github.com/teamed/qulice
http://www.yegor256.com/2018/01/16/educational-aspect-of-static-analysis.html

https://blog.regehr.org/archives/1578
A text editor: We all end up using different editors from time to time, but we should each have a solid default choice that does a good job with most editing tasks. It should highlight and indent any common programming language, integrate with a spellchecker, easily load gigantic files, have nice regex-based search and replace, etc. There are plenty of choices, many CS people migrate to vim or emacs.
A graphing program: I routinely use gnuplot, graphviz, and Powerpoint to make figures. Lots of people like matplotlib.
A presentation tool: Powerpoint, Keynote, Google Slides, something LaTeX based, etc.
A shell language: This is probably bash or PowerShell, but there are plenty of other choices. There’s some overlap with scripting languages but I think there are two distinct niches here: a shell language is for scripting a smallish number of commands, doing a bit of error checking, and perhaps looping or interacting with the user slightly This sort of job is a bit too cumbersome in Python, Perl, or JavaScript.
A systems language: This is for creating servers, daemons, and other code that wants to go fast, use little memory, have few dependencies, and interact tightly with the OS. C or C++ would be the obvious choices, but Rust and Go may be fine too.
A workhorse language: This is your default programming language for most tasks, it should have a huge collection of high-quality libraries, be pretty fast, run on all common platforms, have a great tool ecosystem, etc. Racket, Java, Scala, OCaml, C#, Swift, or Haskell would be great — even C++ would work
http://www.yegor256.com/2018/03/06/speed-vs-quality.html
Here is a list of preventive measures it may take to make it impossible to jeopardize the quality:
What do I mean by saying that programmers must be interested in making changes? They have to be motivated to close tasks. Not just to be in the project, but to deliver. Here is what they can do in order to close tasks faster:
http://www.yegor256.com/2015/01/15/how-to-cut-corners.html
You spend hours just to find out how the code works. Then even more hours trying to fix it. In the end, you miss the deadline and everybody blames you

How can you do that? Create dependencies—new bugs complaining about unclear design, lack of unit tests, absence of necessary classes, or whatever. Be creative and offensive—in a constructive and professional way, of course. Don't get personal

Don't be a hero—don't rush into fixing the bad code you inherited. Think like a developer, not a hacker. Remember that your first and most important responsibility as a disciplined engineer is to help the project revealmaintainability issues. Who will fix them and how is the responsibility of a project manager. Your job is to reveal, not to hide. By being a hero and trying to fix everything in the scope of a single task, you're not doing the project a favor—you're concealing the problem(s).

Demand Better Documentation and Wait
You ask for a manual. You ask for documentation. Properly designed and written source code must be properly documented. Once you see that something is not clear for you, create new dependencies that ask for better documentation of certain aspects of the code.
Again, don't be a hero and try to understand everything yourself. Of course you're a smart guy, but the project doesn't need a single smart guy. The project needs maintainable code that is easy to modify, even by someone who is not as smart as yourself. So do your project a favor: reveal the documentation issue, and ask someone to fix it for you. Not just for you, for everybody. The entire team will benefit from such a request. Once the documentation is fixed, you will continue with your task, and everybody will get source code that is a bit better than it was before. Win-win, isn't it?

Reproduce the Bug and Call It a Day
Catch the bug with a unit test! Prove that the bug exists by failing the build with a new test.
Once you manage to reproduce the bug and the build fails, stop right there. That's more than enough for a single piece of work. Skip the test (for example, using @Ignore annotation in JUnit 4) and commit your changes. Then add documentation to the unit test you just created, preferably in the form of a @todo. Explain there that you managed to reproduce the problem but didn't have enough time to fix it. Or maybe you just don't know how to fix it. Be honest and give all possible details.
I believe that catching a bug with a unit test is, in most cases, more than 80% of success. The rest is way more simple: just fix the code and make the test pass. Leave this job to someone else.



https://mp.weixin.qq.com/s/62fTZoAU_ThqA50v9iY1TQ
我支持将逻辑写在 Java 等应用系统中。其实原因在上面基本描述完了,第一就是复杂 SQL 的表关联其实跟个人的能力有非常大的关系,如果一个 SQL 写得不好,那是极慢极慢的非常容易把整个数据库拖慢的。第二就是维护这些 SQL 也是一件很难受的事情,因为你完全不知道这个 SQL 背后的数据流转是怎样的,你只能根据自己的猜测去查看 SQL 中的 bug,Java 应用好歹还能 debug 一下还有打点看看数据不是?如果逻辑写在 Java 中那么其实你的 DAO 层只需要编写一次,但是可以永久使用,基本不会在这一层浪费很多的时间(用过 ibatis 的都知道改了 SQL 需要重启应用吧?)。第三就是逻辑都写在 SQL ,中对于分库分表和应用拆分来说是一件非常难受的事情,真的难受。
http://keepachangelog.com/en/1.0.0/
http://keepachangelog.com/en/0.3.0/

http://wiki.bash-hackers.org/scripting/terminalcodes
printf '%b\n' 'It is \033[31mnot\033[39m intelligent to use \033[32mhardcoded ANSI\033[39m codes!'
Tput accepts a set of acronyms called capability names and any parameters, if appropriate, then looks up the correct escape sequences for the detected terminal in the terminfo database and prints the correct codes (the terminal hopefully understands)
http://www.lihaoyi.com/post/BuildyourownCommandLinewithANSIescapecodes.html

https://segment.com/blog/engineering-best-practices/
https://segment.com/blog/building-building-blocks/
1. It’s easier to combine than to split apart.
structure code so that it’s easy to be split (or split from the beginning)
if a service or library doesn’t share concerns with existing ones, create a new one rather than shoe-horning it into an existing piece of code
testing and documenting libraries which perform a single function is much easier to understand
keep uptime, resource consumption and monitoring in mind when combining read/write concerns of a service
prefer libraries to frameworks, composing them together where possible

2. Explicit is better than implicit.
“Clever” code usually means “complicated” code. It’s hard to search for, and tough to track down where bugs are happening. We prefer simple code that’s explicit in it’s purpose rather than trying to create a magical API that relies on convention (go’s lack of “magic” is actually one of our favorite things about it).

As part of being explicit, always consider the “grep-ability” of your code. Imagine that you’re trying to find out where the implementation for the post method lives, which is easier to find in a codebase?

    var methods = ['post', 'put', 'get'];
    methods.forEach(method){
      Integration.prototype[method] = request(method);
    });

vs.

    Integration.prototype.post = function(){
     [...]
    };
Where possible, write code that is short, straightforward and easy to understand. Often that will come down to single functions that are easy to test and easy to document. Even libraries can perform just a single function and then be combined for more powerful functionality.

With comments, describe the “why” versus the typical “what” for a given process or routine. If a routine seems out of place but is necessary, it’s sometimes worth leaving a quick note as to why it exists at all.

avoid generating code dynamically or being overly ‘clever’ to shorten the line count
aim for functions that are <7 lines and <2 nested callbacks

3. It doesn’t ship without metrics and tests.
Running code in production without metrics or alerting is flying blind.
write test cases first to check for the broken behavior, then write the fix
all top-level apps should ship with metrics and monitoring
create ‘warning’ alerts for when an internal system is acting up, ‘critical’ ones when it starts affecting end customers
try to keep unrealistic failure scenarios in mind when designing the alerts

4. Cut scope aggressively.
When building a product, there are three aspects you can optimize: Speed, quality, and scope.
it’s usually best to cut scope. It allows us to split shipments into smaller, more manageable chunks, and really focus on making each one great.

evaluate features for their benefit versus their effort
identify features that could be easily layered in later
cut features that create obvious technical debt

5. Maintain a single code path.
have a peer review your code; an objective opinion will almost always help
get someone else to sign-off on non-trivial pull-requests
if you ever find yourself copy-pasting code, consider pulling it into a library
if you need to frequently update a library, or keep state around, turn it into a service

6. Create rapid prototypes.
Building something helps you learn more than you could ever hope to uncover through theorizing. Trust me, prototyping helps discover strange edge-cases and bottlenecks which may require you to rearchitect the solution. This process minimizes the impact of architectural changes.

don’t spend a lot of time with commit messages, keep them short but sensical
refactors typically come from a better understanding of the problem, the best way to get there is by building a version to “throw away”

7. Know when to automate.
if you find yourself repeatedly spending more than a few minutes on a task, take a step back and consider tooling around it
ask yourself if you could be 20% more efficient, or if automation would help
share tools in dotfiles, vm, or task runner so the whole team can use them

8. Aim to open source.
But in practice, it actually creates much cleaner code. We’re guaranteed that the code’s API isn’t tightly coupled to anything we’re building internally, and that it’s more easily re-used across projects.

Open sourced code typically has a well-documented Readme, tests, CI, and more closely resembles the rest of the ecosystem. It’s a good sanity check that we’re not doing anything too weird internally, and the code is easier to forget about and re-visit 6-months later.
if you build a general purpose library without any dependencies, it’s a prime target for open sourcing
try and de-couple code so that it can be used standalone with a clear interface
never include custom configuration in a library, allow it to be passed in with sane defaults

9. Solve the root cause.
Sometimes big problems arise in code and it may seem easier to write a work-around. Don’t do that. Hacking around the outskirts of a problem is only going to create a rat’s nest that will become an even bigger problem in the future. Tackle the root cause head-on.

Sometimes it’s worth taking a step back to solve the root cause or upstream problem rather than hacking around the periphery. Even if it requires a more significant restructuring, it can save you a lot of time and headache down the road, allowing you to achieve much greater scale.

whenever fixing a bug or infrastructure issue, ask yourself whether it’s a core fix or just a band-aid over one of the symptoms
keep tabs on where you’re spending the most time, if code is continually being tweaked, it probably needs a bigger overhaul
if there’s some bug or alert we didn’t catch, make sure the upstream cause is being monitored

10. Design models by concern.
When designing applications, coming up with a data model is one of the trickiest parts of implementation. The frontend, naturally, wants to match the user’s idea of how the data is formatted. Out of necessity, the backend has to match the actual data format. It must be stored in a way that is fast, performant and flexible.

So when starting with a new design, it’s best to first look at the user requirements and ask “which goals do we want to meet?” Then, look at the data we already have (or decide what new data you need) and figure out how it should be combined.

The frontend models should match the user’s idea of the data. We don’t want to have to change the data model every time we change the UI. It should remain the same, regardless of how the interface changes.

The service and backend models should allow for a flexible API from the programmer’s perspective, in a way that’s fast and efficient. It should be easy to combine individual services to build bigger pieces of functionality.

The controllers are the translation layer, tying together individual services into a format which makes sense to the frontend code. If there’s a piece of complicated logic which makes sense to be re-used, then it should be split into it’s own service.

the frontend models should match the user’s conception of the data
the services need to map to a data model that is performant and flexible
controllers can map between services and the frontend to assemble data
Our engineering best practices, in practice.

In practice, this means that we invest heavily in good tooling, modular libraries and microservices. In development, we keep a shared VM that auto-updates, with shared dotfiles for easily navigating our many small repositories. We put a focus on creating projects which increase functionality through composability rather than inheritance. And we’ve worked hard to streamline our process for running services in production.
http://finalshares.com/read-3228?jike-1862

1.能出版出来的书一定是经过反复的思考、雕琢和审核的,因此从专业性的角度来说,一本好书的价值远超其他资料
2.对着书上的代码自己敲的时候方便
“看完书之后再次提升自我的最好途径是看一些相关的好博文“,我个人认为这是学习的第二步,因为一本书往往有好几百页,好的博文是自己看书学习之后的一些总结和提炼,对于梳理学习的内容很有好处,当然这里不是说自己的学习方法,就不再扯下去了。

云思路 | 轻松构建千万级的投票系统
自建的服务真的不靠谱,云是首选

我们就拿负载均衡举例。很多人可能觉得现在负载均衡软件已经很多,而且性能都很好,也很稳定,用的人也很多,不管拿个Nginx过来,还是拿个HAProxy过来,都可以分分钟部署一套负载均衡,包括阿里云的负载均衡其实就是用Nginx构建起来的。



但是,如果你有量上来,我们不说你单台的负载均衡服务器会不会挂掉(如果要防挂,就要多台,有了多台,负载均衡前面还要再加负载均衡,或者DNS轮循,或者VIP等),就是单台负载均衡要抗住并发的连接,就需要考虑很多的事情:



  • 一台Linux服务器做负载均衡,很多人想着,负载均衡就是转发转发流量,所以,我只要后面多加点机器,就可以抗住并发了。真的是这样吗?你要知道,负载均衡向后端的服务器做连接,作为客户端的负载均衡,也是会消耗本地的一个随机端口的,也许你知道,你可以在 /etc/sysctl.conf 修改 net.ipv4.ip_local_port_range=1024 65535,也就是说,你可以有 65535 - 1024 = 64511 个随机端口可以用,而这个配置,限制你一分钟的并发连接数是 64511 个,也就是说,每秒你最多可以服务 1000 个并发连接。为什么是一分钟64511 个?如果你不清楚,那也还是不要自建的好。
  • 1000个最大并发连接的负载均衡服务器,你需要加大内存还是CPU呢?
  • 百度来的网络参数调优有用吗?想想,如果你的负载均衡服务器是后端服务器的客户端,socket的keep-alive以及timeout的时长应该怎么来配置?



如果还要考虑到HA,那需要考虑的事情就更多了。



所以,最简单的方案,还是拿来主义 - 。不管是从人的成本考虑,还是从风险控制的角度考虑,各大主流的云平台,一定比大部分团队的经验更丰富。虽然很多人对云服务的稳定性存在诸多质疑,但是,做为小团队的你,你自己构建的服务就真比它更稳定吗?
我和大胖哥沟通,他事后告诉,他们其实并没有做到100%防刷,或者说,因为时间限制,只做了一层很粗暴的限制:

  • 每个IP限制投票100次;每个人10票的限制通过COOKIE来做
  • 每个IP限制抽奖20次;每个人1次的抽奖限制通过COOKIE来做

每个IP做限制,稍微高出一点规则里的10次,主要是考虑到了NAT的网络,很多公司出口都是一个IP地址。另外,也因为运营上的考虑,并没有接入和打通蜻蜓的用户体系。
  • 抽奖的结果记录用户的来源IP
  • 每个一个小时,自动分析中奖用户是否为“刷奖”:根据中奖的IP,分析该IP的投票次数和抽奖次数,对于不满足10次投票和1次抽奖的中奖者,统统踢出去。

原则:在当前的版本基础上,最小化开发资源,也就是尽量不改目前的投票系统同时尽量不写代码来完成。


预写日志(WAL)介绍
预写日志(WAL,Write Ahead Log)是关系型数据库中用于实现事务性和持久性的一系列技术。简单来说就是,做一个操作之前先讲这件事情记录下来。
真正的执行操作可能数据量会比较大,操作比较繁琐,并且写数据不一定是顺序写,所以如果每一次操作都要等待结果flush到可靠存储(比如磁盘)中才执行下一步操作的话,效率就太低了。换一种思路,如果我们在做真正的操作之前,先将这件事记录下来,持久化到可靠存储中(因为日志一般很小,并且是顺序写,效率很高),然后再去执行真正的操作。这样执行真正操作的时候也就不需要等待执行结果flush到磁盘再执行下一步,因为无论在哪一步出错,我们都能够根据备忘录重做一遍,得到正确的结果。

http://www.codeceo.com/article/programming-level.html
7段—架构设计
还需要掌握架构设计的能力,才能设计出优秀的软件。架构设计有一些技巧:
1、分层
一个软件通常分为:
表现层–UI部分
接口层–后台服务的通讯接口部分
服务层–实际服务部分
存储层—持久化存储部分,存储到文件或者数据库。
分层的软件,可以解耦各个模块,支持并行开发,易于修改,易于提升性能。
2、SOA
模块之间通过网络通讯互相连接,松耦合。每一个模块可以独立部署,可以增加部署实例从而提高性能。每一个模块可以使用不同的语言和平台开发,可以重用之前开发的服务。SOA,常用协议有WebService,REST,JSON-RPC等。
3、性能瓶颈
1)化同步为异步。
用内存队列(Redis),工作流引擎(JBpm)等实现。内存队列容易丢失数据,但是速度快。工作流引擎会把请求保存到数据库中。
通过化同步请求为异步请求,基本上99.99%的性能问题都可以解决。
2)用单机并行硬件处理。
如,使用GPU,FPGA等硬件来处理,提高性能。
3)用集群计算机来处理。
如,Hadoop集群,用多台计算机来并行处理数据。
自己的软件栈中,也可以把一个模块部署多份,并行处理。
4)用cache来满足请求。常用的内容加热cache后,大量的用户请求都只是内存读取数据而已,性能会得到很大的提升。
cache是上帝算法,记得好像它的性能只比最佳性能低一些,就好像你是上帝,能够预见未来一样。现在X86CPU遇到了主频限制,CPU提升性能的主要途径就是增加高速Cache了。
4、大系统小做
遇到大型系统不要慌,把它切分成多个模块,用多个小程序,通过SOA协作来解决。这秉承了Unix的设计思想。Unix上开发了大量单一目的的小程序,它主张用户通过管道来让多个小程序协作,解决用户的需求。当然,管道方式通讯限制太多,不够灵活。因此,现在我们可以通过URI,通过SOA的方式来让多个程序协作。Andorid和iOS上的应用程序,现在都是通过URI实现协作的。这也算是Unix设计思想的现代发展吧?!
5、Sharding切片
现在有一个潮流,就是去IOE。I-IBM大型机,O-Oracle数据库,E-EMC存储。之前,大型系统常用IOE去架构,在大型机上部署一个Oracle数据库,Oracle数据库用EMC存储保存数据。IOE是当今最强的计算机,数据库和存储。但他们面对海量系统也有抗不住的一天。
Oracle数据库是Shareeverything的,它可以在一个计算机集群(服务器节点不能超过16个)上运行。计算机集群都共用一个存储。
去IOE运动,标志着ShareEverything模式的破产。必须使用ShareNothing,系统才能无限扩展。
用MySQL数据库就可以应付任意规模的数据了。前提是,你会Sharding分片。把大系统切分成若干个小系统,切分到若干台廉价服务器和存储上。更Modern一些,就是切分到大量虚拟机上。
如,铁道部的12306网站。我们知道火车票都是从属于某一列列车的。那么我们把每一个列车作为一个单元来切分,就可以把12306网站切分成几千个模块。一台虚拟机可以承载若干个模块。当某些列车成为性能瓶颈之后,就可以把它们迁移到独立的虚拟机上。即使最终有部分列出服务不可用,系统也不会完全不可用。
12306网站,只有一个全局的部分,就是用户登录。这个可以交给第三方负责。如可以让用户用微信,微博,qq等账户登录。
也可以自己实现用户登录服务。还是用切片的方式用多台Redis服务器提供服务。Redis服务器存储每一个登录用户的sessionId和userId,角色,权限等信息。sessionId是随机生成的,可选择其部分bit用于标识它在哪一个Redis服务器上。用户登录后,把sessionId发给客户。用户每次请求时把sessionId发回给服务器。服务器把sessionId发给Redis服务器查询得到其用户信息,对用户请求进行处理。如果在redis服务器上找不到sessionId,则让用户去登录。即使所有注册用户同时登陆,也不需要太多的内存。而且,可以在session内存过多时,删除最早登陆的用户的session,强制他再次登陆。同时活跃的用户数不会太多。
领域知识层次
前面的所有层次,都是关注编程本身的技能,说白了,就是基本功,本身并不能产生太大的价值。但有太多的程序员浪费太多的时间在那些筑基的层次上。
有些程序员特别喜欢钻研编程语言,每有一种新的编程语言出来或者旧语言被热炒,就会投入精力进去研究。我就是其中之一,浪费了很多精力在编程语言上,在奇技淫巧上。
我觉得C++语言是一个特别大的坑。刚开始是作为面向对象的C被开发的。后来发现了模板编程,就大力鼓吹模板编程和进一步的模板元编程。最近又推出了C++11,C++14等新标准,进一步添加了很多新东西,函数式编程,类型推断等。C++过分复杂,太多的坑消耗了大量程序员的大量精力。我使用C++时,只使用面向对象部分和模板部分,其他过于精深的特性都不使用。
计算机科学是一个面相当广泛的学科,有很多领域知识需要和值得我们深入研究,我们才能写出有价值的程序来。软件必须要和行业结合起来,要落地才有价值。仅仅研究编程技巧,不懂领域知识是写不出有价值的程序的。
计算机科学领域有很多,列举一些如下:
存储—-块设备,文件系统,集群文件系统,分布式文件系统,光纤SCSI,iSCSI,RAID等。
网络—-以太网,光纤网,蜂窝网络,WIFI,VLAN等。
计算机体系结构,主要就是CPU指令集。x86,ARM等。
USB协议。需要知道URB包。
PCI协议,PCI-E协议。现代计算机的外设都是PCI协议和PCI-E协议的。显卡现在全是通过 PCI-E协议连接到计算机上的。相对来说减少了很多需要学习的知识。搞虚拟化就需要深入掌握PCI协议。
图像处理–图像压缩,视频实时编码等。
3D游戏
关系数据库
NoSQL数据库
操作系统
分布式操作系统
编译原理
机器学习–现在大数据要用哦!
了解这些领域知识,也包括了解该领域现有的商用硬件、商用软件和开源软件。很多时候,你要完成的工作,已经有现成的工具了。你只要使用现成的工具就可以完成任务,不需要进行开发。有时候,只需要组合现有的工具,写一些脚本就可以完成任务。
如,我一次要实现一个双向同步任务。找到了一个优秀的开源软件Unison,编写一下配置文件就圆满地完成了任务。不需要编写任何代码。
还有一次,要做高可用,用Python调用了几个开源软件就轻松实现了。
编写安装程序,定制操作系统,知道了操作系统的领域知识,写几行脚本就可以轻松搞定。
不具备领域知识的人,就可能不得不进行大量无谓的开发,甚至开发很久之后才发现,这根本就是一条死路。
另外,扎实的领域知识,可以大大提高编程调试、查错的能力。知道编译器和编程语言运行时工作原理,就能快速根据编译错误和警告信息修改代码。
知道操作系统底层运行机制,就能快速找到运行时错误的问题根源。如,有一次我编写一个windows升级服务程序。它是一个windows服务,需要执行dos脚本,这个脚本会替换掉这个windows服务本身。发现有时脚本执行无效,查了一晚上,发现当windows服务安装后,第一次启动就执行脚本时就会有权限问题,log都正确,但实际执行这个脚本没有任何效果。但一旦windows服务程序启动一次之后就ok。这必然是windows操作系统底层安全机制的问题,因为我对Windows内核了解不多,因此花了很长时间才发现这个问题,并对造成这个问题的根%E
https://blog.enki.com/coding-is-boring-unless-4e496720d664
Maintaining legacy code is boring

A large, monolithic code base with complex dependencies requires extra maintenance work. In contrast, a well architected micro-service infrastructure is a bit more flexible. When a micro-service becomes faulty, you can replace it. You can rewrite it from scratch, using a different language or technology. This way, you learn something new rather than patching legacy code. And if your architecture doesn’t allow this yet, you can take steps to improve it, and learn some devops skills in the process.

A microservice strategy is only one among other possible ways to approach a problem of “boring” maintenance. What some places do is to build smart tools to make the maintenance more efficient and fun.

Internal tools are usually boring
As developers, we like to create custom internal tools to solve specific problems, because creating new things is exciting. Also, building tailored solutions often feels cleaner than repurposing existing ones. But learning a proprietary tool is about 10x less interesting than learning a popular open-source technology.
Why?
Because you can’t talk to your friends about it; you can’t brag about knowing it; you can’t read about it on Hacker News; you can’t use it during hackathons.; you can’t use it in your secret side project.
But a lot of companies fall into the trap of creating things that are not worth the boredom they create. In other words: they solve a short-term frustration only to cause more frustration in the long-term.

We try to keep a strong bias for open source technologies. If we can reuse something relevant and exciting, we do it. We don’t shy away from the cutting edge. We throw away our custom code as soon as an open source technology becomes mature enough to replace it. And when our own custom code becomes generic enough, we open source it.

Labels

Review (572) System Design (334) System Design - Review (198) Java (189) Coding (75) Interview-System Design (65) Interview (63) Book Notes (59) Coding - Review (59) to-do (45) Linux (43) Knowledge (39) Interview-Java (35) Knowledge - Review (32) Database (31) Design Patterns (31) Big Data (29) Product Architecture (28) MultiThread (27) Soft Skills (27) Concurrency (26) Cracking Code Interview (26) Miscs (25) Distributed (24) OOD Design (24) Google (23) Career (22) Interview - Review (21) Java - Code (21) Operating System (21) Interview Q&A (20) System Design - Practice (20) Tips (19) Algorithm (17) Company - Facebook (17) Security (17) How to Ace Interview (16) Brain Teaser (14) Linux - Shell (14) Redis (14) Testing (14) Tools (14) Code Quality (13) Search (13) Spark (13) Spring (13) Company - LinkedIn (12) How to (12) Interview-Database (12) Interview-Operating System (12) Solr (12) Architecture Principles (11) Resource (10) Amazon (9) Cache (9) Git (9) Interview - MultiThread (9) Scalability (9) Trouble Shooting (9) Web Dev (9) Architecture Model (8) Better Programmer (8) Cassandra (8) Company - Uber (8) Java67 (8) Math (8) OO Design principles (8) SOLID (8) Design (7) Interview Corner (7) JVM (7) Java Basics (7) Kafka (7) Mac (7) Machine Learning (7) NoSQL (7) C++ (6) Chrome (6) File System (6) Highscalability (6) How to Better (6) Network (6) Restful (6) CareerCup (5) Code Review (5) Hash (5) How to Interview (5) JDK Source Code (5) JavaScript (5) Leetcode (5) Must Known (5) Python (5)

Popular Posts