遍历

理解PHP中的Generator

♀尐吖头ヾ 提交于 2019-12-17 01:42:56
PHP中Generator,似乎是在5.5版中引入了。 PHP中的协程必须依赖于Generator来实现,所以我觉得有必要先专门写一篇文章介绍Generator。 Generator这个单词在这里对应的中文词语应该是“生成器”,在编程这个领域,我们可以把它想象成一个可以生成一系列数据的工具,这个工具可以具体为一个类、一个函数或者是一个语句(由特殊的关键字构成),而且事实上也确实如此。在PHP中Generator是由函数生成的,但这个函数又跟普通的函数不同,具体有什么不同等会会慢慢道来。 我们先介绍Generator的另外一个特点,这个特点也是 php的官方文档 介绍Generator的第一句话:Generator提供了一种方便的实现简单的Iterator(迭代器)的方式,使用Generator实现Iterator不需要创建一个类来继承Iterator接口。 Iterator接口 所以如果想搞清楚Generator,需要先了解Iterator接口。我们通常使用foreach对数组进行遍历,如果要对对象进行遍历,那么这个对象的类就必须实现 Iterator 接口,并且实现Iterator接口所提供的5个方法: Iterator extends Traversable { /* Methods */ abstract public mixed current ( void ) /

服务器模型——从单线程阻塞到多线程非阻塞(中)

旧时模样 提交于 2019-12-16 23:54:48
https://blog.csdn.net/wangyangzhizhou/article/details/78899629 前言的前言 服务器模型涉及到线程模式和IO模式,搞清楚这些就能针对各种场景有的放矢。该系列分成三部分: * 单线程/多线程阻塞I/O模型 * 单线程非阻塞I/O模型 * 多线程非阻塞I/O模型,Reactor及其改进 前言 这里探讨的服务器模型主要指的是服务器端对I/O的处理模型。从不同维度可以有不同的分类,这里从I/O的阻塞与非阻塞、I/O处理的单线程与多线程角度探讨服务器模型。 对于I/O,可以分成阻塞I/O与非阻塞I/O两大类型。阻塞I/O在做I/O读写操作时会使当前线程进入阻塞状态,而非阻塞I/O则不进入阻塞状态。 对于线程,单线程情况下由一条线程负责所有客户端连接的I/O操作,而多线程情况下则由若干线程共同处理所有客户端连接的I/O操作。 单线程非阻塞I/O模型 多线程阻塞I/O模型通过引入多线程确实提高了服务器端的并发处理能力,但每个连接都需要一个线程负责I/O操作。当连接数量较多时可能导致机器线程数量太多,而这些线程大多数时间却处于等待状态,造成极大的资源浪费。鉴于多线程阻塞I/O模型的缺点,有没有可能用一个线程就可以维护多个客户端连接并且不会阻塞在读写操作呢?下面介绍单线程非阻塞I/O模型。 单线程非阻塞I/O模型最重要的一个特点是

遍历文件总结

早过忘川 提交于 2019-12-16 23:46:01
1.遍历主要用到os模块的walk和listdir两个模块。查看os源码不难发现,使用os.walk将返回遍历目录的路径,文件夹名,与文件名。listdir方法以list的数据结构返回文件名 2.源码分享,主要形式为三种. import collections import subprocess import platform import os # 获取指定目录下,指定格式的文件, Usage:get_all_files('/Case', '.yaml') def get_all_files(root: str, pattern: str)-> dict: extension_file = collections.OrderedDict() for root, dirs, files in os.walk(root): for filename in files: if filename.endswith(pattern): path = os.path.join(root, filename).replace('\\', '/') extension_file[filename] = path return extension_file # TODO:递归遍历指定目录,只获取文件名,待优化 def iter_files(path): filename = [] def

102_二叉树的层次遍历

时光怂恿深爱的人放手 提交于 2019-12-16 22:42:50
""" 给定一个二叉树,返回其按层次遍历的节点值。 (即逐层地,从左到右访问所有节点)。 例如: 给定二叉树: [3,9,20,null,null,15,7], 3 / \ 9 20 / \ 15 7 返回其层次遍历结果: [ [3], [9,20], [15,7] ] """ from TreeNode import TreeNode # 递归 def levelOrder ( root ) : ans = [ ] def helper ( temp ) : arr = [ ] ans_ = [ ] if not temp [ - 1 ] : return for node in temp [ - 1 ] : if node : ans_ . append ( node . val ) if node . left : arr . append ( node . left ) if node . right : arr . append ( node . right ) temp . append ( arr ) ans . append ( ans_ ) helper ( temp ) helper ( [ [ root ] ] ) return ans node1 = TreeNode ( 3 ) node2 = TreeNode ( 9 ) node3 = TreeNode

格间计算性能提升方案

左心房为你撑大大i 提交于 2019-12-16 17:38:43
一般情况下,如果报表中存在很多格间计算(即单元格之间的关联计算),那么通常会影响报表性能。这是因为: 1、格间计算很难分步骤编写,导致运算过程很难优化。 2、格间计算可能需要多次遍历单元格集才能完成运算。 3、格间计算往往要利用较多隐藏格作为中间变量。而隐藏格除格值外,还记录了很多与显示相关的属性值,比如:字体、颜色、显示方式等。即便设置了单元格隐藏,但这些属性还在,依然会占用内存,影响计算速度。 不过在润乾报表的集算脚本支持下,这个问题能够得到很好的解决。下面我们就通过一个典型的例子——《雇员销售情况排名》报表,来看下传统方式和润乾报表的对比: 报表要求如下: 按照员工姓名排序,根据订单总价计算排名,并且计算“和上一名的差距”。 一、传统实现方式 1、首先定义 sql 数据集 ds1,其 sql 如下: SELECT EMPLOYEE.EID,MAX(EMPLOYEE.NAME) 姓名,sum(订单明细. 数量 * 订单明细. 单价) 订单总价 FROM EMPLOYEE, 订单, 订单明细 WHERE 订单. 订单 ID = 订单明细. 订单 ID AND EMPLOYEE.EID = 订单. 雇员 ID group by EMPLOYEE.EID order by 姓名 可以看到,为了让输出结果要按姓名排序,SQL 中要写作“ORDER BY 姓名”。 2、报表设计 其中,

迭代器模式(Iterator Pattern)

戏子无情 提交于 2019-12-16 15:49:34
动机(Motivate): 在软件构建过程中,集合对象内部结构常常变化各异。但对于这些集合对象,我们希望在不暴露其内部结构的同时,可以让外部客户代码透明地访问其中包含的元素;同时这种“透明遍历”也为“ 同一种算法在多种集合对象上进行操作”提供了可能。 使用面向对象技术将这种遍历机制抽象为“迭代器对象”为“应对变化中的集合对象”提供了一种优雅的方法。 意图(Intent): 提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示。-------《设计模式》GOF 结构图(Struct): 适用性: 1 .访问一个聚合对象的内容而无需暴露它的内部表示。 2 .支持对聚合对象的多种遍历。 3 .为遍历不同的聚合结构提供一个统一的接口(即, 支持多态迭代)。 生活中的例子: 迭代器提供一种方法顺序访问一个集合对象中各个元素,而又不需要暴露该对象的内部表示。在早期的电视机中,一个拨盘用来改变频道。当改变频道时,需要手工转动拨盘移过每一个频道,而不论这个频道是否有信号。现在的电视机,使用[后一个]和[前一个]按钮。当按下[后一个]按钮时,将切换到下一个预置的频道。想象一下在陌生的城市中的旅店中看电视。当改变频道时,重要的不是几频道,而是节目内容。如果对一个频道的节目不感兴趣,那么可以换下一个频道,而不需要知道它是几频道。 代码实现: 在面向对象 的软件设计中

遍历数组中的元素(含es6方法)

我的梦境 提交于 2019-12-16 15:22:57
  假如有这样一个数组。arr = [12,34,45,46,36,58,36,59],现在要遍历该数组。   方法1:以前我们可能会这样做: for(var i=0;i<arr.length;i++){ console.log(arr[i]+"\n") }   方法2:自ES5发布后,我们可以使用内置的forEach方法来遍历数组。  arr.forEach(function(val){ console.log(val+"\n") })   这段代码看起来简单,然而有些缺陷,就是不能使用break语句中断循环,也不能使用return语句返回到外层函数。   方法3:于是我们很容易想到使用for-in来遍历数组  for(var index in arr){ console.log(arr[index]+"\n") } 然而这样也会有一点问题, 在这段代码中,赋给 index 的值不是实际的数字,而是字符串 “0” 、 “1” 、 “2” ,此时很可能在无意之间进行字符串算数计算,例如:“2”+1==“21”,这给编码带来极大的不便。还有, 在某些情况下,这段代码可能按照随机顺序遍历数组元素。    方法4:下面我的ES6方法登场了,就是使用for-of方法。 for(var val of arr){ console.log(val+"\n") }   是不是很简洁

二叉树的非递归遍历

為{幸葍}努か 提交于 2019-12-16 13:53:10
https://yuanyu.blog.csdn.net/article/details/102639318 144. 二叉树的前序遍历: https://leetcode-cn.com/problems/binary-tree-preorder-traversal/ 94. 二叉树的中序遍历: https://leetcode-cn.com/problems/binary-tree-inorder-traversal/ 145. 二叉树的后序遍历: https://leetcode-cn.com/problems/binary-tree-postorder-traversal/ 1 系统栈调用过程 2 coding public class TreeNode { int val; TreeNode left; TreeNode right; TreeNode(int x) { val = x; } } /** * 144. 二叉树的前序遍历:https://leetcode-cn.com/problems/binary-tree-preorder-traversal/ * 94. 二叉树的中序遍历:https://leetcode-cn.com/problems/binary-tree-inorder-traversal/ * 145. 二叉树的后序遍历:https:/

关于GC(下):CMS和G1GC的比较

半世苍凉 提交于 2019-12-16 11:53:20
简称 STW —— Stop the World,暂停所有在执行的线程 简史 2004年Sun实验室第一次发表G1论文 JDK6U14中第一次作为实验选项引入 JDK7中开始作为替换CMS的方案 JDK9中成为默认的垃圾回收器 JDK10优化,将其fullGC改为并行: JEP307 JDK11引入了更新的ZGC,可能会成为G1的潜在替代者 G1特有数据结构和算法 Region 堆仍然有新生代(eden、survivor)、老年代的划分,但是不再要求它们是内存连续的。每个区都由多个Region组成。 部分老年代Region存储Humongous对象(即下图的H),这种对象大小大于等于Region的一半。 ( 图片来源-Java Hotspot G1 GC的一些关键技术 ) SATB算法 全称Snapshot-At-The-Beginning,起始时活对象的快照。在理解SATB前需要先了解以下知识。 三色标记法 CMS和G1的算法都是通过对gc root 进行遍历,并进行三色标记。标记规则为 黑色(black): 节点被遍历完成,而且子节点都遍历完成。 灰色(gray): 当前正在遍历的节点,而且子节点(即对象的域)还没有遍历。遍历完所有子节点后,将成为黑色 白色(white): 还没有遍历到的节点,即灰色节点的子节点。扫描结束仍是白色时会被回收。 并发扫描时

leetcode-16. 最接近的三数之和

瘦欲@ 提交于 2019-12-16 11:42:47
题目 给定一个包括 n 个整数的数组 nums 和 一个目标值 target。找出 nums 中的三个整数,使得它们的和与 target 最接近。返回这三个数的和。假定每组输入只存在唯一答案。 例如,给定数组 nums = [-1,2,1,-4], 和 target = 1. 与 target 最接近的三个数的和为 2. (-1 + 2 + 1 = 2). 思路 标签:排序和双指针 本题目因为要计算三个数,如果靠暴力枚举的话时间复杂度会到 O(n^3) ,需要降低时间复杂度 首先进行数组排序,时间复杂度 O(nlogn) 在数组 nums 中,进行遍历,每遍历一个值利用其下标i,形成一个固定值 nums[i] 再使用前指针指向 start = i + 1 处,后指针指向 end = nums.length - 1 处,也就是结尾处 根据 sum = nums[i] + nums[start] + nums[end] 的结果,判断 sum 与目标 target 的距离,如果更近则更新结果 ans 同时判断 sum 与 target 的大小关系,因为数组有序,如果 sum > target 则 end--,如果 sum < target 则 start++,如果 sum == target 则说明距离为 0 直接返回结果 整个遍历过程,固定值为 n 次,双指针为 n 次,时间复杂度为