东东东 陈煜东的博客

置顶

腾讯云招聘

2018年1月5日更新

对应的产品:Tencent Cloud

我们需要 云计算研发工程师

岗位描述

  • 开发和维护腾讯云云服务器的后台管理/调度系统(类似于OpenStack);
  • 开发和维护运行在数十万宿主机上的虚拟化Agent;
  • 开发和维护大规模数据的可视化展现、计算汇总以及预测分析。

有感兴趣的一项即可。

加分项

  • 热情、好学,有钻研和折腾的精神;
  • 有良好的沟通能力和乐于分享的意识;
  • 对云计算领域有浓厚的兴趣;
  • 熟悉C/C++/Python中的任意一种,对golang/rust有所研究的更好;
  • 熟悉Linux的基本操作和基本原理,掌握分析、调优工具;
  • 有分布式、虚拟化、HTTP服务器开发经验者优先;
  • 有OpenStack、Docker、libvirt/qemu/kvm等相关开源软件经验者优先。

地点:深圳总部、北京

我们需要 产品经理

岗位描述

  • 重点负责腾讯云计算及块存储等相关基础产品的策划工作
  • 负责调研企业用户、中小开发者需求,决策产品方向、优化产品体验;
  • 负责产品需求撰写、协调设计/研发资源,跟踪产品上线。
  • 负责产品的落地、用户的口碑、用户体验、定价和成本等工作;
  • 支持产品销售过程,提供销售素材和部分售前支撑,对产品规模增长负责;
  • 关注市场和趋势,对产品方向有前瞻性的设计,寻找新的增长点。

岗位要求

  • 本科以上学历,3年以上产品策划或研发等相关互联网经验;
  • 熟悉云计算相关产品,对行业动态变化敏感度高;
  • 有产品设计和商业化包装能力,具备产品理解力
  • 执行能力强,具备较强的团队协作和沟通能力,思维活跃,学习能力、适应能力强;
  • 具备后台研发、运维经验者,优先考虑。

其他的岗位

如果你觉得不想做开发,产品经理,我们也有运维、运营等等可以选择。也欢迎联系我。

联系我

个人交流

my-wechat-qrcode

简历请来 Mjg2Mjg4NDE3QHFxLmNvbQ==

声明:未经允许禁止转载 东东东 陈煜东的博客 文章,谢谢。如经授权,转载请注明: 转载自东东东 陈煜东的博客

本文链接地址: 腾讯云招聘 – https://www.chenyudong.com/archives/we-need-you.html

分类: 云计算

进程不见了,Linux 的OOM Killer

背景

服务器的某个模块的进程莫名其妙的不见了,查看MQ的连接情况,该模块的连接数直接为0,但是其他模块的进程还存在。很是纳闷该模块的进程为什么进程突然不见了。

oom-killer-mq-consumer-connnection

查看进程的log文件,没有发现有stop信号收到。平时停止会收到kill信号。

[12:29:37.290]:[executor.py:_fun: 53]: Info: proc[28269] recv signal[15]
[12:29:37.314]:[mq.py:_consuming:181]: service received STOP signal, stop consume

一下子没有反应过来会被kill 9。想到平时大家都会去/var/log/message查看,打开文件一看:

Dec  2 10:10:00 localhost kernel: [53533657.927030] python invoked oom-killer: gfp_mask=0x200da, order=0, oom_adj=0
Dec  2 10:10:00 localhost kernel: [53533657.927033] Pid: 19679, comm: python Not tainted  #1
Dec  2 10:10:00 localhost kernel: [53533657.927035] Call Trace:
Dec  2 10:10:00 localhost kernel: [53533657.927041]  [<ffffffff81089f9a>] oom_kill_process.clone.0+0xaa/0x270
Dec  2 10:10:00 localhost kernel: [53533657.927043]  [<ffffffff8108a278>] __out_of_memory+0x118/0x180
Dec  2 10:10:00 localhost kernel: [53533657.927045]  [<ffffffff8108a3ba>] out_of_memory+0xda/0x160
Dec  2 10:10:00 localhost kernel: [53533657.927048]  [<ffffffff8108e9cd>] __alloc_pages_nodemask+0x61d/0x630
Dec  2 10:10:00 localhost kernel: [53533657.927052]  [<ffffffff810b8ce3>] alloc_page_vma+0x93/0x150
Dec  2 10:10:00 localhost kernel: [53533657.927054]  [<ffffffff810af10e>] read_swap_cache_async+0xde/0x130
Dec  2 10:10:00 localhost kernel: [53533657.927061]  [<ffffffff810af868>] ? valid_swaphandles+0x68/0x160
Dec  2 10:10:00 localhost kernel: [53533657.927063]  [<ffffffff810af1df>] swapin_readahead+0x7f/0xb0
Dec  2 10:10:00 localhost kernel: [53533657.927067]  [<ffffffff810a09e2>] handle_mm_fault+0x392/0x9d0
Dec  2 10:10:00 localhost kernel: [53533657.927071]  [<ffffffff8102eaa0>] do_page_fault+0x110/0x2e0
Dec  2 10:10:00 localhost kernel: [53533657.927076]  [<ffffffff817de855>] page_fault+0x25/0x30
...
Dec  2 10:10:00 localhost kernel: [53533657.964521] Out of memory: kill process 21270 (python) score 1508 or a child
Dec  2 10:10:00 localhost kernel: [53533657.964523] Killed process 21360 (python)

原来是OOM,给杀死进程了。以为OOM会随便杀进程,之前也出现过一次,也是同一模块的进程都被杀了。于是上网搜索了一次OOM挑选进程的算法。

Linux 如何选择要kill掉的进程

从网上的找了一个比较全面的如下:

OOM Killer在内存耗尽时,会查看所有进程,并分别为每个进程计算分数。将信号发送给分数最高的进程。 
计算分数的方法 
在OOM Killer计算分数时要考虑很多方面。首先要针对每个进程确认下列1~9个事项再计算分数。 
1. 首先,计算分数时是以进程的虚拟内存大小为基准的,虚拟内存大小可以使用ps命令的VSZ或/proc/<PID>/status的 VmSize来确认。对于正在消耗虚拟内存的进程,其最初的得分较高,单位是将1KB作为1个得分,消耗1GB内存的进程,得分约为1024*1024。 
2. 如果进程正在执行swapoff系统调用,则得分设置为最大值(unsigned long的最大值)。这是因为禁用swap的行为与消除内存不足是相反的,会立刻将其作为OOM Killer的对象进程。 
3. 如果是母进程,则将所有子进程内存大小的一半作为分数。 
4. 根据进程的CPU使用时间和进程启动时间调整得分,这是因为在这里认为越是长时间运行或从事越多工作的进程越重要,需保持得分较低。 
5. 对于通过nice命令等将优先级设置得较低的进程,要将得分翻倍。nice-n中设置为1~19的命令的得分翻倍。 
6. 特权进程普遍较为重要,因此将其得分设置为1/4。 
7. 通过capset(3)等设置了功能(capability)CAP_SYS_RAWIO注3的进程,其得分为1/4,将直接对硬件进行操作的进程判断为重要进程。 
8. 关于Cgroup,如果进程只允许与促使OOM Killer运行的进程所允许的内存节点完全不同的内存节点,则其得分为1/8。 
9. 最后通过proc文件系统oom_adj的值调整得分。 

依据以上规则,为所有进程打分,向得分最高的进程发送信号SIGKILL(到Linux 2.6.10为止,在设置了功能CAP_SYS_RAWIO的情况下,发送SIGTERM,在没有设置的情况下,发送SIGKILL)。 
各进程的得分可以使用/proc/<PID>/oom_score来确认。 


来自: https://blog.csdn.net/JeffreyNicole/article/details/47263235 

上面的算法看着有点复杂,另外 Linux 的系统选择的策略不断在演进,还是得看正在用的版本的算法。

大概的算法的意思是:通过设置一些值来影响OOM killer做出决策。Linux下每个进程都有个OOM权重,在 /proc/<pid>/oom_adj里面,取值是-17+15,取值越高,越容易被干掉。

最终OOM killer是通过 /proc/<pid>/oom_score 这个值来决定哪个进程被干掉的。这个值是系统综合进程的内存消耗量、CPU时间(utime + stime)、存活时间(uptime – start time)和oom_adj计算出的,消耗内存越多分越高,存活时间越长分越低。

总之,总的策略是:损失最少的工作,释放最大的内存同时不伤及无辜的用了很大内存的进程,并且杀掉的进程数尽量少。 另外,Linux在计算进程的内存消耗的时候,会将子进程所耗内存的一半同时算到父进程中。

这也说明了,为什么有内存用的很多的模块,却没有被kill了,而是kill了一个cpu使用时间少的一个模块。因为内存大的模块,CPU的运行时间长,所以分数比较低。

top - 17:23:31 up 619 days, 21:41, ? users,  load average: 1.59, 1.88, 1.62
Tasks: 651 total,   1 running, 650 sleeping,   0 stopped,   0 zombie
Cpu(s): 15.7%us,  1.6%sy,  0.0%ni, 74.5%id,  8.1%wa,  0.0%hi,  0.1%si,  0.0%st
Mem:  24738212k total, 24577344k used,   160868k free,     2068k buffers
Swap:  2097144k total,  2097144k used,        0k free,    79416k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
17880 root      20   0 1075m 895m 1632 S  0.0  3.7 123:55.47 python
17897 root      20   0 1076m 894m 1632 S  0.0  3.7 122:55.16 python
17840 root      20   0 1064m 893m 1632 S  0.0  3.7 125:09.59 python

/proc/$pid/oom_score_adj

The value of /proc/<pid>/oom_score_adj is added to the badness score before it
is used to determine which task to kill.  Acceptable values range from -1000
(OOM_SCORE_ADJ_MIN) to +1000 (OOM_SCORE_ADJ_MAX).  This allows userspace to
polarize the preference for oom killing either by always preferring a certain
task or completely disabling it.  The lowest possible value, -1000, is
equivalent to disabling oom killing entirely for that task since it will always
report a badness score of 0.

在计算最终的 badness score 时,会在计算结果是中加上 oom_score_adj ,这样用户就可以通过该在值来保护某个进程不被杀死或者每次都杀某个进程。其取值范围为-1000到1000 。

如果将该值设置为-1000,则进程永远不会被杀死,因为此时 badness score 永远返回0。

/proc/$pid/oom_adj

The value of /proc/<pid>/oom_score_adj is added to the badness score before it

For backwards compatibility with previous kernels, /proc/<pid>/oom_adj may also
be used to tune the badness score.  Its acceptable values range from -16
(OOM_ADJUST_MIN) to +15 (OOM_ADJUST_MAX) and a special value of -17
(OOM_DISABLE) to disable oom killing entirely for that task.  Its value is
scaled linearly with /proc/<pid>/oom_score_adj.

该设置参数的存在是为了和旧版本的内核兼容。其设置范围为-17到15。从Linux 2.6.36开始都安装了/proc/<pid>/oom_score_adj,此后将替换掉/proc/<pid>/oom_adj。即使当前是对/proc/<pid>/oom_adj进行的设置,在内核内部进行变换后的值也是针对/proc/<pid>/oom_score_adj设置的。可以参见 feature-removal-schedule 这里 171行。

/proc/$pid/oom_score

This file can be used to check the current score used by the oom-killer is for
any given <pid>. Use it together with /proc/<pid>/oom_score_adj to tune which
process should be killed in an out-of-memory situation.

OOM killer机制主要根据该值和 /proc/<pid>/oom_score_adj 来决定杀死哪一个进程的。分数越高,越先被kill。

通过如下命令可以查看进程 oom_score 分数情况。最后一列是分数。

# ps -eo pid,command,pmem --sort -rss | awk '{"cat /proc/"$1"/oom_score" | getline oom; print $0"\t"oom}'
cat: /proc/PID/oom_score: No such file or directory
  PID COMMAND                     %MEM
 7663 python ./executor.py vsSche  2.2  794
 7675 python ./executor.py vsSche  2.1  683
 7671 python ./executor.py vsSche  2.1  780
 7811 python ./executor.py vsreso  0.1  1873
 7816 python ./executor.py vsreso  0.1  1877
 7465 python ./dispatcher.py host  0.1  15
 7540 python ./executor.py vnc_au  0.0  1914

其中有一个很低的进程才 15 分,看了下是一个常驻周期性的任务进程,执行的CPU时间非常长,所以算法把该进程的分数设置的非常低。 而经常被kill的进程分数有1900+分,所以这类进程老是被kill。

防止进程不被kill

通过上文说的,一般通过 /proc/<pid>/oom_score_adj设置一个很低的分数,例如 -1000 分永远不被杀死。

当系统认为进程都无法被杀死后,内核就会panic,然后整个机器挂了。

sigkill 信号无法被捕获

日志中记录了 SIGNTERM(15),但是在 SIGNKILL(9)时却没有打印,如果有一个 SIGNKILL 的信号,那么看日志的时候也会有一个更直观的线索。

两者区别:

  • SIGNKILL(9) 的效果是立即杀死进程. 该信号不能被阻塞, 处理和忽略。

  • SIGNTERM(15) 的效果是正常退出进程,退出前可以被阻塞或回调处理。并且它是Linux缺省的程序中断信号。

The signals SIGKILL and SIGSTOP cannot be caught, blocked, or ignored.

不过SIGKILL无法在进程里面被捕获。在Python中会直接跑出一个异常,所以无法打印这个信号。

>>> import signal
>>> def trycache(*args):
...     print args
...
>>> signal.signal(signal.SIGKILL,trycache)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
RuntimeError: (22, 'Invalid argument')

阻止内存泄漏方法

很多程序会跑着跑着然后内存就泄漏了,然后内存就OOM。

特别的,像Python 虚拟机这样的程序,就申请了内存后,就不会释放内存给系统,会一直在虚拟机内部进行使用。那么对待这类程序的内存泄漏最好的方法是什么呢?

周期性reload进程。

是的,就是这么暴力,这么直接。

之前看 uWSGI里有个参数max-requests在处理了一定次数的请求后,会自动reload该进程。这样可以防止该进程的内存泄漏。

像平台类的软件,能做的就是在外部周期性reload进程。而业务的编写者,就得控制好自己进程的内存管理了。

不过要支持一个能reload进程的服务(注意不是restart),这个是一个要求需要比较高能力。幸好大部分的CGI进程都支持reload,例如nginx、php-fpm、uWSGI等。

而一个后台批量型任务,做到restart就行了,毕竟对进程重启对间隙不太敏感。做负载均衡的话,推荐用MQ可以推送给还能处理任务的进程。

自动补充进程

发现一些OOM的被kill的进程,比如 nslcd 进程,不断的被kill,但是会不断给补充进来。因此我们的进程管理设置,也需要增加一些进程自动补充,这样防止进程被oom几天都不知道。这样可以达到变相reload。

参考

关于python捕获内核发出的sigkill信号问题

https://learning-kernel.readthedocs.io/en/latest/mem-management.html

声明:未经允许禁止转载 东东东 陈煜东的博客 文章,谢谢。如经授权,转载请注明: 转载自东东东 陈煜东的博客

本文链接地址: 进程不见了,Linux 的OOM Killer – https://www.chenyudong.com/archives/linux-oom-killer.html

分类: Linux

wget 下载整个网页和css、js、图片数据

想要抓取网站的一个页面,包括css、图片、js的文件,用 Chrome、FireFox 去另存为成网页不行,有些数据不能下载下来。

wget 就可以下载网页及其依赖

# 这个可以将整个页面下载下来。
wget -l 1 -p -np -k http://www.domain.com/page.html
# 可以抓取整站
wget -c -r -nd -np -k -L -p http://www.domain.com

wget 参数

-V 版本信息
-h 帮助信息
-b 后台执行Wget
-o filename 把记录放在文件filename
-a filename 把记录附加在文件filename
-d 显示调试信息
-q 无输出下载方式
-v 详细的屏幕输出(默认)
-nv 简单的屏幕输出
-i inputfiles 从文本文件内读取地址列表
-F forcehtml 从html文件内读取地址列表
-t number number次重试下载(0时为无限次)
-O output document file 写文件到文件
-nc 不覆盖已有的文件
-c 断点下传
-N 时间时间戳。该参数指定wget只下载更新的文件,也就是说,与本地目录中的对应文件的长度和最后修改日期一样的文件将不被下载。
-S 显示服务器响应
-T timeout 超时时间设置(单位秒)
-w time 重试延时(单位秒)
-Y proxy=on/off 是否打开代理
-Q quota=number 重试次数

目录:
-nd –no-directories 不建立目录。
-x, –force-directories 强制进行目录建立的工作。
-nH, –no-host-directories 不建立主机的目录。
-P, –directory-prefix=PREFIX 把档案存到 PREFIX/…
–cut-dirs=NUMBER 忽略 NUMBER 个远端的目录元件。

HTTP 选项:
–http-user=USER 设 http 使用者为 USER.
–http0passwd=PASS 设 http 使用者的密码为 PASS.
-C, –cache=on/off 提供/关闭快取伺服器资料 (正常情况为提供).
–ignore-length 忽略 `Content-Length’ 标头栏位。
–proxy-user=USER 设 USER 为 Proxy 使用者名称。
–proxy-passwd=PASS 设 PASS 为 Proxy 密码。
-s, –save-headers 储存 HTTP 标头成为档案。
-U, –user-agent=AGENT 使用 AGENT 取代 Wget/VERSION 作为识别代号。
FTP 选项:
–retr-symlinks 取回 FTP 的象徵连结。
-g, –glob=on/off turn file name globbing on ot off.
–passive-ftp 使用 “passive” 传输模式。

使用递回方式的取回:
-r, –recursive 像是吸入 web 的取回 — 请小心使用!.
-l, –level=NUMBER 递回层次的最大值 (0 不限制).
–delete-after 删除下载完毕的档案。
-k, –convert-links 改变没有关连的连结成为有关连。
-m, –mirror 开启适合用来映射的选项。
-nr, –dont-remove-listing 不要移除 `.listing’ 档。

递回式作业的允许与拒绝选项:
-A, –accept=LIST 允许的扩充项目的列表
. -R, –reject=LIST 拒绝的扩充项目的列表。
-D, –domains=LIST 允许的网域列表。
–exclude-domains=LIST 拒绝的网域列表 (使用逗号来分隔).
-L, –relative 只跟随关联连结前进。
–follow-ftp 跟随 HTML 文件里面的 FTP 连结。
-H, –span-hosts 当开始递回时便到外面的主机。
-I, –include-directories=LIST 允许的目录列表。
-X, –exclude-directories=LIST 排除的目录列表。
-nh, –no-host-lookup 不透过 DNS 查寻主机。
-np, –no-parent 不追朔到起源目录。

参考链接

声明:未经允许禁止转载 东东东 陈煜东的博客 文章,谢谢。如经授权,转载请注明: 转载自东东东 陈煜东的博客

本文链接地址: wget 下载整个网页和css、js、图片数据 – https://www.chenyudong.com/archives/wget-download-html-and-image-css.html

分类: Diary

Android、IOS 手机扫描家庭二维码连接 WiFi

在家里亲朋好友来,通过扫描 WiFi 二维码来进行连接家里的 WiFi,不用通过输入密码的方法,这是及其方便的事情。

适用平台

  • Android 手机的系统自带相机
  • Android 系统自带的扫一扫
  • Android 系统上浏览器自带的扫一扫
  • 支持常见的华为、小米、oppo、vivo等安卓系统
  • 苹果 iOS 11 及其以上系统自带相机(iOS 9、iOS 10 不支持)
  • iPhone 6手机如果升级到iOS 11可能会很卡,慎重升级

生成 WiFi 二维码

试验过很多在线 WiFi 二维码的生成软件,很多生成的二维码有问题,支持的手机不过多。有的时候很奇怪。为啥有的手机能连接这个 WiFi,iOS 11的手机就不支持呢。

qrcode-wifi

我试过不同的平台生成二维码,仔细对比,发现每个平台生成的二维码不一样。最后找到了一个适用于 Android 和 iOS 的 WiFi 二维码的序列号。如下:

WIFI:T:WPA;S:wifiname;P:wifipasswd;;

说明一下:

  • WIFI 表示这个是一个连接 WiFi 的协议
  • S 表示后面是 WiFi 的 SSID,wifiname 也就是 WiFi 的名称
  • P 表示后面是 WiFi 的密码,wifipasswd 是 WiFi 的密码
  • T 表示后面是密码的加密方式,WPA/WPA2 大部分都是这个加密方式,也使用WPA。如果写WPA/WPA2我的小米手机无法识别。
  • H 表示这个WiFi是否是隐藏的,直接打开 WiFi 扫不到这个信号。苹果还不支持隐藏模式

二维码通过 https://cli.im/text 这个平台生成,文本信息内容如上,可适用于Android、苹果等系统。

扫一扫结果展示

qrcode-wifi-scan-result

各家手机如何使用扫一扫连WiFi

苹果

打开系统自带相机

小米

打开系统自带相机

华为

系统自带相机无法识别。需要主屏下滑,左上角搜索有个二维码扫一扫。

华为手机使用扫一扫

家里是否可以使用微信连WiFi

不可行。

考虑家里的长辈来家里,一般都装有微信,也习惯使用微信的扫一扫。但是却无法通过微信的扫一扫去连接WiFi。

微信扫一扫直接出来的是文本,无法让系统自动连接上WiFi。

以后微信是否会支持该功能不好说。毕竟苹果还不开放第三方的这个连功能。

那么在商店中经常看见有微信的连WiFi的功能,那个是怎么做到的呢?

这个是需要商店开通微信公众账号,并且必须要使用商户版本的公众账号,普通个人的公众账号是无法开通微信联WiFi的功能的。

另外路由器也是需要支持该功能的才行,现在很多的路由器也都会支持这个插件,例如TP-link的一些说明书上也有说。

对个人家庭来说注册非个人公众账号比较麻烦,所以这个使用微信连WiFi 的思路就放弃了。

声明:未经允许禁止转载 东东东 陈煜东的博客 文章,谢谢。如经授权,转载请注明: 转载自东东东 陈煜东的博客

本文链接地址: Android、IOS 手机扫描家庭二维码连接 WiFi – https://www.chenyudong.com/archives/wifi-qrcode-in-home-android-and-ios.html

分类: 实用技巧

通往财富自由之路 – 入门篇(基金定投)

在网上也看了很多基金定投的一些知识,现在整理一下入门的知识,共享出来,和大家一些交流探讨。

目前主要是入门篇,讲述了一些基金定投的一些基本原理。何时买入、手续费、历史回测模型。

将来再分享进阶篇,何时退出,如何退出,退出的几种策略。计划通过对一些价值平均策略、资产再平衡等进行回测,然后介绍相关理念。

入市有风险,投资需谨慎

View Fullscreen

如果有需要,也可以点击下载网页下载 pdf 文件。

投资有风险,入市需谨慎

by www.chenyudong.com

基础知识

  • 为何要理财
    • 货币超发
    • 货币贬值
    • 通货膨胀,大约每年3%
    • 余额宝收益大约3-4%
    • 现在的1w,10年后只有7k购买力
    • 财务自由?
  • 复利

    • 世界第八大奇迹
    • 假设年化收益率20%
    • 1w 10年后 6.2w
    • 1w 20年后 38w
    • 1w 30年后 237w
    • 1w 40年后 1469w
    • 1w 50年后 9100w

    • 一定要有基数,并且够大,后期雪球才能越来越多。

  • 巴菲特的成功
    • 世界上通过投资获得成功的
    • 不用实体开公司
    • 似乎可复制的成功
    • 长期年化收益率20%
    • 长期来看股票类资产收益最高
  • 暴跌85%,永久停牌

    • 你以为暴跌后还有15%价值?
    • 天真!或永久停牌、资不抵债,破产一分钱也没有。
    • 投资不过山海关
  • 股市挣钱要义

    1. 高抛低吸
    2. 分红 让上市公司来给我们赚钱
  • 基金?股票?
    • 个股容易黑天鹅
    • 购买多只股票资金要求高
    • 基金是一堆股票集合,平摊风险
  • 主动型基金
    • 由基金经理通过策略来买卖股票
    • 盈亏靠基金经理能力
    • 给其他基金,输送利益,不如平均收益
    • 各大基金公司都有老鼠仓情况
  • 跑不过指数基金
    • 指数基金不用太多基金经理的能力
    • 只要定期按照公开的比例买卖股票
    • 大部分基金无法长期跑赢指数
    • 指数基金仓位高,波动高,后面还会提到
    • 费用低,后面也会提到
    • 大部分人收益都是7亏2平1赚

定投

  • 定投
    • 每月买入一些基金
    • 长期购买
    • 有强制储蓄的习惯
    • 适合上班族有每月固定收入,不适合有大笔资产的人
    • 无须耗时打理
    • 长期看股票处于上涨趋势
  • 100元跌10%到多少钱?
  • 再涨多少才能100元?
  • 下跌可以买入更多份额
  • 定额定投而非定量
  • 定量定投是一个高价时花的钱多,低价时花的钱少的策略
  • 仅对长期稳定增长模型有效
  • 喜欢上窜下跳
    • 中小盘
    • 创业板
    • 券商指数
  • 不同时期的买入成本图
  • 不同时期的收益率
  • 微笑曲线
  • 微笑曲线
  • 低点一次买入更好?
    • 无法找到低点
    • 如果能找到n倍杠杠买
    • 定期购买可以摊薄成本,让成本在平均价格上
    • 高阶讲如何在价格低买入更多份额
  • 看到下跌就和商场打折一样,买买买
    • 要的就是这种心态
    • 纽约证券交易所就如同一个大超市,你去那里买股票,你希望什么呢?你当然希望股票降价,一路下滑,因为这样可以让你买到便宜货。
    • 下跌不离场
    • 拥有此心态将和巴菲特越走越近
  • 长期,非短期使用的资金
    • 定投是一个长期行动
    • 需要等待下一个牛市出现
    • 假设资金需要3-5年时间不可动
  • 分红——选现金红利还是红利再投资
    • 红利再投资
    • 分红只是将放在基金中的钱取出来,同时基金市值减少
    • 如果再买入需要手续费
    • 定投是注重牛市高位时将资产卖出赚取价差
    • 分红对持有100w,希望每年有利息到手,用于其他投资,不适合定投
  • 什么时候入场
    • 随时
    • 不用关心高点入场
    • 低点买入会将成本摊薄
  • 什么时候退出
    • 从底部上涨100%差不多考虑卖出一些
    • 跌破60日均线?
    • 跌破240日牛熊线
    • 时候未到,请听高阶课程

实践篇

  • 定投多少合适?
    • 扣除生活必需,剩下可支配的20-50%
    • 100减去年纪占比股票型的资产
    • 定投刚开始就亏钱怎么办?
    • 不要更换品种
    • 不要退出
    • 继续买入
    • 等待牛市
  • 看基金经理,公司真的好吗?
    • 基金经理离职?
    • 公司利益输送?
  • 挑选基金看评级?
    • 幸存者偏差
    • 共3361个基金
    • 双五星41只
    • 去除债券只有20+只
  • 前端收费 后端收费

    • 手续费大约1.2%
    • 指数型基金费用低

    • 长期定投推荐天弘

  • FOF fund of fund

    • 投资基金的基金
    • 资产配置

    • 微信阿牛定投

  • 我的实践

    • 每月
    • 收入定投20%
    • 中证500指数基金

    • 将来买入美国 印度的股票 黄金

  • 实践
    • 蚂蚁聚宝
    • 微信
    • 定投指数基金
    • 如果不知道怎么选,推荐天弘基金费用低
  • 忠告
    1. 停利不停损。
    2. 不要在乎过程,只在乎结果。
    3. 傻傻地买,聪明地卖,卖掉不等于结束,要回头再买。
    4. 金额变大时请记住一点,涨也开心,跌要更开心,否则你会很痛苦。
    5. 纪律投资绝对胜过追逐市场趋势。
  • Questions?
  • Thanks

声明:未经允许禁止转载 东东东 陈煜东的博客 文章,谢谢。如经授权,转载请注明: 转载自东东东 陈煜东的博客

本文链接地址: 通往财富自由之路 – 入门篇(基金定投) – https://www.chenyudong.com/archives/the-way-to-wealth.html

分类: 量化交易

WordPress super cache 出现 cURL Problem with the SSL CA cert

为了让博客加快访问速度,使用了 WP Super Cache 插件。不得不说,这个插件还是比较好用的,对网页的打开速度体验提升很大。平时打开需要 700ms 的网页,现在只要 100ms 左右就可以啦。

按照网上的教程,一步一步的操作,将这些配置好了,但是很奇怪的是,缓存页面的过期效果一直不是自己预期的那样的。

缓存在后台设置了 1800s 的过期时间,那么正常情况下,如果上次的缓存时间超过了这个时间,应该会更新新的缓存网页,但是这个家伙一直都不更新。

点击了 缓存测试,测试一下,发现有失败。

cURL: Problem with the SSL CA cert (path? access rights?)

从字面翻译一下,说是SSL的 CA 证书有问题。考虑目前的机器版本比较老,这个情况是存在的,因此需要更新一下 CA 的证书文件。

通过从互联网上下载最新的文件,来更新一下证书。

curl https://curl.haxx.se/ca/cacert.pem -o /etc/pki/tls/certs/ca-bundle.crt

更新后,在点击测试缓存,可以显示成功了。

wp-super-cache-test-cache

现在缓存的策略能够正常工作了,网页上需要展示的一些数据也被刷新了。

声明:未经允许禁止转载 东东东 陈煜东的博客 文章,谢谢。如经授权,转载请注明: 转载自东东东 陈煜东的博客

本文链接地址: WordPress super cache 出现 cURL Problem with the SSL CA cert – https://www.chenyudong.com/archives/wordpress-super-cache-curl-problem-with-the-ssl-ca-cert.html

分类: WordPress

【偏方】 Python 寻找子列表是否存在与其他列表中

有一个 Python 技术优化,是判断一个列表是否属于另外一个列表,注意列表是有顺序的,不是集合。本来一直想找一个大方的简洁方法的,但没想到最后是通过偏门来解决的。

例如:

l = [(1, 2), (3, 4), (5, 6), (7, 8)]
find = [(3, 4), (5, 6)]

# 期望输出
find in l  -> True

字符串的启发

字符串有一些操作。

l = 'abcdefg'
>>> l.index('ef')
4

>>> l.index('h')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: substring not found

字符串有index方法,可以很方便的判断子字符串是否在给定的字符串中,但是列表类的操作,一直没有找到这类的方法。

在和同事的讨论中,同事给了一个启发,使用repr函数获取可以试试。

用字符串的index函数还有一个好处,就是如果子串不在父串中,直接抛出异常,Python 不像其他语言一样,返回-1

repr转成字符串来处理

l = [(1, 2), (3, 4), (5, 6), (7, 8)]
find = [(3, 4), (5, 6)]

>>> repr(l)
'[(1, 2), (3, 4), (5, 6), (7, 8)]'
>>> repr(find)
'[(3, 4), (5, 6)]'

>>> repr(l)[1:-1].index(repr(find)[1:-1])
8
>>> repr(l)[1:-1].index(repr([(5, 5)])[1:-1])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: substring not found

使用join操作的字符串来判断

http://stackoverflow.com/a/2250981 中获得启发,也是利用字符串的方来进行解决的。

>>> ''.join(map(repr, [(3, 4)])) in ''.join(map(repr, [(1, 2), (3, 4)]))
True

不得不说,对比两个方法,其实都是类似的原理,都是通过字符串的字串来进行比较。思路很新颖,直观给人不用for循环进行处理,代码看上去也很简洁。

但是这些方法也只能是说判断子列表是否存在于另外一个列中的,不能判断子列表在另外一个列表的索引值。

另外该方法也不能保证子串只出现一次的情况。

声明:未经允许禁止转载 东东东 陈煜东的博客 文章,谢谢。如经授权,转载请注明: 转载自东东东 陈煜东的博客

本文链接地址: 【偏方】 Python 寻找子列表是否存在与其他列表中 – https://www.chenyudong.com/archives/python-find-lists-in-lists.html

分类: Python

Python 将两层列表展开平铺成一层的5种方法

这几天和同事在讨论,如何用 Python 写出优雅的让列表中的列表展开,变成扁平化的列表。

例如

# 期望输入
input = [[('A', 1), ('B', 2)], [('C', 3), ('D', 4)]]

# 期望输出
output = [('A', 1), ('B', 2), ('C', 3), ('D', 4)]

map 函数合并

>>> new = []; map(new.extend, input); new
[None, None]
[('A', 1), ('B', 2), ('C', 3), ('D', 4)]

这个方法看上去还可以,但是有个致命的缺点,就是map函数会返回值,并且这个返回值是没有用的。另外还需要提前声明一个变量,从代码的简洁性上,不够简洁优雅。

sum 函数合并

>>> sum(input, [])
[('A', 1), ('B', 2), ('C', 3), ('D', 4)]

这个看上去很简洁,不过有类似字符串累加的性能陷阱。后面有性能对比。

reduce 函数

>>> reduce(list.__add__, input)
[('A', 1), ('B', 2), ('C', 3), ('D', 4)]

做序列的累加操作。也是有累加的性能陷阱。

列表推导式

>>> [item for sublist in input for item in sublist]
[('A', 1), ('B', 2), ('C', 3), ('D', 4)]

列表推导式,看着有些长,而且还要for循环两次,变成一行理解需要费劲一些,没有那么直观。

itertools 类库

>>> list(itertools.chain(*input))
[('A', 1), ('B', 2), ('C', 3), ('D', 4)]

通过第三方类库类实现的,相比其他的几个实现,看着还算比较优雅。最后的性能发现居然还很高。

性能大对比

python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' 'reduce(list.__add__,l)'
1000 loops, best of 3: 547 usec per loop

python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' 'sum(l, [])'
1000 loops, best of 3: 509 usec per loop

python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' '[item for sublist in l for item in sublist]'
10000 loops, best of 3: 52.8 usec per loop

python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99; import itertools;' 'list(itertools.chain(*l))'
10000 loops, best of 3: 35.9 usec per loop

python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' 'new = []; map(new.extend, l); new'
10000 loops, best of 3: 34.1 usec per loop

欢迎大家共同探讨优雅的的实现和性能的优化。

参考:http://stackoverflow.com/questions/952914/making-a-flat-list-out-of-list-of-lists-in-python

声明:未经允许禁止转载 东东东 陈煜东的博客 文章,谢谢。如经授权,转载请注明: 转载自东东东 陈煜东的博客

本文链接地址: Python 将两层列表展开平铺成一层的5种方法 – https://www.chenyudong.com/archives/python-make-flat-list-of-list.html

分类: Python

Python 优雅获取本机 IP 方法

见过很多获取服务器本地IP的代码,个人觉得都不是很好,例如以下这些

不推荐:靠猜测去获取本地IP方法

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import socket
import fcntl
import struct

def get_ip_address(ifname):
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    return socket.inet_ntoa(fcntl.ioctl(
        s.fileno(),
        0x8915,  # SIOCGIFADDR
        struct.pack('256s', ifname[:15])
    )[20:24])

print "br1 = "+ get_ip_address('br1')
print "lo = " + get_ip_address('lo')
print "virbr0 = " + get_ip_address('virbr0')

这类代码带有猜测的行为。

如果机器上只有eth0 或者 只有bond0上有IP,那么此类代码都有可能失败,而且还不容易移植到其他平台上。

不推荐:通过hostname来获取本机IP

import socket
print(socket.gethostbyname(socket.gethostname()))

# 有可能出现这个情况
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
socket.gaierror: [Errno -2] Name or service not known

这个方法是通过获取hostname,然后再通过hostname反查处机器的IP。这个方法也是不推荐的。因为很多的机器没有规范这个hostname的设置。

另外就是有些服务器会在 /etc/hosts 中添加本机的hostname的地址,这个做法也不是不可以,但是如果设置成了 127.0.0.1,那么获取出来的IP就都是这个地址了。

通过 UDP 获取本机 IP,目前见过最优雅的方法

这个方法是目前见过最优雅获取本机服务器的IP方法了。没有任何的依赖,也没有去猜测机器上的网络设备信息。

而且是利用 UDP 协议来实现的,生成一个UDP包,把自己的 IP 放如到 UDP 协议头中,然后从UDP包中获取本机的IP。

这个方法并不会真实的向外部发包,所以用抓包工具是看不到的。但是会申请一个 UDP 的端口,所以如果经常调用也会比较耗时的,这里如果需要可以将查询到的IP给缓存起来,性能可以获得很大提升。

# 在 shell 中可以一行调用,获取到本机IP
python -c "import socket;print([(s.connect(('8.8.8.8', 53)), s.getsockname()[0], s.close()) for s in [socket.socket(socket.AF_INET, socket.SOCK_DGRAM)]][0][1])"
10.12.189.16
# 可以封装成函数,方便 Python 的程序调用
import socket

def get_host_ip():
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        s.connect(('8.8.8.8', 80))
        ip = s.getsockname()[0]
    finally:
        s.close()

    return ip

声明:未经允许禁止转载 东东东 陈煜东的博客 文章,谢谢。如经授权,转载请注明: 转载自东东东 陈煜东的博客

本文链接地址: Python 优雅获取本机 IP 方法 – https://www.chenyudong.com/archives/python-get-local-ip-graceful.html

分类: Python

二八择时轮动模型 量化交易信号

二八择时模型量化交易信号是根据我喜欢的一个微信公众账号 seekingbeta_earl的一个量化模型制作出来的。

二八择时模型有好几个类似的名称,但都是一回事:二八轮动量化模型多空指数二八轮动策略什么的。主要就是大盘蓝筹股和小盘成长股的切换。

因此做了一个简单的网页信号,用来发送信号给判断。不用人肉打开软件计算。网址:二八择时轮动信号 – https://www.chenyudong.com/quant/

效果图

二八择时量化信号

二八择时量化信号

特点

  1. 如果是买入,那么背景颜色是  红色  ;如果是空仓,那么背景是  绿色 
  2. 每天 中午11点31分 计算一次。
  3. 每天临近收盘的 14:3014:4514:5014:55各计算一次。以作决策参考。
  4. 每天 下午15点01分 计算一次。
  5. 起始时间是四周前的收盘价,终止时间是本周的最近一个时刻,方便观察本周的信号。

二八轮动策略?

也叫大小盘轮动策略,“二” 代表数量占比 20% 左右的大盘权重股,“八” 代表数量占比 80% 左右的中小盘股票,二八轮动就是指在大盘股与小盘股中间不断切换,哪个涨的好,就持有哪一个。现在有很多优化策略,增加了一个择时指标,在市场不好的时候,股票空仓,转入债券、货币基金或者国债等稳定性的基金。这样不至于在下跌的过程中空仓浪费本金。

其中大盘权重股一般使用 沪深300指数(399300) 来表示,小盘股一般用 中证500指数(399905) 来表示。

二八轮动策略的原理

二八轮动策略实质是一种“动量效应”。动量效应(Momentum effect)又称“惯性效应”,由Jegadeesh和Titman(1993)提出的,是指股票的收益率有延续原来运动方向的趋势,即过去一段时间收益率较高的股票在未来收益率仍会高于过去收益率较低的股票。总得来说,二八轮动是根据动量效应设计的一种“追涨杀跌”的趋势投资方法,解决了投资者面临的“买什么,什么时候买”等一系列投资痛点。 摘自:https://www.gffunds.com.cn/jjkt/llzl/201611/t20161101_55713.shtml

很多的策略都是这样的追涨杀跌,常见的有 海龟模型趋势交易

二八轮动策略具体规则

操作时间:每周五(或者本周的最后一个交易日)临近收盘时。 买入条件:将沪深300指数和中证500指数切换到周线状态,分别查看两者过去四周的累计涨幅。如果过去四周涨幅大的那个指数在四周中能够获得正回报,那么就在收盘前买入对应的ETF持有一周,直至下一次的切换。 卖出条件:但是如果过去四周涨幅大的那个指数在四周中依然是亏损的,那么就选择空仓(或者购买稳定的债券、货币基金),直至下一次切换。

这个策略,算是一个完整的交易系统了。有买入卖出时机,不过仓位都是满仓。

收益情况

二八轮动 二八择时 收益率曲线

二八轮动 二八择时 收益率曲线

只有在大牛市的时候 2007年 和 2015年 收益快速增加,其他的时候收益率低,甚至还会有比较大的回测。如果这个图延伸到2017年,会再下降好多。

这样的收益率的曲线,我见过一个,就是一个 60日均线的策略。在 60日均线之上买入持有,在60日均线下卖出。基本都能把牛市的一个大收益给纳入囊中。

这类靠趋势吃饭的策略,收益都是靠大牛市来获取的,或者行业轮动什么的。靠分析成长股的策略收益的曲线比指数熊市要好。

60日均线上买入收益率曲线

60日均线上买入收益率曲线

声明:未经允许禁止转载 东东东 陈煜东的博客 文章,谢谢。如经授权,转载请注明: 转载自东东东 陈煜东的博客

本文链接地址: 二八择时轮动模型 量化交易信号 – https://www.chenyudong.com/archives/blue-chip-growth-stocks-trading-signal.html

分类: 量化交易

« 较早的 文章

Copyright © 2018 东东东 陈煜东的博客 粤ICP备13059639号-1

SITEMAP回到顶部 ↑