发布新日志

  • Linux中iptables的用法

    2018-11-12 15:52:46

    http://blog.51cto.com/wn2100/2054541

    1 iptables

    iptables命令用于创建数据过滤与NAT规则,在iptables命令中设置数据过滤或处理数据包的策略叫做规则,将多个规则合成一个链。

    1.1 iptables的控制类型

    ACCEPT:允许通过

    LOG:记录日志信息,然后传给下一条规则继续匹配。

    REJECT:拒绝通过,必要时给出提示。

    DROP:直接丢弃,不给出任何回应。

    1.2 规则链

    规则链依据处理数据包的位置不同而进行分类

    PREROUTING:在进行路由选择前处理数据包。

    INPUT:处理入站的数据包。

    OUTPUT:处理出站的数据包。

    FORWARD:处理转发的数据包。

    POSTROUTING:在进行路由选择后处理数据包。

    规则链的先后顺序:

    入站顺序:PREROUTINGàINPUT

    出站顺序:OUTPUTàPOSTROUTING

    转发顺序:PREROUTINGàFORWARDàPOSTROUTING

    1.3 规则表

    iptables中的规则表是用于容纳规则链,规则表默认是允许状态的,那么规则链就是设置被禁止的规则,而反之如果规则表是禁止状态的,那么规则链就是设置被允许的规则             

    raw表:确定是否对该数据包进行状态跟踪。

    mangle表:为数据包设置标记。

    nat表:修改数据包中的源、目的IP地址或端口。

    filter表:此表是默认规则表,确定是否放行该数据包。

    规则表的先后顺序:rawàmangleànatàfilter

    1.4 注意事项

    1.       没有指定规则表则默认指filter表。

    2.       不指定规则链则指表内所有的规则链。

    3.       在规则链中匹配规则时会依次检查,匹配即停止(LOG规则除外),若没有匹配项则按链的默认状态处理。

    1.5 iptables命令用法

    1.5.1 添加规则

    iptables [-t 表名选项 [链名] [条件] [-j 控制类型]

    1.5.1.1 INPUT规则

    # iptables -L -t filter  #查看filter表,“-t filter”可省略,因为默认就是filter

    # iptables -L -t nat   #查看nat

    #INPUT链的默认策略设置为丢弃。(此时ssh连接也被拒绝了) -P:policy

    # iptables -P INPUT DROP    

    #允许所有的ping操作,-I:insert在规则链头部加入新规则 -p:protocol -j: jump指令

    # iptables -I INPUT -p icmp -j ACCEPT

    INPUT链追加一条规则,允许所有未被其他规则匹配上的数据包通过,“-t filter”可省略,因为默认就是filter

    # iptables -t filter -A INPUT -j ACCEPT

    仅允许来自于10.0.0.0/24网段的用户连接本机的ssh服务

    # iptables -I INPUT -s 10.0.0.0/24 -p tcp --dport 22 -j ACCEPT

    # iptables -A INPUT -p tcp --dport 22 -j REJECT

    不允许任何主机访问本机的12345端口

    # iptables -I INPUT -p tcp --dport 12345 -j REJECT

    # iptables -I INPUT -p udp --dport 12345 -j REJECT 

    拒绝所有主机通过eth0网卡访问本机的http服务

    # iptables -I INPUT -i eth0 -p tcp --dport 80 -j REJECT

    1.5.1.2 FORWARD规则

    FORWARD规则相当于路由功能

    禁止用户访问www.wangning.com

    iptables -I FORWARD -d www.wangning.com -j REJECT

    禁止IP10.0.0.66的用户上网

    # iptables -I FORWARD -s 10.0.0.66 -j REJECT

     

    1.5.2 删除规则

    #删除filter表中INPUT规则的第一条

    # iptables -D INPUT 1    

    1.6 保存iptables配置

    # /etc/init.d/iptables save

  • 实例!软件缺陷数据度量和分析

    2018-10-18 11:09:54

  • 使用python求字符串或文件的MD5

    2018-04-11 13:03:30

    #以下可在python3运行。


    #字符串md5,用你的字符串代替’字符串’中的内容。

    import hashlib

    md5=hashlib.md5(‘字符串’.encode(‘utf-8′)).hexdigest()

    print(md5)


    #求文件md5

    import hashlib

    #文件位置中的路径,请用双反斜杠,

    如’D:\\abc\\www\\b.msi’

    file='D:\\abc\\www\\b.msi’

    md5file=open(file,’rb’)

    md5=hashlib.md5(md5file.read()).hexdigest()

    md5file.close()

    print(md5)

  • Win10下python3和python2同时安装并解决pip共存问题

    2018-04-11 11:35:53

  • 消息推送设置

    2018-04-10 16:38:49

    消息推送设置

    设置开关打开状态下,消息推送是否可正常接收(应用启用中和应用关闭时都应该可以收到)

    默认开关应该是全打开状态

    ●设置开关可以自由打开关闭

    ●确认后台未打开APP客户端时,手机消息栏可以接收到消息提醒。且点击可查看。点击后消息栏中消失

    ●确认APP客户端启动时,可以收到消息提醒,且点击可查看。客户端运行时,消息不会进消息栏。

    ●设置开关关闭时,客户端接收不到消息推送。

  • python coverage--单元测试覆盖图

    2018-04-10 10:28:27

    python coverage--单元测试覆盖图
    https://www.jianshu.com/p/ed7ba052ccab

    介绍

    coverage 在单元测试中可以显示覆盖率,显示更清晰的数据

    • 支持python 2.6-python3.X
    • pip install coverage安装

    测试代码

    def add(a, b):
        return a + b
     
     
    def subtract(a, b):
        return a - b
     
     
    def multiply(a, b):
        return a * b
     
     
    def divide(numerator, denominator):
        return float(numerator) / denominator
    
    • unittest测试
    import mymath
    import unittest
     
    class TestAdd(unittest.TestCase):
        """
        Test the add function from the mymath library
        """
     
        def test_add_integers(self):
            """
            Test that the addition of two integers returns the correct total
            """
            result = mymath.add(1, 2)
            self.assertEqual(result, 3)
     
        def test_add_floats(self):
            """
            Test that the addition of two floats returns the correct result
            """
            result = mymath.add(10.5, 2)
            self.assertEqual(result, 12.5)
     
        def test_add_strings(self):
            """
            Test the addition of two strings returns the two string as one
            concatenated string
            """
            result = mymath.add('abc', 'def')
            self.assertEqual(result, 'abcdef')
     
     
    if __name__ == '__main__':
        unittest.main()
    
    • 命名运行
    coverage run test_mymath.py
    coverage report -m

    作者:望月成三人
    链接:https://www.jianshu.com/p/ed7ba052ccab
    來源:简书



    Coverage简介

    Coverage是一种用于统计Python代码覆盖率的工具,通过它我们可以检测测试代码的有效性,即测试case对被测代码的覆盖率如何。
    Coverage支持分支覆盖率统计,可以生成HTML/XML报告。XML报告可以集成入Jenkins和Sonar。
    官方文档:http://coverage.readthedocs.org/en/latest/

    Coverage安装(Ubuntu)

    sudo pip install coverage

    目前最新的版本是4.0。

    Coverage使用

    Coverage支持2种运行方式,一种是命令行方式,另一种是在代码中调用Coverage的API,可以灵活地控制哪些代码需要测试。
    关于这2种方式,可以看以下文档:
    命令行方式:http://coverage.readthedocs.org/en/latest/cmd.html
    API方式:http://coverage.readthedocs.org/en/latest/api.html

    分析Web项目的代码覆盖率

    关于以Python启动的web项目的代码覆盖率统计,请见:

    关于WSGI项目的覆盖率统计,这方面的文档较少,需要一定地摸索,请见:

  • 彻底解决 Jedis 连接池 获取不到连接,连接放回连接池错误的问题

    2018-02-11 16:17:58

    1. public class CacheKit {  
    2.     private static Logger logger = LoggerFactory.getLogger(CacheKit.class);  
    3.     private List<JSONObject> resultList;  
    4.     private static JedisPool pool;  
    5.   
    6.     /** 
    7.      * 初始化Redis连接池 
    8.      */  
    9.     private static void initializePool() {  
    10.         //redisURL 与 redisPort 的配置文件  
    11.         String configFile = "production.properties";  
    12.         if (PropKit.getBoolean("devMode")) {  
    13.             configFile = "dev.properties";  
    14.         }  
    15.   
    16.         JedisPoolConfig config = new JedisPoolConfig();  
    17.         //设置最大连接数(100个足够用了,没必要设置太大)  
    18.         config.setMaxTotal(100);  
    19.         //最大空闲连接数  
    20.         config.setMaxIdle(10);  
    21.         //获取Jedis连接的最大等待时间(50秒)   
    22.         config.setMaxWaitMillis(50 * 1000);  
    23.         //在获取Jedis连接时,自动检验连接是否可用  
    24.         config.setTestOnBorrow(true);  
    25.         //在将连接放回池中前,自动检验连接是否有效  
    26.         config.setTestOnReturn(true);  
    27.         //自动测试池中的空闲连接是否都是可用连接  
    28.         config.setTestWhileIdle(true);  
    29.         //创建连接池  
    30.         pool = new JedisPool(config, PropKit.use(configFile).get("redisURL"),  
    31.                     PropKit.use(configFile).getInt("redisPort"));  
    32.     }  
    33.   
    34.     /** 
    35.      * 多线程环境同步初始化(保证项目中有且仅有一个连接池) 
    36.      */  
    37.     private static synchronized void poolInit() {  
    38.         if (null == pool) {  
    39.             initializePool();  
    40.         }  
    41.     }  
    42.   
    43.     /** 
    44.      * 获取Jedis实例 
    45.      */  
    46.     private static Jedis getJedis() {  
    47.         if (null == pool) {  
    48.             poolInit();  
    49.         }  
    50.   
    51.         int timeoutCount = 0;  
    52.         while (true) {  
    53.             try {  
    54.                 if (null != pool) {  
    55.                     return pool.getResource();  
    56.                 }  
    57.             } catch (Exception e) {  
    58.                 if (e instanceof JedisConnectionException) {  
    59.                     timeoutCount++;  
    60.                     logger.warn("getJedis timeoutCount={}", timeoutCount);  
    61.                     if (timeoutCount > 3) {  
    62.                         break;  
    63.                     }  
    64.                 } else {  
    65.                     logger.warn("jedisInfo ... NumActive=" + pool.getNumActive()  
    66.                             + ", NumIdle=" + pool.getNumIdle()  
    67.                             + ", NumWaiters=" + pool.getNumWaiters()  
    68.                             + ", isClosed=" + pool.isClosed());  
    69.                     logger.error("GetJedis error,", e);  
    70.                     break;  
    71.                 }  
    72.             }  
    73.             break;  
    74.         }  
    75.         return null;  
    76.     }  
    77.   
    78.     /** 
    79.      * 释放Jedis资源 
    80.      * 
    81.      * @param jedis 
    82.      */  
    83.     public static void returnResource(Jedis jedis) {  
    84.         if (null != jedis) {  
    85.             pool.returnResourceObject(jedis);  
    86.         }  
    87.     }  
    88.   
    89.     /** 
    90.      * 绝对获取方法(保证一定能够使用可用的连接获取到 目标数据) 
    91.      * Jedis连接使用后放回  
    92.      * @param key 
    93.      * @return 
    94.      */  
    95.     private String safeGet(String key) {  
    96.         Jedis jedis = getJedis();  
    97.         while (true) {  
    98.             if (null != jedis) {  
    99.                 break;  
    100.             } else {  
    101.                 jedis = getJedis();  
    102.             }  
    103.         }  
    104.         String value = jedis.get(key);  
    105.         returnResource(jedis);  
    106.         return value;  
    107.     }  
    108.   
    109.     /** 
    110.      * 绝对设置方法(保证一定能够使用可用的链接设置 数据) 
    111.      * Jedis连接使用后返回连接池 
    112.      * @param key 
    113.      * @param time 
    114.      * @param value 
    115.      */  
    116.     private void safeSet(String key, int time, String value) {  
    117.         Jedis jedis = getJedis();  
    118.         while (true) {  
    119.             if (null != jedis) {  
    120.                 break;  
    121.             } else {  
    122.                 jedis = getJedis();  
    123.             }  
    124.         }  
    125.         jedis.setex(key, time, value);  
    126.         returnResource(jedis);  
    127.     }  
    128.   
    129.     /** 
    130.      * 绝对删除方法(保证删除绝对有效) 
    131.      * Jedis连接使用后返回连接池</span> 
    132.      * @param key 
    133.      */  
    134.     private void safeDel(String key) {  
    135.         Jedis jedis = getJedis();  
    136.         while (true) {  
    137.             if (null != jedis) {  
    138.                 break;  
    139.             } else {  
    140.                 jedis = getJedis();  
    141.             }  
    142.         }  
    143.         jedis.del(key);  
    144.         returnResource(jedis);  
    145.     }  
    146.   
    147.     /**自定义的一些 get set del 方法,方便使用**/  
    148.     public JSONObject getByCache(String key) {  
    149.         String result = safeGet(key);  
    150.         if (result != null) {  
    151.             return (JSONObject) JSONObject.parse(result);  
    152.         }  
    153.         return null;  
    154.   
    155.     }  
    156.   
    157.     public String getByCacheToString(String key) {  
    158.         String result = safeGet(key);  
    159.         if (result != null) {  
    160.             return result;  
    161.         }  
    162.         return null;  
    163.   
    164.     }  
    165.   
    166.     public List<JSONObject> getArrayByCache(String key) {  
    167.         String result = safeGet(key);  
    168.         if (result != null) {  
    169.             resultList = JSONArray.parseArray(result, JSONObject.class);  
    170.             return resultList;  
    171.         }  
    172.         return null;  
    173.     }  
    174.   
    175.     public JSONArray getJSONArrayByCache(String key) {  
    176.         String result = safeGet(key);  
    177.         if (result != null) {  
    178.             return JSONArray.parseArray(result);  
    179.         }  
    180.         return null;  
    181.     }  
    182.   
    183.     public void setByCache(String key, String s) {  
    184.         safeSet(key, 86400, s);  
    185.     }  
    186.   
    187.     public void setByCacheOneHour(String key, String s) {  
    188.         safeSet(key, 3600, s);  
    189.     }  
    190.   
    191.     public void setByCacheOneHour(String key, List<JSONObject> json) {  
    192.         safeSet(key, 86400, JSONObject.toJSONString(json));  
    193.         resultList = json;  
    194.     }  
    195.   
    196.     public void setByCache(String key, JSONObject json) {  
    197.         safeSet(key, 86400, JSONObject.toJSONString(json));  
    198.     }  
    199.   
    200.     public void setByCache(String key, List<JSONObject> list) {  
    201.         safeSet(key, 86400, JSONObject.toJSONString(list));  
    202.         resultList = list;  
    203.     }  
    204.   
    205.     public void setByCache(String key, JSONArray array) {  
    206.         safeSet(key, 86400, JSONArray.toJSONString(array));  
    207.     }  
    208.   
    209.     public void setByCacheCusTime(String key, String s, int time) {  
    210.         safeSet(key, time, s);  
    211.     }  
    212.   
    213.   
    214.     public void delByCache(String key) {  
    215.         if (null != safeGet(key)) {  
    216.             safeDel(key);  
    217.         }  
    218.     }  
    219.   
    220.     public JSONObject toJSON(DBObject db) {  
    221.         return (JSONObject) JSONObject.toJSON(db);  
    222.     }  
    223.   
    224.     public List<JSONObject> toJSON(List<DBObject> list) {  
    225.         List<JSONObject> json = new ArrayList<>();  
    226.         for (DBObject aList : list) {  
    227.             json.add((JSONObject) JSONObject.toJSON(aList));  
    228.         }  
    229.         return json;  
    230.     }  
    231.   
    232.     public boolean notNull() {  
    233.         return resultList != null && resultList.size() > 0;  
    234.     }  
    235.   
    236.     public List<JSONObject> getResult() {  
    237.         return resultList;  
    238.     }  
    239.   
    240. }
  • python3发送邮件(yagmail)

    2018-01-30 17:58:15

    python3发送邮件(yagmail)

    # coding:utf-8

    import yagmail

    # 链接邮箱服务器
    yag = yagmail.SMTP(user="xxx@xx.com", password="xxx!!", host='smtp.xxx.com')

    # 邮箱正文
    contents = ['This is the body, and here is just text http://somedomain/image.png',
    'You can find an audio file attached.', '/local/path/song.mp3','测试邮件']

    # 发送邮件
    yag.send(['xxx@xx.com', 'xxxxxx@xx.com'], '发送附件', contents, ['test.html', 'logo.jpg', 'yagmal_test.txt'])

    #抄送
    # 邮箱正文  文本及附件
    contents = ['This is the body, and here is just text http://somedomain/image.png',
    'You can find an audio file attached.', '/local/path/song.mp3', '测试邮件', 'test.html', 'logo.jpg',
    'yagmal_test.txt']

    # 发送邮件
    yag.send(to='xx@xx.com', cc='xxx@xxx.com', subject='发送附件', contents=contents)
  • 录制参数设置(HTML-based script和URL-based script的区别)

    2017-11-27 20:14:30

    http://www.51testing.com/html/32/365232-3485547.html


    选中HTML-based script模式后,点击HTML Advanced HTML按钮,进入HTML-based script的高级设置窗口界面。

    • 脚本类型中默认选择的是第一个,而用来描述用户行为的脚本,通常会采用该项。在这类脚本中,脚本的描述形式和用户的操作一致,能够非常直观地看到用户的操作流程。直接创建的URL(web_url)、表单提交(web_submit_form)、链接(web_link)和图像(web_image)等函数,产生的脚本非常直观。
    • 脚本类型的第二个选项仅包含明确的URL脚本。在这种脚本中,所有的链接、图像请求和URL操作都被录制为web_url函数,而表单提交则被录制为web_submit_data函数。这种模式在直观性上不如第一种,但是在某些情况下比较有用。例如,当一个站点中有很多链接具有相同的链接文本时,可以使用这种模式按照每个链接的URL将其列出,便于实现这些操作的参数化和关联
  • 浏览器渲染原理及web前端分析

    2017-11-27 09:51:27

    http://blog.csdn.net/yu1014745867/article/details/78518296

    浏览器的主要功能

    1. 用户界面:包括地址栏、后退/前进按钮、书签目录等,也就是除了用来显示你所请求页面的主窗口之外的其他部分。

    2. 浏览器引擎:用来查询及操作渲染引擎的接口。另外还用来操作浏览器的数据存储。

    3. 渲染引擎:用来显示请求的内容,例如,如果请求内容为html,它负责解析html及css,并将解析后的结果显示出来。

    4. 网络:用来完成网络调用,例如http请求,它具有平台无关的接口,可以在不同平台上工作。

    5. UI后端:用来绘制类似组合选择框及对话框等基本组件,具有不特定于某个平台的通用接口,底层使用操作系统的用户接口。

    6. JS解释器:用来解释执行JS代码。

    7. 数据存储:属于持久层,浏览器需要在硬盘中保存类似cookie的各种数据

    图:浏览器主要组件图

    浏览器渲染机制

    我们现在要在浏览器中显示以上结构的HTML:

    1.客户端浏览器开始从用户向服务器发出请求,服务器响应的将如上的HTML返回给请求的客户端浏览器中。

    2.加载从标签开始,并发现标签内有个外部样式文件要加载

    <link href="../css/css.css" rel="Stylesheet" type="text/css" />
    • 1

    3.这时客户端浏览器又向服务器发出一个请求加载css.css文件,服务器响应。

    4.此时客户端浏览器继续加载html文件里里的标签,在css.css文件加载完后,同时开始渲染页面。

    5.客户端浏览器在里的标签中发现一个标签并且引用了服务器进而的一张名为test.jpg的图片.客户端浏览器又向服务器发出一次请求。而浏览器不会因为此时正在加载标签里的图片而停止等待图片加载完,浏览器继续渲染还未完成的部分。

    6.标签里的图片加载完了,则要显示出来,同时图片会占有一定的面积,又会影响到后面的布局,浏览器不得不又回来重新渲染一次这部分。

    7.总算把body里的标签加载及渲染完后,浏览器又发现了一段代码:

    <script type="text/javascript" src="js/js.js"></script>
    • 1

    8.浏览器又立刻向服务器发出请求加载js.js文件,服务器响应。

    9.浏览器又在js.js文件中发现了一段代码是让

    标签隐藏的代码,此时浏览器又要重新去渲染被隐藏的
    部分。

    10.最后到浏览器发现了为止。

    参考资料:
    深入学习,偏底层(对于架构的理解更透彻)
    http://blog.csdn.net/findsafety/article/details/50424307

    WEB前端分析测试点

    12个测试要点

    优点:
    纯粹的前端视角,可以测试任何的网站,不需要考虑后台

    1.减少http请求的数量(把js,css合并),为了尽可能减少tcp链接的建立和释放连接的资源,减少读取资源读取IO的时间

    2.用好浏览器缓存,浏览器会把所有的访问记录保存在硬盘中,下次访问时会判断时候已保存,提升访问速度。

    3.利用gzip压缩机制,只针对文本类资源有效(js,css,html),文本的压缩比可以达到70%多。gif,png,等图片资源其实已经被压缩过了

    4.把CSS文件放在html的开头,让浏览器一开始把渲染资源下载下来,保证以后的页面渲染比较流畅。
    css主要用来渲染,当发现有css会优先下载下来,便于渲染。

    5.尽可能把js放在html的结尾,当页面渲染完成后,用户操作时候能达到动态的效果

    6.尽量避免css表达式,判断浏览器的版本,分辨率等表达式

    7.尽可能减少DNS查找,dns本身会消耗时间,尽可能使用相对路径。

    DNS作用:把域名解析成IP地址

    8.最好使用js压缩,比gzip更有针对性,js压缩并不是需要解压缩,而是压缩了以后js代码同样可以工作.

    eg.var username–> var u;
    把长的字符变成短的字符,同样适用于css,html

    9.尽量避免重定向redirect eg.访问www.baidu.com/
    /本身也是一种重定向,我们网页内部尽可能制定到某一个指定的地址,以减少资源

    10.去除重复的脚本,脚本重复太多会增大脚本的大小,消耗带宽资源
    如:加减法的函数,可以合并成一个操作函数

    11.使用ajax请求,局部某些数据会变化,需要什么内容只请求那一部分内容
    提升用户体验,节省很多网络传输的带宽成本。
    目前,我们用jQuery js的框架写ajax非常方便.

    12.使用CDN,内容分发网络。cdn不是从前端可控的技术,很大的缓存服务器
    减少总服务器的访问压力,提升用户的访问速度.

  • web编程中页面加载过慢是什么原因引起的?

    2017-11-24 10:14:30

    1、服务器端:检查服务器端的运行效率,看是否是后台运算效率不高导致响应过慢,这可以用日志和工具分析一下。
    2、传输过程:如果你用的窄带或者远程网络,尤其要注意,看看页面大小是否过大,是否有大的图片或js传输
    3、浏览器端:检查javascript运行效率,内存和cpu的占用情况。
    建议你先在ie下用IEwatch插件分析一下会更清楚一些
    内容多。

    使用了大的控件。

    代码未优化。

    网络问题。

    等等

  • mac怎么修改图片大小

    2017-10-23 14:44:47

  • Mac 完整截取 Safari 网页长图的四种方式

    2017-06-09 09:42:42

    https://www.myzaker.com/article/58aa5fa21bc8e01167000022/

    4. 使用 Mac 自带的打印功能保存完整图片

    这种方式比较麻烦,但是需要的时候可以应急。

    第一步:当你想截取完整网页图片的时候,按 commnad-P 选择打印网页,然后在「纸张大小」中选择「管理自定大小」

    第二步:在高度和宽度中选择合适的数值(你可以放大数倍,然后剪裁即可),即可看到整个网页在一张页面中。
    第三,点击 PDF,选择「存储为 PDF」,再用系统自带的「预览」将 PDF 导出为图片然后适当剪裁即可。
  • 推荐一款Mac下支持滚动截屏的截图软件snip

    2017-06-09 09:37:17

    https://jingyan.baidu.com/article/fec4bce2458d03f2618d8b8e.html


     


    1. 首先你截图的对象要有滚动区域,比如截一个长长的网页,然后开始截屏,鼠标左键单击一下,而不是按着鼠标左键拖动

    2. 当你单击之后,会弹出下面这样一个弹窗,等进度条走完了,它就自动把图截好了

  • PHP性能分析工具 xhprof

    2017-06-05 11:33:12

    安装

    下载/解压

    下载地址: 
    http://pecl.php.net/package/xhprof

    cd /data/soft
    wget http://pecl.php.net/get/xhprof-0.9.4.tgz
    tar -zxf xhprof-0.9.4.tgz
    

    编译/安装

    cd xhprof-0.9.4
    cd extension/
    phpize
    
    ./configure --with-php-config=/usr/local/php/bin/php-config
    #上面的路径是自己本机PHP的配置文件路径
    
    make && make install
    #此处完成后会显示出 xhprof.so 所在的路径,将该文件复制到PHP扩展的目录
    cp /data/soft/xhprof-0.9.4/extension/modules/xhprof.so /usr/local/php/lib/php/extensions/no-debug-non-zts-20090626/
    
    这里的目标地址是 php.ini 中 extension_dir 的值。如果 php.ini 中没有 extension_dir 这一项,自己添加到并配置一个目录,然后将 .so 文件复制到其中。
    
    建立分析结果导出目录:
    mkdir -p /data/xhprof/xhprof_data在 php.ini 中添加如下行:
    
    [xhprof]
    xhprof.output_dir = /data/xhprof/xhprof_data
    extension = xhprof.so
    mkdir -p /usr/local/php/include/xhprof/
    在 php-fpm.conf 中添加:
    
    env[XHPROF_ROOT_PATH] = /usr/local/php/include/xhprof/
    #后面在PHP代码中可以通过 $_SERVER['XHPROF_ROOT_PATH'] 来引用,比较方便。
    
    将 xhprof 解压目录下的 xhprof_lib 复制到上面目录中.此步目的是以后在程序中引用里面的类库时更方便,如果不执行该步也可以。
    cp -r /data/soft/xhprof-0.9.4/xhprof_lib/ /usr/local/php/include/xhprof/xhprof_lib
    
    yum install -y graphviz
    #安装图形绘制工具,后面的结果可以通过该工具以图形显示,更直观
    

    查看安装结果

    重新加载 php 配置文件
    service php-fpm reload
    
    在 WEB 页面上查看 phpinfo 或者在命令行中执行:
    php -i | grep xhprof
    
    结果:
    xhprof
    xhprof => 0.9.2
    

    分析结果查看配置

    cp -r /data/soft/xhprof-0.9.4/xhprof_html/ /home/wwwroot/default/xhprof_html
    
    #将 xhprof 自带的结果查看页面复制到本机器的WEB目录下
    
    cp -r /data/soft/xhprof-0.9.4/xhprof_lib/ /home/wwwroot/default/xhprof_lib
    #由于显示结果也用到了 xhprof_lib 里的类库,且里面的代码是按相对路径引用的,所以先直接把该库和页面放在一起
    
    

    使用

    在 PHP 页面顶部加上:

    xhprof_enable(XHPROF_FLAGS_NO_BUILTINS + XHPROF_FLAGS_MEMORY);
    
    

    在页面底部加上:

    $xhprof_data = xhprof_disable();
    include_once $_SERVER['XHPROF_ROOT_PATH'] . "/xhprof_lib/utils/xhprof_lib.php";
    
    include_once $_SERVER['XHPROF_ROOT_PATH'] . "/xhprof_lib/utils/xhprof_runs.php";
    
    $xhprof_runs = new XHProfRuns_Default();
    //数据会保存在php.ini中xhprof.output_dir设置的目录去中
    
    $run_id = $xhprof_runs->save_run($xhprof_data, str_replace(".", "_", basename(__FILE__)));
    //第二个参数是定义文件名称
    

    分析结果

    访问上面的页面后,在结果目录发现有如下文件产生:

    ls -l /data/xhprof/xhprof_data/
    总用量 32
    -rw-r--r-- 1 www www 16080 124 21:24 548060a27725b.co_main_php.xhprof
    -rw-r--r-- 1 www www 16076 124 21:24 548060a2c49f7.co_main_php.xhprof
    

    请求页面: 
    http://yourdomain/xhprof_html/index.php

    页面结果:

    No XHProf runs specified in the URL. 
    Existing runs: 
    548060a2c49f7.co_main_php.xhprof 2014-12-04 21:24:50 
    548060a27725b.co_main_php.xhprof 2014-12-04 21:24:50

    即上面显示的生成的结果文件。 
    点击一个文件查看详细结果,得到:

    PHP性能分析工具 <wbr>xhprof

    PHP性能分析工具 <wbr>xhprof

    转自:http://blog.sina.com.cn/s/blog_5f54f0be0102v995.html


  • cp: omitting directory”错误的解释和解决办法

    2017-05-27 16:40:09

    Linux下拷贝的时候有时候会出现cp:omitting directory的错误 ,例如 cp:omitting directory "bbs" 说明bbs目录下面还有目录,不能直接拷贝


    解决办法:递归拷贝  命令:cp -r bbs ../backup/bbs    解释:-r 这个options是递归的意思



    举一反三:删除的时候也可能出现这种下面有文件不能删除的问题   也用-r 级联删除

                   chmod赋予权限的时候想级联也可以用-R 注意是大写的R

  • 使用itunes安装ipa文件

    2017-05-17 14:01:08

  • 如何看自己ip地址在Mac

    2017-04-11 17:04:14

  • 移动App崩溃原因

    2017-04-11 15:58:43

    转自:http://www.spasvo.com/news/html/201433180305.html

      移动App崩溃原因

      为什么移动App经常崩溃?App崩溃有几个原因:从平台或环境到开发问题。
      一些崩溃原因(排名不分先后) :
      设备碎片化:由于设备极具多样性,App在不同的设备上可能有表现不同。
      带宽限制:带宽不佳的网络对App所需的快速响应时间可能不够。
      网络的变化:不同网络间的切换可能会影响App的稳定性。
      内存管理:可用内存过低,或非授权的内存位置的使用可能会导致App失败。
      用户过多:连接数量过多可能会导致App崩溃。
      代码错误:没有经过测试的新功能,可能会导致App在生产环境中失败。
      第三方服务:广告或弹出屏幕可能会导致App崩溃。

      移动App崩溃的测试用例设计
      测试用例是移动测试最重要部分之一。
      准备和执行预先定义的针对移动App崩溃的测试用例将简化和加速移动App崩溃的测试。
      一些通用的触发移动App崩溃的测试场景,如下:
      1 验证在有不同的屏幕分辨率,操作系统和运营商的多个设备上的App行为。
      2 用新发布的操作系统版本验证App的行为。
      3 验证在如隧道,电梯等网络质量突然改变的环境中的App行为。
      4 通过手动网络从蜂窝更改到Wi-Fi ,或反过来,验证App行为。
      5 验证在没有网络的环境中的App行为。
      6 验证来电/短信和设备特定的警报(如警报和通知)时的App行为。
      7 通过改变设备的方向,以不同的视图模式,验证App行为。
      8 验证设备内存不足时的App行为。
      9 通过用测试工具施加载荷验证App行为。
      10 用不同的支持语言验证App行为。
      显然,还会有更多的导致App崩溃的App特定场景。

  • 无法安装IOS破解软件的解决方法

    2017-03-20 13:48:22

    执行命令sudo spctl --master-disable
431/3123>
Open Toolbar