如果将我录入的对一组数据进行排序序怎么修改代码 PS:在LINUX下执行SQL的代码 (可以不要排序功能 别的也可以)

CSDN博客推荐文章
http://blog.csdn.net
http://static.blog.csdn.net/images/logo.gif
CSDN博客内容聚合服务
http://blog.csdn.net
(C) 2011 CSDN.NET
http://blog.csdn.net
java.lang.Object
http://blog.csdn.net/zengxiantao1994/article/details/
http://blog.csdn.net/zengxiantao1994/article/details/
zengxiantao1994
Object类的定义
& & & & public class Object
& & & &&类Object是类层次结构的根类。每个类都使用Object作为超类。所有对象(包括数组)都实现这个类的方法。
& & & &&Java把现实中的任何事物都当做一个对象(Object),Java是面向对象的,就是Object Orentied简称OO。此处的Object在Java中被定义为一个顶级父类,它是任何类父类,我们可以显示的继承它,也可以隐式继承,如以下实例:
& & & &&public class Dog extends Object {&}
& & & &&与public classDog { },完全等价。
Object类的方法详解
1、publicboolean equals(Object obj)
& & & &&看equals之前需要先看下“==”,因为“==”是判断相等,equals也是判断相等,只是“==”主要用于判断基本数据类型的相等性,当然也可以直接判断两个对象。而equals主要判断对象内容。
& & & &&首先“==”判断基本数据类型时,比较的是两个的值是否相等,当“==”比较的是两个引用对象是,判断的是两者的首地址是否一致(相当于判断是否是同一个引用)。
& & & &&Object类中的equals()方法如下:
& & & &&public boolean equals(Object obj)&{
& & & &&& & & &&return (this == obj);
& & & &&即Object类中的equals()方法等价于==。
& & & &&只有当继承Object的类覆写(override)了equals()方法之后,继承类实现了用equals()方法比较两个对象的内容是否相等,才可以说equals()方法与==的不同。
& & & &&equals()方法需要具有如下特点:
& & & &&自反性(reflexive):任何非空引用x,x.equals(x)返回为true。
& & & &&对称性(symmetric):任何非空引用x和y,x.equals(y)返回true当且仅当y.equals(x)返回true。
& & & &&传递性(transitive):任何非空引用x和y,如果x.equals(y)返回true,并且y.equals(z)返回true,那么x.equals(z)返回true。
& & & &&一致性(consistent):两个非空引用x和y,x.equals(y)的多次调用应该保持一致的结果,(前提条件是在多次比较之间没有修改x和y用于比较的相关信息)。
& & & &&约定:对于任何非空引用x,x.equals(null)应该返回为false。
& & & &&并且覆写equals()方法时,应该同时覆写hashCode()方法,反之亦然。
2、publicint hashCode()
& & & &&返回该对象的哈希码值(hashcode value,一个整型值)。支持此方法是为了提高哈希表(例如java.util.Hashtable提供的哈希表)的性能。如果两个对象被equals()方法判断为相等,那么它们就应该拥有同样的hash
& & & &&当你覆写(override)了equals()方法之后,必须也覆写hashCode()方法,反之亦然。
& & & &&Object类的hashCode()方法为不同的对象返回不同的值,Object类的hashCode值表示的是对象的地址。
& & & &&hashCode的一般性契约(需要满足的条件)如下:
& & & &&1、在Java应用的一次执行过程中,如果对象用于equals比较的信息没有被修改,那么同一个对象多次调用hashCode()方法应该返回同一个整型值。应用的多次执行中,这个值不需要保持一致,即每次执行都是保持着各自不同的值。
& & & &&2、如果equals()判断两个对象相等,那么它们的hashCode()方法应该返回同样的值。
& & & &&3、并没有强制要求如果equals()判断两个对象不相等,那么它们的hashCode()方法就应该返回不同的值。即,两个对象用equals()方法比较返回false,它们的hashCode可以相同也可以不同。但是,应该意识到,为两个不相等的对象产生两个不同的hashCode可以改善哈希表的性能。
3、publicString toString()
& & & &&返回该对象的字符串表示。通常,toString 方法会返回一个“以文本方式表示”此对象的字符串。结果应是一个简明但易于读懂的信息表达式。建议所有子类都重写此方法。
& & & &&Object 类的 toString 方法返回一个字符串,该字符串由类名(对象是该类的一个实例)、at标记符“@”和此对象哈希码的无符号十六进制表示组成。换句话说,该方法返回一个字符串,它的值等于:getClass().getName()
+ '@' +Integer.toHexString(hashCode())。
& & & &&当打印引用,如调用System.out.println()时,会自动调用对象的toString()方法,打印出引用所指的对象的toString()方法的返回值,因为每个类都直接或间接地继承自Object,因此每个类都有toString()方法。
4、protectedObject clone() throws Clone NotSupportedException
& & & &&创建并返回此对象的一个副本。“副本”的准确含义可能依赖于对象的类。
& & & &&这样做的目的是,对于任何对象 x,表达式:x.clone() != x为true,表达式:x.clone().getClass() == x.getClass()也为true,但这些并非必须要满足的要求。一般情况下:
x.clone().equals(x)为true,但这并非必须要满足的要求。
& & & &&首先,使用这个方法的类必须实现java.lang.Cloneable接口,否则会抛出CloneNotSupportedException异常。Cloneable接口中不包含任何方法,所以实现它时只要在类声明中加上implements语句即可。
& & & &&第二个比较特殊的地方在于这个方法是protected修饰的,覆写clone()方法的时候需要写成public,才能让类外部的代码调用。
& & & &&按照惯例,返回的对象应该通过调用super.clone获得。如果一个类及其所有的超类(Object除外)都遵守此约定,则 x.clone().getClass() == x.getClass()。
& & & &&按照惯例,此方法返回的对象应该独立于该对象(正被复制的对象)。要获得此独立性,在super.clone返回对象之前,有必要对该对象的一个或多个字段进行修改。这通常意味着要复制包含正在被复制对象的内部“深层结构”的所有可变对象,并使用对副本的引用替换对这些对象的引用。如果一个类只包含基本字段或对不变对象的引用,那么通常不需要修改
super.clone 返回的对象中的字段。
& & & &&也就是clone的浅拷贝和深拷贝问题,在具体使用的时候需要特别注意:
& & & &&浅拷贝:如果一个对象内部还有一个引用类型的基本变量,那么在拷贝该对象的时候,只是在通过clone方法新产生的新对象中拷贝一个该基本类型的引用。换句话说,也就是新对象和原对象他们内部都含有一个指向同一对象的引用。
& & & &&深拷贝:拷贝对象的时候,如果对象内部含有一个引用类型的变量,那么就会再将该引用类型的变量指向的对象复制一份,然后引用该新对象。
5、publicfinal Class&?&
& & & &&getClass()返回此Object的运行时类。返回的Class对象是由所表示类的static &synchronized 方法锁定的对象。
& & & &&实际结果类型是Class&?extends |X|&,其中|X|表示清除表达式中的静态类型,该表达式调用getClass。例如,以下代码片段中不需要强制转换:
& & & &&Number n = 0;
& & & &&Class&? extends Number& c = n.getClass();
6、protectedvoid finalize() throws Throwable
& & & &&当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。子类重写finalize方法,以配置系统资源或执行其他清除。
& & & &&finalize 的常规协定是:当 Java 虚拟机已确定尚未终止的任何线程无法再通过任何方法访问此对象时,将调用此方法,除非由于准备终止的其他某个对象或类的终结操作执行了某个操作。finalize 方法可以采取任何操作,其中包括再次使此对象对其他线程可用;不过,finalize 的主要目的是在不可撤消地丢弃对象之前执行清除操作。例如,表示输入/输出连接的对象的
finalize 方法可执行显式 I/O 事务,以便在永久丢弃对象之前中断连接。
& & & &&Object 类的 finalize 方法执行非特殊性操作;它仅执行一些常规返回。Object 的子类可以重写此定义。
& & & &&Java 编程语言不保证哪个线程将调用某个给定对象的 finalize 方法。但可以保证在调用 finalize 时,调用 finalize 的线程将不会持有任何用户可见的同步锁定。如果 finalize 方法抛出未捕获的异常,那么该异常将被忽略,并且该对象的终结操作将终止。
& & & &&在启用某个对象的finalize 方法后,将不会执行进一步操作,直到 Java 虚拟机再次确定尚未终止的任何线程无法再通过任何方法访问此对象,其中包括由准备终止的其他对象或类执行的可能操作,在执行该操作时,对象可能被丢弃。
& & & &&对于任何给定对象,Java虚拟机最多只调用一次 finalize 方法。finalize 方法抛出的任何异常都会导致此对象的终结操作停止,但可以通过其他方法忽略它。
7、wait()与notify/notifyAll方法
& & & &&首先必须要注意的是wait()与notify/notifyAll
方法必须在同步代码块中使用。
& & & &&当线程执行wait()时,会把当前的锁释放,然后让出CPU,进入等待状态。当执行notify/notifyAll方法时,会唤醒一个处于等待该对象锁的线程,然后继续往下执行,直到执行完退出对象锁锁住的区域(synchronized修饰的代码块)后再释放锁。
& & & &&这里需要注意,notify/notifyAll()执行后,并不立即释放锁,而是要等到执行完临界区中代码后,再释放。故在实际编程中,我们应该尽量在线程调用notify/notifyAll()后,立即退出临界区。即不要在notify/notifyAll()后面再写一些耗时的代码。此外wait()方法唤醒的线程也不是立马就能获得锁,进入运行状态,wait方法只是唤醒它进入等待队列。
作者:zengxiantao1994 发表于 17:50:56
阅读:1 评论:0
Java设计模式_(创建型)_原型模式
http://blog.csdn.net/vtopqx/article/details/
http://blog.csdn.net/vtopqx/article/details/
引用百科:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。原型模式是一种创建型设计模式,Prototype模式允许一个对象再创建另外一个可定制的对象,根本无需知道任何如何创建的细节,工作原理是:通过将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象通过请求原型对象拷贝它们自己来实施创建。解决什么问题:它主要面对的问题是:“某些结构复杂的对象”的创建工作;由于需求的变化,这些对象经常面临着剧烈的变化,但是他们却拥有比较稳定一致的接口。如何解决:利用已有的一个原型对象,快速地生成和原型对象一样的实例。关键代码:&1、实现克隆操作,在 JAVA 继承 Cloneable,重写 clone()。 2、原型模式同样用于隔离类对象的使用者和具体类型(易变类)之间的耦合关系,它同样要求这些&易变类&拥有稳定的接口。优点:&1、性能提高。 2、逃避构造函数的约束。缺点:&1、配备克隆方法需要对类的功能进行通盘考虑,这对于全新的类不是很难,但对于已有的类不一定很容易,特别当一个类引用不支持串行化的间接对象,或者引用含有循环结构的时候。 2、必须实现 Cloneable 接口。 3、逃避构造函数的约束。使用场景:&1、资源优化场景。&2、类初始化需要消化非常多的资源,这个资源包括数据、硬件资源等。&3、性能和安全要求的场景。&4、通过 new 产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式。&5、一个对象多个修改者的场景。&6、一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以考虑使用原型模式拷贝多个对象供调用者使用。&7、在实际项目中,原型模式很少单独出现,一般是和工厂方法模式一起出现,通过 clone 的方法创建一个对象,然后由工厂方法提供给调用者。原型模式已经与 Java 融为浑然一体,大家可以随手拿来使用。注意事项:与通过对一个类进行实例化来构造新对象不同的是,原型模式是通过拷贝一个现有对象生成新对象的。浅拷贝实现 Cloneable,重写,深拷贝是通过实现 Serializable 读取二进制流。具体实现:我们将创建一个抽象类&Prototype和扩展了&Prototype类的实体类。下一步是定义类&cacheMap,该类把 Prototype对象存储在一个 Map中,并在请求的时候返回它们的克隆。Client,测试类使用&Client类来获取&Prototype的克隆对象。如下:具体代码如下:-------------------------------------------------------------------------------------------------------------------1、定义原型抽象类Prototype(也可以是接口)&实现Cloneable接口public abstract class Prototype implements Cloneable {
protected S
abstract void show();
public String getType() {
public String getId() {
public void setId(String id) {
public Object clone() {
Object clone =
clone = super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}2、定义具体的自定义创建实例类:public class Instance1 extends Prototype {
public Instance1() {
type = &Instance1&;
void show() {
System.out.println(&Inside Rectangle::draw() method.&);
}public class Instance2 extends Prototype {
public Instance2() {
type = &Instance2&;
void show() {
System.out.println(&Inside Square::draw() method.&);
}3、创建客户端Client测试:public class Client {
//设置个实例对象缓存
private static Map&String, Prototype& cacheMap = new HashMap&String, Prototype&();
public static void main(String[] args) {
//初始化待克隆创建对象
loadCache();
//分别进行各对象实例进行创建
Instance1 clonedInstance1 = (Instance1) getProto(&1&);
System.out.println(&Prototype : & + clonedInstance1.getType());
Instance2 clonedInstance2 = (Instance2) getProto(&2&);
System.out.println(&Prototype : & + clonedInstance2.getType());
* @Description: 根据不同实例ID进行克隆
* @param shapeId 实例编号
public static Prototype getProto(String shapeId) {
Prototype cachedProto = cacheMap.get(shapeId);
return (Prototype) cachedProto.clone();
// 例如,我们要添加三种形状
public static void loadCache() {
Instance1 obj1 = new Instance1();
obj1.setId(&1&);
cacheMap.put(obj1.getId(), obj1);
Instance2 obj2 = new Instance2();
obj2.setId(&2&);
cacheMap.put(obj2.getId(), obj2);
}通过以上代码,可以实现利用已有的一个原型对象,快速地生成和原型对象一样的实例。运行以上代码之后,可以生成,Prototype : Instance1Prototype : Instance2
作者:vtopqx 发表于 17:19:13
阅读:0 评论:0
windows+sublime text3+MINGW编译运行c
http://blog.csdn.net/hahachenchen789/article/details/
http://blog.csdn.net/hahachenchen789/article/details/
hahachenchen789
在linux下,编译运行c或者c++或python等非常简单,因为包含了gcc,g++编译器和python解释器。
在windows下,可以利用MINGW安装gcc和g++编译器。
MINGW:是Minimalist GNUfor Windows的缩写。
MINGW提供了一键自动安装的傻瓜式安装软件,地址:
然后选择第二个base和g++即可。其他对于c都不需要。
安装好后,配置环境变量。这个百度即可。这里写下本人的路径,方便以后查看:
系统变量-&PATH:&C:\MinGW\bin
系统变量:新建变量:LIBRARY_PATH 变量值:C:\MinGW\lib
系统变量:新建变量:C_INCLUDEDE_PATH变量值:C:\MinGW\include
安装好后,可以在命令行,输入gcc -v,能够显示版本信息而不报错,说明成功。
sublime的安装不多赘述,要说明的是如何添加c的编译系统。进入如下界面:
然后在新弹出的文本框中输入以下配置信息:
&working_dir&: &$file_path&,
&cmd&: &gcc -Wall \&$file_name\& -o \&$file_base_name\&&,
&file_regex&: &^(..[^:]*):([0-9]+):?([0-9]+)?:? (.*)$&,
&selector&: &source.c&,
&variants&:
&name&: &Run&,
&shell_cmd&: &gcc -Wall \&$file\& -o \&$file_base_name\& && start cmd /c \&${file_path}/${file_base_name} & pause\&&
然后ctrl+s保存为c.sublime-buld即可。
再次点击,tool-&build system,能够看到c这个选项,勾选即可。
然后新建一个c文件,写一个例子,利用ctrl+B编译运行即可。结果会以命令提示符的形式弹出。
作者:hahachenchen789 发表于 16:23:25
阅读:42 评论:0
Leetcode c语言-Implement strStr()
http://blog.csdn.net/hahachenchen789/article/details/
http://blog.csdn.net/hahachenchen789/article/details/
hahachenchen789
Implement strStr().
Returns the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack.
这道题是实现c的库函数,strstr(str1,str2),也就是返回子字符串str2在str1中第一次出现的位置,如果没有,则返回-1。
思路如下:首先在字符串str1中找str2的第一个字符,如果存在,再进一步比较str2后面的字符与str1后面的字符是否相等。很容易的一道题。
int strStr(char* haystack, char* needle) {
int flag=0;
if (!needle[0])
while (haystack[i]) {
if (needle[0]==haystack[i]) {
while (needle[j]) {
if (needle[j] && !haystack[tmp])
return -1;
if (needle[j]==haystack[tmp]) {
if (flag==0)
return -1;
要注意到一些细节。
1.如果子字符串为空,那么返回0。
2.如果子字符串的长度大于母字符串,那么不用比对,直接输出-1,这样能够大大降低时间开销。那么如何知道他们的长度,如果用while循环,分别得出它们的长度,固然可取,但由于两个while遍历字符串,时间开销会大大增加,得不偿失。
因此本人采用的办法如下:
if (needle[j] && !haystack[tmp])
return -1;
在比对过程中,如果needle的某个字符不为0,也就是没有到最后,而母字符串haystack的字符为0,也就是此时haystack已经到了最后,此时,needle一定不存在于haystack中,返回0。
下图是采用了长度判断和没有采用的运行时间对比:
可以看出采用了长度判断,时间开销大大减少。
作者:hahachenchen789 发表于 16:02:54
阅读:43 评论:0
Android魔术(第五弹)—— 一步步实现滑动折叠列表
http://blog.csdn.net/chzphoenix/article/details/
http://blog.csdn.net/chzphoenix/article/details/
chzphoenix
Android魔法系列:
项目的github地址:& 很多炫酷的自定义效果,欢迎fork和star!
1、效果展示
这个效果是一年多前完成的,是模仿了当时喵街app的首页的效果,现在整理出来可能有些过时了,不过一些知识点和思路还是很有帮助的。实现后效果如下:
2、效果分析
首先我们看静止状态,如图:
这时处于顶端展示的item相对于其他item是展开的状态,有几点表现:一是整体高度要高一些;二是无遮罩高亮状态;三是文字内容大一些。这样就达到了一个凸显的效果。
然后我们观察滑动中的状态,如图:
当我们向上滑动的时候,可以看到第一个item开始折叠,而第二个item逐渐展开,同时遮罩效果减弱,文字内容逐渐变大。这样就产生了滑动折叠的效果。
而且,为了能让最后的item也可以凸显出来,我们需要在列表的结尾插入一个footer以保证最后的item可以置顶显示,如图:
3、Item布局
效果分析完了,下面我们来看看如何实现。
首先是Item的布局,这里只关注重要的部分,代码如下:
&FrameLayout&xmlns:android=&/apk/res/android&
& & & & & & &android:layout_width=&match_parent&
& & & & & & &android:layout_height=&wrap_content&&
& & &RelativeLayout
& & & & android:id=&@+id/item_content&
& & & & android:layout_width=&match_parent&
& & & & android:layout_height=&@dimen/scroll_fold_item_height&&
& & & & &ImageView
& & & & & & android:id=&@+id/item_img&
& & & & & & android:layout_width=&match_parent&
& & & & & & android:layout_height=&match_parent&
& & & & & & android:scaleType=&fitXY&/&
& & & & &ImageView
& & & & & & android:id=&@+id/item_img_shade&
& & & & & & android:layout_width=&match_parent&
& & & & & & android:layout_height=&match_parent&
& & & & & & android:src=&#000000&/&
& & & & &LinearLayout
& & & & & & android:id=&@+id/scale_item_content&
& & & & & & android:layout_width=&200dp&
& & & & & & android:layout_height=&wrap_content&
& & & & & & android:layout_centerHorizontal=&true&
& & & & & & android:orientation=&vertical&&
& & & & & & ...
& & & & & &
& & & & &/LinearLayout&
& & & & ...
& & &/RelativeLayout&
&/FrameLayout&
最外层用FrameLayout,这样当FrameLayout高度变小时,item_content可以超出FrameLayout的范围,产生折叠的效果。
item_content的高度是固定不变的,真正改变的是外层的FrameLayout。
scale_item_content中是那些大小可变的文字内容
布局比较简单,后面会讲到如何使用这些layout达到效果。
另外还有一个footer的布局,因为很简单就不贴出代码了。
3、实现Adapter
列表是通过RecyclerView来实现的,所以我们先实现Adapter。代码也比较简单,我们挑重点说。
首先是Adapter的两个基本方法的实现:
public&ViewHolder&onCreateViewHolder(ViewGroup&parent,&int&viewType)&{
& &if(viewType&==&0)&{
& & & View&item&=&LayoutInflater.from(mContext).inflate(R.layout.scroll_fold_list_item,&null);
& & & return&new&ItemViewHolder(item);
& & & View&bottom&=&LayoutInflater.from(mContext).inflate(R.layout.scroll_fold_list_footer,&null);
& & & return&new&BottomViewHolder(bottom);
public&void&onBindViewHolder(ViewHolder&holder,&int&position)&{
& &holder.initData(position);
这里使用viewType来区分普通的item和footer(通过getItemViewType方法)。BottomViewHolder和ItemViewHolder继承同一个类,代码如下:
abstract&class&ViewHolder&extends&RecyclerView.ViewHolder{
& &View&item;
& &public&ViewHolder(View&itemView)&{
& & & super(itemView);
& & & item&=&itemView;
& &abstract&void&initData(int&position);
class&BottomViewHolder&extends&ViewHolder{
& &public&BottomViewHolder(View&itemView)&{
& & & super(itemView);
& &@Override
& &void&initData(int&position)&{
& & & ViewGroup.LayoutParams&bottomParams&=&itemView.getLayoutParams();
& & & if(bottomParams&==&null){
& & & & &bottomParams&=&new&ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,&0);
& & & bottomParams.height&=&recyclerView.getHeight()&-&itemHeight&+&10;
& & & itemView.setLayoutParams(bottomParams);
class&ItemViewHolder&extends&ViewHolder{
& &View&content;
& &ImageViewℑ
& &TextView&name;
& &public&ItemViewHolder(View&itemView)&{
& & & super(itemView);
& & & item&=&itemView;
& & & content&=&itemView.findViewById(R.id.item_content);
& & & image&=&(ImageView)itemView.findViewById(R.id.item_img);
& & & name&=&(TextView)&itemView.findViewById(R.id.item_name);
& &void&initData(int&position){
& & & image.setImageResource(IMGS[position]);
& & & name.setText(NAMES[position]);
& & & ViewGroup.LayoutParams&params&=&item.getLayoutParams();
& & & if(params&==&null){
& & & & &params&=&new&ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,&0);
& & & params.height&=&itemSmallHeight;
& & & content.findViewById(R.id.item_img_shade).setAlpha(ITEM_SHADE_DARK_ALPHA);
& & & item.setLayoutParams(params);
我们先看BottomViewHolder,动态的设置footer的高度为列表高度减去itemHeight,再加上10像素。这个itemHeight是展开后item的高度,即置顶的item的高度。这里之所以再加上10像素,是因为如果设置高度正好是余下的高度,当快速滑动到底部的时候有几率会出现问题,所以这里让高度略大于实际展示的高度。
然后来看ItemViewHolder,也是动态的设置高度为ItemSmallHeight,这个高度是收缩后item的高度,而且将遮罩设置为最暗。注意这里全部初始化为收缩状态,没有单独设置一个置顶展开的状态,这个我们后面会解释为什么。
4、监听滑动
上面我们完成了adapter类,添加给RecyclerView即可。不过想要实现效果,就需要监听RecyclerView的滑动,并做相应的处理,代码如下:
list.addOnScrollListener(new&RecyclerView.OnScrollListener()&{
& &@Override
& &public&void&onScrolled(RecyclerView&recyclerView,&int&dx,&int&dy)&{
& & & changeItemState();
& &@Override
& &public&void&onScrollStateChanged(RecyclerView&recyclerView,&int&newState)&{
可以看到在滑动过程(onScrolled)中调用changeItemState()这个函数,代码如下:
private&void&changeItemState(){
& &int&firstVisibleIndex&=&linearLayoutManager.findFirstVisibleItemPosition();
& &ViewGroup&first&=&(ViewGroup)&linearLayoutManager.findViewByPosition(firstVisibleIndex);
& &int&firstVisibleOffset&=&-first.getTop();
& &int&changeheight&=&(int)&(firstVisibleOffset&*&(ScrollFoldAdapter.ITEM_CONTENT_TEXT_SCALE&-&1));
& &//&减少当前展示的第一个item的高度。
& &if&(first&==&null)&{
& &changeItemHeight(first,&itemHeight&-&changeheight);
& &changeItemState(first,&ScrollFoldAdapter.ITEM_CONTENT_TEXT_SCALE,&ScrollFoldAdapter.ITEM_SHADE_LIGHT_ALPHA);
& &//&增大当前展示的第二个item的高度,改变内容大小,改变透明度
& &if&(firstVisibleIndex&+&1&&&adapter.getItemCount()&-&1)&{
& & & ViewGroup&second&=&(ViewGroup)&linearLayoutManager.findViewByPosition(firstVisibleIndex&+&1);
& & & changeItemHeight(second,&itemSmallHeight&+&changeheight);
& & & float&scale&=&(float)&firstVisibleOffset&/&itemSmallHeight
& & & & & & *&(ScrollFoldAdapter.ITEM_CONTENT_TEXT_SCALE&-&1)&+&1.0f;
& & & float&alpha&=&(ScrollFoldAdapter.ITEM_SHADE_DARK_ALPHA&-&ScrollFoldAdapter.ITEM_SHADE_LIGHT_ALPHA)
& & & & & & *&(1&-&(float)&firstVisibleOffset&/&itemSmallHeight)
& & & & & & +&ScrollFoldAdapter.ITEM_SHADE_LIGHT_ALPHA;
& & & changeItemState(second,&scale,&alpha);
& & *&由于快速滑动,导致计算及状态有误&所以下面就是消除这种误差,校准状态。具体如下
& & *&将第一个item上面(存在的)的和第二个Item下面的都变为收缩的高度,内容缩放到最小,透明度为0。65
& &for&(int&i&=&0;&i&&=&linearLayoutManager.findLastVisibleItemPosition();&i++)&{
& & & if&(i&&&adapter.getItemCount()&-&1&&&&i&!=&firstVisibleIndex&&&&i&!=&firstVisibleIndex&+&1)&{
& & & & &ViewGroup&item&=&(ViewGroup)&linearLayoutManager.findViewByPosition(i);
& & & & &if(item&==&null){
& & & & & & & & & &
& & & & & & & &}
& & & & & & & &changeItemHeight(item,&itemSmallHeight);
& & & & &float&scale&=&1;
& & & & &float&alpha&=&ScrollFoldAdapter.ITEM_SHADE_DARK_ALPHA;
& & & & &changeItemState(item,&scale,&alpha);
整体思路如下:
获取当前置顶展示的item,计算该item相对于列表顶端的偏移。这个偏移是关键参数,通过这个偏移计算出第一个item收缩的高度和第二个item展开的高度,并且计算第二个item遮罩的透明度和文字内容的大小。
这里调用了另外两个函数changeItemHeight(view, int)和changeItemState(view, float, float)。其中changeItemHeight(view, int)用来改变item的高度实现展开或折叠;而changeItemState(view,
float, float)用来改变遮罩透明度和文字内容大小。两个函数代码如下:
&*&改变一个item的高度。
&*&@param&item
&*&@param&height
private&void&changeItemHeight(View&item,&int&height)&{
& &ViewGroup.LayoutParams&itemParams&=&item.getLayoutParams();
& &itemParams.height&=&height;
& &item.setLayoutParams(itemParams);
&*&改变一个item的状态,包括透明度,大小等
&*&@param&item
&*&@param&scale
&*&@param&alpha
private&void&changeItemState(ViewGroup&item,&float&scale,&float&alpha)&{
& &if&(item.getChildCount()&&&0)&{
& & & View&changeView&=&item.findViewById(R.id.scale_item_content);
& & & changeView.setScaleX(scale);
& & & changeView.setScaleY(scale);
& & & View&shade&=&item.findViewById(R.id.item_img_shade);
& & & shade.setAlpha(alpha);
改变高度很简单,没必要解释了。改变遮罩透明度就是改变其alpha,而文字内容大小的改变则是利用setScaleX和setScaleY两个函数,实际上是将scale_item_content这个layout整个进行缩放,其内容就会随着变大/小。
回到changeItemState()函数,改变了第一个和第二个item后,可以看到又将其他的item置为收缩状态。这是因为快速滑动会造成某些item处于中间的状态,做这一步操作就是校正快速滑动导致的一些问题。
上面我们提到过,所有的item都初始化成收缩状态了。其实当RecyclerView添加到屏幕上时,是一定会产生滑动的。所以我们进入页面的时候,我们什么都没有操作,滑动监听的函数却被调用了。这样通过changeItemState()函数就可以将置顶的item变为展开状态,所以初始的展示状态是正确的。
5、回弹效果
以上是滑动的时候的处理,然而这样还不够。当滑动停止的时候,有可能第一个item正处于显示一半的状态,这样第二个item也没有完全展开,显示效果不好。
所以我们还需要实现一个回弹效果,当滑动停止的时候,让列表自动调整到某一个item正好置顶的状态。
这部分的处理在滑动监听的onScrollStateChanged中,代码如下:
list.addOnScrollListener(new&RecyclerView.OnScrollListener()&{
& &@Override
& &public&void&onScrolled(RecyclerView&recyclerView,&int&dx,&int&dy)&{
& & & changeItemState();
& &@Override
& &public&void&onScrollStateChanged(RecyclerView&recyclerView,&int&newState)&{
& & & if&(newState&==&RecyclerView.SCROLL_STATE_IDLE)&{
& & & & &int&firstVisibleIndex&=&linearLayoutManager.findFirstVisibleItemPosition();
& & & & &View&first&=&linearLayoutManager.findViewByPosition(firstVisibleIndex);
& & & & &int&firstVisibleOffset&=&-first.getTop();
& & & & &if&(firstVisibleOffset&==&0)&{
& & & & & &
& & & & &}
& & & & &if&(firstVisibleOffset&&&itemSmallHeight&/&2)&{
& & & & & & list.scrollBy(0,&-firstVisibleOffset);
& & & & &}&else&{
& & & & & & list.scrollBy(0,&itemSmallHeight&-&firstVisibleOffset);
& & & & &}
& & & & &changeItemState();
上面是完整的滑动监听的代码。在onScrollStateChanged中,判断状态是否是滑动结束(SCROLL_STATE_IDLE)。如果滑动结束,判断顶部显示的item的偏移,根据偏移的大小选择回弹方向。如果偏移很小(第一个item大部分内容显示出来了),则下滚至第一个item置顶的状态;否则上滚至第二个item置顶的状态。
这样保证了静止状态下一定有一个item完全置顶高亮显示。
最后又调用了changeItemState函数,主要目的是校正一些误差。
6、总结一下
整个效果中其实没有太多难点,主要是考察了对RecyclerView滑动的理解。目前这个版本在快滑时还有一个小问题。
除了RecyclerView这个版本,实际上这个效果还有一个ScrollView的版本。其实在ListView和RecyclerView上实现这个效果都多少有些问题。所以我早期自己实现了能够复用和回收的ScrollView,利用这个自定义的ScrollView实现了这个效果,并且为其自定义了scroller使其回弹有了动画效果。ScrollView版本目前未发现任何问题,但是由于很多功能要自己实现,整体代码比较复杂,就选用了RecyclerView这个版本来给大家讲解。大家有兴趣可以去github上的项目中,切到tag
v1.0就可以看到了。
项目的github地址:
& 很多炫酷的自定义效果,欢迎fork和star!
Android魔法系列:
作者:chzphoenix 发表于 15:35:47
阅读:130 评论:0
C#中Abstract和Virtual
http://blog.csdn.net/qq_/article/details/
http://blog.csdn.net/qq_/article/details/
在C#的学习中,容易混淆virtual方法和abstract方法的使用,现在来讨论一下二者的区别。二者都牵涉到在派生类中与override的配合使用。
一、Virtual方法(虚方法)
virtual 关键字用于在基类中修饰方法。virtual的使用会有两种情况:
情况1:在基类中定义了virtual方法,但在派生类中没有重写该虚方法。那么在对派生类实例的调用中,该虚方法使用的是基类定义的方法。
情况2:在基类中定义了virtual方法,然后在派生类中使用override重写该方法。那么在对派生类实例的调用中,该虚方法使用的是派生重写的方法。
二、Abstract方法(抽象方法)
abstract关键字只能用在抽象类中修饰方法,并且没有具体的实现。抽象方法的实现必须在派生类中使用override关键字来实现。
接口和抽象类:
最本质的区别:抽象类是一个不完全的类,是对对象的抽象,而接口是一种行为规范。
C# 是面向对象的程序设计语言,每一个函数都属于一个类。
Static:当一个方法被声明为Static时,这个方法是一个静态方法,编译器会在编译时保留这个方法的实现。也就是说,这个方法属于类,但是不属于任何成员,不管这个类的实例是否存在,它们都会存在。就像入口函数Static void Main,因为它是静态函数,所以可以直接被调用。
Virtua:当一个方法被声明为Virtual时,它是一个虚拟方法,直到你使用ClassName variable = new ClassName();声明一个类的实例之前,它都不存在于真实的内存空间中。这个关键字在类的继承中非常常用,用来提供类方法的多态性支持。
overrride:表示重写 这个类是继承于Shape类
public override double Area 这个属性再shape中肯定存在 但是这里我们不想用shape中的 所以要重写
virtual,abstract是告诉其它想继承于他的类 你可以重写我的这个方法或属性,否则不允许。
一个生动的例子 :老爸表示基类(被继承的类) 儿子表示子类(继承的类)
老爸用virtual告诉儿子:”孩子,你要继承我的事业,在这块上面可以自己继续发展你自己的”
儿子用override告诉全世界:”这个我可不是直接拿我爸的,他只是指个路给我,是我自己奋斗出来的”
abstract:抽象方法声明使用,是必须被派生类覆写的方法,抽象类就是用来被继承的;可以看成是没有实现体的虚方法;如果类中包含抽象方法,那么类就必须定义为抽象类,不论是否还包含其他一般方法;抽象类不能有实体的。
interface:用来声明接口
1.只提供一些方法规约,不提供方法主体. 如:
public interface IPerson
void getName();
2.方法不能用public abstract等修饰,无字段变量,无构造函数。
3.方法可包含参数。 如
public interface IPerson
void getAge(string s);
一个例子(例1):
public interface IPerson
IPerson();
public void getIDcard();
void getName();
void getAge(string s);
实现interface的类
1.与继承类的格式一致,如 public class Chinese:IPerson{}
2.必须实现 interface 中的各个方法
例2,继承例1
public class Chinese:IPerson
public Chinese(){}
public void getName(){}
public void getAge(string s){}
abstract:声明抽象类、抽象方法
1.抽象方法所在类必须为抽象类
2.抽象类不能直接实例化,必须由其派生类实现。
3.抽象方法不包含方法主体,必须由派生类以override方式实现此方法,这点跟interface中的方法类似
public abstract class Book
public Book()
public abstract void getPrice();
public virtual void getName() //虚方法,可覆盖
Console.WriteLine("this is a test:virtual getName()");
public virtual void getContent() //虚方法,可覆盖
Console.WriteLine("this is a test:virtual getContent()");
public void getDate() //一般方法,若在派生类中重写,须使用new关键字
Console.WriteLine("this is a test: void getDate()");
public class JavaBook:Book
public override void getPrice() //实现抽象方法,必须实现
Console.WriteLine("this is a test:JavaBook override abstract getPrice()");
public override void getName() //覆盖原方法,不是必须的
Console.WriteLine("this is a test:JavaBook override virtual getName()");
测试如下:
public class test
public test()
JavaBook jbook=new JavaBook();
jbook.getPrice();
jbook.getName();
jbook.getContent();
jbook.getDate();
public static void Main()
test t=new test();
virtual:标记方法为虚方法
1.可在派生类中以override覆盖此方法
2.不覆盖也可由对象调用
3.无此标记的方法(也无其他标记),重写时需用new隐藏原方法
abstract 与virtual : 方法重写时都使用 override 关键字
接口定义以大写字母I开头。方法只定义其名称,在C#中,方法默认是公有方法;用public修饰方法是不允许的,否则会出现编译错误;接口可以从别的接口继承,如果是继承多个接口,则父接口列表用逗号间隔。
接口可以通过类来实现,当类的基列表同时包含基类和接口时,列表中首先出现的是基类;类必须要实现其抽象方法;
接口使用:见代码(转)
interface使用
interface使用(实例一)
namespace Dage.Interface
public interface IPrint
string returnPrintName();
using Dage.I
namespace Dage.Print
public class HP: IPrint
public string returnPrintName()
return "这是HP牌打印机";
namespace Dage.Print
public class Eps: IPrint
public string returnPrintName()
return "这是Eps牌打印机";
using Dage.I
namespace Dage
public class Printer
public Printer()
public string PrintName(IPrint iPrint)
return iPrint.returnPrintName();
//——————————————–
–WinFrom中调用代码:
private void button1_Click(object sender, System.EventArgs e)
Printer p= new Printer();
switch (this.comboBox1.Text)
case "HP":
MessageBox.Show(p.PrintName(new HP()));
case "Eps":
MessageBox.Show(p.PrintName(new Eps()));
MessageBox.Show("没有发现这个品牌!");
作者:qq_ 发表于 15:19:25
阅读:75 评论:1
[HNOI2008]玩具装箱toy
(斜率优化DP)
http://blog.csdn.net/ever_glow/article/details/
http://blog.csdn.net/ever_glow/article/details/
1010: [HNOI2008]玩具装箱toy
Time Limit:&1 Sec&&Memory Limit:&162 MB
Submit:&11388&&Solved:&4801
Description
Sample Input
Sample Output
了解斜率DP之后,信心满满的来A这道题,可怕在WA两位数之后,参考别人的写法过了,后来再修改,还是WA,经过无数次折磨之后才知道是最后入队列的问题,应该是++i,我一直在执行i++,然后花样WA。
通过此题对斜率优化 DP 有了更深层次的理解,但是化简的过程实在是折磨人,而且竟然还化简出了不能进行斜率DP的dp[i]*dp[j]形式,要不是知道这个题是斜率DP,估计就放弃了。推断的过程都是千篇一律。
看到最小费用就想用最小费用流,虽然不怎么会用。哎。。。
代码实现:
#include&iostream&
#include&algorithm&
#include&cstring&
#include&cmath&
#include&queue&
#include&cstdio&
#define ll long long
#define mset(a,x) memset(a,x,sizeof(a))
const double PI=acos(-1);
const int inf=0x3f3f3f3f;
const double esp=1e-6;
const int maxn=5e4+5;
const int mod=1e9+7;
int dir[4][2]={0,1,1,0,0,-1,-1,0};
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
ll inv(ll b){if(b==1)return 1; return (mod-mod/b)*inv(mod%b)%}
ll fpow(ll n,ll k){ll r=1;for(;k;k&&=1){if(k&1)r=r*n%n=n*n%}}
ll n,m,q[maxn],head,
ll sum[maxn],dp[maxn];
double get_k(ll y,ll x)
return ((dp[x]-dp[y]+(sum[x]+m)*(sum[x]+m)-(sum[y]+m)*(sum[y]+m))/(2.0*(sum[x]-sum[y])));
tail=1;head=1;
q[tail]=0;
for(i=1;i&=n;i++)
while(head&tail&&get_k(q[head],q[head+1])&=sum[i])
dp[i]=dp[q[head]]+(sum[i]-sum[q[head]]-m)*(sum[i]-sum[q[head]]-m);
while(head&tail&&get_k(q[tail],i)&get_k(q[tail-1],q[tail]))
q[++tail]=i;
int main()
ll i,j,k,x;
while(cin&&n&&m)
mset(dp,0);
mset(q,0);
mset(sum,0);
for(i=1;i&=n;i++)
sum[i]=sum[i-1]+x;
for(i=1;i&=n;i++)
sum[i]+=i;
cout&&dp[n]&&
作者:Ever_glow 发表于 14:58:43
阅读:78 评论:0
Java 虚拟机垃圾回收机制
http://blog.csdn.net/freekiteyu/article/details/
http://blog.csdn.net/freekiteyu/article/details/
freekiteyu
Java 虚拟机垃圾回收机制
垃圾回收是一种自动的存储管理机制。 当一些被占用的内存不再需要时,就应该予以释放,以让出空间,这种存储资源管理,称为垃圾回收(Garbage Collection)。 垃圾回收器可以让程序员减轻许多负担,也减少程序员犯错的机会。
哪些对象需要回收?
自动垃圾回收机制就是寻找Java堆中的对象,并对对象进行分类判别,寻找出正在使用的对象和已经不会使用的对象,然后把那些不会使用的对象从堆上清除。
引用计数法
引用计数算法是垃圾收集器中的早期策略。 在这种方法中,堆中的每个对象实例都有一个引用计数。 当一个对象被创建时,且将该对象实例分配给一个引用变量,该对象实例的引用计数设置为 1。 当任何其它变量被赋值为这个对象的引用时,对象实例的引用计数加 1(a = b,则b引用的对象实例的计数器加 1),但当一个对象实例的某个引用超过了生命周期或者被设置为一个新值时,对象实例的引用计数减 1。 特别地,当一个对象实例被垃圾收集时,它引用的任何对象实例的引用计数器均减 1。 任何引用计数为0的对象实例可以被当作垃圾收集。
引用计数收集器可以很快的执行,并且交织在程序运行中,对程序需要不被长时间打断的实时环境比较有利,但其很难解决对象之间相互循环引用的问题
可达性分析
可达性分析算法是从离散数学中的图论引入的,程序把所有的引用关系看作一张图,通过一系列的名为 “GC Roots” 的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain)。 当一个对象到 GC Roots 没有任何引用链相连(用图论的话来说就是从 GC Roots 到这个对象不可达)时,则证明此对象是不可用的。
标记-清除算法
标记,也就是垃圾收集器会找出那些需要回收的对象所在的内存和不需要回收的对象所在的内存,并把它们标记出来,简单的说,也就是先找出垃圾在哪儿?
所有堆中的对象都会被扫描一遍,以此来确定回收的对象,所以这通常会是一个相对比较耗时的过程。
清除,垃圾收集器会清除掉上一步标记出来的那些需要回收的对象区域。
存在的问题就是碎片问题,标记清除之后会产生大量不连续的内存碎片,空间碎片太多可能会导致以后在程序运行过程中需要分配较大对象时,无法找到足够的连续内存而不得不提前触发另一次垃圾收集动作。
标记清除算法每次执行都需要对堆中全部对象扫面一遍效率不高,为解决效率问题,复制算法将内存按容量划分为大小相等的两块,每次只是用其中的一块。 当这一块使用完了,就将还存活的对象复制到另一块上面,然后再把已使用过的内存空间一次清理掉。 这样使得每次都对半区进行内存回收,内存分配时也就不用考虑内存碎片等复杂情况,只要移动堆顶指针,按顺序分配内存即可,实现简单,运行高效。
标记-整理算法
由于简单的标记清除可能会存在碎片的问题,所以又出现了压缩清除的方法,也就是先清除需要回收的对象,然后再对内存进行压缩操作,将内存分成可用和不可用两大部分。
当前商业虚拟机的垃圾收集都采用“分代收集”(Generation Collection)算法,这种算法并没有什么新的思想,只是根据对象存活周期的不同将内存划分为几块。 一般是把 Java 堆分为新生代和老年代,这样就可以根据各个年代的特点采用最适当的收集算法。 在新生代中,每次垃圾收集时都发现有大批对象死去,只有少量存活,那就选用复制算法,只需要付出少量存活对象的复制成本就可以完成收集。 而老年代中因为对象存活率较高、没有额外的空间对它进行分配担保,就必须使用“标记-清除”或者“标记-整理”算法来回收。
所有新 new 出来的对象都会最先出现在新生代中,当新生代这部分内存满了之后,就会发起一次垃圾收集事件,这种发生在新生代的垃圾收集称为 Minor collections。 这种收集通常比较快,因为新生代的大部分对象都是需要回收的,那些暂时无法回收的就会被移动到老年代。
全局暂停事件(Stop the World):所有小收集(minor garbage collections)都是全局暂停事件,也就是意味着所有的应用线程都需要停止,直到垃圾回收的操作全部完成。类似于“你妈妈在给你打扫房间的时候,肯定也会让你老老实实地在椅子上或者房间外待着,如果她一边打扫,你一边乱扔纸屑,这房间还能打扫完?”
老年代用来存储那些存活时间较长的对象。 一般来说,我们会给新生代的对象限定一个存活的时间,当达到这个时间还没有被收集的时候就会被移动到老年代中。随着时间的推移,老年代也会被填满,最终导致老年代也要进行垃圾回收。这个事件叫做大收集(major garbage collection)。
大收集也是全局暂停事件。通常大收集比较慢,因为它涉及到所有的存活对象。所以,对于对相应时间要求高的应用,应该将大收集最小化。此外,对于大收集,全局暂停事件的暂停时长会受到用于老年代的垃圾回收器的影响。
永久代存储了描述应用程序类和方法的元数据,JVM 运行应用程序的时候需要这些元数据。 永久代由 JVM 在运行时基于应用程序所使用的类产生。 此外,Java SE 类库的类和方法可能也存储在这里。
如果 JVM 发现有些类不在被其他类所需要,同时其他类需要更多的空间,这时候这些类可能就会被垃圾回收。
分代垃圾回收过程
我们已经知道垃圾回收所需要的方法和堆内存的分代,那么接下来我们就来具体看一下垃圾回收的具体过程。
第一步 所有 new 出来的对象都会最先分配到新生代区域中,两个 survivor 区域初始化是为空的。
第二步,当 eden 区域满了之后,就引发一次小收集(minor garbage collections)。
第三步,当在小收集(minor garbage collections)存活下来的对象就会被移动到 S0 survivor 区域。
第四步,然后当 eden 区域又填满的时候,又会发生下一次的垃圾回收,存活的对象会被移动到 survivor 区域而未存活对象会被直接删除。 但是,不同的是,在这次的垃圾回收中,存活对象和之前的 survivor 中的对象都会被移动到 s1 中。 一旦所有对象都被移动到 s1 中,那么 s2 中的对象就会被清除,仔细观察图中的对象,数字表示经历的垃圾收集的次数。 目前我们已经有不同的年龄对象了。
第五步,下一次垃圾回收的时候,又会重复上次的步骤,清除需要回收的对象,并且又切换一次 survivor 区域,所有存活的对象都被移动至 s0。 eden 和 s1 区域被清除。
第六步,重复以上步骤,并记录对象的年龄,当有对象的年龄到达一定的阈值的时候,就将新生代中的对象移动到老年代中。在本例中,这个阈值为8。
第七步,接下来垃圾收集器就会重复以上步骤,不断的进行对象的清除和年代的移动。
最后,我们观察上述过程可以发现,大部分的垃圾收集过程都是在新生代进行的,直到老年代中的内存不够用了才会发起一次 大收集(major garbage collection),会进行标记和整理压缩。
垃圾回收器的类型
Java 提供多种类型的垃圾回收器。 JVM 中的垃圾收集一般都采用“分代收集”,不同的堆内存区域采用不同的收集算法,主要目的就是为了增加吞吐量或降低停顿时间。
Serial 收集器:新生代收集器,使用复制算法,使用一个线程进行 GC,串行,其它工作线程暂停。
ParNew 收集器:新生代收集器,使用复制算法,Serial 收集器的多线程版,用多个线程进行 GC,并行,其它工作线程暂停。 使用 -XX:+UseParNewGC 开关来控制使用 ParNew+Serial Old 收集器组合收集内存;使用 -XX:ParallelGCThreads 来设置执行内存回收的线程数。
Parallel Scavenge 收集器:吞吐量优先的垃圾回收器,作用在新生代,使用复制算法,关注 CPU 吞吐量,即运行用户代码的时间/总时间。 使用 -XX:+UseParallelGC 开关控制使用 Parallel Scavenge+Serial Old 收集器组合回收垃圾。
Serial Old 收集器:老年代收集器,单线程收集器,串行,使用标记整理算法,使用单线程进行GC,其它工作线程暂停。
Parallel Old 收集器:吞吐量优先的垃圾回收器,作用在老年代,多线程,并行,多线程机制与 Parallel Scavenge 差不错,使用标记整理算法,在 Parallel Old 执行时,仍然需要暂停其它线程。
CMS(Concurrent Mark Sweep)收集器:老年代收集器,致力于获取最短回收停顿时间(即缩短垃圾回收的时间),使用标记清除算法,多线程,优点是并发收集(用户线程可以和GC线程同时工作),停顿小。 使用 -XX:+UseConcMarkSweepGC 进行 ParNew+CMS+Serial Old 进行内存回收,优先使用 ParNew+CMS,当用户线程内存不足时,采用备用方案 Serial Old 收集。
《深入理解 Java 虚拟机》
作者:freekiteyu 发表于 14:18:05
阅读:108 评论:0
保持iOS设备屏幕常亮的方法
http://blog.csdn.net/gsg8709/article/details/
http://blog.csdn.net/gsg8709/article/details/
因为自己的应用程序运行的时候需要保持屏幕常亮,可以加入以下语句:
(1)如果是在Xcode中做开发:
[ [ UIApplication sharedApplication] setIdleTimerDisabled:YES ] ;
设置为YES保持屏幕常亮.
(2)iOS5中,可以调节亮度了,我没有试过,大家试试看
[[UIScreen mainScreen]setBrightness:0.5f];
取值范围从0.0到1.0
(3)如果使用私有API,iOS5以下也可以做到,不过你的应用程序也会被Apple reject的
[[UIApplication sharedApplication]setBacklightLevel:1.0f];
作者:gsg8709 发表于 14:13:08
阅读:108 评论:0
Javamail配置阿里云邮箱发送邮件
http://blog.csdn.net/weixin_/article/details/
http://blog.csdn.net/weixin_/article/details/
前言:前面已经介绍过使用163邮箱发送邮件激活账号的例子了,本来想着应该千篇一律的,但是这里使用阿里邮箱发送邮件略有不同,更改配置之后总是报错,所以这里记录一下,为以后再次搭建方便,同时如果遇到同样问题的你看到这篇博客解决了,那就更好了。先了解一下基本的配置元素的概念:什么是POP3、SMTP?1、什么是POP3:POP3是Post Office Protocol3的简称,即邮局协议的第3个版本,它规定怎样将个人计算机连接到Internet的邮件服务器和下载电子邮件的电子协议。它是因特网电子邮件的第一个离线协议标准,POP3允许用户从服务器上把邮件存储到本地主机(即自己的计算机)上,同时删除保存在邮件服务器上的邮件,而POP3服务器则是遵循 POP3协议的接收邮件服务器,用来接收电子邮件的。2、什么是SMTP:SMTP 的全称是“Simple MailTransfer Protocol”,即简单邮件传输协议。它是一组用于从源地址到目的地址传输邮件的规范,通过它来控制邮件的中转方式。SMTP 协议属于 TCP/IP 协议簇,它帮助每台计算机在发送或中转信件时找到下一个目的地。SMTP 服务器就是遵循 SMTP 协议的发送邮件服务器。(SMTP 认证,简单地说就是要求必须在提供了账户名和密码之后才可以登录 SMTP 服务器,这就使得那些垃圾邮件的散播者无可乘之机。增加 SMTP 认证的目的是为了使用户避免受到垃圾邮件的侵扰。)代码实现流程:1,引入的包:&dependency&
&groupId&javax.mail&/groupId&
&artifactId&mail&/artifactId&
&version&1.4.7&/version&
&/dependency&
2,邮箱信息在Properties中的相关配置:smtpServer=
fromUserName=你的阿里邮箱账号
fromUserPassword=你的邮箱密码
这里注意了,很容易出错,网上一搜基本的教程都是这样的:smtpServer=也就是properties.put(&mail.smtp.host&, );但如果你使用的是阿里的企业邮箱,这样把邮箱的配置服务器地址照搬过来的做法是有问题的。这里应该使用自己企业的域名地址,比如我的域名是(当然这个也是假的,举个例子,哈哈),这里就应该配置。否则报错:javax.mail.AuthenticationFailedException:526Authentication failure[0]这里应该注意一下。3,邮箱实体类(设置邮箱、邮件的相关信息)public class EmailInfo {
private final String SSL_FACTORY = &javax.net.ssl.SSLSocketFactory&;
private String smtpS
// SMTP服务器地址
private S // 端口
private String fromUserN
// 登录SMTP服务器的用户名,发送人邮箱地址
private String fromUserP
// 登录SMTP服务器的密码
private String toU
private S // 邮件主题
private S // 邮件正文
public EmailInfo() {
public EmailInfo(String toUser, String subject, String content) {
this.toUser = toU
this.subject =
this.content =
this.smtpServer = Global.getConfig(&smtpServer&);
this.port = Global.getConfig(&port&);
this.fromUserName = Global.getConfig(&fromUserName&);
this.fromUserPassword = Global.getConfig(&fromUserPassword&);
//get、set方法略
4,发送邮件的实现类(工具类):public class EmailUtil {
* 进行base64加密,防止中文乱码
private static String changeEncode(String str) {
str = MimeUtility.encodeText(new String(str.getBytes(), &UTF-8&), &UTF-8&, &B&); // &B&代表Base64
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
public static boolean sendHtmlMail(EmailInfo emailInfo) {
Properties properties = new Properties();
properties.put(&mail.smtp.host&, emailInfo.getSmtpServer());
properties.put(&mail.transport.protocol&, &smtp&);
properties.put(&mail.smtp.auth&, &true&);
properties.put(&mail.smtp.socketFactory.class&, &javax.net.ssl.SSLSocketFactory&); // 使用JSSE的SSL
properties.put(&mail.smtp.socketFactory.fallback&, &false&); // 只处理SSL的连接,对于非SSL的连接不做处理
properties.put(&mail.smtp.port&, emailInfo.getPort());
properties.put(&mail.smtp.socketFactory.port&,emailInfo.getPort());
Session session = Session.getInstance(properties);
session.setDebug(true);
MimeMessage message = new MimeMessage(session);
Address address = new InternetAddress(emailInfo.getFromUserName());
message.setFrom(address);
Address toAddress = new InternetAddress(emailInfo.getToUser());
message.setRecipient(MimeMessage.RecipientType.TO, toAddress); // 设置收件人,并设置其接收类型为TO
// 主题message.setSubject(changeEncode(emailInfo.getSubject()));
message.setSubject(emailInfo.getSubject());
message.setSentDate(new Date());
Multipart multipart = new MimeMultipart();
// 创建一个包含HTML内容的MimeBodyPart
BodyPart html = new MimeBodyPart();
// 设置HTML内容
html.setContent(emailInfo.getContent(), &text/ charset=utf-8&);
multipart.addBodyPart(html);
// 将MiniMultipart对象设置为邮件内容
message.setContent(multipart);
message.saveChanges();
} catch (Exception e) {
e.printStackTrace();
Transport transport = session.getTransport(&smtp&);
transport.connect(emailInfo.getSmtpServer(), emailInfo.getFromUserName(), emailInfo.getFromUserPassword());
transport.sendMessage(message, message.getAllRecipients());
transport.close();
} catch (Exception e) {
e.printStackTrace();
5,测试一下:public static void main(String[] args) {
EmailUtil util = new EmailUtil();
String content =Global.getConfig(&email_user_add_content&);
content.format(content, &111&,&222&);
System.out.println(content);
EmailInfo info = new EmailInfo(&&, Global.getConfig(&email_user_add_subject&), &&p&这是一个测试邮件&/p&&);
util.sendHtmlMail(info);
}这下就妥妥的了,这些代码运行没有问题,但是用到了其他的一些辅助类,如Global.getConfig()获取配置文件中的信息,用时替换掉就行。应用中配置使用邮箱接收发送邮件,经常会因为各个邮箱配置的细微差异出现错误,多半是认证不通过,而认证不通过的原因无非是:1、服务器错误2、用户名错误3、用户名密码不匹配。遇到错误从这几方面下手就可以了,在代码中使用邮箱发送邮件时要先在客户端试一次,确保邮箱在客户端是可接可收的。这里顺便说一下怎么在outlook客户端添加阿里云邮箱。1,点击文件——》添加账户2,选择配置方式3,填写账户信息:4,点击“其他设置”最后就完成了配置,发送一封邮件测试一下就妥妥的了。
作者:weixin_ 发表于 14:02:13
阅读:48 评论:0
Leetcode c语言-Remove Element
http://blog.csdn.net/hahachenchen789/article/details/
http://blog.csdn.net/hahachenchen789/article/details/
hahachenchen789
Given an array and a value, remove all instances of that value in place and return the new length.
Do not allocate extra space for another array, you must do this in place with constant memory.
The order of elements can be changed. It doesn't matter what you leave beyond the new length.
Given input array&nums&=&[3,2,2,3],&val&=&3
Your function should return length = 2, with the first two elements of&nums&being 2.
这道题非常简单,与上题思路类似,不多赘述。
int removeElement(int* nums, int numsSize, int val) {
int len=0;
for (i=0;i&numsSi++) {
if (nums[i]!=val) {
nums[len]=nums[i];
作者:hahachenchen789 发表于 13:36:32
阅读:37 评论:0
17. Letter Combinations of a Phone Number(根据手机按键求字母的组合)
http://blog.csdn.net/xiangwanpeng/article/details/
http://blog.csdn.net/xiangwanpeng/article/details/
xiangwanpeng
Given a digit string, return all possible letter combinations that the number could represent.A mapping of digit to letters (just like on the telephone buttons) is given below.Input:Digit string &23&
Output: [&ad&, &ae&, &af&, &bd&, &be&, &bf&, &cd&, &ce&, &cf&].
Note:Although the above answer is in lexicographical order, your answer could be in any order you want.题目大意:给定一个由数字构成的字符串,根据如图所示的手机按键中的 数字-&字符串 的关系,求出所有可能字母的组合。例如,给定数字字符串 “23”,因为2在手机按键上对应字符串 “abc”,3在手机按键上对应字符串 “def”,所以输出由9个字符串组成,分别是&&ad&, &ae&, &af&, &bd&, &be&, &bf&, &cd&, &ce&, &cf&。解题思路:采用递归的思想,每次传递的参数分别是:输入的数字字符串digits,记录要返回字符串的集合res,当前遍历到digits的位置pos,当前得到的字符串curCombination。每次根据pos取得digits对应位置的数字,然后根据这个数字去字典里面查找手机按键上对应的字符串,对字符串中的每个字符,添加到curCombination的末尾,并做下一层递归。当pos&=digits.length()时,已经遍历完digits,当前的curCombination就是一个满足条件的字符串,将其添加到res并return。解题代码:(3ms,beats 78.36%)class Solution {
String[] dict = new String[] { &&, &&, &abc&, &def&, &ghi&, &jkl&, &mno&, &pqrs&, &tuv&, &wxyz& };
public void letterCombination(String digits, List&String& res, int pos, String curCombination) {
if (pos &= digits.length()) {
res.add(curCombination);
for (char c : dict[digits.charAt(pos) - '0'].toCharArray()) {
letterCombination(digits, res, pos + 1, curCombination + c);
public List&String& letterCombinations(String digits) {
if (digits == null || digits.length() == 0) {
return Collections.emptyList();
List&String& res = new ArrayList&&();
letterCombination(digits, res, 0, &&);
作者:xiangwanpeng 发表于 11:48:55
阅读:78 评论:0
前端开发中的基础思考题1
http://blog.csdn.net/faremax/article/details/
http://blog.csdn.net/faremax/article/details/
前些日子在忙着面试,拿了心仪的 offer 以后闲下来整理了一些面试相关的基本概念。由于很多关于代码细节的东西之前的博客都有更详细的解释,所以本文涉及代码细节比较少,主要是面试相关的概念,也是前端比较零碎的一些知识。
以下内容包括我面试过程遇到的以及有些仅复习时遇到的内容,有不对的地方欢迎指正。
什么是盒子模型?
在网页中,一个元素占有空间的大小由几个部分构成,其中包括元素的内容(content),元素的内边距(padding),元素的边框(border),元素的外边距(margin)四个部分。这四个部分占有的空间中,有的部分可以显示相应的内容,而有的部分只用来分隔相邻的区域或区域。4个部分一起构成了css中元素的盒模型。
简述一下src与href的区别
href 是指向网络资源所在位置,建立和当前元素(锚点)或当前文档(链接)之间的链接,用于超链接。
src是指向外部资源的位置,指向的内容将会嵌入到文档中当前标签所在位置;在请求src资源时会将其指向的资源下载并应用到文档内,例如js脚本,img图片和frame等元素。当浏览器解析到该元素时,会暂停其他资源的下载和处理,直到将该资源加载、编译、执行完毕,图片和框架等元素也如此,类似于将所指向资源嵌入当前标签内。这也是为什么将js脚本放在底部而不是头部。
简述同步和异步的区别
同步是阻塞模式,异步是非阻塞模式。
同步就是指一个进程在执行某个请求的时候,若该请求需要一段时间才能返回信息,那么这个进程将会一直等待下去,直到收到返回信息才继续执行下去;
异步是指进程不需要一直等下去,而是继续执行下面的操作,不管其他进程的状态。当有消息返回时系统会通知进程进行处理,这样可以提高执行的效率。
怎样添加、移除、移动、复制、创建和查找节点?
创建新节点
createDocumentFragment()
createElement()
createTextNode()
添加、移除、替换、插入
appendChild()
removeChild()
replaceChild()
insertBefore()
getElementsByTagName()
getElementsByName()
getElementById()
一次完整的HTTP事务是怎样的一个过程?
发起TCP的3次握手
建立TCP连接后发起http请求
服务器端响应http请求,浏览器得到html代码
浏览器解析html代码,并请求html代码中的资源
浏览器对页面进行渲染呈现给用户
你所了解到的Web攻击技术,如何防止被攻击?
XSS(Cross-Site Scripting,跨站脚本攻击):指通过存在安全漏洞的Web网站注册用户的浏览器内运行非法的HTML标签或者JavaScript进行的一种攻击。
SQL 注入攻击:通过表单提交可运行的 sql 语句,以破坏数据库数据。
CSRF(Cross-Site Request Forgeries,跨站点请求伪造):指攻击者通过设置好的陷阱,强制对已完成的认证用户进行非预期的个人信息或设定信息等某些状态更新。
dDos 拒绝服务攻击:通过大量请求疯狂占用服务器资源至其瘫痪。
CDN 攻击:使用不合理数据发起请求或请求不合理接口。
身份伪造:冒充服务器或用户获取从另一方获取信息。
输入验证,过滤标签、事件、脚本、SQL
http头: X-XSS-Protection
cookie保护:set-cookie 头加入 http-only
输入验证,过滤标签、事件、脚本、SQL
数据库权限最小化
使用接口而非 SQL 语句
限制文件上传类型
验证 http 头 referer 项
在 http 中加入 taken
隐藏敏感信息
session 定期失效
权限验证、中间件校验
CA 证书校验
dDos 拒绝服务攻击
流量防火墙
对版本控制进行Hash验证
跳转验证(重定向验证)
ajax是什么?ajax的交互模型?
ajax 是异步 javascript
readyState属性状态有5个可取值: 0=未初始化,1=启动 2=发送,3=接收,4=完成
Ajax的特点
通过异步模式,提升了用户体验
优化了浏览器和服务器之间的传输,减少不必要的数据往返,减少了带宽占用
Ajax在客户端运行,承担了一部分本来由服务器承担的工作,减少了大用户量下的服务器负载。
Ajax优点是通过异步通信实现局部刷新
ajax的缺点
ajax不支持浏览器back按钮。
安全问题 AJAX暴露了与服务器交互的细节。
对搜索引擎的支持比较弱。
破坏了程序的异常机制。
不容易调试。
如何解决跨域问题?
有三种行为受到限制:1. Cookie、LocalStorage和IndexDB无法获取;2. DOM无法获得。3. AJAX请求不能发送。
一级域名相同,只是二级域名不同,浏览器允许通过设置 document.domain 共享 cookie 和 DOM
目前有三种方法,可以解决跨域窗口的通信问题:
onhashchange 事件 + #data 片段标识符
监听子窗口 window.name 属性的变化
window.postMessage(data, url), html5 新接口,监听 onmessage 事件
其他方法:代理服务器,JSONP,WebSocket(http origin头),CORS(Access-Control-Allow-Origin)
什么叫优雅降级和渐进增强?
渐进增强(progressive enhancement): 针对低版本浏览器进行构建页面,保证最基本的功能,然后再针对高级浏览器进行效果、交互等改进和追加功能达到更好的用户体验。
优雅降级(graceful degradation): 一开始就构建完整的功能,然后再针对低版本浏览器进行兼容。
优雅降级是从复杂的现状开始,并试图减少用户体验的供给
渐进增强则是从一个非常基础的,能够起作用的版本开始,并不断扩充,以适应未来环境的需要
降级(功能衰减)意味着往回看;而渐进增强则意味着朝前看,同时保证其根基处于安全地带
前端网页制作怎么克服不同分辨率的问题?
根据屏幕不同大小,缩小窗口出横向滚动条在所难免,但理想情况下,页面应该能适应不同客户端浏览器和分辨率。实际操作通常又有三种情况:版面自适应、视觉自适应、内容自适应。
严格模式特点
添加了保留字 protectedstatic 和 interface
在严格模式下不可以用with
在严格模式下变量必须显示声明varletconst
在严格模式下this默认是undefined
在严格模式下为只读变量和不可扩展对象赋值会报错 而不是静默失败
在严格模式下不可以在eval参数中定义变量和函数
在严格模式下有名参数是arguments参数的静态副本而非引用
在严格模式下用delete删除var声明的变量和不可配置属性时抛出异常而不是静默失败返回false
在严格模式下arguments和eval是关键字不能被修改
在严格模式下不可以用8进制
在严格模式下函数的形参不可以同名
在严格模式下不可以使用caller和arguments的属性会报错
在Javascript中什么是伪数组?如何将伪数组转化为标准数组?
伪数组(类数组):无法直接调用数组方法或期望length属性有什么特殊的行为,但仍可以对真正数组遍历方法来遍历它们。它们的本质是对象,其 key 为数字,而存在一个 key 为 ‘length’ 的属性表示其长度。典型的是函数的argument参数、NodeList对象。转换方式有一下几种:
var arr = Array.prototype.slice.call(fakeArray);
var arr = […fakeArray];
var arr = Array.from(fakeArray);
浏览器本地存储
在较高版本的浏览器中,js 提供了 sessionStorage 和 globalStorage。在HTML5中提供了 localStorage 来取代 globalStorage。html5中的Web Storage包括了两种存储方式:sessionStorage 和 localStorage。
cookie 在浏览器和服务器间来回传递。 sessionStorage和localStorage不会
cookie 存储空间很有限(50个 or 4kB),sessionStorage和localStorage的存储空间更大(5M);
sessionStorage和localStorage有更多丰富易用的接口;
sessionStorage和localStorage各自独立的存储空间;
sessionStorage 活到会话结束,而localStorage用于持久化的本地存储,除非主动删除数据,否则数据是永远不会过期的
线程与进程的区别
首先我们需要理解:进程是系统资源分配的最小单位,而线程是程序代码执行的最小单位
一个程序至少有一个进程,一个进程至少有一个线程。线程的划分尺度小于进程,使得多线程程序的并发性高。另外,进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。
从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。但操作系统并没有将多个线程看做多个独立的应用,来实现进程的调度和管理以及资源分配。
请说出三种减少页面加载时间的方法。
压缩js html css和图片,使用 gzip 编码传输,减少传输时间
选择合适的图片格式,合理利用缓存,减少传输时间
合并 js css 及 图片(精灵图),减少请求数量
避免不必要的 repaint 和 reflow, 合理使用 GPU 加速渲染
避免不必要的重定向,使用长连接,优化网络结构
使用 CDN 减短数据传输路径
优化服务器,快速响应与负载均衡
null和undefined的区别?
null是一个表示”无”的对象,转为数值时为0;undefined是一个表示”无”的原始值,转为数值时为NaN。当声明的变量还未被初始化时,变量的默认值为undefined。
null用来表示尚未存在的对象,常用来表示函数企图返回一个不存在的对象。
undefined表示”缺少值”,就是此处应该有一个值,但是还没有定义。典型用法是:
变量被声明了,但没有赋值时,就等于undefined。
调用函数时,应该提供的参数没有提供,该参数等于undefined。
对象没有赋值的属性,该属性的值为undefined。
函数没有返回值时,默认返回undefined。
null表示”没有对象”,即该处不应该有值。典型用法是:
作为函数的参数,表示该函数的参数不是对象。
作为对象原型链的终点。
new操作符具体干了什么呢?
1.创建一个空对象,并将this绑定在该对象;
2.该对象继承构造函数的原型;
3.执行构造函数;
4.如果构造函数返回对象类型,则返回该对象,否则返回第一步新建的对象 this
哪些操作会造成内存泄漏?
内存泄漏指任何对象在您不再拥有或需要它之后仍然存在,无意义的占用内存。
会导致内存泄露的事情:
绑定事件的元素是不能在remove时被清理的,应该在remove之前取消事件绑定。不过更好的办法是用事件委托的方式绑定事件。
意外的全局变量,会使得实际函数结束就应该释放的内存保留下来,造成资源浪费,包括以下两种情况:
定时器中的变量定义,会在每次执行函数的时候重复定义变量,产生严重的内存泄漏。
如果闭包的作用域链中保存着一个DOM对象或者ActiveX对象,那么就意味着该元素将无法被销毁:
通过createElement,createTextNode等方法创建的元素会在写入DOM后被释放
循环引用导致引用计数永远不为0,内存无法释放:
对 Node 的优点和缺点提出了自己的看法?
因为 Node 是基于事件驱动和无阻塞的,所以非常适合处理并发请求,
因此构建在 Node 上的代理服务器相比其他技术实现的服务器表现要好得多。
与 Node 代理服务器交互的客户端代码是由 Javascript 语言编写的,是同一种语言,这是非常美妙的事情。
Node是一个相对新的开源项目,所以不太稳定,它总是一直在变,
而且缺少足够多的第三方库支持。看起来,就像是Ruby/Rails当年的样子。
其实前两个已经好多了,现在呢,就是坑比较多。
你如何对网站的文件和资源进行优化?
文件最小化/文件压缩
使用CDN托管
缓存的使用
一个页面从输入 URL 到页面加载显示完成,这个过程中都发生了什么?
简单来说,分为4个步骤:
当发送一个URL请求时,不管这个URL是Web页面的URL还是Web页面上每个资源的URL,浏览器都会开启一个线程来处理这个请求,同时在远程DNS服务器上启动一个DNS查询。这能使浏览器获得请求对应的IP地址。
浏览器与远程Web服务器通过TCP三次握手协商来建立一个TCP/IP连接。该握手包括一个同步报文,一个同步-应答报文和一个应答报文,这三个报文在 浏览器和服务器之间传递。该握手首先由客户端尝试建立起通信,而后服务器应答并接受客户端的请求,最后由客户端发出该请求已经被接受的报文。
一旦TCP/IP连接建立,浏览器会通过该连接向远程服务器发送HTTP的GET请求。远程服务器找到资源并使用HTTP响应返回该资源,值为200的HTTP响应状态表示一个正确的响应。
此时,Web服务器提供资源服务,客户端开始下载资源。而后由浏览器完成页面渲染
HTTP 常见状态码
继续,一般在发送post请求时,已发送了http header之后服务端将返回此信息,表示确认,之后发送具体参数信息
正常返回信息
请求成功并且服务器创建了新的资源
服务器已接受请求,但尚未处理
Moved Permanently
请求的网页已永久移动到新位置。
临时性重定向。
临时性重定向,且总是使用 GET 请求新的 URI。
Not Modified
自从上次请求后,请求的网页未修改过。
Bad Request
服务器无法理解请求的格式,客户端不应当尝试再次使用相同的内容发起请求。
Unauthorized
请求未授权。
禁止访问。
找不到如何与 URI 相匹配的资源。
Internal Server Error
最常见的服务器端错误。
Service Unavailable
服务器端暂时无法处理请求(可能是过载或维护)。
请解释一下 JavaScript 的同源策略。
同源策略是客户端脚本(尤其是Javascript)的重要的安全度量标准。它最早出自Netscape Navigator2.0,其目的是防止某个文档或脚本从多个不同源装载。这里的同源策略指的是:协议,域名,端口相同,同源策略是一种安全协议。指一段脚本只能读取来自同一来源的窗口和文档的属性。
GET和POST的区别,何时使用POST?
GET:一般用于信息获取,使用URL传递参数,对所发送信息的数量也有限制,一般在2000个字符(不同浏览器有差异,保证可用性,以最小的为主)
POST:一般用于修改服务器上的资源,对所发送的信息没有限制。
GET 方式需要使用 Request.QueryString 来取得变量的值,而 POST 方式通过 Request.Form 来获取变量的值,也就是说 Get 是通过地址栏来传值,而 Post 是通过提交表单来传值。
然而,在以下情况中,请使用 POST 请求:
无法使用缓存文件(更新服务器上的文件或数据库)
向服务器发送大量数据(POST 没有数据量限制)
发送包含未知字符的用户输入时,POST 比 GET 更稳定也更可靠。
数据会重新提交
可藏为书签
无法藏为书签
不可以缓存
application/x-www-from-urlencode
application/x-www-from-urlencode或 multipart/form-data (二进制为多重编码
参数保留在历史记录中
参数不会留在历史记录
URL最长2048个字符(2kB)
数据不可见
XHTML和HTML有什么区别
HTML是一种基本的WEB网页设计语言,XHTML是一个基于XML的置标语言
最主要的不同:
XHTML 元素必须被正确地嵌套。
XHTML 元素必须被关闭。
标签名必须用小写字母。
XHTML 文档必须拥有根元素。
语义化的 HTML 的好处?
直观的认识标签 对于搜索引擎的抓取有好处,用正确的标签做正确的事情!
html语义化就是让页面的内容结构化,便于对浏览器、搜索引擎解析;
在没有样式CSS情况下也以一种文档格式显示,并且是容易阅读的。搜索引擎的爬虫依赖于标记来确定上下文和各个关键字的权重,利于 SEO。
使阅读源代码的人对网站更容易将网站分块,便于阅读维护理解。
常见的浏览器内核有哪些?
Presto(&12.16), Webkit(&12.16)
Carakan(&=10.50)
OdinMonkey(&=22.0)
HTML5有哪些新特性、移除了那些元素?如何处理HTML5新标签的浏览器兼容问题?如何区分 HTML 和HTML5?
HTML5 现在已经不是 SGML 的子集,主要是关于图像,位置,存储,多任务等功能的增加。
绘画 canvas
用于媒介回放的 video 和 audio 元素
本地离线存储 localStorage 长期存储数据,浏览器关闭后数据不丢失;
sessionStorage 的数据在浏览器关闭后自动删除
语意化更好的内容元素,比如 article、footer、header、nav、section
表单控件,calendar、date、time、email、url、search
新的技术webworker, websockt, Geolocation
移除的元素
纯表现的元素:basefont,big,center,font, s,strike,tt,u;
对可用性产生负面影响的元素:frame,frameset,noframes;
处理兼容问题
IE8/IE7/IE6支持通过document.createElement方法产生的标签,可以利用这一特性让这些浏览器支持HTML5新标签,浏览器支持新标签后,还需要添加标签默认的样式。
区分 HTML 和 HTML5
中本质出发,HTML5 既然不是 SGML 的子集,其文档类型声明简单:&!DOCTYPE html&,而 HTML4.01及以下,需要引入 dtd 文件。
在你的日常开发中遇到过哪些常用布局是无法用纯 CSS 实现的?
更好用的 Flex
元素查询(Element Queries)
CSS 分页滚动
非矩形布局
流式 Grid 布局
请描述一下 cookies,sessionStorage 和 localStorage 的区别?
cookie 在浏览器和服务器间来回传递。 sessionStorage和localStorage不会
cookie 存储空间很有限
sessionStorage和localStorage的存储空间更大;
sessionStorage和localStorage有更多丰富易用的接口;
sessionStorage和localStorage各自独立的存储空间;
谈谈This对象的理解。
this 是 js 的一个关键字,随着函数使用场合不同,this 的值会发生变化。
this 默认指的是调用函数的那个对象,如果没有明确指出这个调用对象,就指向全局对象。
this 一般情况下:是全局对象 global。 作为方法调用,那么this就是指这个对象。
函数的 this 可以使用 bind 改变,也可以通过 call, apply 改变调用时的 this 值。
核心点:this 指向谁是函数调用时决定的,而不是函数定义时决定的。
谈一谈JavaScript作用域链
当执行一段JavaScript代码(全局代码或函数)时,JavaScript引擎会创建为其创建一个作用域又称为执行上下文(Execution Context),在页面加载后会首先创建一个全局的作用域,然后每执行一个函数,会建立一个对应的作用域,从而形成了一条作用域链。每个作用域都有一条对应的作用域链,链头是全局作用域,链尾是当前函数作用域。
作用域链的作用是用于解析标识符,当函数被创建时(不是执行),会将this、arguments、命名参数和该函数中的所有局部变量添加到该当前作用域中,当JavaScript需要查找变量X的时候(这个过程称为变量解析),它首先会从作用域链中的链尾也就是当前作用域进行查找是否有X属性,如果没有找到就顺着作用域链继续查找,直到查找到链头,也就是全局作用域链,仍未找到该变量的话,就认为这段代码的作用域链上不存在x变量,并抛出一个引用错误(ReferenceError)的异常。
如何理解JavaScript原型链
JavaScript中的每个对象都有一个prototype属性,我们称之为原型,而原型的值也是一个对象,因此它也有自己的原型,这样就串联起来了一条原型链,原型链的链头是object,它的prototype比较特殊,值为null。
原型链的作用是用于对象继承,函数A的原型属性(prototype property)是一个对象,当这个函数被用作构造函数来创建实例时,该函数的原型属性将被作为原型赋值给所有对象实例,比如我们新建一个数组,数组的方法便从数组的原型上继承而来。
当访问对象的一个属性时, 首先查找对象本身, 找到则返回; 若未找到, 则继续查找其原型对象的属性(如果还找不到实际上还会沿着原型链向上查找, 直至到根). 只要没有被覆盖的话, 对象原型的属性就能在所有的实例中找到,若整个原型链未找到则返回undefined。
对前端工程师这个职位你是怎么样理解的?
前端是最贴近用户的程序员,前端的能力就是能让产品从 90分进化到 100 分,甚至更好
参与项目,快速高质量完成实现效果图,精确到1px;
与团队成员,UI设计,产品经理的沟通;
做好的页面结构,页面重构和用户体验;
处理hack,兼容、写出优美的代码格式;
针对服务器的优化、拥抱最新前端技术。
平时如何管理你的项目?
先期团队必须确定好全局样式(globe.css),编码模式(utf-8) 等;
编写习惯必须一致(例如都是采用继承式的写法,单样式都写成一行);
标注样式编写人,各模块都及时标注(标注关键样式调用的地方);
页面进行标注(例如 页面 模块 开始和结束);
CSS跟HTML 分文件夹并行存放,命名都得统一(例如style.css);
JS 分文件夹存放 命名以该JS功能为准的英文翻译。
图片采用整合的 images.png png8 格式文件使用 尽量整合在一起使用方便将来的管理
JavaScript如何实现继承?
构造继承(call apply)
原型继承(共享)
实例继承(先生成一个实例)
拷贝继承(深拷贝)
清除浮动有哪些方式?比较好的方式是哪一种?
父级div定义height。
结尾处加空div标签clear:both。
父级div定义伪类:after和zoom。
父级div定义overflow:hidden。
父级div定义overflow:auto。
父级div也浮动,需要定义宽度。
父级div定义display:table。
结尾处加br标签clear:both。
比较好的是第3种方式,好多网站都这么用。
box-sizing常用的属性有哪些?分别有什么作用?
(Q1)box-sizing: content-box|border-box|
(Q2)content-box:宽度和高度分别应用到元素的内容框。在宽度和高度之外绘制元素的内边距和边框(元素默认效果)。
border-box:元素指定的任何内边距和边框都将在已设定的宽度和高度内进行绘制。通过从已设定的宽度和高度分别减去边框和内边距才能得到内容的宽度和高度。
Doctype作用?标准模式与兼容模式各有什么区别?
告知浏

我要回帖

更多关于 对数据透视表进行排序 的文章

 

随机推荐