首页 文章 精选 留言 我的

精选列表

搜索[基础模型],共10000篇文章
优秀的个人博客,低调大师

JVM调优基础

1. JVM命令功能 jcmd help jhat: 读取内存堆转存 jmap: 提供转存和内存使用信息 jinfo:查看jvm的系统属性,也可以是设置系统属性,可用于脚本 jstack: 转存java进程信息,可用于脚本 jstat: 提供GC和类装载活动的信息,可用于脚本 jvisualvm: 可视化工具 jstat -J-Djstat.showUnspported=true -snap 5376 -- 获得监控信息 -XX:ReservedCodeCacheSize=N 标志可以设置代码缓存最大值-XX:InitialCodeCacheSize=N 代码缓存从初始大小开始分配 1.1 常用信息 1.错误信息:C: C帧, j: java帧 V: VM帧 v:VM生成的stub帧,J:其它帧,含java帧(编译) 2: TPS:每秒事物数,比如执行了dml操作,那么相应的tps会增加 RPS: 每秒请求数,并发数/平均响应时间 OPS:每秒操作次数 QPS是指每秒内查询次数,比如执行了select操作,相应的qps会增加。 PV 是指页面被浏览的次数,比如你打开一网页,那么这个网站的pv就算加了一次; 3 vmstate 1: 单个线程,CPU内存等监控, iostat -xm 5 , nicstat 5: 监控网络信息 4 JVM内部线程状态: _thread_uninitialized _thread_new _thread_in_native _thread_in_vm _thread_in_java _thread_block _<thread_state_type>_trans 5.JVM状态 not at a safepoint: 正常执行的状态 at safepoint: 所有线程阻塞,等待VM完成专门的VM操作(VM operation) synchronizing : VM接到一个专门的VM操作请求,等待VM中所有现场阻塞 2. JVM保留内存和分配内存之间的差别: 编译是基于JVM计数器: 方法调用计数器和方法中的循环回边计数器, 当方法或循环 编译的时候,就会进入编译队列,队列有一个或多个后台线程处理.也就是异步的,并不是严格先进先出,调用计数次数多的方法有更高优先级,也就是PrintCompilation输出中ID乱序的原因. OSR(on-stack Replacement): 在循环进行的时候还能编译循环,在循环代码编译结束后,JVM会替换在栈上的代码,循环的下一次就行快的多的代码 -XX:CompliThreshold=Nclient默认1500,server默认10000,一般不用修改),这个数值是回边计数器和方法调用次数的总和 -XX:PrintCompilation(默认false):每编译一个循环和方法就输出编译内容 -XX:CICompilerCount=N :JVM 处理队列的线程总数 -XX:+BackgroundCompilation(默认为true,即异步处理,也可以改为false,一个方法适合编译就一直等到他确实被编译) jstat -compiler 8895 输出这个pid的编译过的方法,有时也会出现编译失败的方法 jstat -printcompilation 8895 1000 (每秒钟输出一次编译的方法) -XX:-Inline (默认开启,关闭的话严重影响性能)-XX:PrintInlining 生成内联信息 方法是否内联取决于: 多热和它的大小,只有字节码小于325字节才会或者小于35字节-XX:MaxFreqInlineSize=N -XX:MaxInLineSize=N 逃逸分析-XX:+DoEscapeAnalysis(默认为true) 逆优化 (意味着编译器不得不撤销之前的优化): (1) 代码状态为"made not entrant"(代码被丢弃) -原因: 可能和类与接口的工作方式有关,也可能与分层编译的实现有关 (2) "made zombie"(产生僵尸代码) client编译的结果后来server编译更优化的结果 编译级别: C1编译器有3种级别,所以总有5种编译级别 0: 解释代码 1: 简单的C1编译代码 2: 受限的C1编译代码 3: 完全的C1编译代码 4: C2编译代码 目前主流的4个GC算法: 1: Serial : -XX:+UseSerialGC 2: Throughput(Parallel): 7之后默认,使用多线程收集Eden区, -XX:+UseParalleGC -XX:+UseParallelOldGC 3: Concurrent (CMS): 修改之前UseParalleGC算法收集Eden区,改用 -XX:UseParNewGC收集Eden, -XX:+UseConcMarkSweepGC 后台线程扫描Old区的垃圾对象,停顿时间少, 问题: (1)占用CPU线程资源,(2)内存碎片化严重,最后变成Serial(间隔时间长),整理好内存之后重复之前 4: G1: -XX:+UseG1GC, 属于Concurrent收集器,老年代的收集工作由后台线程完成,大多数不需要暂停应用线程,由于老年代被划分到不同的 区域,G1收集器通过将对象从一个区域复制到另外一个区域,完成对象的清理工作,这也意味着G1实现了堆的压缩整理(至少是部分整理) System.gc() 会触发Full GC -Xms4096m -Xmx4096m 设置一样大就不需要估算堆是否需要调整大小了 -XX:NewRatio=N(默认2): 新生代与老年代的空间占用比率 Initial Yong Gen size = Initial Heap Size / (1+NewRatio) --> 默认新生代占 1/3 -XX:NewSize=N 直接设置新生代初始的大小 -XX:MaxNewSize: 设置新生代最大大小 -XX:PermSize=N, -XX:MaxPermSize=N 设置永久区的大小 -XX:MetaspaceSize=N -XX:MaxMatespaceSize=N 调整 除了SerialGC之外几乎所有的GC都是使用多线程,启动线程数由 -XX:ParalleGCThreads=N控制-XX:+UseParallelGC -XX:+UseParNewGC -XX:+UseG1GC 收集新生代空间-XX:+UseParallelOldGC 收集老年代空间估算公式: ParalleGCThreads = 8 + ((N-8)*5/8), 每超出5/8个CPU启动一个新的线程(可能会略高,需适当调整) -XX:-UseAdaptiveSizePolicy(默认开启) 可以在全局范围内关闭自适应调整功能,如果堆容量最大值和最小值设置同样的值,与此同时,新生代的最大值和最小值也设置为同样的值,自适应功能将会被关闭 -XX:PrintAdaptiveSizePolicy: 一旦发生GC会在日志中包含GC不同空间调整的信息 -verbose:gc 或 -XX:+PrintGC -XX:+PrintGCDetails(默认关闭) -XX:+PrintGCTimeStamps -XX:+PirntGCDateStamps -XX:+UseGCLogfileRotation -XX:NumberOfGCLogfiles=N -XX:GCLogfileSize=N 组合使用可以控制循环输出日志 文件大小不足8kb按照8kb算 查看日志可以使用 gchisto 或者jstat -gcutil pid 1000 每秒输出日志信息 GC回收算法 1. Throughput 收集器 回收新生代的垃圾 Minor GC 回收老年代垃圾 Full GC -XX:MaxGCPauseMillis=N 设定应用可承受最大停顿时间 -XX:GCTimeRatio=N 设置你希望应用程序在垃圾回收上花费多少时间(与应用线程的运行时间相比) 公式: ThroughputGoal=1-1/(1+GCTimeRatio) 默认是99,也就是运行程序占99%,只有1%的时间消耗在垃圾回收上 2. CMS收集器 CMS会对新生代的对象进行回收 ParNew(所有线程都会被暂停) CMS会启动一个并发线程对老年代空间进行垃圾回收,(不会内存整理) 如有必要,CMS会发起 Full GC CMS收集步骤: 1: Init-mark: 找到堆中所有垃圾回收根节点对象 2: current-mark: 和应用程序并行,标记,(可能还会产生垃圾) 3: preclean-start: 预处理,与应用程序并行 4: remark(多个阶段),不是并发,STW 5: concurrent-sweep: 与应用程序并行 6: concurrent-reset: 并发重置 CMS可能会产生的问题: concurrent mode failure:新生代发生GC,同时老年代又没有足够的空间容纳晋升的对象时,CMS GC就会退化成Full GC,所有的应用线程都会暂停,老年代对象进行回收,这个操作是单线程的,所以非常耗时 老年代有足够的空间容纳晋升的对象,但是空间非常碎片化,导致晋升失败. 这时新生代暂停了所有的应用线程,专门在老年代整理碎片内存,好消息是内存碎片整理完了,但是会有很长时间停顿,这比并发模式失效停顿的时间还长.(因为并发模式失效时只需要整理堆里无效的对象) 针对并发模式失效的调优: 增大老年代空间 以更高的频率运行后台回收线程 使用更多的后台线程 注意点:1. CMS与其他回收算法的显著不同就是:除非发生Full GC,否则CMS的新生代大小不会调整.CMS的目标就是尽量避免Full GC, 可以使用: MaxPauseMllis=N和GCTimeRatio=N来确定使用多大的堆和多大的空间 2. 给后台线程更多的运行机会: -XX:CMSInitiatingOccupancyFraction=N和-XX+UseCMSInitiatingOccupanyOnly(默认70,即CMS在老年代空间占70%时启动并发收集周期调整) 调整后台线程: -XX:ConcGCThreads=N增加后台线程,ConcGCThreads=(3+ParallelGCThreads) / 4 3. CMS不会处理永久代的垃圾,如果耗尽会产生一次Full GC来回收垃圾,可以设置: -XX:+CMSPermGenSweepingEnable(默认false)标志开启和老年代同样的回收方式,后台开启一组线程并发回收永久代中的垃圾,同时配合:+XX:CMSInitiatingPermOccupancyFrantion=N指定在永久代占用达到比例值时开启回收线程. java8 CMSPermGenSweepingEnable标志默认开启 4: 增量式CMS,(java8种不推荐使用) 当CPU资源有限,后台线程会间歇性暂停,让出一部分CPU给应用线程 开启: -XX:+CMSIncrementalMode, 设置: -XX:CMSIncrementalSaftyFactor=N,-XX:CMSIncrementalDutyCycleMin=N,-XX:CMSIncrementalPacing可以控制GC线程为应用线程让出多少CPU G1收集器 分区(Region)一般分为2048个区域,专注于垃圾最多的分区,用最少的时间回收最多的垃圾 新生代进行回收时,要么被回收,要么被晋升,新生代采用分区机制的部分原因是采用预定义的分区能够便于代的大小调整 主要包括4种操作: 1.新生代垃圾收集 2.后台收集,并发周期 3.混合式垃圾回收(不仅进行新生代的GC同时也回收部分后台扫描线程标记的分区) 4.以及必要的Full GC 操作步骤: 1:initial-mark(STW) 2: root-scan(并发) 3: conc-mark 4:remark 5: conc -clean G1注意: 1: 并发模式失效:,在G1启动标记周期,但老年代在周期完成之前就被填完,G1会放弃标记周期,(GC-concurrent-mark-abort)2:晋升失败: G1完成了标记阶段,开始启动混合式垃圾回收,清理老年代分区,不过,老年代空间在垃圾回收释放出足够内存之前就会被耗尽. 一般都是混合式回收之后就是Full GC 3:疏散失败:进行新生代垃圾回收时,S区和老年代中没有足够的空间容纳所有的幸运对象.这表明堆已经几乎用完或者碎片化了.转用Full GC,性能下降,最简单的解决办法就是增加堆 4:巨型对象分配失败也可能会导致Full GC G1 调优: G1调优的主要目标就是避免发生并发模式失败或者疏散失败 -XX:MaxGCPauseMillis=N(默认200ms,这个CMS有所不同) 1:调整G1的后台线程数,可以使用ParallelGCThreads设置运行的线程数,计算方式ConcGCThreads=(ParallelGCThreads+2)/4 这个和CMS也不同 2: -XX:InitiatingHeapOccupancyPercent=N(默认45),堆占用比例,如果设置过高会陷入Full GC泥潭中,因为并发阶段没有足够的时间在剩下的堆空间被填满之前完成垃圾回收,如果设置过小又会以超过实际的节奏在后台大量处理 3:调整G1收集器混合式垃圾收集周期:混合式垃圾收集取决于三个因素(1)有多少分区被发现大部分是垃圾对象,默认超过35%就会标记为可进行垃圾回收,实验版标志: -XX:G1MixedGCLiveThresholdPercent=N (2)G1垃圾回收分区时最大混合式GC周期数,参数 -XX:G1MixedGCCountTarget=N(默认8),减少该值可以解决晋升失败的问题(代价是混合式GC周期的停顿时间会更长) (3)GC停顿可忍受的最大时常,参数-XX:MaxGCPauseMillis 4:2种情况下会被移动到老年区: (1):S区实在太小,S区被填满之后,Eden区剩下的活跃的对象直接放到Old区,(2)在S区经历的GC周期的个数上限(Tenuring Threshold) 5: S区是新生代的一部分,跟堆内存的其他区域一样,JVM可以对他动态调节,参数: -XX:InitialSurvivorRatio=N(默认8)决定, survivor_space_size=new_size / (initial_survivor_ratio+2) JVM可以增大S区空间直至最大上限, -XX:MinSurvivorRatio(默认3)设置(注意参数在分母,名字不直观),maximum_survivor_space=new_size / (min_survivor_ratio + 2), -XX:TargetSurvivorRatio=N可以在Survivor空间调整之后能保证垃圾回收之后有50%的空间是空闲的. 6: -XX:InitialTenuringThreshold=N可以设置初始晋升阈值(Throughput和G1的默认值7,CMS默认值是7),JVM最终会在1和最大阈值(-XX:MaxTenuringThreshold=N)之间选择一个合适的值, 对于Throughput和G1,最大值默认15,CMS最大默认6) 7:-XX:PrintTenringDistribution标志可以在GC中增加这些信息 8: TLAB的大小由三个因素决定: (1)应用线程的线程数(2)Eden空间的大小(3)线程分配率,默认开启,-XX:-UseTLAB可以关闭. -XX:TLABSize=N可以显示的指定TLAB的大小(默认为0,由Eden区的大小动态计算出),这个标志只能设置TLAB的初始大小,为了避免每次GC时都调整TLAB的大小可以使用 -XX:-ResizeTLAB,TLAB调整时,最小容量可以使用:-XX:MinTLABSize=N设置(默认2kb),最大容量略小于1GB 9: -XX:+PrintTLAB输出信息 G1分区大小: size=1<<log(初始堆的大小/2048), 分区最小1MB,最大不能超过32MB, 堆的大小: 堆的大小 Region Size < 4GB 1MB 4GB - 8GB 2MB 8GB - 16GB 4MB 16GB - 32GB 8MB 32GB - 64GB 16MB > 64GB 32MB G1分区的大小可以通过-XX:G1HeapRegionSize=N设置(默认0,动态计算出),选择合适的大小,使分区数量接近于: 2048个 堆内存 1.jmap -dump:live,file=/path/heap.dump.hprof pid, jmap有live选项会在堆转储之前强制执行一次Full GC, jcmd默认就会这么做 jcmd pid GC.heap_dump /path/heap_dump.hprof -XX:+HeapDumpOnOutOfMemoryError(默认false)会在抛出OutofMemoryError时转储 -XX:HeapDumpPath=/path 指定堆转储位置,默认java_pid.hprof -XX:+HeapDumpAfterFullGC:在运行一次Full GC之后生成一个堆转储 -XX:+HeapDumpBeforeullGC:会在一次Full GC之前生成一个堆转储文件 3: Exception in thread 'main' java.lang.OutOfMemoryError: GC overhead limit exceeded:原因: (1) 花在Full GC上的时间超出了-XX:GCTimeLimit=N(默认98,也就是98%的时间花在了GC上了) (2):一次Full GC回收的内存量少于-XX:GCHeapFreeLimit=N设置的值,默认值2,即意味着如果Full GC期间释放的内存不足堆的2%,(3)上面2个条件连续5次Full GC都成立(这个值无法调整) (4):-XX:+UseGCOverHeadLimit标志的值为true(默认true) 请注意:所有四个条件都满足的时候才会报错,如果连续4次Full GC都成立,作为释放内存的最后一搏,JVM中所有的软引用都会在第五次Full GC之前被释放 减少内存使用(减少对象大小,对象延迟初始化,规范化对象) 1.对普通对象,对象头字段在32位JVM上占8字节,在64位JVM上占16字节,对于数组,对象头在32位JVM以及堆小于32GB的64位JVM上占16字节,其他情况是64字节 2.不可变对象:基本的数据类型Double,Boolean,以及一些基于数值的类型,BigDeciaml,String,像这类不可变对象的单一化表示,就被称为标准化(canonical)版本,类似有String.intern 例如: 创建一个Map来保存该对象的标准化版本,为防止内存泄漏,采用WeakHashMap class ImmutableObject{ WeakHashMap<ImmutableObject,ImmutableObject> map = new WeakHashMap<>(); public ImmutableObject canonicalVersion(ImmutableObject io){ synchronized (map){ ImmutableObject cv = map.get(io); if(cv == null){ map.put(io,io); cv = io; } return cv; } } } String提供了自己的标准化方法,intern()方法.保留字符串的表是保留在原生内存中的,他是一个大小固定的HashTable,在Java 7u40之前默认是1009个桶,之后的版本中,默认改为60013个 可以通过-XX:StringTableSize=N设置,输出信息: -XX:+PrintStringTableStatistics(默认false) 对象重用的方式: 对象池和ThreadLocals,注意:被重用的对象会在堆中停留很长时间,如果有大量对象存于堆中,那用来创建新对象的空间就少了.并且会通过Eden S0 S1最终才会进入Old区,执行一次Full GC所化的时间与老年代中仍然存活的对象数量成正比,存活对象的数量甚至比堆的大小更重要. 线程池: 线程初始化成本高 JDBC池: 数据库连接初始化的成本高 EJB池: EJB初始化成本高 大数组:java要求,一个数组在分配的时候,其中的每个元素都必须初始化为某个默认初始值(null,0,false) 原生NIO缓冲区:不管缓冲区多大,分配一个直接java.nio.Buffer(即调用allocateDirector()方法返回的缓冲区) 安全相关的类: MessageDigest,Signature以及其他安全算法的实例 字符串编解码对象,大多数都是软引用 StringBuilder协助者:BigDecimal类在计算中间结果时会重用一个StringBuilder对象 随机数生成器: Random和SecureRandom类,生成这些类代价较高 从DNS查询到的名字:网络查询代价很高 ZIP编解码器:初始化开销不是特别高,但是释放成本很高,因为这些对象要依赖对象终结操作(finalization)来确保释放掉所用的原生内存. 对象池: (1)GC影响,降低GC效率 (2)同步: 对象池必然是同步 (3)限流(Throttling):对于稀缺的资源访问,线程池可以起到限流的作用.同时也意味着,超出的部分会等待资源. 线程局部变量:(1)生命周期管理 (2)基数性(Cardinality):线程局部变量通常会伴生线程数与保存的可重用对象数之间一一对应的关系.(3)不需要同步 注意: 初始化一个Random对象的开销非常大,而且持续创建这个类的实例,与再多个线程间共享一个类实例的同步瓶颈相比,性能可能更差.使用TreadLocalRandom类性能会更好. -XX:+PrintReferenceGC(默认false),可以输出调试信息 软引用的释放: (1):所引用的对象不能有其它的强引用,如果软引用是指向其所引用对象的唯一引用,而且该引用最近没有被访问过,则所引用对象会在下一次GC周期前释放. long ms = SoftRefLRUPolicyMSPerMB * AmountOfFreeMemoryInMb if(now - last_access_to_reference > ms) free the reference (2) 堆空间空闲内存的数量,例如堆空间4GB,再一次Full GC之后,堆可能被占用了50%,因此空闲堆是2GB,SoftRefLRUPolicyMSPerMB的默认值1000,意味着 过去的 2048s内没有访问到的任何软引用都会被清理. 如果4GB的堆占了75%,则过去的1024s没有访问到的软引用会被回收. log ms = 2048000;//2048*1000 if(System.currentTimeMillis()- last_access_to_reference_in_ms ms) free the reference 注意: 对于长期运行的应用,如果满足以下2个条件,可以考虑增加SoftRefLRUPolicyMSPerMB的值: (1)有很多空闲堆可用 (2)软引用会频繁访问 ,(不过情况罕见,增加软引用的策略值就是告诉JVM不到万不得已不要释放软引用) 软引用:当问题中的所引用对象会同时被几个线程使用时,考虑弱引用,否则入弱引用很可能会被GC掉,只有弱引用的对象在每个GC周期都可以回收 原生内存的使用 1.从Java8开始: -XX:NativeMemoryTracking=off|summary|detail 标志来跟踪JVM如何分配原生内存. 也可以使用-XX:+PrintNMTStatistics(默认false)启动 ,前提需要设置-XX:+UnlockDiagnosticVMOptions 2: 开启压缩指针: -XX:+UseCompressedOops(默认启用的) Ordinary object pointer tables Area Cool cold 2 is right $1800 col is 2 left $0099

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

Java基础巩固——反射

什么是反射 反射机制就是指程序运行时能够获取自身的信息。在Java中,只要给出类的名字,就可以通过反射机制来获取类的信息 哪里用的到反射机制 在jdbc中就是使用的反射来实例化对象,比如:Class.forName("com.mysql.jdbc.Driver.class").newInstance(); 框架都用到反射机制,spring,hibernate、struts都是用反射机制实现的。 反射机制的优点和缺点 为什么要用反射机制?直接创建对象不就可以了吗,这就涉及到了动态与静态的概念, 静态编译:在编译时确定类型,绑定对象,即通过。 动态编译:运行时确定类型,绑定对象。动态编译最大限度发挥了java的灵活性,体现了多 态的应用,有以降低类之间的藕合性。 一句话,反射机制的优点就是可以实现动态创建对象和编译,体现出很大的灵活性,特别是在J2EE的开发中. 它的灵活性就表现的十分明显。比如,一个大型的软件,不可能一次就把把它设计的很完美,当这个程序编译后,发布了,当发现需要更新某些功能时,我们不可能要用户把以前的卸载,再重新安装新的版本,假如这样的话,这个软件肯定是没有多少人用的。采用静态的话,需要把整个程序重新编译一次才可以实现功能的更新,而采用反射机制的话,它就可以不用卸载,只需要在运行时才动态的创建和编译,就可以实现该功 能。 它的缺点是对性能有影响。使用反射基本上是一种解释操作,我们可以告诉JVM,我们希望做什么并且它 满足我们的要求。这类操作总是慢于只直接执行相同的操作。 利用反射机制能干什么 Class c=Class.forName("className");注明:className必须为全名,也就是得包含包名,比如,cn.netjava.pojo.UserInfo; Object obj=c.newInstance();//创建对象的实例 获取构造器 Constructor getConstructor(Class[] params)//根据指定参数获得public构造器 Constructor[] getConstructors()//获得public的所有构造器 Constructor getDeclaredConstructor(Class[] params)//根据指定参数获得public和非public的构造器 Constructor[] getDeclaredConstructors()//获得public的所有构造器 获取类的方法 Method getMethod(String name, Class[] params),根据方法名,参数类型获得方法 Method[] getMethods()//获得所有的public方法 Method getDeclaredMethod(String name, Class[] params)//根据方法名和参数类型,获得public和非public的方法 Method[] getDeclaredMethods()//获得所以的public和非public方法 获取类的属性 Field getField(String name)//根据变量名得到相应的public变量 Field[] getFields()//获得类中所以public的方法 Field getDeclaredField(String name)//根据方法名获得public和非public变量 Field[] getDeclaredFields()//获得类中所有的public和非public方法 使用实例 获取类属性: public class TestGetField extends Object { private static final long serialVersionUID = -2862585049955236662L; public static void main(String args[]) throws Exception { Class<?> clazz = Class.forName("reflect.TestGetField"); System.out.println("===============本类属性==============="); // 取得本类属性 Field[] fields = clazz.getDeclaredFields(); getField(fields); System.out.println("==========实现的接口或者父类的属性=========="); // 取得实现的接口或者父类的属性 Field[] fatherField = clazz.getFields(); getField(fatherField); } public static void getField(Field[] fields) { for (Field field : fields) { // 权限修饰符 int mo = field.getModifiers(); String priv = Modifier.toString(mo); Class<?> type = field.getType(); System.out.println(priv + " " + type.getName() + " " + field.getName() + ";"); } } } 获取类的方法: public class TestGetMethod implements Serializable{ private static final String testString= "hello"; public static void main(String args[]) throws Exception{ Class<?> clazz = Class.forName("reflect.TestGetMethod"); Method[] methods = clazz.getMethods(); for (Method method :methods){ Class<?> returnType = method.getReturnType(); Class<?> para[] = method.getParameterTypes(); int temp = method.getModifiers(); System.out.print(Modifier.toString(temp)); System.out.print(returnType.getName()); System.out.print(method.getName()); for (Class par:para){ System.out.println(par.getName()); } } } } 实例化类: public class TestNewInstance { public static void main(String[] args) throws Exception{ Class<?> class1 = null; class1 = Class.forName("reflect.User"); // 第一种方法,实例化默认构造方法,调用set赋值 User user = (User)class1.newInstance(); user.setAge(20); user.setName("adf"); System.out.println(user); // 第二种 取得全部的构造函数 使用构造函数赋值 } } class User { private int age; private String name; public User() { super(); } public User(String name) { super(); this.name = name; } public User(int age, String name) { super(); this.age = age; this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "User [age=" + age + ", name=" + name + "]"; } } 使用类的方法: public class TestUseMethod { public static void main(String[] args)throws Exception{ Class<?> clazz = Class.forName("reflect.TestUseMethod"); // 调用reflect1方法 Method method = clazz.getMethod("reflect1"); method.invoke(clazz.newInstance()); // 调用reflect2方法 method = clazz.getMethod("reflect2", int.class, String.class); method.invoke(clazz.newInstance(),20,"test"); } public void reflect1() { System.out.println("Java 反射机制 - 调用某个类的方法1."); } public void reflect2(int age, String name) { System.out.println("Java 反射机制 - 调用某个类的方法2."); System.out.println("age -> " + age + ". name -> " + name); } } 动态代理: public class TestProxy { public static void main(String args[]) throws Exception{ MyInvocationHandler demo = new MyInvocationHandler(); Subject subject = (Subject) demo.bind(new RealSubject()); System.out.println(subject.say("janti",20)); } } interface Subject{ public String say(String name, int age); } // 定义真实项目 class RealSubject implements Subject { public String say(String name, int age) { return name + " " + age; } } //如果想要完成动态代理,首先需要定义一个InvocationHandler接口的子类,已完成代理的具体操作。 class MyInvocationHandler implements InvocationHandler{ private Object object = null; public Object bind(Object obj){ this.object = obj; return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object temp = method.invoke(this.object,args); return temp; } } 个人博客网站 http://www.janti.cn

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

QTQuick控件基础(2)

import QtQuick 2.2import QtQuick.Controls 1.2import QtQuick.Window 2.1ApplicationWindow { visible: true width: 640 height: 480 title: qsTr("Hello World") menuBar: MenuBar{ Menu{ title: qsTr("File") MenuItem{ text: qsTr("EXIT") onTriggered: Qt.quit() } } } Column{ spacing: 10 //button Button{ x:10;y:10;width: 140 text:qsTr("Button with menu") menu:Menu{ MenuItem{text:qsTr("Item1")} MenuItem{text:qsTr("Item2")} } } //radiobutton ExclusiveGroup{id:group} RadioButton{ text:qsTr("from top") exclusiveGroup: group checked: true } RadioButton{ text:qsTr("from cursor") exclusiveGroup: group } //switch Switch{checked: true} Switch{checked: false} //combobox ComboBox{ id:editableCombo editable: true model: ListModel{ id:model ListElement{ text:"Banana";color:"Yellow"} ListElement{ text:"Apple";color:"Green"} ListElement{ text:"Cocont";color:"Brown"} } onAccepted: { if(editableCombo.find(currentText) === -1){ model.append({text:editText}) currentIndex = editableCombo.find(editText) } } } //spinbox SpinBox{ minimumValue: -5;maximumValue: 10 prefix: "today";suffix: "degree" decimals: 1;stepSize: 1 } //TextField TextField{ width: 200 placeholderText: "写字写字" echoMode: TextInput.PasswordEchoOnEdit } TextField{width: 200} //TextArea TextArea{ width: 240 textFormat: TextEdit.RichText font.pointSize: 13 text: "<b>Hello</b><i>world!</i>" } TextArea{ width: 240 textFormat: TextEdit.PlainText font.pointSize: 13 text: "<b>Hello</b><i>world!</i>" } //BusyIndicator BusyIndicator{ running: true } //ProgressBar ProgressBar{ id:progressBar minimumValue: 0 maximumValue: 100 } Timer{ interval: 100 running: true repeat: true onTriggered: progressBar.value++ } }} 同样的道理,它在android上也有很好的实现 来自为知笔记(Wiz) 附件列表 目前方向:图像拼接融合、图像识别 联系方式:jsxyhelu@foxmail.com

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

QTQuick控件基础(1)

一、Item QtQuick所有的可视项目都继承自Item,它定义了可视化项目所有通用特性(x\y\width\height\anchors等)具体包括 1、作为容器 2、不透明性 没有设置opacity属性 设置了opacity属性为0.5 当然也可以这样写 3、visible属性用来设置项目是否可见。如果visible属性为false,则不接受鼠标键盘事件;同理还有enable属性; 4、堆叠顺序,简单的说,就是z越大,越在顶层。当然前提是要保证是在并集的情况下。 通过z的设置,将原本在上面的蓝色矩形变换到底层,同时将两个矩形的结构由嵌套改编成并行。 或者可以通过将z设置为负值直接达到这个目标 5、定位子项目和坐标映射 包含childAt来返回在点x,y处的子项目,以及item的mapFromItem返回item坐标系统中点映射在该项目坐标系统的结果。 二、Rectangle Rectangle主要是使用纯色或者渐变填充一个矩形区域,并提供一个边框。 1、渐变,使用了GradientStop表明渐变的头和尾 2、边框,我们实现一个圆角矩形 三、Text 可以按照常用的方式,也可以以html的方式 1、颜色,有两种表示颜色的方法 2、文本裁剪,如果clip为true则裁剪,否则通过设置文本换行或者文本省略。这个截图已经可以说明 3、超链接 四、TextInput TextInput用来显示单行可编辑纯文本。以及相关的现实策略。比如intvalidator/DoubleValidator以及RegExpoValidator等 按下回车后读取数据 当然我们推荐使用qtcontrols中的textbox 四、定位器 column/row/grid/flow是四种定位器 五、repeater和positioner用来创建大量的项目并且获得特定的数据 注意其中的index是直接委托获得的。 六、anchor锚定位 一般来说,锚都是相对于父控件的,所以记录这幅图最为重要: 七、MouseArea 其最为重要的是 onClicked事件 八、timer 实时获得当前时间 来自为知笔记(Wiz) 目前方向:图像拼接融合、图像识别 联系方式:jsxyhelu@foxmail.com

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

Spark基础 --RDD详解

RDD算子分为两类:Transformation和Action,如下图,记住这张图,走遍天下都不怕。 Transformation:将一个RDD通过一种规则映射为另外一个RDD。 Action:返回结果或保存结果。 注意:只有action才触发程序的执行,transformation不触发执行。 RDD的操作种类有多个,分为: 单指RDD操作、Key/Value RDD操作、多个RDD联合操作,其他操作。 单值RDD 1. Map map (f: T => U) : RDD[U] ,其中f定义了类型为T的元素到类型为U 的元素的映射,RDD[T] => RDD[U]的变换 举例: var rdd=sc.makeRDD(1 to 7,3) 简写为 rdd.map(_+1) //rdd.map(x=>x+1) 2. collect collect(): Array[T],T是RDD中元素类型,将RDD转化为数组。 举例: val rdd = sc.makeRDD(1 to 7, 3) rdd.collect() 注意:此算子非常危险,他会将所有RDD中的数据汇总到Drive端的JVM内存中,对Drive端压力很大。 3. take take(num: Int): Array[T] ,其中k是整数,T是RDD中元素类型,返回RDD中前k个元素,并保存成数组 举例: val rdd = sc.makeRDD(1 to 7, 3) rdd.take(2) 4. glom glom() : RDD[Array[T]],将RDD中每个partition中元素转换为数组 举例: val rdd = sc.makeRDD(1 to 7, 3) rdd.glom.collect 5. coalesce coalesce(numPartitions: Int) : RDD[T],将RDD中的partition个数合并为numPartitions个 举例: val rdd = sc.makeRDD(1 to 7,7) rdd.coalesce(3) // 生成新的RDD,它包含三个Partition 6. repartition repartition(numPartitions: Int) :RDD[T],将RDD中的partition个数均匀合并为numPartitions个 举例: val list = Seq(Seq(),Seq(),Seq(),Seq(),Seq(),Seq(), Seq(1,2,3,4,5,6,7)) val rdd = sc.makeRDD(list, 7).flatMap(x => x) rdd.repartition(3) // 生成新的RDD,它包含三个Partition 7. filter filter(f: T => Boolean): RDD[T] ,其中f定义了类型为T的元素是否留下,过滤输入RDD中的元素,将f返回true的元素留下 举例: var rdd=sc.makeRDD(1 to 7,7) rdd.filter(_%3==0) 8. count count(): Long,统计RDD中元素个数,并返回Long类型 val rdd = sc.makeRDD(1 to 7, 3) rdd.count() // 统计RDD中元素总数 9. flatMap flatMap(f: T =>TraversableOnce[U]): RDD[U],将函数f作用在RDD中每个元素上,并展开(flatten) 输出的每个结果, flatMap = flatten + map,先映射(map),再拍扁(flatten ) 举例: val rdd = sc.makeRDD(1 to 3, 3) rdd.flatMap( x => 1 to x) // 将x映射成1~x 10. reduce reduce(f: (T, T) => T): T, 按照函数f对RDD中元素,进行规约 举例: val rdd = sc.makeRDD(1 to 7, 3) rdd.reduce((x, y) => x + y) 简写为:rdd.reduce(_ + _) 11. foreach foreach(f: T => Unit):Unit,对RDD中每个元素,调用函数f 举例: val rdd = sc.makeRDD(1 to 7, 3) rdd.foreach( x => println(x)) 简写为:rdd.foreach(println) Key/Value RDD 首先先来看下如何创建一个Key/Value的rdd var seq=Seq((A,1),(B,1),(C,1)) var rdd=sc.makeRDD(seq) 1.mapValues 对vaule做map操作 举例: val pairs = Seq((A,1), (B,2), (A,2), (C, 4), (B, 1), (B, 1), (D, 1)) val rdd = sc.makeRDD(pairs, 3) rdd.mapValues(_ + 1) 2.reduceByKey 对Key相同的value做计算 举例: val pairs = Seq(('A',1), ('B',2), ('A',2), ('C', 4), ('B', 1), ('B', 1), ('D', 1)) val rdd = sc.makeRDD(pairs, 3) rdd.reduceByKey(_ + _) 3.groupByKey 将RDD[key,value] 按照相同的key进行分组,形成RDD[key,Iterable[value]]的形式, 有点类似于sql中的groupby 举例: val pairs = Seq((A,1), (B,2), (A,2), (C, 4), (B, 1), (B, 1), (D, 1)) val rdd = sc.makeRDD(pairs, 3) rdd.groupByKey() 注意:能用reducebykey代替就不用groupbykey,groupbykey会将所有的元素进行聚合,消耗大量内存。 多RDD 1. union 将多个RDD合并为一个RDD 举例: val pairs1 = Seq((A,1), (B,1), (C,1), (D, 1), (A, 2), (C, 3)) val rdd1 = sc.makeRDD(pairs1, 3) val pairs2 = Seq((A,4), (D,1), (E, 1)) val rdd2 = sc.makeRDD(pairs2, 2) rdd1.union(rdd2) 2. zip zip函数用于将两个RDD组合成Key/Value形式的RDD,如果两个rdd中的partition数量不一致,会报错。 举例: val s1 = Seq(A, B, C, D, E) val rdd1 = sc.makeRDD(s1) val s2 = Seq(1, 2, 3, 4, 5) val rdd2 = sc.makeRDD(s2) rdd1.zip(rdd2) 3. join join相当于SQL中的内关联join,只返回两个RDD根据K可以关联上的结果,join只能用于两个RDD之间的关联, 如果要多个RDD关联,多关联几次即可 举例: val pairs1 = Seq((A,1), (B,1), (C,1), (D, 1), (A, 2), (C, 3)) val rdd1 = sc.makeRDD(pairs1, 3) val pairs2 = Seq((A,4), (D,1), (C,1), (E, 1)) val rdd2 = sc.makeRDD(pairs2, 2) rdd1.join(rdd2) 还有些是是其他rdd操作符,这里就不讲解了,上述所写如有不对之处,还请各位前辈赐教。

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

JAVA多线程基础

一:线程与进程 1 线程:进程中负责程序执行的执行单元 线程本身依靠程序进行运行 线程是程序中的顺序控制流,只能使用分配给程序的资源和环境 2 进程:执行中的程序 一个进程至少包含一个线程 3 单线程:程序中只存在一个线程,实际上主方法就是一个主线程 4 多线程:在一个程序中运行多个任务 目的是更好地使用CPU资源 二:线程的实现 1:继承Thread类 1 package Threads; 2 3 public class Thread_one extends Thread{ 4 5 @Override 6 public void run() { 7 // TODO Auto-generated method stub 8 System.out.println(Thread.currentThread().getName()); 9 } 10 } 我们继承Thread类,然后重写run()方法,写入你要执行的操作; 线程了类是创建好了,下面就是使用这个线程类: 1 package Threads; 2 3 public class Test1 { 4 public static void main(String[] args) { 5 for (int i = 0; i < 10; i++) { 6 new Thread_one().start(); 7 } 8 } 9 } 正确的启动线程的方法是start()方法,而不是使用run()方法,下面具体说明 ; 运行的结果: 我们可以发现多次运行结果是不一样的: 下面我们把启动改为run()试一试; 1 package Threads; 2 3 public class Test1 { 4 public static void main(String[] args) { 5 for (int i = 0; i < 10; i++) { 6 new Thread_one().run(); 7 } 8 } 9 } 多次运行发现结果都是一样的,发现运行的都是main这个主线程,而没有创建新的线程: 总结 run()和start()的区别: ①:首次正确启动一个线程是使用start()方法; ②:run()方法中只是定义需要执行的任务,如果调用run方法,即相当于在主线程中执行run方法,跟普通的方法调用没有任何区别,此时并不会创建一个新的线程来执行定义的任务。 ③:start()在调用start()方法后,线程就进入了就绪的状态,其实也就是一个可运行的状态,什么时候运行是根据cpu的调度的,看这个线程是否抢到了cpu的资源,所以说我们执行多个线程多次执行的顺序结果是不一样的; 2:实现Runnable 1 package Threads; 2 3 public class Thread_two implements Runnable{ 4 5 @Override 6 public void run() { 7 // TODO Auto-generated method stub 8 System.out.println(Thread.currentThread().getName()); 9 } 10 11 } 继承Thread和实现Runnable实现一个线程过程都差不多; 调用启动有些区别: 1 package Threads; 2 3 public class Test2 { 4 5 public static void main(String[] args) { 6 // TODO Auto-generated method stub 7 for (int i = 0; i < 10; i++) { 8 new Thread(new Thread_two()).start(); 9 } 10 } 11 } 我们查看Thread源码发现,他需要一个Runnable类型的对象; 我们附给他我们实现Runnable接口的对象 运行发现实现了效果: 总结: 实现Runnable接口比继承Thread类所具有的优势: 1):可以避免java中的单继承的限制 四:线程的不同状态及转换: 1、新建状态(New):新创建了一个线程对象。 2、就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于可运行线程池中,变得可运行,等待获取CPU的使用权。 3、运行状态(Running):就绪状态的线程获取了CPU,执行程序代码。 4、阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞的情况分三种: (一)、等待阻塞:运行的线程执行wait()方法,JVM会把该线程放入等待池中。 (二)、同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池中。 (三)、其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。 5、死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。 解析: 新建状态: 只是创建了这个线程对象。 就绪状态: 该状态的线程位于可运行线程池中,变得可运行,等争抢到cpu资源后就才会真正的进入到可运行的状态; 运行状态:就绪状态的线程获取了CPU,执行程序代码。 阻塞状态: ①:wait(); 只能用 notify唤醒 或者notifyall ②:sleep 定义毫秒数,到时间自动唤醒,继续执行任务; ③:yield 线程的礼让,让正在执行的线程变成可运行状态,然后在重新争抢cpu。 yield()应该做的是让当前运行线程回到可运行状态,以允许具有相同优先级的其他线程获得运行机会。因此,使用yield()的目的是让相同优先级的线程之间能适当的轮转执行。但是,实际中无法保证yield()达到让步目的,因为让步的线程还有可能被线程调度程序再次选中。 ④:join加入主线程; 让正在运行的主线程停止,然后先运行这个线程。 1 package Threads; 2 3 public class Test3 { 4 public static void main(String[] args) { 5 System.out.println("开始:"); 6 Thread3 t2=new Thread3(); 7 Thread t=new Thread(t2); 8 t.start(); 9 System.out.println("结束:"); 10 } 11 } 这明显不是我们想要的结果: 使用join加入主线程: 1 package Threads; 2 3 public class Test3 { 4 public static void main(String[] args) throws InterruptedException { 5 System.out.println("开始:"); 6 Thread3 t2=new Thread3(); 7 Thread t=new Thread(t2); 8 t.start(); 9 t.join(); 10 System.out.println("结束:"); 11 } 12 } 在很多情况下,主线程生成并起动了子线程,如果子线程里要进行大量的耗时的运算,主线程往往将于子线程之前结束,但是如果主线程处理完其他的事务后,需要用到子线程的处理结果,也就是主线程需要等待子线程执行完成之后再结束,这个时候就要用到join()方法了。 总结: sleep和wait的区别: 1. 所属的层面不同:Thread类的方法:sleep() Object的方法:wait()。 2.wait停止的线程则需要使用notifyall()和notifi()唤醒;3. 每个对象都有一个锁来控制同步访问。Synchronized关键字可以和对象的锁交互,来实现线程的同步。 sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。4. wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用 ;5. sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常 五:线程常用的方法: sleep(): 强迫一个线程睡眠N毫秒。 isAlive(): 判断一个线程是否存活。 join(): 等待线程终止。 activeCount(): 程序中活跃的线程数。 enumerate(): 枚举程序中的线程。 currentThread(): 得到当前线程。 isDaemon(): 一个线程是否为守护线程。 setDaemon(): 设置一个线程为守护线程。(用户线程和守护线程的区别在于,是否等待主线程依赖于主线程结束而结束) setName(): 为线程设置一个名称。 wait(): 强迫一个线程等待。 notify(): 通知一个线程继续运行。 setPriority(): 设置一个线程的优先级。 六:线程的同步: 常用的同步方法就是使用synchronized关键字 为什么要使用线程同步,因为当一个资源可能会有多个线程访问的时候,当第一个线程进来之后对资源进行了修改,但是在修改的过程中第二个线程也进来了,那第二个线程取到的数据就不是最新的数据,是个虚假的数据,那么这个线程所执行的操作都没有意义了; 看个小例子: 1 package Threads; 2 3 public class Thread3 implements Runnable{ 4 private static int a=10; 5 @Override 6 public void run() { 7 // TODO Auto-generated method stub 8 try { 9 Tong(); 10 } catch (InterruptedException e) { 11 // TODO Auto-generated catch block 12 e.printStackTrace(); 13 } 14 } 15 public static void Tong() throws InterruptedException{ 16 for (int i = 0; i < 10; i++) { 17 System.out.println(Thread.currentThread().getName()+"||||"+(--a)); 18 Thread.sleep(1000); 19 } 20 } 21 } 22 23 24 25 26 package Threads; 27 28 public class Test3 { 29 public static void main(String[] args) throws InterruptedException { 30 System.out.println("开始:"); 31 Thread3 t2=new Thread3(); 32 Thread t=new Thread(t2); 33 Thread t3=new Thread(t2); 34 t.start(); 35 t3.start(); 36 t.join(); 37 t3.join(); 38 System.out.println("结束:"); 39 } 40 } 里面的sleep就是模拟让两个线程同时访问一个资源 运行结果为: 我们可以看到是有重复数据的,也就是虚假的数据 thread-0和thread-1同时访问了count:7这个数据; 解决办法就是使用同步方法: 1 package Threads; 2 3 public class Thread3 implements Runnable{ 4 private static int a=10; 5 @Override 6 public void run() { 7 // TODO Auto-generated method stub 8 try { 9 Tong(); 10 } catch (InterruptedException e) { 11 // TODO Auto-generated catch block 12 e.printStackTrace(); 13 } 14 } 15 public static synchronized void Tong() throws InterruptedException{ 16 for (int i = 0; i < 10; i++) { 17 System.out.println(Thread.currentThread().getName()+"||||"+(--a)); 18 Thread.sleep(1000); 19 } 20 } 21 } 加上synchronized 关键字 总结:其实同步就是对这个资源对象就行加锁,只能同时有一个线程能操作这个资源,如果有第二个线程要访问,那只有等第一个线程执行结束之后才能进行访问; 七:实现经典多线程例子生产者,消费者: 首先创建商品类 1 package Threads; 2 3 public class Piao { 4 private int count=5; 5 6 public synchronized void sheng() throws InterruptedException{ 7 if(count>=10){ 8 System.out.println("商品过多:"+count); 9 wait(); 10 }else{ 11 System.out.println("商品生产成功:"+(++count)); 12 notify(); 13 } 14 } 15 public synchronized void mai() throws InterruptedException{ 16 if(count<=0){ 17 System.out.println("商品库存不够:"+count); 18 wait(); 19 }else{ 20 System.out.println("商品卖出成功:"+(--count)); 21 notify(); 22 } 23 } 24 } 在创建生产者和消费者: 1 package Threads; 2 3 public class Sheng implements Runnable{ 4 private Piao p; 5 6 public Sheng(Piao p) { 7 super(); 8 this.p = p; 9 } 10 @Override 11 public void run() { 12 // TODO Auto-generated method stub 13 for (int i = 0; i < 10; i++) { 14 try { 15 p.sheng(); 16 } catch (InterruptedException e) { 17 // TODO Auto-generated catch block 18 e.printStackTrace(); 19 } 20 } 21 } 22 } 23 24 25 26 27 package Threads; 28 29 public class Mai implements Runnable{ 30 private Piao p; 31 32 public Mai(Piao p) { 33 super(); 34 this.p = p; 35 } 36 @Override 37 public void run() { 38 // TODO Auto-generated method stub 39 for (int i = 0; i < 10; i++) { 40 try { 41 p.mai(); 42 } catch (InterruptedException e) { 43 // TODO Auto-generated catch block 44 e.printStackTrace(); 45 } 46 } 47 } 48 } 测试类: 1 package Threads; 2 3 public class Test4 { 4 5 public static void main(String[] args) { 6 // TODO Auto-generated method stub 7 Piao p=new Piao(); 8 new Thread(new Mai(p)).start(); 9 new Thread(new Sheng(p)).start(); 10 } 11 12 } 运行结果为: 欢迎大家一起说出自己的想法。

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

Linux常用基础命令

一、系统目录结构 约定俗成: bin (binaries)存放二进制可执行文件 sbin (super user binaries)存放二进制可执行文件,只有root才能访问 etc (etcetera)存放系统配置文件 usr (unix shared resources)用于存放共享的系统资源 home 存放用户文件的根目录 root 超级用户目录 dev(devices)用于存放设备文件 lib (library)存放跟文件系统中的程序运行所需要的共享库及内核模块 mnt (mount)系统管理员安装临时文件系统的安装点 boot 存放用于系统引导时使用的各种文件 tmp (temporary)用于存放各种临时文件 var (variable)用于存放运行时需要改变数据的文件 二、基本命令 1.目录操作 相对路径和绝对路径说明: 现在在/home/dijia478/下 ./a/b.txt和a/b.txt都表示相对路径,当前目录下的a文件夹下的b.txt文件 /home/dijia478/a/b.txt表示绝对路径,根目录下的home文件夹下的dijia478文件夹下的a文件夹下的b.txt文件 cd ./a 切换到当前目录的a文件夹 cd .. 切换到上一层目录 cd / 切换到系统根目录 cd ~ 切换到用户主目录 cd - 切换到上一个所在目录 pwd 显示当前所在目录的绝对路径 2.查看文件列表 ls /path/显示该目录所有文件或文件夹名 ls -a 显示所有文件或文件夹名(包含隐藏的) ls -l 按列表显示所有文件或文件夹,缩写成ll ll -h 友好的显示文件大小(显示成K,MB,GB) 3.创建和删除文件夹 mkdir app 创建app文件夹 mkdir –p app2/test 级联创建aap2以及test文件夹 rmdir app 删除app目文件夹(需要是空文件夹) 4.文件操作 rm a.txt 删除a.txt文件,删除需要用户确认,y/n rm -f a.txt 不询问,直接删除a.txt文件 rm -r a 递归删除a文件夹(无论是否有内容) rm -rf a 不询问递归删除a文件夹(慎用) rm -rf * 删除当前目录下所有内容(最好别用) rm -rf /* no 作 no die(Linux系统就玩完了) cp a.txt b.txt 将a.txt复制为b.txt文件 cp a.txt ../ 将a.txt文件复制到上一层目录中 mv a.txt ../ 将a.txt文件移动到上一层目录中 mv a.txt b.txt 将a.txt文件重命名为b.txt touch a.txt 创建一个空的a.txt文件 echo "good good study" > a.txt 把">"左边的输出内容放到右边的文件里去,如果存在就覆盖,如果不存在就创建 vi a.txt 用文本编辑器编辑一个文件,如果不存在就创建 5.文件打包归档和压缩 tar -cvf file.tar dirpath filepath 将dir文件夹和file文件在当前目录下打包成file.tar tar –xvf file.tar 解包到当前目录 gzip file.tar 压缩文件或文件夹 gzip –d file.tar.gz 解压文件或文件夹 tar -czvf file.tar.gz dirpath filepath 将dir文件夹和file文件在当前目录下打包并压缩成file.tar.gz tar -xzvf file.tar.gz 解压并解包到当前目录下 tar -xzvf file.tar.gz -C /home/dijia478/ 解压并解包到/home/dijia478/目录下 常用参数: -c:创建一个新tar文件 -v:显示运行过程的信息 -f:指定文件名 -z:调用gzip压缩命令进行压缩 -t:查看压缩文件的内容 -x:解开tar文件 zip test.txt.zip test.txt 也是打包并压缩 unzip test.txt.zip 解包并解包 6.查看文本文件 cat a.txt 一次性显示整个文件内容 more a.txt 可以分页看(翻页:空格,往回翻:b ,退出: q或者 Ctrl+C) less a.txt 不仅可以分页,还可以方便地搜索,回翻等操作(翻页:空格,往回翻:↑,往下翻:↓,退出:q或者 Ctrl+C) tail -10 a.txt 查看文件的尾部的10行 tail -f user.log 实时刷新显示文件的尾部,这条命令对于观察调试程序的运行非常重要 head -20 a.txt 查看文件的头部20行 注:ctrl+c 结束查看 7.搜索查找命令 grep‘haha’./* 打印当前目录下所有文件中含有'haha'的地方(支持正则表达式) grep -c‘haha’./* 显示匹配到的行数 grep -r‘haha’./* 对子目录也进行遍历搜索 grep -l‘haha’./* 只显示命中的文件名 grep -n‘haha’./* 显示命中的行号 grep -ld skip‘haha’./* 显示命中的文件名,不要搜索子目录 参数含义: -r 递归搜索子目录 -l 只列出有匹配行的文件名 -n 列出匹配行的行号 -d skip 不搜索子文件夹 常用grep跟其他命令组合使用来查找我们关心的信息(管道) 示例: service --status-all | grep 'httpd' 在当前系统所有服务中查找'httpd' netstat -nltp | grep '22' 查找监听'22'端口的服务程序 ps –ef | grep java 查找系统中当前运行的java进程 find ./ -name '*.txt' 查找以.txt结尾的文件(会遍历当前目录) find ./ -name ‘install*’ 查找以install开头的文件或文件夹 find ./ -type f 查找普通文件 find ./ -type l 查找连接文件(快捷方式) 8.文本命令 > 重定向输出,覆盖原有内容; >> 重定向输出,又追加功能; cat /etc/passwd > a.txt 将密码文件输出定向到a.txt中 cat /etc/passwd >> a.txt 输出并且追加 ifconfig > ifconfig.txt 保存ip信息到文件中 wc -l a.txt 统计文本行数 wc -w a.txt 统计文本单词数 wc -m a.txt 统计文本字符数 wc -c a.txt 统计文本字节数 vi编辑器 vi filepath 打开文件 按Esc键 切换到命令行模式 切换到插入模式: i 在当前位置生前插入 I 在当前行首插入 a 在当前位置后插入 A 在当前行尾插入 o 在当前行之后插入一行 O 在当前行之前插入一行 dd 删除整行 7 dd 向上删除7行 U 回退(类似于windows 中 ctrl + z) R 替换 :(冒号) 切换到底行模式 :q 退出 :wq 保存并退出(shift + zz也可以保存) :q! 不保存退出 9.其他常用命令 echo $JAVA_HOME 输出变量JAVA_HOME的值 whoami 查询当前登陆的用户名 which ls 查询ls命令的$PATH路径 mkdir test && cd test 只有在 && 左边的命令返回真(命令返回值 $? == 0),&& 右边的命令才会被执行。 只要有一个命令返回假(命令返回值 $? == 1),后面的命令就不会被执行。 三、用户管理命令 1.添加用户 基本示例: useradd user001 passwd 123456 需要设置密码 参数手册: -u 指定组ID(uid) -g 指定所属的组名(gid) -G 指定多个组,用逗号“,”分开(Groups) -c 用户描述(comment) -d 指定用户目录 -e 失效时间(expire date) 2.删除用户 userdel user002 这样删除的时候,用户的主目录会被保留 userdel -r user002 删除用户的同时删除用户的主目录 3.修改用户属性 指令:usermod 参数: -l 修改用户名 (login)usermod -l a b(b改为a) -g 修改组 usermod -g sys tom -d 修改用户的宿主目录 -G 添加多个组 usermod -G sys,root tom -L 锁定用户账号密码(Lock) -U 解锁用户账号(Unlock) 示例: usermod -l user002 user001 将user001的登陆名改为user002 usermod -g root user002 将user002的组改为root组 usermod -G hello1,hello2 user002 给user002添加两个组hello1,hello2 usermod -d /home/dijia478 user002 将user002的主目录改成/home/dijia478 (要事先创建dijia478目录,并且拷入环境变量文件) 4.用户组管理 用户组相关属性: 每个用户至少属于一个用户组 (创建新用户时如果不指定所属组,则会自动创建并归属到一个跟用户名同名的组) 每个用户组可以包含多个用户 同一个用户组的用户享有该组共有的权限 用户组管理操作命令: groupadd java 创建用户组 groupdel hello2 删除用户组 groupmod –n newname oldname 修改用户组名称 groups user002 查看用所属的组 5.用户及用户组相关配置文件 用户配置信息存放位置: 保存用户信息的文件:/etc/passwd 保存密码的文件:/etc/shadow passwd文件示例: user002:x:500:500:user002:/home/user002:/bin/bash passwd文件各字段含义: account:password:UID:GID:GECOS:directory:shell shadow文件示例: user002:$1$vRug41$UUxYzdP0i6s6wtUPieGDQ/:18617:0:99999:7::: shadow文件各字段含义: 用户名 登陆系统的用户名 密码 加密密码 最后一次修改时间 用户最后一次修改密码距现在的天数,从1970-1-1起 最小时间间隔 两次修改密码之间的最小天数 最大时间间隔 密码有效天数 警告时间 从系统警告到密码失效的天数 账号闲置时间 账号闲置时间 失效时间 密码失效的天数 标志 标志 用户组配置信息存放位置: 保存用户组的文件:/etc/group 保存用户组密码的文件:/etc/gshadow(设置组管理员时才有用) 6.其他的用户管理命令 id user002 查看一个用户的UID和GID su user001 切换到user001用户 su - user001 切换到user001用户,并且将环境也切换到user001用户的环境(推荐使用) exis 退出当前shell(会退出当前登录用户) 四、网络配置管理 1.网卡地址配置 检查网络连通性: ping 要测试的ip 查看ip地址 ifconfig 查看所有网络设备的地址信息 ifconfig eth0 查看指定的eth0以太网卡的地址信息 修改ip地址 ifconfig eth0 192.168.2.150 netmask 255.255.255.0 通过setup修改网络配置 在root权限下执行setup指令可以打开一个带菜单的伪图形界面来修改网络配置 通过配置文件修改ip地址 vi /etc/sysconfig/network-scripts/ifcfg-eth0 修改该配置文件即可改ip地址 [root@localhost ~]# vi /etc/sysconfig/network-scripts/ifcfg-eth0 DEVICE=eth0 BOOTPROTO=none HWADDR=00:0c:29:f1:b2:e8#网卡物理地址 IPV6INIT=yes NM_CONTROLLED=yes ONBOOT=yes TYPE=Ethernet UUID="b3cd1ac3-aecf-4845-9812-9337135c072b" IPADDR=192.168.2.199# IP地址 NETMASK=255.255.255.0#子网掩码 DNS2=8.8.8.8#域名服务器2 GATEWAY=192.168.2.1#网关 DNS1=192.168.2.1#域名服务器1 USERCTL=no 2.主机名配置管理 查看主机名 在shell提示符的@后有显示 或者用hostname指令打印出主机名 修改主机名 vi /etc/sysconfig/network 修改其中的hostname配置项: HOSTNAME=newname 修改完成之后要重启服务器才能生效 要想立即生效,可以执行指令 hostname newname,然后注销重登陆 主机名-IP映射,服务器本地映射 服务器网络寻址时默认是现在本地的hosts文件中查找IP映射,通过修改hosts来映射局域网内部的主机名非常方便 实现方法,将局域网内的每一台主机的“hostnamip”写入每一台主机的hosts文件中: vi /etc/hosts 192.168.2.150 user001-server-01 192.168.2.151 user001-server-02 192.168.2.152 user001-server-03 3.网络服务启动与停止 列出系统所有应用服务状态: service --status-all 查看指定服务运行状态: service servicename status 启动服务: service servicename start 停止服务: service servicename stop 列出所有服务的随机自起配置: chkconfig --list 关闭服务的随机自起: chkconfig servicename off 开启服务的随机自起: chkconfig servicename on 常用示例: 重启网络服务:service network restart 停止httpd:service httpd stop 启动httpd:service httpd start 关闭防火墙服务:service iptables stop 关闭防火墙自动启动:chkconfig iptables off 4.查看网络连接信息 指令:netstat netstat常用示例: netstat -natp netstat -nltp netstat -naup netstat -an | grep 3306 查询3306端口占用情况 常用参数解释: -a 显示所有连接和监听端口 -l 只显示监听进程 -t (tcp)仅显示tcp相关选项 -u (udp)仅显示udp相关选项 -n 拒绝显示别名,能显示数字的全部转化成数字。 -p 显示建立相关链接的程序名 五、常用系统管理命令 1.磁盘/内存使用信息查看 df -h 查看磁盘空间状态信息 du -sh * 查看指定目录下所有子目录和文件的汇总大小 free 查看内存使用状况 2.进程管理 top 查看实时刷新的系统进程信息 ps -ef 查看系统中当前瞬间的进程信息快照 ps -ef | grep myshell.sh 搜索myshell进程的信息 kill -9 pid 杀掉进程(-9 表示强制杀死) 3.sudo权限的配置 root用户因为具有不受限制的权限,使用不慎可能对系统造成不可估量的损害,因而,生产实际中,轻易不要使用su去切换到root的身份 如果普通用户需要使用一些系统级管理命令,可以使用sudo来执行,比如 sudo vi /etc/profile 给普通用户赋予sudo权限,配置方法如下: 例如,要给hadoop用户赋予sudo任何指令(或某条指定的命令)的权利,则编辑sudoers文件vi /etc/sudoers 在其中加入需要赋予权限的用户(红色标识) …… root ALL=(ALL) ALL #让hadoop用户可以用root身份执行所有指令 hadoopALL=(ALL) ALL #让user002用户可以用root身份执行所有指令 ItcastALL=(root)/usr/sbin/useradd, /usr/bin/passwd …… 检查是否生效: [root@user001-server-01 user002]# sudo -lU user002 User user002 is not allowed to run sudo on user001-server-01. 4.修改系统的默认启动级别 vi /etc/inittab # 0 - halt (Do NOT set initdefault to this) # 1 - Single user mode # 2 - Multiuser, without NFS (The same as 3, if you do not have networking) # 3 - Full multiuser mode # 4 - unused # 5 - X11 # 6 - reboot (Do NOT set initdefault to this) # id:3:initdefault: ~ 用level 3 就启动全功能状态的命令行界面,5是图形界面。不要设置其他的,容易作死。 在命令行模式下,用startx可以手动启动图形界面(在服务器上操作) 5.文件权限管理 Linux三种文件类型: 普通文件: 包括文本文件、数据文件、可执行的二进制程序文件等。 目录文件: Linux系统把目录看成是一种特殊的文件,利用它构成文件系统的树型结构。 设备文件: Linux系统把每一个设备都看成是一个文件 文件类型标识: 普通文件(-) 目录(d) 符号链接(l) * 进入etc可以查看,相当于快捷方式 字符设备文件(c) 块设备文件(s) 套接字(s) 命名管道(p) 文件权限管理: chmod u+rwx a.txt 为a.txt添加所属用户的rwx权限 chmod 755 a.txt 为a.txt设置所属用户rwx权限,所属组rx权限,其他用户rx权限(r-4,w-2,x-1) chmod u=rwx,g=rx,o=rx a.txt (u代表所属用户 g代表所属组的成员用户 o代表其他用户) chown user001:hello1 a.txt 将a.txt的所有者改成user001用户,所属组改成hello1组(需要root权限) chown -R user001:hello1 dir 将dir文件夹的所有者改成user001用户,所属组改成hello1组(需要root权限) 6.其他系统管理命令 date "+%Y%m%d" 按格式显示当前系统时间 date -s "2020-01-01 10:10:10" 设置系统时间 clear 清屏幕(只是滚到上面看不到了) uname 显示系统信息。 uname -a 显示本机详细信息。 依次为:内核名称(类别),主机名,内核版本号,内核版本,内核编译日期,硬件名,处理器类型,硬件平台类型,操作系统名称

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

elk组件 基础语法

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 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 Shipper->Broker->Indexer->ES 1.input input{stdin{}} output{ stdout{codec=>rubydebug} } file { codec=>multiline{ pattern=> "^\s" what=> "previous" } path=>[ "xx" , "xx" ] exclude=> "1.log" add_field=>[ "log_ip" , "xx" ] tags=> "tag1" #设置新事件的标志 delimiter=> "\n" #设置多长时间扫描目录,发现新文件 discover_interval=>15 #设置多长时间检测文件是否修改 stat_interval=>1 #监听文件的起始位置,默认是end start_position=>beginning #监听文件读取信息记录的位置 sincedb_path=> "E:/software/logstash-1.5.4/logstash-1.5.4/test.txt" #设置多长时间会写入读取的位置信息 sincedb_write_interval=>15 } 2.filter filter{ multiline{ #指定合并规则——所有不是以数字开头的行需要被合并 pattern=> "^[^\d]" #合并到哪里——上一行 what=> "previous" } filter{ multiline{ type => "type" #类型,不多说 pattern=> "pattern,aregexp" #参数,也可以认为是字符,有点像grep,如果符合什么字符就交给下面的what去处理 negate=>boolean what=> "previous" or "next" #这个是符合上面pattern的要求后具体怎么处理,处理方法有两种,合并到上面一条日志或者下面的日志 } } filter{ grep { match=>[ "@message" , "PHPFatalerror" ] drop=> false add_tag=>[fatal_error] } grep { tags=>[fatal_error] match=>[ "@message" , ".*(xbox\.com|xbox\.mib\.com\.cn|supports\.game\.mib\.com\.cn)" ] drop=> false add_tag=>[xboxerror] } } #过滤掉内容包含5.3.3与down以外日志 filter{ if [message]!~ "5.3.3|down" { ruby{ code=> "event.cancel" } } } #使用自带的过滤规则显示更多的字段 filter{ grok{ match=>{ "message" => "%{COMBINEDAPACHELOG}" } } } #合并不是以[开头的日志 filter{ multiline{ pattern=> "^[^[]" negate=> true what=> "previous" } } filter{ if [path]=~ "error" { mutate{replace=>{ "type" => "apache_error" }} grok{ match=>{ "message" => "%{COMBINEDAPACHELOG}" } } } date { match=>[ "timestamp" , "dd/MMM/yyyy:HH:mm:ssZ" ] } } filter{ if [path]=~ "access" { mutate{replace=>{ type => "apache_access" }} grok{ match=>{ "message" => "%{COMBINEDAPACHELOG}" } } date { match=>[ "timestamp" , "dd/MMM/yyyy:HH:mm:ssZ" ] } } else if [path]=~ "error" { mutate{replace=>{ type => "apache_error" }} } else { mutate{replace=>{ type => "random_logs" }} } } 3.output 发邮件 output{ email{ match=>[ "@message" , "aaaaa" ] to=> "storyskya@gmail.com" from=> "monitor@mib.com.cn" options=>[ "smtpIporHost" , "smtp.mibnet.com" , "port" , "25" , "userName" , "monitor@mib.com.cn" , "starttls" , "true" , "password" , "opmonitor" , "authenticationType" , "login" ] subject=> "123" body=> '123' via=>smtp } } output{ if [ type ]== "syslog" { elasticsearch{ hosts=> "172.16.0.102:9200" index=> "syslog-%{+YYYY.MM.dd}" } } if [ type ]== "nginx" { elasticsearch{ hosts=> "172.16.0.102:9200" index=> "nglog-%{+YYYY.MM.dd}" } } #匹配内容包含paramiko与simplejson的日志通邮件发送 if [message]=~ /paramiko |simplejson/{ email{ to=> "12222222@wo.cn" from=> "good_zabbix@163.com" contenttype=> "text/plain;charset=UTF-8" address=> "smtp.163.com" username=> "test@163.com" password=> "12344" subject=> "服务器%{host}日志异常" body=> "%{@timestamp}%{type}:%{message}" } } } output{ stdout{codec=>rubydebug} redis{ host=> '192.168.1.104' data_type=> 'list' key=> 'logstash:redis' } } output{ elasticsearch{host=>localhost} stdout{codec=>rubydebug} } 替换 mutate{ type => "phplog" gsub=>[ "@message" , "'" , "\"" ] } 调试 #/usr/local/logstash-1.5.2/bin/logstash-e'input{stdin{}}output{stdout{}}' curl' logstash-e 'input{stdin{}}output{stdout{codec=>rubydebug}}' # logstash agent -f logstash-simple.conf --verbose //开启debug模式 本文转自 liqius 51CTO博客,原文链接:http://blog.51cto.com/szgb17/1865408,如需转载请自行联系原作者

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

Docker 基础命令介绍

Docker是一种C/S结构,所以就会有客户端和服务端。Docker支持很多子命令,例如我们在命令行docker然后tab键会出来很多命令 当然docker工具很多,除了docker命令行工具,用户也可以通过 REST API 与服务器通信 Docker daemon是服务器组件,以 Linux 后台服务的方式运行。可以通过命令:systemctl status docker.service看到 Docker daemon 运行在 Docker host 上,负责创建、运行、监控容器,构建、存储镜像。 监听地址的配置: 默认docker daemon只能监听本地host,如果远程要访问,需要打开tcp监听,如下: 1 /etc/systemd/system/multi-user .target.wants /docker .service 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 [Unit] Description=DockerApplicationContainerEngine Documentation=https: //docs .docker.com After=network.targetdocker.socketfirewalld.service Requires=docker.socket [Service] Type=notify #thedefaultisnottousesystemdforcgroupsbecausethedelegateissuesstill #existsandsystemdcurrentlydoesnotsupportthecgroupfeaturesetrequired #forcontainersrunbydocker ExecStart= /usr/bin/dockerd -Hfd: // #上面这里如果改成这样就开启了监听远程所有端口:ExecStart=/usr/bin/dockerd-Hfd://-Htcp://0.0.0.0 ExecReload= /bin/kill -sHUP$MAINPID LimitNOFILE=1048576 #Havingnon-zeroLimit*scausesperformanceproblemsduetoaccountingoverhead #inthekernel.Werecommendusingcgroupstodocontainer-localaccounting. LimitNPROC=infinity LimitCORE=infinity #UncommentTasksMaxifyoursystemdversionsupportsit. #Onlysystemd226andabovesupportthisversion. TasksMax=infinity TimeoutStartSec=0 #setdelegateyessothatsystemddoesnotresetthecgroupsofdockercontainers Delegate= yes #killonlythedockerprocess,notallprocessesinthecgroup KillMode=process [Install] WantedBy=multi-user.target 重启服务端docker 1 2 systemctldaemon-reload systemctlrestartdocker.service 调试 可以通过在客户端通过H参数来指定服务器和info子命令来查看服务端信息 这里可以看到哦啊服务端运行情况 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 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 root@d1: /etc/apt #docker-H192.168.56.132info Containers:1 Running:0 Paused:0 Stopped:1 Images:1 ServerVersion:17.03.1-ce StorageDriver:aufs RootDir: /var/lib/docker/aufs BackingFilesystem:extfs Dirs:9 Dirperm1Supported: true LoggingDriver:json- file CgroupDriver:cgroupfs Plugins: Volume: local Network:bridgehostmacvlannulloverlay Swarm:inactive Runtimes:runc DefaultRuntime:runc InitBinary:docker-init containerdversion:4ab9917febca54791c5f071a9d1f404867857fcc runcversion:54296cf40ad8143b62dbcaa1d90e520a2136ddfe initversion:949e6fa SecurityOptions: apparmor seccomp Profile:default KernelVersion:4.4.0-31-generic OperatingSystem:Ubuntu16.04.1LTS OSType:linux Architecture:x86_64 CPUs:2 TotalMemory:3.842GiB Name:d1 ID:SQ7Y:TBJA:LS5G:IQNB:CIHC:6T2D:J22X:F3QK:7AS2:7KLN:NIIQ:JLXY DockerRootDir: /var/lib/docker DebugMode(client): false DebugMode(server): false Registry:https: //index .docker.io /v1/ WARNING:Noswaplimitsupport Experimental: false InsecureRegistries: 127.0.0.0 /8 RegistryMirrors: http: //febb9aec .m.daocloud.io LiveRestoreEnabled: false 本文转自 kesungang 51CTO博客,原文链接:http://blog.51cto.com/sgk2011/1923361,如需转载请自行联系原作者

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

Mongodb基础实践(二)

在前面的文章里面主要介绍了MongoDB的文档,集合,数据库等操作和对文档的增、删、改相关知识,接下来会总结一点有关查询的相关知识。 在MySQL中,我们知道数据查询是优化的主要内容,读写分离等技术都是可以用来处理数据库查询优化的,足以见数据库查询是每个系统中很重要的一部分,之前介绍了find的简单使用,下面会介绍一些相对比较复杂一点的查询。 一、数据查询 MySQL数据库中主要是用select 结合where子句实现数据的查询,功能特别强大,例如多表联合查询、支持正则表达式等。不在这里做过多的相关介绍。这里主要介绍MongoDB的相关查询,MongoDB中主要用find()实现数据的查询,同时也可以使用一些条件限制。 1.1显示单条数据 在上篇文章中提到了find()的使用,但是每次查询数据,都是查询所有的,显示其中的一部分,可以用it迭代。有时候我们想要查询其中的一条数据,具体操作要根据具体需求实现。 MongoDB 查询数据的语法 1 db.collection. find (query,projection) query :可选,使用查询操作符指定查询条件 projection :可选,使用投影操作符指定返回的键。查询时返回文档中所有键值, 只需省略该参数即可(默认省略)。可以使用 pretty() 方法以易读的方式来读取数据,,语法格式如下 1 >db.col. find ().pretty() pretty() 方法以格式化的方式来显示所有文档。 例如: 1 2 3 4 5 6 7 8 9 10 11 db.winner. find ().pretty() { "_id" :ObjectId( "592e7d1caaa464fa8a557e95" ), "winne" :1955} { "_id" :ObjectId( "592e7d1eaaa464fa8a557e96" ), "winne" :1955} { "_id" :ObjectId( "592e7d1faaa464fa8a557e97" ), "winne" :1955} { "_id" :ObjectId( "592e7d1faaa464fa8a557e98" ), "winne" :1955} { "_id" :ObjectId( "592e7d21aaa464fa8a557e99" ), "winne" :1955} { "_id" :ObjectId( "592e7d22aaa464fa8a557e9a" ), "winne" :1955} { "_id" :ObjectId( "592e7e14aaa464fa8a557ec4" ), "winne" :41} { "_id" :ObjectId( "592e7e14aaa464fa8a557ec5" ), "winne" :42} { "_id" :ObjectId( "592e7e14aaa464fa8a557ec6" ), "winne" :43} { "_id" :ObjectId( "592e7e14aaa464fa8a557ec7" ), "winne" :44} 1、查询某个集合中的所有数据 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 db.winner. find () { "_id" :ObjectId( "592e7d1caaa464fa8a557e95" ), "winne" :1955} { "_id" :ObjectId( "592e7d1eaaa464fa8a557e96" ), "winne" :1955} { "_id" :ObjectId( "592e7d1faaa464fa8a557e97" ), "winne" :1955} { "_id" :ObjectId( "592e7d1faaa464fa8a557e98" ), "winne" :1955} { "_id" :ObjectId( "592e7d21aaa464fa8a557e99" ), "winne" :1955} { "_id" :ObjectId( "592e7d22aaa464fa8a557e9a" ), "winne" :1955} { "_id" :ObjectId( "592e7e14aaa464fa8a557ec4" ), "winne" :41} { "_id" :ObjectId( "592e7e14aaa464fa8a557ec5" ), "winne" :42} { "_id" :ObjectId( "592e7e14aaa464fa8a557ec6" ), "winne" :43} { "_id" :ObjectId( "592e7e14aaa464fa8a557ec7" ), "winne" :44} { "_id" :ObjectId( "592e7e14aaa464fa8a557ec8" ), "winne" :45} { "_id" :ObjectId( "592e7e14aaa464fa8a557ec9" ), "winne" :46} { "_id" :ObjectId( "592e7e14aaa464fa8a557eca" ), "winne" :47} { "_id" :ObjectId( "592e7e14aaa464fa8a557ecb" ), "winne" :48} { "_id" :ObjectId( "592e7e14aaa464fa8a557ecc" ), "winne" :49} { "_id" :ObjectId( "592e7e14aaa464fa8a557ecd" ), "winne" :50} { "_id" :ObjectId( "592e7e14aaa464fa8a557ece" ), "winne" :51} { "_id" :ObjectId( "592e7e14aaa464fa8a557ecf" ), "winne" :52} { "_id" :ObjectId( "592e7e14aaa464fa8a557ed0" ), "winne" :53} { "_id" :ObjectId( "592e7e14aaa464fa8a557ed1" ), "winne" :54} Type "it" for more 默认显示20条数据,其他数据可以输入it迭代。 2、显示一条数据 find()是输出所有结果,里面可能有些文档内容相同,但是“_id”肯定是不一样的,这时我们可以使用findOne()方法查询,或者可以使用db.winner.find({winne:1955}).limit(1)。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 db.winner. find ({winne:1955}) { "_id" :ObjectId( "592e7d1caaa464fa8a557e95" ), "winne" :1955} { "_id" :ObjectId( "592e7d1eaaa464fa8a557e96" ), "winne" :1955} { "_id" :ObjectId( "592e7d1faaa464fa8a557e97" ), "winne" :1955} { "_id" :ObjectId( "592e7d1faaa464fa8a557e98" ), "winne" :1955} { "_id" :ObjectId( "592e7d21aaa464fa8a557e99" ), "winne" :1955} { "_id" :ObjectId( "592e7d22aaa464fa8a557e9a" ), "winne" :1955} 假如要查询winner集合中winne=1955的一条数据,而用 find ()查询出所有的数据,这时就可以使用findOne() db.winner.findOne({winne:1955}) { "_id" :ObjectId( "592e7d1caaa464fa8a557e95" ), "winne" :1955} 或者可以使用 db.winner. find ({winne:1955}).limit(1) { "_id" :ObjectId( "592e7d1caaa464fa8a557e95" ), "winne" :1955} 两者的区别 findOne()有点类似MySQL里面的distinct,会返回查询的第一条结果,如果搜索不到想要的数据就会 返回NULL, db.winner.findOne({winne:200888}) null db.winner. find ({winne:1955}).limit(1)方法就和MySQL里面的limit是一样的,主要是限制查询结果的条数。 3、查询满足一定条件的数据 在MySQL中查询时,可以结合where以及字段等信息查询数据,而MongoDB中也是可以的,同样可以支持一些条件判断语句。 格式 范例 RDBMS中的类似语句 等于 {<key>:<value>} db.col.find({"winne":"1995"}).pretty() wherewinne= '50' 小于 {<key>:{$lt:<value>}} db.col.find({"winne":{$lt:50}}).pretty() wherewinne< 50 小于或等于 {<key>:{$lte:<value>}} db.col.find({"winne":{$lte:50}}).pretty() wherewinne<= 50 大于 {<key>:{$gt:<value>}} db.col.find({"winne":{$gt:50}}).pretty() wherewinne> 50 大于或等于 {<key>:{$gte:<value>}} db.col.find({"winne":{$gte:50}}).pretty() wherewinne>= 50 不等于 {<key>:{$ne:<value>}} db.col.find({"winne":{$ne:50}}).pretty() wherewinne!= 50 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 33 $gt--------greaterthan$gte---------gtequal $lt-------- less than$lte---------ltequal $ ne -----------notequal 1、查询winner集合中winne<50的相关数据 db.winner. find ({winne:{$lt:50}}) { "_id" :ObjectId( "592e7e14aaa464fa8a557ec4" ), "winne" :41} { "_id" :ObjectId( "592e7e14aaa464fa8a557ec5" ), "winne" :42} { "_id" :ObjectId( "592e7e14aaa464fa8a557ec6" ), "winne" :43} { "_id" :ObjectId( "592e7e14aaa464fa8a557ec7" ), "winne" :44} { "_id" :ObjectId( "592e7e14aaa464fa8a557ec8" ), "winne" :45} { "_id" :ObjectId( "592e7e14aaa464fa8a557ec9" ), "winne" :46} { "_id" :ObjectId( "592e7e14aaa464fa8a557eca" ), "winne" :47} { "_id" :ObjectId( "592e7e14aaa464fa8a557ecb" ), "winne" :48} { "_id" :ObjectId( "592e7e14aaa464fa8a557ecc" ), "winne" :49} { "_id" :ObjectId( "592e7e17aaa464fa8a557f28" ), "winne" :41} { "_id" :ObjectId( "592e7e17aaa464fa8a557f29" ), "winne" :42} { "_id" :ObjectId( "592e7e17aaa464fa8a557f2a" ), "winne" :43} { "_id" :ObjectId( "592e7e17aaa464fa8a557f2b" ), "winne" :44} 2、查询winner集合中40=<winne<50的相关数据 db.winner. find ({winne:{$gte:40,$lt:45}}) { "_id" :ObjectId( "592e7e14aaa464fa8a557ec4" ), "winne" :41} { "_id" :ObjectId( "592e7e14aaa464fa8a557ec5" ), "winne" :42} { "_id" :ObjectId( "592e7e14aaa464fa8a557ec6" ), "winne" :43} { "_id" :ObjectId( "592e7e14aaa464fa8a557ec7" ), "winne" :44} { "_id" :ObjectId( "592e7e17aaa464fa8a557f28" ), "winne" :41} { "_id" :ObjectId( "592e7e17aaa464fa8a557f29" ), "winne" :42} { "_id" :ObjectId( "592e7e17aaa464fa8a557f2a" ), "winne" :43} { "_id" :ObjectId( "592e7e17aaa464fa8a557f2b" ), "winne" :44} { "_id" :ObjectId( "592e7e18aaa464fa8a557f8c" ), "winne" :41} { "_id" :ObjectId( "592e7e18aaa464fa8a557f8d" ), "winne" :42} { "_id" :ObjectId( "592e7e18aaa464fa8a557f8e" ), "winne" :43} { "_id" :ObjectId( "592e7e18aaa464fa8a557f8f" ), "winne" :44} 4、MongoDB AND 条件 MongoDB 的 find() 方法可以传入多个键(key),每个键(key)以逗号隔开,语法格式如下: >db.winner.find({key1:value1, key2:value2}).pretty() 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 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 #插入测试数据 for (i=0;i<20;i++)db.info2.insert({name: "linux" , object: "SA" , company: "docker" , phone:i}) for (i=0;i<20;i++)db.info2.insert({name: "openstack" , object: "DBA" , company: "could" , phone:i}) #检查测试数据 >db.info2. find () db.info2. find () { "_id" :ObjectId( "592f838dd276944818f7edb4" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :0} { "_id" :ObjectId( "592f838dd276944818f7edb5" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :1} { "_id" :ObjectId( "592f838dd276944818f7edb6" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :2} { "_id" :ObjectId( "592f838dd276944818f7edb7" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :3} { "_id" :ObjectId( "592f838dd276944818f7edb8" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :4} { "_id" :ObjectId( "592f838dd276944818f7edb9" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :5} { "_id" :ObjectId( "592f838dd276944818f7edba" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :6} { "_id" :ObjectId( "592f838dd276944818f7edbb" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :7} { "_id" :ObjectId( "592f838dd276944818f7edbc" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :8} { "_id" :ObjectId( "592f838dd276944818f7edbd" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :9} { "_id" :ObjectId( "592f838dd276944818f7edbe" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :10} { "_id" :ObjectId( "592f838dd276944818f7edbf" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :11} { "_id" :ObjectId( "592f838dd276944818f7edc0" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :12} { "_id" :ObjectId( "592f838dd276944818f7edc1" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :13} { "_id" :ObjectId( "592f838dd276944818f7edc2" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :14} { "_id" :ObjectId( "592f838dd276944818f7edc3" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :15} { "_id" :ObjectId( "592f838dd276944818f7edc4" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :16} { "_id" :ObjectId( "592f838dd276944818f7edc5" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :17} { "_id" :ObjectId( "592f838dd276944818f7edc6" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :18} { "_id" :ObjectId( "592f838dd276944818f7edc7" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :19} >db.info2. find ().count() #检查数据的条数 40 #筛选name=linuxobject=SAphone<5 db.info2. find ({name: "linux" ,object: "SA" ,phone:{$lt:5}}) 执行 db.info2. find ({name: "linux" ,object: "SA" ,phone:{$lt:5}}) { "_id" :ObjectId( "592f838dd276944818f7edb4" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :0} { "_id" :ObjectId( "592f838dd276944818f7edb5" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :1} { "_id" :ObjectId( "592f838dd276944818f7edb6" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :2} { "_id" :ObjectId( "592f838dd276944818f7edb7" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :3} { "_id" :ObjectId( "592f838dd276944818f7edb8" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :4} 筛选name=linuxobject=SA5<phone<=10 db.info2. find ({name: "linux" ,object: "SA" ,phone:{ "$gt" :5, "$lte" :10}}) db.info2. find ({name: "linux" ,object: "SA" ,phone:{ "$gt" :5, "$lte" :10}}) { "_id" :ObjectId( "592f838dd276944818f7edba" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :6} { "_id" :ObjectId( "592f838dd276944818f7edbb" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :7} { "_id" :ObjectId( "592f838dd276944818f7edbc" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :8} { "_id" :ObjectId( "592f838dd276944818f7edbd" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :9} { "_id" :ObjectId( "592f838dd276944818f7edbe" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :10} 筛选5<phone<=10 db.info2. find ({phone:{ "$gt" :5, "$lte" :10}}) { "_id" :ObjectId( "592f838dd276944818f7edba" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :6} { "_id" :ObjectId( "592f838dd276944818f7edbb" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :7} { "_id" :ObjectId( "592f838dd276944818f7edbc" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :8} { "_id" :ObjectId( "592f838dd276944818f7edbd" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :9} { "_id" :ObjectId( "592f838dd276944818f7edbe" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :10} { "_id" :ObjectId( "592f838fd276944818f7edce" ), "name" : "openstack" , "object" : "DBA" , "company" : "could" , "phone" :6} { "_id" :ObjectId( "592f838fd276944818f7edcf" ), "name" : "openstack" , "object" : "DBA" , "company" : "could" , "phone" :7} { "_id" :ObjectId( "592f838fd276944818f7edd0" ), "name" : "openstack" , "object" : "DBA" , "company" : "could" , "phone" :8} { "_id" :ObjectId( "592f838fd276944818f7edd1" ), "name" : "openstack" , "object" : "DBA" , "company" : "could" , "phone" :9} { "_id" :ObjectId( "592f838fd276944818f7edd2" ), "name" : "openstack" , "object" : "DBA" , "company" : "could" , "phone" :10} 5 MongoDB OR 条件 MongoDB 除了有类似MySQL的AND条件语句外,还有OR 条件语句,OR 条件语句使用了关键字 $or,语法格式如下: >db.collections.find( { $or: [ {key1: value1}, {key2:value2} ] } ).pretty() 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 33 34 35 36 37 38 39 40 41 42 43 #查name=linux或者object=redis db.info2. find ( {$or:[{name: "linux" },{object: "redis" }] } ) db.info2. find (db.info2. find ( ...{$or:[{name: "linux" },{object: "redis" }]{$or:[{name: "linux" },{object: "redis" }] ... ...}} ...)) { "_id" :ObjectId( "592f838dd276944818f7edb4" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :0} { "_id" :ObjectId( "592f838dd276944818f7edb5" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :1} { "_id" :ObjectId( "592f838dd276944818f7edb6" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :2} { "_id" :ObjectId( "592f838dd276944818f7edb7" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :3} { "_id" :ObjectId( "592f838dd276944818f7edb8" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :4} { "_id" :ObjectId( "592f838dd276944818f7edb9" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :5} { "_id" :ObjectId( "592f838dd276944818f7edba" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :6} { "_id" :ObjectId( "592f838dd276944818f7edbb" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :7} { "_id" :ObjectId( "592f838dd276944818f7edbc" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :8} { "_id" :ObjectId( "592f838dd276944818f7edbd" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :9} { "_id" :ObjectId( "592f838dd276944818f7edbe" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :10} { "_id" :ObjectId( "592f838dd276944818f7edbf" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :11} { "_id" :ObjectId( "592f838dd276944818f7edc0" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :12} { "_id" :ObjectId( "592f838dd276944818f7edc1" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :13} { "_id" :ObjectId( "592f838dd276944818f7edc2" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :14} { "_id" :ObjectId( "592f838dd276944818f7edc3" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :15} { "_id" :ObjectId( "592f838dd276944818f7edc4" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :16} { "_id" :ObjectId( "592f838dd276944818f7edc5" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :17} { "_id" :ObjectId( "592f838dd276944818f7edc6" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :18} { "_id" :ObjectId( "592f838dd276944818f7edc7" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :19} Type "it" for more >itit { "_id" :ObjectId( "592f8964d276944818f7eddc" ), "name" : "MongoDB" , "object" : "redis" , "company" : "winner" , "phone" :0} { "_id" :ObjectId( "592f8964d276944818f7eddd" ), "name" : "MongoDB" , "object" : "redis" , "company" : "winner" , "phone" :1} { "_id" :ObjectId( "592f8964d276944818f7edde" ), "name" : "MongoDB" , "object" : "redis" , "company" : "winner" , "phone" :2} { "_id" :ObjectId( "592f8964d276944818f7eddf" ), "name" : "MongoDB" , "object" : "redis" , "company" : "winner" , "phone" :3} { "_id" :ObjectId( "592f8964d276944818f7ede0" ), "name" : "MongoDB" , "object" : "redis" , "company" : "winner" , "phone" :4} { "_id" :ObjectId( "592f8964d276944818f7ede1" ), "name" : "MongoDB" , "object" : "redis" , "company" : "winner" , "phone" :5} { "_id" :ObjectId( "592f8964d276944818f7ede2" ), "name" : "MongoDB" , "object" : "redis" , "company" : "winner" , "phone" :6} { "_id" :ObjectId( "592f8964d276944818f7ede3" ), "name" : "MongoDB" , "object" : "redis" , "company" : "winner" , "phone" :7} { "_id" :ObjectId( "592f8964d276944818f7ede4" ), "name" : "MongoDB" , "object" : "redis" , "company" : "winner" , "phone" :8} { "_id" :ObjectId( "592f8964d276944818f7ede5" ), "name" : "MongoDB" , "object" : "redis" , "company" : "winner" , "phone" :9} 6、AND和OR综合使用 查询phone<5,name=MongoDB或者name=linux 1 2 3 4 5 6 7 8 9 10 11 12 db.info2. find ({phone:{$lt:5},$or:[{name: "MongoDB" },{name: "linux" }]}) db.info2. find ({phone:{$lt:5},$or:[{name: "MongoDB" },{name: "linux" }]}) { "_id" :ObjectId( "592f838dd276944818f7edb4" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :0} { "_id" :ObjectId( "592f838dd276944818f7edb5" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :1} { "_id" :ObjectId( "592f838dd276944818f7edb6" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :2} { "_id" :ObjectId( "592f838dd276944818f7edb7" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :3} { "_id" :ObjectId( "592f838dd276944818f7edb8" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :4} { "_id" :ObjectId( "592f8964d276944818f7eddc" ), "name" : "MongoDB" , "object" : "redis" , "company" : "winner" , "phone" :0} { "_id" :ObjectId( "592f8964d276944818f7eddd" ), "name" : "MongoDB" , "object" : "redis" , "company" : "winner" , "phone" :1} { "_id" :ObjectId( "592f8964d276944818f7edde" ), "name" : "MongoDB" , "object" : "redis" , "company" : "winner" , "phone" :2} { "_id" :ObjectId( "592f8964d276944818f7eddf" ), "name" : "MongoDB" , "object" : "redis" , "company" : "winner" , "phone" :3} { "_id" :ObjectId( "592f8964d276944818f7ede0" ), "name" : "MongoDB" , "object" : "redis" , "company" : "winner" , "phone" :4} 7、查询结果排序 在MySQL中是有order by条件,可以根据desc或者asc进行升序或者降序操作,而MongoDB中是可以利用sort()方法实现排序的,例如对6中的结果处理,根据phone排序。 基本语法 db.info2.find().sort({phone:1})#这里phone表示根据该key排序,1表示升序,-1表示降序。 1 2 3 4 5 6 7 8 9 10 11 db.info2. find ({phone:{$lt:5},$or:[{name: "MongoDB" },{name: "linux" }]}). sort ({phone:1}) { "_id" :ObjectId( "592f838dd276944818f7edb4" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :0} { "_id" :ObjectId( "592f8964d276944818f7eddc" ), "name" : "MongoDB" , "object" : "redis" , "company" : "winner" , "phone" :0} { "_id" :ObjectId( "592f838dd276944818f7edb5" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :1} { "_id" :ObjectId( "592f8964d276944818f7eddd" ), "name" : "MongoDB" , "object" : "redis" , "company" : "winner" , "phone" :1} { "_id" :ObjectId( "592f838dd276944818f7edb6" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :2} { "_id" :ObjectId( "592f8964d276944818f7edde" ), "name" : "MongoDB" , "object" : "redis" , "company" : "winner" , "phone" :2} { "_id" :ObjectId( "592f838dd276944818f7edb7" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :3} { "_id" :ObjectId( "592f8964d276944818f7eddf" ), "name" : "MongoDB" , "object" : "redis" , "company" : "winner" , "phone" :3} { "_id" :ObjectId( "592f838dd276944818f7edb8" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :4} { "_id" :ObjectId( "592f8964d276944818f7ede0" ), "name" : "MongoDB" , "object" : "redis" , "company" : "winner" , "phone" :4} 8、MongoDB Skip() 方法 在前面介绍了limit(),sort(),count()等方法,接下来要介绍一个比较有趣的skip()方法,在使用limit()的时候可以显示你要求的几条,而skip()方法是跳过几条。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 db.info2. find ({phone:{$lt:5},$or:[{name: "MongoDB" },{name: "linux" }]}). sort ({phone:1}) { "_id" :ObjectId( "592f838dd276944818f7edb4" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :0} { "_id" :ObjectId( "592f8964d276944818f7eddc" ), "name" : "MongoDB" , "object" : "redis" , "company" : "winner" , "phone" :0} { "_id" :ObjectId( "592f838dd276944818f7edb5" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :1} { "_id" :ObjectId( "592f8964d276944818f7eddd" ), "name" : "MongoDB" , "object" : "redis" , "company" : "winner" , "phone" :1} { "_id" :ObjectId( "592f838dd276944818f7edb6" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :2} { "_id" :ObjectId( "592f8964d276944818f7edde" ), "name" : "MongoDB" , "object" : "redis" , "company" : "winner" , "phone" :2} { "_id" :ObjectId( "592f838dd276944818f7edb7" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :3} { "_id" :ObjectId( "592f8964d276944818f7eddf" ), "name" : "MongoDB" , "object" : "redis" , "company" : "winner" , "phone" :3} { "_id" :ObjectId( "592f838dd276944818f7edb8" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :4} { "_id" :ObjectId( "592f8964d276944818f7ede0" ), "name" : "MongoDB" , "object" : "redis" , "company" : "winner" , "phone" :4} 使用skip()方法 db.info2. find ({phone:{$lt:5},$or:[{name: "MongoDB" },{name: "linux" }]}). sort ({phone:1}).skip(3) { "_id" :ObjectId( "592f8964d276944818f7eddd" ), "name" : "MongoDB" , "object" : "redis" , "company" : "winner" , "phone" :1} { "_id" :ObjectId( "592f838dd276944818f7edb6" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :2} { "_id" :ObjectId( "592f8964d276944818f7edde" ), "name" : "MongoDB" , "object" : "redis" , "company" : "winner" , "phone" :2} { "_id" :ObjectId( "592f838dd276944818f7edb7" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :3} { "_id" :ObjectId( "592f8964d276944818f7eddf" ), "name" : "MongoDB" , "object" : "redis" , "company" : "winner" , "phone" :3} { "_id" :ObjectId( "592f838dd276944818f7edb8" ), "name" : "linux" , "object" : "SA" , "company" : "docker" , "phone" :4} { "_id" :ObjectId( "592f8964d276944818f7ede0" ), "name" : "MongoDB" , "object" : "redis" , "company" : "winner" , "phone" :4} skip方法有点类似于MySQL里面的limit之间间隔情况。 这里介绍了有关查询的问题,在数据库中,查询是非常重要的一部分,所以介绍的篇幅也是比较多的,后期遇到其他问题也会继续总结输出。 本文转自 tianya1993 51CTO博客,原文链接:http://blog.51cto.com/dreamlinux/1931384,如需转载请自行联系原作者

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

Android基础:SlidingDrawer知识

SlidingDrawer抽屉,主要有handler和content组成,handler一般是图片,cotent随意,基本的方法主要有 open()、animateOpen()、close()、animateClose()、SlidingDrawer.setOnDrawerOpenListener()、SlidingDrawer.setOnDrawerCloseListener() lock()、unlock(), 系统自带的抽屉可以从下往上、或者从右往左拉开,通过orientation来设置,如果要使SlidingDrawer按指定高度拉开,应该放到Relativelayout中,同时设置alignParentBotom为true. <?xml version= "1.0" encoding= "utf-8" ?> <RelativeLayout xmlns:android= "http://schemas.android.com/apk/res/android" android:layout_width= "match_parent" android:layout_height= "match_parent" android:orientation= "vertical" > <SlidingDrawer android:id= "@+id/slidingdrawer" android:layout_width= "fill_parent" android:layout_height= "400px" android:content= "@+id/content" android:handle= "@+id/handler" android:orientation= "horizontal" android:layout_alignParentBottom= "true" > <ImageView android:id= "@id/handler" android:layout_width= "wrap_content" android:layout_height= "wrap_content" android:src= "@drawable/handler" /> <TextView android:id= "@+id/content" android:layout_width= "fill_parent" android:layout_height= "fill_parent" android:text= "测试。。。。。。。。" android:textSize= "18px" android:gravity= "center_vertical" android:background= "#ff00ff00" /> </SlidingDrawer> </RelativeLayout> handler = (ImageView) findViewById(R.id.handler); content = (TextView) findViewById(R.id.content); slidingdrawer = (SlidingDrawer) findViewById(R.id.slidingdrawer); slidingdrawer.open(); slidingdrawer.setOnDrawerOpenListener( new OnDrawerOpenListener() { @Override public void onDrawerOpened() { handler.setImageDrawable(MainActivity. this .getResources().getDrawable(R.drawable.p)); ScaleAnimation anim = new ScaleAnimation( 0 .0f, 1 .0f, 0 .0f, 1 .0f); anim.setDuration( 1000 ); // slidingdrawer.setAnimation(anim); // slidingdrawer.startAnimation(anim); } }); slidingdrawer.setOnDrawerCloseListener( new OnDrawerCloseListener() { @Override public void onDrawerClosed() { handler.setImageDrawable(MainActivity. this .getResources().getDrawable(R.drawable.handler)); /**锁定slidingdrawer.lock();**/ // slidingdrawer.lock(); } }); 本文转自demoblog博客园博客,原文链接http://www.cnblogs.com/0616--ataozhijia/archive/2012/11/01/2750165.html如需转载请自行联系原作者 demoblog

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

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

Nacos

Nacos

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

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册