BEM即块(Block)、元素(Element)、修饰符(modifier),是由著名的俄罗斯搜索引擎团队Yandex提出的一种前端命名方法论。BEM命名约定更加严格,而且包含更多的信息,一般用于团队开发一个耗时的大项目中。
我们常见的BEM命名方式一般都是经过改良的,本文介绍的是Nicolas Gallagher(Twitter前端工程师)的改进版。
命名约定的格式如下:

.block{ ... }           /* 代表更高级别的抽象或组件 */
.block__element{ ... }  /* 代表.block的后代,用于形成一个完整的block整体 */
.block--modifier{ ... } /* 代表block的不同状态或不同版本 */

之所以使用两个连字符和下划线而不是一个,是为了让自己定义的块可以用单个连字符来界定,如:

.myHeader-search{ ... }                 /* 自定义的某个块 */
.myHeader-search__textElement{ ... }    /* 自定义块中的textElement元素 */
.myHeader-search--full{ ... }           /* 自定义块中的full修饰符 */

BEM的关键在于,光凭名字就可以告诉其他开发者某个标记(class)是用来干什么的。通过直观地阅读class属性,我们就能明白模块之间是如何关联的:有一些仅仅是组件,有一些则是这些组件的子孙或者元素,还有一些是组件其他形态或者是修饰符。我们通过下面的示例来进一步说明:

<!-- 假设有个组件Person -->
<div class="Person">
    <!-- hand是子元素,left、male是状态或修饰符:左、男性,即男性的左手-->
    <div class="hand left male"></div>
    <!-- 女性的右手 -->
    <div class="hand right female"></div>
</div>

上面的代码使用了常规CSS来表示,各个class都是有意义的,但是他们之间却是脱节的,拿female来说,是指女性人类还是指某种雌性的动物?hand是在表示指针(英文hand有钟表指针的含义)还是一只正在玩指纸牌的手呢?使用BEM我们可以获得更多的描述和更加清晰的结构,并且通过命名我们就可以知道元素之间的关联。代码如下:

<!-- 使用BEM命名 -->
<div class="Person">
    <!-- 女性人类的手 -->
    <div class=Person__hand--female></div>
    <!-- 人类的左手 -->
    <div class="Person_hand--left"></div>
</div>

再看一个常规方式命名的例子:

<!-- 搜索表单,full表示当前状态 -->
<form class="site-search full">
    <input type="text" class="field" />
    <input type="submit" class="button" value="搜索" />
</form>

上面的命名不好的地方就在于名称不够精确,不能告诉我们足够的信息。尽管我们可以用它们完成工作,但它们确实非常含糊不清,不够优雅。使用BEM记号法后就是下面的代码:

<!-- 状态或修饰符使用两个横线(--) -->
<form class="site-search site-search--full">
    <!-- 模块下的元素使用两个下划线(__) -->
    <input type="text" class="site-search__field"/>
    <input type="submit" class="site-search__button" value="搜索" />
</form>

在上面的代码中,我们可以清晰地看到有个叫.site-search的块,内部有个叫做.site-search__field的元素,并且site-search还有另一种形态叫做.site-search–full

  • 通常人们会认为BEM这种写法难看。但是,如果仅仅认为这种写法看上去不怎么好看而羞于使用,那么我们将错失最重要的东西。
  • BEM看上去有些怪怪的,但是它的好处远远超过外观上的瑕疵
  • BEM有可能导致输入更长的文本,但是大部分编辑器都有代码自动补全的功能,而且gzip压缩将会让我们消除对文件体积的担忧

BEM命名规则:http://segmentfault.com/a/1190000000391762
class命名方案:http://www.w3cplus.com/css/css-class-name.html
常用的CSS命名规范:http://www.html5cn.org/article-7600-1.html
通用CSS笔记、建议与指导:https://github.com/chadluo/CSS-Guidelines/blob/master/README.md
CSS代码重构和优化之路:http://luopq.com/2016/01/05/css-optimize/
CSS进阶:http://caibaojian.com/toutiao/6098

作为买不起正版的穷苦人民,在网上找了许多破解办法都已经失效了,无意间发现有大佬做的反代工具可以使用,废话少说,下面为大家讲解如何简单愉♂快的破解idea和webstorm。
原网页:http://blog.lanyus.com/archives/317.html

一、安装IDEA与WebStorm

过程(略)


二、idea破解

1. 代理工具下载地址:https://github.com/ilanyu/ReverseProxy/releases/tag/v1.0


根据自己的操作系统选择下载

我是64位,所以下了一个

2. 打开反代软件

就这样开着就好,不需要再管他
(重启电脑后,需要再打开反代软件)

3. 打开idea

点击License server ,输入http://127.0.0.1:8888
点击Activate

大功告成!


建议去IntelliJ官网下载最新版的idea,服务器上提供的貌似设置有点问题
idea常用快捷键:http://blog.csdn.net/dc_726/article/details/42784275
快捷键大全:https://www.cnblogs.com/zhangpengshou/p/5366413.html
也可以按照eclipse的习惯进行设置,享受idea吧~

什么是集合


一组存储对象的容器(动态) 。

集合类存放于java.util包中。

集合类存放的都是对象的引用,而非对象本身,出于表达上的便利,我们称集合中的对象就是指集合中对象的引用(reference)。

集合类型主要有3种:set(集)、list(列表)和map(映射)。

Collection<–List<–Vector

Collection<–List<–ArrayList

Collection<–List<–LinkedList

Collection<–Set<–HashSet

Collection<–Set<–HashSet<–LinkedHashSet

Collection<–Set<–SortedSet<–TreeSet

  1. 所有的List中只能容纳单个不同类型的对象组成的表,而不是Key-Value键值对。例如:[ tom,1,c ];

  2. 所有的List中可以有相同的元素,例如Vector中可以有 [ tom,koo,too,koo ];

  3. 所有的List中可以有null元素,例如[ tom,null,1 ];

  4. 基于Array的List(Vector,ArrayList)适合查询,而LinkedList(链表)适合添加,删除操作。

  5. Set实现的基础是Map(HashMap);

  6. Set中的元素是不能重复的,如果使用add(Object obj)方法添加已经存在的对象,则会覆盖前面的对象

为什么要使用集合

当你事先不知道要存放数据的个数,或者你需要一种比数组下标存取机制更灵活的方法时,你就需要用到集合类。

集(set)是最简单的一种集合,它的对象不按特定方式排序,只是简单的把对象加入集合中,就像往口袋里放东西。

对集中成员的访问和操作是通过集中对象的引用进行的,所以集中不能有重复对象。

集也有多种变体,可以实现排序等功能,如TreeSet,它把对象添加到集中的操作将变为按照某种比较规则将其插入到有序的对象序列中。它实现的是SortedSet接口,也就是加入了对象比较的方法。通过对集中的对象迭代,我们可以得到一个升序的对象集合。

Log4j是Apache的一个开源项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件,甚至是套接口服务器、NT的事件记录器、UNIX Syslog守护进程等;我们也可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。最方便的就是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。

本篇指南主要介绍Log4j 1.x版本的配置与使用

Log4j最新版下载地址:http://www.apache.org/dyn/closer.cgi/logging/log4j/1.2.17/log4j-1.2.17.zip

一、在Eclipse中配置Log4j

1.1、新建Java工程,导入包log4j-1.2.17.jar,工程如下图:

1.2、在src下创建log4j.propertiese配置文件,复制并粘贴以下内容到文件中:

### 根logger主要定义log4j支持的日志级别及输出目的地 ###
log4j.rootLogger=debug,stdout,file

### 配置控制台输出及输出格式 ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n

### 输出DEBUG级别以上的日志到工程根目录下的logs/log.log文件,可以自行修改为绝对路径 ###
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=logs/log.log
log4j.appender.file.Append=true
log4j.appender.file.Threshold=DEBUG
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ]  %m%n

注意:粘贴到Eclipse中后,有些小伙伴会呈现“乱码”:\u6839,这是Unicode编码,并不影响程序的执行。

1.3、在Java类中书写代码

package com.xuetang9.kenny;
import org.apache.log4j.Logger;
/**
 * 使用Log4j打印日志信息<br/>
 * @author Kenny
 * @version 1.0
 * @date 2018年1月8日 下午9:41:13
 * @copyright 老九学堂
 */
public class LoggerTest {
    private static Logger logger = Logger.getLogger(LoggerTest.class);
    public static void main(String[] args) {
        //日志记录的行为是分等级的,分为OFF、FATAL、ERROR、WARN、INFO、DEBUG、TRACE、ALL或者您定义的级别。
        //Log4j建议只使用四个级别,优先级从高到低分别是ERROR、WARN、INFO、DEBUG。
        logger.debug("记录debug级别信息");
        logger.info("记录info级别信息");
        logger.warn("记录warn级别信息");
    }
}

1.4、输出结果:

控制台:

logs/log.log文件中:

二、Log4j的基本使用方法

Log4j是高度可配置的,并可通过在运行时的外部文件配置。它根据记录的优先级别,并提供机制,以指示记录信息到许多的目的地,诸如:数据库,文件,控制台,UNIX系统日志等。
Log4j中有三个主要组成部分:
– loggers: 负责捕获记录信息。
– appenders : 负责发布日志信息,以不同的首选目的地。
– layouts: 负责格式化不同风格的日志信息。

2.1、配置文件的定义

log4j也可以通过配置文件的方式进行设置,目前支持两种格式的配置文件:xml文件和properties文件(推荐)。
1、配置根Logger,语法为:

log4j.rootLogger=[level], appenderName1, appenderName2, ....

level表示日志记录的优先级,分为OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL或者自定义的级别(E、F、G等)。Log4j建议只使用四个级别,优先级从高到低分别是ERROR、WARN、INFO、DEBUG。通过在这里定义的级别,我们可以控制到应用程序中相应级别的日志信息的开关。比如在这里定义了INFO级别,则应用程序中所有DEBUG级别的日志信息将不被打印出来。appenderName就是指日志信息输出到哪个地方。可以同时指定多个输出目的地。
2、配置日志信息输出目的地(Appender),语法如下:

log4j.appender.appenderName=fully.qualified.name.of.appender.class
log4j.appender.appenderName.option1=value1
    ...............
log4j.appender.appenderName.option=valueN

其中,log4j提供的appender有以下几种,根据项目需要使用即可:

org.apache.log4j.ConsoleAppender            输出到控制台
org.apache.log4j.FileAppender               输出到文件
org.apache.log4j.DailyRollingFileAppender   每天产生一个日志文件
org.apache.log4j.RollingFileAppender        文件大小到达指定尺寸的时候产生一个新的文件
org.apache.log4j.WriterAppender             将日志信息以流格式发送到任意指定的地方

3、配置日志信息输出的格式(布局),语法如下:

log4j.appender.appenderName.layout=fully.qualified.name.of.layout.class
log4j.appender.appenderName.layout.option1=value1
    ..............
log4j.appender.appenderName.layout.option=valueN

Log4j提供的格式layout有以下几种:

org.apache.log4j.HTMLLayout     以HTML表格形式布局
org.apache.log4j.PatternLayout  可以灵活地指定布局模式(常用)
org.apache.log4j.SimpleLayout   包含日志信息的级别和信息字符串
org.apache.log4j.TTCCLayout     包含日志产生的时间、线程、类别等等信息

Log4j采用类似C语言的printf函数格式化日志信息,打印参数如下:

%p 输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL
%r 输出自应用启动到输出该log信息耗费的毫秒数
%c 输出所属的类目,通常就是所在类的全名
%t 输出产生该日志事件的线程名
%n 输出一个回车换行符,Windows平台为“rn”,Unix平台为“n”
%d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH:mm:ss,SSS},输出类似:2018年12月31日 23:59:59,123
%l 输出日志事件的发生位置,包括类名、发生的线程,以及在代码中的行数。如:LoggerTest.main(LoggerTest.java:18)

4、日志级别
每个Logger都被了一个日志级别(log level),用来控制日志信息的输出。日志级别从高到低分为:
A:off 最高等级,用于关闭所有日志记录。
B:fatal 指出每个严重的错误事件将会导致应用程序的退出。
C:error 指出虽然发生错误事件,但仍然不影响系统的继续运行。
D:warm 表明会出现潜在的错误情形。
E:info 一般和在粗粒度级别上,强调应用程序的运行全程。
F:debug 一般用于细粒度级别上,对调试应用程序非常有帮助。
G:all 最低等级,用于打开所有日志记录。

上面这些级别是定义在org.apache.log4j.Level类中。Log4j只建议使用4个级别,优先级从高到低分别是error,warn,info和debug。通过使用日志级别,可以控制应用程序中相应级别日志信息的输出。例如,如果使用b了info级别,则应用程序中所有低于info级别的日志信息(如debug)将不会被打印出来。

java.util.logging.Logger在java JDK1.4以后便有这个东西的存在,但是因为log4j的存在,一直默默无闻被人们忽略。其实在一些测试性的代码中,jdk自带的这个logger比log4j更加的方便。

如何使用:
一、创建Logger对象
static Logger getLogger(String name) ——为指定子系统查找或创建一个 logger。
static Logger getLogger(String name, String resourceBundleName)——为指定子系统查找或创建一个 logger。
注意:name是Logger的名称,当名称相同时候,同一个名称的Logger只创建一个。

二、Logger的级别
在java.util.logging.Level中,有一套比log4j更加详细的级划分。各级别按从搞到低排列如下:
1.SEVERE(最高值)
2.WARNING
3.INFO
4.CONFIG
5.FINE
6.FINER
7.FINEST(最低值)
此外,还有一个级别 OFF,可用来关闭日志记录,使用级别 ALL 启用所有消息的日志记录。

logger默认的级别是INFO,比INFO更低的日志将不显示。
Logger的默认级别定义是在jre安装目录的lib下面。
# Limit the message that are printed on the console to INFO and above. 
java.util.logging.ConsoleHandler.level = INFO

实例:
一、简单的实例

public class TestLogger {
    public static void main(String[] args) {
        Logger log =Logger.getLogger("lavasoft");
        log.setLevel(Level.INFO);
        Logger log1 = Logger.getLogger("lavasoft");
        System.out.println(log==log1);     //true
        Logger log2 = Logger.getLogger("lavasoft.blog");
        log2.setLevel(Level.WARNING);
        log.info("aaa");
        log2.info("bbb");
        log2.fine("fine");
         }
    }
true
2009-7-28 20:00:30 TestLogger main 
信息: aaa

Process finished with exit code 0

当注释掉log2.setLevel(Level.WARNING);
输出结果:

true
2018-1-8 12:25:10 TestLogger main 
信息: aaa
2018-1-8 12:25:10 TestLogger main 
信息: bbb

Process finished with exit code 0
从这里可以看出,logger的名字是有层级关系的。这和log4j的控制方式完全一致。

下面是API文档的原文:
一般使用圆点分隔的层次命名空间来命名 Logger。Logger 名称可以是任意的字符串,但是它们一般应该基于被记录组件的包名或类名,如 java.net 或 javax.swing。此外,可以创建“匿名”的 Logger,其名称未存储在 Logger 命名空间中。
可通过调用某个 getLogger 工厂方法来获得 Logger 对象。这些方法要么创建一个新 Logger,要么返回一个合适的现有 Logger。

二、Logger的Handler
Handler 对象从 Logger 中获取日志信息,并将这些信息导出。例如,它可将这些信息写入控制台或文件中,也可以将这些信息发送到网络日志服务中,或将其转发到操作系统日志中。

可通过执行 setLevel(Level.OFF) 来禁用 Handler,并可通过执行适当级别的 setLevel 来重新启用。

Handler 类通常使用 LogManager 属性来设置 Handler 的 Filter、Formatter 和 Level 的默认值。

java.util.logging.Handler
java.util.logging.MemoryHandler
java.util.logging.StreamHandler
java.util.logging.ConsoleHandler
java.util.logging.FileHandler
java.util.logging.SocketHandler

例:

public class TestLogger { 
        public static void main(String[] args) throws IOException { 
                Logger log = Logger.getLogger("lavasoft");
                log.setLevel(Level.INFO);
                Logger log1 = Logger.getLogger("lavasoft");
                System.out.println(log==log1);     //true
                Logger log2 = Logger.getLogger("lavasoft.blog");
//                log2.setLevel(Level.WARNING);

                ConsoleHandler consoleHandler =new ConsoleHandler();
                consoleHandler.setLevel(Level.ALL);
                log.addHandler(consoleHandler);
                FileHandler fileHandler = new FileHandler("C:/testlog%g.log");
                fileHandler.setLevel(Level.INFO);
                log.addHandler(fileHandler);
                log.info("aaa");
                log2.info("bbb");
                log2.fine("fine");
        }
}

输出结果:

true
2018-1-8 12:30:14 TestLogger main
信息: aaa
2018-1-8 12:30:14 TestLogger main
信息: aaa
2018-1-8 12:30:14 TestLogger main
信息: bbb
2018-1-8 12:30:14 TestLogger main
信息: bbb

Process finished with exit code 0

查看C盘:

可见,默认的日志方式是xml格式,很烂。所以最好自定义下logger的格式。需要用Formatter来定义。

三、Logger的Formatter

Formatter 为格式化 LogRecords 提供支持。
一般来说,每个日志记录 Handler 都有关联的 Formatter。Formatter 接受 LogRecord,并将它转换为一个字符串。
有些 formatter(如 XMLFormatter)需要围绕一组格式化记录来包装头部和尾部字符串。可以使用 getHeader 和 getTail 方法来获得这些字符串。

LogRecord 对象用于在日志框架和单个日志 Handler 之间传递日志请求。
LogRecord(Level level, String msg)
用给定级别和消息值构造 LogRecord。

java.util.logging.Formatter 
java.util.logging.SimpleFormatter 
java.util.logging.XMLFormatter

简单举个实例:

public class TestLogger { 
        public static void main(String[] args) throws IOException { 
                Logger log = Logger.getLogger("lavasoft"); 
                log.setLevel(Level.INFO); 
                Logger log1 = Logger.getLogger("lavasoft"); 
                System.out.println(log == log1);     //true 
                Logger log2 = Logger.getLogger("lavasoft.blog"); 
//                log2.setLevel(Level.WARNING); 

                ConsoleHandler consoleHandler = new ConsoleHandler(); 
                consoleHandler.setLevel(Level.ALL); 
                log.addHandler(consoleHandler); 
                FileHandler fileHandler = new FileHandler("C:/testlog%g.log"); 
                fileHandler.setLevel(Level.INFO); 
                fileHandler.setFormatter(new MyLogHander()); 
                log.addHandler(fileHandler); 

                log.info("aaa"); 
                log2.info("bbb"); 
                log2.fine("fine"); 
        } 
} 

class MyLogHander extends Formatter { 
        @Override 
        public String format(LogRecord record) { 
                return record.getLevel() + ":" + record.getMessage()+"\n"; 
        } 
}

输出:
在控制和C盘输出的文件如图

以上就是所有关于Logger的使用和实例,小伙伴们使用成功了吗。

方法和构造方法的区别

构造方法
1.方法名称和类名相同。
2.不用写返回值和定义返回值类型。
3.不可以写return语句。
写构造方法的目的是为了给对象初始化
当一个类中没有定义构造方法时,系统会默认添加一个无参的构造方法。
当在类中自定义构造方法之后,默认的无参构造方法会消失(如果需要无参构造方法需要自己在写一个无参构造)。
构造方法与一般方法在运行上的不同:
构造方法在创建的时候就给对象初始化了;
一般方法是对象调用才执行,给对象添加对象具备的功能; 一般方法可以被对象多次调用;

set和get

set是设置的意思,而get是获取的意思,这两个方法是对数据进行设置和获取用的。
在类中使用set和get方法时,都是在set和get后面跟上一些特定的词来形成特定意思的方法名,比如setage()和getage(),表示设置年龄和获取年龄。

重载和重写

重载就是写几个相同的方法,但是他们的参数列表和返回值以及参数类型不同,根据你自己的实际需要,用的时候想调那个就调那个
重写就是子类继承了父类,其中就继承了方法,但是父类的方法子类用着不爽;所以想改改;那么这就是重写。
子类中的方法与父类中的方法具有相同的方法名、返回类型和参数列表,则新方法将覆盖原有的方法。

如果又需要父类中原有的方法,可使用super关键字,该关键字引用了当前类的父类。