几道 C++ 问题

Question 6

Method overriding is key to the concept of Polymorphism. 覆盖是多态的核心 True

多态可以概括成“一个接口,多个方法”,运行时决定调用函数。C++ 多态利用虚函数实现,虚函数允许子类重新定义方法,子类重新定义方法的做法称为“覆盖”,或者重写。(直接覆盖成员函数和覆盖虚函数,只有重写了虚函数的才能算作是体现了C++ 多态性)

封装可以使得代码模块化,继承可以扩展已存在的代码,而多态的目的则是为了接口重用。也就是说,不论传递过来的究竟是那个类的对象,函数都能够通过同一个接口调用到适应各自对象的实现方法。

最常见的用法就是声明基类的指针,利用该指针指向任意一个子类对象,调用相应的虚函数,可以根据指向的子类的不同而实现不同的方法。如果没有使用虚函数的话,即没有利用C++多态性,则利用基类指针调用相应的函数的时候,将总被限制在基类函数本身,而无法调用到子类中被重写过的函数。因为没有多态性,函数调用的地址将是一定的,而固定的地址将始终调用到同一个函数,这就无法实现一个接口,多种方法的目的了。

#include <iostream>  
using namespace std;  

class A  
{  
public:  
    void foo()  
    {  
        printf("1\n");  
    }  
    virtual void fun()  
    {  
        printf("2\n");  
    }  
};  
class B : public A  
{  
public:  
    void foo()  
    {  
        printf("3\n");  
    }  
    void fun()  
    {  
        printf("4\n");  
    }  
};  
int main(void)  
{  
    A a;  
    B b;  
    A *p = &a;  
    p->foo();  
    p->fun();  
    p = &b;  
    p->foo();  
    p->fun();  
    return 0;  
}  

输出
1 2
1 4

基类指针指向基类对象,调用基类函数;基类指针指向子类对象, p->foo() 指针是个基类指针,指向是一个固定偏移量的函数,因此此时指向的就只能是基类的foo()函数的代码了,因此输出的结果还是1。而p->fun() 指针是基类指针,指向的fun是一个虚函数,由于每个虚函数都有一个虚函数列表,此时p调用fun()并不是直接调用函数,而是通过虚函数列表找到相应的函数的地址,因此根据指向的对象不同,函数地址也将不同,这里将找到对应的子类的fun()函数的地址,因此输出的结果也会是子类的结果4。

上面例子,还有一种问法

B *ptr = (B *)&a;  ptr->foo();  ptr->fun();

输出
3 2

从原理上来解释,由于B是子类指针,虽然被赋予了基类对象地址,但是ptr->foo()在调用的时候,由于地址偏移量固定,偏移量是子类对象的偏移量,于是即使在指向了一个基类对象的情况下,还是调用到了子类的函数,虽然可能从始到终都没有子类对象的实例化出现。而ptr->fun()的调用,可能还是因为C++多态性的原因,由于指向的是一个基类对象,通过虚函数列表的引用,找到了基类中fun()函数的地址,因此调用了基类的函数。由此可见多态性的强大,可以适应各种变化,不论指针是基类的还是子类的,都能找到正确的实现方法。

“隐藏”是指派生类的函数屏蔽了与其同名的基类函数,规则如下: (1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual 关键字,基类的函数将被隐藏(注意别与重载混淆)。 (2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual 关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)。

纯虚函数,virtual ReturnType Function()= 0;

C++支持两种多态性:编译时多态性,运行时多态性。

  • 编译时多态性:通过重载函数实现
  • 运行时多态性:通过虚函数实现。

虚函数是在基类中被声明为virtual,并在派生类中重新定义的成员函数,可实现成员函数的动态覆盖(Override) 包含纯虚函数的类称为抽象类。由于抽象类包含了没有定义的纯虚函数,所以不能定义抽象类的对象。

Q16

Which objected oriented design concept is key to the factory design pattern?

Inheritance

Q23

Which of the following describe the C++ programming language?

Compiled Declarative

Q25

The friend keyword is used to grant access to private class members. True

  1. 友元函数:普通函数对一个访问某个类中的私有或保护成员。
  2. 友元类:类A中的成员函数访问类B中的私有或保护成员。

友元函数

friend <类型><友元函数名>(<参数表>);  

友元函数只是一个普通函数,并不是该类的类成员函数,它可以在任何地方调用,友元函数中通过对象名来访问该类的私有或保护成员

#include <iostream>
using namespace std;

class Base{
public:
    Base(int _data):data(_data){};

    friend int getData(Base& _base);
private:
    int data;
};

int getData(Base& _base){
    return _base.data;
}

int main() {
    Base b(2);
    std::cout << getData(b) << endl;
    return 0;
}

友元类

friend class <友元类名>;

友元类的声明在该类的声明中,而实现在该类外。

#include <iostream>
using namespace std;

class Base{
public:
    Base(int _data):data(_data){};

    friend class FClass;
private:
    int data;
};

class FClass{
public:
    int getData(Base _base){
        return _base.data;		// call friend class private data
    }
};

int main() {
    Base b(2);
    FClass c;
    cout << c.getData(b) << endl;
    return 0;
}

Q38

Choose word or words to describe UML language.

  • Picture
  • Relational
  • Interpreted
  • Abstract
  • None of the answers are correct.

只有 Picture 正确

The Unified Modeling Language (UML) is a general-purpose, developmental, modeling language in the field of software engineering, that is intended to provide a standard way to visualize the design of a system.

为啥没有 Relation 有点神奇~ UML 图能够看出类与类的关系的啊

Q40

Generalization is used by UML to describe Inheritance and the deriving of one class from another.

Generaliztion 是从属关系,可以表示继承,或者派生

http://www.uml-diagrams.org/generalization.html

Q44

#include <iostream>

void f0(int& sum){
    sum = 3+2*7;
}

int main() {
    int *p, sum = 0;
    (*p)++;
    sum = sum * 3;
    f0(sum);
    std::cout << sum << ",";
    return 0;
}

(*p)++ 一行有问题

具体问题内容请看这里


2016-03-03

切换 Linux 内核版本

Linux 内核是开源类 Unix 系统宏内核。仅仅一个内核并不是一套完整的操作系统。有一套基于 Linux 内核的完整操作系统叫作 Linux 操作系统。Kernel 是 Linux 系统的核心,主要负责硬件的支持。

Linux 内核提供了安全补丁, bugfix 和新特性。

Linux 内核在 GNU 通用公共许可证第 2 版之下发布。

修改启动内核版本需要谨慎,每一步在确认知道自己在做什么的情况下再操作。Linux 内核版本变更可能导致网络访问异常,声音异常,甚至是桌面环境无法启动。在安装和移除内核时,确保已经已经阅读过相关帮助,确保自己知道如何选择不同版本的内核,如何恢复之前的版本,以及如何检查 DKMS 状态。

Linux 内核版本号的意义

Linux 内核版本号由 3 组数字组成:第一个组数字。第二组数字。第三组数字

  • 第一个组数字:目前发布的内核主版本。
  • 第二个组数字:偶数表示稳定版本;奇数表示开发中版本。
  • 第三个组数字:错误修补的次数。

查看内核版本

在 Linux 机器上执行如下命令查看当前正在使用的内核版本

uname -r

使用如下命令查看当前系统安装的内核版本

dpkg -l | grep linux-image

如果使用的是 Linux Mint 那么在 Update Manager 中,选择 View -> Linux Kernels 可以查看当前安装的版本和正在使用的版本,或者选择安装新的版本切换。

安装和卸载内核版本

sudo apt search linux-image
sudo apt install xxx
sudo apt-get purge xxx

选择内核版本

一个系统可以同时安装多个内核,但是运行时只能选择一个,当启动电脑时,在显示 grub 菜单时可以选择加载哪一个内核。(当只有一个系统安装时,grub 菜单可能被跳过,强制显示 grub 菜单可以在启动电脑时一直按住 Shift 按键)

Advanced options 选项中,可以选择系统上安装的内核版本,在启动时选择一个即可。

DKMS

DKMS 全称是 Dynamic Kernel Module Support,它可以帮我们维护内核外的这些驱动程序,在内核版本变动之后可以自动重新生成新的模块。

sudo apt-get install dkms

内核包含了所有的开源驱动,一般都可以正常工作,私有的驱动(DVIDIA,AMD,Broadcom… 等等)不包含在其中。这些私有驱动(proprietary drivers)需要在安装时手动编译到每一个内核中。这个操作可以用 dkms 来完成。如果私有驱动无法正常编译到内核中,可能导致启动异常,所以需要提前检查

dkms status

reference


2016-03-02 linux , kernel , versions

Nexus 6 刷机及电信 3G/4G 破解

adb and fastboot

从 Android 开发官网下载 Android SDK,从事过 Android 开发的应该知道 adb 和 fastboot 工具,在完整 SDK 中这两个工具在 platform-tools 文件夹下。如果想要方便的使用这两个工具,可以将文件路径加入到系统环境变量中,这样以后就可以在任何目录使用 adb 和 fastboot 命令。

flash factory image

救砖,或者在 recovery 下没有备份又无法开机的情况下只能刷回原厂镜像救砖机。因此折腾需谨慎,刷机前请一定使用 recovery 备份系统及数据。可以从 Google 官网下载镜像。

下载镜像

https://developers.google.com/android/nexus/images#shamu

解压之后应该会有如下文件

bootloader-shamu-moto-apq8084-71.15.img  2016/01/06  07:19        10,636,288
flash-all.bat                            2016/01/06  07:19               985
flash-all.sh                             2016/01/06  07:19               856
flash-base.sh                            2016/01/06  07:19               814
image-shamu-mmb29q.zip                   2016/01/06  07:19     1,009,825,337
radio-shamu-d4.01-9625-05.32+fsg-9625-02.109.img      2016/01/06  07:19       118,272,512

解锁bootloader

解锁 bootloader 会抹去手机一切内容,需谨慎,总之只需要一句命令

 fastboot oem unlock

然后利用音量键及电源键来确认解锁 bootloader, 之后运行

 fastboot reboot

重启手机。

刷镜像

  1. 关机并进入 fastboot 也就是 bootloader模式,在关机状态下,同时按住“电源键”+“音量下”
  2. 数据线连接手机与电脑,在驱动安装正确之后
  3. 执行 flash-all.bat (Windows 下) 或者 flash-all.sh (MAC或者 Linux 下)
  4. 等待执行完毕,手机恢复成出厂镜像

root

root 工具及教程来自 @Chainfire ,在此由衷的感谢他。

  • 下载ZIP工具
  • 解压文件,并将手机进入 bootloader/fastboot 模式
  • 连接数据线,并运行 root-windows.bat (Windows 下)或者 chmod +x root-linux.sh 并运行 root-linux.sh (Linux下) Mac下同Linux

Recovery

第三方的 Recovery 有以下的功能:

  • Wipe your phone’s data (Factory reset) and cache
  • Make, restore and manage backups of your phone’s operating system and software
  • Mount, unmount and format your phone’s internal as well as external storage partitions
  • Install a custom ROM or application from a zip file to your phone
  • Wipe Dalvik cache and battery statistics
  • Make logs for error reporting and debugging

刷入 recovery

  • 官网 下载 Nexus 6 TWRP 的 recovery 文件
  • 进入 bootloader/fastboot 模式
  • 执行以下命令

    fastboot flash recovery recovery.img

    recovery.img 即下载的 Recovery 镜像。

  • 利用音量键选择 recovery ,点击电源键选择,可以进入 “Recovery Mode”.

安装完 recovery 之后就能够快速的备份系统,恢复出厂设置,恢复备份数据,刷入新ROM,刷入ZIP

kernel

一张图解释什么是 kernel

android kernel

Nexus 6 第三方的 kernel 有很多选择 比如 franco.kernel,这里推荐 ElementalX,有如下功能

  • Easy installation and setup with Aroma installer
  • overclock/underclock CPU
  • user voltage control
  • Advance color control
  • MultiROM support
  • optional USB fastcharge
  • optional sweep2wake and doubletap2wake
  • optional sweep2sleep
  • sound control
  • init.d support
  • NTFS r/w and exFAT support
  • option to disable fsync
  • adjustable vibration
  • does not force encryption

安装 ElementalX kernel

  • ElementalX 官网下载,并保存到手机
  • 进入 Recovery Mode
  • 刷入 ZIP ,选择下载的文件,安装

Nexus 6 破解电信3G/4G

6.0.1 (MMB29Q) 有效

下载文件,教程中需要用的软件及文件 https://yunpan.cn/cxCaHyqkKPwg9 提取码 db02

  • DFS
  • QPST

还有这里

  • moto x qc diag interface - 64bit.zip
  • carrier_policy.xml

具体步骤参考nexus6破解电信教程

简单来说破解4G步骤:

  • 用QPTS工具里面的EFS Explorer, 添加/policyman/carrier_policy.xml,nexus6 默认没有这个文件
  • 进入BP TOOLS模式,安装好后,必须确认好你的设备管理器 端口(COM和LPT)中BP驱动的端口号
  • 从开始菜单中,打开QPST configuration
  • 先点Ports标签,然后点Add New Prot 输入你的设备端口号
  • 点StartClient菜单中的EFS Explorer选项
  • 连接上手机后,在EFS 根目录创建policyman目录
  • 把carrier_policy.xml(见附件)拖进policyman目录中
  • 完成后重启手机

破解完成后请在手机拨号面板那输入 *#*#4636#*#* 看下首选网络是不是LTE/GSM/CDMA auto(prl)

参考


2016-03-01 Android , Nexus 6

Linux 常用命令合集

部分内容为 《Linux 命令速查手册》读书记录。

系统

uname -a               # 查看内核 / 操作系统 /CPU 信息
head -n 1 /etc/issue   # 查看操作系统版本
cat /proc/cpuinfo      # 查看 CPU 信息
hostname               # 查看计算机名
lspci -tv              # 列出所有 PCI 设备
lsusb -tv              # 列出所有 USB 设备
lsmod                  # 列出加载的内核模块
env                    # 查看环境变量

资源

监视系统资源,包括跟踪正在运行的程序 (ps,top)终止进程(kill),列出打开的文件(lsof),报告系统内存占用(free),磁盘空间占用(dfdu)等等。

ps aux                  # 查看系统正在运行的进程
ps -ef                  # 查看所有进程
ps f                    # 查看进程树
top                     # 实时显示进程状态
kill -9 PID             # 终止正在运行的进程 -9 强制中断, -15 正常中止
lsof                    # 列出打开的文件
free -m                 # 查看内存使用量和交换区使用量
df -h                   # 查看各分区使用情况
du -sh 《目录名》        # 查看指定目录的大小
grep MemTotal /proc/meminfo   # 查看内存总量
grep MemFree /proc/meminfo    # 查看空闲内存量
uptime                  # 查看系统运行时间、用户数、负载
cat /proc/loadavg       # 查看系统负载

磁盘和分区

mount | column -t      # 查看挂接的分区状态
fdisk -l               # 查看所有分区
swapon -s              # 查看所有交换分区
hdparm -i /dev/hda     # 查看磁盘参数(仅适用于 IDE 设备)
dmesg | grep IDE       # 查看启动时 IDE 设备检测状况

网络

这里列举了常用和网络相关的命令,包括查看本地 IP(ifconfig),判断网络连通性(ping,traceroute) 等等。其中 ifconfig, iwconfig ,route 等等命令都有双重用途,不仅能够查看网络连接属性,也能够进行配置。

ifconfig               # 查看所有网络接口的属性
ifup eth0              # 开启网络
ifdown eth0            # 关闭 eth0 网卡
iwconfig               # 查看无线接口属性
iptables -L            # 查看防火墙设置
ping                   # 网络连通性
route -n               # 查看路由表
netstat -lntp          # 查看所有监听端口
netstat -antp          # 查看所有已经建立的连接
netstat -s             # 查看网络统计信息
traceroute https://google.com  # 显示数据包从计算机路由到指定的主机经过的每一步
mtr                    # traceroute 更好的代替
host                   # 查看网站 DNS 结果
dhclient -r eth0       # 使用 DHCP 获得新网络地址

mtr 使用介绍

用户

w                      # 查看活动用户
id 《用户名》            # 查看指定用户信息
last                   # 查看用户登录日志
cut -d: -f1 /etc/passwd   # 查看系统所有用户
cut -d: -f1 /etc/group    # 查看系统所有组
crontab -l             # 查看当前用户的计划任务

服务

chkconfig --list       # 列出所有系统服务
chkconfig --list | grep on    # 列出所有启动的系统服务

2016-03-01 commands , linux , network , cpu , collection

每天学习一个命令:multitail 同时监控多个日志

MultiTail是一个开源的ncurses的实用工具,可用于在一个窗口或单一外壳,显示实时一样的尾巴命令,该命令拆分控制台为更多子窗口的日志文件的最后几行(很像显示多个日志文件到标准输出屏幕命令 )。 它还支持颜色突出显示,过滤,添加和删除窗口等。

他和tail的区别就是他会在控制台中打开多个窗口,这样可以同时监控多个日志。

安装

apt install multitail

如果要在 CentOS,基于 Red Hat 的发行版中使用,需要开启 EPEL repository,然后安装

yum install -y multitail

使用

监控两个日志文件,窗口上下

multitail /var/log/syslog /var/log/auth.log

如果要让窗口左右排布

multitail -s 2 /var/log/syslog /var/log/auth.log

同理,-s num 来表示后接多少个文件

进入 multitail 之后,有一些交互式命令

  • h 来打开帮助
  • 使用 b 来选择打开的文件,使用上下键选择文件,一旦选择文件 multitail 会显示文件最后 100 行,使用 jk 移动光标,或者 gg/G 来快速移动到文件顶部或者最后,q 退出
  • a 用来添加另外的监控日志文件

reference


2016-02-24 multitail , tail , linux , command , log

使用 certbot 自动生成 SSL 证书并自动续期

Let’s Encrypt 是一个免费 SSL 证书发行项目,自动化发行证书,证书有 90 天的有效期。于是有了另外一个项目可以自动安装,自动续期。

直接上网站

选择 WEB 服务器版本,系统版本,然后执行脚本即可。

执行完成之后执行 certbot run 跟着步骤就行了。

crontab -e 编辑文件

0 0 1 * * /usr/bin/certbot renew --force-renewal

定时每天检查,如果要过期则自动延期。


2016-02-23 certbot , ssl , https

Linux 启动项管理

Linux 启动项管理

Debian/Ubuntu/Linux Mint 系利用 update-rc.d 来管理 Linux 自启动服务。RedHat/Fedora/CentOS 下貌似有一个 chkconfig 来管理。

而我使用的 Linux Mint 自带的启动服务管理配置地址在 ~/.config/autostart 目录下。

Linux 中的服务通常利用 /etc/init.d/ 目录下的脚本进行启动,停止或者重新加载等操作。一般情况下如果安装完服务之后,该服务会自动启动。比如安装完 apache2 之后, apache 服务会在下次启动时自动启动。如果不需要 apache2 随机启动,可以你禁用自启动,然后在需要的时候手动的启动 apache 服务

# /etc/init.d/apache2 start

先看一下启动脚本的内容

# ls -l /etc/rc?.d/*apache2
lrwxrwxrwx 1 root root 17 Feb  5 21:47 /etc/rc0.d/K09apache2 -> ../init.d/apache2
lrwxrwxrwx 1 root root 17 Feb  5 21:47 /etc/rc1.d/K09apache2 -> ../init.d/apache2
lrwxrwxrwx 1 root root 17 Feb  5 21:47 /etc/rc2.d/K09apache2 -> ../init.d/apache2
lrwxrwxrwx 1 root root 17 Feb  5 21:47 /etc/rc3.d/K09apache2 -> ../init.d/apache2
lrwxrwxrwx 1 root root 17 Feb  5 21:47 /etc/rc4.d/K09apache2 -> ../init.d/apache2
lrwxrwxrwx 1 root root 17 Feb  5 21:47 /etc/rc5.d/K09apache2 -> ../init.d/apache2
lrwxrwxrwx 1 root root 17 Feb  5 21:47 /etc/rc6.d/S09apache2 -> ../init.d/apache2

运行级别(run level) 从 0,1到6,在每一个链接前有K和S区别,K 表示 Kill 停止一个服务,而 S 表示 Start 启动一个服务。

不同的运行级别定义如下:

# 0 - 停机
# 1 - 单用户模式
# 2 - 多用户,没有 NFS
# 3 - 完全多用户模式(标准的运行级)
# 4 – 系统保留的
# 5 - X11 (x window)
# 6 - 重新启动

Debian (Ubuntu/Linux Mint)

rcconf

Debian 系Linux下利用 rcconf 管理自启动脚本,rcconf的全称是 Debian Runlevel Configuration tool, 运行级别配置工具。作用和 update-rc.d 类似,但是更加直观简洁。他是一个 TUI(Text User Interface)。

rcconf

sudo apt-get install rcconf
sudo rcconf

运行之后就会出现非常直观的配置界面,用方向键,空格,Tab就能够实现配置。如果熟悉命令依然可以通过 rcconf 命令来进行快速配置。

update-rc.d

如果想要完全禁止 apache2 服务,需要删除 /etc/rcX.d/ 目录下所有的链接,而使用 update-rc.d

# update-rc.d -f apache2 remove

添加自启动服务

# update-rc.d apache2 defaults
Adding system startup for /etc/init.d/apache2 ...
/etc/rc0.d/K20apache2 -> ../init.d/apache2
/etc/rc1.d/K20apache2 -> ../init.d/apache2
/etc/rc6.d/K20apache2 -> ../init.d/apache2
/etc/rc2.d/S20apache2 -> ../init.d/apache2
/etc/rc3.d/S20apache2 -> ../init.d/apache2
/etc/rc4.d/S20apache2 -> ../init.d/apache2
/etc/rc5.d/S20apache2 -> ../init.d/apache2

从上面的log中可以看到,默认的优先级是20(K和S后面数字)和 91 有很大区别。 S20 链接早于 S91 启动, K91 在 K20 之前停止。

如果想要 apache2 服务以 91 优先级启动或者停止,可以使用

# update-rc.d apache2 defaults 91
Adding system startup for /etc/init.d/apache2 ...
/etc/rc0.d/K91apache2 -> ../init.d/apache2
/etc/rc1.d/K91apache2 -> ../init.d/apache2
/etc/rc6.d/K91apache2 -> ../init.d/apache2
/etc/rc2.d/S91apache2 -> ../init.d/apache2
/etc/rc3.d/S91apache2 -> ../init.d/apache2
/etc/rc4.d/S91apache2 -> ../init.d/apache2
/etc/rc5.d/S91apache2 -> ../init.d/apache2

如果需要为启动和停止设置不同的优先级,则可以

# update-rc.d apache2 defaults 20 80
Adding system startup for /etc/init.d/apache2 ...
/etc/rc0.d/K80apache2 -> ../init.d/apache2
/etc/rc1.d/K80apache2 -> ../init.d/apache2
/etc/rc6.d/K80apache2 -> ../init.d/apache2
/etc/rc2.d/S20apache2 -> ../init.d/apache2
/etc/rc3.d/S20apache2 -> ../init.d/apache2
/etc/rc4.d/S20apache2 -> ../init.d/apache2
/etc/rc5.d/S20apache2 -> ../init.d/apache2

这样启动为20,停止为80. 而如果需要自定义不同的运行级别,则可以

# update-rc.d apache2 start 20 2 3 4 5 . stop 80 0 1 6 .
Adding system startup for /etc/init.d/apache2 ...
/etc/rc0.d/K80apache2 -> ../init.d/apache2
/etc/rc1.d/K80apache2 -> ../init.d/apache2
/etc/rc6.d/K80apache2 -> ../init.d/apache2
/etc/rc2.d/S20apache2 -> ../init.d/apache2
/etc/rc3.d/S20apache2 -> ../init.d/apache2
/etc/rc4.d/S20apache2 -> ../init.d/apache2
/etc/rc5.d/S20apache2 -> ../init.d/apache2

如此之后,在运行级别 2, 3, 4, 5 为S20 ,运行级别 0, 1, 6 则是 K80.

同样可以更加复杂

# update-rc.d apache2 start 20 2 3 4 . start 30 5 . stop 80 0 1 6 .
Adding system startup for /etc/init.d/apache2 ...
/etc/rc0.d/K80apache2 -> ../init.d/apache2
/etc/rc1.d/K80apache2 -> ../init.d/apache2
/etc/rc6.d/K80apache2 -> ../init.d/apache2
/etc/rc2.d/S20apache2 -> ../init.d/apache2
/etc/rc3.d/S20apache2 -> ../init.d/apache2
/etc/rc4.d/S20apache2 -> ../init.d/apache2
/etc/rc5.d/S30apache2 -> ../init.d/apache2

RedHat/Fedora/CentOS

chkconfig

sudo chkconfig --add apache2

or

sudo chkconfig -- level 35 apache2 on

关于 chkconfig 更多的用法可以参考这里

reference


2016-02-09 linux , 学习笔记

Genymotion 安装

在Linux下安装 Genymotion Android 模拟器。最近拾起 Android Development,Android 模拟器必不可少,用来用去 Genymotion 模拟器算是速度和效率最棒的模拟器了。

事前准备

Genymotion 依赖 VirtualBox 运行,在安装之前确保已经安装 VirtualBox. 在Linux Mint下直接去 Software Manager 搜索 VirtualBox 然后点击安装即可。

Genymotion 安装需要一个 Genymotion 的个人账号,Genymotion 高级功能需要付费,所以去官网注册一个个人账号使用。 官网地址:https://www.genymotion.com

下载安装包,在注册账号登陆之后去首页按照自己的系统选择 32bit 或者 64bit 的安装包下载。目前最新的版本为 2.6.0.

安装

假设安装包下载到 ~/Downloads 目录下,在终端:

# cd ~/Downloads/
# Move the downloaded file to ~/Android/ directory #
mv genymotion-2.6.0_x64.bin ~/Android/

# Set executable permission
chmod +x genymotion-2.6.0_x64.bin

# Install genymotion by running the file
./genymotion-2.6.0_x64.bin

# Navigate into genymotion directory
cd genymotion

# launch the genymotion #
./genymotion

运行 genymotion 之后,添加设备,此时需要登陆账号,有的时候会遇到 “unknown generic error” 错误,在我的观察下可能就是因为 genymotion 服务器挂了,等些时候再尝试即可。或者有的时候是因为代理的关系。

unknown generic error

下载对应的镜像,然后就能够运行模拟器了。

为了方便使用可以将 Genymotion 的地址加入到 PATH 中,这样就能快速启动 Genymotion. 类似:

$ PATH=$PATH:/home/einverne/Android/genymotion/

使用

在使用 Genymotion 的时候,有时会遇到 ”INSTALL_FAILED_NO_MATCHING_ABIS“ 错误。一些时候是因为 APP 和模拟器CPU架构的问题,但是在 Genymotion 这里需要额外安装一个文件。点击这里 去xda 下载 Genymotion-ARM-Translation_v1.1.zip 这个文件。并拖到模拟器中。这样就不会出现问题了。如果需要在模拟器中安装 GApps ,可以在上面的链接中找到对应的方法。

如果使用过程中出现 “An error occured while deploying the file. INSTALL_FAILED_CPU_ABI_INCOMPATIBLE” 这样的错误,利用上面的方法也能解决。造成这个错误的原因是因为 Genymotion 是一个基于 x86 的虚拟环境,不是一个 ARM 的模拟器。而 Genymotion 在更新过程中移除了 ARM Translation 和 Google Play Apps , 这样对开发者和使用者造成了一定的困扰,不过还好依然可以通过其他方法解决。

reference


2016-02-08 Android , AndroidDev , Genymotion

django web framework 学习笔记

这两天大概看了一下Python的web框架—-Django,顺带复习一下Python。从刚开始的一无所知,到现在对Django中MVC的一些了解,感觉收获颇丰,还顺带回想起来以前学习过程中的一些MVC的知识,虽然Django不是完全按照MVC的命名模式 Model,View,Controller,但是它依然遵循类似的开发模式,Django自己说自己是 MTV 模式, Model,Template,View。

在看 Django 之前也了解了一些 Python 的Web框架,在之前的写字应用中用 webpy 作了一个简单的接口,webpy 实现很简单,用它当然也能做一些大项目,但是可能需要自己Custom的东西比较多。而Django可以快速上手。

Installation

安装非常简单,先安装 virtualenv

$ pip install virtualenv
$ cd my_project_folder
$ virtualenv .			# create virtual env in current folder
$ source bin/activate

再安装 Django , 创建工程,然后就可以开工了。

$ pip install django  	# install latest version
# pip install django==1.9 或者指定某一版本
# pip install django --upgrade
$ django-admin startproject projectname

几个很常用的命令,在 manage.py 目录下:

$ python manage.py help
$ python manage.py runserver [port]
$ python manage.py makemigrations # 每一次修改 model 之后需要运行,之后需要运行 migrate
$ python manage.py migrate   # 已经代替了 python manage.py syncdb 数据库相关,创建表
$ python manage.py createsuperuser
$ python manage.py startapp appname

几个文件

几个文件解释:

  • models.py 和数据库表相关

    model 中需要用到的 Field ,关键字:[Model field reference]

  • views.py 显示相关

    处理HttpRequest请求,通过模板生成HTML网页返回

  • urls.py 匹配URL模式

    通过正则匹配请求URL,将对应URL导向相应的view。Django 1.9 中可以引用三种对应的URL匹配模式,Function views,Class-based viewsIncluding another URLconf 方式来定义URL。

  • settings.py 项目设置

    项目地址,安装应用,数据库,静态文件地址,等等都在此文件中配置。

学习方式

我觉得最好的教程就是官方的Getting started with Django,但是唯一的坏处就是不够视频直观,这个时候上 Google 搜Django tutorial 能够找到很多视频教程,先行入门之后,再去回头看官方的教程或者文档,会很轻松的加快学习进度。

个人觉得几个很重要的文档,在新建 model 的时候, Django 自带了一些 Field, 这些变量的定义直接影响到数据库中保存的数据,在我刚开始学习的时候经常查看Model field reference. 在定义完 model 之后需要执行 python manage.py makemigrationspython manage.py migrate 来同步自定义的 model 和 数据库中内容。

在 view 中需要 render 模板的时候,常用的方式就是在 工程下app 的同级目录增加 templates 目录,将html模板放到该目录下。并且需要在 settings.py 文件中 TEMPLATES 设置中增加 'DIRS': [os.path.join(BASE_DIR, "templates")],. 可以参考 官方文档 .

而接下来是网页的表单,可以自定义表单,也可以通过 Model 直接生成对应的表单,官方都有详细的介绍。

至此生成一个自己的简单页面应该没有任何问题了。下面就是学习一些深入的内容,在之前的视频中有用到 django-registration-redux 一个第三方的注册登陆的实现。能够快速实现一个网站的注册邮箱验证以及登录验证。然后因为 Django 生成的网页表单太丑,所以还用了 django-crispy-forms 这样一个第三方生成表单的应用。快速生成带CSS样式的表单。具体的使用看文档都能够快速使用。

到此,可以看一些教程实现一些自定义的表单 validation,可以看一下第三方应用的实现来充实一下自己的 django 知识,甚至可以实现一个具体的应用来锻炼一下。

参考

  • 官方参考 其中有很详细的文档、教程、已经一些基本的网页应用实现,缓存,分页,RSS,消息,Sessions 等等
  • YouTube 教程 一步一步教你用 Django 实现一个简单的个人博客。

2016-01-31 Django , Python , 学习笔记 , Web

FFmpeg 项目中便携式媒体播放器 ffplay 使用

FFplay 是一个使用 FFmpeg 和 SDL 库制作的简易轻便的媒体播放器,他可以用来测试 FFmpeg APIs。

使用方式很简答

ffplay [options] input_file

简单使用

播放 demo.mp4 ,播放完成后自动退出

ffplay -autoexit demo.mp4

以特定大小播放 demo.mp4

ffplay -x 640 -y 480 demo.mp4

从指定时间开始播放

ffplay -ss 10 demo.mp4

指定播放时长

ffplay -t 10 demo.mp4

关闭音频

ffplay -an demo.mp4

关闭视频

ffplay -vn demo.mp4

将窗口标题设置为 “myplayer”,循环播放 2 次

ffplay -window_title myplayer -loop 2 demo.mp4

设置显示模式

ffplay -showmode rdft demo.mp4

参数 -showmode 后面接的mode值可以为

  • 0, video 视频,默认
  • 1, waves 音频波形
  • 2, rdft 音频频谱

默认值 video, 在播放时,可以通过 w 快捷键在几种模式中切换

播放流媒体

ffplay 相比于本地播放器,他也能够播放网络视频,如果能够拿到视频的网络播放地址,不管是直链,还是 m3u8,也能够直接加在 ffplay 后面播放,顺便也可以直接查看视频流的信息。

本地做一个测试,开启一个终端播放 ffplay

ffplay udp://127.0.0.1:8080

然后使用 ffmpeg 生成流媒体

ffmpeg -r 25 -i demo.mp4 -f mpegts udp://127.0.0.1:8080

这里的参数

  • -r 25 表示每秒25帧
  • -f 输出视频流

快捷键

q, ESC            退出
f                 全屏
p, SPC            暂停
w                 切换显示模式(视频/音频波形/音频频带)
s                 步进到下一帧
left/right        快退/快进 10 秒
down/up           快退/快进 1 分钟
page down/page up 跳转到前一章/下一章(如果没有章节,快退/快进 10 分钟)
mouse click       跳转到鼠标点击的位置(根据鼠标在显示窗口点击的位置计算百分比)

reference


2016-01-20 ffmpeg , ffplay , sdl , media , linux

电子书

Google+

最近文章

  • Go 语言学习笔记 3:基础类型 和大多数强类型语言一样,Go 也有自己基本的类型系统。Go 语言的类型大致可以分为四大类:
  • 服务器监控整理 之前也有分享过两个很不错的服务器监控程序 nodequery 和 netdata。之后又陆陆续续发现了其他一些不错的监控程序,所以就顺手整理一下。
  • 由 WebM 格式学习常见的容器和编码格式 因为使用 YouTube 所以接触到了 WebM 格式,这个格式 Google 开源的一个媒体容器格式,常见的文件后缀名是 .webm,他设计的目标是为了给 HTML5 提供视频和音频。Google 发起的 WebM 项目还有一个姊妹项目 WebP 是提供图像编码的。BSD 协议开源。1 https://en.wikipedia.org/wiki/WebM ↩
  • 读万字访谈后感:软硬件公司的差别 9 月份一次出门在路上看了这篇万字采访,这篇文章主要以 Osterloh (Google 硬件部门 Leader)为脉络梳理了 Google 这几年在 硬件方面的尝试。文章中的观点并不是那么直白,但是看完却有一股气憋在心中不得不抒。作为用 Google 产品这么多年的忠实用户,Galaxy Nexus,Nexus 6 也是陪我度过了很多年,而 Google Glass 当年如何的红火,但是不得不说在 Google 在硬件确实不如其软件行业的发展,现在音箱被 Amazon Echo 压着打,手机不管是 Nexus 还是 Pixel 丝毫无法动摇 iPhone 的地位,更不用说失败的 Nexus Q,Android TV,等等。
  • Jupyter 简单使用 Jupyter 是一个为了支持多语言交互式编程的项目, Jupyter Notebook 是一个开源的网络程序,允许用户创建和分享包含代码,视图,方程式,文本的文档。