Countly在andoid和vps集成使用,开源的统计分析sdk
这几天项目需要,简单研究了一下countly,说实话完全满足项目需要,比umeng这类产品干净多了。
Countly Mobile Analytics
下面就讲一下android 集成的过程,以及 服务器端报表部分的使用。
1、android 集成。
下载完后,一个工程4个文件,很整洁,赞一个。
这个工程,运行之前把libary去掉勾选,默认这个工程被设置成一个库了。
然后,直接打开CounlyActivity.java这个文件,
Countly.sharedInstance().init(this,你的服务器地址,你的app_key);
上面的你的服务器地址和你的app_key都是先要安装好服务端的程序才能设置的。
下面讲一下服务器端程序的安装和使用。
1、下载完程序后,直接进入bin目录执行sh counly.install.sh ,等5分钟自动全部安装完毕,这方便多了,发现采用node.js代码写的,效率就有些打折扣了。
、
对了,我的系统是unbuntu server.
2、它会给你自动装上nginx ,如果你服务器上已经安装apache了,会提示你80端口被占,这个需要你去设置以下nginx.conf里的listen port,随便改个端口就行了
3、服务器网站访问成功后,就在 “管理”-“应用”里添加一个新的应用:
应用密钥就是在android里需要的app_key。
这样子就连通了。
下面简单讲一下会出现的问题:
10-12 15:00:52.570: E/SQLiteDatabase(15701): close() was never explicitly called on database '/data/data/ly.count.android.api/databases/countly'
如果你发现出现这个异常,基本上就是CountlyDB的全部操作没有执行db.close()方法,然后在activiy的stop方法也没有关闭sqlite 数据库导致的,下面就是我简单修改的CountlyDB.java
- package ly.count.android.api;
- import java.io.InputStream;
- import java.io.UnsupportedEncodingException;
- import java.net.URI;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.Iterator;
- import java.util.Locale;
- import java.util.Map;
- import java.util.Timer;
- import java.util.TimerTask;
- import org.OpenUDID.OpenUDID_manager;
- import org.apache.http.HttpResponse;
- import org.apache.http.client.methods.HttpGet;
- import org.apache.http.impl.client.DefaultHttpClient;
- import org.json.JSONArray;
- import org.json.JSONException;
- import org.json.JSONObject;
- import android.content.Context;
- import android.content.pm.PackageManager.NameNotFoundException;
- import android.database.Cursor;
- import android.database.sqlite.SQLiteDatabase;
- import android.database.sqlite.SQLiteOpenHelper;
- import android.telephony.TelephonyManager;
- import android.util.DisplayMetrics;
- import android.util.Log;
- import android.view.Display;
- import android.view.WindowManager;
- public class Countly {
- private static Countly sharedInstance_;
- private Timer timer_;
- private ConnectionQueue queue_;
- private EventQueue eventQueue_;
- private boolean isVisible_;
- private double unsentSessionLength_;
- private double lastTime_;
- private int activityCount_;
- private CountlyDB countlyDB_;
- static public Countly sharedInstance() {
- if (sharedInstance_ == null)
- sharedInstance_ = new Countly();
- return sharedInstance_;
- }
- private Countly() {
- queue_ = new ConnectionQueue();
- timer_ = new Timer();
- timer_.schedule(new TimerTask() {
- @Override
- public void run() {
- onTimer();
- }
- }, 60 * 1000, 60 * 1000);
- isVisible_ = false;
- unsentSessionLength_ = 0;
- activityCount_ = 0;
- }
- public void init(Context context, String serverURL, String appKey) {
- OpenUDID_manager.sync(context);
- countlyDB_ = new CountlyDB(context);
- queue_.setContext(context);
- queue_.setServerURL(serverURL);
- queue_.setAppKey(appKey);
- queue_.setCountlyDB(countlyDB_);
- eventQueue_ = new EventQueue(countlyDB_);
- }
- public void onStart() {
- activityCount_++;
- if (activityCount_ == 1)
- onStartHelper();
- }
- public void onStop() {
- activityCount_--;
- if (activityCount_ == 0)
- onStopHelper();
- if(countlyDB_!=null){
- countlyDB_.close();
- }
- }
- public void onStartHelper() {
- lastTime_ = System.currentTimeMillis() / 1000.0;
- queue_.beginSession();
- isVisible_ = true;
- }
- public void onStopHelper() {
- if (eventQueue_.size() > 0)
- queue_.recordEvents(eventQueue_.events());
- double currTime = System.currentTimeMillis() / 1000.0;
- unsentSessionLength_ += currTime - lastTime_;
- int duration = (int) unsentSessionLength_;
- queue_.endSession(duration);
- unsentSessionLength_ -= duration;
- isVisible_ = false;
- }
- public void recordEvent(String key, int count) {
- eventQueue_.recordEvent(key, count);
- if (eventQueue_.size() >= 10)
- queue_.recordEvents(eventQueue_.events());
- }
- public void recordEvent(String key, int count, double sum) {
- eventQueue_.recordEvent(key, count, sum);
- if (eventQueue_.size() >= 10)
- queue_.recordEvents(eventQueue_.events());
- }
- public void recordEvent(String key, Map<String, String> segmentation, int count) {
- eventQueue_.recordEvent(key, segmentation, count);
- if (eventQueue_.size() >= 10)
- queue_.recordEvents(eventQueue_.events());
- }
- public void recordEvent(String key, Map<String, String> segmentation, int count, double sum) {
- eventQueue_.recordEvent(key, segmentation, count, sum);
- if (eventQueue_.size() >= 10)
- queue_.recordEvents(eventQueue_.events());
- }
- private void onTimer() {
- if (isVisible_ == false)
- return;
- double currTime = System.currentTimeMillis() / 1000.0;
- unsentSessionLength_ += currTime - lastTime_;
- lastTime_ = currTime;
- int duration = (int) unsentSessionLength_;
- queue_.updateSession(duration);
- unsentSessionLength_ -= duration;
- if (eventQueue_.size() > 0)
- queue_.recordEvents(eventQueue_.events());
- }
- }
- class ConnectionQueue {
- private CountlyDB queue_;
- private Thread thread_ = null;
- private String appKey_;
- private Context context_;
- private String serverURL_;
- public void setAppKey(String appKey) {
- appKey_ = appKey;
- }
- public void setContext(Context context) {
- context_ = context;
- }
- public void setServerURL(String serverURL) {
- serverURL_ = serverURL;
- }
- public void setCountlyDB(CountlyDB countlyDB) {
- queue_ = countlyDB;
- }
- public void beginSession() {
- String data;
- data = "app_key=" + appKey_;
- data += "&" + "device_id=" + DeviceInfo.getUDID();
- data += "&" + "timestamp=" + (long) (System.currentTimeMillis() / 1000.0);
- data += "&" + "sdk_version=" + "2.0";
- data += "&" + "begin_session=" + "1";
- data += "&" + "metrics=" + DeviceInfo.getMetrics(context_);
- queue_.offer(data);
- tick();
- }
- public void updateSession(int duration) {
- String data;
- data = "app_key=" + appKey_;
- data += "&" + "device_id=" + DeviceInfo.getUDID();
- data += "&" + "timestamp=" + (long) (System.currentTimeMillis() / 1000.0);
- data += "&" + "session_duration=" + duration;
- queue_.offer(data);
- tick();
- }
- public void endSession(int duration) {
- String data;
- data = "app_key=" + appKey_;
- data += "&" + "device_id=" + DeviceInfo.getUDID();
- data += "&" + "timestamp=" + (long) (System.currentTimeMillis() / 1000.0);
- data += "&" + "end_session=" + "1";
- data += "&" + "session_duration=" + duration;
- queue_.offer(data);
- tick();
- }
- public void recordEvents(String events) {
- String data;
- data = "app_key=" + appKey_;
- data += "&" + "device_id=" + DeviceInfo.getUDID();
- data += "&" + "timestamp=" + (long) (System.currentTimeMillis() / 1000.0);
- data += "&" + "events=" + events;
- queue_.offer(data);
- tick();
- }
- private void tick() {
- if (thread_ != null && thread_.isAlive())
- return;
- if (queue_.isEmpty())
- return;
- thread_ = new Thread() {
- @Override
- public void run() {
- while (true) {
- String data = queue_.peek();
- if (data == null)
- break;
- int index = data.indexOf("REPLACE_UDID");
- if (index != -1) {
- if (OpenUDID_manager.isInitialized() == false)
- break;
- data = data.replaceFirst("REPLACE_UDID", OpenUDID_manager.getOpenUDID());
- }
- try {
- DefaultHttpClient httpClient = new DefaultHttpClient();
- HttpGet method = new HttpGet(new URI(serverURL_ + "/i?" + data));
- HttpResponse response = httpClient.execute(method);
- InputStream input = response.getEntity().getContent();
- while (input.read() != -1)
- ;
- httpClient.getConnectionManager().shutdown();
- Log.d("Countly", "ok ->" + data);
- queue_.poll();
- } catch (Exception e) {
- Log.d("Countly", e.toString());
- Log.d("Countly", "error ->" + data);
- break;
- }
- }
- }
- };
- thread_.start();
- }
- }
- class DeviceInfo {
- public static String getUDID() {
- return OpenUDID_manager.isInitialized() == false ? "REPLACE_UDID" : OpenUDID_manager.getOpenUDID();
- }
- public static String getOS() {
- return "Android";
- }
- public static String getOSVersion() {
- return android.os.Build.VERSION.RELEASE;
- }
- public static String getDevice() {
- return android.os.Build.MODEL;
- }
- public static String getResolution(Context context) {
- WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
- Display display = wm.getDefaultDisplay();
- DisplayMetrics metrics = new DisplayMetrics();
- display.getMetrics(metrics);
- return metrics.widthPixels + "x" + metrics.heightPixels;
- }
- public static String getCarrier(Context context) {
- TelephonyManager manager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
- return manager.getNetworkOperatorName();
- }
- public static String getLocale() {
- Locale locale = Locale.getDefault();
- return locale.getLanguage() + "_" + locale.getCountry();
- }
- public static String appVersion(Context context) {
- String result = "1.0";
- try {
- result = context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionName;
- } catch (NameNotFoundException e) {
- }
- return result;
- }
- public static String getMetrics(Context context) {
- String result = "";
- JSONObject json = new JSONObject();
- try {
- json.put("_device", getDevice());
- json.put("_os", getOS());
- json.put("_os_version", getOSVersion());
- json.put("_carrier", getCarrier(context));
- json.put("_resolution", getResolution(context));
- json.put("_locale", getLocale());
- json.put("_app_version", appVersion(context));
- } catch (JSONException e) {
- e.printStackTrace();
- }
- result = json.toString();
- try {
- result = java.net.URLEncoder.encode(result, "UTF-8");
- } catch (UnsupportedEncodingException e) {
- }
- return result;
- }
- }
- class Event {
- public String key = null;
- public Map<String, String> segmentation = null;
- public int count = 0;
- public double sum = 0;
- public int timestamp = 0;
- }
- class EventQueue {
- private ArrayList<Event> events_;
- private CountlyDB countlyDB_;
- public EventQueue(CountlyDB countlyDB) {
- countlyDB_ = countlyDB;
- events_ = countlyDB_.getEvents();
- }
- public int size() {
- synchronized (this) {
- return events_.size();
- }
- }
- public String events() {
- String result = "";
- synchronized (this) {
- JSONArray eventArray = new JSONArray();
- for (int i = 0; i < events_.size(); ++i) {
- JSONObject json = new JSONObject();
- Event currEvent = events_.get(i);
- try {
- json.put("key", currEvent.key);
- json.put("count", currEvent.count);
- json.put("sum", currEvent.sum);
- json.put("timestamp", currEvent.timestamp);
- if (currEvent.segmentation != null) {
- json.put("segmentation", new JSONObject(currEvent.segmentation));
- }
- } catch (JSONException e) {
- e.printStackTrace();
- }
- eventArray.put(json);
- }
- result = eventArray.toString();
- events_.clear();
- countlyDB_.clearEvents();
- }
- try {
- result = java.net.URLEncoder.encode(result, "UTF-8");
- } catch (UnsupportedEncodingException e) {
- }
- return result;
- }
- public void recordEvent(String key, int count) {
- synchronized (this) {
- for (int i = 0; i < events_.size(); ++i) {
- Event event = events_.get(i);
- if (event.key.equals(key)) {
- event.count += count;
- event.timestamp = Math.round((event.timestamp + (System.currentTimeMillis() / 1000)) / 2);
- countlyDB_.saveEvents(events_);
- return;
- }
- }
- Event event = new Event();
- event.key = key;
- event.count = count;
- event.timestamp = Math.round(System.currentTimeMillis() / 1000);
- events_.add(event);
- countlyDB_.saveEvents(events_);
- }
- }
- public void recordEvent(String key, int count, double sum) {
- synchronized (this) {
- for (int i = 0; i < events_.size(); ++i) {
- Event event = events_.get(i);
- if (event.key.equals(key)) {
- event.count += count;
- event.sum += sum;
- event.timestamp = Math.round((event.timestamp + (System.currentTimeMillis() / 1000)) / 2);
- countlyDB_.saveEvents(events_);
- return;
- }
- }
- Event event = new Event();
- event.key = key;
- event.count = count;
- event.sum = sum;
- event.timestamp = Math.round(System.currentTimeMillis() / 1000);
- events_.add(event);
- countlyDB_.saveEvents(events_);
- }
- }
- public void recordEvent(String key, Map<String, String> segmentation, int count) {
- synchronized (this) {
- for (int i = 0; i < events_.size(); ++i) {
- Event event = events_.get(i);
- if (event.key.equals(key) && event.segmentation != null && event.segmentation.equals(segmentation)) {
- event.count += count;
- event.timestamp = Math.round((event.timestamp + (System.currentTimeMillis() / 1000)) / 2);
- countlyDB_.saveEvents(events_);
- return;
- }
- }
- Event event = new Event();
- event.key = key;
- event.segmentation = segmentation;
- event.count = count;
- event.timestamp = Math.round(System.currentTimeMillis() / 1000);
- events_.add(event);
- countlyDB_.saveEvents(events_);
- }
- }
- public void recordEvent(String key, Map<String, String> segmentation, int count, double sum) {
- synchronized (this) {
- for (int i = 0; i < events_.size(); ++i) {
- Event event = events_.get(i);
- if (event.key.equals(key) && event.segmentation != null && event.segmentation.equals(segmentation)) {
- event.count += count;
- event.sum += sum;
- event.timestamp = Math.round((event.timestamp + (System.currentTimeMillis() / 1000)) / 2);
- countlyDB_.saveEvents(events_);
- return;
- }
- }
- Event event = new Event();
- event.key = key;
- event.segmentation = segmentation;
- event.count = count;
- event.sum = sum;
- event.timestamp = Math.round(System.currentTimeMillis() / 1000);
- events_.add(event);
- countlyDB_.saveEvents(events_);
- }
- }
- }
- class CountlyDB extends SQLiteOpenHelper {
- private static final int DATABASE_VERSION = 1;
- private static final String DATABASE_NAME = "countly";
- private static final String CONNECTIONS_TABLE_NAME = "CONNECTIONS";
- private static final String EVENTS_TABLE_NAME = "EVENTS";
- private static final String CONNECTIONS_TABLE_CREATE = "CREATE TABLE " + CONNECTIONS_TABLE_NAME + " (ID INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, CONNECTION TEXT NOT NULL);";
- private static final String EVENTS_TABLE_CREATE = "CREATE TABLE " + EVENTS_TABLE_NAME + " (ID INTEGER UNIQUE NOT NULL, EVENT TEXT NOT NULL);";
- CountlyDB(Context context) {
- super(context, DATABASE_NAME, null, DATABASE_VERSION);
- }
- @Override
- public void onCreate(SQLiteDatabase db) {
- db.execSQL(CONNECTIONS_TABLE_CREATE);
- db.execSQL(EVENTS_TABLE_CREATE);
- }
- @Override
- public void onUpgrade(SQLiteDatabase db, int arg1, int arg2) {
- }
- public String peek() {
- synchronized (this) {
- SQLiteDatabase db = this.getReadableDatabase();
- Cursor cursor = db.query(CONNECTIONS_TABLE_NAME, null, null, null, null, null, "ID DESC", "1");
- String connection = null;
- if (cursor != null && cursor.getCount() > 0) {
- cursor.moveToFirst();
- connection = cursor.getString(1);
- Log.d("Countly", "Fetched: " + connection);
- }
- db.close();
- return connection;
- }
- }
- public String poll() {
- synchronized (this) {
- SQLiteDatabase db = this.getReadableDatabase();
- Cursor cursor = db.query(CONNECTIONS_TABLE_NAME, null, null, null, null, null, "ID DESC", "1");
- String connection = null;
- if (cursor != null && cursor.getCount() > 0) {
- cursor.moveToFirst();
- connection = cursor.getString(1);
- int rawId = Integer.parseInt(cursor.getString(0));
- SQLiteDatabase writeDb = this.getWritableDatabase();
- writeDb.execSQL("DELETE FROM " + CONNECTIONS_TABLE_NAME + " WHERE ID = " + rawId + ";");
- Log.d("Countly", "Fetched and deleted: " + connection);
- }
- db.close();
- return connection;
- }
- }
- public void offer(String data) {
- SQLiteDatabase db = this.getWritableDatabase();
- db.execSQL("INSERT INTO " + CONNECTIONS_TABLE_NAME + "(CONNECTION) VALUES('" + data + "');");
- Log.d("Countly", "Insert into " + CONNECTIONS_TABLE_NAME + ": " + data);
- db.close();
- }
- public boolean isEmpty() {
- SQLiteDatabase db = this.getReadableDatabase();
- Cursor cursor = db.query(CONNECTIONS_TABLE_NAME, null, null, null, null, null, "ID DESC", "1");
- boolean rtn= !(cursor != null && cursor.getCount() > 0);
- db.close();
- return rtn;
- }
- // Event related functions
- public ArrayList<Event> getEvents() {
- SQLiteDatabase db = this.getReadableDatabase();
- Cursor cursor = db.query(EVENTS_TABLE_NAME, null, null, null, null, null, "ID = 1", "1");
- ArrayList<Event> eventsArray = new ArrayList<Event>();
- if (cursor != null && cursor.getCount() > 0) {
- cursor.moveToFirst();
- String events = cursor.getString(1);
- JSONObject json = new JSONObject();
- try {
- json = new JSONObject(events);
- } catch (JSONException e) {
- e.printStackTrace();
- }
- JSONArray jArray = json.optJSONArray("events");
- if (jArray != null) {
- for (int i = 0; i < jArray.length(); i++) {
- try {
- eventsArray.add(jsonToEvent(new JSONObject(jArray.get(i).toString())));
- } catch (JSONException e) {
- e.printStackTrace();
- }
- }
- }
- }
- db.close();
- return eventsArray;
- }
- public void saveEvents(ArrayList<Event> events) {
- JSONArray eventArray = new JSONArray();
- JSONObject json = new JSONObject();
- for (int i = 0; i < events.size(); ++i) {
- eventArray.put(eventToJSON(events.get(i)));
- }
- try {
- json.put("events", eventArray);
- } catch (JSONException e) {
- e.printStackTrace();
- }
- SQLiteDatabase db = this.getWritableDatabase();
- db.execSQL("INSERT OR REPLACE INTO " + EVENTS_TABLE_NAME + "(ID, EVENT) VALUES(1, '" + json.toString() + "');");
- db.close();
- }
- public void clearEvents() {
- SQLiteDatabase writeDb = this.getWritableDatabase();
- writeDb.execSQL("DELETE FROM " + EVENTS_TABLE_NAME + ";");
- writeDb.close();
- }
- private JSONObject eventToJSON(Event event) {
- JSONObject json = new JSONObject();
- try {
- json.put("key", event.key);
- json.put("count", event.count);
- json.put("sum", event.sum);
- json.put("timestamp", event.timestamp);
- if (event.segmentation != null) {
- json.put("segmentation", new JSONObject(event.segmentation));
- }
- } catch (JSONException e) {
- e.printStackTrace();
- }
- return json;
- }
- private Event jsonToEvent(JSONObject json) {
- Event event = new Event();
- try {
- event.key = json.get("key").toString();
- event.count = Integer.valueOf(json.get("count").toString());
- event.sum = Double.valueOf(json.get("sum").toString());
- event.timestamp = Integer.valueOf(json.get("timestamp").toString());
- HashMap<String, String> segmentation = new HashMap<String, String>();
- @SuppressWarnings("unchecked")
- Iterator<String> nameItr = ((JSONObject) json.get("segmentation")).keys();
- while (nameItr.hasNext()) {
- String key = nameItr.next();
- segmentation.put(key, ((JSONObject) json.get("segmentation")).getString(key));
- }
- event.segmentation = segmentation;
- } catch (JSONException e) {
- e.printStackTrace();
- }
- return event;
- }
- }
最后讲一下,自定义事件的使用。
- Countly.sharedInstance().recordEvent("open acivity", count++);
- Map<String, String> music = new HashMap<String, String>();
- music.put("type", "popular");
- music.put("artist", "JJLin");
- music.put("User_status", "registered");
- Countly.sharedInstance().recordEvent( "music",music,count++);
你看Countly提供了好几种方式:
第一种方式,就是一个tag和一个计数,足够我们使用了。
对于第三种,我觉得有更高需要采用的到,举个例子:
附上网站自定义事件的报表:
如果大家有啥问题可以找我讨论。
Countly在andoid和vps集成使用,开源的统计分析sdk的更多相关文章
- [转]Infobright是一个与MySQL集成的开源数据仓库
[文章作者:张宴 本文版本:v1.1 最后修改:2010.05.18 转载请注明原文链接:http://blog.zyan.cc/infobright/] Infobright是一个与MySQL集成的 ...
- 学会这几步,简单集成视频编辑原子能力SDK
华为视频编辑服务6.2.0版本上线后,我们为大家带来了两大变化:分别是丰富多样的AI能力和灵活选择的集成方式.为让开发者更快上手使用,今天小编带来了视频编辑原子能力SDK的具体集成方法.快来试试吧! ...
- 微信小程序集成腾讯云 IM SDK
微信小程序集成腾讯云 IM SDK 1.背景 因业务功能需求需要接入IM(即时聊天)功能,一开始想到的是使用 WebSocket 来实现这个功能,然天意捉弄(哈哈)服务器版本太低不支持 wx 协议(也 ...
- 设定十分钟android在状态栏上集成的开源project推荐
1.前言 于android kitkat 有一个新功能可以设置背景的手机状态栏,让手机风的整个界面格是一致的,它看起来非常酷,在今年的google i/o向上android l这样的风格.来如今看我们 ...
- iOS编译集成linux开源c库的一些记录
最近一个iOS项目需要使用一些Linux下面的开源c库,说是Linux的其实是跨平台的,各种Unix系统都有支持.理论上iOS来自MacOS,而MacOS其实是一种兼容的Unix系统,所以这些库应该也 ...
- 云原生强大且灵活的持续集成CI开源框架Tekton实战-上
@ 目录 概述 定义 常见CICD工具 使用好处 组件 基本概念 安装 前提条件 安装Tekton Pipelines 创建并运行任务 安装Dashboard 安装Cli Pipelines示例演示 ...
- MyBridgeWebViewDemo【集成JsBridge开源库的的封装的webview】
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 使用的是第三方库lzyzsd/JsBridge,但是不同的是,将自己封装的MyBridgeWebView通过继承BridgeWebV ...
- 集成支付宝钱包支付iOS SDK的方法与经验
流程 摘自第一个文档<支付宝钱包支付接口开发包2.0标准版.pdf> 图中的“商户客户端”就是我们的iOS客户端需要做的事情: 调用支付宝支付接口 处理支付宝返回的支付结果 在调用支付宝支 ...
- 集成支付宝钱包支付ios SDK的方法和经验
没想到,支付宝的SDK是我目前用过的所有第三方SDK中最难用的一个了. 下载 首先,你要想找到这个SDK,都得费点功夫.现在的SDK改名叫移动支付集成开发包了,下载页面在 这里 的 “请点此下载集成开 ...
随机推荐
- YII数据库操作中打印sql
配置如下: 'components' => array( 'db'=>array( 'enableParamLogging' => true, ), 'log'=>array( ...
- 我的JAVA基础学习史1
又开始学习了..很是兴奋呢~~~~ 本来是想学安卓的,但是安卓的视频课程中,第一阶段是环境,第二阶段是JAVA基础(讲课的这个老师真是在念课本,但是实在没有办法,没找到更好.更完整的资料了). 虽然以 ...
- javascript里的post和get有什么区别
FORM中的get post方法区别Form中的get和post方法,在数据传输过程中分别对应了HTTP协议中的GET和POST方法.二者主要区别如下: 1.Get是用来从服务器上获得数据,而Post ...
- 1106. Two Teams(dfs 染色)
1106 结点染色 当前结点染为黑 朋友染为白 依次染下去 这题是为二分图打基础吧 #include <iostream> #include<cstdio> #include ...
- 宏ut_2pow_remainder
求余数 12%8=4 n%m也能计算出余数,但效率可能比位操作要低一些 /*************************************************************// ...
- poj2352
纪念树状数组初步(……): 这题已经给了y升序,y相同时x升序,(yeah) 所以容易想到O(n^2)的模拟算法: 其实分析一下就是对于当前xi,统计之前有多少个小于等于xi(因为已经保证了没有相同坐 ...
- hdu 3367 Pseudoforest
Pseudoforest Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) To ...
- Mysql加密方式
MySQL数据库的认证密码有两种方式, MySQL 4.1版本之前是MySQL323加密,MySQL 4.1和之后的版本都是MySQLSHA1加密, MySQL数据库中自带Old_Password(s ...
- 让memcached和mysql更好的工作
这次是Fotolog的经验,传说中比Flickr更大的网站,Fotolog在21台服务器上部署了51个memcached实例,总计有254G缓存空间可用,缓存了多达175G的内容,这个数量比很多网站的 ...
- 我的WCF之旅(3):在WCF中实现双工通信
双工(Duplex)模式的消息交换方式体现在消息交换过程中,参与的双方均可以向对方发送消息.基于双工MEP消息交换可以看成是多个基本模式下(比如请求-回复模式和单项模式)消息交换的组合.双工MEP又具 ...