It's the 6th year the boy participated the competition and he got his 4th major bursary.
I started programming at his age now and won 4 awards before I went to university studying computer science. That's a connection spanning nearly 30 years between a father and a son.
Sunday, November 23, 2014
Friday, November 07, 2014
Method names are new (redundant) comments
It's very interesting to see how developers react to commonly accepted coding conventions.
We all know methods should be short, and comments can be avoided when methods are short and with meaningful names. But by following these conventions, we sometimes only generate another form of redundant comments. Let me explain it with an example.
if (feeType == FeeType.PERCENTAGE) {
...
}
What's the problem here? It reads not like in human language, or not DSL enough. Let's extract the condition to a one-liner method, and make the method name suitable to be appeared after if.
if (feeIsBasedOnPercentage(feeType)) {
...
}
We all know methods should be short, and comments can be avoided when methods are short and with meaningful names. But by following these conventions, we sometimes only generate another form of redundant comments. Let me explain it with an example.
if (feeType == FeeType.PERCENTAGE) {
...
}
What's the problem here? It reads not like in human language, or not DSL enough. Let's extract the condition to a one-liner method, and make the method name suitable to be appeared after if.
if (feeIsBasedOnPercentage(feeType)) {
...
}
Much better, right? Now the question is, if the condition needs further explanation, why not explain it directly with a comment side by side, like this.
if (feeType == FeeType.PERCENTAGE) {
// fee is based on percentage
...
}
// fee is based on percentage
...
}
No, this's not good. The comment looks like redundant. It just repeats what's in the if statement. Okay, let's remove the redundant comment.
if (feeType == FeeType.PERCENTAGE) {
...
}
...
}
So, what was the question again?
If you find yourself extract / write
- a very short, usually one-liner, method, and
- it's only called once, and
- method name is repeating what's in the body
private boolean feeIsBasedOnPercentage(FeeType feeType) {
return feeType == FeeType.PERCENTAGE;
}
return feeType == FeeType.PERCENTAGE;
}
Finally, I'd like to guess how this redundant way of programming was developed, just for fun.
private boolean feeIsBasedOnPercentage(FT ft) {
return ft == FT.P;
}
Hope you get the idea of why I call it redundant. If you do, Dependency is the new Inheritance is another one for you.
Disclaimer, code snippets used here are for illustration only.
return ft == FT.P;
}
Hope you get the idea of why I call it redundant. If you do, Dependency is the new Inheritance is another one for you.
Disclaimer, code snippets used here are for illustration only.
Thursday, August 07, 2014
Are you setting Connect Timeout correctly?
Application development nowadays is becoming more and more like mashing up. Unless you provide file storage service, or data repository service, there's no way you can avoid consuming 3rd party APIs / (micro-) services. In Java battlefield, most of the time, internal or external APIs are provided via RESTful interface. If this is the case, chances are to consume a web service you'll be using one of
- org.springframework.web.client.RestTemplate
- org.apache.http.impl.client.HttpClientBuilder, or its cached version
- org.apache.http.impl.client.cache.CachingHttpClientBuilder
- org.apache.http.impl.client.DefaultHttpClient, or its fluent version
- org.apache.http.client.fluent.Request
No matter which one you end up use, it's always a good practice to set timeout for HTTP clients, and this can be done only by org.apache.http.client.config.RequestConfig. Now can you please check the value you pass into RequestConfig.Builder#setConnectTimeout()? If it's significantly larger than 5(ms, not a typo here), you're not setting it correctly.
Connect timeout is used to provide QoS of the creation of TCP connection between client and server, not the whole lifecycle of the connection, or in pooled environment, from borrow to return. If this process can't finish in few milliseconds, org.apache.http.conn.ConnectTimeoutException should be thrown to speed up the exception handling. It's not the end of the world however, if you misuse it. It's just better to fail fast in case something goes wrong for better user experience, rather than wasting the x seconds you set.
Then how about the RequestConfig.Builder#setSocketTimeout()? Well, I may have another post on it. Until then, it's more like the meaning you think setConnectionTimeout has.
Never take anything for granted.
Connect timeout is used to provide QoS of the creation of TCP connection between client and server, not the whole lifecycle of the connection, or in pooled environment, from borrow to return. If this process can't finish in few milliseconds, org.apache.http.conn.ConnectTimeoutException should be thrown to speed up the exception handling. It's not the end of the world however, if you misuse it. It's just better to fail fast in case something goes wrong for better user experience, rather than wasting the x seconds you set.
Then how about the RequestConfig.Builder#setSocketTimeout()? Well, I may have another post on it. Until then, it's more like the meaning you think setConnectionTimeout has.
Never take anything for granted.
Wednesday, July 02, 2014
Glad I'm of some help
I'm no way near a productive blogger. Even though I've got only 80 posts in nearly 5 years, some of them are referred by more popular bloggers, which is definitely helping more people and, at the same time, giving me the credit.
Empathy and Samba by http://www.abclinuxu.cz/poradna/linux/show/287722
Schema of iTunes podcast feed by http://wiki.bcmoney-mobiletv.com/index.php?title=ITunes
Let scim and ibus support Skype by http://zazchor.me/blog/2013/09/13/fix-ibus-not-working-with-skype-4-dot-2-in-ubuntu-12-dot-04/
How to install Adobe Flash plugin on Ubuntu 12.04 by http://howaryoo.wordpress.com/2012/08/10/ubuntu-12-04-lts-new-install-oracle-java-and-flash/
Java development using Ubuntu 11.10 and OpenJDK 7 by https://twitter.com/taq/status/125972118000242689
Let's keep up sharing / open-sourcing knowledge.
Empathy and Samba by http://www.abclinuxu.cz/poradna/linux/show/287722
Schema of iTunes podcast feed by http://wiki.bcmoney-mobiletv.com/index.php?title=ITunes
Let scim and ibus support Skype by http://zazchor.me/blog/2013/09/13/fix-ibus-not-working-with-skype-4-dot-2-in-ubuntu-12-dot-04/
How to install Adobe Flash plugin on Ubuntu 12.04 by http://howaryoo.wordpress.com/2012/08/10/ubuntu-12-04-lts-new-install-oracle-java-and-flash/
Java development using Ubuntu 11.10 and OpenJDK 7 by https://twitter.com/taq/status/125972118000242689
Let's keep up sharing / open-sourcing knowledge.
Sunday, June 08, 2014
Couchbase and couchbase-client
If you got this when starting Couchbase,
Port server memcached on node 'babysitter_of_ns_1@127.0.0.1' exited with status 71. Restarting. Messages: Thu Oct 3 14:13:51.448736 EST 3: failed to ensure corefile creation
make below changes in /etc/security/limits.conf
couchbase hard nofile 10240
couchbase hard core unlimited
See http://www.couchbase.com/issues/browse/MB-4727
If you got exception about XML datatype like this, exclude org.codehaus.jettison:jettison from couchbase:couchbase-client will solve it.
13:50:00,995 ERROR [[resteasy-servlet]] Servlet.service() for servlet resteasy-servlet threw exception
java.lang.LinkageError: loader constraint violation: when resolving field "DATETIME" the class loader (instance of org/jboss/classloader/spi/base/BaseClassLoader) of the referring class, javax/xml/datatype/DatatypeConstants, and the class loader (instance of ) for the field's resolved type, javax/xml/namespace/QName, have different Class objects for that type
at com.sun.xml.bind.v2.model.impl.RuntimeBuiltinLeafInfoImpl.(RuntimeBuiltinLeafInfoImpl.java:267)
at com.sun.xml.bind.v2.model.impl.RuntimeTypeInfoSetImpl.(RuntimeTypeInfoSetImpl.java:65)
at com.sun.xml.bind.v2.model.impl.RuntimeModelBuilder.createTypeInfoSet(RuntimeModelBuilder.java:133)
at com.sun.xml.bind.v2.model.impl.RuntimeModelBuilder.createTypeInfoSet(RuntimeModelBuilder.java:85)
at com.sun.xml.bind.v2.model.impl.ModelBuilder.(ModelBuilder.java:156)
at com.sun.xml.bind.v2.model.impl.RuntimeModelBuilder.(RuntimeModelBuilder.java:93)
at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:450)
at com.sun.xml.bind.v2.runtime.JAXBContextImpl.(JAXBContextImpl.java:298)
at com.sun.xml.bind.v2.runtime.JAXBContextImpl.(JAXBContextImpl.java:141)
at com.sun.xml.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1157)
at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:145)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
Wednesday, March 12, 2014
install Docker on Ubuntu 13.10
$ sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys D8576A8BA88D21E9
$ sudo sh -c "echo deb http://get.docker.io/ubuntu docker main\ > /etc/apt/sources.list.d/docker.list"
$ sudo apt-get update
$ sudo apt-get install lxc-docker
$ sudo docker version
Client version: 0.9.0
Go version (client): go1.2.1
Git commit (client): 2b3fdf2
Server version: 0.9.0
Git commit (server): 2b3fdf2
Go version (server): go1.2.1
Last stable version: 0.9.0
$ sudo docker search ubuntu | grep '^ubuntu'
ubuntu General use Ubuntu base image. Tags availa... 108
ubuntu-upstart 0
ubuntu/ping 0
$ sudo docker pull ubuntu:saucy
Pulling repository ubuntu
9f676bd305a4: Download complete
511136ea3c5a: Download complete
1c7f181e78b9: Download complete
$ sudo docker images -a
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
ubuntu saucy 9f676bd305a4 5 weeks ago 178 MB
<none> <none> 1c7f181e78b9 5 weeks ago 0 B
<none> <none> 511136ea3c5a 9 months ago 0 B
$ sudo docker run -i -t -privileged=true ubuntu:saucy /bin/bash
# apt-get install openjdk-7-jdk
# exit
$ sudo docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6a3720326142 ubuntu:saucy /bin/bash 2 hours ago Exit 0 stupefied_bell
$ sudo docker commit 6a3720326142 jerry/ubuntu13.10_java7
5d7e72d6b3a571f384efdbe31418f47b7d32eb6e5df9fe5c7c5357dc07843f86
$ sudo docker images -a
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
jerry/ubuntu13.10_java7 latest 5d7e72d6b3a5 3 minutes ago 512.5 MB
ubuntu saucy 9f676bd305a4 5 weeks ago 178 MB
<none> <none> 1c7f181e78b9 5 weeks ago 0 B
<none> <none> 511136ea3c5a 9 months ago 0 B
$ sudo docker rmi IMAGE_ID
$ sudo docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2aec90f4a9c3 jerry/ubuntu13.10_java7:latest /bin/bash 2 hours ago Exit -1 nostalgic_pike
6a3720326142 ubuntu:saucy /bin/bash 2 hours ago Exit 0 stupefied_bell
$ sudo docker rm CONTAINER_ID
$ sudo docker run jerry/ubuntu13.10_java7 java -version
WARNING: Local (127.0.0.1) DNS resolver found in resolv.conf and containers can't use it. Using default external servers : [8.8.8.8 8.8.4.4]
java version "1.7.0_51"
OpenJDK Runtime Environment (IcedTea 2.4.4) (7u51-2.4.4-0ubuntu0.13.10.1)
OpenJDK 64-Bit Server VM (build 24.45-b08, mixed mode)
$ sudo docker start 2aec90f4a9c3
$ sudo docker attach 2aec90f4a9c3
ifconfig
eth0 Link encap:Ethernet HWaddr 0e:5a:8f:4b:46:a3
inet addr:172.17.0.2 Bcast:0.0.0.0 Mask:255.255.0.0
inet6 addr: fe80::c5a:8fff:fe4b:46a3/64 Scope:Link
UP BROADCAST RUNNING MTU:1500 Metric:1
RX packets:18 errors:0 dropped:0 overruns:0 frame:0
TX packets:15 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:1687 (1.6 KB) TX bytes:1014 (1.0 KB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
$ sudo docker stop 2aec90f4a9c3
$ sudo sh -c "echo deb http://get.docker.io/ubuntu docker main\ > /etc/apt/sources.list.d/docker.list"
$ sudo apt-get update
$ sudo apt-get install lxc-docker
$ sudo docker version
Client version: 0.9.0
Go version (client): go1.2.1
Git commit (client): 2b3fdf2
Server version: 0.9.0
Git commit (server): 2b3fdf2
Go version (server): go1.2.1
Last stable version: 0.9.0
$ sudo docker search ubuntu | grep '^ubuntu'
ubuntu General use Ubuntu base image. Tags availa... 108
ubuntu-upstart 0
ubuntu/ping 0
$ sudo docker pull ubuntu:saucy
Pulling repository ubuntu
9f676bd305a4: Download complete
511136ea3c5a: Download complete
1c7f181e78b9: Download complete
$ sudo docker images -a
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
ubuntu saucy 9f676bd305a4 5 weeks ago 178 MB
<none> <none> 1c7f181e78b9 5 weeks ago 0 B
<none> <none> 511136ea3c5a 9 months ago 0 B
$ sudo docker run -i -t -privileged=true ubuntu:saucy /bin/bash
# apt-get install openjdk-7-jdk
# exit
$ sudo docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6a3720326142 ubuntu:saucy /bin/bash 2 hours ago Exit 0 stupefied_bell
$ sudo docker commit 6a3720326142 jerry/ubuntu13.10_java7
5d7e72d6b3a571f384efdbe31418f47b7d32eb6e5df9fe5c7c5357dc07843f86
$ sudo docker images -a
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
jerry/ubuntu13.10_java7 latest 5d7e72d6b3a5 3 minutes ago 512.5 MB
ubuntu saucy 9f676bd305a4 5 weeks ago 178 MB
<none> <none> 1c7f181e78b9 5 weeks ago 0 B
<none> <none> 511136ea3c5a 9 months ago 0 B
$ sudo docker rmi IMAGE_ID
$ sudo docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2aec90f4a9c3 jerry/ubuntu13.10_java7:latest /bin/bash 2 hours ago Exit -1 nostalgic_pike
6a3720326142 ubuntu:saucy /bin/bash 2 hours ago Exit 0 stupefied_bell
$ sudo docker rm CONTAINER_ID
$ sudo docker run jerry/ubuntu13.10_java7 java -version
WARNING: Local (127.0.0.1) DNS resolver found in resolv.conf and containers can't use it. Using default external servers : [8.8.8.8 8.8.4.4]
java version "1.7.0_51"
OpenJDK Runtime Environment (IcedTea 2.4.4) (7u51-2.4.4-0ubuntu0.13.10.1)
OpenJDK 64-Bit Server VM (build 24.45-b08, mixed mode)
$ sudo docker start 2aec90f4a9c3
$ sudo docker attach 2aec90f4a9c3
ifconfig
eth0 Link encap:Ethernet HWaddr 0e:5a:8f:4b:46:a3
inet addr:172.17.0.2 Bcast:0.0.0.0 Mask:255.255.0.0
inet6 addr: fe80::c5a:8fff:fe4b:46a3/64 Scope:Link
UP BROADCAST RUNNING MTU:1500 Metric:1
RX packets:18 errors:0 dropped:0 overruns:0 frame:0
TX packets:15 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:1687 (1.6 KB) TX bytes:1014 (1.0 KB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
$ sudo docker stop 2aec90f4a9c3
Monday, March 03, 2014
Maven 3.1 and 3.2 are incompatible with 3.0
As title says, Apache Maven 3.1.x and 3.2.x are not compatible with 3.0.x, and this may affect your artifacts.
The main difference is whether or not, the default (compile) scope dependencies in a test, or provided scope dependency will be included in the final artifact, if you know what I mean.
In Maven 3.0, all the compile scope dependencies in test or provided scope dependencies will be included, unless they're overwritten by others in any ways.
In Maven 3.1 and 3.2 however, all the compile scope dependencies in test or provided scope dependencies will NOT be included, unless they overwrite others in any ways.
Personally, I like what Maven 3.1 and 3.2 are doing. Just a heads up you may get hurt by including ugly designed test or provided dependencies.
Wednesday, February 19, 2014
Dependency is the new Inheritance
To warm up, please have a read how bad inheritance is.
disadvantages of inheritance in java
Why extends is evil
Okay, dependency is the new inheritance, just even harder to do it right.
With inheritance, you extend something means you decide to be it, just a bit special. It's more base classes' responsibilities to make sure it doesn't become something else. With dependency however, you introduce a dependency just because it has something that's useful to you, no matter how much in it you don't need at all. Check the exclusions in pom.xml to see how many dependencies, direct or indirect, you included and later you found they caused trouble. Isn't this the new Refused Bequest, except there's no better way to solve it?
With versioned dependency, you changed something but others depend on it don't know if it breaks their part. "If it ain't broke, don't fix it". They choose to stick with the old version of what you've changed, and not to move forward with you. Without their following and feedback, you make further changes more freely, knowing that only part, if any, of your users bother to follow what you're doing.
Popular languages, like C# and Java, only allow single inheritance to avoid the potential problem caused by multiple inheritance. This makes inheritance less dangerous for everyday use. But you are free to depend on no matter how many dependencies. Very likely, those dependencies depend on difference versions of same module, directly or indirectly. Then it becomes your job if this doesn't work and you have to manually exclude all but one, the one that can fit all. Put it simply, you have to manage and solve dependency conflict, which is never part of your job in single inheritance paradigm.
Hope I'm clear and to the point by now why dependency is the new inheritance. Versioned dependency is the root of Dependency Hell? Not really, but you must have the skills and experience to handle it.
disadvantages of inheritance in java
Why extends is evil
Okay, dependency is the new inheritance, just even harder to do it right.
With inheritance, you extend something means you decide to be it, just a bit special. It's more base classes' responsibilities to make sure it doesn't become something else. With dependency however, you introduce a dependency just because it has something that's useful to you, no matter how much in it you don't need at all. Check the exclusions in pom.xml to see how many dependencies, direct or indirect, you included and later you found they caused trouble. Isn't this the new Refused Bequest, except there's no better way to solve it?
With versioned dependency, you changed something but others depend on it don't know if it breaks their part. "If it ain't broke, don't fix it". They choose to stick with the old version of what you've changed, and not to move forward with you. Without their following and feedback, you make further changes more freely, knowing that only part, if any, of your users bother to follow what you're doing.
Popular languages, like C# and Java, only allow single inheritance to avoid the potential problem caused by multiple inheritance. This makes inheritance less dangerous for everyday use. But you are free to depend on no matter how many dependencies. Very likely, those dependencies depend on difference versions of same module, directly or indirectly. Then it becomes your job if this doesn't work and you have to manually exclude all but one, the one that can fit all. Put it simply, you have to manage and solve dependency conflict, which is never part of your job in single inheritance paradigm.
Hope I'm clear and to the point by now why dependency is the new inheritance. Versioned dependency is the root of Dependency Hell? Not really, but you must have the skills and experience to handle it.
Subscribe to:
Posts (Atom)