在Java里怎样把exception的stacktrace压缩到一行?

在Java里怎样把exception的stacktrace压缩到一行?

一般在Java里,我们可以用printStackTrace把stacktrace打印出来。

try {
    // do something
} catch (Exception e) {
    e.printStackTrace();    
}

在server里,如果我们需要用graylog来search log,就需要把stacktrace压缩到一行。我们可以用apache的ExceptionUtils

import org.apache.commons.lang.exception.ExceptionUtils;
//...

try {
    // do something
} catch (Exception e) {
    logger.error("Exception: {}", 
        ExceptionUtils.getStackTrace(e)
    );
}

ECharts快速上手

ECharts快速上手

前段一直是我的短板, 没有太多机会系统学习. 最近想做一个股票分析系统的webapp, 于是就在网上找合适的javascript library做data visualization. D3.js以前用过, 觉得太过底层, 写起来太麻烦. 于是发现了ECharts, 好像是国内大神写得, 已经是Apache project, 非常厉害. 于是follow了这个tutorial. 里面有些小细节我觉得初学者可能会卡住, 这里我写得详细一点.

安装npm

npm是node package manager的意思, 是用了管理安装javascript libraries的. 相当于Python里的pip. 安装可以看我前面的文章.

安装ECharts

首先给项目建立一个新的directory

% mkdir test_echart
% cd test_echart

在项目directory里安装echarts library

npm install echarts --save

完成后directory里会有那么几个东西

% ls
package-lock.json
node_modules/		package.json

开始Coding

在项目directory里面添加一个html file叫main.html, 内容如下调用echart

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <!-- including ECharts file -->
    <script src="node_modules/echarts/dist/echarts.min.js"></script>
</head>

<body>
    <!-- preparing a DOM with width and height for ECharts -->
    <div id="main" style="width:600px; height:400px;"></div>
</body>

<script type="text/javascript">
        // based on prepared DOM, initialize echarts instance
        var myChart = echarts.init(document.getElementById('main'));

        // specify chart configuration item and data
        var option = {
            title: {
                text: 'ECharts entry example'
            },
            tooltip: {},
            legend: {
                data:['Sales']
            },
            xAxis: {
                data: ["shirt","cardign","chiffon shirt","pants","heels","socks"]
            },
            yAxis: {},
            series: [{
                name: 'Sales',
                type: 'bar',
                data: [5, 20, 36, 10, 10, 20]
            }]
        };

        // use configuration item and data specified to show chart
        myChart.setOption(option);
    </script>
</html>

header里面的这行相当于Python的import

    <script src="node_modules/echarts/dist/echarts.min.js"></script>

现在directory内容如下

% ls
main.html		package-lock.json
node_modules/		package.json

用浏览器打开main.html. 在Mac里可以在terminal里用

% open main.html

网页显示如下, 还是挺酷的.

简单看看js code, option就是一个json object, 里面包含了图的一些信息和data. 一开始init了一个echarts object, 然后给它set一下option这个json object. 和d3比起来还是简单多了.

        var myChart = echarts.init(document.getElementById('main'));
        
        var option = {
            // json object
        };

        myChart.setOption(option);

我把数据改一改, 就可以显示一些投资标的的市值了

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <!-- including ECharts file -->
    <script src="node_modules/echarts/dist/echarts.min.js"></script>
</head>

<body>
    <!-- preparing a DOM with width and height for ECharts -->
    <div id="main" style="width:1000px; height:400px;"></div>
</body>

<script type="text/javascript">
        // based on prepared DOM, initialize echarts instance
        var myChart = echarts.init(document.getElementById('main'));

        // specify chart configuration item and data
        var option = {
            title: {
                text: 'Market Caps'
            },
            tooltip: {},
            legend: {
                data:['Sales']
            },
            xAxis: {
                data: []
            },
            yAxis: {},
            series: [{
                name: 'Sales',
                type: 'bar',
                data: []
            }]
        };

        const MARKET_CAP = 'market cap';
        var legends = [MARKET_CAP];
        var symbols = ['AAPL', 'GOOGL', 'FB', 'AMZN', 'NVDA', 'NFLX', 'TSLA', 'BTC', 'ETH', 'V', 'MA']
        var marketCaps = [2256, 1185, 778, 1634, 323, 238, 669, 622, 109, 482, 356];

        option.legend.data = legends;
        option.xAxis.data = symbols;
        option.series[0].data = marketCaps;	
        option.series[0].name = MARKET_CAP;	

        // use configuration item and data specified to show chart
        myChart.setOption(option);
    </script>
</html>

网页更新如下. 接上个数据的后端就可以显示不同的数据了.

照顾新生儿的经验总结

照顾新生儿的经验总结

现代社会, 尤其生活在湾区这种竞争激烈并且高物价的地方. 当父母不容易. 本文为宝妈总结的照顾小宝宝经验, 希望对其他新手父母有帮助.

照顾新生儿的关键就是要照顾小宝宝的吃睡玩.

我这里主要谈谈胸喂常遇到的问题. 胸喂最大的问题是宝宝是否能以正确的姿势吸奶. 大宝出生的时候没有经验,而且大宝天生舌筋可能有点紧,所以刚开始几天母乳没吃好,黄疸有点严重.二宝还好没有遇到这个问题,而且在医院遇到的护士教了我很有用的经验,所以二宝吸奶很好. 如果你担心你的宝宝吸奶是否正确,可以在医院的时候请教护士, 医院还有免费的母乳喂养指导lactation consultant. 我学到的经验是如果宝宝吸奶发出很大的咂咂声,那就说明宝宝吸奶舌头姿势不对, 有很多空气进去. 如果姿势正确,还是发出这样的声音,那你要怀疑宝宝舌筋有问题, 你可以找儿医做个简单的检查.检查很简单, 宝宝张开嘴, 儿医就可以通过观察宝宝舌头下的舌筋,和宝宝舌头的一些简单动作就可以大概看出来.

如果宝宝吸奶正常, 那下来还可能会遇到宝宝吐奶和呛奶的问题. 我家宝宝一般会在吃完奶过一会后吐奶, 我的解决办法是, 喂完后竖起来抱宝宝来拍嗝. 顺利的话, 稍微一拍,宝宝的嗝就出来, 但有时候拍很久都没嗝, 这时候我误以为没嗝, 把宝宝放下一会后, 她却吐奶了. 后来我发现, 如果喂奶的时候尽量让宝宝竖起来的姿势吸奶, 吃完奶后嗝很快就可以拍出来. 但是有时候拍完嗝后还是会有少量奶吐出来, 那么我怀疑有两个原因,一个是喂完奶后竖抱的时间不够长(一般的话要半个小时), 还有一个可能是宝宝吃的太多溢出来了, 那这种情况的话, 我的解决办法是少量多次, 我参考了网上的EASY程序3小时循环图.

但是这个schedule对我来说要做个小调整,因为我发现到宝宝睡觉的时候,我抱着她哄睡,她却哭闹, 我不知道她是因为没吃饱呢,还是不是真饿只是为了奶睡. 为了判断,我一般是这样, 首先每次喂宝宝的话保证宝宝吸的时间在10-15分钟, 中间可能要休息拍嗝(休息拍嗝时间不算),那么可能分2-3次喂. 但是时间够了,不代表宝宝一定吃饱了, 因为胸喂的话不知道奶的速度,所以仅靠时间判断奶量并不准确. 喂完后, 等一会看看,如果宝宝哭闹很久, 放倒胸前抱的话, 作出找奶的动作,那么可能是没吃饱, 如果只是稍微哭闹不持久的话, 那就可能不是真饿. 下来我们说下呛奶的问题. 我的宝宝一般只有在胸喂的时候奶速太急的时候会呛奶, 吐奶的时候她一般不会呛, 只是突然哭一下,然后奶从嘴角涌出来, 所以我看到她吐奶的第一反应是擦拭掉奶,防止流进耳朵. 呛奶的时候,宝宝一般会咳嗽, 然后休息几秒就好了, 我会保持她倾斜吃奶的姿势面朝上,不会去立刻竖抱起来拍, 网上也是不建议立即竖抱, 这样的话会容易把奶吸入呼吸道, 建议让宝宝侧着脸,然后轻拍宝宝背部. 但最好的话还是要避免呛奶的出现, 我的方法是, 如果知道奶速很急, 那就靠在椅子或者墙上,身体后倾, 让宝宝趴着吃, 这样宝宝就不会呛了.

大部分宝宝不能像大人那样自主入睡, 所以大人会比较辛苦. 我现在的偷懒办法是, 睡前让宝宝多消耗体力, 比如tummy time. 然后关灯放固定的催眠音乐, 抱累的话, 大人可以坐在椅子上靠后, 让宝宝趴在胸上, 身体有个角度, 这样大人也不累, 宝宝也舒服不用担心吐奶, 这样等宝宝睡着后, 就可以放下了. 我最近发现了个问题就是, 用普通的毯子给宝宝打包的话, 在抱的过程中, 尤其是竖抱的时候, 毯子会上移,遮住宝宝的口鼻, 所以我建议还是用睡袋. 为了防止宝宝睡觉过程中吐奶, 然后醒来, 我把宝宝的小床的床垫一头抬高一点,这样宝宝的床有个坡度. 等过些时间后, 再把床放平.

一个月左右的小宝宝活动能力还很有限, 能玩的东西不多, 我们家用的是下图这个可以让宝宝躺着踢上面琴键的小玩具, 踢到了就会响音乐. 上面还有些小动物造型的小挂件. 她高兴的时候还挺喜欢玩的.

最后推荐两个好用的apple watch功能, 一个是track 喂奶的时间, 一个是照明功能, 晚上胸喂的话不用起来开灯.

怎样用apache2设置多个网站? | How to set up multiple websites using apache2?

怎样用apache2设置多个网站

添加网站内容

Ubuntu里apache2的网站内容在

/var/www/html/

我们可以把网站内容(php, html files)放在上面路径的子路径中, 比如

/var/www/html/site1
/var/www/html/site2

设置Apache2

本文以Ubuntu为例子. 我们需要设置的文件在

/etc/apache2

首先要在sites-available里添加新的网站, 比如叫site1

cd /etc/apache2/sites-available
vim site1.conf

添加文件内容如下

<VirtualHost *:80>
	# The ServerName directive sets the request scheme, hostname and port that
	# the server uses to identify itself. This is used when creating
	# redirection URLs. In the context of virtual hosts, the ServerName
	# specifies what hostname must appear in the request's Host: header to
	# match this virtual host. For the default virtual host (this file) this
	# value is not decisive as it is used as a last resort host regardless.
	# However, you must set it for any further virtual host explicitly.
	#ServerName www.example.com

	ServerAdmin webmaster@localhost
	ServerName site1.com
	ServerAlias www.site1.com
	DocumentRoot /var/www/html/site1

	# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
	# error, crit, alert, emerg.
	# It is also possible to configure the loglevel for particular
	# modules, e.g.
	#LogLevel info ssl:warn

	ErrorLog ${APACHE_LOG_DIR}/error.log
	CustomLog ${APACHE_LOG_DIR}/access.log combined

	# For most configuration files from conf-available/, which are
	# enabled or disabled at a global level, it is possible to
	# include a line for only one particular virtual host. For example the
	# following line enables the CGI configuration for this host only
	# after it has been globally disabled with "a2disconf".
	#Include conf-available/serve-cgi-bin.conf
</VirtualHost>

然后添加第二个网站, 比如叫site2

cd /etc/apache2/sites-available
vim site2.conf

给site2添加内容

<VirtualHost *:80>
	# The ServerName directive sets the request scheme, hostname and port that
	# the server uses to identify itself. This is used when creating
	# redirection URLs. In the context of virtual hosts, the ServerName
	# specifies what hostname must appear in the request's Host: header to
	# match this virtual host. For the default virtual host (this file) this
	# value is not decisive as it is used as a last resort host regardless.
	# However, you must set it for any further virtual host explicitly.
	#ServerName www.example.com

	ServerAdmin webmaster@localhost
	ServerName site2.com
	ServerAlias www.site2.com
	DocumentRoot /var/www/html/site2

	# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
	# error, crit, alert, emerg.
	# It is also possible to configure the loglevel for particular
	# modules, e.g.
	#LogLevel info ssl:warn

	ErrorLog ${APACHE_LOG_DIR}/error.log
	CustomLog ${APACHE_LOG_DIR}/access.log combined

	# For most configuration files from conf-available/, which are
	# enabled or disabled at a global level, it is possible to
	# include a line for only one particular virtual host. For example the
	# following line enables the CGI configuration for this host only
	# after it has been globally disabled with "a2disconf".
	#Include conf-available/serve-cgi-bin.conf
</VirtualHost>

最后需要给以上两个site的conf file创建symbolic link, 放在sites-enabled里

ln -s /etc/apache2/sites-available/site1.conf /etc/apache2/sites-enabled/site1.conf
ln -s /etc/apache2/sites-available/site2.conf /etc/apache2/sites-enabled/site2.conf

可能需要重启apache2

sudo service apache2 restart

更新域名指向

以Namecheap为例子, 到所选域名, 比如site1.com里, 点击Manage, 然后在Advanced DNS里, 如下设置

Namecheap Advanced DNS setup

给site2也做类似的配置, 因为都在同一台服务器上, host ip是一样的, 把site1.com换成site2.com就可以

最后在浏览器打开site1.com和site2.com看看是否正常工作.

2020-12-16 比特币定投实验更新 | 2020-12-16 Update on Dollar average plan for buying bitcoin

继续执行比特币定投计划. 昨晚睡觉前挂了个19,400的单子, 今天早上起来发现BTC已经涨到涨到2万多一个了. 应该是历史新高了吧. 写作的时候已经是2万1千多. 幸好昨晚的单子居然能买到, 比较幸运. 挂的价格要比当时市场价格低不少, 没想到在横盘很久后起飞前赶上.

目前三次买入, 每次$20, 成本$60, 目前持有的BTC市场价格$68.39, 六个星期的总投入盈利为13.98%. 其实价格波动对定投来说是无所谓, 涨得慢了能在便宜的价格多买点, 涨了呢, 至少目前持有的增值了, 什么样都有高兴或不高兴的理由. 我也知道靠这种买入的资金量很难发财, 没有闲钱也就只能在自己能承担的风险内量力而行了. 没有很多本金的情况下, 投资现阶段只是辅助, 主要还是需要提高自己身价和场外赚钱能力.

算法练习 Leetcode 力扣 416. Partition Equal Subset Sum 的Python解法

题目

题目链接

Given a non-empty array nums containing only positive integers, find if the array can be partitioned into two subsets such that the sum of elements in both subsets is equal.

给一个堆正整数, 能不能把这组数分成2部分使得每部分的和一样. 比如给定[1, 5, 5, 11], 那么可以分成[1, 5, 5] 和 [11], 这样每组的和都是11, 就return true.

Bottom up dynamic programming 解法

Continue reading “算法练习 Leetcode 力扣 416. Partition Equal Subset Sum 的Python解法”