2018年4月

ListOperations不允许value为空

使用redisTemplate向ListOperations里面存储长度为0的list的时候,会报错:Values must not be 'null' or empty redis
典型业务代码如下:

String key = String.format(Consts.OFFER_LIST_COUNTRY_NEW, country, fornew);
ListOperations<String, Robad> operations = redisTemplate.opsForList();
List<Robad> raList = new ArrayList<>();
// 缓存存在
boolean hasKey = redisTemplate.hasKey(key);
if (hasKey) {
    raList=operations.range(key, 0, 1000);
}else {
    raList = robadMapper.getListByCountry(country, fornew);
    if(raList!=null&&raList.size()>0) {
        operations.rightPushAll(key, raList);
    }
    
}

上面raList 如果为空的会报错,所以我判断了,但此时可能会导致缓存击穿,需要额外处理。
经查询源代码发现确实有判单。

/*
     * (non-Javadoc)
     * @see org.springframework.data.redis.core.ListOperations#rightPushAll(java.lang.Object, java.util.Collection)
     */
    @Override
    public Long rightPushAll(K key, Collection<V> values) {

        final byte[] rawKey = rawKey(key);
        final byte[][] rawValues = rawValues(values);

        return execute(new RedisCallback<Long>() {
            public Long doInRedis(RedisConnection connection) {
                return connection.rPush(rawKey, rawValues);
            }
        }, true);
    }
/**
     * @param values must not be {@literal empty} nor contain {@literal null} values.
     * @return
     * @since 1.5
     */
    byte[][] rawValues(Collection<V> values) {

        Assert.notEmpty(values, "Values must not be 'null' or empty.");
        Assert.noNullElements(values.toArray(), "Values must not contain 'null' value.");

        byte[][] rawValues = new byte[values.size()][];
        int i = 0;
        for (V value : values) {
            rawValues[i++] = rawValue(value);
        }

        return rawValues;
    }

常用正则表达式

1:检测字符串是否包含emoji表情
如果mysql数据库的编码不是utf8mb4,那么是插入不进去的,必须手动过滤这些表情

public boolean hasEmoji(String content){

    Pattern pattern = Pattern.compile("[\ud83c\udc00-\ud83c\udfff]|[\ud83d\udc00-\ud83d\udfff]|[\u2600-\u27ff]");
    Matcher matcher = pattern.matcher(content);
    if(matcher .find()){
        return true;    
    }
        return false;
}

android ANR发生的原因总结和解决办法

定义
主线程在特定的时间内没有做完特定的事情

常见的场景
A.input事件超过5S没有处理完成
B.service executing 超时(bind,create,start,unbind等等),前台20s,后台200s
C.广播处理超时,前台10S,后台60s
D.ContentProvider执行超时,20s
常见的原因
A.耗时操作,如复杂的layout,庞大的for循环,IO等。
B.被Binder 对端block
C.被子线程同步锁block
D.Binder被占满导致主线程无法和SystemServer通信
E.得不到系统资源(CPU/RAM/IO)
其中ABCD比较好分析,而E比较困难。
如何分析?
指导思想:通过各种线索,寻求主线程在过去一段时间内发生block的可能原因。

线索包括:
A.traces.txt/dropbox
AMS在ANR发生的时候,dump相关进程(ANR的进程、systemserver、mediaserver,surfaceFinger等)的当前栈到traces.txt。
traces.txt存在的几种形式:
1. adb pull /data/anr/
2. slog/2012xxxxx/misc/anr/snapshot_xxxx.log
3. slog/dropbox/data_app_anr_xxxxx.tgz
4. slog/dropbox/system_app_anr_xxxx.tgz
需要注意的是,traces.txt是抓取的是超时后(如input超时就是5s后)的snapshot,并不一定能够真实的反应出block的点。
也存在抓到主线程没有block,在idle的情况。
B.Eventlog中的dvm_lock_sample.
在同步锁发生content的时候,虚拟机会将这个竞争记录在eventlog中:
dvm_lock_sample: [system_server,1,Binder_7, 22, ActivityManagerService.java,15921,-,9628,4]
进程名 被block线程 block时间(ms) 被block的行号 持有者行号
实现可以参考art/runtime/monitor_android.cc LogContentionEvent函数
如果主线程是被binder对端、被同步锁block,那么eventlog中就很有可能会有dvm_lock_sample的打印。
华为项目上实现了更加强大的功能BlockMonitor,在主线程有耗时操作(如handlemsg、Binder调用耗时)的时候会打印出栈。

C.搜索主线程在发生ANR前后的main,systemlog,结合代码查看可能block在哪里。
现在发生ANR的时候,sprdruntimeinfo在mainlog中会Dump出比较多的信息,其中比较重要的是binder、cpu。
D.ANR发生的时候,打印出的CPU的占用。
注意,并不能因为有进程cpu占用高就果断的去怀疑他。
因为最主要的线索traces.txt的有效性并不是非常高,所以ANR问题分析是存在一定的局限性的。

其它常见错误

1:URLConnection请求网页报循环重定向错误
java.net.ProtocolException: Server redirected too many times
解决办法:

CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL));
URLConnection connection = new URL(url).openConnection();

2:ImportError: C extension: umpy.core.multiarray failed to import not built. If you want to import pandas from the source directory, you may need to run 'python setup.py build_ext --inplace' to build the C extensions first.
原本pandas==0.17.1,升级到0.20.3就可以了
python -m pip install pandas==0.20.3 --force-reinstall --upgrade --no-deps --no-cache --find-links https://3f23b170c54c2533c070-1c8a9b3114517dc5fe17b7c3f8c63a43.ssl.cf2.rackcdn.com/ --no-index

3:微信小程序开发'errcode': 40029
一般是appid或者secret不匹配,仔细检查一下

4:redis安装
zmalloc.h:50:31: fatal error: jemalloc/jemalloc.h: No such file or directory
在make前运行make distclean

5:Failed building wheel for pycrypto
apt-get install build-essential libssl-dev libffi-dev python-dev python3-dev

6:空格的问题
通常有两种ascii160 和 ascii32,其中160是不间断空格,一般常用的是32,可替换为:

String str = "ciika";  //包含了不间断空格的字符串
str = str.replaceAll("\\u00A0", "");

kafka常见错误

1:kafka.common.FailedToSendMessageException: Failed to send messages after 3 tries
修改kafka的配置文件server.properties

zookeeper.connect=192.168.1.95:2181
advertised.listeners=PLAINTEXT://192.168.1.95:9092