hbase協處理器編碼實例

来源:http://www.cnblogs.com/learn21cn/archive/2016/12/23/6213450.html
-Advertisement-
Play Games

Observer協處理器通常在一個特定的事件(諸如Get或Put)之前或之後發生,相當於RDBMS中的觸發器。Endpoint協處理器則類似於RDBMS中的存儲過程,因為它可以讓你在RegionServer上對數據執行自定義計算,而不是在客戶端上執行計算。 本文是以上兩者的簡單實例,使用的環境:環境 ...


Observer協處理器通常在一個特定的事件(諸如GetPut)之前或之後發生,相當於RDBMS中的觸發器。Endpoint協處理器則類似於RDBMS中的存儲過程,因為它可以讓你在RegionServer上對數據執行自定義計算,而不是在客戶端上執行計算。

本文是以上兩者的簡單實例,使用的環境:環境 jdk1.8 hadoop2.6.5 hbase1.2.4。

1、Endpoint實例 
1> 編寫適用於protobuf的proto文件,如下,儘量不要帶註釋,因為編譯時可能出現亂碼

option java_package = "com.endpoint.test";
option java_outer_classname = "Sum";
option java_generic_services = true;
option java_generate_equals_and_hash = true;
option optimize_for = SPEED;

message SumRequest {
    required string family = 1;    
    required string column = 2;    
}
message SumResponse {
    required int64 sum = 1 [default = 0];
}
service SumService {
    rpc getSum(SumRequest)
        returns (SumResponse);
}

 2> 編譯上面的proto文件
使用protoc程式進行編譯,linux下或者windows均可,protoc程式可以直接從github下載:https://github.com/google/protobuf/releases,也可以自己編譯生成,參見protobuf的編譯安裝

註意,編譯的版本要與hadoop以及hbase使用的版本相同,或者略高,但最好不要過高,hadoop2.6.5 hbase1.2.4使用的都是protobuf2.5.0的版本,寫此篇文章時的最新版為3.1.0

(高版本必須指定syntax,例如proto3的syntax在第一行非空白非註釋行,必須寫:syntax = "proto3",欄位規則移除了 “required”,並把 “optional” 改名為 “singular”,移除了 default 選項。可搜索Protobuf 的 proto3 與 proto2 的區別進行瞭解。)下載的話選擇帶win或linux的版本,這是編譯好的版本。有很多帶具體語言的版本,是一些具體某種語言的發行版源碼包。,為了與hbase以及hadoop統一起來,此處用的是protoc-2.5.0-win32.zip。

解壓文件:

 

 使用windows命令行進入上面的目錄,執行以下命令即可:

protoc.exe sum1.proto --java_out=./

高版本有編譯好的適用於linux下的protoc程式文件,低版本沒有。在linux下執行以下命令:

protoc sum.proto --java_out=./

 結果都一樣,生成的代碼參見摺疊部分,有很多,因為上面文件中指定java_outer_classname = "Sum",所以會生成Sum類,將這個類引入到項目中,註意項目的包名稱與上面文件中指定(option java_package = "com.endpoint.test")的名稱要一致。

   1 // Generated by the protocol buffer compiler.  DO NOT EDIT!
   2 // source: sumcode.proto
   3 
   4 package com.endpoint.test;
   5 
   6 public final class Sum {
   7   private Sum() {}
   8   public static void registerAllExtensions(
   9       com.google.protobuf.ExtensionRegistry registry) {
  10   }
  11   public interface SumRequestOrBuilder
  12       extends com.google.protobuf.MessageOrBuilder {
  13 
  14     // required string family = 1;
  15     /**
  16      * <code>required string family = 1;</code>
  17      */
  18     boolean hasFamily();
  19     /**
  20      * <code>required string family = 1;</code>
  21      */
  22     java.lang.String getFamily();
  23     /**
  24      * <code>required string family = 1;</code>
  25      */
  26     com.google.protobuf.ByteString
  27         getFamilyBytes();
  28 
  29     // required string column = 2;
  30     /**
  31      * <code>required string column = 2;</code>
  32      */
  33     boolean hasColumn();
  34     /**
  35      * <code>required string column = 2;</code>
  36      */
  37     java.lang.String getColumn();
  38     /**
  39      * <code>required string column = 2;</code>
  40      */
  41     com.google.protobuf.ByteString
  42         getColumnBytes();
  43   }
  44   /**
  45    * Protobuf type {@code SumRequest}
  46    */
  47   public static final class SumRequest extends
  48       com.google.protobuf.GeneratedMessage
  49       implements SumRequestOrBuilder {
  50     // Use SumRequest.newBuilder() to construct.
  51     private SumRequest(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
  52       super(builder);
  53       this.unknownFields = builder.getUnknownFields();
  54     }
  55     private SumRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
  56 
  57     private static final SumRequest defaultInstance;
  58     public static SumRequest getDefaultInstance() {
  59       return defaultInstance;
  60     }
  61 
  62     public SumRequest getDefaultInstanceForType() {
  63       return defaultInstance;
  64     }
  65 
  66     private final com.google.protobuf.UnknownFieldSet unknownFields;
  67     @java.lang.Override
  68     public final com.google.protobuf.UnknownFieldSet
  69         getUnknownFields() {
  70       return this.unknownFields;
  71     }
  72     private SumRequest(
  73         com.google.protobuf.CodedInputStream input,
  74         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
  75         throws com.google.protobuf.InvalidProtocolBufferException {
  76       initFields();
  77       int mutable_bitField0_ = 0;
  78       com.google.protobuf.UnknownFieldSet.Builder unknownFields =
  79           com.google.protobuf.UnknownFieldSet.newBuilder();
  80       try {
  81         boolean done = false;
  82         while (!done) {
  83           int tag = input.readTag();
  84           switch (tag) {
  85             case 0:
  86               done = true;
  87               break;
  88             default: {
  89               if (!parseUnknownField(input, unknownFields,
  90                                      extensionRegistry, tag)) {
  91                 done = true;
  92               }
  93               break;
  94             }
  95             case 10: {
  96               bitField0_ |= 0x00000001;
  97               family_ = input.readBytes();
  98               break;
  99             }
 100             case 18: {
 101               bitField0_ |= 0x00000002;
 102               column_ = input.readBytes();
 103               break;
 104             }
 105           }
 106         }
 107       } catch (com.google.protobuf.InvalidProtocolBufferException e) {
 108         throw e.setUnfinishedMessage(this);
 109       } catch (java.io.IOException e) {
 110         throw new com.google.protobuf.InvalidProtocolBufferException(
 111             e.getMessage()).setUnfinishedMessage(this);
 112       } finally {
 113         this.unknownFields = unknownFields.build();
 114         makeExtensionsImmutable();
 115       }
 116     }
 117     public static final com.google.protobuf.Descriptors.Descriptor
 118         getDescriptor() {
 119       return com.endpoint.test.Sum.internal_static_SumRequest_descriptor;
 120     }
 121 
 122     protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
 123         internalGetFieldAccessorTable() {
 124       return com.endpoint.test.Sum.internal_static_SumRequest_fieldAccessorTable
 125           .ensureFieldAccessorsInitialized(
 126               com.endpoint.test.Sum.SumRequest.class, com.endpoint.test.Sum.SumRequest.Builder.class);
 127     }
 128 
 129     public static com.google.protobuf.Parser<SumRequest> PARSER =
 130         new com.google.protobuf.AbstractParser<SumRequest>() {
 131       public SumRequest parsePartialFrom(
 132           com.google.protobuf.CodedInputStream input,
 133           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
 134           throws com.google.protobuf.InvalidProtocolBufferException {
 135         return new SumRequest(input, extensionRegistry);
 136       }
 137     };
 138 
 139     @java.lang.Override
 140     public com.google.protobuf.Parser<SumRequest> getParserForType() {
 141       return PARSER;
 142     }
 143 
 144     private int bitField0_;
 145     // required string family = 1;
 146     public static final int FAMILY_FIELD_NUMBER = 1;
 147     private java.lang.Object family_;
 148     /**
 149      * <code>required string family = 1;</code>
 150      */
 151     public boolean hasFamily() {
 152       return ((bitField0_ & 0x00000001) == 0x00000001);
 153     }
 154     /**
 155      * <code>required string family = 1;</code>
 156      */
 157     public java.lang.String getFamily() {
 158       java.lang.Object ref = family_;
 159       if (ref instanceof java.lang.String) {
 160         return (java.lang.String) ref;
 161       } else {
 162         com.google.protobuf.ByteString bs = 
 163             (com.google.protobuf.ByteString) ref;
 164         java.lang.String s = bs.toStringUtf8();
 165         if (bs.isValidUtf8()) {
 166           family_ = s;
 167         }
 168         return s;
 169       }
 170     }
 171     /**
 172      * <code>required string family = 1;</code>
 173      */
 174     public com.google.protobuf.ByteString
 175         getFamilyBytes() {
 176       java.lang.Object ref = family_;
 177       if (ref instanceof java.lang.String) {
 178         com.google.protobuf.ByteString b = 
 179             com.google.protobuf.ByteString.copyFromUtf8(
 180                 (java.lang.String) ref);
 181         family_ = b;
 182         return b;
 183       } else {
 184         return (com.google.protobuf.ByteString) ref;
 185       }
 186     }
 187 
 188     // required string column = 2;
 189     public static final int COLUMN_FIELD_NUMBER = 2;
 190     private java.lang.Object column_;
 191     /**
 192      * <code>required string column = 2;</code>
 193      */
 194     public boolean hasColumn() {
 195       return ((bitField0_ & 0x00000002) == 0x00000002);
 196     }
 197     /**
 198      * <code>required string column = 2;</code>
 199      */
 200     public java.lang.String getColumn() {
 201       java.lang.Object ref = column_;
 202       if (ref instanceof java.lang.String) {
 203         return (java.lang.String) ref;
 204       } else {
 205         com.google.protobuf.ByteString bs = 
 206             (com.google.protobuf.ByteString) ref;
 207         java.lang.String s = bs.toStringUtf8();
 208         if (bs.isValidUtf8()) {
 209           column_ = s;
 210         }
 211         return s;
 212       }
 213     }
 214     /**
 215      * <code>required string column = 2;</code>
 216      */
 217     public com.google.protobuf.ByteString
 218         getColumnBytes() {
 219       java.lang.Object ref = column_;
 220       if (ref instanceof java.lang.String) {
 221         com.google.protobuf.ByteString b = 
 222             com.google.protobuf.ByteString.copyFromUtf8(
 223                 (java.lang.String) ref);
 224         column_ = b;
 225         return b;
 226       } else {
 227         return (com.google.protobuf.ByteString) ref;
 228       }
 229     }
 230 
 231     private void initFields() {
 232       family_ = "";
 233       column_ = "";
 234     }
 235     private byte memoizedIsInitialized = -1;
 236     public final boolean isInitialized() {
 237       byte isInitialized = memoizedIsInitialized;
 238       if (isInitialized != -1) return isInitialized == 1;
 239 
 240       if (!hasFamily()) {
 241         memoizedIsInitialized = 0;
 242         return false;
 243       }
 244       if (!hasColumn()) {
 245         memoizedIsInitialized = 0;
 246         return false;
 247       }
 248       memoizedIsInitialized = 1;
 249       return true;
 250     }
 251 
 252     public void writeTo(com.google.protobuf.CodedOutputStream output)
 253                         throws java.io.IOException {
 254       getSerializedSize();
 255       if (((bitField0_ & 0x00000001) == 0x00000001)) {
 256         output.writeBytes(1, getFamilyBytes());
 257       }
 258       if (((bitField0_ & 0x00000002) == 0x00000002)) {
 259         output.writeBytes(2, getColumnBytes());
 260       }
 261       getUnknownFields().writeTo(output);
 262     }
 263 
 264     private int memoizedSerializedSize = -1;
 265     public int getSerializedSize() {
 266       int size = memoizedSerializedSize;
 267       if (size != -1) return size;
 268 
 269       size = 0;
 270       if (((bitField0_ & 0x00000001) == 0x00000001)) {
 271         size += com.google.protobuf.CodedOutputStream
 272           .computeBytesSize(1, getFamilyBytes());
 273       }
 274       if (((bitField0_ & 0x00000002) == 0x00000002)) {
 275         size += com.google.protobuf.CodedOutputStream
 276           .computeBytesSize(2, getColumnBytes());
 277       }
 278       size += getUnknownFields().getSerializedSize();
 279       memoizedSerializedSize = size;
 280       return size;
 281     }
 282 
 283     private static final long serialVersionUID = 0L;
 284     @java.lang.Override
 285     protected java.lang.Object writeReplace()
 286         throws java.io.ObjectStreamException {
 287       return super.writeReplace();
 288     }
 289 
 290     @java.lang.Override
 291     public boolean equals(final java.lang.Object obj) {
 292       if (obj == this) {
 293        return true;
 294       }
 295       if (!(obj instanceof com.endpoint.test.Sum.SumRequest)) {
 296         return super.equals(obj);
 297       }
 298       com.endpoint.test.Sum.SumRequest other = (com.endpoint.test.Sum.SumRequest) obj;
 299 
 300       boolean result = true;
 301       result = result && (hasFamily() == other.hasFamily());
 302       if (hasFamily()) {
 303         result = result && getFamily()
 304             .equals(other.getFamily());
 305       }
 306       result = result && (hasColumn() == other.hasColumn());
 307       if (hasColumn()) {
 308         result = result && getColumn()
 309             .equals(other.getColumn());
 310       }
 311       result = result &&
 312           getUnknownFields().equals(other.getUnknownFields());
 313       return result;
 314     }
 315 
 316     private int memoizedHashCode = 0;
 317     @java.lang.Override
 318     public int hashCode() {
 319       if (memoizedHashCode != 0) {
 320         return memoizedHashCode;
 321       }
 322       int hash = 41;
 323       hash = (19 * hash) + getDescriptorForType().hashCode();
 324       if (hasFamily()) {
 325         hash = (37 * hash) + FAMILY_FIELD_NUMBER;
 326         hash = (53 * hash) + getFamily().hashCode();
 327       }
 328       if (hasColumn()) {
 329         hash = (37 * hash) + COLUMN_FIELD_NUMBER;
 330         hash = (53 * hash) + getColumn().hashCode();
 331       }
 332       hash = (29 * hash) + getUnknownFields().hashCode();
 333       memoizedHashCode = hash;
 334       return hash;
 335     }
 336 
 337     public static com.endpoint.test.Sum.SumRequest parseFrom(
 338         com.google.protobuf.ByteString data)
 339         throws com.google.protobuf.InvalidProtocolBufferException {
 340       return PARSER.parseFrom(data);
 341     }
 342     public static com.endpoint.test.Sum.SumRequest parseFrom(
 343         com.google.protobuf.ByteString data,
 344         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
 345         throws com.google.protobuf.InvalidProtocolBufferException {
 346       return PARSER.parseFrom(data, extensionRegistry);
 347     }
 348     public static com.endpoint.test.Sum.SumRequest parseFrom(byte[] data)
 349         throws com.google.protobuf.InvalidProtocolBufferException {
 350       return PARSER.parseFrom(data);
 351     }
 352     public static com.endpoint.test.Sum.SumRequest parseFrom(
 353         byte[] data,
 354         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
 355         throws com.google.protobuf.InvalidProtocolBufferException {
 356       return PARSER.parseFrom(data, extensionRegistry);
 357     }
 358     public static com.endpoint.test.Sum.SumRequest parseFrom(java.io.InputStream input)
 359         throws java.io.IOException {
 360       return PARSER.parseFrom(input);
 361     }
 362     public static com.endpoint.test.Sum.SumRequest parseFrom(
 363         java.io.InputStream input,
 364         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
 365         throws java.io.IOException {
 366       return PARSER.parseFrom(input, extensionRegistry);
 367     }
 368     public static com.endpoint.test.Sum.SumRequest parseDelimitedFrom(java.io.InputStream input)
 369         throws java.io.IOException {
 370       return PARSER.parseDelimitedFrom(input);
 371     }
 372     public static com.endpoint.test.Sum.SumRequest parseDelimitedFrom(
 373         java.io.InputStream input,
 374         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
 375         throws java.io.IOException {
 376       return PARSER.parseDelimitedFrom(input, extensionRegistry);
 377     }
 378     public static com.endpoint.test.Sum.SumRequest parseFrom(
 379         com.google.protobuf.CodedInputStream input)
 380         throws java.io.IOException {
 381       return PARSER.parseFrom(input);
 382     }
 383     public static com.endpoint.test.Sum.SumRequest parseFrom(
 384         com.google.protobuf.CodedInputStream input,
 385         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
 386         throws java.io.IOException {
 387       return PARSER.parseFrom(input, extensionRegistry);
 388     }
 389 
 390     public static Builder newBuilder() { return Builder.create(); }
 391     public Builder newBuilderForType() { return newBuilder(); }
 392     public static Builder newBuilder(com.endpoint.test.Sum.SumRequest prototype) {
 393       return newBuilder().mergeFrom(prototype);
 394     }
 395     public Builder toBuilder() { return newBuilder(this); }
 396 
 397     @java.lang.Override
 398     protected Builder newBuilderForType(
 399         com.google.protobuf.GeneratedMessage.BuilderParent parent) {
 400       Builder builder = new Builder(parent);
 401       return builder;
 402     }
 403     /**
 404      * Protobuf type {@code SumRequest}
 405      */
 406     public static final class Builder extends
 407         com.google.protobuf.GeneratedMessage.Builder<Builder>
 408        implements com.endpoint.test.Sum.SumRequestOrBuilder {
 409       public static final com.google.protobuf.Descriptors.Descriptor
 410           getDescriptor() {
 411         return com.endpoint.test.Sum.internal_static_SumRequest_descriptor;
 412       }
 413 
 414       protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
 415           internalGetFieldAccessorTable() {
 416         return com.endpoint.test.Sum.internal_static_SumRequest_fieldAccessorTable
 417             .ensureFieldAccessorsInitialized(
 418                 com.endpoint.test.Sum.SumRequest.class, com.endpoint.test.Sum.SumRequest.Builder.class);
 419       }
 420 
 421       // Construct using com.endpoint.test.Sum.SumRequest.newBuilder()
 422       private Builder() {
 423         maybeForceBuilderInitialization();
 424       }
 425 
 426       private Builder(
 427           com.google.protobuf.GeneratedMessage.BuilderParent parent) {
 428         super(parent);
 429         maybeForceBuilderInitialization();
 430       }
 431       private void maybeForceBuilderInitialization() {
 432         if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
 433         }
 434       }
 435       private static Builder create() {
 436         return new Builder();
 437       }
 438 
 439       public Builder clear() {
 440         super.clear();
 441         family_ = "";
 442         bitField0_ = (bitField0_ & ~0x00000001);
 443         column_ = "";
 444         bitField0_ = (bitField0_ & ~0x00000002);
 445         return this;
 446       }
 447 
 448       public Builder clone() {
 449         return create().mergeFrom(buildPartial());
 450       }
 451 
 452       public com.google.protobuf.Descriptors.Descriptor
 453           getDescriptorForType() {
 454         return com.endpoint.test.Sum.internal_static_SumRequest_descriptor;
 455       }
 456 
 457       public com.endpoint.test.Sum.SumRequest getDefaultInstanceForType() {
 458         return com.endpoint.test.Sum.SumRequest.getDefaultInstance();
 459       }
 460 
 461       public com.endpoint.test.Sum.SumRequest build() {
 462         com.endpoint.test.Sum.SumRequest result = buildPartial();
 463         if (!result.isInitialized()) {
 464           throw newUninitializedMessageException(result);
 465         }
 466         return result;
 467       }
 468 
 469       	   

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 下麵是幾種簡單實現分隔線的方法,個人比較喜歡第二種,我也給出了最後第五種比較2的寫法,請大家拍磚,或者提供其他好的方法。 單個標簽實現分隔線: 點此查看實例展示 優點:代碼簡潔 巧用背景色實現分隔線: 點此查看實例展示 優點:代碼簡潔,可自適應寬度 inline-block實現分隔線: 點此查看實例 ...
  • 上一篇記錄了BaiduTemplate模板引擎使用示例附源碼,在此基礎上對使用方法進行了封裝 自定義插件jajaxrefresh.js 代碼如下: 調用方法: 預覽效果: 源碼下載 ...
  • 0x01 iframe的跳出框架 0x02 iframe樣式設置 0x03 iframe重置高度 1、首先來一個,跳出iframe的好方法,直接可以在Login.aspx頁面使用。 2、再來段比較好看的iframe 3、子頁面的使用,子頁面,在調整大小後,可以調用父頁面的SetWinHeight就可 ...
  • <!doctype html><html><head> <meta charset="UTF-8"> <title>前端Demo常用庫文件鏈接</title> <!--bootstrap--> <link rel="stylesheet" href="http://cdn.bootcss.com/b ...
  • localStorage(本地存儲),可以長期存儲數據,沒有時間限制,一天,一年,兩年甚至更長,數據都可以使用。sessionStorage(會話存儲),只有在瀏覽器被關閉之前使用,創建另一個頁面時同意可以使用,關閉瀏覽器之後數據就會消失。 HTML5 的本地存儲 API 中的 localStora ...
  • 1、Math.random():返回 0 ~ 1 之間的隨機數。2、Math.ceil():返回值:返回大於或等於x,並且與之最接近的整數(如果x是正數,則把小數“入”;如果x是負數,則把小數“舍”)。3、Math.round():四捨五入取整。4、Math.floor():返回值:返回小於或等於x ...
  • 僅記錄一些我工作中常用的自定義js函數。 1、獲取URL請求參數 調用方式:var id = GetQueryString("id"); 2、在文本框中游標位置插入文本值 調用方式:這裡使用了easyui中的combobox控制項和ueditor富文本控制項 easyui-combobox代碼: $(" ...
  • 第一種方法: 第二種方法: ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...