【网络技术】HTTP常见状态码

HTTP状态码(HTTP Status Code)

  一些常见的状态码为:

  1xx(临时响应)表示临时响应并需要请求者继续执行操作的状态代码。代码 说明

  100 (继续) 请求者应当继续提出请求。 服务器返回此代码表示已收到请求的第一部分,正在等待其余部分。

  101 (切换协议) 请求者已要求服务器切换协议,服务器已确认并准备切换。

  2xx (成功)表示成功处理了请求的状态代码。代码 说明

  200 (成功) 服务器已成功处理了请求。 通常,这表示服务器提供了请求的网页。

  201 (已创建) 请求成功并且服务器创建了新的资源。

  202 (已接受) 服务器已接受请求,但尚未处理。

  203 (非授权信息) 服务器已成功处理了请求,但返回的信息可能来自另一来源。

  204 (无内容) 服务器成功处理了请求,但没有返回任何内容。

  205 (重置内容) 服务器成功处理了请求,但没有返回任何内容。

  206 (部分内容) 服务器成功处理了部分 GET 请求。

  3xx (重定向) 表示要完成请求,需要进一步操作。 通常,这些状态代码用来重定向。代码 说明

  300 (多种选择) 针对请求,服务器可执行多种操作。 服务器可根据请求者 (user agent) 选择一项操作,或提供操作列表供请求者选择。

  301 (永久移动) 请求的网页已永久移动到新位置。 服务器返回此响应(对 GET 或 HEAD 请求的响应)时,会自动将请求者转到新位置。

  302 (临时移动) 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。

  303 (查看其他位置) 请求者应当对不同的位置使用单独的 GET 请求来检索响应时,服务器返回此代码。

  304 (未修改) 自从上次请求后,请求的网页未修改过。 服务器返回此响应时,不会返回网页内容。

  305 (使用代理) 请求者只能使用代理访问请求的网页。 如果服务器返回此响应,还表示请求者应使用代理。

  307 (临时重定向) 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。

  4xx(请求错误) 这些状态代码表示请求可能出错,妨碍了服务器的处理。代码 说明

  400 (错误请求) 服务器不理解请求的语法。

  401 (未授权) 请求要求身份验证。 对于需要登录的网页,服务器可能返回此响应。

  403 (禁止) 服务器拒绝请求。

  404 (未找到) 服务器找不到请求的网页。

  405 (方法禁用) 禁用请求中指定的方法。

  406 (不接受) 无法使用请求的内容特性响应请求的网页。

  407 (需要代理授权) 此状态代码与 401(未授权)类似,但指定请求者应当授权使用代理。

  408 (请求超时) 服务器等候请求时发生超时。

  409 (冲突) 服务器在完成请求时发生冲突。 服务器必须在响应中包含有关冲突的信息。

  410 (已删除) 如果请求的资源已永久删除,服务器就会返回此响应。

  411 (需要有效长度) 服务器不接受不含有效内容长度标头字段的请求。

  412 (未满足前提条件) 服务器未满足请求者在请求中设置的其中一个前提条件。

  413 (请求实体过大) 服务器无法处理请求,因为请求实体过大,超出服务器的处理能力。

  414 (请求的 URI 过长) 请求的 URI(通常为网址)过长,服务器无法处理。

  415 (不支持的媒体类型) 请求的格式不受请求页面的支持。

  416 (请求范围不符合要求) 如果页面无法提供请求的范围,则服务器会返回此状态代码。

  417 (未满足期望值) 服务器未满足"期望"请求标头字段的要求。

  5xx(服务器错误)这些状态代码表示服务器在尝试处理请求时发生内部错误。 这些错误可能是服务器本身的错误,而不是请求出错。代码 说明

  500 (服务器内部错误) 服务器遇到错误,无法完成请求。

  501 (尚未实施) 服务器不具备完成请求的功能。 例如,服务器无法识别请求方法时可能会返回此代码。

  502 (错误网关) 服务器作为网关或代理,从上游服务器收到无效响应。

  503 (服务不可用) 服务器目前无法使用(由于超载或停机维护)。 通常,这只是暂时状态。

  504 (网关超时) 服务器作为网关或代理,但是没有及时从上游服务器收到请求。

  505 (HTTP 版本不受支持) 服务器不支持请求中所用的 HTTP 协议版本。

发表在 网络技术 | 标签为 | 留下评论

【Linux】Ubuntu系统服务器下增加crontab定时任务实现定时重启

在Linux系统下完成定时计划任务,可以使用at或者crontab命令。其中,at命令主要针对只执行一次的需求场景,crontab则可以完成重复的定时任务。具体的使用说明可以参见:http://www.jb51.net/LINUXjishu/19905.html

在本例当中,因为需求,希望每天晚上12点能让服务器自动重启一下,所以进行了设置,主要步骤如下:

1、查看cron服务状态

service cron status

2、增加任务

crontab -e 或者直接修改文件vim /etc/crontab

增加如下一行

0 0 * * * root /data/reboot.sh

3、编写执行脚本reboot.sh

#!/bin/bash

date >> /data/reboot_log.txt

reboot

4、修改脚本reboot.sh权限,使脚本可执行

chmod 777 reboot.sh

chmod u+x reboot.sh

5、新建重启日志文件

vim /data/reboot_log.txt

6、重启cron服务

service cron restart

经过上述配置之后,服务器在每天的0点0分就会执行/data/reboot.sh脚本,将当前时间输入到重启日志/data/reboot_log.txt,然后执行reboot进行重启。

另外,需将cron服务设置为开机启动,这样重启之后才能继续实现下一次重启,否则每次重启之后需要手动开启cron服务,service cron start。在我使用的Ubuntu系统服务器中,cron服务为默认开机启动的。

发表在 Linux技术 | 标签为 , | 留下评论

【设计模式】设计模式漫谈之模板方法模式和单例模式实现的三种方法

一、模板方法模式(Template Method)


【模板方法】定义在一个操作中的一个算法框架,把一些步骤推迟到子类去实现。模板方法模式让子类不需要改变算法结构而重新定义特定的算法步骤。

父类可以把不允许改变的方法设置为final 或者 private。

【回调】表示一段可执行逻辑的引用,我们把该引用传递到另外一段逻辑里,供这段逻辑适时调用。

DRY:Don't Repeat Yourself

OAOO:Once And Only Once


二、单例模式(Singleton)

【单例模式】

1.普通方法(线程安全)

类的构造方法为private;获取类实例的方法为public static 

public class Singleton{
private static Singleton instance = new Singleton()
private Singleton(){...}
public static Singleton getInstance(){
return instance;
}
}

使用:Singleton singleton = Singleton.getInstance();

JVM加载类时,对于static属性的初始化只能由一个线程执行且仅一次

2.延迟创建:把单例的实例化过程移到getInstance

public class ThreadSafeSingleton{
public static synchronized ThreadSafeSingleton getInstance(){
if(instance == null){
instance = new ThreadSafeSingleton();
}
return instance;
}
}

为了线程安全,需要加上synchronized。

3.Double-Check locking

public class DoubleCheckSingleton{
private volatile static DoubleCheckSingleton instance = null;
public static DoubleCheckSingleton getInstance(){
if(instance == null){
synchronized(DoubleCheckSingleton.class){
if(instance == null)
instance = new DoubleCheckSingleton();
}
}
return instance;
}
}

 这里instance是用volatile修饰,因为volatile具有synchronized的可见性,即线程能够自动发现volatile变量的最新值。这样,如果instance实例化成功,其他线程便能发现。

4.Initialization on demand holder模式:线程安全的延迟加载方法

public class LazyLoadedSingleton{
private LazyLoadedSingleton(){}
public static class LazyHolder(){
public static final LazyLoadedSingleton singletonInstance = new LazyLoadedSingleton();
}
public static LazyLoadedSingleton getInstance(){
return LazyHolder.singletonInstance;
}
}

只有第一次调用getInstance方法的时候,JVM才会加载LazyHolder类,然后初始化static属性的singletonInstance这个变量。

发表在 设计模式 | 留下评论

【设计模式】简述策略模式、观察者模式、装饰者模式、工厂方法模式

一、策略模式:

定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。

专门提供某行为接口的实现。

“有一个”比“是一个”好


二、观察者模式

定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会受到通知并自动更新。

JavaBean和Swing中都用到了观察者模式。GUI框架、RMI

Java的内置观察者模式:

    被观察者要extends继承 java.util.Observable类,用到registerOberver(Oberver o) ; setChanged()和 notifyObservers() 或 notifyObservers(Object arg)


private ArrayList observers;

public void registerOberver(Oberver o){

     observers.add(o);

}

public void removeObserver(Oberver o){

 int i = observers.indexOf(o);

 if(i >= 0){

  observers.remove(i);

 }

}

public notifyObservers(){

 for (int i=0;i<observers.size() ;i++ ) {

  Oberver observer = (Oberver)observers.get(i);

  observer.update(data1,data2);

 }

}

    观察者要implements java.util.Observer 接口,用到 update(Observable o,Object arg);


三、装饰者模式

动态地将责任附加到对象上,若要扩展功能,装饰者提供了比继承更有弹性的替代方案。

Java IO

组合和委托可以在运行时动态地加上新的行为。

装饰者反映出被装饰的组件类型(二者具有相同的类型,都经过接口或继承实现)


四、

工厂方法模式:定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个,工厂方法让类把实

例化推迟到子类。

简单工厂:工厂处理创建对象的细节。

抽象工厂模式:提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。

        工厂方法是抽象的,依赖继承它的子类来处理对象的创建。创建一系列产品

发表在 设计模式 | 标签为 | 留下评论

【设计模式】设计模式的原则

  • 找出应用中可能需要变化之处,独立出来

  • 针对接口编程,而不是针对实现编程

  • 多用组合,少用继承

  • 松耦合,高内聚

  • 对扩展开放,对修改封闭

  • 依赖倒置原则(工厂方法):在工厂方法里,高层组件抽象工厂类依赖抽象产品类,而低层组件的具体产品类也依赖抽象产品类。

  • 要依赖抽象,而不要依赖具体类原则:不能让高层组件依赖低层组件。而且二者都应该依赖于抽象。

  • 控制反转(模板方法):我们经常把控制逻辑写在其他地方(如Framework)而非客户化的代码里,这样就可以更加专注于客户化的逻辑。也就是由外部逻辑负责调用客户化的逻辑。

  • 依赖注入:外部程序把服务对象通过某种方式注入到客户对象供其使用的方法称为依赖注入。

发表在 设计模式 | 标签为 , | 留下评论

【Android】一个通过组播实现的局域网服务器搜索功能

服务器端代码:

package com.isunhui.multicast;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.NetworkInterface;

public class Main {
	public static void main(String[] args){
		try{
			MulticastSocket ms = new  MulticastSocket(10000);//生成套接字并绑定端口
			InetAddress group = InetAddress.getByName("224.0.0.1");//设定多播IP
			ms.setNetworkInterface(NetworkInterface.getByInetAddress(group.getLocalHost()));
			ms.joinGroup(group);//接受者加入多播组,需要和发送者在同一组
			byte[] buf = new byte[100];
			DatagramPacket packet = new DatagramPacket(buf , buf.length);//创建接收报文,以接收通过广播传递过来的
			while(true){
				ms.receive(packet);//接收报文,程序停滞等待直到接收到报文
				System.out.println("receive:"+new String(packet.getData()));
				System.out.println("from "+packet.getAddress().getHostAddress());

				DatagramSocket ds = new DatagramSocket(); 
				byte[] buf2 = "server address".getBytes("utf-8");
				DatagramPacket packet2=new DatagramPacket(buf2,buf2.length,packet.getAddress(),10001);
				ds.send(packet2);//发送报文
				ds.close();
			}
		}catch(Exception e){
			System.out.println(e.toString());
		}
	}
}

手机端代码:

package com.isunhui.multicast;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.NetworkInterface;
import java.util.ArrayList;
import java.util.Enumeration;

import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;


public class MainActivity extends ActionBarActivity {
	private Button send;
    private TextView serverIP;
    private TextView localIP;
    private ArrayList<InetAddress> ipList;
    private Handler handler;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        serverIP = (TextView)findViewById(R.id.serverIP);
        localIP = (TextView)findViewById(R.id.localIP);
        send = (Button)findViewById(R.id.send);
        ipList = new ArrayList<InetAddress>();
        handler = new Handler();
        
        try
        {
            for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();)
            {
                NetworkInterface intf = en.nextElement();
                for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();)
                {
                    InetAddress inetAddress = enumIpAddr.nextElement();
                    if (!inetAddress.isLoopbackAddress())
                    {
                        ipList.add(inetAddress);
                    }
                }
            }
        }
        catch (Exception e)
        {
            Log.e("getIP", e.toString());
        }
        localIP.setText("本地IP:"+ipList.get(1).getHostAddress().toString());

        final Runnable runnable = new Runnable() {
            @Override
            public void run() {
                try{
                    MulticastSocket msSocket = new MulticastSocket();//生成套接字并绑定30001端口
                    InetAddress group=InetAddress.getByName("224.0.0.1");//设定多播IP
                    byte[] buff = "search server".getBytes("utf-8");//设定多播报文的数据
                    msSocket.joinGroup(group);//加入多播组,发送方和接受方处于同一组时,接收方可抓取多播报文信息
                    msSocket.setTimeToLive(4);//设定TTL
//设定UDP报文(内容,内容长度,多播组,端口)
                    DatagramPacket packet = new DatagramPacket(buff,buff.length,group,10000);
                    msSocket.send(packet);//发送报文
                    msSocket.close();//关闭套接字
                    
                    DatagramSocket ds = new DatagramSocket(10001);
                    byte[] buf2 = new byte[100];
                    DatagramPacket packet2 = new DatagramPacket(buf2,buf2.length);
                    ds.receive(packet2);
                    ds.close();
                    final String serverIP_str=packet2.getAddress().getHostAddress();
                    handler.post(new Runnable(){
						@Override
						public void run() {
							// TODO Auto-generated method stub
							serverIP.setText("服务器IP:"+serverIP_str);
						}                    
                    });
                }catch (Exception e){
                    Log.e("sendMulticast",e.toString());
                }
            }
        };

        send.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new Thread(runnable).start();
            }
        });
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}

发表在 Android技术 | 标签为 , , | 留下评论

【PM学习笔记】工具网站及社区

思维导图:https://www.mindmeister.com/

项目管理:https://trello.com/

      https://basecamp.com/

网站分析:https://www.google.com/analytics/

      http://yslow.org/

网站监测:http://www.jiankongbao.com/

网站优化:https://www.google.cn/websiteoptimizer

站长工具:http://tool.chinaz.com/

广告投放:https://www.google.com/adsense/start/

      http://union.baidu.com/

      http://pub.alimama.com/

产品经理社区

要有光:http://www.yaoyouguang.com/

常用工具:

ps,ai,axure

发表在 PM学习笔记 | 留下评论

【Android】开发工具adt-bundle下载链接

目前,google官方只提供Android Studio的下载了,不再提供adt-bundle的下载,仍想要使用Eclipse+ADT的方式进行Android开发,可以使用下面的链接下载adt-bundle:

win32: https://dl.google.com/android/adt/adt-bundle-windows-x86-20140702.zip 

win64: https://dl.google.com/android/adt/adt-bundle-windows-x86_64-20140702.zip

发表在 Android技术 | 标签为 , | 留下评论

【数据结构与算法】之递归算法:汉诺塔问题

当一个问题规模较大且不易求解的时候,考虑将问题分成几个小额模块,逐一解决:折半查找法。

  • 汉诺塔问题:

三根针,X,Y,Z,X针从下到上穿好了由大到小的64片金片——汉诺塔。按照这个法则移动金片:一次只移动一片,不管在哪根针上,小片必须在大片上面。最终将X上的塔移动到Z上

S1:将X上63个金片借助Z移动到Y上——>再细分步骤

S2:将X上第64个金片移动到Z上

S3:将Y上63个金片借助X移动到Z上——再细分步骤

#include <stdio.h>
//将n个盘子从x借助y移动到z上
void move(int n,char x,char y,char z){
 if(1 == n) {
  printf("%c-->%c\n",x,z );
 }else{
  move(n-1,x,z,y);	//将n-1个盘子从x借助z移动到y上
  printf("%c-->%c\n",x,z);	//将第n个盘子从x移动到z上
  move(n-1,y,x,z);	//将n-1个盘子从y借助x移动到z上
 }   
}
int int main(int argc, char const *argv[])
{
 int n;
 printf("请输入汉诺塔的层数");
 scanf("%d" ,&n);
 printf("移动步骤如下:\n");
 move(n,'x','y','z');
 return 0;
}

发表在 数据结构与算法 | 标签为 , | 留下评论

【数据结构】之栈

  1. 后进先出

  2. 只能在线性表的表尾进行插入和删除的操作。表尾即栈顶。

  3. 栈包含的元素:base、top、stackSize

  4. top指向栈顶,是空的,待插入的地方,插完之后记得++。如果是删除操作,需要将top先下移一位。

  5. 清空一个栈:只要将栈顶的内容赋值为栈底的内容即可

  6. 指针只能相减,不能相加。相减的结果是元素的个数(比如N个整型,即自动识别类型)

发表在 数据结构与算法 | 标签为 | 留下评论