首页 文章 精选 留言 我的

精选列表

搜索[学习],共10000篇文章
优秀的个人博客,低调大师

【Android进阶学习】底部Tab的两种实现方式

先写上代码,稍后在写分析的................... 第一种: 下面的tabs.xml布局文件中,整个布局是垂直显示的,分为FrameLayout和TabWidget上下两部分,在FrameLayout布局里面使用layout_weight=“1” ,而TabWidget没有设置这个属性,那就默认为0。那么在这布局中,FrameLayout就按比例分得整个屏幕的3/4,而没有设置layout_weight属性的TabWidget只是占用刚好能显示自己空间大小的位置。这样的话,就能达到就Tab置于底部了。 layout_weight具体可以看看http://liangruijun.blog.51cto.com/3061169/632532里面的FrameLayout布局 tabs.xml <?xmlversion="1.0"encoding="utf-8"?> <TabHostxmlns:android="http://schemas.android.com/apk/res/android" android:id="@android:id/tabhost" android:layout_width="fill_parent" android:layout_height="fill_parent" > <LinearLayout android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <FrameLayout android:id="@android:id/tabcontent" android:layout_width="fill_parent" android:layout_height="match_parent" android:layout_weight="1" > <TextView android:id="@+id/view1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="nihao" /> <TextView android:id="@+id/view2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="nihenhao" /> </FrameLayout> <TabWidget android:id="@android:id/tabs" android:layout_width="fill_parent" android:layout_height="wrap_content" /> </LinearLayout> </TabHost> main.xml <?xmlversion="1.0"encoding="utf-8"?> <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" /> </LinearLayout> TestHostActivity.java packagecom.lingdududu.test; importandroid.app.TabActivity; importandroid.os.Bundle; importandroid.widget.TabHost; publicclassTestHostActivityextendsTabActivity{ /**Calledwhentheactivityisfirstcreated.*/ @Override publicvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.tabs); TabHosttabhost=getTabHost(); tabhost.addTab(tabhost.newTabSpec("111").setIndicator("view1").setContent(R.id.view1)); tabhost.addTab(tabhost.newTabSpec("222").setIndicator("view2").setContent(R.id.view2)); } } 效果: 第二种: 在LinerLayout布局里面嵌套FrameLayout和RelativeLayout布局,将TabWidget放置在RelativeLayout里面,之后设置RelativeLayout的android:layout_alignParentBottom="true"属性,这个属性的功能是将TabWidget置于父元素(也就是LinerLayout)的底部。这样就能将Tab置于底部了。 <?xmlversion="1.0"encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TabHost android:id="@+id/tabhost" android:layout_width="fill_parent" android:layout_height="fill_parent"> <FrameLayout android:id="@android:id/tabcontent" android:layout_width="fill_parent" android:layout_height="fill_parent" android:paddingBottom="62px" > <TextView android:id="@+id/tab1" android:layout_width="fill_parent" android:layout_height="fill_parent" android:text="这是TabOne" /> <TextView android:id="@+id/tab2" android:layout_width="fill_parent" android:layout_height="fill_parent" android:text="这是TabTwo"/> </FrameLayout> <RelativeLayout android:layout_width="fill_parent" android:layout_height="fill_parent" > <TabWidget android:id="@android:id/tabs" android:layout_alignParentBottom="true" android:layout_width="fill_parent" android:layout_height="65.0px" android:background="@drawable/tab_bg" /> </RelativeLayout> </TabHost> </LinearLayout> main.xml <?xmlversion="1.0"encoding="utf-8"?> <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" /> </LinearLayout> TabHostActivity.java packagecom.lingdududu.test; importandroid.app.Activity; importandroid.os.Bundle; importandroid.widget.TabHost; publicclassTabHostActivityextendsActivity{ publicvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.tabs); TabHosttabs=(TabHost)findViewById(R.id.tabhost); tabs.setup(); TabHost.TabSpecspec=tabs.newTabSpec("tag1"); spec.setContent(R.id.tab1); spec.setIndicator("TabOne"); tabs.addTab(spec); spec=tabs.newTabSpec("tag2"); spec.setContent(R.id.tab2); spec.setIndicator("TabTwo"); tabs.addTab(spec); tabs.setCurrentTab(0); } } 效果图: 本文转自 lingdududu 51CTO博客,原文链接: http://blog.51cto.com/liangruijun/747173

优秀的个人博客,低调大师

Spark RDD概念学习系列之RDD的checkpoint(九)

RDD的检查点 首先,要清楚。为什么spark要引入检查点机制?引入RDD的检查点? 答:如果缓存丢失了,则需要重新计算。如果计算特别复杂或者计算耗时特别多,那么缓存丢失对于整个Job的影响是不容忽视的。为了避免缓存丢失重新计算带来的开销,Spark又引入检查点机制。 RDD的缓存能够在第一次计算完成后,将计算结果保存到内存、本地文件系统或者Tachyon(分布式内存文件系统)中。通过缓存,Spark避免了RDD上的重复计算,能够极大地提升计算速度。但是,如果缓存丢失了,则需要重新计算。如果计算特别复杂或者计算耗时特别多,那么缓存丢失对于整个Job的影响是不容忽视的。为了避免缓存丢失重新计算带来的开销,Spark又引入检查点(checkpoint)机制。 RDD的缓存和RDD的checkpoint的区别 RDD的缓存是在计算结束后,直接将计算结果通过用户定义的存储级别(存储级别定义了缓存存储的介质,现在支持内存、本地文件系统和Tachyon)写入不同的介质。 而RDD的检查点不同,它是在计算完成后,重新建立一个Job来计算。 为了避免重复计算,推荐先将RDD缓存,这样就能保证检查点的操作可以快速完成。 RDD的checkpoint的处理 在缓存没有命中的情况下,首先会判断是否保存了RDD的checkpoint,如果有,则读取checkpoint。为了理解checkpoint的RDD是如何读取计算结果的,需要先看一下checkpoint的数据是如何写入的。 首先在Job结束后,会判断是否需要checkpoint。如果需要,就调用org.apache.spark.rdd.RDDCheckpointData#doCheckpoint。doCheckpoint首先为数据创建一个目录;然后启动一个新的Job来计算,并且将计算结果写入新创建的目录;接着创建一个org.apache.spark.rdd.CheckpointRDD;最后,原始RDD的所有依赖被清除,这就意味着RDD的转换的计算链(compute chain)等信息都被清除。这个处理逻辑中,数据写入的实现在org.apache.spark.rdd.CheckpointRDD$#writeToFile。 简要的核心逻辑如下: //创建一个保存checkpoint数据的目录 val path = new Path(rdd.context.checkpointDir.get, "rdd-" + rdd.id) val fs = path.getFileSystem(rdd.context.hadoopConfiguration) if (!fs.mkdirs(path)) { throw new SparkException("Failed to create checkpoint path " + path) }//创建广播变量 val broadcastedConf = rdd.context.broadcast( new SerializableWritable(rdd.context.hadoopConfiguration))//开始一个新的Job进行计算,计算结果存入路径path中 rdd.context.runJob(rdd, CheckpointRDD.writeToFile[T](path.toString, broadcastedConf) _)//根据结果的路径path来创建CheckpointRDD val newRDD = new CheckpointRDD[T](rdd.context, path.toString)//保存结果,清除原始RDD的依赖、Partition信息等 RDDCheckpointData.synchronized { cpFile = Some(path.toString) cpRDD = Some(newRDD) // RDDCheckpointData对应的CheckpointRDD rdd.markCheckpointed(newRDD) //清除原始RDD的依赖,Partition cpState = Checkpointed //标记checkpoint的状态为完成 } 至此,RDD的checkpoint完成,其中checkpoint的数据可以通过checkpointRDD的readFromFile读取。但是,上述逻辑在清除了RDD的依赖后,并没有和check-pointRDD建立联系。 那么Spark是如何确定一个RDD是否被checkpoint了,而且正确读取checkpoint的数据呢? 答案就在org.apache.spark.rdd.RDD#dependencies的实现,它会首先判断当前的RDD是否已经Checkpoint过,如果有,那么RDD的依赖就变成了对应的Ch eckpointRDD: privatedefcheckpointRDD: Option[RDD[T]]=checkpointData.flatMap(_.checkpointRDD) final def dependencies: Seq[Dependency[_]] = { checkpointRDD.map(r => List(new OneToOneDependency(r))).getOrElse { if (dependencies_ == null) { //没有checkpoint dependencies_ = getDependencies } dependencies_ } } 理解了Checkpoint的实现过程。 接下来看一下computeOrReadCheckpoint的实现。前面提到了,它一共在两个地方被调用,org.apache.spark.rdd.RDD#iterator和org.apache.spark.CacheManager#getOrCompute。它实现的逻辑比较简单,首先检查当前RDD是否被Checkpoint过,如果有,读取Checkpoint的数据;否则开始计算。 实现如下: private[spark] def computeOrReadCheckpoint(split: Partition, context: TaskContext) : Iterator[T] = { if (isCheckpointed) firstParent[T].iterator(split, context) else compute(split, context) } firstParent[T].iterator(split,context)会调用对应CheckpointRDD的iterator,最终调用到它的compute: override def compute(split: Partition, context: TaskContext): Iterator[T] = { val file=new Path(checkpointPath, CheckpointRDD.splitIdToFile(split.index)) CheckpointRDD.readFromFile(file, broadcastedConf, context) // 读取Checkpoint的数据 } 本文转自大数据躺过的坑博客园博客,原文链接:http://www.cnblogs.com/zlslch/p/5723758.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

Spark RDD概念学习系列之RDD是什么?(四)

RDD是什么? 通俗地理解,RDD可以被抽象地理解为一个大的数组(Array),但是这个数组是分布在集群上的。详细见 Spark的数据存储 Spark的核心数据模型是RDD,但RDD是个抽象类,具体由各子类实现,如MappedRDD、 ShuffledRDD等子类。 Spark将常用的大数据操作都转化成为RDD的子类。 官方对RDD的解释是:弹性分布式数据集,全称是Resilient Distributed Datasets。RDD是只读的、分区记录的集合。RDD只能基于在稳定物理存储中的数据集和其他已有的RDD上执行确定性操作来创建。这些确定性操作称为转换,如map、filter、groupBy、join。 RDD不需物化,RDD含有如何从其他RDD衍生(即计算)出本RDD的相关信息(即Lineage),因此在RDD部分分区数据丢失的时候可以从物理存储的数据计算出相应的RDD分区。 这个数据集的全部或部分可以缓存在内存中,在多次计算间重用。 所谓弹性,是指在内存不够时可以与磁盘进行交换。进一步见 细谈RDD的弹性 这设计了RDD的另一个特性:内存计算,就是将数据保存到内存中。同时为了解决内存容量限制问题,Spark为我们提供了最大的自由度,所有数据均可由我们来进行cache的设置,包括是否cache和如何cache。 RDD是基于工作集的应用抽象。 Hadoop MapReduce基于数据集的处理:从物理存储上加载数据,然后操作数据,然后写入物理存储设备。 基于数据集的操作不适应的场景: 1、 不适合于大量的迭代。 2、 交互式查询 重点是,基于数据流的方式,不能够复用曾经的结果或者中间计算结果。 简洁点来说, RDD是弹性分布式数据集的简称,其本身是一个抽象类,其内部实现包括以下五个部分,其中前三个是必备的: getPartitions方法:分区列表(数据块列表) compute方法(计算每个分片的函数) getDependencies方法(对父RDD的依赖列表) partitioner:key-value(键-值)RDD的分区器 getPreferredLocations方法:每个数据分片的预定义地址列表(如HDFS上的数据块的地址) 其中,前三个用于描述RDD间的Lineage信息,后两个可用于优化执行。 本文转自大数据躺过的坑博客园博客,原文链接:http://www.cnblogs.com/zlslch/p/5723446.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

Hadoop MapReduce概念学习系列之shuffle大揭秘(十九)

shuffle是非常重要!一定要深入理解和多实践。 缓存,分组,排序,转发,这些都是mr的shuffle。 Soga 我想得到按流量来排序,而且还是倒序,怎么达到实现呢?这就牵扯到排序的的问题 默认是根据key来排, 我想根据value里的某个排, 解决思路:将value里的某个,放到key里去,然后来排 下面,开始weekend110的hadoop的自定义排序实现 也要修改FlowBean代码 本文转自大数据躺过的坑博客园博客,原文链接:http://www.cnblogs.com/zlslch/p/5713701.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

Hadoop MapReduce概念学习系列之MPI和MapReduce(十三)

在当前最流行的高性能并行体系结构中比较常用的并行编程环境分为两类:消息传递和共享存储。MPI是基于消息传递的经典代表,是消息传递井行程序设计的标准,用于构建高可靠的、可伸缩的、灵活的分布式应用程消息传递井行处理开销比较大,适合于大粒度的进程级并行计算,相对其他并行编程环境,它具有很好的可移植性,几乎能被所有的并行环境支持;还具有很好的可扩展性,具有完备的异步通信功能,能按照用户的要求很好地分解问题,组织不同进程之间进行数据交换,适合大规模可扩展性的并行算法。MPI模式在学术研究领域应用较多,而在商业领域,云计算系统大多采用的是Google云计算系统中的MapReduce并行编程模型。云计算强调的就是简单的编程模型,而MapReduce就是一种高效的、简单的并行编程模式,也是一种高效的任务调度器。MapReduce这种编程模型不仅适用于云计算,在多核和多处理器、Cell processor以及异构机群上同样有良好的性能。利用MapReduce ,程序员能够轻松地编写紧耦合的程序,在运行时能高效地调度和执行任务,在实现时,在Map函数中指定对各分块数据的处理过程,在Reduce函数中指定如何对分块数据处理的中问结果进行归约。用户只需要指定Map和Reduce函数来编写分布式的并行程序,不需要关心如何将输人的数据分块、分配和调度,同时系统还将处理集群内节点失败及节点间通信的管理等。而MPI仅仅是一个并行计算标准,没有相应的分布式文件系统的支撑,在大数据场景下大文件的存储及访问都会成为一个问题,同时用户还需要考虑集群节点之间的通信协调、容错等问题,这些使得MPI的编程难度比较大,集群本身的规模也很难做到像MapReduce那样的超大规模。 本文转自大数据躺过的坑博客园博客,原文链接:http://www.cnblogs.com/zlslch/p/5080596.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

Hadoop概念学习系列之Hadoop的几点优点(六)

任何软件,特别对于开源软件和系统而言,有优点和缺点,这是再平常不过呢?为什么这么说,开源出来,需要更多人去共同开发和修改,这样,才可以站住开源世界的领先者。 1. 高可靠性。Hadoop按位存储和处理数据的能力值得人们信赖。 2. 高扩展性。Hadoop是在可用的计算机集簇间分配数据完成计算任务的,这些集簇可以方便地扩展到数以千计的节点中。 3. 高效性。Hadoop能够在节点之间动态地移动数据,以保证各个节点的动态平衡,因为以其处理速度非常快。 4. 高容错性。Hadoop能够自动保存数据的多份副本,并且能够自动将失败的任务重新分配。 本文转自大数据躺过的坑博客园博客,原文链接:http://www.cnblogs.com/zlslch/p/5058178.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

《从零开始学Swift》学习笔记(Day 36)——静态方法

静态方法与静态属性类似,Swift中定义了静态方法,也称为类型方法。静态方法的定义与静态属性类似,枚举和结构体的静态方法使用的关键字是static;类静态方法使用的关键字是class或static,如果使用static定义,则该方法不能在子类中被重写(override);如果使用class定义,则该方法可以被子类重写。 结构体静态方法 看一个结构体静态方法的示例,代码如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 structAccount{ varowner:String= "Tony" //声明实例属性账户名 static varinterestRate:Double= 0.0668 //声明静态属性利率 static funcinterestBy(amount:Double)->Double{ //定义静态方法 return interestRate*amount } funcmessageWith(amount:Double)->String{ //定义实例方法 letinterest=Account.interestBy(amount) return "\(self.owner)的利息是\(interest)" } } //调用静态方法 print(Account.interestBy(10_000. 00 )) varmyAccount=Account() //调用实例方法 print(myAccount.messageWith(10_000. 00 )) 枚举静态方法 看一个枚举静态方法的示例,代码如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 enum Account{ case 中国银行 case 中国工商银行 case 中国建设银行 case 中国农业银行 static varinterestRate:Double= 0.0668 //声明静态属性利率 static funcinterestBy(amount:Double)->Double{ //定义静态方法 return interestRate*amount } } //调用静态方法 print(Account.interestBy(10_000. 00 )) //调用静态方法 从示例可以看出,结构体和枚举的静态方法使用定义没有区别。 类静态方法 看一个类静态方法的示例,代码如下: 1 2 3 4 5 6 7 8 9 10 11 class Account{ varowner:String= "Tony" //账户名 //可以换成static class funcinterestBy(amount:Double)->Double{ //使用关键字class定义静态方法 return 0.08886 *amount } } //调用静态方法 print(Account.interestBy(10_000. 00 )) //调用静态方法 本文转自 tony关东升 51CTO博客,原文链接:http://blog.51cto.com/tonyguan/1746990,如需转载请自行联系原作者

优秀的个人博客,低调大师

Hadoop MapReduce概念学习系列之MapReduce的特点(八)

MapReduce 为什么如此受欢迎?尤其现在互联网+时代,互联网+公司都在使用 MapReduce。MapReduce 之所以如此受欢迎,它主要有以下几个特点。 1、MapReduce易于编程。它简单的实现一些接口,就可以完成一个分布式程序,这个分布式程序可以分布到大量廉价的 PC 机器运行。也就是说你写一个分布式程序,跟写一个简单的串行程序是一模一样的。 就是因为这个特点使得 MapReduce 编程变得非常流行。 2、良好的扩展性。当你的计算资源不能得到满足的时候,你可以通过简单的增加机器来扩展它的计算能力。 3、高容错性。MapReduce 设计的初衷就是使程序能够部署在廉价的 PC 机器上,这就要求它具有很高的容错性。比如其中一台机器挂了,它可以把上面的计算任务转移到另外一个节点上面上运行,不至于这个任务运行失败,而且这个过程不需要人工参与,而完全是由 Hadoop 内部完成的。 4、适合 PB 级以上海量数据的离线处理。这里加红字体离线处理,说明它适合离线处理而不适合在线处理。比如像毫秒级别的返回一个结果,MapReduce 很难做到。 MapReduce 虽然具有很多的优势,但是它也有不擅长的地方。这里的不擅长不代表它不能做,而是在有些场景下实现的效果差,并不适合 MapReduce 来处理,主要表现在以下几个方面。 1、实时计算。MapReduce 无法像 Mysql 一样,在毫秒或者秒级内返回结果。 2、流式计算。流式计算的输入数据时动态的,而 MapReduce 的输入数据集是静态的,不能动态变化。这是因为 MapReduce 自身的设计特点决定了数据源必须是静态的。 3、DAG(有向图)计算。多个应用程序存在依赖关系,后一个应用程序的输入为前一个的输出。在这种情况下,MapReduce 并不是不能做,而是使用后,每个MapReduce 作业的输出结果都会写入到磁盘,会造成大量的磁盘IO,导致性能非常的低下。 MapReduce 定义 Hadoop 中的 MapReduce 是一个使用简单的软件框架,基于它写出来的应用程序能够运行在由上千个商用机器组成的大型集群上,并以一种可靠容错式并行处理TB级别的数据集。 MapReduce 来源 Hadoop MapReduce 源于 Google 在2004年12月份发表的 MapReduce 论文。 Hadoop MapReduce 其实就是 Google MapReduce 的一个克隆版本。 本文转自大数据躺过的坑博客园博客,原文链接:http://www.cnblogs.com/zlslch/p/5058757.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

Storm概念学习系列之Tuple元组(数据载体)

Tuple元组 Tuple 是 Storm 的主要数据结构,并且是 Storm 中使用的最基本单元、数据模型和元组。 Tuple 描述 Tuple 就是一个值列表, Tuple 中的值可以是任何类型的,动态类型的Tuple的fields可以不用声明;默认情况下,Storm中的Tuple支持私有类型、字符串、字节数组等作为它的字段值,如果使用其他类型,就需要序列化该类型。 Tuple的字段默认类型有 :integer、 float、 double、 long、short、 string、 byte、 binary(byte[])。 Tuple元组,是消息传递的基本单元,是一个命名的值列表,元组中的字段可以是任何类型的对象。Storm使用元组作为其数据模型,元组支持所有的基本类型、字符串和字节数组作为字段值,只要实现类型的序列化接口就可以使用该类型的对象。 元组本来应该是一个key-value的Map,但是由于各个组件间传递的元组的字段名称已经事先定义好,所以只要按序把元组填入各个value即可,所以元组是一个vlue的List。 Tuple是Storm采用的数据表示模型,所有的数据都以Tuple的形式在各个组件之间流动。Tuple是一组字段列表,每个字段由一个字段名和字段值组成,每个Tuple类似于数据库中的一行记录。在默认的情况下,Tuple的字段类型可以是integer、long、short、byte、string、double、float、boolean和byte array。当然,你也可以通过实现序列化器自定义类型。 Tuple 数据结构如图 1 所示。 图 1 Tuple 数据结构 Tuple 可以理解成键值对。例如,创建一个Bolt 要发送两个字段(命名为 double 和 triple),其中键就是定义在declareOutputFields 方法中的 Fields 对象,值就是在 emit 方法中发送的 Values 对象。 以下是一个简单例子 public class DoubleAndTripleBolt extends BaseRichBolt { OutputCollectorBase _collector; @Override public void prepare(Map conf, TopologyContext context, OutputCollectorBase collector) { _collector = collector; } @Override public void execute(Tuple input) { int val = input.getInteger(0); _collector.emit(input, new Values(val*2, val*3)); _collector.ack(input); } @Override public void declareOutputFields(OutputFieldsDeclarer declarer) { declarer.declare(new Fields("double", "triple")); }} 此外,在使用的 Storm Java 包中, backtype.storm.tuple 主要有以下几个类: Fileds.class MessageId.class Tuple.class TupleImpl.class Values.class 列出以上内容是为了更好地理解 Tuple,这样能够从本质上理解 Tuple,在使用时更加得心应手。 Tuple 的生命周期 了解一个 Tuple 的生命周期就需要查看源码,如下的 Java 代码展示了 Spout(消息源)接口发出 Tuple(消息)的整个过程。 public interface ISpout extends Serializable { void open(Map conf, TopologyContext context, SpoutOutputCollector collector); void nextTuple(); void ack(Object msgId); void fail(Object msgId); void close(); } 首 先, Storm 调 用 Spout(消息源)的nextTuple 方法来获取下一个Tuple,Spout通过Open 方法的参数提供的SpoutOutputCollector将新Tuple发射到其中一个输出消息流。 注意:发射Tuple 时, Spout提供一个message-id,通过这个ID 来追踪该Tuple。 接下来, Storm跟踪该Tuple的树形结构是否成功创建,并根据 messageid调用Spout中的ack函数,以确认Tuple是否被完全处理。如果Tuple超时,则调用 Spout 的 fail 方法。 由此看出,同一个Tuple不管是acked,还是failed都是由创建它的Spout发出并维护的,所以,即使Spout 在集群环境中同时执行很多的任务,该Tuple 也不会被其他任务调用或生成 acked或 failed 状态。总之, Storm会利用内部的 Acker 机制保证每个Tuple 被可靠地处理。最后,在任务完成后,Spout调用Close方法结束 Tuple 的使命。 比如 本文转自大数据躺过的坑博客园博客,原文链接:http://www.cnblogs.com/zlslch/p/5989281.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

8、周期性任务、find、break和continue 学习笔记

find [options] [查找路径] [查找条件] [处理动作] 查找路径:默认为当前目录 查找条件:默认为查找指定路径下的所有文件 处理动作:默认为显示 查找条件: -name "文件名称" 支持使用globbing正则表达式 -iname "文件名称" 查找时不区分字符大小写 -user UserName 根据属主查找 -group GroupName 根据属组查找 -uid UID 根据uid查找 -gid GID 根据gid查找 -nouser 查找没有属主的文件 -nogroup 查找没有属组的文件 组合条件: -a 与,同时满足 -o 或,满足其一 -not, ! 非,取反 -type: 根据文件类型查找 f: 普通文件 d: 目录 b: 块设备 c: 字符设备 l: 符号链接文件 p: 命名管道 s: 套接字 -size: 根据文件大小查找(常用单位:k, M, G) -#M 查找所有文件大小小于#M的文件 +#M 查找所有文件大小大于#M的文件 #M 查找所有文件大小等于#M的文件 根据时间戳查找: 以天为单位(time): -atime -mtime -ctime +# 查找(#+1)天之外被访问过的文件 -# 查找#天之内被访问过的文件 查找短于(#+1)> x >=#天的时间段被访问过 以分钟为单位(min): -amin -mmin -cmin +# 查找(#+1)分之外被访问过的文件 -# 查找#天之分被访问过的文件 查找短于(#+1)> x >=#分的时间段被访问过 根据权限查找: -perm [+|-]MODE MODE 精确匹配 +MODE 任何一类用户的任何一位权限匹配;常用于查找某类用户的某特定权限是否存在; -MODE 每类用户的指定要检查的权限位都匹配; 文件权限:644 -perm 600 否,因为不匹配644 -perm +222 是,因为任何一位有2权限 -perm +002 否,因为任何一位的权限都不匹配 -perm -444 是,因为每位的4权限都匹配 练习: 1、查找/var/目录属主为root且属组为mail的所有文件; # find /var/ -user root -a -group mail 2、查找/usr目录下不属于root、bin或hadoop的所用文件; # find /usr/ -not -user root -a -not -user bin -a -not -user hadoop # find /usr/ -not \( -user root -o -user bin -o -user hadoop \) 3、查找/etc/目录下最近一周内其内容修改过的,且不属于root或hadoop的文件; # find /etc/ -mtime -7 -a -not -user root -a -not -user hadoop # find /etc/ -mtime -7 -a -not \( -user root -o -user hadoop \) 4、查找当前系统上没有属主或属组,且最近1个月内曾被访问过的文件; # find / \( -nouser -o -nogroup \) -a -atime -30 5、查找/etc/目录下大于1M且类型为普通文件的所有文件; # find /etc/ -size +1M -a -type f 6、查找/etc/目录所有用户都没有写权限的文件; # find /etc/ -not -perm +222 所有都没有:相反:任何一个有 所有都有:相反:至少有一个没有 7、查找/etc/目录下至少有一类用户没有写权限; # find /etc/ -not -perm -222 8、查找/etc/init.d/目录下,所有用户都有执行权限且其它用户有写权限的文件; # find /etc/init.d/ -perm -113 处理动作: -print 默认打印在标准输出上 -ls 以长格式输出各文件信息 -exec COMMAND {} \; 对查找到的文件执行指定的命令 -ok COMMAND {} \; 交互式的-exec; | xargs COMMAND find补充材料(摘自互联网): find与xargs 在使用find命令的-exec选项处理匹配到的文件时, find命令将所有匹配到的文件一起传递给exec执行。但有些系统对能够传递给exec的命令长度有限制,这样在find命令运行几分钟之后,就会出现 溢出错误。 错误信息通常是“参数列太长”或“参数列溢出”。这就是xargs命令的用处所在,特别是与find命令一起使用。 find命令把匹配到的文件传递给xargs命令,而xargs命令每次只获取一部分文件而不是全部,不像-exec选项那样。这样它可以先处理最先获取的一部分文件,然后是下一批,并如此继续下去。 在有些系统中,使用-exec选项会为处理每一个匹配到的文件而发起一个相应的进程,并非将匹配到的文件全部作为参数一次执行;这样在有些情况下就会出现进程过多,系统性能下降的问题,因而效率不高; 而使用xargs命令则只有一个进程。另外,在使用xargs命令时,究竟是一次获取所有的参数,还是分批取得参数,以及每一次获取参数的数目都会根据该命令的选项及系统内核中相应的可调参数来确定。 文件的特殊权限: 可执行文件:suid 任何用户执行此可执行文件时,不再以用户自己的身份当作进程的属主,而是以文件的属主当作进程的属主 suid表现为文件属主执行权限位上的s或S,有执行权限的为s而没有执行权限的为S 如何设定suid权限: chmod u+s FILE 目录文件:sgid 具有sgid的目录,用户在此目录下创建文件时,新建文件的属组不再是用户所属的基本组,而是目录的属组 sgid表现为文件属组执行权限位上的s或S,有执行权限的为s而没有执行权限的为S 如何设定sgid权限: chmod g+s FILE ... 粘滞位:sticky 对于公共可写的目录,用户可创建文件,可以删除自己的文件,但无法删除别的用户的文件 sticky表示为文件其它用户执行权限位上的t或T,,有执行权限的为t而没有执行权限的为T 如何设定sticky权限: chmod o+t FILE ... 练习: 1、复制cat命令至/tmp目录,普通用户使用/tmp/cat命令能查看root用户有权限查看的所有文件 cp `which cat` /tmp/ cp /etc/shadow /tmp/ chmod u+s cat 2、新建/tmp/test目录: 要求openstack和docker用户对其有写权限,且在目录创建的文件的属组都为cloud组 要求每个用户不能删除别人的文件,但可以编辑 mkdir /tmp/test groupadd cloud useradd -G cloud openstack useradd -G cloud docker chmod g+w /tmp/test/ chown :cloud /tmp/test chmod g+s test/ Linux任务计划: 一次性任务执行:at 周期性任务执行:crontab 一次性任务执行: at: 交互式:让用户在at>提示符输入多个要执行命令; at TIME at> Ctrl+d:提交任务; 批处理:将任务的各命令写入文件由at进行调用; at -f /path/to/at_job_file TIME at作业有队列:使用单个字母表示 查看作业:at -l = atq 删除一个尚未执行的作业: at -d job_num atrm job_num 任务计划的执行结果会通过邮件的方式发送给任务提交者; mail命令: 交互模式接收邮件; 交互模式发送邮件: -s "Subject" < /path/to/somefile 周期性任务计划:cron crond: 守护进程 服务进程: 阻塞,轮询 系统cron: 文件:/etc/crontab 用户cron: /var/spool/cron/UserName /etc/crontab文件:每行定义一个独立的任务; SHELL=/bin/bash PATH=/sbin:/bin:/usr/sbin:/usr/bin MAILTO=root HOME=/ # For details see man 4 crontabs # Example of job definition: # .---------------- minute (0 - 59) # | .------------- hour (0 - 23) # | | .---------- day of month (1 - 31) # | | | .------- month (1 - 12) OR jan,feb,mar,apr ... # | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat # | | | | | # * * * * * user-name command to be executed 时间表示法: 1、每个时间位都应该使用其可用的有效取值范围内的值; 2、某时间位上的*表示对应位的所有有效取值; 3、-: 连续的时间相邻点取值; 4、,: 离散的时间点取值; 5、/#:表示在指定时间范围内每隔#一次; 注意:通过输出重定向而拒收邮件: 将执行结果重定向到/dev/null &> /dev/null 将邮件发给空用户 MAILTO="" 用户cron: 使用crontab命令来实现 -l: 查看自己的cron任务列表; -e: 通过EDITOR变量中定义的编辑器打开用户自己的cron配置文件; 编辑单独的任务都使用-e选项,无论是删除、修改还是新建; -r: 移除crontab文件 如果是管理员: -u UserName:为别的用户配置crontab作业; # crontab -e -u docker 提醒:如果在crontab的用户命令中使用%,得转义为\% 5 3 * * * /bin/touch ~/testfile_`date +\%Y-\%m-\%d`.txt 在使用单引号后,%也可以不用转义 5 3 * * * /bin/touch ~/testfile_`date +'%Y-%m-%d'`.txt 练习: 1、每3分钟执行一个“echo "how are you?"; 2、每周2、4、6备份/etc/目录至/backup目录中,备份的文件名以当etc_开头并跟上当日的日期作为文件名; 3、每天6、9、12、15、18查看一下当前系统挂载的所有文件系统,并将查看的结果追加至/tmp/mounts.txt文件中; 4、每天每两小时取当前系统内存空间余量,将其保存至/stats/memory.txt文件中; crontab文件的格式: 空白行会被忽略 # 开头的行是注释; 1、*/3 * * * * /bin/echo "how are you?" 2、3 2 * * 2,4,6 /bin/tar -Jcf /backup/etc_`date '+%F'`.tar.xz /etc/* 3、17 6,9,12,15,18 * * * /bin/mount >> /tmp/mounts.txt 4、34 */2 * * * /bin/grep "^MemFree:" /proc/meminfo >> /stats/memory.txt 如何实现秒级别的任务: * * * * * for i in {0..4}; do /bin/echo "how are you?"; sleep 10; done facl: 文件访问控制列表 facl: 附加原有权限模型之上另一层权限控制机制,保存至文件扩展属性信息中; getfacl FILE 获取文件的权限信息 setfacl {-x|-m} 权限 FILE 设置文件的权限 -m: 设定权限 -m u:UserName:Perms -m g:GroupName:Perms -m m::Perms -x: 取消权限 -x u:UserName -x g:GroupName -x m: -R: 递归 bash编程之循环控制: for varName in LIST; do 循环体 done while CONDITION; do 循环体 done until CONDITION; do 循环体 done 循环控制: continue: 提前结束本次循环而开始评估下一轮; break [n]: 跳出当前循环 练习:提示用户输入用户名,显示用户的ID号;直到用户输入quit退出; #!/bin/bash # if [ $UID -ne 0 ]; then echo "`basename $0` must be running as root" exit 1 fi while true; do read -p "Enter a user name: " userName if [ "$userName" == 'quit' ]; then break fi id -u $userName done 练习:写一个脚本 1、提示用户输入一个目录路径; 2、显示目录下至少包含一个大写字母的文件名; #!/bin/bash # while true; do read -p "Enter a directory: " dirName [ "$dirName" == 'quit' ] && exit 3 [ -d "$dirName" ] && break || echo "Wrong directory..." done for fileName in $dirName/*; do if [[ "$fileName" =~ .*[[:upper:]]{1,}.* ]]; then echo "$fileName" fi done 本文转自开源殿堂 51CTO博客,原文链接http://blog.51cto.com/kaiyuandiantang/1943241:,如需转载请自行联系原作者

优秀的个人博客,低调大师

Android开发学习笔记:Intent的简介以及属性的详解

一.Intent的介绍 Intent的中文意思是“意图,意向”,在Android中提供了Intent机制来协助应用间的交互与通讯,Intent负责对应用中一次操作的动作、动作涉及数据、附加数据进行描述,Android则根据此Intent的描述,负责找到对应的组件,将 Intent传递给调用的组件,并完成组件的调用。Intent不仅可用于应用程序之间,也可用于应用程序内部的Activity/Service之间的交互。因此,可以将Intent理解为不同组件之间通信的“媒介”专门提供组件互相调用的相关信息。 二.Inten启动组件的方法 Intent可以启动一个Activity,也可以启动一个Service,还可以发起一个广播Broadcasts。具体方法如下: 组件名称 方法名称 Activity startActvity( ) startActivity( ) Service startService( ) bindService( ) Broadcasts sendBroadcasts( ) sendOrderedBroadcasts( ) sendStickyBroadcasts( ) 三.Intent的属性 Intent有以下几个属性: 动作(Action),数据(Data),分类(Category),类型(Type),组件(Compent)以及扩展信(Extra)。其中最常用的是Action属性和Data属性。 1.Intent的Action属性 Action是指Intent要完成的动作,是一个字符串常量。SDK中定义了一些标准的Action常量如下表所示。 Constant Target component Action ACTION_CALL activity Initiate a phone call. ACTION_EDIT activity Display data for the user to edit. ACTION_MAIN activity Start up as the initial activity of a task, with no data input and no returned output. ACTION_SYNC activity Synchronize data on a server with data on the mobile device. ACTION_BATTERY_LOW broadcast receiver A warning that the battery is low. ACTION_HEADSET_PLUG broadcast receiver A headset has been plugged into the device, or unplugged from it. ACTION_SCREEN_ON broadcast receiver The screen has been turned on. ACTION_TIMEZONE_CHANGED broadcast receiver The setting for the time zone has changed. 下面是一个测试Action常量的例子: main.xml <?xmlversion="1.0"encoding="utf-8"?> <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" /> <Button android:text="测试Action属性" android:id="@+id/getBtn" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> strings.xml <?xmlversion="1.0"encoding="utf-8"?> <resources> <stringname="hello">测试Action属性</string> <stringname="app_name">IntentActionDemo</string> </resources> MainActivity.java packagecom.android.action.activity; importandroid.app.Activity; importandroid.content.Intent; importandroid.os.Bundle; importandroid.view.View; importandroid.view.View.OnClickListener; importandroid.widget.Button; publicclassMainActivityextendsActivity{ privateButtongetBtn; @Override publicvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.main); getBtn=(Button)findViewById(R.id.getBtn); getBtn.setOnClickListener(newOnClickListener(){ @Override publicvoidonClick(Viewv){ Intentintent=newIntent(); intent.setAction(Intent.ACTION_GET_CONTENT);//设置IntentAction属性 intent.setType("vnd.android.cursor.item/phone");//设置IntentType属性 //主要是获取通讯录的内容 startActivity(intent);//启动Activity } }); } } 效果图: 2.Intent的Data属性 Intent的Data属性是执行动作的URI和MIME类型,不同的Action有不同的Data数据指定。比如:ACTION_EDIT Action应该和要编辑的文档URI Data匹配,ACTION_VIEW应用应该和要显示的URI匹配。 3.Intent的Category属性 Intent中的Category属性是一个执行动作Action的附加信息。比如:CATEGORY_HOME则表示放回到Home界面,ALTERNATIVE_CATEGORY表示当前的Intent是一系列的可选动作中的一个。下表是SDK文档中关于Category的信息。 Constant Meaning CATEGORY_BROWSABLE The target activity can be safely invoked by the browser to display data referenced by a link — for example, an image or an e-mail message. CATEGORY_GADGET The activity can be embedded inside of another activity that hosts gadgets. CATEGORY_HOME The activity displays the home screen, the first screen the user sees when the device is turned on or when the HOME key is pressed. CATEGORY_LAUNCHER The activity can be the initial activity of a task and is listed in the top-level application launcher. CATEGORY_PREFERENCE The target activity is a preference panel. 下面是一个回到Home界面的例子: main.xml <?xmlversion="1.0"encoding="utf-8"?> <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical"android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="测试IntentCategory" /> <Button android:id="@+id/Button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="转到Home界面" /> </LinearLayout> strings.xml <?xmlversion="1.0"encoding="utf-8"?> <resources> <stringname="hello">HelloWorld,MainActivity!</string> <stringname="app_name">IntentCategoryDemo</string> </resources> MainActivity.java packagecom.android.category.activity; importandroid.app.Activity; importandroid.content.Intent; importandroid.os.Bundle; importandroid.view.View; importandroid.view.View.OnClickListener; importandroid.widget.Button; publicclassMainActivityextendsActivity{ privateButtonbtn; @Override publicvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.main); btn=(Button)findViewById(R.id.Button1); btn.setOnClickListener(newOnClickListener(){ @Override publicvoidonClick(Viewv){ Intentintent=newIntent(); intent.setAction(Intent.ACTION_MAIN);//添加Action属性 intent.addCategory(Intent.CATEGORY_HOME);//添加Category属性 startActivity(intent);//启动Activity } }); } } 效果图: 4.Intent的Type属性 Intent的Type属性显式指定Intent的数据类型(MIME)。一般Intent的数据类型能够根据数据本身进行判定,但是通过设置这个属性,可以强制采用显式指定的类型而不再进行推导。 5.Intent的Compent属性 Intent的Compent属性指定Intent的的目标组件的类名称。通常 Android会根据Intent 中包含的其它属性的信息,比如action、data/type、category进行查找,最终找到一个与之匹配的目标组件。但是,如果 component这个属性有指定的话,将直接使用它指定的组件,而不再执行上述查找过程。指定了这个属性以后,Intent的其它所有属性都是可选的。 6.Intent的Extra属性 Intent的Extra属性是添加一些组件的附加信息。比如,如果我们要通过一个Activity来发送一个Email,就可以通过Extra属性来添加subject和body。 下面的例子在第一个Activity的EditText输入用户名,该年龄保存在Intent的Extras属性中。当单击Button时,会在第二个Activity中显示用户名。 first.xml <?xmlversion="1.0"encoding="utf-8"?> <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="请输入用户名" /> <EditText android:id="@+id/EditText1" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <Button android:id="@+id/Button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="测试Extras属性" /> </LinearLayout> second.xml <?xmlversion="1.0"encoding="utf-8"?> <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:id="@+id/TextView1" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> strings.xml <?xmlversion="1.0"encoding="utf-8"?> <resources> <stringname="hello">HelloWorld,FirstActivity!</string> <stringname="app_name">IntentExtrasDemo</string> </resources> FirstActivity.java packagecom.android.extras.activity; importandroid.app.Activity; importandroid.content.Intent; importandroid.os.Bundle; importandroid.view.View; importandroid.view.View.OnClickListener; importandroid.widget.Button; importandroid.widget.EditText; publicclassFirstActivityextendsActivity{ privateButtonbtn; privateEditTextetx; @Override publicvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.first); btn=(Button)findViewById(R.id.Button1); etx=(EditText)findViewById(R.id.EditText1); btn.setOnClickListener(newOnClickListener(){ @Override publicvoidonClick(Viewv){ Intentintent=newIntent(); //设置Intent的class属性,跳转到SecondActivity intent.setClass(FirstActivity.this,SecondActivity.class); //为intent添加额外的信息 intent.putExtra("useName",etx.getText().toString()); //启动Activity startActivity(intent); } }); } } SecondActivity.java packagecom.android.extras.activity; importandroid.app.Activity; importandroid.content.Intent; importandroid.os.Bundle; importandroid.widget.TextView; publicclassSecondActivityextendsActivity{ privateTextViewtv; @Override publicvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); //设置当前的Activity的界面布局 setContentView(R.layout.second); //获得Intent Intentintent=this.getIntent(); tv=(TextView)findViewById(R.id.TextView1); //从Intent获得额外信息,设置为TextView的文本 tv.setText(intent.getStringExtra("useName")); } } 注意:在添加第二个Activity SecondActivity的时候,要在AndroidManifest.xml里面添加上SecondActivity,具体如下,即是在15行</activity>的后面添加上16~18行的代码。如果不这样做,就会在模拟器上出现错误。 <?xmlversion="1.0"encoding="utf-8"?> <manifestxmlns:android="http://schemas.android.com/apk/res/android" package="com.android.extras.activity" android:versionCode="1" android:versionName="1.0"> <uses-sdkandroid:minSdkVersion="10"/> <applicationandroid:icon="@drawable/icon"android:label="@string/app_name"> <activityandroid:name=".FirstActivity" android:label="@string/app_name"> <intent-filter> <actionandroid:name="android.intent.action.MAIN"/> <categoryandroid:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> <activityandroid:name=".SecondActivity" android:label="@string/app_name"> </activity> </application> </manifest> 效果图: 本文转自 lingdududu 51CTO博客,原文链接: http://blog.51cto.com/liangruijun/634411

优秀的个人博客,低调大师

写得蛮好的linux学习笔记一-目录架构(收藏)

linux目录架构 / 根目录 /bin 常用的命令 binary file 的目錄 /boot 存放系统启动时必须读取的档案,包括核心 (kernel) 在内 /boot/grub/menu.lst GRUB设置 /boot/vmlinuz 内核 /boot/initrd 核心解壓縮所需 RAM Disk /dev 系统周边设备 /etc 系统相关设定文件 /etc/DIR_COLORS 设定颜色 /etc/HOSTNAME 设定用户的节点名 /etc/NETWORKING 只有YES标明网络存在 /etc/host.conf 文件说明用户的系统如何查询节点名 /etc/hosts 设定用户自已的IP与名字的对应表 /etc/hosts.allow 设置允许使用inetd的机器使用 /etc/hosts.deny 设置不允许使用inetd的机器使用 /etc/hosts.equiv 设置远端机不用密码 /etc/inetd.conf 设定系统网络守护进程inetd的配置 /etc/gateways 设定路由器 /etc/protocols 设定系统支持的协议 /etc/named.boot 设定本机为名字服务器的配置文件 /etc/sysconfig/network-scripts/ifcfg-eth0 设置IP /etc/resolv.conf 设置DNS /etc/X11 X Window的配置文件,xorg.conf 或 XF86Config 這兩個 X Server 的設定檔 /etc/fstab 记录开机要mount的文件系统 /etc/inittab 设定系统启动时init进程将把系统设置成什么样的runlevel /etc/issue 记录用户登录前显示的信息 /etc/group 设定用户的组名与相关信息 /etc/passwd 帐号信息 /etc/shadow 密码信息 /etc/sudoers 可以sudo命令的配置文件 /etc/securetty 设定哪些终端可以让root登录 /etc/login.defs 所有用户登录时的缺省配置 /etc/exports 设定NFS系统用的 /etc/init.d/ 所有服務的預設啟動 script 都是放在這裡的,例如要啟動或者關閉 /etc/xinetd.d/ 這就是所謂的 super daemon 管理的各項服務的設定檔目錄 /etc/modprobe.conf 内核模块额外参数设定 /etc/syslog.conf 日志设置文件 /home 使用者家目录 /lib 系统会使用到的函数库 /lib/modules kernel 的相关模块 /var/lib/rpm rpm套件安装处 /lost+found 系統不正常產生錯誤時,會將一些遺失的片段放置於此目錄下 /mnt 外设的挂载点 /media 与/mnt类似 /opt 主机额外安装的软件 /proc 虚拟目录,是内存的映射 /proc/version 内核版本 /proc/sys/kernel 系统内核功能 /root 系统管理员的家目录 /sbin 系统管理员才能执行的指令 /srv 一些服務啟動之後,這些服務所需要取用的資料目錄 /tmp 一般使用者或者是正在執行的程序暫時放置檔案的地方 /usr 最大的目录,存许应用程序和文件 /usr/X11R6: X-Window目录 /usr/src: Linux源代码 /usr/include:系统头文件 /usr/openwin 存放SUN的OpenWin /usr/man 在线使用手册 /usr/bin 使用者可執行的 binary file 的目錄 /usr/local/bin 使用者可執行的 binary file 的目錄 /usr/lib 系统会使用到的函数库 /usr/local/lib 系统会使用到的函数库 /usr/sbin 系统管理员才能执行的指令 /usr/local/sbin 系统管理员才能执行的指令 /var 日志文件 /var/log/secure 記錄登入系統存取資料的檔案,例如 pop3, ssh, telnet, ftp 等都會記錄在此檔案中 /var/log/wtmp 記錄登入者的訊息資料, last /var/log/messages 幾乎系統發生的錯誤訊息 /var/log/boot.log 記錄開機或者是一些服務啟動的時候,所顯示的啟動或關閉訊息 /var/log/maillog 紀錄郵件存取或往來( sendmail 與 pop3 )的使用者記錄 /var/log/cron 記錄 crontab 這個例行性服務的內容 /var/log/httpd, /var/log/news, /var/log/mysqld.log, /var/log/samba, /var/log/procmail.log: 分別是幾個不同的網路服務的記錄檔 本文转自 OldHawk 博客园博客,原文链接:http://www.cnblogs.com/taobataoma/archive/2007/08/10/850252.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

《从零开始学Swift》学习笔记(Day 29)——访问级别

访问级别: Swift提供了3种不同访问级别,对应的访问修饰符为:public、internal和private。这些访问修饰符可以修饰类、结构体、枚举等面向对象的类型,还可以修饰变量、常量、下标、元组、函数、属性等内容。 public。可以访问自己模块中的任何public实体。如果使用import语句引入其他模块,我们可以访问其他模块中的public实体。 internal。只能访问自己模块的任何internal实体,不能访问其他模块中的internal实体。internal可以省略,换句话说,默认访问限定是internal。 private。只能在当前源文件中使用的实体,称为私有实体。使用private修饰,可以用作隐藏某些功能的实现细节。 使用访问修饰符的示例代码如下: 1 2 3 4 5 6 7 public class PublicClass{} internalclassInternalClass{} private class PrivateClass{} public varintPublicVariable= 0 letintInternalConstant= 0 private funcintPrivateFunction(){} 使用最佳访问级别: 由于中Swift中访问限定符能够修饰的实体很多,使用起来比较繁琐,下面我们给出一些最佳实践。 1.统一性原则 原则1:如果一个类型(类、结构体、枚举)定义为internal或private,那么类型声明的变量或常量不能使用public访问级别。因为public的变量或常量可以被任何人访问,而internal或private的类型不可以。 原则2:函数的访问级别不能高于它的参数和返回类型(类、结构体、枚举)的访问级别。假设函数声明为public级别,而参数或者返回类型声明为internal或private,就会出现函数可以被任何人访问,而它的参数和返回类型不可以访问的矛盾情况。 2.设计原则 如果我们编写的是应用程序,应用程序包中的所有Swift文件和其中定义的实体,都是供本应用使用的,而不是提供其他模块使用,那么我们就不用设置访问级别了,即使用默认的访问级别。 如果我们开发的是框架,框架编译的文件不能独立运行,因此它天生就是给别人使用的,这种情况下我们要详细设计其中的Swift文件和实体的访问级别,让别人使用的可以设定为public,不想让别人看到的可以设定为internal或private。 3.元组类型的访问级别 元组类型的访问级别遵循元组中字段最低级的访问级别,例如下面的代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 private class Employee{ varno:Int= 0 varname:String= "" varjob:String? varsalary:Double= 0 vardept:Department? } structDepartment{ varno:Int= 0 varname:String= "" } private letemp=Employee() vardept=Department() private varstudent1=(dept,emp)① 4.枚举类型的访问级别 枚举中成员的访问级别继承自该枚举,因此我们不能为枚举中的成员指定访问级别。示例代码如下: 1 2 3 4 5 6 7 public enum WeekDays{ case Monday case Tuesday case Wednesday case Thursday case Friday } 由于WeekDays枚举类型是public访问级别,因而它的成员也是public级别。 本文转自 tony关东升 51CTO博客,原文链接:http://blog.51cto.com/tonyguan/1746589,如需转载请自行联系原作者

优秀的个人博客,低调大师

《从零开始学Swift》学习笔记(Day 32)——计算属性

计算属性本身不存储数据,而是从其他存储属性中计算得到数据。 计算属性概念: 计算属性提供了一个getter(取值访问器)来获取值,以及一个可选的setter(设置访问器)来间接设置其他属性或变量的值。计算属性的语法格式如下: 1 2 3 4 5 6 7 8 9 10 11 12 面向对象类型类型名{ 存储属性 ...... var计算属性名:属性数据类型{ get{ return 计算后属性值 } set(新属性值){ ...... } } } 定义计算属性比较麻烦,要注意后面的几个大括号的对齐关系。 我们先看一个示例: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 import Foundation class Employee{ varno:Int= 0 varfirstName:String= "Tony" //存储属性 varlastName:String= "Guan" //存储属性 varjob:String? varsalary:Double= 0 lazyvardept:Department=Department() varfullName:String{ //计算属性 get{ return firstName+ "." +lastName //返回拼接的结果 } set(newFullName){ //存储传递进来的参数值 varname=newFullName.componentsSeparatedByString( "." ) firstName=name[ 0 ] lastName=name[ 1 ] } } } structDepartment{ letno:Int= 0 varname:String= "" } varemp=Employee() print(emp.fullName) //取出属性值 emp.fullName= "Tom.Guan" //给属性赋值 print(emp.fullName) 只读计算属性: 计算属性可以只有getter访问器,没有setter访问器,这就是只读计算属性。指定计算属性不仅不用写setter访问器,而且get{}代码也可以省略。与上一节相比,代码将大大减少。修改上一节示例为只读计算属性,代码如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 class Employee{ varno:Int= 0 varfirstName:String= "Tony" varlastName:String= "Guan" varjob:String? varsalary:Double= 0 lazyvardept:Department=Department() varfullName:String{ //简洁的setter访问器 return firstName+ "." +lastName } } structDepartment{ letno:Int= 0 varname:String= "" } varemp=Employee() print(emp.fullName) 只读计算属性不能够赋值,下列语句是错误的。 1 emp.fullName= "Tom.Guan" 本文转自 tony关东升 51CTO博客,原文链接:http://blog.51cto.com/tonyguan/1746597,如需转载请自行联系原作者

资源下载

更多资源
优质分享App

优质分享App

近一个月的开发和优化,本站点的第一个app全新上线。该app采用极致压缩,本体才4.36MB。系统里面做了大量数据访问、缓存优化。方便用户在手机上查看文章。后续会推出HarmonyOS的适配版本。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

用户登录
用户注册