苏杰的产品创新课学习笔记–从问题到解决方案

在产品创新过程中,产品经理要做到在两个极端之间取得平衡:

不听:与用户接触太少,不了解用户的想法;

照做:用户说什么就做什么;

乔布斯对用户需求的看法:人们不知道自己想要什么,直到你你把它摆在他们面前。

因此产品经理的的心法是:用心听,但不照着做。


用户需求层层深入的过程:

1、用户需求场景,是用户的观点和行为,是表象。

2、用户需求背后的目标和动机,是用户言行的原因。

3、用户心智,是需求的本质,回归到人性和价值观。

从以上三点,归纳出要做什么,按照什么节奏做(把控迭代周期和产品包大小),还要考虑花费多少钱和其他资源。


对照案例:福特汽车

用户需求:更快的马

用户的目标:更快的到达目的地

在一个不成熟的新领域,做到第一层和第二层就可以了。但表层需求被相似的产品跟进后,市场进入成熟阶段的同质性竞争红海,需要我们将产品回归到第三层用户心智。

对照案例:微信游戏打飞机

两点人性诉求:社交和尊重

游戏里面的索要飞机功能,是满足轻度社交的需求;好友排行榜,是满足炫耀和表现自己的诉求。

生活中的对照案例

客厅装修时的多控开关,是表面需求,用户的目标是不走回头路,可以更方便的开关灯,到第三层人性方面,就是人性“懒”的表现,所以有了各种智能设备、有了声控、人体感应灯解决方案。

敏捷开发培训的内容纪要–思维导图

虽然很早之前也看过敏捷宣传的书,敏捷开发有个感性的认识,但由于公司整体上遵瀑布开发模式,因此一直对敏捷处于一知半解的状态。

今年公司计划引入敏捷开发模式,加上去年对外和几个软件开发项目都进展不顺利,因此希望系统化的了解敏捷的理念和实施方法论,因此对3月份进行的2天敏捷培训听得比较认真,并且整理了笔记形成了下面的思维导图。

近期计划在一个真实的项目中,按照Scrum的方式进行敏捷实践,2个月进行8迭代,希望能切实解决目前项目开发的痛点。

敏捷开发培训

mysql执行计划中extra列的内容说明

对mysql执行计划中extra列中部分常见内容含义总结如下:

using index: 使用了索引覆盖,仅通过索引能获取select所需的数据

using index & using where:使用了索引覆盖,但因为有where语句,返回结果进行了进一步的过滤

using index condition:mysql 5.6之后的ICP(Index Condition Pushdown)特性,使用了索引,并回表查询,但where条件可以通过存储引擎过滤,一般情况是where中字段包含使用的索引字段中

using where:表示使用了where语句的过滤条件,和是否使用索引没有直接关系

nginx中rewrite指令使用记录

问题背景说明:

某系统发布的Webservice,经过API网关Kong代理后发现WSDL文件无法查看。
经测试发现原因是因为Kong身份验证的需要,在原url增加了apkikey=xxx这样的参数,如:

http://www.companya.com/app/services/orderDataService?wsdl&apkikey=xxx

该系统处理增加参数的请求时,出现下面的错误信息:

Invalid SOAP request.

解决思路:

在不修改应用程序代码的情况,想办法在nginx层做处理,将请求中apikey=xxx的部分过滤掉,再由tomcat服务器处理。
最终测试成功的nginx配置:

        location /api {
            if ($query_string ~ ^(.*)&apikey=(.*)) {
              set $p $1;
              rewrite ^ $p? last;
            }

            proxy_pass   http://tomcat_cluster;
        }

代码虽然看上去很简单,但由于对nginx的配置写法不熟悉,还是费了不少劲,有几个要点:
1. location的匹配对象,只是uri本身,不包括?之后的参数,如果使用的话用$query_string变量。
2. 代码第3行代码是必须的,因为rewrite本身也使用了正则匹配,如果直接使用$1的话,引用的rewrite匹配的结果。
3. 代码第4行$p后面的分号,也是必须,否则nginx会自动将uri之后的参数,附加到rewrite后的地址,在目前的这个配置下造成循环处理报错。
4. rewrite在最后一个参数,有4个可选项,含义如下:
last 相当于发起一个新的请求,nginx会重现根据location指令进行匹配处理
break 直接使用当前资源,不再执行location里余下的语句
permanent HTTP 301重定向
redirect HTTP 302重定向
前两个浏览器中的url地址不变,后两个会变为rewrite后的地址

参考资料: Nginx的rewrite指令官方文档

oracle用户修改口令审计

1、创建存储更改信息的表

create table PW_CHANGE_LOG
(
  username    VARCHAR2(100),
  change_date DATE,
  host        VARCHAR2(100),
  os_user     VARCHAR2(100)
);

2、使用SYS用户执行下面两个语句,使用Resource Manager来记录口令更改记录

CREATE OR REPLACE FUNCTION password_change_log (
  username varchar2,
  password varchar2,
  old_password varchar2
) RETURN boolean
IS
  v_host varchar2(100);
  v_os_user varchar2(100);
BEGIN
  SELECT SYS_CONTEXT('USERENV', 'HOST'), SYS_CONTEXT('USERENV', 'OS_USER')
  INTO v_host, v_os_user
  FROM DUAL;

  INSERT INTO PW_CHANGE_LOG VALUES (USERNAME, SYSDATE, v_host, v_os_user);
  RETURN(TRUE);
END;
/

CREATE PROFILE LOG_PW_CHANGE LIMIT PASSWORD_VERIFY_FUNCTION PASSWORD_CHANGE_LOG;

shell必备利器-fzf 模糊搜索

大家使用Linux命令行中,是否碰到过这样的场景:以前使用过的命令或文件,但时间一长记得不准确了,但有几个关键字还是有印象的,这时候如何能快速、准确的找出当时的命令或文件?

大家肯定会想到,用history | grep的方法,现在给大家介绍一个更简便的方法,就是今天要说的fzf脚本。

1. 安装(使用git的方法)

git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf
~/.fzf/install

2. 快速查找历史命令
fzf安装后,默认会覆盖原有的Ctrl+R的功能。
因此再按Ctrl+R的时候,就会进入fzf的查找界面,查询方式类似于baidu、google等搜索引擎:支持查询多个关键字,默认为AND的关系。
举个例子:如果记得以前启动seafile的命令,按照记忆输入 seafile start,就可以所有包含这两个关键字的历史命令。
候选列表操作方法:
上下移动:箭头键,或Ctrl+/Ctrl+p
选择:回车键,或用鼠标左键单击
退出:ESC或Ctrl+g

3. 快速选择文件
快捷键:Ctrl+t,列出当前文件夹及子文件夹中的文件

4 快速进入文件夹
快捷键:Atl+c,递归列出当前文件家下的所有子文件
按回车键自动进入选中的文件夹

5. 不使用快捷键的方式触发fzf
在cd vi等命令中选择文件或文件夹的时候,输入**,按TAB,将使用fzf进行查找

参考资料
Shell脚本:模糊搜索神器

曲折的Seafile安装过程

嗯,我得承认,这次安装Seafile折腾的事情,完全是因为最初想偷个懒:申请的vps是centos 6.9 64位,不是Seafile官方推荐的centos 7,所以在网上找了个安装教程开始安装,于是开始了漫长的折腾。

参考文章:
CentOS6.8安装seafile
官方文档: 部署 Seafile 服务器(使用 SQLite)

1、因文件数量不会太多,不想再安装mysql,想用个sqlite算了。结果在安装seafile的时候,报错找不到sqllite3模块。查资料下载源代码编译sqlite3,又重新编译python2.7,算是安装上了。

2、安装完成后启动,一切正常,但访问seahub的时候,出现Internal Error 500的错误。诡异的是,所有日志文件中均没有报错,查了N多资料,最大的可能说是python依赖的包没安装全,但实在没头绪找出缺少哪些包。

3、当时心里不忿,难道6.9就装不上?VPS重新安装了同样的操作系统,按照步骤重新一步一步来,到seafile启动时候,出现和第一个参考资料出现了同样的错误: ”libc.so.6: version `GLIBC_2.14′ not found”.

按照文章中给出的方法,下载新版本的glibc编译安装后,想把lib64/libc.so.6的软链接,修改为编译后libc文件。先把源文件重命名,然后建立新的软连接,居然报错了:

ls: error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory

不得已,查资料修改,按照下面的方法改过来:

LD_PRELOAD=/lib64/libc-2.14.so ln -s /lib64/libc-2.14.so /lib64/libc.so.6

可惜的是,软链接修改后,seafile仍然无法启动。
更悲催的是,中间参考一篇文章,建议将新版本的libc编译覆盖到原位置。尝试了一下,在make或make install中间出错后,出现N多loading shared libraries的问题,基本上这个操作系统的命令都不能用了,连恢复的方法想不到了。

4、幸亏吃饭后脑子清醒了一些:既然操作系统已经坏了,干脆按照官方建议在centos 7下安装吧。
没有再找其他资料,按照官方安装文档一步步执行,顺顺当当的安装成功后,使用也一切正常。

后记:
官方6.1版本的客户端,不支持windows xp操作系统。所幸的是服务器端兼容性比较好,在网上找5.X版本安装后也能正常使用。
吐个槽就是官方的下载页面, 服务器端和客户端都只有最新版本,要是有历史版本的下载链接就更方便了。

zsh使用小记

知乎上关于zsh亮点的文章,我是看了这个介绍才对zsh有了兴趣:为什么说 zsh 是 shell 中的极品?

安装过程

yum -y install git zsh

# 安装oh-my-zsh
wget https://github.com/robbyrussell/oh-my-zsh/raw/master/tools/install.sh -O - | sh

# 安装插件autojump

git clone git://github.com/joelthelion/autojump.git ~/.oh-my-zsh/custom/plugins/autojump
cd  ~/.oh-my-zsh/custom/plugins/autojump
./install.py

# 安装其他插件
git clone https://github.com/zsh-users/zsh-completions ~/.oh-my-zsh/custom/plugins/zsh-completions
git clone https://github.com/zsh-users/zsh-autosuggestions $ZSH_CUSTOM/plugins/zsh-autosuggestions
git clone https://github.com/zsh-users/zsh-syntax-highlighting.git ${ZSH_CUSTOM}/plugins/zsh-syntax-highlighting

# 修改~/.zshrc
# 加到最后一行
[[ -s ~/.autojump/etc/profile.d/autojump.sh ]] && . ~/.autojump/etc/profile.d/autojump.sh
# 启用插件
plugins=(
  git autojump zsh-completions zsh-autosuggestions zsh-syntax-highlighting
)
# 修改插件主题
ZSH_THEME="ys"

# 重新加载配置文件
source ~/.zshrc
autoload -U compinit && compinit

# 打开新的terminal, 验证新的插件功能是否已经生效

zsh的插件列表:
awesome-zsh-plugins
oh-my-zsh Plugins Overview

另外记录两个其他的命令

# 修改时区
echo "export TZ='Asia/Shanghai'" >> /etc/profile
source /etc/profile

# 查看历史操作,去重
history | awk '{$1=""; print $0;}' | uniq

Tmux学习记录

一、安装
高版本的centos可以用yum直接安装,我用5.9 64位版本还不行,需要从源代码编译,且需要先编译依赖的libevent包
参考文章:Tmux学习笔记
有几个补充:
1. 首先需安装gcc
2. ncurses安装的是6.1版本,5.9版本在make的时候会报错
3. tmux安装版本为2.6
4. tmux的configure语句需修改

yum install gcc ncurses-devel

wget https://cloud.github.com/downloads/libevent/libevent/libevent-2.0.21-stable.tar.gz
tar zxvf libevent-2.0.21-stable.tar.gz
cd libevent-2.0.21-stable
./configure --prefix=/usr/local/libevent
make && make install

wget http://ftp.gnu.org/pub/gnu/ncurses/ncurses-6.1.tar.gz
tar xf ncurses-6.1.tar.gz
cd ncurses-6.1
./configure --prefix=/usr/local/ncurses
make && make install

wget https://github.com/tmux/tmux/releases/download/2.6/tmux-2.6.tar.gz
tar xf tmux-2.6.tar.gz
cd /opt/tmux-2.6
./configure CFLAGS="-I/usr/local/libevent/include -I/usr/local/ncurses/include" LDFLAGS="-L/usr/local/libevent/lib -L/usr/local/ncurses/lib" --prefix=/usr/local/tmux

cp /usr/local/libevent/lib/libevent-2.0.so.5 /usr/lib64
cp /usr/local/tmux/bin/tmux /usr/local/bin/

tmux -V

二、使用教程的参考文章:
Tmux使用手册
tmux-Productive-Mouse-Free-Development_zh
上面的文章已经讲的非常全面了,在实际测试过程中,记录几个实用的小Tips:
1、我是在windows上使用ssh的方式连接linux服务器上,如果想把Tmux窗口中文本复制到windows上,可以使用Shift+鼠标左键选择的方式。使用shift+insert的快捷键,可以将windows操作系统的剪贴板内容复制到tmux中。
2、快捷键Crtl+d可以直接关闭当前窗口
3、Tmux的窗口是没有滚动条的,如果想查看屏幕以前输出的内容,需要先进入复制模式,按照vi的方式进行上下滚动(j/k按行滚动,Crtl+b/Ctrl+f按屏幕滚动)
4、快捷键Prefix+=,列出所有粘贴缓存区并粘贴选中的缓存内容,可以在不同的session、窗口之间共享数据,相当于windows中的多重剪贴板功能,非常实用。

===update 2018-04-06===

为了让tmux中vi正常显示中文,需要设置环境变量
export LANG=”zh_CN.utf8″
export LC_ALL=”zh_CN.utf8″

superset安装记录

由于不熟悉python,踩了不少坑,仅以此文记录

1. centos 5.8 32位,更新及安装基本的编译环境

sudo yum upgrade python-setuptools
sudo yum install gcc gcc-c++ libffi-devel python-devel python-pip python-wheel openssl-devel libsasl2-devel openldap-devel

2. 安装Python 3.4.8,注意要使用altinstall,否则后面的安装过程会出现找不到python 2 module的错误

wget https://www.python.org/ftp/python/3.4.8/Python-3.4.8.tgz
tar xvf Python-3.4.8.tgz
cd Python-3.4.8

/configure --prefix=/usr/local
make
make altinstall

创建python3和pip的链接

cd /usr/bin
ln -s /usr/local/python3/bin/python3.4 ./python3
ln -s /usr/local/python3/bin/pip3.4 ./pip

不建议将python3设置默认的python执行程序,否则执行后续的yum操作会报错,当然可以用下面的脚本执行yum,但毕竟麻烦。

cd /usr/bin
python2.6 yum list installed

3. 修改环境变量,
当前目录增加到PATH中,设置语言为UTF-8,否则执行fabmanager会报错

vi ~/.bash_profile
将最后几行修改为:

PATH=.:$PATH:$HOME/bin
export PATH
export LC_ALL=en_US.utf-8
export LANG=en_US.utf-8export LANG=en_US.utf-8

4. 安装superset

pip install --upgrade setuptools pip

pip install superset

cd /usr/local/python3.4 /bin
python3 fabmanager create-admin --app superset
python3 superset db upgrade
python3 superset load_examples
python3 superset init
python3 superset runserver

5. 访问superset

http://localhost:8088

用户名为admin,口令是fabmanger中设置的口令

参考资料;
官方安装文档