Monthly Archives: 1月 2017

1月 31st, 2017

 我在phpclasses.org上面偶然发现一个很有用的,由Bakr Alsharif开发的可以帮助开发者基于皮肤像素点来检测图片裸照的类文件.

      它会分析在一张图片的不同部分使用的颜色,并决定其是否匹配人类皮肤颜色的色调.

      作为分析的结果,他会返回一个反映图片包含裸露的可能性的分值.

      此外,他还可以输出被分析的图片,上面对使用给定颜色的肤色的像素进行了标记.

      当前它可以对PNG,GIF和JPEG图片进行分析.

      PHP

      下面展示了如何使用这个PHP类.

      让我们先从包含裸体过滤器,nf.php文件开始.

include ('nf.php');

      接下来,创建一个新的名叫ImageFilter的类,然后把它放到一个叫做$filter的变量中.

$filter new ImageFilter;

      获取图片的分值并将其放到一个$score变量中.

$score $filter -> GetScore($_FILES['img']['tmp_name']);

      如果图片分值大于或等于60%,那就展示一条(告警)消息.

if($score >= 60){
/*Message*/
}

      下面是所有的PHP代码:

<?php
/*Include the Nudity Filter file*/
include ('nf.php');
/*Create a new class called $filter*/
$filter new ImageFilter;
/*Get the score of the image*/
$score $filter -> GetScore($_FILES['img']['tmp_name']);
/*If the $score variable is set*/
if (isset($score)) {
    /*If the image contains nudity, display image score and message. Score value if more than 60%, it is considered an adult image.*/
    if ($score >= 60) {
        echo "Image scored " $score "%, It seems that you have uploaded a nude picture.";
    /*If the image doesn't contain nudity*/
    else if ($score < 0) {
        echo "Congratulations, you have uploaded an non-nude image.";
    }
}
?>

      标记语言

      我们可以使用一个基础的HTML表单上传图片.

<form method="post" enctype="multipart/form-data" action="<?php echo $SERVER['PHP_SELF'];?> ">
Upload image: 
<input type="file" name="img" id="img" />
<input type="submit" value="Sumit Image" />
</form>

      总结

      请记得,PHP不能够检测所有的裸体图片,所以不完全可信.我希望你觉得这还有点用处.

TAGS: ,
1月 31st, 2017

强制下载application/force-download,将发送HTTP 标头您的浏览器并告诉它下载,而不是在浏览器中运行的文件
$content_url//下载文件地址,可以是网络地址,也可以是本地物理路径或者虚拟路径
ob_end_clean(); //函数ob_end_clean 会清除缓冲区的内容,并将缓冲区关闭,但不会输出内容。
header(“Content-Type: application/force-download;”); //告诉浏览器强制下载
header(“Content-Transfer-Encoding: binary”);
header(“Content-Length: $taille”);
header(“Content-Disposition: attachment; filename=\”下载后的名字以及后缀\”);
header(“Expires: 0”);
header(“Cache-control: private”);
header(“Pragma: no-cache”); //不缓存页面
readfile($content_url);

TAGS:
1月 31st, 2017

一、防火墙设置

CentOS 7.x默认使用的是firewall作为防火墙,这里改为iptables防火墙。

1、关闭firewall:

systemctl stop firewalld.service #停止firewall

systemctl disable firewalld.service #禁止firewall开机启动

2、安装iptables防火墙

yum install iptables-services #安装

vi /etc/sysconfig/iptables #编辑防火墙配置文件

# sample configuration for iptables service

# you can edit this manually or use system-config-firewall

# please do not ask us to add additional ports/services to this default configuration

*filter

:INPUT ACCEPT [0:0]

:FORWARD ACCEPT [0:0]

:OUTPUT ACCEPT [0:0]

-A INPUT -m state –state RELATED,ESTABLISHED -j ACCEPT

-A INPUT -p icmp -j ACCEPT

-A INPUT -i lo -j ACCEPT

-A INPUT -p tcp -m state –state NEW -m tcp –dport 22 -j ACCEPT

-A INPUT -p tcp -m state –state NEW -m tcp –dport 11211 -j ACCEPT

-A INPUT -j REJECT –reject-with icmp-host-prohibited

-A FORWARD -j REJECT –reject-with icmp-host-prohibited

COMMIT

:wq! #保存退出

systemctl restart iptables.service #最后重启防火墙使配置生效

systemctl enable iptables.service #设置防火墙开机启动

/usr/libexec/iptables/iptables.init restart #重启防火墙

二、关闭SELINUX

vi /etc/selinux/config

#SELINUX=enforcing #注释掉

#SELINUXTYPE=targeted #注释掉

SELINUX=disabled #增加

:wq! #保存退出

setenforce 0 #使配置立即生效

三 、系统约定

软件源代码包存放位置:/usr/local/src

源码包编译安装位置:/usr/local/软件名字

四、下载软件包

1、下载libevent

http://ftp.lfs-matrix.net/pub/blfs/conglomeration/libevent/libevent-2.0.22-stable.tar.gz

2、下载memcached

http://memcached.org/files/memcached-1.4.34.tar.gz

五、安装编译工具包

yum install -y apr* autoconf automake bison bzip2 bzip2* cloog-ppl compat* cpp curl curl-devel fontconfig fontconfig-devel freetype freetype* freetype-devel gcc gcc-c++ gtk+-devel gd gettext gettext-devel glibc kernel kernel-headers keyutils keyutils-libs-devel krb5-devel libcom_err-devel libpng libpng-devel libjpeg* libsepol-devel libselinux-devel libstdc++-devel libtool* libgomp libxml2 libxml2-devel libXpm* libxml* libtiff libtiff* make mpfr ncurses* ntp openssl openssl-devel patch pcre-devel perl php-common php-gd policycoreutils telnet t1lib t1lib* nasm nasm* wget zlib-devel

六、安装配置memcached

1、安装libevent

cd /usr/local/src

tar zxvf libevent-2.0.22-stable.tar.gz

cd libevent-2.0.22-stable

./configure –prefix=/usr/local/libevent

make

make install

2、安装memcached

cd /usr/local/src

tar zxvf memcached-1.4.34.tar.gz

cd memcached-1.4.34

./configure –enable-sasl –prefix=/usr/local/memcached -with-libevent=/usr/local/libevent

make

make install

3、测试Memcached

groupadd memcached #创建组

useradd -g memcached memcached -s /bin/false #创建账号

ln -s /usr/local/memcached/bin/memcached   /usr/local/bin/memcached  #添加软连接

启动Memcache的服务器端的命令为:

/usr/local/memcached/bin/memcached -d -m 4096 -u root -l 192.168.4.6 -p 11211 -c 1024 -P /usr/local/memcached/memcached.pid

或者

/usr/local/memcached/bin/memcached -d -m 4096 -u memcached -l 192.168.4.6 -p 11211 -c 1024

参数说明:

-d选项是启动一个守护进程,

-m是分配给Memcache使用的内存数量,单位是MB,这里是4096MB

-u是运行Memcache的用户,比如root或者memcached

-l是监听的服务器IP地址,这里指定服务器的IP地址192.168.4.6,不设置默认监听服务器所有IP地址

-p是设置Memcache监听的端口,默认为11211

-c选项是最大运行的并发连接数,默认是1024

-P是设置保存Memcache的pid文件,/usr/local/memcached/memcached.pid

开机自启动,在/etc/rc.d/rc.local中加入一行

/usr/local/memcached/bin/memcached -d -m 4096 -u root -l 192.168.4.6 -p 11211 -c 1024 -P /usr/local/memcached/memcached.pid

也可以使用下面的命令:

/usr/local/memcached/bin/memcached -d -m 4096 -p 11211 -u memcached

ip不指定时,默认监听本地所有ip地址,用户最好选择是非root用户,例如memcached

关闭Memcached服务

cat /usr/local/memcached/memcached.pid  #查看进程

kill 22856 #结束进程

或者

killall memcached  #结束服务

系统运维 www.osyunwei.com 温馨提醒:qihang01原创内容©版权所有,转载请注明出处及原文链接

4、设置Memcached开机启动

vi /etc/rc.d/init.d/memcached

#!/bin/sh

#

# memcached: MemCached Daemon

#

# chkconfig: – 90 25

# description: MemCached Daemon

#

# Source function library.

. /etc/rc.d/init.d/functions

. /etc/sysconfig/network

MEMCACHED=”/usr/local/memcached/bin/memcached”

start()

{

echo -n $”Starting memcached: ”

daemon $MEMCACHED -u memcached -d -m 4096 -p 11211 -c 1024

echo

}

stop()

{

echo -n $”Shutting down memcached: ”

killproc memcached

echo

}

[ -f $MEMCACHED ] || exit 0

# See how we were called.

case “$1″ in

start)

start

;;

stop)

stop

;;

restart|reload)

stop

start

;;

condrestart)

stop

start

;;

*)

echo $”Usage: $0 {start|stop|restart|reload|condrestart}”

exit 1

esac

exit 0

:wq! #保存退出

chmod 775 /etc/rc.d/init.d/memcached #赋予文件执行权限

chkconfig memcached on #设置开机启动

/etc/rc.d/init.d/memcached start #启动

至此,Linux下Memcached服务器部署完成。

1月 31st, 2017

我们将使用 find 命令,它用于搜索目录层次结构中的文件,以及 wc 命令,它会打印每个文件或来自标准输入的换行符、单词和字节计数。

以下是我们在 find 命令中使用的选项,如下所示:

  1. -type – 指定要搜索的文件类型,在上面的情况下,f 表示查找所有常规文件。
  2. -print – 打印文件绝对路径。

以下是我们 wc 命令中使用的选项,如下所示:

  1. -l – 此选项打印换行符的总数,也即由 find 命令输出的绝对文件路径总数。

find 命令的一般语法。

  1. # find . -type f -print | wc -l
  2. $ sudo find . -type f -print | wc -l

重要:使用 sudo 命令来读取指定目录中的所有文件,包括具有超级用户权限的子目录中的文件,以避免 “Permission denied” 错误,如下截图所示:

Linux 中的文件数量

Linux 中的文件数量

你可以看到,在上面的第一个命令中,find 命令没有读取当前工作目录中的所有文件。

下面是更多的示例,分别显示 /var/log/etc 目录中的常规文件总数:

  1. $ sudo find /var/log/ -type f -print | wc -l
  2. $ sudo find /etc/ -type f -print | wc -l
TAGS: ,
1月 27th, 2017

目录

1、树状目录结构图

2、/目录

3、/etc/目录

4、/usr/目录

5、/var/目录

6、/proc/目录

7、/dev/目录

该文章主要来自于网络进行整理。

目录结构参考地址:

http://www.hudong.com/wiki/linux%E7%9B%AE%E5%BD%95%E7%BB%93%E6%9E%84

http://linux.ccidnet.com/art/3067/20070315/1037337_1.html

http://os.51cto.com/art/200802/65783.htm

http://www.iteye.com/topic/1125162

下面红色字体为比较重要的目录

1、树状目录结构图

2、/目录

目录 描述
/ 第一层次结构的根、整个文件系统层次结构的根目录
/bin/ 需要在单用户模式可用的必要命令(可执行文件);面向所有用户,例如:catlscp,和/usr/bin类似。
/boot/ 引导程序文件,例如:kernelinitrd;时常是一个单独的分区[6]
/dev/ 必要设备, 例如:, /dev/null.
/etc/ 特定主机,系统范围内的配置文件

关于这个名称目前有争议。在贝尔实验室关于UNIX实现文档的早期版本中,/etc 被称为/etcetra 目录[7]这是由于过去此目录中存放所有不属于别处的所有东西(然而,FHS限制/etc存放静态配置文件,不能包含二进制文件)。[8]自从早期文档出版以来,目录名称已被以各种方式重新称呼。最近的解释包括反向缩略语如:”可编辑的文本配置”(英文 “Editable Text Configuration”)或”扩展工具箱”(英文 “Extended Tool Chest”)。[9]

/etc/opt/ /opt/的配置文件
/etc/X11/ X_Window系统(版本11)的配置文件
/etc/sgml/ SGML的配置文件
/etc/xml/ XML的配置文件
/home/ 用户的家目录,包含保存的文件、个人设置等,一般为单独的分区。
/lib/ /bin/ and /sbin/中二进制文件必要的文件。
/media/ 可移除媒体(如CD-ROM)的挂载点 (在FHS-2.3中出现)。
/lost+found 在ext3文件系统中,当系统意外崩溃或机器意外关机,会产生一些文件碎片在这里。当系统在开机启动的过程中fsck工具会检查这里,并修复已经损坏的文件系统。当系统发生问题。可能会有文件被移动到这个目录中,可能需要用手工的方式来修复,或移到文件到原来的位置上。
/mnt/ 临时挂载的文件系统。比如cdrom,u盘等,直接插入光驱无法使用,要先挂载后使用
/opt/ 可选应用软件
/proc/ 虚拟文件系统,将内核进程状态归档为文本文件(系统信息都存放这目录下)。例如:uptime、 network。在Linux中,对应Procfs格式挂载。该目录下文件只能看不能改(包括root)
/root/ 超级用户家目录
/sbin/ 必要的系统二进制文件,例如: init、 ip、 mount。sbin目录下的命令,普通用户都执行不了。
/srv/ 站点的具体数据,由系统提供。
/tmp/ 临时文件(参见 /var/tmp),在系统重启时目录中文件不会被保留。
/usr/ 默认软件都会存于该目录下。用于存储只读用户数据的第二层次;包含绝大多数的()用户工具和应用程序。
/var/ 变量文件——在正常运行的系统中其内容不断变化的文件,如日志,脱机文件和临时电子邮件文件。有时是一个单独的分区。如果不单独分区,有可能会把整个分区充满。如果单独分区,给大给小都不合适。

3/etc/目录

特定主机系统范围内的配置文件

目录 描述
/etc/rc /etc/rc.d

/etc/rc*.d

启动、或改变运行级时运行的scripts或scripts的目录.
/etc/hosts 本地域名解析文件
/etc/sysconfig/network IP、掩码、网关、主机名配置
/etc/resolv.conf DNS服务器配置
/etc/fstab 开机自动挂载系统,所有分区开机都会自动挂载
/etc/inittab 设定系统启动时Init进程将把系统设置成什么样的runlevel及加载相关的启动文件配置
/etc/exports 设置NFS系统用的配置文件路径
/etc/init.d 这个目录来存放系统启动脚本
/etc/profile, /etc/csh.login,  /etc/csh.cshrc 全局系统环境配置变量
/etc/issue 认证前的输出信息,默认输出版本内核信息
/etc/motd 设置认证后的输出信息,
/etc/mtab 当前安装的文件系统列表.由scripts初始化,并由mount 命令自动更新.需要一个当前安装的文件系统的列表时使用,例如df 命令
/etc/group 类似/etc/passwd ,但说明的不是用户而是组.
/etc/passwd 用户数据库,其中的域给出了用户名、真实姓名、家目录、加密的口令和用户的其他信息.
/etc/shadow 在安装了影子口令软件的系统上的影子口令文件.影子口令文件将/etc/passwd 文件中的加密口令移动到/etc/shadow 中,而后者只对root可读.这使破译口令更困难.
/etc/sudoers 可以sudo命令的配置文件
/etc/syslog.conf 系统日志参数配置
/etc/login.defs 设置用户帐号限制的文件
/etc/securetty 确认安全终端,即哪个终端允许root登录.一般只列出虚拟控制台,这样就不可能(至少很困难)通过modem或网络闯入系统并得到超级用户特权.
/etc/printcap 类似/etc/termcap ,但针对打印机.语法不同.
/etc/shells 列出可信任的shell.chsh 命令允许用户在本文件指定范围内改变登录shell.提供一台机器FTP服务的服务进程ftpd 检查用户shell是否列在 /etc/shells 文件中,如果不是将不允许该用户登录.
/etc/xinetd.d 如果服务器是通过xinetd模式运行的,它的脚本要放在这个目录下。有些系统没有这个目录,比如Slackware,有些老的版本也没有。在Redhat Fedora中比较新的版本中存在。
/etc/opt/ /opt/的配置文件
/etc/X11/ X_Window系统(版本11)的配置文件
/etc/sgml/ SGML的配置文件
/etc/xml/ XML的配置文件
/etc/skel/ 默认创建用户时,把该目录拷贝到家目录下

4/usr/目录

默认软件都会存于该目录下。用于存储只读用户数据的第二层次;包含绝大多数的用户工具和应用程序。

目录 描述
/usr/X11R6 存放X-Windows的目录;
/usr/games 存放着XteamLinux自带的小游戏;
/usr/doc Linux技术文档;
/usr/include 用来存放Linux下开发和编译应用程序所需要的头文件;
/usr/lib 存放一些常用的动态链接共享库和静态档案库;
/usr/man 帮助文档所在的目录;
/usr/src Linux开放的源代码,就存在这个目录,爱好者们别放过哦;
/usr/bin/ 非必要可执行文件 (在单用户模式中不需要);面向所有用户。
/usr/lib/ /usr/bin/和/usr/sbin/中二进制文件的
/usr/sbin/ 非必要的系统二进制文件,例如:大量网络服务守护进程
/usr/share/ 体系结构无关(共享)数据。
/usr/src/ 源代码,例如:内核源代码及其头文件。
/usr/X11R6/ X Window系统版本 11, Release 6.
/usr/local/ 本地数据的第三层次,具体到本台主机。通常而言有进一步的子目录,例如:bin/、lib/、share/.这是提供给一般用户的/usr目录,在这里安装一般的应用软件;

5/var/目录

/var 包括系统一般运行时要改变的数据.每个系统是特定的,即不通过网络与其他计算机共享.

目录 描述
/var/log/message 日志信息,按周自动轮询
/var/spool/cron/root 定时器配置文件目录,默认按用户命名
/var/log/secure 记录登陆系统存取信息的文件,不管认证成功还是认证失败都会记录
/var/log/wtmp 记录登陆者信息的文件,last,who,w命令信息来源于此
/var/spool/clientmqueue/ 当邮件服务未开启时,所有应发给系统管理员的邮件都将堆放在此
/var/spool/mail/ 邮件目录
/var/tmp 比/tmp 允许的大或需要存在较长时间的临时文件. (虽然系统管理员可能不允许/var/tmp 有很旧的文件.)
/var/lib 系统正常运行时要改变的文件.
/var/local /usr/local 中安装的程序的可变数据(即系统管理员安装的程序).注意,如果必要,即使本地安装的程序也会使用其他/var 目录,例如/var/lock .
/var/lock 锁定文件.许多程序遵循在/var/lock 中产生一个锁定文件的约定,以支持他们正在使用某个特定的设备或文件.其他程序注意到这个锁定文件,将不试图使用这个设备或文件.
/var/log/ 各种程序的Log文件,特别是login   (/var/log/wtmp log所有到系统的登录和注销) 和syslog (/var/log/messages 里存储所有核心和系统程序信息. /var/log 里的文件经常不确定地增长,应该定期清除.
/var/run 保存到下次引导前有效的关于系统的信息文件.例如, /var/run/utmp 包含当前登录的用户的信息.
/var/cache/ 应用程序缓存数据。这些数据是在本地生成的一个耗时的I/O或计算结果。应用程序必须能够再生或恢复数据。缓存的文件可以被删除而不导致数据丢失。

6/proc/目录

虚拟文件系统,将内核进程状态归档为文本文件(系统信息都存放这目录下)。

例如:uptime、 network。在Linux中,对应Procfs格式挂载。该目录下文件只能看不能改(包括root)

目录 描述
/proc/meminfo 查看内存信息
/proc/loadavg 还记得 top 以及 uptime 吧?没错!上头的三个平均数值就是记录在此!
/proc/uptime 就是用 uptime 的时候,会出现的资讯啦!
/proc/cpuinfo 关于处理器的信息,如类型、厂家、型号和性能等。
/proc/cmdline 加载 kernel 时所下达的相关参数!查阅此文件,可了解系统是如何启动的!
/proc/filesystems 目前系统已经加载的文件系统罗!
/proc/interrupts 目前系统上面的 IRQ 分配状态。
/proc/ioports 目前系统上面各个装置所配置的 I/O 位址。
/proc/kcore 这个就是内存的大小啦!好大对吧!但是不要读他啦!
/proc/modules 目前我们的 Linux 已经加载的模块列表,也可以想成是驱动程序啦!
/proc/mounts 系统已经挂载的数据,就是用 mount 这个命令呼叫出来的数据啦!
/proc/swaps 到底系统挂加载的内存在哪里?呵呵!使用掉的 partition 就记录在此啦!
/proc/partitions 使用 fdisk -l 会出现目前所有的 partition 吧?在这个文件当中也有纪录喔!
/proc/pci 在 PCI 汇流排上面,每个装置的详细情况!可用 lspci 来查阅!
/proc/version 核心的版本,就是用 uname -a 显示的内容啦!
/proc/bus/* 一些汇流排的装置,还有 U盘的装置也记录在此喔!

7/dev/目录

设备文件分为两种:块设备文件(b)和字符设备文件(c)
设备文件一般存放在/dev目录下,

对常见设备文件作如下说明:

目录 描述
/dev/hd[a-t] IDE设备
/dev/sd[a-z] SCSI设备
/dev/fd[0-7] 标准软驱
/dev/md[0-31] 软raid设备
/dev/loop[0-7] 本地回环设备
/dev/ram[0-15] 内存
/dev/null 无限数据接收设备,相当于黑洞
/dev/zero 无限零资源
/dev/tty[0-63] 虚拟终端
/dev/ttyS[0-3] 串口
/dev/lp[0-3] 并口
/dev/console 控制台
/dev/fb[0-31] framebuffer
/dev/cdrom => /dev/hdc
/dev/modem => /dev/ttyS[0-9]
/dev/pilot => /dev/ttyS[0-9]
/dev/random 随机数设备
/dev/urandom 随机数设备
TAGS: ,
1月 27th, 2017

任何没有下载管理器的 Linux 操作系统是不完整的。多年来,基于 Linux 的发行版使用 wget 作为默认下载管理器。它是一个很棒的小程序,可以在命令行下工作,如果你需要安装东西、下载东西、运行 shell 脚本等,某种程度上都可以在 wget 中完成任务。在过去的很多年里,我们发现 wget 缺乏一些高级的功能,而它的替代品 aria2 ,由于满足了高级 Linux 用户的渴望而受到了许多用户的关注。我们将在本文中回顾 aria2 的安装过程以及 wget 和 aria2 之间的区别,因此你可以决定哪个下载管理器最符合你的需要。

安装 aria2

在 Ubuntu/Debian 中安装 aria2:

只要在 Ubuntu 中运行下面的命令安装:

  1. sudo apt-get install aria2

aria2

aria2

在 Fedora/RHEL/Centos 中安装 aria2:

运行下面的命令在 Fedora/RHEL 和基于 Centos 的系统中安装:

  1. sudo yum install aria2

在 Arch Linux 中安装 aria2:

运行下面的命令在基于 Arch Linux 的系统中安装。

  1. sudo pacman -Sy aria2

aria2 的重要功能

让我们来讨论 aria2 中使它如此受欢迎的重要功能:

  • 通过使用多个连接下载文件,最大限度地利用可用带宽。
  • 同时下载多个文件和同时下载的能力。
  • torrent 客户端提供的所有功能都可以在这个小程序中找到。
  • 它提供 meta 链接下载。
  • 支持使用 JSON-RPC 和 XML-RPC 协议的远程过程调用。
  • 无需等待当前下载完成,轻松批量下载文件。

aria2 的一些副作用:

aria2 的多线程机制可能会使目标服务器过载。相比下来 wget 就轻量级多了,wget 比 aria2 消耗资源少 20%。aria2 尚未经受 wget 那样巨大的使用规模的测试,因此可能完全准备好成为默认下载管理器。

wget 的重要特性

  • 当然它是最广泛使用和测试的下载管理器。
  • 它是一个简单的程序,具有较少的功能,但稳定工作了几十年。
  • 默认所有 Linux 发行版上都有,不需要繁重的安装。
  • 与 aria2 相比更轻量级。

总结

虽然 wget 没有丰富的功能,但仍然工作得相当不错,然而,高级用户肯定会喜欢 aria2,因为它满足更快和并发下载的需要。aria2 可能需要很长时间来取代 wget 成为默认下载管理器,而目前 wget 用在几乎所有 linux 发行版的安装程序脚本中。

TAGS: ,
1月 27th, 2017

Vim 编辑器是一个基于命令行的工具,是传奇编辑器 vi 的增强版。尽管图形界面的富文本编辑有很多,但是熟悉 Vim 对于每一位 Linux 的使用者都能有所帮助——无论你是经验丰富的系统管理员,还是刚上手树莓派的新手用户。

这个轻量级的编辑器是个非常强大的工具。在有经验的使用者手中,它能完成不可思议的任务。除了常规的文本编辑功能以外,它还支持一些进阶特性。例如,基于正则表达式的搜索和替换、编码转换,以及语法高亮、代码折叠等的编程特性。

使用 Vim 时有一个非常重要的一点需要注意,那就是按键的功能取决于编辑器当前的“模式”。例如,在“普通模式”输入字母j时,光标会向下移动一行。而当你在“插入模式”下输入字符,则只是正常的文字录入。

下面就是速查表,以便于你充分利用 Vim。

基本操作

快捷键 功能
Esc 从当前模式转换到“普通模式”。所有的键对应到命令。
i “插入模式”用于插入文字。回归按键的本职工作。
: “命令行模式” Vim 希望你输入类似于保存该文档命令的地方。

方向键

快捷键 功能
h 光标向左移动一个字符
jCtrl + J 光标向下移动一行
kCtrl + P 光标向上移动一行
l 光标向右移动一个字符
0 (数字 0)移动光标至本行开头
$ 移动光标至本行末尾
^ 移动光标至本行第一个非空字符处
w 向前移动一个词 (上一个字母和数字组成的词之后)
W 向前移动一个词 (以空格分隔的词)
5w 向前移动五个词
b 向后移动一个词 (下一个字母和数字组成的词之前)
B 向后移动一个词 (以空格分隔的词)
5b 向后移动五个词
G 移动至文件末尾
gg 移动至文件开头

浏览文档

快捷键 功能
( 跳转到上一句
) 跳转到下一句
{ 跳转到上一段
} 跳转到下一段
[[ 跳转到上一部分
]] 跳转到下一部分
[] 跳转到上一部分的末尾
][ 跳转到上一部分的开头

插入文本

快捷键 功能
a 在光标后插入文本
A 在行末插入文本
i 在光标前插入文本
o (小写字母 o)在光标下方新开一行
O (大写字母 O)在光标上方新开一行

特殊插入

快捷键 功能
:r [filename] 在光标下方插入文件 [filename] 的内容
:r ![command] 执行命令 [command] ,并将输出插入至光标下方

删除文本

快捷键 功能
x 删除光标处字符
dw 删除一个词
d0 删至行首
d$ 删至行末
d) 删至句末
dgg 删至文件开头
dG 删至文件末尾
dd 删除该行
3dd 删除三行

简单替换文本

快捷键 功能
r{text} 将光标处的字符替换成 {text}
R 进入覆写模式,输入的字符将替换原有的字符

复制/粘贴文本

快捷键 功能
yy 复制当前行至存储缓冲区
["x]yy 复制当前行至寄存器 x
p 在当前行之后粘贴存储缓冲区中的内容
P 在当前行之前粘贴存储缓冲区中的内容
["x]p 在当前行之后粘贴寄存器 x 中的内容
["x]P 在当前行之前粘贴寄存器 x 中的内容

撤销/重做操作

快捷键 功能
u 撤销最后的操作
Ctrl+r 重做最后撤销的操作

搜索和替换

快捷键 功能
/search_text 检索文档,在文档后面的部分搜索 search_text
?search_text 检索文档,在文档前面的部分搜索 search_text
n 移动到后一个检索结果
N 移动到前一个检索结果
:%s/original/replacement 检索第一个 “original” 字符串并将其替换成 “replacement”
:%s/original/replacement/g 检索并将所有的 “original” 替换为 “replacement”
:%s/original/replacement/gc 检索出所有的 “original” 字符串,但在替换成 “replacement” 前,先询问是否替换

书签

快捷键 功能
m {a-zA-Z} 在当前光标位置设置书签,书签名可用一个大小写字母({a-zA-Z})
:marks 列出所有书签
{a-zA-Z} 跳转到书签 {a-zA-Z}

选择文本

快捷键 功能
v 进入逐字可视模式
V 进入逐行可视模式
Esc 退出可视模式

改动选中文本

快捷键 功能
~ 切换大小写
d 删除一个词
c 变更
y 复制
> 右移
< 左移
! 通过外部命令进行过滤

保存并退出

快捷键 功能
:q 退出 Vim,如果文件已被修改,将退出失败
:w 保存文件
:w new_name 用 new_name 作为文件名保存文件
:wq 保存文件并退出 Vim
:q! 退出 Vim,不保存文件改动
ZZ 退出 Vim,如果文件被改动过,保存改动内容
ZQ 与 :q! 相同,退出 Vim,不保存文件改动

下载 Vim 快捷键速查表

仅仅是这样是否还不足以满足你?别担心,我们已经为你整理好了一份下载版的速查表,以备不时之需。

点此下载(英文)

TAGS: ,
1月 27th, 2017

毫无疑问, Vim 是一个很强大的文本编辑器。它提供了大量的特性,这意味着学习并记住 Vim 的所有功能实际上是不可能的。但是我们至少可以不断学习简单的方法来完成事情,从而随着时间的增长,我们使用编辑器的经验将会变得更好。

请记住,在这篇文章中我们将讨论的一些 Vim 编辑器技巧是针对高级用户的。

:如果你是第一次接触 Vim,你可以首先阅读我们的入门指南。对于已经使用过 Vim 编辑器的用户,我确信 Vim 快捷键速查表将会对你很有帮助。如果你已经是一名有经验的用户,你可能对一些针对有经验用户的技巧比较感兴趣。

请注意文中提到的所有技巧绝大多数都是在简单、易于理解的代码环境中进行阐述的,因为它们在软件开发中确实很实用。但这并不意味着普通用户(非程序员、没有把 Vim 作为一般的文本编辑器)在他们的工作中用不到。

1、为文件设置特定的变量

有时候,在一个特定文件中,你可能想把输入的制表符用空格代替,或者想要把源代码文件使用两个空格缩进,即便编辑器的默认缩进是四个空格。

基本上我们在这儿讨论对针对文件的的更改。 Vim 提供的这个特性允许你对一个指定的文件更改特定的设置。这个特性叫做 “模式行Modeline” 。

比如,如果你想把输入的每一个制表符(Tab)用空格代替,那么你只需要在文件的前几行或最后几行加入下面的模式行:

  1. # vim: set expandtab:

如果想把默认缩进从 4 个空格变成 2 个空格,可以在源文件中添加下面的模式行:

  1. // vim: noai:ts=2:sw=2

在使用模式行时,请记住下面这几个重要的点:

  • 模式行只能添加在文件中的前五行或者最后五行。
  • 为了使用模式行这个特性,必须在 .vimrc 文件中添加 :set modeline
  • 在以 root 用户身份对文件进行编辑的时候该特性失效。

了解更多的信息,请阅读该特性的官方文档

2、 关键字补全

当你开始写的复杂代码越来越多或者开始在一个大的源文件上编辑时,你会遇到一些变量名字。有时,要记住所有的变量名字不太容易,所以当需要输入变量名字的时候,你通常从已经使用过的地方复制过来。

幸运的是,使用 Vim 你只需要输入变量的几个起始字母即可。在’插入模式’中,按 Ctrl + n 或者 Ctrl + p 可以得到一个匹配的关键词列表。 Ctrl + n 用来插入下一个匹配词; Ctrl + p 给出一个之前匹配的关键词列表。

下图是该特性的一个展示:

正如上面的屏幕截图清晰展示的那样,列表中也会出现其他源文件中包含的词。关于该特性的更多信息,请访问这儿

3、 搜索

假设你正在调试代码,其中一个需要做的工作是快速查看一个变量在一个文件中所有出现的地方。一个常用的方法是退出‘插入模式’,输入 /[变量名字] 命令,按回车 ,然后返回‘插入模式’,使用 np 在关键字之间导航。

上面讲到的这种方法没毛病,但是还有一种更简单、更快捷的方法可以来完成这样的搜索。使用这种方法,首先你需要退出‘插入模式’,然后把光标移动到你想要搜索的词/变量下面,这并不费时。接下来,你只需要按 Shift + * 即可。

重复这样做,然后编辑器将会带你找到在文件中所有使用了这个词/变量的地方。

 

1月 27th, 2017

相信大家对如下的Category都很熟悉,很多网站都有类似如下的功能,“商品推荐”,”猜你喜欢“,在实体店中我们有导购来为我们服务,在网络上

我们需要同样的一种替代物,如果简简单单的在数据库里面去捞,去比较,几乎是完成不了的,这时我们就需要一种协同推荐算法,来高效的推荐浏览者喜

欢的商品。

一:概念

SlopeOne的思想很简单,就是用均值化的思想来掩盖个体的打分差异,举个例子说明一下:

在这个图中,系统该如何计算“王五“对”电冰箱“的打分值呢?刚才我们也说了,slopeone是采用均值化的思想,也就是:R王五 =4-{[(5-10)+(4-5)]/2}=7 。

下面我们看看多于两项的商品,如何计算打分值。

rb = (n * (ra – R(A->B)) + m * (rc – R(C->B)))/(m+n)

注意: a,b,c 代表“商品”。

ra 代表“商品的打分值”。

ra->b  代表“A组到B组的平均差(均值化)”。

m,n 代表人数。

根据公式,我们来算一下。

r王五 = (2 * (4 – R(洗衣机->彩电)) + 2 * (10 – R(电冰箱->彩电))+ 2 * (5 – R(空调->彩电)))/(2+2+2)=6.8

是的,slopeOne就是这么简单,实战效果非常不错。

 

二:实现

1:定义一个评分类Rating。

复制代码
 1     /// <summary>
 2     /// 评分实体类
 3     /// </summary>
 4     public class Rating
 5     {
 6         /// <summary>
 7         /// 记录差值
 8         /// </summary>
 9         public float Value { get; set; }
10 
11         /// <summary>
12         /// 记录评分人数,方便公式中的 m 和 n 的值
13         /// </summary>
14         public int Freq { get; set; }
15 
16         /// <summary>
17         /// 记录打分用户的ID
18         /// </summary>
19         public HashSet<int> hash_user = new HashSet<int>();
20 
21         /// <summary>
22         /// 平均值
23         /// </summary>
24         public float AverageValue
25         {
26             get { return Value / Freq; }
27         }
28     }
复制代码

2: 定义一个产品类

复制代码
 1     /// <summary>
 2     /// 产品类
 3     /// </summary>
 4     public class Product
 5     {
 6         public int ProductID { get; set; }
 7 
 8         public string ProductName { get; set; }
 9 
10         /// <summary>
11         /// 对产品的打分
12         /// </summary>
13         public float Score { get; set; }
14     }
复制代码

3:SlopeOne类

参考了网络上的例子,将二维矩阵做成线性表,有效的降低了空间复杂度。

复制代码
  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 
  6 namespace SupportCenter.Test
  7 {
  8     #region Slope One 算法
  9     /// <summary>
 10     /// Slope One 算法
 11     /// </summary>
 12     public class SlopeOne
 13     {
 14         /// <summary>
 15         /// 评分系统
 16         /// </summary>
 17         public static Dictionary<int, Product> dicRatingSystem = new Dictionary<int, Product>();
 18 
 19         public Dictionary<string, Rating> dic_Martix = new Dictionary<string, Rating>();
 20 
 21         public HashSet<int> hash_items = new HashSet<int>();
 22 
 23         #region 接收一个用户的打分记录
 24         /// <summary>
 25         /// 接收一个用户的打分记录
 26         /// </summary>
 27         /// <param name="userRatings"></param>
 28         public void AddUserRatings(IDictionary<int, List<Product>> userRatings)
 29         {
 30             foreach (var user1 in userRatings)
 31             {
 32                 //遍历所有的Item
 33                 foreach (var item1 in user1.Value)
 34                 {
 35                     //该产品的编号(具有唯一性)
 36                     int item1Id = item1.ProductID;
 37 
 38                     //该项目的评分
 39                     float item1Rating = item1.Score;
 40 
 41                     //将产品编号字存放在hash表中
 42                     hash_items.Add(item1.ProductID);
 43 
 44                     foreach (var user2 in userRatings)
 45                     {
 46                         //再次遍历item,用于计算俩俩 Item 之间的差值
 47                         foreach (var item2 in user2.Value)
 48                         {
 49                             //过滤掉同名的项目
 50                             if (item2.ProductID <= item1Id)
 51                                 continue;
 52 
 53                             //该产品的名字
 54                             int item2Id = item2.ProductID;
 55 
 56                             //该项目的评分
 57                             float item2Rating = item2.Score;
 58 
 59                             Rating ratingDiff;
 60 
 61                             //用表的形式构建矩阵
 62                             var key = Tools.GetKey(item1Id, item2Id);
 63 
 64                             //将俩俩 Item 的差值 存放到 Rating 中
 65                             if (dic_Martix.Keys.Contains(key))
 66                                 ratingDiff = dic_Martix[key];
 67                             else
 68                             {
 69                                 ratingDiff = new Rating();
 70                                 dic_Martix[key] = ratingDiff;
 71                             }
 72 
 73                             //方便以后以后userrating的编辑操作,(add)
 74                             if (!ratingDiff.hash_user.Contains(user1.Key))
 75                             {
 76                                 //value保存差值
 77                                 ratingDiff.Value += item1Rating - item2Rating;
 78 
 79                                 //说明计算过一次
 80                                 ratingDiff.Freq += 1;
 81                             }
 82 
 83                             //记录操作人的ID,方便以后再次添加评分
 84                             ratingDiff.hash_user.Add(user1.Key);
 85                         }
 86                     }
 87                 }
 88             }
 89         }
 90         #endregion
 91 
 92         #region 根据矩阵的值,预测出该Rating中的值
 93         /// <summary>
 94         /// 根据矩阵的值,预测出该Rating中的值
 95         /// </summary>
 96         /// <param name="userRatings"></param>
 97         /// <returns></returns>
 98         public IDictionary<int, float> Predict(List<Product> userRatings)
 99         {
100             Dictionary<int, float> predictions = new Dictionary<int, float>();
101 
102             var productIDs = userRatings.Select(i => i.ProductID).ToList();
103 
104             //循环遍历_Items中所有的Items
105             foreach (var itemId in this.hash_items)
106             {
107                 //过滤掉不需要计算的产品编号
108                 if (productIDs.Contains(itemId))
109                     continue;
110 
111                 Rating itemRating = new Rating();
112 
113                 // 内层遍历userRatings
114                 foreach (var userRating in userRatings)
115                 {
116                     if (userRating.ProductID == itemId)
117                         continue;
118 
119                     int inputItemId = userRating.ProductID;
120 
121                     //获取该key对应项目的两组AVG的值
122                     var key = Tools.GetKey(itemId, inputItemId);
123 
124                     if (dic_Martix.Keys.Contains(key))
125                     {
126                         Rating diff = dic_Martix[key];
127 
128                         //关键点:运用公式求解(这边为了节省空间,对角线两侧的值呈现奇函数的特性)
129                         itemRating.Value += diff.Freq * (userRating.Score + diff.AverageValue * ((itemId < inputItemId) ? 1 : -1));
130 
131                         //关键点:运用公式求解 累计每两组的人数
132                         itemRating.Freq += diff.Freq;
133                     }
134                 }
135 
136                 predictions.Add(itemId, itemRating.AverageValue);
137             }
138 
139             return predictions;
140         }
141         #endregion
142     }
143     #endregion
144 
145     #region 工具类
146     /// <summary>
147     /// 工具类
148     /// </summary>
149     public class Tools
150     {
151         public static string GetKey(int Item1Id, int Item2Id)
152         {
153             return (Item1Id < Item2Id) ? Item1Id + "->" + Item2Id : Item2Id + "->" + Item1Id;
154         }
155     }
156     #endregion
157 }
复制代码

 

4: 测试类Program

这里我们灌入了userid=1000,2000,3000的这三个人,然后我们预测userID=3000这个人对 “彩电” 的打分会是多少?

复制代码
 1     public class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5             SlopeOne test = new SlopeOne();
 6 
 7             Dictionary<int, List<Product>> userRating = new Dictionary<int, List<Product>>();
 8 
 9             //第一位用户
10             List<Product> list = new List<Product>()
11             {
12                 new Product(){ ProductID=1, ProductName="洗衣机",Score=5},
13                 new Product(){ ProductID=2, ProductName="电冰箱", Score=10},
14                 new Product(){ ProductID=3, ProductName="彩电", Score=10},
15                 new Product(){ ProductID=4, ProductName="空调", Score=5},
16             };
17 
18             userRating.Add(1000, list);
19 
20             test.AddUserRatings(userRating);
21 
22             userRating.Clear();
23             userRating.Add(1000, list);
24 
25             test.AddUserRatings(userRating);
26 
27             //第二位用户
28             list = new List<Product>()
29             {
30                 new Product(){ ProductID=1, ProductName="洗衣机",Score=4},
31                 new Product(){ ProductID=2, ProductName="电冰箱", Score=5},
32                 new Product(){ ProductID=3, ProductName="彩电", Score=4},
33                  new Product(){ ProductID=4, ProductName="空调", Score=10},
34             };
35 
36             userRating.Clear();
37             userRating.Add(2000, list);
38 
39             test.AddUserRatings(userRating);
40 
41             //第三位用户
42             list = new List<Product>()
43             {
44                 new Product(){ ProductID=1, ProductName="洗衣机", Score=4},
45                 new Product(){ ProductID=2, ProductName="电冰箱", Score=10},
46                 new Product(){ ProductID=4, ProductName="空调", Score=5},
47             };
48 
49             userRating.Clear();
50             userRating.Add(3000, list);
51 
52             test.AddUserRatings(userRating);
53 
54             //那么我们预测userID=3000这个人对 “彩电” 的打分会是多少?
55             var userID = userRating.Keys.FirstOrDefault();
56             var result = userRating[userID];
57 
58             var predictions = test.Predict(result);
59 
60             foreach (var rating in predictions)
61                 Console.WriteLine("ProductID= " + rating.Key + " Rating: " + rating.Value);
62         }
63     }
复制代码

 

 
文章来自网络博客,原文地址:http://www.cnblogs.com/huangxincheng/archive/2012/11/22/2782647.html

1月 27th, 2017

这篇我们看看最长公共子序列的另一个版本,求字符串相似度(编辑距离),我也说过了,这是一个非常实用的算法,在DNA对比,网

页聚类等方面都有用武之地。

一:概念

对于两个字符串A和B,通过基本的增删改将字符串A改成B,或者将B改成A,在改变的过程中我们使用的最少步骤称之为“编辑距离”。

比如如下的字符串:我们通过种种操作,痉挛之后编辑距离为3,不知道你看出来了没有?

二:解析

可能大家觉得有点复杂,不好理解,我们试着把这个大问题拆分掉,将”字符串 vs 字符串“,分解成”字符 vs 字符串“,再分解

成”字符 vs 字符“。

<1> ”字符“vs”字符“

这种情况是最简单的了,比如”A“与”B“的编辑距离很显然是1。

<2> ”字符”vs”字符串”

”A“改成”AB“的编辑距离为1,“A”与“ABA”的编辑距离为2。

<3>“字符串”vs“字符串”

“ABA”和“BBA”的编辑距离为1,仔细发现我们可以得出如下结论,”ABA“是由23个子序列与”BBA“字符串求的的编辑距离集

合中取出的最小编辑距离,也就是说在这种情况下我们出现了重复计算的问题,我在求子序列”AB“和”BBA”的编辑距离时,我是由

子序列”A“和”BBA“与”B“和”BBA“之间的编辑距离中选出一个最小值,然而序列A和序列B早之前我已经计算过了,这种重复计算

的问题有点像”斐波那契”,正好满足“动态规划”中的最优子结构和重叠子问题,所以我们决定采用动态规划来解决。

 

三:公式

跟“最长公共子序列”一样,我们采用一个二维数组来保存字符串X和Y当前的位置的最小编辑距离。

现有两个序列X={x1,x2,x3,…xi},Y={y1,y2,y3,….,yi},

设一个C[i,j]: 保存Xi与Yj的当前最小的LD。

①: 当 X= Yi 时,则C[i,j]=C[i-1,j-1];

②:当 X!= Y时, 则C[i,j]=Min{C[i-1,j-1],C[i-1,j],C[i,j-1]};

最终我们的C[i,j]一直保存着最小的LD。

 

四:代码

复制代码
 1 using System;
 2 
 3 namespace ConsoleApplication2
 4 {
 5     public class Program
 6     {
 7         static int[,] martix;
 8 
 9         static string str1 = string.Empty;
10 
11         static string str2 = string.Empty;
12 
13         static void Main(string[] args)
14         {
15             while (true)
16             {
17                 str1 = Console.ReadLine();
18 
19                 str2 = Console.ReadLine();
20 
21                 martix = new int[str1.Length + 1, str2.Length + 1];
22 
23                 Console.WriteLine("字符串 {0} 和 {1} 的编辑距离为:{2}\n", str1, str2, LD());
24             }
25         }
26 
27         /// <summary>
28         /// 计算字符串的编辑距离
29         /// </summary>
30         /// <returns></returns>
31         public static int LD()
32         {
33             //初始化边界值(忽略计算时的边界情况)
34             for (int i = 0; i <= str1.Length; i++)
35             {
36                 martix[i, 0] = i;
37             }
38 
39             for (int j = 0; j <= str2.Length; j++)
40             {
41                 martix[0, j] = j;
42             }
43 
44             //矩阵的 X 坐标
45             for (int i = 1; i <= str1.Length; i++)
46             {
47                 //矩阵的 Y 坐标
48                 for (int j = 1; j <= str2.Length; j++)
49                 {
50                     //相等情况
51                     if (str1[i - 1] == str2[j - 1])
52                     {
53                         martix[i, j] = martix[i - 1, j - 1];
54                     }
55                     else
56                     {
57                         //取“左前方”,“上方”,“左方“的最小值
58                         var temp1 = Math.Min(martix[i - 1, j], martix[i, j - 1]);
59 
60                         //获取最小值
61                         var min = Math.Min(temp1, martix[i - 1, j - 1]);
62 
63                         martix[i, j] = min + 1;
64                     }
65                 }
66             }
67 
68             //返回字符串的编辑距离
69             return martix[str1.Length, str2.Length];
70         }
71     }
72 }
复制代码

 

 

文章来自网络博客,原文地址:http://www.cnblogs.com/huangxincheng/archive/2012/11/11/2765633.html