OOSMOS介绍

原英文 oosmos 官网
无意中看见大牛的微博提及,正好物联网也是本人感兴趣的领域,正好周末闲暇,翻译下文章,切换下心情。水平有限,还请路过的大侠多指点。

正文:

  1. 什么是OOSMOS
    OOSMOS(Object-Oriented State Machine Operating System)代表面向对象的状态机操作系统。它是一个以基本的上下文为对象的操作系统,而不象传统的以线程为对象。

    因为没有线程,所以没有线程栈(译者:消耗较小资源),所以OOSMOS是一个理想的用于那些传统的基于线程的操作系统无法满足的内存紧张的平台环境。

    OOSMOS 有着强大的分级状态机引擎可以管理非常复杂的事件驱动系统。

  2. OOSMOS的优点

  • 很适合:
    物联网(IOT)
    教育-STEM
    创客活动
    医疗设备
    自动化设备
    控制系统
    航天系统
    企业
    逻辑控制/工作流
    各种界面切换控制
    机器人
    基础的只要是事件驱动的系统
  • 免费
  • 适合 c 甚至 c++
  • 封装简单
  • 对CPU消耗低
  • 没有线程,也就没有线程栈
  • 特别的进行了面相对象的封装和无关信息隐藏
  • 灵活扩展
  • 高效,对象的时间和内存消耗固定
  • 强大的状态机引擎
    支持不限数量的当前对象超时。
  • 支持状态查询
  • 支持异步函数
  • 支持正交区域
  • 支持状态机调试
  • 支持事件管理
    事件码通过对象的类来管理
    事件支持参数传递
    事件支持发布/订阅模式
    事件对象有自己的事件队列
  • 移植方便,基于c 89,还在以下的环境测试:
    MPLABX(包含ChipKit的PIC32系列)
    Arduino(AVR,ARM)
    ChipKit(PIC32,使用类Arduino或者MPLAB X)
    Energia(MSP430,使用类Arduino IDE)
    Intel Galileo
    mbed(ARM,使用web IDE)
    MSP430
    LightBlue Bean
    ESP8266
    Linux(树莓派)
    Windows(Visual Studio)
  1. OOSMOS是怎么工作的-简介
    OOSMOS由对象组成,每一个对象可以有一个状态机能反映对象当前的状态。
    工作时,最重要的是可视化,所以让我们看一些已经运行一段时间的状态机(图 1)

    图1 两个运行态的对象状态切换图
    上图中,红框代表对象的当前状态,我们看到A的状态是On,B的状态是Off。
    OOSMOS循环地一个一个运行每一个对象。
    当OOSMOS反转对象A时,A就变成On状态,唯一退出On状态的方式是tm(m_TimeOnMS)超时,超时前,每一次都运行A。OOSMOS会检查对象是否超时,如果超时,将会向对象发送TIMEOUT事件,对象将会调用oosmos_Transition方法,状态由On切换为Off。在切换的同时,OOSMOS将会在On状态调用EXIT事件,然后调用ENTER事件,变成Off状态。如果没有超时,切换就不会发生,对象会一直保持当前状态。

  2. 学习OOSMOS的最好方式
    学习OOSMOS最好的方式是下载和解压项目,然后编译其中的例子,选择你最合适和熟悉的平台。修改下代码,看下新的项目行为,从而通过比较学习。
    开始学习时,Windows或者Linux例子是不错的选择,你可以用源码级别的调试工具去设置断点和现实变量。
    OOSMOS用户手册涵盖所有的概念和技术点。OOSMOS API参考手册提供快速的函数和宏查看。

over,have fun!

通过event-hook将Github自动部署至Hugo网站

WHAT

hugo是一个轻量高效的博客系统,很适合个人博客。使用hugo,我们只要写作完markdown文档,就可以利用hugo工具,自动生成网页,
变成我们的网站。

我们理想的步骤:

  • 在github上写完markdown文章
  • 提交完后,数秒后就看见了我们的网站页面
  • 在github上修改完网站的配置文件,数秒后我们的网站就变化和更新了。

好爽!

流程

为了完成上面的效果,我们大概分为几步:

  1. 设置github的webservice hook。当完成一篇新的文章或者修改旧的文章后,github就会向目标网站发webservice hook消息。
  2. 目标网站收到消息后git pull,解析消息特征,更新相关的文档,最后调用hugo
  3. hugo将markdown文章转化成html静态页面
  4. 将html页面部署到目标web服务器

HOW

详细请移步:
https://github.com/hiproz/hugo-sync

分分钟就搞定了,一劳永逸!

have fun!

docker中的”layers”指的是什么东西

在很多的docker的说明中,我们都能看到“layer”的身影,那么到底什么是”layer“?

参见http://docker-doc.readthedocs.org/en/latest/terms/layer.html中的说明:

When Docker mounts the rootfs, it starts read-only, as in a traditional Linux boot, but then, instead of changing the file system to read-write mode, it takes advantage of a union mount to add a read-write file system over the read-only file system. In fact there may be multiple read-only file systems stacked on top of each other. We think of each one of these file systems as a layer.

简单翻译如下:
当docker加载rootfs时,和传统的linux系统中一样,它是只读的,但是随后,不是将当前文件系统变成可读写,而是利用union mount添加一个可读写的文件系统在当前的只读系统上。实际上将会有很多的只读文件系统叠加在彼此之上。我们将这里的每一层文件系统称之为”layer”。

参考阅读:
https://docs.docker.com/engine/understanding-docker/#how-does-a-docker-image-work
https://www.ctl.io/developers/blog/post/caching-docker-images/

手机多基站定位中RXLEV跟接收信号强度(dbm)的对应关系

在开发手机多基站定位的过程中,会获取手机当前基站周边的其他基站的接收侧信号等级rxlev,当我们要做多基站定位时,要转化成基站侧的信号强度。 RXLEV跟接收信号强度的对应关系如下表:(信号依次增强)

RXLEV = 0                             RX < -110 dBm

RXLEV = 1        -110 dBm =< RX < -109 dBm

RXLEV = 2        -109 dBm =< RX < -108 dBm

RXLEV = 3        -108 dBm =< RX < -107 dBm

RXLEV = 61       -50  dBm =< RX <  -49 dBm

RXLEV = 62       -49  dBm =< RX <= -48 dBm

RXLEV = 63                           RX >  -48 dBm

APNs调试工具Knuff介绍

作为一个ios开发者,在你调试APNs时,正常的情况下你需要弄好证书给到后台的同事上线到测试环境,然后才能开始测试调试推送的相关功能。

如果这个过程遇到证书错误,后台代码错误,苹果变更接口等,等到能调试ios的功能,需要等到好久的时间。

那么ios可以独立调试APNs的相关功能吗?当然可以,Knuff就是一款简洁简单的推送调试工具。下面的以MAC的为介绍对象,其他平台的请自行理解。

软件界面如下:

Knuff功能说明

Custom:自定义模式,可以自行选择证书,我们测试自己的应用,就用这个模式

Knuff iOS: Knuff iOS表示使用Knuff的证书,直接推送给Knuff配套的ios应用。

Choose:选择推送的push证书,我们需要选择我们证书,关于如何生成正确的证书,请自行google。

Production:选择证书后,就会出现这个选择,production表示appstore证书,推送给appstore版本的APP。

Sandbox:表示开发调试的非AppStore版本。

Priority:测试时可随意选择。

Payload:表示要推送的报文,具体字段含义这里就不展开了,请自行了解。

Token:device token,在注册苹果 APNs服务时获取的。参考代码如下:

注册服务

[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings
                                                                             settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge)
                                                                             categories:nil]];

[[UIApplication sharedApplication] registerForRemoteNotifications];

回调事件
调用didRegisterForRemoteNotificationsWithDeviceToken

至此我们就可以开始测试了,通过这个工具我们就能轻易的测试我们的device token是否正确,测试我们生成的证书是否正确。给自己发送任意想测试的payload。

have fun!

关于苹果前后台定位的使用

其实主要就是要理解这两个函数的功能和适用场景:
startUpdatingLocation
startMonitoringSignificantLocationChanges

可以参看苹果的这个demo:https://developer.apple.com/library/content/samplecode/Regions/Introduction/Intro.html
理解了,自己改动下,就能实现强大的后台定位

2016.12.25:
了解更多的细节,可以参看这里,全部确认到了,基本就搞定了:
https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/LocationAwarenessPG/CoreLocation/CoreLocation.html

linker command failed with exit code 1 (use -v to see invocation)

最近在重构之前的代码,所以在本地游多个分支,经常出现如下的问题:
linker command failed with exit code 1 (use -v to see invocation)

之前也是基本重新update下pod基本就ok,今天发现之前ok的提交到git的代码,拉到本地又出现这个问题了,所有有必要弄清楚根源,避免每次都各种莫名尝试浪费时间。

从其中的一条错误提示入手:

ld: warning: directory not found for option ‘-L/Users/xxx/Library/Developer/Xcode/DerivedData/xxx-gttrbsolrpknxhbtjxulraplunas/Build/Products/Debug-iphonesimulator/AFNetworking’

在这个路径下确实发现缺少东西,对于目前成功编译的项目,我们手动删除目标后,再此编译,发现也提示这个错误这个很奇怪,按理应该成功才对。所以初步的原因是这个目标对象对应的pod库没有。那么是什么时候生成的呢,我们进一步分析。

在尝试了pod install和update后,目标并没有生成,所以pod阶段只是创建关联project。应该还是在编译阶段生成的。

按照正常的流程,应该是build时生成相应的target的库,现在却没有生成,进一步在网上搜索,看到“Build Active Architecture Only”
这个选项,当为 YES时,表示只编译当前的architecture版本。所以改为yes后,便可以生成当前 architecture的库了。

所以失败的原因是,这个选项为NO时默认生成所有的target的库,但是是按默认顺序的,还并没有来的及生成当前的目标库,所以link时就失败了。改为YES,相当于当前平台更改为了最高优先级,所以就直接生成了。

NSManageObjectContext – Class is not key value coding-compliant for the key @count

最近把ios的代码升级到了ios10和xcode8 ,出现了大量:

NSManageObjectContext – Class is not key value coding-compliant for the key @count

解决:
参考:http://stackoverflow.com/questions/39511997/nsmanageobjectcontext-class-is-not-key-value-coding-compliant-for-the-key-cou

更新RestKit:
pod ‘RestKit’, :git => ‘https://github.com/RestKit/RestKit.git’, :commit => ‘9cbba9eb1b490c3c5e2873c8fba8e9c0fec1bf07’

更新后会有新的错误,依照提示修复就可以了。

centos开启swap

os:centos6
type:vps
1. 创建用于交换分区的文件
2. 设置交换分区文件
3. 立即启用交换分区文件
4. 设置开机时自启用swap分区,需要修改文件/etc/fstab中的swap行,添加记录。

dd if=/dev/zero of=/data/swap bs=1M count=4096
mkswap /data/swap
swapon /data/swap
/data/swap swap swap defaults 0 0

mysql批量备份脚本

如何实现自动备份数据路里面所有业务表的功能:

#!/bin/bash
echo "Dump mysql databases..."

DB_USER=xxx
DB_PASSWORD=xxx

DB_LIST=$(echo "show databases;" | mysql -u${DB_USER} -p${DB_PASSWORD})
for db in ${DB_LIST}
do
  if [ $db != "Database" ] && [ $db != "mysql" ] &&
      [ $db != "phpmyadmin" ] && [ $db != "information_schema" ] &&
      [ $db != "performance_schema" ]; then
    echo "  backup "$db
    mysqldump -u${DB_USER} -p${DB_PASSWORD} $db > ./$db.sql
  fi
done

这一生,至少当一次傻瓜-奇迹的苹果

如果把读书比多银海拾贝,这本书就是沙粒中一颗精致优美的贝壳。

本书很精薄,我基本上是一口气读完的,从晚上9点多到临晨1点多。

全书讲述了主人公木村,因执念绿色种植苹果的理念,被人当作傻子,最终经历8年的执着和等待,最终获得成功的故事。

故事里面不光有木村的执着,还有生动鲜活的果园风光,虫鸟与风草。文章细致描写了绿色种植理念的起因和主人公实际操作后面临的真实果园处境,采用第三视角和第一视角口述的方式交叉推进,显得真实而生动。

当主人公经历8年的辛苦,孤独,嘲讽,最终看到开花结果,而他的岳父母去世的时候,我的眼眶湿润了,有多少奋斗的人能等到亲人共享的时刻。

当因为自己的执念而让妻子和孩子受苦时,木村的心里苦不甘言,只能默默承受,恰似无数正在奋斗的人们。

最终执念和傻得到了回报,而我经历了一次难得的心灵旅程。

人生难得执念,主人公的成功也不必介怀,真实的人生,大部分人面临的最终可能是失败。

but:
人生只有一次,这种执念傻瓜的经历,又何尝不是一种幸福和境界?

OpenResty最佳实践-随笔

简介

完整内容地址:https://moonbingbing.gitbooks.io/openresty-best-practices/content/index.html

决定在动手之前先把这本书浅读一遍,磨刀不误砍柴工。

这里记录的都是我自己的理解和观点,或者需要强调的知识点,并不代表书的详细内容,详细还是请参见原文。

纪要

  1. lua葡萄牙语里面表示美丽的月亮。
  2. 纯c编写,能被当作c库嵌入和调用,能方便和c/c++相互调用。
  3. 变量没有类型,可以动态绑定。
  4. 运行期能编译字符串形式的程序文本并载入虚拟机执行。(这个有点意思)
  5. nil 是一种类型,Lua 将 nil 用于表示“无效值”。Lua 中 nil 和 false 为“假”,其它所有值均为“真”。比如 0 和空字符串就是“真”;(惊讶)
  6. table:“关联数组” 是一种具有特殊索引方式的数组,索引通常是字符串(string)或者 number 类型,但也可以是除 nil 以外的任意类型的值。
  7. 与或是and or,结果不再是0或者1
  8. do return end 实现代码return的随意打桩
  9. 函数支持变长参数 …
  10. 做函数参数时,table是传引用,其他类型都是传值
  11. 模块的全局变量检测用工具releng
  12. 字符串下标是从1开始的,跟物理位置次序一致
  13. openresety支持防止sql注入的方法
  14. 支持匿名对象 ” _ “,用来占位,这个和golang一致
  15. 压力测试的好工具wrk
  16. 规则中尽量不要使用if
  17. 代码中不要使用阻塞操作,尽量不要使用lua的原生接口,使用openresty的相应接口
  18. 火焰图是个定位底层调用栈的好东西
  19. cosocket是好东西

openresty安装篇

环境版本

OS:CentOS Linux release 7.1.1503 (Core)
openresty:1.9.15.1

安装准备

除非你要修改源码,如果只是运行官方的包,官方建议优先考虑预编译包,centos 系统支持如下:

版本号 支持的体系结构
5.x x86_64, i386
6.x x86_64, i386
7.x x86_64

配置yum源

你可以在你的 CentOS 系统中添加 openresty 资源库,这样就可以方便的安装我们的包,以后也可以更新(通过 yum update 命令)。添加资源库,你只用创建一个名为 /etc/yum.repos.d/OpenResty.repo 的文件,内容如下:

[openresty]
name=Official OpenResty Repository
baseurl=https://copr-be.cloud.fedoraproject.org/results/openresty/openresty/epel-$releasever-$basearch/
skip_if_unavailable=True
gpgcheck=1
gpgkey=https://copr-be.cloud.fedoraproject.org/results/openresty/openresty/pubkey.gpg
enabled=1
enabled_metadata=1

显示支持的包

sudo yum –disablerepo=”*” –enablerepo=”openresty” list available

Loaded plugins: fastestmirror
openresty                                         | 3.5 kB     00:00     
openresty/7/x86_64/primary_db                       |  32 kB   00:01     
Determining fastest mirrors
Available Packages
openresty.x86_64                         1.9.15.1-16.el7.centos openresty
openresty-debug.x86_64                   1.9.15.1-7.el7.centos  openresty
openresty-debug-debuginfo.x86_64         1.9.15.1-7.el7.centos  openresty
openresty-debuginfo.x86_64               1.9.15.1-16.el7.centos openresty
openresty-doc.noarch                     1.9.15.1-16.el7.centos openresty
openresty-openssl.x86_64                 1.0.2h-3.el7.centos    openresty
openresty-openssl-debug.x86_64           1.0.2h-4.el7.centos    openresty
openresty-openssl-debug-debuginfo.x86_64 1.0.2h-4.el7.centos    openresty
openresty-openssl-debug-devel.x86_64     1.0.2h-4.el7.centos    openresty
openresty-openssl-debuginfo.x86_64       1.0.2h-3.el7.centos    openresty
openresty-openssl-devel.x86_64           1.0.2h-3.el7.centos    openresty
openresty-resty.noarch                   1.9.15.1-16.el7.centos openresty
openresty-valgrind.x86_64                1.9.15.1-6.el7.centos  openresty
openresty-valgrind-debuginfo.x86_64      1.9.15.1-6.el7.centos  openresty
perl-Lemplate.noarch                     0.07-3.el7.centos      openresty
perl-Test-Nginx.noarch                   0.25-3.el7.centos      openresty

安装

关于openresty的rpm包的介绍见这里:http://openresty.org/cn/rpm-packages.html

按照文档的说明,我们暂时只需要安装openresty,openresty-resty,openresty-doc三个包就可以了

yum install openresty
yum install openresty-resty
yum install openresty-doc

运行

sudo /sbin/service openresty start

stop, restart, 和 reload 这些指令也是支持的。

默认网站实例是加载在/usr/local/openresty/nginx/ 目录下的,如果要改变成自定义的目录使用 -p 选项:

sudo openresty -p /opt/my-fancy-app/

这个命令实测,是需要手动创建目录的,记得要先停止openresty。

其他问题

防火墙

在centos7下面,防火墙由iptables变更为firewalld,测试时需要增加相应的80端口,或者暂时关闭防火墙。

配置firewalld 使用firewall-cmd,默认需要安装:

yum install firewalld firewalld-config

查看当前开放zone,端口,服务:

firewall-cmd --get-active-zones
firewall-cmd --zone=public --list-ports
firewall-cmd --zone=public --list-service

增加80端口:

firewall-cmd --zone=public --add-port=80/tcp

自启动

添加openresty的开机自启动:

chkconfig --add openresty
chkconfig openresty on

由于centos已经用systemD代替了systemV,系统不再有rc-local服务了,所以我们也不能简单添加rc.local了(网上流传的给增加运行权限的,在本机验证不成功)。标准的做法就是创建新的任务,通过chkconfig来启动了。

因为firewallD的规则是不能保存的,所以我们要放到开机自启动脚本中。

libreswan libevent错误

安装libreswan时遇到如下的错误:

/data/l2tp/l2tp/libreswan-3.17/programs/pluto/state.c:800: undefined reference to event_free'
server.o: In function
init_event_base’:
/data/l2tp/l2tp/libreswan-3.17/programs/pluto/server.c:582: undefined reference to evthread_make_base_notifiable'
server.o: In function
pluto_event_new’:
/data/l2tp/l2tp/libreswan-3.17/programs/pluto/server.c:442: undefined reference to event_new'
server.o: In function
pluto_event_free’:
/data/l2tp/l2tp/libreswan-3.17/programs/pluto/server.c:588: undefined reference to event_free'
/data/l2tp/l2tp/libreswan-3.17/programs/pluto/server.c:589: undefined reference to
event_free’
/data/l2tp/l2tp/libreswan-3.17/programs/pluto/server.c:590: undefined reference to event_free'
/data/l2tp/l2tp/libreswan-3.17/programs/pluto/server.c:591: undefined reference to
event_free’
timer.o: In function delete_pluto_event':
/data/l2tp/l2tp/libreswan-3.17/programs/pluto/timer.c:814: undefined reference to
event_free’
ikev2_parent.o:/data/l2tp/l2tp/libreswan-3.17/programs/pluto/ikev2_parent.c:2704: more undefined references to event_free' follow
/usr/local/lib/libevent_pthreads.so: undefined reference to
evthread_set_condition_callbacks’
/usr/local/lib/libevent_pthreads.so: undefined reference to event_mm_malloc_'
/usr/local/lib/libevent_pthreads.so: undefined reference to
event_mm_free_’
/usr/local/lib/libevent_pthreads.so: undefined reference to evthread_set_id_callback'
/usr/local/lib/libevent_pthreads.so: undefined reference to
evthread_set_lock_callbacks’
collect2: ld returned 1 exit status
make[3]: *** [pluto] Error 1
make[3]: Leaving directory /data/l2tp/l2tp/libreswan-3.17/OBJ.linux.x86_64/programs/pluto'
make[2]: *** [local-base] Error 2
make[2]: Leaving directory
/data/l2tp/l2tp/libreswan-3.17/programs/pluto’
make[1]: *** [all] Error 2
make[1]: Leaving directory `/data/l2tp/l2tp/libreswan-3.17/programs’
make: *** [all] Error 2
libreswan-3.17 install failed.

问题分析:
1. 检查libreswan的版本和代码包的正确性,去官网下载比对,确认下载是最新的代码。
2. 查看日志,根据event_free关键词,判断出问题的应该是libevent库,所以确认libevent,发现已经按照说明成功下载了libevent2了。
3. 继续查找日志细节:
—> Package libevent2.x86_64 0:2.0.21-2.el6 will be installed
–> Processing Conflict: libevent2-devel-2.0.21-2.el6.x86_64 conflicts libevent-devel
–> Finished Dependency Resolution
Error: libevent2-devel conflicts with libevent-devel-1.4.13-4.el6.x8664
从上面的提示看到是libevent2跟系统默认自带的libevent冲突了

解决:
yum remove libevent-devel-1.4.13-4.el6.x86_64

yum install libevent2-devel

strongswan charon logging 配置

系统:ubuntu 14.04

strongswan 配置文件路径 /usr/local/etc/

默认的strongwan的日志是打印在syslog 里面的。为了便于管理和分析,我们希望日志能打印在专门的文件里。而strongswan 自带的charon守护服务就默认包含了charon-logging功能,我们只要开启此功能即可。

相关的配置参考如下:
https://wiki.strongswan.org/projects/strongswan/wiki/LoggerConfiguration

新史太阁记-一个不世出的产品经理成长史

因为刚看完了《丰臣秀吉》,想找些其他描写日本社会文化历史以及现状的书籍时,一不小心就看到了这本司马辽太郎的《新史太阁记》。

书的内容基本沿袭大的历史框架,不再有秀吉嗜好女色的大篇幅描写,也没有更多的民间传说的影子,总之更贴近历史的脉络,少了些民间的历史玄幻。小说从秀吉的少年开始,一直到巅峰时期,戛然而止。

这期间陆陆续续看了些秀吉的书,还有影视材料,最震撼的不仅是日本战国的武士情怀,还有出于职业背景的条件反射:如何成为一个伟大的产品经理。注意,我特意使用了伟大一词。

对于技术人的成功,我一直坚持认为:技术-产品-公司,这3个梯度的进阶和成功,才是真正的成功。而这三个体度的难度系数相差远不止一个数量级。而要完成这样的转变,你要有开阔的眼界和思维,要理解社会的发展和人性的需求,要有理想主义者的坚持和奉献牺牲。

我看到过很多技术牛人,他们热衷于 一系列能让人感觉新奇的技术,但是他们却很难理解要为产品或者公司的成功去奉献和坚持,他们更关注短期的自我的收获,缺乏长远的对产品成功,公司成功的认知和追求。会新奇的技术是有价值的,但最终为大众提供价值的是产品本身,这个涵盖技术,设计,交互,服务等,远不是很多技术人想象的因为一个所谓的技术就能怎样。

好吧,扯远了,说一说我从秀吉的故事中总结的一个伟大的产品经理的一些要素吧。

我们一般说的产品经理的价值:

清晰准确的产品定义:功能需求定义,目标用户群体定义,商业模型定义,生命周期定义。
秀吉:每一次的战事秀吉都有着清晰的产品定义,他知道自己最终要的是臣服和胜利,所以他会选择合理的战术方略,而不是简单粗暴野战屠杀,故事里面每一战事秀吉都有着很深入的分析和合适的方案提出,而这一切都是因为他对目标有着清晰的定义,能外交的就不兵刃,能围城的就不破城,因为我要的是胜利,而不是摧毁对方和杀戮。

技术质量的保障:依赖自身的知识背景,采用合理的管理方式,选择正确的技术架构,来保证可靠,低成本,快速的实现产品解决方案。
秀吉:故事里的秀吉每一此都能根据天时地利提出一套低成本而且行之有效战事方略,这些战术的方案最终保证了秀吉在保存力量的情况下取得成功。

沟通协调:在遇到资源问题或者对外需求时,能高效的沟通和获取资源保证团队的进度需求,在收到内部领导的不合理需求时,也能顶住压力和风险,保证团队能按照正确的方式和方向去开发。
秀吉:毋庸置疑,历史上真正的秀吉无论跟信长还是家康比,秀吉无疑是一个善于沟通,善于外交的政治家。

士气目标管理:产品经理不是简单的让相关的设计开发坐在一起开发就好了,要了解每个人的性格,让所有人都能认识到产品项目的价值,都能认识到自身的价值,充分体现自豪感和主动性,从而发挥巨大的价值,最终形成团队超强的战斗力。在取得阶段的进步或者奖励时,也能适时的鼓励团队,鼓励成员,保证团队高昂的士气,从而取得不可能达到的成绩。
秀吉:秀吉的部下基本都是草莽出身之所以能取得最后的高水准的胜利,得益于秀吉队伍高昂的士气,无论是通过金钱的奖励还是封地的奖赏。

背黑锅:大家都是凡人,不是神仙,到最后难免有错误的决定或者失败的计划,产品经理的另外一个用户就是替大家来背黑锅。因为产品经理就是产品和团队的负责人,失败了,产品经理是最大的责任人,无需客观理由。

而要成为伟大的产品经理,还需具备:

对产品方向执着的信念:无论是早期对信长的神一般的信仰还是后面对胜利的信念,秀吉能走这么远,能在众多的力量中崛起,最重要的是秀吉是一个理想主义者,靠执着的信念在一次次的战事和政治中取得成功。

克服一切困难创造条件解决问题的能力:面对困难时,在其他人迟疑时,秀吉积极承担,克服不利,最终树立了在织田家的声望和地位,比如美浓之战的善后工作。

愿意付出一切保证产品成功的奉献精神:秀吉对每一次的任务都是倾尽全力的,可以说为达目标不择手段,甚至去做一些被人唾骂的残忍行为。

最终,秀吉从一个茅屋少年成为日本战国时代的一代枭雄,成为了一个伟大的产品经理。