linux 运行级, runlevel

linux 运行级, runlevel 作为默认,REDHAT Linux 9.0在启动时会自动启动X-Window进入图形化操作界面。而许多Linux铁杆玩家已经习惯了在Console字符界面工作,或是有些玩家嫌X-Window启动太慢,喜欢直观快速的Console操作。 1.进入字符界面 为了在Linux启动时直接进入Console界面,我们可以编辑/etc/inittab文件。找到 id:5:initdefault: 这一行,将它改为 id:3:initdefault: 后重新启动系统即可。我们看到,简简单单地将5改为3,就能实现启动时进入X-Window图形操作界面或Console字符界面的转换,这是因为Linux操作系统有六种不同的运行级 (run level) ,在不同的运行级下,系统有着不同的状态,这六种运行级分别为: 0: 停机 (记住不要把initdefault 设置为0,因为这样会使Linux无法启动 ) 1: 单用户模式,就像Win9X下的安全模式。 2: 多用户,但是没有 NFS 。 3: 完全多用户模式,标准的运行级。 4: 一般不用,在一些特殊情况下可以用它来做一些事情。 5: X11,即进到 X-Window 系统。 6: 重新启动 (记住不要把initdefault 设置为6,因为这样会使Linux不断地重新启动) 。 其中运行级3就是我们要进入的标准Console字符界面模式。 2.自由转换字符界面和X-Window图形界面 在了解了启动自动进入X-Window图形操作界面和Console字符操作界面的转换后,也许你会想,这两种操作界面各有各的好处,我能不能"贪心"一点,同时拥有这两种操作界面呢?在无所不能的Linux操作系统中,这个要求当然是可以得到满足的。 在X-Window图形操作界面中按"Alt+Ctrl+功能键Fnn=1~6"就可以进入Console字符操作界面。这就意味着你可以同时拥有X-Window加上6个Console字符操作界面,这是一件多么令人振奋的事情啊! 在Console字符操作界面里如何回到刚才的X-Window中呢?很简单,按"Alt+Ctrl+F7"即可。这时Linux默认打开7个屏幕,编号为tty1tty7。X-Window启动后,占用的是tty7号屏幕,tty1tty6仍为字符界面屏幕。也就是说,用"Alt+Ctrl+Fn"组合键即可实现字符界面与X Window界面的快速切换。 Linux的老用户们都知道,X-Window是一个非常方便地图形界面,它能使用户用鼠标最简单的进行操作,但是它也有不少缺点: 比如启动和运行速度慢、稳定性不够、兼容性差、容易崩溃等。但是一旦X-Window系统出了问题,并不会使整个Linux系统的崩溃而导致数据丢失或系统损坏,因为当X-Window由于自身或应用程序而失去响应或崩溃时,我们可以非常方便地退出X-Window进入Console进行故障处理,要做的只是按"Alt+Ctrl+Backspace"键,这意味着只要系统没有失去对键盘的响应,X-Window出了任何问题,都可以方便地退出。

2011-11-21 · 1 min · 47 words · -

Closure Tools

Closure Tools Google已经基于Apache License 2.0把Closure Stylesheets开源,这种工具属于Closure Tools包之内,在处理CSS的时候很有用。Closure Stylesheets是一个Java程序,它向CSS中添加了变量、函数、条件语句以及混合类型,使得我们更易于处理大型的CSS文件。开发者可以使用Google stylesheets (GSS)这种工具来生成web应用程序或者网站所使用的真正的CSS文件。 http://www.infoq.com/cn/news/2011/11/Google-Closure-Stylesheets

2011-11-21 · 1 min · 11 words · -

观察者模式, Observer pattern

观察者模式, Observer pattern 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。 观察者模式 (Observer)又称发布-订阅模式 (Publish-Subscribe:Pub/Sub)。它是一种通知机制,让发送通知的一方 (被观察方)和接收通知的一方 (观察者)能彼此分离,互不影响。 观察者模式 (有时又被称为发布-订阅模式、模型-视图模式、源-收听者模式或从属者模式) 是软件设计模式的一种。在此种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知。这通常透过调用各观察者所提供的方法来实现。此种模式通常被用来实作事件处理系统。 此模式完美的将观察者和被观察的对象分离开。举个例子,用户界面可以作为一个观察者,业务数据是被观察者,用户界面观察业务数据的变化,发现数据变化后,就显示在界面上。面向对象设计的一个原则是: 系统中的每个类将重点放在某一个功能上,而不是其他方面。一个对象只做一件事情。观察者模式在模块之间划定了清晰的界限,提高了应用程序的可维护性和重用性。 观察者模式有很多实现方式,从根本上说,该模式必须包含两个角色: 观察者和被观察对象。在刚才的例子中,业务数据是被观察对象,用户界面是观察者。观察者和被观察者之间存在"观察"的逻辑关联,当被观察者发生改变的时候,观察者就会观察到这样的变化,并且做出相应的响应。如果在用户界面、业务数据之间使用这样的观察过程,可以确保界面和数据之间划清界限,假定应用程序的需求发生变化,需要修改界面的表现,只需要重新构建一个用户界面,业务数据不需要发生变化。 实现观察者模式的时候要注意,观察者和被观察对象之间的互动关系不能体现成类之间的直接调用,否则就将使观察者和被观察对象之间紧密的耦合起来,从根本上违反面向对象的设计的原则。无论是观察者"观察"观察对象,还是被观察者将自己的改变"通知"观察者,都不应该直接调用。 实现观察者模式有很多形式,比较直观的一种是使用一种"注册——通知——撤销注册"的形式。 @startuml class Publisher interface Subscriber Publisher o-right- Subscriber class ConcreateSubscriber Subscriber <|-- ConcreateSubscriber class Client ConcreateSubscriber <.. Client Publisher<--Client @enduml @startuml class Demo class Editor note right: 发布者\nPublisher\n被观察对象\nSubject Editor<-- Demo interface EventListener note left: 订阅者\nSubscriber\n观察者\nObserver class EmailNotificationListener note left: 具体订阅者 EventListener<|-- EmailNotificationListener EmailNotificationListener<.. Demo class EventManager EventManager --o Editor EventListener -right-o EventManager class LogOpenListener EventListener<|-- LogOpenListener LogOpenListener<.. Demo @enduml 发布者, Publisher, 被观察对象, Subject 发布者 (Publisher) 会向其他对象发送值得关注的事件。 事件会在发布者自身状态改变或执行特定行为后发生。 发布者中包含一个允许新订阅者加入和当前订阅者离开列表的订阅构架。 ...

2011-11-20 · 3 min · 620 words · -

Gradle basic, command

Gradle basic, command create project structure gradle init --type java-application --dsl kotlin command gradle build install # archlinux sudo pacman -S gradle # mac brew install gradle windows install gradle scoop install main/gradle-bin download latest version of gradle from http://www.gradle.org/downloads.html extract the gradle package sudo emacs ~/.bashrc add the gradle to path. set PATH=$JAVA_HOME/bin:/home/wiloon/program/gradle-1.0-milestone-3/bin:$PATH export PATH restart the system # 更新依赖包 gradle build --refresh-dependencies # publish to maven gradle publish # create project structure mkdir java21 gradle init \ --type java-application \ --dsl kotlin \ --test-framework junit-jupiter \ --package com.wiloon.java21 \ --project-name java21 \ --no-split-project \ --java-version 21 gradle init --type java-library --project-name jvm-library --dsl kotlin gradle init --type java-library gradle init --type java-application #check module dependency gradle dependencies --configuration compileClasspath gradle :core:dependencies #specifies the build file. gradle -b xxx/xxx/build.gradle #The Application Plugin #apply plugin: 'application' # 打包-tar gradle distTar gradle distZip # 安装到本地 gradle installDist #convert maven project to gradle project gradle init --type pom #eclipse gradle eclipse gradle cleanEclipse #idea gradle idea gradle cleanIdea #skip test gradle build -x test #load local jars compile files('libs/jfx-2.3.8.jar') // project dependency dependencies { compile project(":project-name") } ...

2011-11-20 · 1 min · 212 words · -

STDIN STDOUT, STDERR

STDIN STDOUT, STDERR Unix/Linux/BSD 都有三个特别文件,分别 标准输入 即 STDIN , 在 /dev/stdin , 一般指键盘输入, shell里代号是 0 标准输出 STDOUT, 在 /dev/stdout, 一般指终端(terminal), 就是显示器, shell里代号是 1 标准错误 STDERR, 在 /dev/stderr 也是指终端(terminal), 不同的是, 错误信息送到这里 shell里代号是 2 stdout和stderr 有人说stdio是带缓冲的,stderr是不带缓冲的,这并不是指fd=1和fd=2这两个设备文件,这两个设备是字符设备,本身没有缓存。并且你看一个进程的1和2两个fd指向的其实是同一个终端设备文件 ls -l /proc/8669/fd/ total 0 lrwx------ 1 root root 64 4月 25 20:57 0 -> /dev/pts/7 lrwx------ 1 root root 64 4月 25 20:57 1 -> /dev/pts/7 lrwx------ 1 root root 64 4月 25 20:57 2 -> /dev/pts/7 所以,细想一下就知道,向1或2两个fd写东西,在内核里走的是完全相同的路径,不可能存在一会儿缓存一会儿不缓存的情况。 ...

2011-11-19 · 1 min · 169 words · -

TimeUnit

TimeUnit http://chenjumin.iteye.com/blog/2182171 //关于秒的常用方法 TimeUnit.SECONDS.toMillis(1) 1秒转换为毫秒数 TimeUnit.SECONDS.toMinutes(60) 60秒转换为分钟数 TimeUnit.SECONDS.sleep(5) 线程休眠5秒 TimeUnit.SECONDS.convert(1, TimeUnit.MINUTES) 1分钟转换为秒数 //TimeUnit.DAYS 日的工具类 //TimeUnit.HOURS 时的工具类 //TimeUnit.MINUTES 分的工具类 //TimeUnit.SECONDS 秒的工具类 //TimeUnit.MILLISECONDS 毫秒的工具类 http://www.importnew.com/7219.html TimeUnit是什么 TimeUnit是java.util.concurrent包下面的一个类,TimeUnit提供了可读性更好的线程暂停操作,通常用来替换 Thread.sleep(),在很长一段时间里 Thread的sleep() 方法作为暂停线程的标准方式,几乎所有Java程序员都熟悉它,事实上sleep方法本身也很常用而且出现在很多面试中。如果你已经使用过 Thread.sleep(),当然我确信你这样做过,那么你一定熟知它是一个静态方法,暂停线程时它不会释放锁,该方法会抛出 InterrupttedException 异常 (如果有线程中断了当前线程) 。但是我们很多人并没有注意的一个潜在的问题就是它的可读性。Thread.sleep() 是一个重载方法,可以接收长整型毫秒和长整型的纳秒参数,这样对程序员造成的一个问题就是很难知道到底当前线程是睡眠了多少秒、分、小时或者天。看看下面这个Thread.sleep()方法: Thread.sleep (2400000) 粗略一看,你能计算出当前线程是等待多长时间吗?可能有些人可以,但是对于大多数程序员来说这种写法的可读性还是很差的,你需要把毫秒转换成秒和分,让我们来看看另外一个例子,这个例子比前面那个例子可读性稍微好一点: Thread.sleep(4_60_1000); 这比前面那个例子已经好多了,但是仍然不是最好的,你注意到睡眠时间用毫秒,不容易猜出当前线程将等待4分钟。TimeUnit类解决了这个问题,通过指定DAYS、HOURS、MINUTES,SECONDS、MILLISECONDS和NANOSECONDS。java.utils.concurrent .TimeUnit 是Java枚举应用场景中最好的例子之一,所有TimeUnit都是枚举实例,让我们来看看线程睡眠4分钟用TimeUnit是如何使用的。 TimeUnit.MINUTES.sleep(4); // sleeping for 4 minutes 类似你可以采用秒、分、小时级别来暂停当前线程。你可以看到这比Thread的sleep方法的可读的好多了。记住TimeUnit.sleep()内部调用的Thread.sleep()也会抛出InterruptException。你也可以查看JDK源代码去验证一下。下面是一个简单例子,它展示如果使用TimeUnit.sleep()方法。 public class TimeUnitTest { public static void main(String args[]) throws InterruptedException { System.out.println("Sleeping for 4 minutes using Thread.sleep()"); Thread.sleep(4 * 60 * 1000); System.out.println("Sleeping for 4 minutes using TimeUnit sleep()"); TimeUnit.SECONDS.sleep(4); TimeUnit.MINUTES.sleep(4); TimeUnit.HOURS.sleep(1); TimeUnit.DAYS.sleep(1); } } 除了sleep的功能外,TimeUnit还提供了便捷方法用于把时间转换成不同单位,例如,如果你想把秒转换成毫秒,你可以使用下面代码: ...

2011-11-19 · 1 min · 93 words · -

commons-logging Log4J

commons-logging Log4J commons-logging vs Log4J Log4J是一个功能很强大的日志记录组件,它提供了丰富的日志记录功能,它本身和commons-logging没有什么关系,也就是说一个项目中可以单独使用Log4J来记录日志,而不需要引入commons-logging包,这样也能实现记录日志的功能,但是这样有一个不太好的地方就是如果你想使用其他的Logging组建,比如jdk1.4自带的logging框架,就不得不修改原有文件中所有使用了Log4J组建的代码。 这时,commons-logging就派上用场了,说白了commons-logging就是一个记录日志的统一接口,它定义了一套抽象的记录日志的接口,用户可以通过配置,来使用任何一个符合该接口的Logging组建。而commons-logging组建本身仅仅提供了一个很简单的记录日志的类SimpleLog,这个类的记录日志功能很有限。因此,通常情况下,会将Log4J组建与commons-logging组建一块儿使用,在程序代码中,使用commons-logging的接口方法来记录日志,而后台实际使用的是Log4J组建。 commons-logging组建使用具体的Log组建的顺序如下 如果定义了org.apache.commons.logging.Log系统参数,则使用指定的Logging实现; 如果在CLASSPATH里发现了Log4J,则使用Log4J; 如果使用的是JDK1.4,则使用JDK1.4内置的Logging框架; 如果都没有找到,则使用Commons Logging内置的简单Log实现。 我们在做项目时,日志的记录是必不可少的一项任务,而我们通常是使用 apache 的 log4j 日志管理工具。然而,在项目中,我们经常会看到两个 jar 包: commons-logging.jar 和 log4j.rar。为什么我们在使用 log4j 的同时还要引入 commons-logging.jar 呢,或者说不用 commons-logging.jar 可不可以,这两者之间到底是怎么的一种关系呢? 作为记录日志的工具,它至少应该包含如下几个组成部分(组件): Logger 记录器组件负责产生日志,并能够对日志信息进行分类筛选,控制什么样的日志应该被输出,什么样的日志应该被忽略。它还有一个重要的属性 - 日志级别。不管何种日志记录工具,大概包含了如下几种日志级别: DEBUG, INFO, WARN, ERROR 和 FATAL。 Level 日志级别组件。 Appender 日志记录工具基本上通过 Appender 组件来输出到目的地的,一个 Appender 实例就表示了一个输出的目的地。 Layout Layout 组件负责格式化输出的日志信息,一个 Appender 只能有一个 Layout。 我们再来看看 log4j.jar,打开 jar 包,我们可以看到 Logger.class(Logger),Level.class(Level), FileAppender.class(Appender), HTMLLayout.class(Layout)。其它的我们先忽略不看,这几个字节码文件正好是记录日志必不可少的几个组件。 接下来看看 commons-logging 中的 org.apache.commons.logging.Log.java 源码: Java代码 package org.apache.commons.logging; public interface Log { ...

2011-11-18 · 2 min · 331 words · -

Debian/Ubuntu 系统 Update-rc.d

Debian/Ubuntu 系统 Update-rc.d https://wangyan.org/blog/ubuntu-update-rc-d.html Ubuntu或者Debian系统中update-rc.d命令,是用来更新系统启动项的脚本。这些脚本的链接位于/etc/rcN.d/目录,对应脚本位于/etc/init.d/目录。在了解update-rc.d命令之前,你需要知道的是有关Linux 系统主要启动步骤,以及Ubuntu中运行级别的知识。 一、Linux 系统主要启动步骤 读取 MBR 的信息,启动 Boot Manager。 加载系统内核,启动 init 进程, init 进程是 Linux 的根进程,所有的系统进程都是它的子进程。 init 进程读取 /etc/inittab 文件中的信息,并进入预设的运行级别。通常情况下 /etc/rcS.d/ 目录下的启动脚本首先被执行,然后是/etc/rcN.d/ 目录。 根据 /etc/rcS.d/ 文件夹中对应的脚本启动 Xwindow 服务器 xorg,Xwindow 为 Linux 下的图形用户界面系统。 启动登录管理器,等待用户登录。 二、运行级别 Ubuntu中的运行级别 0 (关闭系统) 1 (单用户模式,只允许root用户对系统进行维护。) 2 到 5 (多用户模式,其中3为字符界面,5为图形界面。) 6 (重启系统) 切换运行级别 init [0123456Ss] 例如: init 0 命令关机; init 6 命令重新启动 启动项管理工具 sudo apt-get install sysv-rc-conf //或者使用带gui的工具bum sudo sysv-rc-conf 三、update-rc.d命令详解 ...

2011-11-18 · 1 min · 119 words · -

分布式ID, 雪花算法

分布式ID, 雪花算法 https://zhuanlan.zhihu.com/p/85837641 雪花算法这一在分布式架构中很常见的玩意,但一般也不需要怎么去深入了解,一方面一般个人项目用不到分布式之类的大型架构,另一方面,就算要用到,市面上很多ID生成器也帮我们完成了这项工作。 分布式ID的特点 全局唯一性 不能出现有重复的ID标识,这是基本要求。 递增性 确保生成ID对于用户或业务是递增的。 高可用性 确保任何时候都能生成正确的ID。 高性能性 在高并发的环境下依然表现良好。 分布式ID的常见解决方案 UUID Java自带的生成一串唯一随机36位字符串 (32个字符串+4个“-”)的算法。它可以保证唯一性,且据说够用N亿年,但是其业务可读性差,无法有序递增。 SnowFlake 今天的主角雪花算法,它是Twitter开源的由64位整数组成分布式ID,性能较高,并且在单机上递增。 具体参考: https://github.com/twitter-archive/snowflake UidGenerator UidGenerator是百度开源的分布式ID生成器,其基于雪花算法实现。 具体参考: https://github.com/baidu/uid-generator/blob/master/README.zh_cn.md Leaf Leaf是美团开源的分布式ID生成器,能保证全局唯一,趋势递增,但需要依赖关系数据库、Zookeeper等中间件。 具体参考: https://tech.meituan.com/MT_Leaf.html 雪花算法的概要 SnowFlake是Twitter公司采用的一种算法,目的是在分布式系统中产生全局唯一且趋势递增的ID。 组成部分 (64bit) 1.第一位 占用1bit,其值始终是0,没有实际作用。 2.时间戳 占用41bit,精确到毫秒,总共可以容纳约69年的时间。 3.工作机器id 占用10bit,其中高位5bit是数据中心ID,低位5bit是工作节点ID,做多可以容纳1024个节点。 4.序列号 占用12bit,每个节点每毫秒0开始不断累加,最多可以累加到4095,一共可以产生4096个ID。 SnowFlake算法在同一毫秒内最多可以生成多少个全局唯一ID呢:: 同一毫秒的ID数量 = 1024 X 4096 = 4194304

2011-11-12 · 1 min · 49 words · -

tomcat config, server, user

tomcat config, server, user server Listener 监听器,用来监听某些事件的发生。 VersionLoggerListener,启动时对tomcat,java,操作系统信息打印日志。 JreMemoryLeakPreventionListener, JreMemoryLeakPreventionListener,防止内存溢出的监听器。 http://liuxi.name/blog/20160608/jvm-full-gc-hourly.html GlobalResourcesLifecycleListener,初始化定义在元素GlobalNamingResources下的全局JNDI资源 ThreadLocalLeakPreventionListener,防止ThreadLocal溢出监听器。 connectionTimeout - 网络连接超时,单位: 毫秒。设置为0表示永不超时,这样设置有隐患的。通常可设置为30000毫秒。 keepAliveTimeout - 长连接最大保持时间 (毫秒) user config Tomcat 6 <?xml version='1.0' encoding='utf-8'?> <tomcat-users> <role rolename="tomcat"/> <role rolename="role1"/> <role rolename="manager"/> <role rolename="admin"/> <user username="tomcat" password="tomcat" roles="tomcat"/> <user username="both" password="tomcat" roles="tomcat,role1"/> <user username="role1" password="tomcat" roles="role1"/> <user username="admin" password="admin" roles="admin,manager"/> <user username="hhh" password="123456" roles="role1,tomcat,admin,manager"/> </tomcat-users> Tomcat 7 <role rolename="manager"/> <role rolename="manager-gui"/> <role rolename="admin"/> <role rolename="admin-gui"/> <user username="tomcat" password="tomcat" roles="admin-gui,admin,manager-gui,manager"/>

2011-11-12 · 1 min · 72 words · -

shell逻辑运算符

shell逻辑运算符 -d 常用!侦测『目录』是否存在 -b 侦测是否为一个『 block 档案』 -c 侦测是否为一个『 character 档案』 -S 侦测是否为一个『 socket 标签档案』 -L 侦测是否为一个『 symbolic link 的档案』 -e 侦测『某个东西』是否存在! 2. 关于程序的逻辑卷标! -G 侦测是否由 GID 所执行的程序所拥有 -O 侦测是否由 UID 所执行的程序所拥有 -p 侦测是否为程序间传送信息的 name pipe 或是 FIFO (老实说,这个不太懂!) 3. 关于档案的属性侦测! -r 侦测是否为可读的属性 -w 侦测是否为可以写入的属性 -x 侦测是否为可执行的属性 -s 侦测是否为『非空白档案』 -u 侦测是否具有『 SUID 』的属性 -g 侦测是否具有『 SGID 』的属性 -k 侦测是否具有『 sticky bit 』的属性 4. 两个档案之间的判断与比较 ;例如[ test file1 -nt file2 ] -nt 第一个档案比第二个档案新 -ot 第一个档案比第二个档案旧 -ef 第一个档案与第二个档案为同一个档案 ( link 之类的档案) 5. 逻辑的『和(and)』『或(or)』 && 逻辑的 AND 的意思 || 逻辑的 OR 的意思 运算符号 代表意义 = 等于 应用于: 整型或字符串比较 如果在[] 中,只能是字符串 != 不等于 应用于: 整型或字符串比较 如果在[] 中,只能是字符串 < 小于 应用于: 整型比较 在[] 中,不能使用 表示字符串 > 大于 应用于: 整型比较 在[] 中,不能使用 表示字符串 -lt 小于 应用于: 整型比较 -gt 大于 应用于: 整型比较 -le 小于或等于 应用于: 整型比较 -ge 大于或等于 应用于: 整型比较 -a 双方都成立 (and) 逻辑表达式 –a 逻辑表达式 -o 单方成立 (or) 逻辑表达式 –o 逻辑表达式 -z 空字符串 -n 非空字符串

2011-11-12 · 1 min · 149 words · -

missing LSB tags and overrides

missing LSB tags and overrides update-rc.d tomcat defaults pop out warning message missing LSB tags and overrides add the following lines into the script BEGIN INIT INFO Provides: tomcat Required-Start: $remote_fs $syslog Required-Stop: $remote_fs $syslog Default-Start: 2 3 4 5 Default-Stop: 0 1 6 Short-Description: Start tomcat at boot time Description: Enable service provided by tomcat. END INIT INFO

2011-11-12 · 1 min · 59 words · -

tomcat 开机启动, jsvc

tomcat 开机启动, jsvc 参考http://tomcat.apache.org/tomcat-7.0-doc/setup.html的介绍,tomcat自带了jsvc工具, 需要先安装gcc, make 在tomcat的bin目录下: cd $CATALINA_HOME/bin tar xvfz commons-deamon-native.tar.gz cd commons-daemon-1.0.x-native-src/unix ./configure make cp jsvc ../.. cd ../.. 设置启动脚本 在$CATALINA_HOME/bin/commons-daemon-1.0.x-native-src/unix/samples目录下有一个Tomcat7.sh文件,将其复制到/etc/init.d/m目录下并命名为tomcat: sudo cp Tomcat7.sh /etc/init.d/tomcat add following lines to the file. ### BEGIN INIT INFO # Provides: tomcat # Required-Start: $remote_fs $syslog # Required-Stop: $remote_fs $syslog # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Start tomcat at boot time # Description: Enable service provided by tomcat. ### END INIT INFO CATALINA_HOME=/xxx/xxx/xxx/apache-tomcat-7.0.22 export CATALINA_HOME JAVA_HOME=/opt/jvm/jdk1.7.0 export JAVA_HOME 修改运行级别 ...

2011-11-12 · 1 min · 96 words · -

Jakarta

Jakarta http://zh.wikipedia.org/zh-cn/Jakarta%E9%A1%B9%E7%9B%AE Jakarta项目是在Apache软件基金会营运的开放源代码开发项目之一。开发着面向对象编程语言Java的程序库,框架等。 Jakarta是Apache组织下的一套Java解决方案的开源软件的名称,它包括了很多子项目。Tomcat、Ant、Struts等等现在是Apache下的开源项目,也曾是Jakarta的关联项目。 Jakarta的名称是想把与Jakarta关系非常深的爪哇岛关联起来。编程语言Java的命名源自这个岛的名字 (印尼语: Jawa、英语: Java) ,而城市雅加达 (Jakarta) 正是这个岛上的第一大城市,也是印度尼西亚的首府。 子项目 其中,Jakarta项目所包括的相关工具、库以及框架等罗列如下: BCEL - 处理Java字节码的类库 BSF - 脚本程序框架 Cactus - 服务器端Java类测试工具框架 ECS - The Element Construction Set is a Java API for generating elements for various markup anguages. HttpComponents- 超文本传输协议. JCS - 分布式缓存系统. JMeter - 压力测试工具 ORO - Java类库,提供与Perl5兼容的正则表达式功能 Regexp - 纯Java正则表达式包 Slide - a content repository primarily using WebDAV. Taglibs - 一个代码库,用于支持开发定制化的JSP tag lib 以前隶属于Jakarta项目,但现在作为Apache软件基金的单独项目,有: Ant - 构建工具 Commons - 一组使用类的合集,主要作为Java标准库的补充 HiveMind - a services and configuration microkernel ...

2011-11-12 · 1 min · 111 words · -

守护进程, 守护线程

守护进程, 守护线程 守护进程详解及创建,daemon() 使用 守护进程概述 Linux Daemon (守护进程) 是运行在后台的一种特殊进程。它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。它不需要用户输入就能运行而且提供某种服务,不是对整个系统就是对某个用户程序提供服务。Linux 系统的大多数服务器就是通过守护进程实现的。常见的守护进程包括系统日志进程 syslogd、 web 服务器 httpd、邮件服务器 sendmail 和数据库服务器 MySQLd 等。 守护进程一般在系统启动时开始运行,除非强行终止,否则直到系统关机都保持运行。守护进程经常以超级用户 (root) 权限运行,因为它们要使用特殊的端口 (1-1024) 或访问某些特殊的资源。 一个守护进程的父进程是 init 进程,因为它真正的父进程在 fork 出子进程后就先于子进程 exit 退出了,所以它是一个由 init 继承的孤儿进程。守护进程是非交互式程序,没有控制终端,所以任何输出,无论是向标准输出设备 stdout 还是标准出错设备 stderr 的输出都需要特殊处理。 守护进程的名称通常以 d 结尾,比如 sshd、xinetd、crond 等 二,创建守护进程步骤 首先我们要了解一些基本概念: 进程组 : 每个进程也属于一个进程组 每个进程主都有一个进程组号,该号等于该进程组组长的 PID 号. 一个进程只能为它自己或子进程设置进程组 ID 号 会话期: 会话期(session)是一个或多个进程组的集合。 setsid()函数可以建立一个对话期: 如果,调用setsid的进程不是一个进程组的组长,此函数创建一个新的会话期。 (1)此进程变成该对话期的首进程 (2)此进程变成一个新进程组的组长进程。 (3)此进程没有控制终端,如果在调用setsid前,该进程有控制终端,那么与该终端的联系被解除。 如果该进程是一个进程组的组长,此函数返回错误。 (4)为了保证这一点,我们先调用fork()然后exit(),此时只有子进程在运行 现在我们来给出创建守护进程所需步骤: 编写守护进程的一般步骤步骤: 在父进程中执行fork并exit推出; 在子进程中调用setsid函数创建新的会话; 在子进程中调用chdir函数,让根目录 ”/” 成为子进程的工作目录; 在子进程中调用umask函数,设置进程的umask为0; 在子进程中关闭任何不需要的文件描述符 说明: 在后台运行。 为避免挂起控制终端将Daemon放入后台执行。方法是在进程中调用fork使父进程终止,让Daemon在子进程中后台执行。 if(pid=fork()) exit(0);//是父进程,结束父进程,子进程继续 脱离控制终端,登录会话和进程组 有必要先介绍一下Linux中的进程与控制终端,登录会话和进程组之间的关系: 进程属于一个进程组,进程组号 (GID) 就是进程组长的进程号 (PID) 。登录会话可以包含多个进程组。这些进程组共享一个控制终端。这个控制终端通常是创建进程的登录终端。 控制终端,登录会话和进程组通常是从父进程继承下来的。我们的目的就是要摆脱它们,使之不受它们的影响。方法是在第1点的基础上,调用setsid()使进程成为会话组长: setsid(); 说明: 当进程是会话组长时setsid()调用失败。但第一点已经保证进程不是会话组长。setsid()调用成功后,进程成为新的会话组长和新的进程组长,并与原来的登录会话和进程组脱离。由于会话过程对控制终端的独占性,进程同时与控制终端脱离。 禁止进程重新打开控制终端 现在,进程已经成为无终端的会话组长。但它可以重新申请打开一个控制终端。可以通过使进程不再成为会话组长来禁止进程重新打开控制终端: if(pid=fork()) exit(0);//结束第一子进程,第二子进程继续 (第二子进程不再是会话组长) 关闭打开的文件描述符 进程从创建它的父进程那里继承了打开的文件描述符。如不关闭,将会浪费系统资源,造成进程所在的文件系统无法卸下以及引起无法预料的错误。按如下方法关闭它们: for(i=0;i 关闭打开的文件描述符close(i);> 改变当前工作目录 进程活动时,其工作目录所在的文件系统不能卸下。一般需要将工作目录改变到根目录。对于需要转储核心,写运行日志的进程将工作目录改变到特定目录如/tmpchdir("/") 重设文件创建掩模 进程从创建它的父进程那里继承了文件创建掩模。它可能修改守护进程所创建的文件的存取位。为防止这一点,将文件创建掩模清除: umask(0); 处理SIGCHLD信号 处理SIGCHLD信号并不是必须的。但对于某些进程,特别是服务器进程往往在请求到来时生成子进程处理请求。如果父进程不等待子进程结束,子进程将成为僵尸进程 (zombie) 从而占用系统资源。如果父进程等待子进程结束,将增加父进程的负担,影响服务器进程的并发性能。在Linux下可以简单地将SIGCHLD信号的操作设为SIG_IGN。 signal(SIGCHLD,SIG_IGN); 这样,内核在子进程结束时不会产生僵尸进程。这一点与BSD4不同,BSD4下必须显式等待子进程结束才能释放僵尸进程。 创建守护进程 在创建之前我们先了解setsid()使用: ...

2011-11-12 · 6 min · 1278 words · -

正整数

正整数 整数是不包括小数部分的数,正整数是指大于0整数。例如1,2,3……等可以用来表示完整计量单位的对象个数的数,是正整数。

2011-11-12 · 1 min · 2 words · -

jinfo

jinfo jinfo可以输出并修改运行时的java 进程的opts。用处比较简单,用于输出JAVA系统参数及命令行参数。用法是jinfo -opt pid 如: 查看2788的MaxPerm大小可以用 jinfo -flag MaxPermSize 2788 jinfo -flag MaxHeapSize 13112 打印命令行标识参数和系统属性键值对。 -flag name 打印指定的命令行标识参数的名称和值。 -flag [+|-]name 启用或禁用指定的boolean类型的命令行标识参数。 -flag name=value 为给定的命令行标识参数设置指定的值。 -flags 成对打印传递给JVM的命令行标识参数。 -sysprops 以键值对形式打印Java系统属性。 -h 打印帮助信息。 -help 打印帮助信息。 http://www.softown.cn/post/182.html

2011-11-11 · 1 min · 34 words · -

interview index

Interview index https://www.techinterviewhandbook.org/best-practice-questions/ https://raymondjiang.net/2022/02/18/about-leetcode-blind-75/?utm_short=pu2Q5X https://leetcode-cn.com/circle/discuss/CTEQMT/ #http://www.wiloon.com/?p=4781 #http://www.wiloon.com/?p=4219 #http://www.wiloon.com/?p=4117 #http://www.wiloon.com/?p=19

2011-11-11 · 1 min · 9 words · -

数字单位, 十亿,百亿,兆

数字单位, 十亿,百亿,兆 个十百千万亿兆京垓秭穰沟 个十百千万,十万,百万,千万,亿,十亿,百亿,千亿,兆,十兆,百兆,千兆,万兆,亿兆,后面是京,京之后的单位有十京、百京、千京、垓、十垓、百垓、千垓、秭、十秭、百秭、千秭、穰、十穰、百穰、千穰、沟…

2011-11-09 · 1 min · 4 words · -

dentry

dentry 上一节提到了,struct file并不是文件系统的核心数据结构,那么dentry和inode,这两个结构体谁是文件系统的核心数据结构呢,它们存在的目的又分别是什么呢? 首先dentry是目录项缓存,是一个存放在内存里的缩略版的磁盘文件系统目录树结构,他是directory entry的缩写。我们知道文件系统内的文件可能非常庞大,目录树结构可能很深,该树状结构中,可能存在几千万,几亿的文件。 首先假设不存在dentry这个数据结构,我们看下我们可能会面临什么困境: 比如我要打开/usr/bin/vim 文件, 1 首先需要去/所在的inode找到/的数据块,从/的数据块中读取到usr这个条目的inode, 2 跳转到user 对应的inode,根据/usr inode 指向的数据块,读取到/usr 目录的内容,从中读取到bin这个条目的inode 3 跳转到/usr/bin/对应的inode,根据/usr/bin/指向的数据块,从中读取到/usr/bin/目录的内容,从里面找到vim的inode 我们都知道,Linux提供了page cache页高速缓存,很多文件的内容已经缓存在内存里,如果没有dentry,文件名无法快速地关联到inode,即使文件的内容已经缓存在页高速缓存,但是每一次不得不重复地从磁盘上找出来文件名到VFS inode的关联。 因此理想情况下,我们需要将文件系统所有文件名到VFS inode的关联都纪录下来,但是这么做并不现实,首先并不是所有磁盘文件的inode都会纪录在内存中,其次磁盘文件数字可能非常庞大,我们无法简单地建立这种关联,耗尽所有的内存也做不到将文件树结构照搬进内存 https://bean-li.github.io/vfs-inode-dentry/

2011-11-09 · 1 min · 24 words · -