跳至主要内容

博文

目前显示的是 八月, 2016的博文

Mysql Learning Time And Locking

Mysql time related learning notes. timestamp vs datetime range the TIMESTAMP type’s range is ‘1970-01-01 00:00:01’ UTC to ‘2038-01-09 03:14:07’ UTC. the DATETIME type’s range is ‘1000-01-01 00:00:00’ to ‘9999-12-31 23:59:59’. why I can set timestamp a invalid default value That is because of server SQL Mode - NO_ZERO_DATE. From the reference: NO_ZERO_DATE - In strict mode, don’t allow ‘0000-00-00’ as a valid date. You can still insert zero dates with the IGNORE option. When not in strict mode, the date is accepted but a warning is generated. how to init timestamp and datatime CREATE TABLE t1 ( ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP , dt DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP ); Mysql lock Alter table and lock alter table without locking table? create a new table and copy content to it, finally rename table for mysql online operation is not good enough to handle all DML operations

Copy specific file and its structure

Description Suppose the file structure under the directory /tmp/gsl is like following shows(notice that not all sub-directory has Makefile, for example ./block ): . |-- INSTALL |-- Makefile |-- NEWS |-- ... |-- blas | |-- ChangeLog | |-- Makefile | |-- TODO | |-- blas.c | |-- ... |-- block | |-- ChangeLog | |-- block.c |-- bspline | |-- Makefile | |-- ... |-- ... There are many Makefile in different sub-directories and we want to copy those Makefile to home/usrname/gsl . And the result should be like this: . |-- Makefile |-- blas | |-- Makefile |-- bspline | |-- Makefile |-- ... Question if the target directory already have necessary parent folder for Makefile, like blas, bspline, how to copy? if the target directory don’t have necessary parent folder for Makefile, like blas, bspline, how to copy? Answer only for question 1 cd /tmp/gsl # use `find` to find out those file ; # use `sed` to substitute directory name: # ':

Interesting bug of intellij decompiler

Strange char When I view the source of a project, I notice it use log4j. So, I click into the logger.error method, and intellij decompile the class file and show the following code: public void error (Object message, Throwable t) { if (! this .repository.isDisabled( '鱀' )) { //<--here if (Level.ERROR.isGreaterOrEqual( this .getEffectiveLevel())) { this .forcedLog(FQCN, Level.ERROR, message, t); } } } I was attracted by that strange character, because this character is so rare, so who would use such char in the code? There must be some reason. Real source It is strange, right? I am curious about that strange character so I find the source as following: void error(Object message, Throwable t) { if (repository.isDisabled(Level.ERROR_INT)) return ; if (Level.ERROR.isGreaterOrEqual( this .getEffectiveLevel())) forcedLog(FQCN, Level.ERROR, message, t); } // Level.ERROR_INT public final static int ERROR_INT = 40000

Mysql pagination performance

I was assigned a task to do performance tuning of a pagination service method and I collect some performance statistic from both online and offline. The main aim to change is two kinds of code: invoked too many times cost too much time per call I have made some minor code change to avoid call some functions repeatedly, and the next goal is to handle a very slow database query. Such slow sql When implementing pagination of a table query, we use the following two sql statement to accomplish it. select count (id) from table where isDeleted = 0 ; select id from table where isDeleted = 0 limit M, N; But the this solution is very slow: for a table of 600,000 rows, this sql and rpc call cost 15s on average. After profiling the application, I find the sql cost the most of time. To optimize the situation, I come up with the following way. New pagination way When it comes up to pagination, there actually have two types: user interface used: show count of all

Understand KMP

KMP wiki introduciton The core thought behind the complex description is avoiding duplicate comparison. For example: aim: ababababd ^ ^ s i pattern: ababd ^ j When aim[i] != pattern[j] , what brute-force solution usually do is set i = s + 1; j = 0 to re-compare it. But actually, we already know aim[s + 1] == pattern[1] && pattern[1] != pattern[0] , so this comparison will always fail. So if there any way to avoid this? kmp algorithm use a pre-processed array – next to handle this. What does next mean Back to upper example, if we using kmp to compare and fail the comparison, i will remain not changed, j = next[j];//2 in this case . aim: ababababd ^ ^ s i pattern: ababd ^ j So what on earth the next is? We try to understand it by example: ------------------------ aim | // // /|y| |/ // // |z|

ClassNotFound when deploy war

Today, when I run the tomcat web project in intellij, tomcat fail to start up with error: NoClassDefFoundError: xxxx ... Caused by: ClassNotFoundException: xxxx Steps to solve Check artifact First we check whether the class is in the artifact. Because intellij use artifact to build jar/war to deploy, if artifact not have this class, tomcat will certainly not find it. What should notice is that, even it compile well doesn’t mean it can run if you not include it in right classpath for ClassLoader to find. In my case, I find the dependency of a jar file is upgraded and I didn’t update maven. I update maven repository using the following command: mvn clean package -U But after update, the library in artifact is still the old version( in essence, the intellij use xml files under .idea/artifacts/ to config the artifact, and the setting is still the old version – seems a bug of intellij ). So I have to update the intellij artifact setting to make it right manually.

Learn Data Binding of Android

Notice setContentView List like view data binding NavigationView data binding get data from bound view Notice setContentView @Override protected void onCreate (Bundle savedInstanceState) { super .onCreate(savedInstanceState); MainActivityBinding binding = DataBindingUtil.setContentView( this , R.layout.main_activity); User user = new User( "Test" , "User" ); binding.setUser(user); //setContentView(R.layout.activity_device_info); } Remember to remove the old setContentView() in the onCreate() , or it may override your data binding List-like view data binding This blog and Android guide give us very good example and explanation. What should be noticed is that the example used the RecyclerView to bind data, and I doesn’t find good example with ListView. NavigationView data binding It seems no direct way to make data binding for NavigationView, so I have to implement it in somewhat hacker way: First, in order

Spring 拦截 DAO

缘由 由于要对数据库的部分数据做缓存,并且没有现成的缓存与数据库的一致性的保障机制,所以只能在DAO对数据库操作的同时更新缓存。 为了避免对原有代码的侵入,决定采用spring的aop拦截DAO对数据库的操作然后更新缓存。 分析 尝试 一开始,我实现了如下的代码,对删除进行拦截: @AfterReturning ( pointcut = "execution(public * dao.AccountDao+.deleteX(..))" , returning = "affectedRowCount" ) public void delete (JoinPoint joinPoint, int affectedRowCount) { if (affectedRowCount == 1 ) { xCache.delete((Integer) joinPoint.getArgs()[ 0 ]); } } 但是测试发现,拦截并没有成功。 深入 经检查,spring的配置没有问题,aop的语法也是正确的。那为什么拦截不到呢? 于是怀疑跟AccountDao这个interface有关: public interface AccountDao extends GenericDao { @DAOAction (action = DAOActionType.UPDATE) public int delete (@ DAOParam ("accountId") int accountId); //... } 仔细查看源码,发现这个interface其实并没有实现类!也就是说,这个interface或者他内部的方法是动态生成的。 查看这个bean的定义如下: < bean id = "accountDao" parent = "parentDao" > < property name = "proxyInterfaces"

Android Thread

Single-thread model As JCIP introduced, many UI framework is single threaded. They use thread confinement to avoid deadlock and integrity of data. Android also use this model. By default, all components of the same application run in the same process and thread (called the “main” thread). If an application component starts and there already exists a process for that application (because another component from the application exists), then the component is started within that process and uses the same thread of execution. How to use But sometimes, we want to perform some long time task like using network to download something and read from db. In order to make UI responsive, we should perform those jobs in another thread (Notice: not in the Service , which in default still run on the main thread). When we finish the long time data loading job, we have to push the data back to our UI thread. But we shouldn’t access it directly, which volatile the single thread model and

tomcat进程消失(被杀)问题

缘由 最近,一个机器上的tomcat进程莫名消失了,为了暂时解决问题,设置提升了内存设置。但是,之后过了没多久tomcat又消失了。为了排查问题,我仔细分析了机器上的log。 一开始去查看运行目录是否有dump文件,发现并没有,看似并不是OutOfMemoryError的问题, 也没有JVM crash之后会生成的hs_err_pidxxx.log, JVM也没有出错。 再去查看tomcat的日志,发现也没有异常,突然就结束了,看起来也并不是tomcat崩溃了。 不是JVM崩溃,也不是tomcat崩溃,这个让我们很困惑。通过搜索,得知可能是被os杀掉了。 通过 demsg 命令,得到如下的输出: google之后,发现有可能是linux的奇怪特性。 分析 memory overcommit linux有一个比较奇怪的特性,叫memory overcommit。详细内容可以 参考这里 。 主要表现就是malloc永远会返回一个合法的指针。举个例子,假设我们的机器有4G内存,有两个JVM,每个JVM都说我要4G,linux仍然会成功的分配给他们。 这个特性对于大多数程序来说没有影响,因为一般程序不会占满自己申请的内存,他们可能只用申请的30%内存,于是相安无事。 JVM and GC 但是对于JVM,尤其是长时间运行的JVM,memory overcommit会有很大影响。 对于大多数GC算法来说,只有在堆分配不出内存的时候才会进行GC活动,释放到达不了的object。 回到上面的例子,假设两个JVM长时间运行,内存都逼近1.5G,对于JVM来说,自己才使用了1.5G内存,可能新生代还很空,没有必要进行GC。但是linux不一样,他知道实际的内存(3G+内核+其他软件,比如vim)可能已经没有多少了,于是启动 oom-killer 杀死某一个进程(根据运行时间,内存占用等决定),而长时间运行,占用大量内存的Java进程很容易被选择。 总结 综上,如果tomcat真的是每次被内核杀死,要做的不是提高Xmx,Xms,反而是降低。 不过即使不是每次都被内核杀死,我也建议在beta机器上降低内存设置,试着让tomcat长时间的跑,看会不会OutOfMemoryError,并且看看那时JVM产生的du