问:
JavaScript: Traversing and Reversing Singly-Linked Lists and Converting Between SLLs and Numbers
INTRO
Today, while doing a mock interview with a Facebook JavaScript problem, I blanked out on how to handle singly-linked lists.  The code I had so far is simply a function that takes 2 linked lists and returns another linked list.  My plan is below.

QUESTION
You are given two non-empty linked lists of arbitrary length representing two non-negative integers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.

You may assume the two numbers do not contain any leading zero, except the number 0 itself.

Example:

Input: (2 -> 4 -> 3) + (5 -> 6 -> 4) Output: 7 -> 0 -> 8 Explanation:
  342 + 465 = 807.

PLAN

Copy each number from the first linked list into an array in order.

Reverse the array.

Convert the array to a string then to an integer and store this in a variable.

Repeat this for the second linked list.

Sum the two numbers and store this value in a variable.

Convert this sum into a string.

Use Array.from on this string to convert it into an array then reverse the array.

?

Return the new linked list.

```<code>/*
 * Definition for singly-linked list.
 * function ListNode(val)
 * {
 *  this.val = val;
 *  this.next = null;
 * }
 */

/* Expected input and output.
 * @param {ListNode} l1
 * @param {ListNode} l2
 * @return {ListNode}
 */

var addTwoNumbers = function(l1, l2)
{

};

</code>```

答:
You don't have to create new arrays holding the same data as the linked list. You can process both the lists while iterating on them and creating the result list in same loop. While doing this you have to take care of the carry from the addition.

Basically you have to do like:

```<code>let currNodeList1 = l1, currNodeList2 = l2;  //assuming that l1 and l2 point to head of linked list
let resultListHead = null, currNodeResultList = null;  //to store the result
let carry = 0, sum = 0;
while(currNodeList1 != null && currNodeList2 != null) {
    sum = carry + currNodeList1.val + currNodeList2.val;
    carry = Math.trunc(sum / 10);
    sum = sum % 10;

    let newListNode = new ListNode(sum);
    if(currNodeResultList == null) {
        resultListHead = newListNode;
    } else {
        currNodeResultList.next = newListNode;
    }
    currNodeResultList = newListNode;
    currNodeList1 = currNodeList1.next;
    currNodeList2 = currNodeList2.next;
}

if(currNodeList1 == null) {   //other list is longer in length
    while(currNodeList2 != null) {
         // calculate sum as carry + currNodeList2.val
         //same carry logic and keep appending to the end of the result list
    }
}

if(currNodeList2 == null) {   //other list is longer in length
    while(currNodeList1 != null) {
         //calculate sum as carry + currNodeList2.val
         //same carry logic and keep appending to the end of the result list
    }
}
</code>```

Obviously you can make the code more modular by refactoring the repeating parts but the general idea should be this.

Body:
INTRO
Today, while doing a mock interview with a Facebook JavaScript problem, I blanked out on how to handle singly-linked lists.  The code I had so far is simply a function that takes 2 linked lists and returns another linked list.  My plan is below.

QUESTION
You are given two non-empty linked lists of arbitrary length representing two non-negative integers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.

You may assume the two numbers do not contain any leading zero, except the number 0 itself.

Example:

Input: (2 -> 4 -> 3) + (5 -> 6 -> 4) Output: 7 -> 0 -> 8 Explanation:
  342 + 465 = 807.

PLAN

Copy each number from the first linked list into an array in order.

Reverse the array.

Convert the array to a string then to an integer and store this in a variable.

Repeat this for the second linked list.

Sum the two numbers and store this value in a variable.

Convert this sum into a string.

Use Array.from on this string to convert it into an array then reverse the array.

?

Return the new linked list.

/*
 * Definition for singly-linked list.
 * function ListNode(val)
 * {
 *  this.val = val;
 *  this.next = null;
 * }
 */

/* Expected input and output.
 * @param {ListNode} l1
 * @param {ListNode} l2
 * @return {ListNode}
 */

var addTwoNumbers = function(l1, l2)
{

};

Body:
You don't have to create new arrays holding the same data as the linked list. You can process both the lists while iterating on them and creating the result list in same loop. While doing this you have to take care of the carry from the addition.

Basically you have to do like:

let currNodeList1 = l1, currNodeList2 = l2;  //assuming that l1 and l2 point to head of linked list
let resultListHead = null, currNodeResultList = null;  //to store the result
let carry = 0, sum = 0;
while(currNodeList1 != null && currNodeList2 != null) {
    sum = carry + currNodeList1.val + currNodeList2.val;
    carry = Math.trunc(sum / 10);
    sum = sum % 10;

    let newListNode = new ListNode(sum);
    if(currNodeResultList == null) {
        resultListHead = newListNode;
    } else {
        currNodeResultList.next = newListNode;
    }
    currNodeResultList = newListNode;
    currNodeList1 = currNodeList1.next;
    currNodeList2 = currNodeList2.next;
}

if(currNodeList1 == null) {   //other list is longer in length
    while(currNodeList2 != null) {
         // calculate sum as carry + currNodeList2.val
         //same carry logic and keep appending to the end of the result list
    }
}

if(currNodeList2 == null) {   //other list is longer in length
    while(currNodeList1 != null) {
         //calculate sum as carry + currNodeList2.val
         //same carry logic and keep appending to the end of the result list
    }
}

Obviously you can make the code more modular by refactoring the repeating parts but the general idea should be this.


来源: stackexchange

问:
angular disable button on dynamic list
My list is taking info from external API, Im creating it dynamically, When I click on the 'li' element (I create 10 of them) with (click) method bunch of info shows up (second ul list). The problem is that I want to disable all other elements (all other 9) that aren't clicked, ofc until I unclick that one I clicked before. Summing I want be able to click only 1 element at once others must be disable for that moment.
Could someone explain/show me how to do this?</p>

```<code><ng-container>
  <div class="wrapper">
    <ul class="exteriorUL" *ngFor="let planet of results$; let i = index;">
      <li (click)="hidden[i] = !hidden[i]">
          <b class="btn btn-success">{{planet.name}}</b>
      </li>
      <ul class="interiorUL" [hidden]="!hidden[i]">
        <li>
            <span>Rotation period:</span> {{planet.rotation_period}} h
        </li>
        <li>
            <span>Orbital period:</span> {{planet.orbital_period}} days
        </li>
        <li>
            <span>Climate:</span> {{planet.climate}}
        </li>
        <li>
            <span>Planet terrain:</span> {{planet.terrain}}
        </li>
        <li>
          <span>Population:</span> {{planet.population}}
        </li>
        <li>
            <span>Gravity:</span> {{planet.gravity}}
        </li>
        <li>
            <span>Diameter:</span> {{planet.diameter}} km
        </li>

        <hr>
      </ul>
    </ul>
  </div>
</ng-container>
</code>```

答:
Try this:

TS:

```<code>isAnyItemClicked:boolean = false;
clickedItem:string = 'Mercury'; // I guessed the name Mercury, set the appropiate name which you want to enable

clickItem(){
  if(this.clickedItem == ''){
     this.isAnyItemClicked = false
  } else {
     this.isAnyItemClicked = true
  }
}
</code>```

HTML:

```<code><li (click)="clickItem();clickedItem= planet.name" [class.disabled]="isAnyItemClicked && clickedItem != planet.name">...</li>
</code>```

CSS:

```<code>.disabled {
    pointer-events: none;
    opacity: 0.6;
}
</code>```

ContentLicense: CC BY-SA 4.0

Title: angular disable button on dynamic list

Body:
My list is taking info from external API, Im creating it dynamically, When I click on the 'li' element (I create 10 of them) with (click) method bunch of info shows up (second ul list). The problem is that I want to disable all other elements (all other 9) that aren't clicked, ofc until I unclick that one I clicked before. Summing I want be able to click only 1 element at once others must be disable for that moment.
Could someone explain/show me how to do this?

<ng-container>

          {{planet.name}}

            Rotation period: {{planet.rotation_period}} h

            Orbital period: {{planet.orbital_period}} days

            Climate: {{planet.climate}}

            Planet terrain: {{planet.terrain}}

          Population: {{planet.population}}

            Gravity: {{planet.gravity}}

            Diameter: {{planet.diameter}} km

</ng-container>

Body:
Try this:

TS:

isAnyItemClicked:boolean = false;
clickedItem:string = 'Mercury'; // I guessed the name Mercury, set the appropiate name which you want to enable

clickItem(){
  if(this.clickedItem == ''){
     this.isAnyItemClicked = false
  } else {
     this.isAnyItemClicked = true
  }
}

HTML:

<li (click)="clickItem();clickedItem= planet.name" [class.disabled]="isAnyItemClicked && clickedItem != planet.name">...</li>

CSS:

.disabled {
    pointer-events: none;
    opacity: 0.6;
}


问:
error "application non installée" When I want to upload a new update to my app
I have a app in 'Google play store'. I want to upload a new update to my app .

When I finished the new version of the application, I tried to install it on the phone over the old version but I get the error message application not installed.

I used the same package name and same keystore

答: Sometimes it happens because of the build is not packaged properly. It happened with me when i was using JNI. If Clean, invalidate cache and rebuild is not working then please share more details about the app which libraries and features you are using like progurd, jni or something else.</p>


问:
Accessing USB device data based only on DESCRIPTOR HID Report
I have a Digital Sound Level Meter (sonometer) GM1356 with USB. There is some software to handle it on Windows, however I don't have CD and it's not available on the internet. What I want do to is to read it's data about current noise level on Linux.

I found already a library that allows me to do this in a language I know (ruby, libusb). In next step I installed wireshark to check out what it sends do the pc. It doesn't send too much. The most interesting packet I found is DESCRIPTOR HID Report. I wonder what next steps should I take to read data that is interesting for me. How can I determine what requests I should send to get it?

```<code>HID Report
    Global item (Usage)
        Header
            .... ..10 = bSize: 2 bytes (2)
            .... 01.. = bType: Global (1)
            0000 .... = bTag: Usage (0x0)
        Usage page: [Vendor-defined] (0xffa0)
    Local item (Usage)
        Header
            .... ..01 = bSize: 1 byte (1)
            .... 10.. = bType: Local (2)
            0000 .... = bTag: Usage (0x0)
        Usage: [Vendor-defined] (0xffa00001)
    Main item (Collection)
        Header
            .... ..01 = bSize: 1 byte (1)
            .... 00.. = bType: Main (0)
            1010 .... = bTag: Collection (0xa)
        Collection type: Application (0x01)
        Local item (Usage)
            Header
                .... ..01 = bSize: 1 byte (1)
                .... 10.. = bType: Local (2)
                0000 .... = bTag: Usage (0x0)
            Usage: [Vendor-defined] (0xffa00002)
        Main item (Collection)
            Header
                .... ..01 = bSize: 1 byte (1)
                .... 00.. = bType: Main (0)
                1010 .... = bTag: Collection (0xa)
            Collection type: Physical (0x00)
            Global item (Usage)
                Header
                    .... ..10 = bSize: 2 bytes (2)
                    .... 01.. = bType: Global (1)
                    0000 .... = bTag: Usage (0x0)
                Usage page: [Vendor-defined] (0xffa1)
            Local item (Usage)
                Header
                    .... ..01 = bSize: 1 byte (1)
                    .... 10.. = bType: Local (2)
                    0000 .... = bTag: Usage (0x0)
                Usage: [Vendor-defined] (0xffa10003)
            Local item (Usage)
                Header
                    .... ..01 = bSize: 1 byte (1)
                    .... 10.. = bType: Local (2)
                    0000 .... = bTag: Usage (0x0)
                Usage: [Vendor-defined] (0xffa10004)
            Global item (Logical minimum)
                Header
                    .... ..01 = bSize: 1 byte (1)
                    .... 01.. = bType: Global (1)
                    0001 .... = bTag: Logical minimum (0x1)
                Logical minimum: 128
            Global item (Logical maximum)
                Header
                    .... ..01 = bSize: 1 byte (1)
                    .... 01.. = bType: Global (1)
                    0010 .... = bTag: Logical maximum (0x2)
                Logical maximum: 127
            Global item (Physical minimum)
                Header
                    .... ..01 = bSize: 1 byte (1)
                    .... 01.. = bType: Global (1)
                    0011 .... = bTag: Physical minimum (0x3)
                Physical minimum: 0
            Global item (Physical maximum)
                Header
                    .... ..01 = bSize: 1 byte (1)
                    .... 01.. = bType: Global (1)
                    0100 .... = bTag: Physical maximum (0x4)
                Physical maximum: 255
            Global item (Report size)
                Header
                    .... ..01 = bSize: 1 byte (1)
                    .... 01.. = bType: Global (1)
                    0111 .... = bTag: Report size (0x7)
                Report size: 8
            Global item (Report count)
                Header
                    .... ..01 = bSize: 1 byte (1)
                    .... 01.. = bType: Global (1)
                    1001 .... = bTag: Report count (0x9)
                Report count: 8
            Main item (Input)
                Header
                    .... ..01 = bSize: 1 byte (1)
                    .... 00.. = bType: Main (0)
                    1000 .... = bTag: Input (0x8)
                .... .... 0 = Data/constant: Data
                .... ...1 . = Data type: Variable
                .... ..0. . = Coordinates: Absolute
                .... .0.. . = Min/max wraparound: No Wrap
                .... 0... . = Physical relationship to data: Linear
                ...0 .... . = Preferred state: Preferred State
                ..0. .... . = Has null position: No Null position
                .0.. .... . = [Reserved]: False
                0... .... . = Bits or bytes: Buffered bytes (default, no second byte present)
            Local item (Usage)
                Header
                    .... ..01 = bSize: 1 byte (1)
                    .... 10.. = bType: Local (2)
                    0000 .... = bTag: Usage (0x0)
                Usage: [Vendor-defined] (0xffa10005)
            Local item (Usage)
                Header
                    .... ..01 = bSize: 1 byte (1)
                    .... 10.. = bType: Local (2)
                    0000 .... = bTag: Usage (0x0)
                Usage: [Vendor-defined] (0xffa10006)
            Global item (Logical minimum)
                Header
                    .... ..01 = bSize: 1 byte (1)
                    .... 01.. = bType: Global (1)
                    0001 .... = bTag: Logical minimum (0x1)
                Logical minimum: 128
            Global item (Logical maximum)
                Header
                    .... ..01 = bSize: 1 byte (1)
                    .... 01.. = bType: Global (1)
                    0010 .... = bTag: Logical maximum (0x2)
                Logical maximum: 127
            Global item (Physical minimum)
                Header
                    .... ..01 = bSize: 1 byte (1)
                    .... 01.. = bType: Global (1)
                    0011 .... = bTag: Physical minimum (0x3)
                Physical minimum: 0
            Global item (Physical maximum)
                Header
                    .... ..01 = bSize: 1 byte (1)
                    .... 01.. = bType: Global (1)
                    0100 .... = bTag: Physical maximum (0x4)
                Physical maximum: 255
            Global item (Report size)
                Header
                    .... ..01 = bSize: 1 byte (1)
                    .... 01.. = bType: Global (1)
                    0111 .... = bTag: Report size (0x7)
                Report size: 8
            Global item (Report count)
                Header
                    .... ..01 = bSize: 1 byte (1)
                    .... 01.. = bType: Global (1)
                    1001 .... = bTag: Report count (0x9)
                Report count: 8
            Main item (Output)
                Header
                    .... ..01 = bSize: 1 byte (1)
                    .... 00.. = bType: Main (0)
                    1001 .... = bTag: Output (0x9)
                .... .... 0 = Data/constant: Data
                .... ...1 . = Data type: Variable
                .... ..0. . = Coordinates: Absolute
                .... .0.. . = Min/max wraparound: No Wrap
                .... 0... . = Physical relationship to data: Linear
                ...0 .... . = Preferred state: Preferred State
                ..0. .... . = Has null position: No Null position
                .0.. .... . = (Non)-volatile: Non Volatile
                0... .... . = Bits or bytes: Buffered bytes (default, no second byte present)
            Main item (End collection)
                Header
                    .... ..00 = bSize: 0 bytes (0)
                    .... 00.. = bType: Main (0)
                    1100 .... = bTag: End collection (0xc)
        Main item (End collection)
            Header
                .... ..00 = bSize: 0 bytes (0)
                .... 00.. = bType: Main (0)
                1100 .... = bTag: End collection (0xc)
</code>```

答:
When you decode the HID descriptor it will show the packet formats. Unfortunately, in this case the usage pages are vendor-defined so it is not possible to say exactly how each usage is to be interpreted.

I decoded it using hidrdd (disclaimer: I wrote it, but it is free open source so I have no conflict of interest) as:

```<code>//--------------------------------------------------------------------------------
// Decoded Application Collection
//--------------------------------------------------------------------------------

/*
06 A0FF      (GLOBAL) USAGE_PAGE         0xFFA0 Vendor-defined
09 01        (LOCAL)  USAGE              0xFFA00001 <-- Warning: Undocumented usage (document it by inserting 0001 into file FFA0.conf)
A1 01        (MAIN)   COLLECTION         0x01 Application (Usage=0xFFA00001: Page=Vendor-defined, Usage=, Type=) <-- Error: COLLECTION must be preceded by a known USAGE
09 02          (LOCAL)  USAGE              0xFFA00002 <-- Warning: Undocumented usage (document it by inserting 0002 into file FFA0.conf)
A1 00          (MAIN)   COLLECTION         0x00 Physical (Usage=0xFFA00002: Page=Vendor-defined, Usage=, Type=) <-- Error: COLLECTION must be preceded by a known USAGE
06 A1FF          (GLOBAL) USAGE_PAGE         0xFFA1 Vendor-defined
09 03            (LOCAL)  USAGE              0xFFA10003 <-- Warning: Undocumented usage (document it by inserting 0003 into file FFA1.conf)
09 04            (LOCAL)  USAGE              0xFFA10004 <-- Warning: Undocumented usage (document it by inserting 0004 into file FFA1.conf)
15 80            (GLOBAL) LOGICAL_MINIMUM    0x80 (-128)
25 7F            (GLOBAL) LOGICAL_MAXIMUM    0x7F (127)
35 00            (GLOBAL) PHYSICAL_MINIMUM   0x00 (0)  <-- Info: Consider replacing 35 00 with 34
45 FF            (GLOBAL) PHYSICAL_MAXIMUM   0xFF (-1)
75 08            (GLOBAL) REPORT_SIZE        0x08 (8) Number of bits per field
95 08            (GLOBAL) REPORT_COUNT       0x08 (8) Number of fields
81 02            (MAIN)   INPUT              0x00000002 (8 fields x 8 bits) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap  <-- Error: PHYSICAL_MAXIMUM (-1) is less than PHYSICAL_MINIMUM (0)
09 05            (LOCAL)  USAGE              0xFFA10005 <-- Warning: Undocumented usage (document it by inserting 0005 into file FFA1.conf)
09 06            (LOCAL)  USAGE              0xFFA10006 <-- Warning: Undocumented usage (document it by inserting 0006 into file FFA1.conf)
15 80            (GLOBAL) LOGICAL_MINIMUM    0x80 (-128) <-- Redundant: LOGICAL_MINIMUM is already -128
25 7F            (GLOBAL) LOGICAL_MAXIMUM    0x7F (127) <-- Redundant: LOGICAL_MAXIMUM is already 127
35 00            (GLOBAL) PHYSICAL_MINIMUM   0x00 (0) <-- Redundant: PHYSICAL_MINIMUM is already 0 <-- Info: Consider replacing 35 00 with 34
45 FF            (GLOBAL) PHYSICAL_MAXIMUM   0xFF (-1) <-- Redundant: PHYSICAL_MAXIMUM is already -1
75 08            (GLOBAL) REPORT_SIZE        0x08 (8) Number of bits per field <-- Redundant: REPORT_SIZE is already 8
95 08            (GLOBAL) REPORT_COUNT       0x08 (8) Number of fields <-- Redundant: REPORT_COUNT is already 8
91 02            (MAIN)   OUTPUT             0x00000002 (8 fields x 8 bits) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap  <-- Error: PHYSICAL_MAXIMUM (-1) is less than PHYSICAL_MINIMUM (0)
C0             (MAIN)   END_COLLECTION     Physical  <-- Warning: Physical units are still in effect PHYSICAL(MIN=0,MAX=-1) UNIT(0x,EXP=0)
C0           (MAIN)   END_COLLECTION     Application  <-- Warning: Physical units are still in effect PHYSICAL(MIN=0,MAX=-1) UNIT(0x,EXP=0)
*/

//--------------------------------------------------------------------------------
// Vendor-defined inputReport (Device --> Host)
//--------------------------------------------------------------------------------

typedef struct
{
                                                     // No REPORT ID byte
                                                     // Collection: CA: CP:
  int8_t   VEN_0003;                                 // Usage 0xFFA10003: , Value = -128 to 127, Physical = (Value + 128) x -1 / 255
  int8_t   VEN_0004[7];                              // Usage 0xFFA10004: , Value = -128 to 127, Physical = (Value + 128) x -1 / 255
} inputReport_t;

//--------------------------------------------------------------------------------
// Vendor-defined outputReport (Device <-- Host)
//--------------------------------------------------------------------------------

typedef struct
{
                                                     // No REPORT ID byte
                                                     // Collection: CA: CP:
  int8_t   VEN_0005;                                 // Usage 0xFFA10005: , Value = -128 to 127, Physical = (Value + 128) x -1 / 255
  int8_t   VEN_0006[7];                              // Usage 0xFFA10006: , Value = -128 to 127, Physical = (Value + 128) x -1 / 255
} outputReport_t;
</code>```

As you can see, the above HID descriptor has some issues (for example, physical maximum 45 FF is -1, but I think they meant 255 - which should be represented as 46 FF 00) but the problem remains that it tells you nothing about the meaning of the usages. BTW, even Wireshark has not reported the logical minimum correctly: 15 80 is -128 not 128.

All we can tell from it is that the reports are 8-bytes long and that the first byte seems to be some kind of id (well, its usage is different from the remaining 7 bytes).

Only the vendor's driver knows how to interpret the reports, but with a sufficient number of Wireshark packet captures obtained under controlled conditions you may be able reverse engineer a workable interpretation.

Sorry, but that's the best I can do with this.

Body:
I have a Digital Sound Level Meter (sonometer) GM1356 with USB. There is some software to handle it on Windows, however I don't have CD and it's not available on the internet. What I want do to is to read it's data about current noise level on Linux.

I found already a library that allows me to do this in a language I know (ruby, libusb). In next step I installed wireshark to check out what it sends do the pc. It doesn't send too much. The most interesting packet I found is DESCRIPTOR HID Report. I wonder what next steps should I take to read data that is interesting for me. How can I determine what requests I should send to get it?

HID Report
    Global item (Usage)
        Header
            .... ..10 = bSize: 2 bytes (2)
            .... 01.. = bType: Global (1)
            0000 .... = bTag: Usage (0x0)
        Usage page: [Vendor-defined] (0xffa0)
    Local item (Usage)
        Header
            .... ..01 = bSize: 1 byte (1)
            .... 10.. = bType: Local (2)
            0000 .... = bTag: Usage (0x0)
        Usage: [Vendor-defined] (0xffa00001)
    Main item (Collection)
        Header
            .... ..01 = bSize: 1 byte (1)
            .... 00.. = bType: Main (0)
            1010 .... = bTag: Collection (0xa)
        Collection type: Application (0x01)
        Local item (Usage)
            Header
                .... ..01 = bSize: 1 byte (1)
                .... 10.. = bType: Local (2)
                0000 .... = bTag: Usage (0x0)
            Usage: [Vendor-defined] (0xffa00002)
        Main item (Collection)
            Header
                .... ..01 = bSize: 1 byte (1)
                .... 00.. = bType: Main (0)
                1010 .... = bTag: Collection (0xa)
            Collection type: Physical (0x00)
            Global item (Usage)
                Header
                    .... ..10 = bSize: 2 bytes (2)
                    .... 01.. = bType: Global (1)
                    0000 .... = bTag: Usage (0x0)
                Usage page: [Vendor-defined] (0xffa1)
            Local item (Usage)
                Header
                    .... ..01 = bSize: 1 byte (1)
                    .... 10.. = bType: Local (2)
                    0000 .... = bTag: Usage (0x0)
                Usage: [Vendor-defined] (0xffa10003)
            Local item (Usage)
                Header
                    .... ..01 = bSize: 1 byte (1)
                    .... 10.. = bType: Local (2)
                    0000 .... = bTag: Usage (0x0)
                Usage: [Vendor-defined] (0xffa10004)
            Global item (Logical minimum)
                Header
                    .... ..01 = bSize: 1 byte (1)
                    .... 01.. = bType: Global (1)
                    0001 .... = bTag: Logical minimum (0x1)
                Logical minimum: 128
            Global item (Logical maximum)
                Header
                    .... ..01 = bSize: 1 byte (1)
                    .... 01.. = bType: Global (1)
                    0010 .... = bTag: Logical maximum (0x2)
                Logical maximum: 127
            Global item (Physical minimum)
                Header
                    .... ..01 = bSize: 1 byte (1)
                    .... 01.. = bType: Global (1)
                    0011 .... = bTag: Physical minimum (0x3)
                Physical minimum: 0
            Global item (Physical maximum)
                Header
                    .... ..01 = bSize: 1 byte (1)
                    .... 01.. = bType: Global (1)
                    0100 .... = bTag: Physical maximum (0x4)
                Physical maximum: 255
            Global item (Report size)
                Header
                    .... ..01 = bSize: 1 byte (1)
                    .... 01.. = bType: Global (1)
                    0111 .... = bTag: Report size (0x7)
                Report size: 8
            Global item (Report count)
                Header
                    .... ..01 = bSize: 1 byte (1)
                    .... 01.. = bType: Global (1)
                    1001 .... = bTag: Report count (0x9)
                Report count: 8
            Main item (Input)
                Header
                    .... ..01 = bSize: 1 byte (1)
                    .... 00.. = bType: Main (0)
                    1000 .... = bTag: Input (0x8)
                .... .... 0 = Data/constant: Data
                .... ...1 . = Data type: Variable
                .... ..0. . = Coordinates: Absolute
                .... .0.. . = Min/max wraparound: No Wrap
                .... 0... . = Physical relationship to data: Linear
                ...0 .... . = Preferred state: Preferred State
                ..0. .... . = Has null position: No Null position
                .0.. .... . = [Reserved]: False
                0... .... . = Bits or bytes: Buffered bytes (default, no second byte present)
            Local item (Usage)
                Header
                    .... ..01 = bSize: 1 byte (1)
                    .... 10.. = bType: Local (2)
                    0000 .... = bTag: Usage (0x0)
                Usage: [Vendor-defined] (0xffa10005)
            Local item (Usage)
                Header
                    .... ..01 = bSize: 1 byte (1)
                    .... 10.. = bType: Local (2)
                    0000 .... = bTag: Usage (0x0)
                Usage: [Vendor-defined] (0xffa10006)
            Global item (Logical minimum)
                Header
                    .... ..01 = bSize: 1 byte (1)
                    .... 01.. = bType: Global (1)
                    0001 .... = bTag: Logical minimum (0x1)
                Logical minimum: 128
            Global item (Logical maximum)
                Header
                    .... ..01 = bSize: 1 byte (1)
                    .... 01.. = bType: Global (1)
                    0010 .... = bTag: Logical maximum (0x2)
                Logical maximum: 127
            Global item (Physical minimum)
                Header
                    .... ..01 = bSize: 1 byte (1)
                    .... 01.. = bType: Global (1)
                    0011 .... = bTag: Physical minimum (0x3)
                Physical minimum: 0
            Global item (Physical maximum)
                Header
                    .... ..01 = bSize: 1 byte (1)
                    .... 01.. = bType: Global (1)
                    0100 .... = bTag: Physical maximum (0x4)
                Physical maximum: 255
            Global item (Report size)
                Header
                    .... ..01 = bSize: 1 byte (1)
                    .... 01.. = bType: Global (1)
                    0111 .... = bTag: Report size (0x7)
                Report size: 8
            Global item (Report count)
                Header
                    .... ..01 = bSize: 1 byte (1)
                    .... 01.. = bType: Global (1)
                    1001 .... = bTag: Report count (0x9)
                Report count: 8
            Main item (Output)
                Header
                    .... ..01 = bSize: 1 byte (1)
                    .... 00.. = bType: Main (0)
                    1001 .... = bTag: Output (0x9)
                .... .... 0 = Data/constant: Data
                .... ...1 . = Data type: Variable
                .... ..0. . = Coordinates: Absolute
                .... .0.. . = Min/max wraparound: No Wrap
                .... 0... . = Physical relationship to data: Linear
                ...0 .... . = Preferred state: Preferred State
                ..0. .... . = Has null position: No Null position
                .0.. .... . = (Non)-volatile: Non Volatile
                0... .... . = Bits or bytes: Buffered bytes (default, no second byte present)
            Main item (End collection)
                Header
                    .... ..00 = bSize: 0 bytes (0)
                    .... 00.. = bType: Main (0)
                    1100 .... = bTag: End collection (0xc)
        Main item (End collection)
            Header
                .... ..00 = bSize: 0 bytes (0)
                .... 00.. = bType: Main (0)
                1100 .... = bTag: End collection (0xc)

Body:
When you decode the HID descriptor it will show the packet formats. Unfortunately, in this case the usage pages are vendor-defined so it is not possible to say exactly how each usage is to be interpreted.

I decoded it using hidrdd (disclaimer: I wrote it, but it is free open source so I have no conflict of interest) as:

//--------------------------------------------------------------------------------
// Decoded Application Collection
//--------------------------------------------------------------------------------

/*
06 A0FF      (GLOBAL) USAGE_PAGE         0xFFA0 Vendor-defined
09 01        (LOCAL)  USAGE              0xFFA00001 <-- Warning: Undocumented usage (document it by inserting 0001 into file FFA0.conf)
A1 01        (MAIN)   COLLECTION         0x01 Application (Usage=0xFFA00001: Page=Vendor-defined, Usage=, Type=) <-- Error: COLLECTION must be preceded by a known USAGE
09 02          (LOCAL)  USAGE              0xFFA00002 <-- Warning: Undocumented usage (document it by inserting 0002 into file FFA0.conf)
A1 00          (MAIN)   COLLECTION         0x00 Physical (Usage=0xFFA00002: Page=Vendor-defined, Usage=, Type=) <-- Error: COLLECTION must be preceded by a known USAGE
06 A1FF          (GLOBAL) USAGE_PAGE         0xFFA1 Vendor-defined
09 03            (LOCAL)  USAGE              0xFFA10003 <-- Warning: Undocumented usage (document it by inserting 0003 into file FFA1.conf)
09 04            (LOCAL)  USAGE              0xFFA10004 <-- Warning: Undocumented usage (document it by inserting 0004 into file FFA1.conf)
15 80            (GLOBAL) LOGICAL_MINIMUM    0x80 (-128)
25 7F            (GLOBAL) LOGICAL_MAXIMUM    0x7F (127)
35 00            (GLOBAL) PHYSICAL_MINIMUM   0x00 (0)  <-- Info: Consider replacing 35 00 with 34
45 FF            (GLOBAL) PHYSICAL_MAXIMUM   0xFF (-1)
75 08            (GLOBAL) REPORT_SIZE        0x08 (8) Number of bits per field
95 08            (GLOBAL) REPORT_COUNT       0x08 (8) Number of fields
81 02            (MAIN)   INPUT              0x00000002 (8 fields x 8 bits) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap  <-- Error: PHYSICAL_MAXIMUM (-1) is less than PHYSICAL_MINIMUM (0)
09 05            (LOCAL)  USAGE              0xFFA10005 <-- Warning: Undocumented usage (document it by inserting 0005 into file FFA1.conf)
09 06            (LOCAL)  USAGE              0xFFA10006 <-- Warning: Undocumented usage (document it by inserting 0006 into file FFA1.conf)
15 80            (GLOBAL) LOGICAL_MINIMUM    0x80 (-128) <-- Redundant: LOGICAL_MINIMUM is already -128
25 7F            (GLOBAL) LOGICAL_MAXIMUM    0x7F (127) <-- Redundant: LOGICAL_MAXIMUM is already 127
35 00            (GLOBAL) PHYSICAL_MINIMUM   0x00 (0) <-- Redundant: PHYSICAL_MINIMUM is already 0 <-- Info: Consider replacing 35 00 with 34
45 FF            (GLOBAL) PHYSICAL_MAXIMUM   0xFF (-1) <-- Redundant: PHYSICAL_MAXIMUM is already -1
75 08            (GLOBAL) REPORT_SIZE        0x08 (8) Number of bits per field <-- Redundant: REPORT_SIZE is already 8
95 08            (GLOBAL) REPORT_COUNT       0x08 (8) Number of fields <-- Redundant: REPORT_COUNT is already 8
91 02            (MAIN)   OUTPUT             0x00000002 (8 fields x 8 bits) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap  <-- Error: PHYSICAL_MAXIMUM (-1) is less than PHYSICAL_MINIMUM (0)
C0             (MAIN)   END_COLLECTION     Physical  <-- Warning: Physical units are still in effect PHYSICAL(MIN=0,MAX=-1) UNIT(0x,EXP=0)
C0           (MAIN)   END_COLLECTION     Application  <-- Warning: Physical units are still in effect PHYSICAL(MIN=0,MAX=-1) UNIT(0x,EXP=0)
*/

//--------------------------------------------------------------------------------
// Vendor-defined inputReport (Device --> Host)
//--------------------------------------------------------------------------------

typedef struct
{
                                                     // No REPORT ID byte
                                                     // Collection: CA: CP:
  int8_t   VEN_0003;                                 // Usage 0xFFA10003: , Value = -128 to 127, Physical = (Value + 128) x -1 / 255
  int8_t   VEN_0004[7];                              // Usage 0xFFA10004: , Value = -128 to 127, Physical = (Value + 128) x -1 / 255
} inputReport_t;

//--------------------------------------------------------------------------------
// Vendor-defined outputReport (Device <-- Host)
//--------------------------------------------------------------------------------

typedef struct
{
                                                     // No REPORT ID byte
                                                     // Collection: CA: CP:
  int8_t   VEN_0005;                                 // Usage 0xFFA10005: , Value = -128 to 127, Physical = (Value + 128) x -1 / 255
  int8_t   VEN_0006[7];                              // Usage 0xFFA10006: , Value = -128 to 127, Physical = (Value + 128) x -1 / 255
} outputReport_t;

As you can see, the above HID descriptor has some issues (for example, physical maximum 45 FF is -1, but I think they meant 255 - which should be represented as 46 FF 00) but the problem remains that it tells you nothing about the meaning of the usages. BTW, even Wireshark has not reported the logical minimum correctly: 15 80 is -128 not 128.

All we can tell from it is that the reports are 8-bytes long and that the first byte seems to be some kind of id (well, its usage is different from the remaining 7 bytes).

Only the vendor's driver knows how to interpret the reports, but with a sufficient number of Wireshark packet captures obtained under controlled conditions you may be able reverse engineer a workable interpretation.

Sorry, but that's the best I can do with this.


问:
How to show attendance below the same date in table using php?
I create a monthly attendance report of students. I want to show present  and absent below the same date.

```<code>  <?php foreach ($status as $st): ?>
  <?php
  $date = date("d",strtotime($st['ats_date']));
    if ($dat['en_id'] == $st['en_id']) {
      // if ($st['ats_date'] != NULL){
        for ($row=1; $row <= 31; $row++) {
        if ($row == $date) {
          // code...

        if ($st['ats_status'] == 'Present' ) {

          echo "<th> P </th>";
        }
        elseif ($st['ats_status'] == 'Absent' ) {
          echo "<th> A </th>";
        }
        elseif ($st['ats_status'] == 'Leave' ) {
          echo "<th> L </th>";
        }
        else {
          echo "<th> H </th>";
        }
        }
          // }
          }
      }
     ?>
  <?php endforeach; ?>

</code>```

I want this result

答:
A few things in your code:

1) Not every month has 31 days. So you should use the last day of the month you are displaying as end number:

$last_day = date('t', THE_MONTH_YOU_ARE_DISPLAYING );

2) The  tag is for table headers.  is for table cells

3) As for your question, you could use an array filled with empty table cells for the row:
   $array = array_fill( 1 , $last_day, '	');

then in your code, determine the day of the month from the date, replacing the empty cell with A, P, L or H.

```<code>//get last day of month as maximum
$last_day = date('t', $display-month );

//create empty array from 1 till last_day
$array = array_fill( 1 , $last_day, '<td></td>');

foreach ($status as $st){

    if ($dat['en_id'] == $st['en_id']) {
       //get the date of the record
       $day = date("d",strtotime($st['ats_date']));

       //determine the status
       if ($st['ats_status'] == 'Present' )$status = 'P'
       elseif ($st['ats_status'] == 'Absent' )$status = 'A'
       elseif ($st['ats_status'] == 'Leave' )$status = 'L';
       else $status = 'H';

       //replace the value on the exact day in the array with the status
       $array[ $day ]='<td>'.$status.'</td>';
       }
//create table row
$student_status='<tr>'.implode('',$student_array).'</tr>';
echo $student_status;
</code>```

NOTE: Code is not tested.

Body:
I create a monthly attendance report of students. I want to show present  and absent below the same date.

  <?php foreach ($status as $st): ?>
  <?php
  $date = date("d",strtotime($st['ats_date']));
    if ($dat['en_id'] == $st['en_id']) {
      // if ($st['ats_date'] != NULL){
        for ($row=1; $row <= 31; $row++) {
        if ($row == $date) {
          // code...

        if ($st['ats_status'] == 'Present' ) {

          echo " P 	";
        }
        elseif ($st['ats_status'] == 'Absent' ) {
          echo " A 	";
        }
        elseif ($st['ats_status'] == 'Leave' ) {
          echo " L 	";
        }
        else {
          echo " H 	";
        }
        }
          // }
          }
      }
     ?>
  <?php endforeach; ?>

I want this result

Body:
A few things in your code:

1) Not every month has 31 days. So you should use the last day of the month you are displaying as end number:

$last_day = date('t', THE_MONTH_YOU_ARE_DISPLAYING );

2) The <th> tag is for table headers. <td> is for table cells

3) As for your question, you could use an array filled with empty table cells for the row:
   $array = array_fill( 1 , $last_day, '<td></td>');

then in your code, determine the day of the month from the date, replacing the empty cell with A, P, L or H.

//get last day of month as maximum
$last_day = date('t', $display-month );

//create empty array from 1 till last_day
$array = array_fill( 1 , $last_day, '<td></td>');

foreach ($status as $st){

    if ($dat['en_id'] == $st['en_id']) {
       //get the date of the record
       $day = date("d",strtotime($st['ats_date']));

       //determine the status
       if ($st['ats_status'] == 'Present' )$status = 'P'
       elseif ($st['ats_status'] == 'Absent' )$status = 'A'
       elseif ($st['ats_status'] == 'Leave' )$status = 'L';
       else $status = 'H';

       //replace the value on the exact day in the array with the status
       $array[ $day ]='<td>'.$status.'</td>';
       }
//create table row
$student_status='<tr>'.implode('',$student_array).'</tr>';
echo $student_status;

NOTE: Code is not tested.


问:
I am trying to dial secret code like *#*#0808#*#* on keypad dialer from adb shell
I want to dial a number through the android dialer which opens the keypad/dialer and dials the number using adb commands.

I tried to dial the number using this adb shell commands:

adb shell am start -a android.intent.action.CALL -d tel:*#*#0808#*#*

But that dials the number OTA as an MMI code, and that is not what we want.

I am told that the code ##0808## is a secret code that launches a hidden menu, and that it must be dialled through the dialler.

I found out that the command:

adb shell monkey -p com.android.dialer -c android.intent.category.LAUNCHER 1

launches the phone app (but not the num keypad).

So, then I tried to dial it using the commands:

adb shell monkey -p com.android.dialer/com.android.incallui.InCallActivity -c android.intent.category.LAUNCHER 1 *#*#0808#*#*

but that didn't work.

Could someone help why it isn't working? and How could I launch the dialer and dial that number?

Thanks!

答:
What exactly are you trying to reach? These code are called USSD codes (try google Android USSD codes). And they are different on every device. Ok, some of them are working on most of the phones, but it's not rule. Please be very careful with these codes since some of them can do factory reset or set-up your device improperly.

When executing these codes via adb, you need to url encode them (check https://www.degraeve.com/reference/urlencoding.php), so * is %2A and # is %23 In your case:

```<code>adb shell am start -a android.intent.action.CALL -d tel:%2A%23%2A%230808%23%2A%23%2A
</code>```

But if the code doesn't work for you when inserted via dialer, this will not work neither.
I try your code on my Sony Xperia Z5 with Android 6.0 and it didn't work :-(

BTW usb setting can be accessed via Settings>Developer Options>USB Configuration

Body:
What exactly are you trying to reach? These code are called USSD codes (try google Android USSD codes). And they are different on every device. Ok, some of them are working on most of the phones, but it's not rule. Please be very careful with these codes since some of them can do factory reset or set-up your device improperly.

When executing these codes via adb, you need to url encode them (check https://www.degraeve.com/reference/urlencoding.php), so * is %2A and # is %23 In your case:

adb shell am start -a android.intent.action.CALL -d tel:%2A%23%2A%230808%23%2A%23%2A

But if the code doesn't work for you when inserted via dialer, this will not work neither.
I try your code on my Sony Xperia Z5 with Android 6.0 and it didn't work :-(

BTW usb setting can be accessed via Settings>Developer Options>USB Configuration


问:
java.io.NotSerializableException
We are getting the following error in our clustered QA environment. We run Weblogic 10.3.3.0 on linux.

```<code>####<Mar 29, 2011 3:59:54 PM CDT> <Error> <Cluster> <app2.qa.server.com> <qa_app2j> <[ACTIVE] ExecuteThread: '1' for queue: 'weblogic.kernel.Default (self-tuning)'> <<anonymous>> <1301432394933> <BEA-000126> <All session objects should be serializable to replicate. Check the objects in your session. Failed to replicate non-serializable object.
java.rmi.MarshalException: failed to marshal update(Lweblogic.cluster.replication.ROID;ILjava.io.Serializable;Ljava.lang.Object;); nested exception is:
java.io.NotSerializableException: com.tjf.admin.virtualFair.Job$1
at weblogic.rjvm.BasicOutboundRequest.marshalArgs(BasicOutboundRequest.java:92)
at weblogic.rmi.internal.BasicRemoteRef.invoke(BasicRemoteRef.java:221)
at weblogic.cluster.replication.ReplicationManager_1033_WLStub.update(Unknown Source)
at sun.reflect.GeneratedMethodAccessor15419.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at weblogic.cluster.replication.SecureReplicationInvocationHandler$ReplicationServicesInvocationAction.run(SecureReplicationInvocationHandler.java:184)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:121)
at weblogic.cluster.replication.SecureReplicationInvocationHandler.invoke(SecureReplicationInvocationHandler.java:154)
at $Proxy98.update(Unknown Source)
at weblogic.cluster.replication.ReplicationManager.updateSecondary(ReplicationManager.java:535)
at weblogic.servlet.internal.session.ReplicatedSessionData.syncSession(ReplicatedSessionData.java:594)
at weblogic.servlet.internal.session.ReplicatedSessionContext.sync(ReplicatedSessionContext.java:85)
at weblogic.servlet.internal.ServletRequestImpl$SessionHelper.syncSession(ServletRequestImpl.java:2810)
at weblogic.servlet.internal.ServletRequestImpl$SessionHelper.syncSession(ServletRequestImpl.java:2785)
at weblogic.servlet.internal.ServletResponseImpl$1.run(ServletResponseImpl.java:1480)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:121)
at weblogic.servlet.internal.ServletResponseImpl.send(ServletResponseImpl.java:1474)
at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1455)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:201)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:173)
</code>```

Here is the java file that is causing this:

```<code>package com.tjf.admin.virtualFair;

import com.tjf.TargetedJobFairsConstants;
import com.tjf.util.TargetedJobFairsToolBox;
import org.apache.log4j.Logger;

import java.io.Serializable;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Comparator;
import java.util.TreeMap;

public class Job implements Serializable {
protected int id;
protected String name;
protected String description;
protected int companyId;
protected String hash;

private static Logger logger = initializeLogger();

protected static Logger initializeLogger() {
Logger logger = Logger.getLogger(TargetedJobFairsConstants.TJF_LOG4J_NAME);
logger.info("logger initialized!");
return logger;
}
public Job(String name, String description, int companyId) {
this.name = name;
this.description = description;
this.companyId = companyId;
}

public Job(int id, String name, String description, int companyId) {
this.id = id;
this.name = name;
this.description = description;
this.companyId = companyId;
}

public Job(String name, String description) {
this.name = name;
this.description = description;
this.companyId = companyId;
}

public String getHash() {
if (id != -1 && name != null && !name.equals("")) {
return TargetedJobFairsToolBox.createHash(name, "" + id);
} else {
return null;
}
}

public int getCompanyId() {
return companyId;
}

public void setCompanyId(int companyId) {
this.companyId = companyId;
}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getDescription() {
return description;
}

public void setDescription(String description) {
this.description = description;
}

public static boolean validateName(String name, StringBuffer message) {
if (name != null && !name.trim().equals("")) {
// check for duplicated Virtual Fair Company Name
return true;
} else {
if (message.length() > 0) {
message.append(", Name ");
} else {
message.append(" Name ");
}
return false;
}
}

public static boolean validateDescription(String description, StringBuffer message) {
if (description != null && !description.trim().equals("")) {
return true;
} else {
if (message.length() > 0) {
message.append(", Description ");
} else {
message.append(" Description ");
}
return false;
}
}

public static boolean validateCompanyIDString(String companyID, StringBuffer message) {
if (companyID != null && !companyID.trim().equals("")) {
return true;
} else {
if (message.length() > 0) {
message.append(", unknown virtual fair error(32) ");
} else {
message.append(" unknown virtual fair error(32) ");
}
return false;
}
}

protected boolean insertJob(Connection tjfConn, StringBuffer message) {
PreparedStatement insertJobStmt = null;
String insertJobSQL = null;

try {
insertJobSQL = "insert into VIRTUAL_FAIR_JOB ( NAME, DESCRIPTION, COMPANY_ID ) " +
"values (?, ?, ?) ";

insertJobStmt = tjfConn.prepareStatement(insertJobSQL);
insertJobStmt.setString(1, this.name);
insertJobStmt.setString(2, this.description);
insertJobStmt.setInt(3, this.companyId);

insertJobStmt.executeUpdate();
message.append(" Job \"" + this.name + "\" was successfully created.");
return true;
} catch (Exception x) {
logger.error(x, x);
if (message.length() > 0) {
message.append(", unknown virtual fair error(33) ");
} else {
message.append(" unknown virtual fair error(33) ");
}
return false;
}
}

protected boolean updateJob(Connection tjfConn, StringBuffer message) {
PreparedStatement insertJobStmt = null;
String insertJobSQL = null;

try {
insertJobSQL = "update VIRTUAL_FAIR_JOB set NAME = ?, DESCRIPTION = ? where" +
" COMPANY_ID = ? and ID = ?";

insertJobStmt = tjfConn.prepareStatement(insertJobSQL);
insertJobStmt.setString(1, this.name);
insertJobStmt.setString(2, this.description);
insertJobStmt.setInt(3, this.companyId);
insertJobStmt.setInt(4, this.id);

insertJobStmt.executeUpdate();
message.append(" Job \"" + this.name + "\" was successfully updated.");
return true;
} catch (Exception x) {
logger.error(x, x);
if (message.length() > 0) {
message.append(", unknown virtual fair error(34) ");
} else {
message.append(" unknown virtual fair error(34) ");
}
return false;
}
}

public static boolean deleteJobByCompanyID(Connection tjfConn, int companyID, StringBuffer message) {
PreparedStatement deleteJobStmt = null;
String deleteJobSQL = null;

try {
deleteJobSQL = "delete from VIRTUAL_FAIR_JOB where " +
" COMPANY_ID = ? ";

deleteJobStmt = tjfConn.prepareStatement(deleteJobSQL);
deleteJobStmt.setInt(1, companyID);

deleteJobStmt.executeUpdate();
message.append(" Jobs were successfully deleted.");
return true;
} catch (Exception x) {
logger.error(x, x);
if (message.length() > 0) {
message.append(", unknown virtual fair error(35) ");
} else {
message.append(" unknown virtual fair error(35) ");
}
return false;
}
}

public static boolean deleteJob(Connection tjfConn, int jobID, int companyID, StringBuffer message) {
PreparedStatement deleteJobStmt = null;
String deleteJobSQL = null;

try {
deleteJobSQL = "delete from VIRTUAL_FAIR_JOB where " +
" COMPANY_ID = ? and ID = ? ";

deleteJobStmt = tjfConn.prepareStatement(deleteJobSQL);
deleteJobStmt.setInt(1, companyID);
deleteJobStmt.setInt(2, jobID);

deleteJobStmt.executeUpdate();
message.append(" Job was successfully deleted.");
return true;
} catch (Exception x) {
logger.error(x, x);
if (message.length() > 0) {
message.append(", unknown virtual fair error(36) ");
} else {
message.append(" unknown virtual fair error(36) ");
}
return false;
}
}

public static TreeMap<Job, Integer> getJobListforCompany(Connection tjfConn, int companyID, StringBuffer message) {
TreeMap<Job, Integer> jobsList = new TreeMap<Job, Integer>(new Comparator() {
public int compare(Object job, Object anotherJob) {
String name1 = ((Job) job).getName();
String name2 = ((Job) anotherJob).getName();
return name1.toLowerCase().compareTo(name2.toLowerCase());
}
});
PreparedStatement getJobListStmt = null;
String getJobListSQL = null;
ResultSet getJobListRset = null;
try {
getJobListSQL = "select ID, NAME, DESCRIPTION, COMPANY_ID from VIRTUAL_FAIR_JOB where COMPANY_ID = ?";
getJobListStmt = tjfConn.prepareStatement(getJobListSQL);
getJobListStmt.setInt(1, companyID);
getJobListRset = getJobListStmt.executeQuery();

while (getJobListRset.next()) {
Job holdJob = new Job(getJobListRset.getInt(1),
getJobListRset.getString(2),
getJobListRset.getString(3),
getJobListRset.getInt(4));
jobsList.put(holdJob, holdJob.id);
}
return jobsList;
} catch (Exception x) {
logger.error(x, x);
if (message.length() > 0) {
message.append(", unknown virtual fair error(37) ");
} else {
message.append(" unknown virtual fair error(37) ");
}
return null;
}
}

public static Job getJobByID(Connection tjfConn, int jobID, StringBuffer message) {

PreparedStatement getJobListStmt = null;
String getJobListSQL = null;
ResultSet getJobListRset = null;
try {
getJobListSQL = "select ID, NAME, DESCRIPTION, COMPANY_ID from VIRTUAL_FAIR_JOB where ID = ?";
getJobListStmt = tjfConn.prepareStatement(getJobListSQL);
getJobListStmt.setInt(1, jobID);
getJobListRset = getJobListStmt.executeQuery();

Job holdJob = null;
if (getJobListRset.next()) {
holdJob = new Job(getJobListRset.getInt(1),
getJobListRset.getString(2),
getJobListRset.getString(3),
getJobListRset.getInt(4));
}
return holdJob;
} catch (Exception x) {
logger.error(x, x);
if (message.length() > 0) {
message.append(", unknown virtual fair error(38) ");
} else {
message.append(" unknown virtual fair error(38) ");
}
return null;
}
}
}
</code>```

What might cause this?

答:
It's the Comparator that's created on this line:

```<code>TreeMap<Job, Integer> jobsList = new TreeMap<Job, Integer>(new Comparator() {
</code>```

At least, I think it is, because the $1 in the stacktrace usually indicates an inner class, and that's the only inner class I can see. Plus, I believe creating it like that would make the TreeMap non-serializable (because it wants to serialize the comparator).

Instead of making it an anonymous class, declare it separately, and make it implement java.io.Serializable.

ContentLicense: CC BY-SA 3.0

Title: java.io.NotSerializableException

Body:
We are getting the following error in our clustered QA environment. We run Weblogic 10.3.3.0 on linux.

####<Mar 29, 2011 3:59:54 PM CDT> <Error> <Cluster> <app2.qa.server.com> <qa_app2j> <[ACTIVE] ExecuteThread: '1' for queue: 'weblogic.kernel.Default (self-tuning)'> <<anonymous>> <1301432394933> <BEA-000126> <All session objects should be serializable to replicate. Check the objects in your session. Failed to replicate non-serializable object.
java.rmi.MarshalException: failed to marshal update(Lweblogic.cluster.replication.ROID;ILjava.io.Serializable;Ljava.lang.Object;); nested exception is:
java.io.NotSerializableException: com.tjf.admin.virtualFair.Job$1
at weblogic.rjvm.BasicOutboundRequest.marshalArgs(BasicOutboundRequest.java:92)
at weblogic.rmi.internal.BasicRemoteRef.invoke(BasicRemoteRef.java:221)
at weblogic.cluster.replication.ReplicationManager_1033_WLStub.update(Unknown Source)
at sun.reflect.GeneratedMethodAccessor15419.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at weblogic.cluster.replication.SecureReplicationInvocationHandler$ReplicationServicesInvocationAction.run(SecureReplicationInvocationHandler.java:184)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:121)
at weblogic.cluster.replication.SecureReplicationInvocationHandler.invoke(SecureReplicationInvocationHandler.java:154)
at $Proxy98.update(Unknown Source)
at weblogic.cluster.replication.ReplicationManager.updateSecondary(ReplicationManager.java:535)
at weblogic.servlet.internal.session.ReplicatedSessionData.syncSession(ReplicatedSessionData.java:594)
at weblogic.servlet.internal.session.ReplicatedSessionContext.sync(ReplicatedSessionContext.java:85)
at weblogic.servlet.internal.ServletRequestImpl$SessionHelper.syncSession(ServletRequestImpl.java:2810)
at weblogic.servlet.internal.ServletRequestImpl$SessionHelper.syncSession(ServletRequestImpl.java:2785)
at weblogic.servlet.internal.ServletResponseImpl$1.run(ServletResponseImpl.java:1480)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:121)
at weblogic.servlet.internal.ServletResponseImpl.send(ServletResponseImpl.java:1474)
at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1455)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:201)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:173)

Here is the java file that is causing this:

package com.tjf.admin.virtualFair;

import com.tjf.TargetedJobFairsConstants;
import com.tjf.util.TargetedJobFairsToolBox;
import org.apache.log4j.Logger;

import java.io.Serializable;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Comparator;
import java.util.TreeMap;

public class Job implements Serializable {
protected int id;
protected String name;
protected String description;
protected int companyId;
protected String hash;

private static Logger logger = initializeLogger();

protected static Logger initializeLogger() {
Logger logger = Logger.getLogger(TargetedJobFairsConstants.TJF_LOG4J_NAME);
logger.info("logger initialized!");
return logger;
}
public Job(String name, String description, int companyId) {
this.name = name;
this.description = description;
this.companyId = companyId;
}

public Job(int id, String name, String description, int companyId) {
this.id = id;
this.name = name;
this.description = description;
this.companyId = companyId;
}

public Job(String name, String description) {
this.name = name;
this.description = description;
this.companyId = companyId;
}

public String getHash() {
if (id != -1 && name != null && !name.equals("")) {
return TargetedJobFairsToolBox.createHash(name, "" + id);
} else {
return null;
}
}

public int getCompanyId() {
return companyId;
}

public void setCompanyId(int companyId) {
this.companyId = companyId;
}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getDescription() {
return description;
}

public void setDescription(String description) {
this.description = description;
}

public static boolean validateName(String name, StringBuffer message) {
if (name != null && !name.trim().equals("")) {
// check for duplicated Virtual Fair Company Name
return true;
} else {
if (message.length() > 0) {
message.append(", Name ");
} else {
message.append(" Name ");
}
return false;
}
}

public static boolean validateDescription(String description, StringBuffer message) {
if (description != null && !description.trim().equals("")) {
return true;
} else {
if (message.length() > 0) {
message.append(", Description ");
} else {
message.append(" Description ");
}
return false;
}
}

public static boolean validateCompanyIDString(String companyID, StringBuffer message) {
if (companyID != null && !companyID.trim().equals("")) {
return true;
} else {
if (message.length() > 0) {
message.append(", unknown virtual fair error(32) ");
} else {
message.append(" unknown virtual fair error(32) ");
}
return false;
}
}

protected boolean insertJob(Connection tjfConn, StringBuffer message) {
PreparedStatement insertJobStmt = null;
String insertJobSQL = null;

try {
insertJobSQL = "insert into VIRTUAL_FAIR_JOB ( NAME, DESCRIPTION, COMPANY_ID ) " +
"values (?, ?, ?) ";

insertJobStmt = tjfConn.prepareStatement(insertJobSQL);
insertJobStmt.setString(1, this.name);
insertJobStmt.setString(2, this.description);
insertJobStmt.setInt(3, this.companyId);

insertJobStmt.executeUpdate();
message.append(" Job \"" + this.name + "\" was successfully created.");
return true;
} catch (Exception x) {
logger.error(x, x);
if (message.length() > 0) {
message.append(", unknown virtual fair error(33) ");
} else {
message.append(" unknown virtual fair error(33) ");
}
return false;
}
}

protected boolean updateJob(Connection tjfConn, StringBuffer message) {
PreparedStatement insertJobStmt = null;
String insertJobSQL = null;

try {
insertJobSQL = "update VIRTUAL_FAIR_JOB set NAME = ?, DESCRIPTION = ? where" +
" COMPANY_ID = ? and ID = ?";

insertJobStmt = tjfConn.prepareStatement(insertJobSQL);
insertJobStmt.setString(1, this.name);
insertJobStmt.setString(2, this.description);
insertJobStmt.setInt(3, this.companyId);
insertJobStmt.setInt(4, this.id);

insertJobStmt.executeUpdate();
message.append(" Job \"" + this.name + "\" was successfully updated.");
return true;
} catch (Exception x) {
logger.error(x, x);
if (message.length() > 0) {
message.append(", unknown virtual fair error(34) ");
} else {
message.append(" unknown virtual fair error(34) ");
}
return false;
}
}

public static boolean deleteJobByCompanyID(Connection tjfConn, int companyID, StringBuffer message) {
PreparedStatement deleteJobStmt = null;
String deleteJobSQL = null;

try {
deleteJobSQL = "delete from VIRTUAL_FAIR_JOB where " +
" COMPANY_ID = ? ";

deleteJobStmt = tjfConn.prepareStatement(deleteJobSQL);
deleteJobStmt.setInt(1, companyID);

deleteJobStmt.executeUpdate();
message.append(" Jobs were successfully deleted.");
return true;
} catch (Exception x) {
logger.error(x, x);
if (message.length() > 0) {
message.append(", unknown virtual fair error(35) ");
} else {
message.append(" unknown virtual fair error(35) ");
}
return false;
}
}

public static boolean deleteJob(Connection tjfConn, int jobID, int companyID, StringBuffer message) {
PreparedStatement deleteJobStmt = null;
String deleteJobSQL = null;

try {
deleteJobSQL = "delete from VIRTUAL_FAIR_JOB where " +
" COMPANY_ID = ? and ID = ? ";

deleteJobStmt = tjfConn.prepareStatement(deleteJobSQL);
deleteJobStmt.setInt(1, companyID);
deleteJobStmt.setInt(2, jobID);

deleteJobStmt.executeUpdate();
message.append(" Job was successfully deleted.");
return true;
} catch (Exception x) {
logger.error(x, x);
if (message.length() > 0) {
message.append(", unknown virtual fair error(36) ");
} else {
message.append(" unknown virtual fair error(36) ");
}
return false;
}
}

public static TreeMap<Job, Integer> getJobListforCompany(Connection tjfConn, int companyID, StringBuffer message) {
TreeMap<Job, Integer> jobsList = new TreeMap<Job, Integer>(new Comparator() {
public int compare(Object job, Object anotherJob) {
String name1 = ((Job) job).getName();
String name2 = ((Job) anotherJob).getName();
return name1.toLowerCase().compareTo(name2.toLowerCase());
}
});
PreparedStatement getJobListStmt = null;
String getJobListSQL = null;
ResultSet getJobListRset = null;
try {
getJobListSQL = "select ID, NAME, DESCRIPTION, COMPANY_ID from VIRTUAL_FAIR_JOB where COMPANY_ID = ?";
getJobListStmt = tjfConn.prepareStatement(getJobListSQL);
getJobListStmt.setInt(1, companyID);
getJobListRset = getJobListStmt.executeQuery();

while (getJobListRset.next()) {
Job holdJob = new Job(getJobListRset.getInt(1),
getJobListRset.getString(2),
getJobListRset.getString(3),
getJobListRset.getInt(4));
jobsList.put(holdJob, holdJob.id);
}
return jobsList;
} catch (Exception x) {
logger.error(x, x);
if (message.length() > 0) {
message.append(", unknown virtual fair error(37) ");
} else {
message.append(" unknown virtual fair error(37) ");
}
return null;
}
}

public static Job getJobByID(Connection tjfConn, int jobID, StringBuffer message) {

PreparedStatement getJobListStmt = null;
String getJobListSQL = null;
ResultSet getJobListRset = null;
try {
getJobListSQL = "select ID, NAME, DESCRIPTION, COMPANY_ID from VIRTUAL_FAIR_JOB where ID = ?";
getJobListStmt = tjfConn.prepareStatement(getJobListSQL);
getJobListStmt.setInt(1, jobID);
getJobListRset = getJobListStmt.executeQuery();

Job holdJob = null;
if (getJobListRset.next()) {
holdJob = new Job(getJobListRset.getInt(1),
getJobListRset.getString(2),
getJobListRset.getString(3),
getJobListRset.getInt(4));
}
return holdJob;
} catch (Exception x) {
logger.error(x, x);
if (message.length() > 0) {
message.append(", unknown virtual fair error(38) ");
} else {
message.append(" unknown virtual fair error(38) ");
}
return null;
}
}
}

What might cause this?

Body:
It's the Comparator that's created on this line:

TreeMap<Job, Integer> jobsList = new TreeMap<Job, Integer>(new Comparator() {

At least, I think it is, because the $1 in the stacktrace usually indicates an inner class, and that's the only inner class I can see. Plus, I believe creating it like that would make the TreeMap non-serializable (because it wants to serialize the comparator).

Instead of making it an anonymous class, declare it separately, and make it implement java.io.Serializable.


问:
Best Clustering Algorithm for High Dimensional Vectors
I am attempting to use some sort of clustering method on a set of datapoint vectors which have 45 dimensions. I'm fairly new to clustering data points and was wondering if anyone could point out appropriate methods to utilize? I was attempted using K-Means Clustering but was wondering if the dimensionality of my data might be too large for this?</p>

答:
Complexity of K-means clustering is O(qknp), where q is the number of iterations, k is the number of clusters, n is the sample size, and p is the dimensionality.

You probably don't want to change k.

Most of the time q is determined during the execution of the K-Means algorithm, It stops when cluster-means stop changing.

Most of the time you want to use all of your data, but you may reduce your sample size, this will decrease accuracy of your results.

You may reduce dimensions of your data by using principal component analysis. This results in some(little in most cases) information loss. which effects your results.


问:
After implementing background location updates FCM gone mad and are sent continuously without programmed trigger
I am creating simple chat app using Firebase. My database has node for messages, and when user gets message from another user - cloud function monitors changes and sends firebase cloud message to user's token. UNUserNotificationCenterDelegate was properly implemented in AppDelegate.
Everything worked fine until I began to implement background location updates with CoreLocation locationManager.startUpdatingLocation() method. I instantiate locationManager also in AppDelegate.
My app saves current location to UserDefaults(), then updates location, compares it to saved location in UserDefaults and if it is far from saved location or was not saved to database for certain period of time, current location is saved to Firebase database and is updated at UserDefaults().
After running app I started to get notifications from Firebase (both in foreground and in background) which are last 5-8 (then up to 58 at a time) messages that user got new message.

I tried to understand what triggers these FCMs but only could print notification.description to console

I tried
     func applicationDidBecomeActive(_ application: UIApplication) {
            // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
                UNUserNotificationCenter.current().removeAllPendingNotificationRequests()
            UNUserNotificationCenter.current().removeAllDeliveredNotifications()
    }

but it didn't work

```<code>import UIKit
import Firebase
import UserNotifications
import GoogleMobileAds
import CoreLocation

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate, MessagingDelegate {

    var window: UIWindow?
   lazy var locationManager: CLLocationManager = {
        let locationManager = CLLocationManager()
        locationManager.delegate = self
        locationManager.desiredAccuracy = kCLLocationAccuracyBest
        locationManager.allowsBackgroundLocationUpdates = true
        return locationManager
    }()

    var currentLocation: CLLocation?
    var defaults = UserDefaults.standard
    var geocoder = CLGeocoder()

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        window = UIWindow(frame: UIScreen.main.bounds)
        window?.makeKeyAndVisible()
        FirebaseApp.configure()

        self.startLocationService()
        locationManager.startUpdatingLocation()

        self.registerForPushNotifications()

        Messaging.messaging().delegate = self

        return true
    }

    func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) {

        let dataDict:[String: String] = ["token": fcmToken]
        NotificationCenter.default.post(name: Notification.Name("FCMToken"), object: nil, userInfo: dataDict)
    }

    func applicationDidBecomeActive(_ application: UIApplication) {
        UNUserNotificationCenter.current().removeAllPendingNotificationRequests(    )

UNUserNotificationCenter.current().removeAllDeliveredNotifications()
    }

    func registerForPushNotifications() {
        let notificationCenter = UNUserNotificationCenter.current()
        notificationCenter.delegate = self
        notificationCenter.requestAuthorization(options: [.alert, .sound, .badge]) {
            (granted, error) in
            guard granted else { return }
            self.getNotificationSettings()
        }
    }

    func getNotificationSettings() {
        UNUserNotificationCenter.current().getNotificationSettings { (settings) in
            guard settings.authorizationStatus == .authorized else { return }
            DispatchQueue.main.async {
                UIApplication.shared.registerForRemoteNotifications()
            }
        }
    }

    func application(_ application: UIApplication,
                 didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        let tokenParts = deviceToken.map { data -> String in
            return String(format: "%02.2hhx", data)
        }
        print("Registered with device token \(tokenParts.joined())")

    }

    func application(_ application: UIApplication,
                 didFailToRegisterForRemoteNotificationsWithError error: Error) {
        print("Failed to register: \(error.localizedDescription)")
    }

    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {

        print("notification is \(notification.description)")

       completionHandler([.sound])

    }

    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
        print("Received notification \(response.notification)")

    }

    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {

        if application.applicationState == .active {
            application.applicationIconBadgeNumber = 0
        } else {
            let numberOfUnreadMessages = userInfo["count"] as! String
            if let badgeNumber = Int(numberOfUnreadMessages) {
                application.applicationIconBadgeNumber = badgeNumber
            }

            completionHandler(UIBackgroundFetchResult.newData)
        }
    }
}

extension AppDelegate: CLLocationManagerDelegate {

    func startLocationService() {
        print("Starting location services in AppDelegate")
        if CLLocationManager.authorizationStatus() == .authorizedAlways || CLLocationManager.authorizationStatus() == .authorizedWhenInUse {

            activateLocationServices()

        } else {
            locationManager.requestAlwaysAuthorization()
        }
    }

    private func activateLocationServices() {
        if UIApplication.shared.applicationState == .active {
            locationManager.startUpdatingLocation()
        } else {
            locationManager.startMonitoringSignificantLocationChanges()
        }
    }

    func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
        if status == .authorizedAlways || status == .authorizedWhenInUse {
            activateLocationServices()
        } else {
            print("CLAuthorizationStatus is notDetermined")
        }
    }

    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
        print("error happened while getting current location: \(error.localizedDescription)")
    }

    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        currentLocation = locations.first
        print("AppDelegate got location")

        if defaults.value(forKey: "currentLatitude") == nil {
            let currentLatitude = currentLocation?.coordinate.latitude
            let currentLongtitude = currentLocation?.coordinate.longitude
            let currentAltitude = currentLocation?.altitude
            let timeStamp: Double = Double(Int(NSDate().timeIntervalSince1970))

            defaults.set(currentLatitude, forKey: "currentLatitude")
            defaults.set(currentLongtitude, forKey: "currentLongtitude")
            defaults.set(currentAltitude, forKey: "currentAltitude")
            defaults.set(timeStamp, forKey: "locationUpdated")
            print("UserDefaults updated with current location")
        }

        saveLocationToDatabase()

    }

    func saveLocationToDatabase() {

        var previousLocation: CLLocation?
        var previuosTime: Double?

        guard let currentLocation = currentLocation, let currentUserUid = defaults.string(forKey: "uid") else { return }

        let previousLatitude = defaults.double(forKey: "currentLatitude")
        let previousLongtitude = defaults.double(forKey: "currentLongtitude")
        previuosTime = defaults.double(forKey: "locationUpdated")

        previousLocation = CLLocation(latitude: previousLatitude, longitude: previousLongtitude)
        let timeStamp: Double = Double(Int(NSDate().timeIntervalSince1970))

        if previousLocation != nil && previuosTime != nil {
            let distance = currentLocation.distance(from: previousLocation!)
            let time =  timeStamp - previuosTime!

            if distance < 100 && time < 60 {
                print("distance is \(distance), time is \(time)")
                print("No need to save location")
                return
            } else {
                self.saveChangesToDatabase()
            }
        } else {
            self.saveChangesToDatabase()
        }
    }

    func saveChangesToDatabase() {
        guard let currentLocation = currentLocation, let currentUserUid = defaults.string(forKey: "uid") else { return }
        let usersRef = Database.database().reference().child("users").child(currentUserUid)
        usersRef.child("location").child("latitude").setValue(currentLocation.coordinate.latitude)
        usersRef.child("location").child("longtitude").setValue(currentLocation.coordinate.longitude)
        usersRef.child("location").child("altitude").setValue(currentLocation.altitude)
        let timeToSet: NSNumber = NSNumber(value: Int(NSDate().timeIntervalSince1970))
        usersRef.child("location").child("updated").setValue(timeToSet)

        print("Location saved to database")

        defaults.set(currentLocation.coordinate.latitude, forKey: "currentLatitude")
        defaults.set(currentLocation.coordinate.longitude, forKey: "currentLongtitude")
        defaults.set(currentLocation.altitude, forKey: "currentAltitude")
        defaults.set(timeToSet, forKey: "locationUpdated")
        print("UserDefaults updated with current location")

        self.geocoder.reverseGeocodeLocation(currentLocation) { (placemarks, error) in
            if let error = error {
                print(error.localizedDescription)
                return
            }
            guard let placemark = placemarks?.first else { return }
            if let city = placemark.locality, let state = placemark.administrativeArea {
                let currentPlace = "\(city), \(state)"
                usersRef.child("location").child("currentPlace").setValue(currentPlace)
            }
        }
    }

}
</code>```

My console is:

AppDelegate got location
distance is 0.00017503746557926585, time is 58.0
No need to save location
AppDelegate got location
Location saved to database
UserDefaults updated with current location
notification is ,, trigger: >>
notification is ,, trigger: >>

and so on....

答: The problem is completely in Firebase Cloud Functions and it has nothing to do with CoreLocation services</p>

Body:
I am creating simple chat app using Firebase. My database has node for messages, and when user gets message from another user - cloud function monitors changes and sends firebase cloud message to user's token. UNUserNotificationCenterDelegate was properly implemented in AppDelegate.
Everything worked fine until I began to implement background location updates with CoreLocation locationManager.startUpdatingLocation() method. I instantiate locationManager also in AppDelegate.
My app saves current location to UserDefaults(), then updates location, compares it to saved location in UserDefaults and if it is far from saved location or was not saved to database for certain period of time, current location is saved to Firebase database and is updated at UserDefaults().
After running app I started to get notifications from Firebase (both in foreground and in background) which are last 5-8 (then up to 58 at a time) messages that user got new message.

I tried to understand what triggers these FCMs but only could print notification.description to console

I tried
     func applicationDidBecomeActive(_ application: UIApplication) {
            // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
                UNUserNotificationCenter.current().removeAllPendingNotificationRequests()
            UNUserNotificationCenter.current().removeAllDeliveredNotifications()
    }

but it didn't work

import UIKit
import Firebase
import UserNotifications
import GoogleMobileAds
import CoreLocation

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate, MessagingDelegate {

    var window: UIWindow?
   lazy var locationManager: CLLocationManager = {
        let locationManager = CLLocationManager()
        locationManager.delegate = self
        locationManager.desiredAccuracy = kCLLocationAccuracyBest
        locationManager.allowsBackgroundLocationUpdates = true
        return locationManager
    }()

    var currentLocation: CLLocation?
    var defaults = UserDefaults.standard
    var geocoder = CLGeocoder()

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        window = UIWindow(frame: UIScreen.main.bounds)
        window?.makeKeyAndVisible()
        FirebaseApp.configure()

        self.startLocationService()
        locationManager.startUpdatingLocation()

        self.registerForPushNotifications()

        Messaging.messaging().delegate = self

        return true
    }

    func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) {

        let dataDict:[String: String] = ["token": fcmToken]
        NotificationCenter.default.post(name: Notification.Name("FCMToken"), object: nil, userInfo: dataDict)
    }

    func applicationDidBecomeActive(_ application: UIApplication) {
        UNUserNotificationCenter.current().removeAllPendingNotificationRequests(    )

UNUserNotificationCenter.current().removeAllDeliveredNotifications()
    }

    func registerForPushNotifications() {
        let notificationCenter = UNUserNotificationCenter.current()
        notificationCenter.delegate = self
        notificationCenter.requestAuthorization(options: [.alert, .sound, .badge]) {
            (granted, error) in
            guard granted else { return }
            self.getNotificationSettings()
        }
    }

    func getNotificationSettings() {
        UNUserNotificationCenter.current().getNotificationSettings { (settings) in
            guard settings.authorizationStatus == .authorized else { return }
            DispatchQueue.main.async {
                UIApplication.shared.registerForRemoteNotifications()
            }
        }
    }

    func application(_ application: UIApplication,
                 didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        let tokenParts = deviceToken.map { data -> String in
            return String(format: "%02.2hhx", data)
        }
        print("Registered with device token \(tokenParts.joined())")

    }

    func application(_ application: UIApplication,
                 didFailToRegisterForRemoteNotificationsWithError error: Error) {
        print("Failed to register: \(error.localizedDescription)")
    }

    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {

        print("notification is \(notification.description)")

       completionHandler([.sound])

    }

    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
        print("Received notification \(response.notification)")

    }

    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {

        if application.applicationState == .active {
            application.applicationIconBadgeNumber = 0
        } else {
            let numberOfUnreadMessages = userInfo["count"] as! String
            if let badgeNumber = Int(numberOfUnreadMessages) {
                application.applicationIconBadgeNumber = badgeNumber
            }

            completionHandler(UIBackgroundFetchResult.newData)
        }
    }
}

extension AppDelegate: CLLocationManagerDelegate {

    func startLocationService() {
        print("Starting location services in AppDelegate")
        if CLLocationManager.authorizationStatus() == .authorizedAlways || CLLocationManager.authorizationStatus() == .authorizedWhenInUse {

            activateLocationServices()

        } else {
            locationManager.requestAlwaysAuthorization()
        }
    }

    private func activateLocationServices() {
        if UIApplication.shared.applicationState == .active {
            locationManager.startUpdatingLocation()
        } else {
            locationManager.startMonitoringSignificantLocationChanges()
        }
    }

    func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
        if status == .authorizedAlways || status == .authorizedWhenInUse {
            activateLocationServices()
        } else {
            print("CLAuthorizationStatus is notDetermined")
        }
    }

    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
        print("error happened while getting current location: \(error.localizedDescription)")
    }

    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        currentLocation = locations.first
        print("AppDelegate got location")

        if defaults.value(forKey: "currentLatitude") == nil {
            let currentLatitude = currentLocation?.coordinate.latitude
            let currentLongtitude = currentLocation?.coordinate.longitude
            let currentAltitude = currentLocation?.altitude
            let timeStamp: Double = Double(Int(NSDate().timeIntervalSince1970))

            defaults.set(currentLatitude, forKey: "currentLatitude")
            defaults.set(currentLongtitude, forKey: "currentLongtitude")
            defaults.set(currentAltitude, forKey: "currentAltitude")
            defaults.set(timeStamp, forKey: "locationUpdated")
            print("UserDefaults updated with current location")
        }

        saveLocationToDatabase()

    }

    func saveLocationToDatabase() {

        var previousLocation: CLLocation?
        var previuosTime: Double?

        guard let currentLocation = currentLocation, let currentUserUid = defaults.string(forKey: "uid") else { return }

        let previousLatitude = defaults.double(forKey: "currentLatitude")
        let previousLongtitude = defaults.double(forKey: "currentLongtitude")
        previuosTime = defaults.double(forKey: "locationUpdated")

        previousLocation = CLLocation(latitude: previousLatitude, longitude: previousLongtitude)
        let timeStamp: Double = Double(Int(NSDate().timeIntervalSince1970))

        if previousLocation != nil && previuosTime != nil {
            let distance = currentLocation.distance(from: previousLocation!)
            let time =  timeStamp - previuosTime!

            if distance < 100 && time < 60 {
                print("distance is \(distance), time is \(time)")
                print("No need to save location")
                return
            } else {
                self.saveChangesToDatabase()
            }
        } else {
            self.saveChangesToDatabase()
        }
    }

    func saveChangesToDatabase() {
        guard let currentLocation = currentLocation, let currentUserUid = defaults.string(forKey: "uid") else { return }
        let usersRef = Database.database().reference().child("users").child(currentUserUid)
        usersRef.child("location").child("latitude").setValue(currentLocation.coordinate.latitude)
        usersRef.child("location").child("longtitude").setValue(currentLocation.coordinate.longitude)
        usersRef.child("location").child("altitude").setValue(currentLocation.altitude)
        let timeToSet: NSNumber = NSNumber(value: Int(NSDate().timeIntervalSince1970))
        usersRef.child("location").child("updated").setValue(timeToSet)

        print("Location saved to database")

        defaults.set(currentLocation.coordinate.latitude, forKey: "currentLatitude")
        defaults.set(currentLocation.coordinate.longitude, forKey: "currentLongtitude")
        defaults.set(currentLocation.altitude, forKey: "currentAltitude")
        defaults.set(timeToSet, forKey: "locationUpdated")
        print("UserDefaults updated with current location")

        self.geocoder.reverseGeocodeLocation(currentLocation) { (placemarks, error) in
            if let error = error {
                print(error.localizedDescription)
                return
            }
            guard let placemark = placemarks?.first else { return }
            if let city = placemark.locality, let state = placemark.administrativeArea {
                let currentPlace = "\(city), \(state)"
                usersRef.child("location").child("currentPlace").setValue(currentPlace)
            }
        }
    }

}

My console is:

AppDelegate got location
distance is 0.00017503746557926585, time is 58.0
No need to save location
AppDelegate got location
Location saved to database
UserDefaults updated with current location
notification is ,, trigger: >>
notification is ,, trigger: >>

and so on....


问:
Why File.OpenRead() appends relative path to the executable file?
Why while using the following code

```<code>string filePath = @"C:\test\upload.pdf"
FileStream fs = File.OpenRead(filePath);
</code>```

raises the following exception?

```<code>The filename, directory name, or volume label syntax is incorrect :
'C:\ConsoleApp\bin\Debug\netcoreapp2.1\C:\test\upload.pdf'
</code>```

From where the C:\ConsoleApp\bin\Debug\netcoreapp2.1\ directory comes from?

Update:
The File.OpenRead() in my case, exists within in an dll & the filePath (C:\test\upload.pdf) is sent via the application that is using the dll.

答:
The File.OpenRead() in my case, exists within in an dll .

Set the CopyLocal= true in properties of dll in which File.OpenRead exists.

Body:
Why while using the following code

string filePath = @"C:\test\upload.pdf"
FileStream fs = File.OpenRead(filePath);

raises the following exception?

The filename, directory name, or volume label syntax is incorrect :
'C:\ConsoleApp\bin\Debug\netcoreapp2.1\C:\test\upload.pdf'

From where the C:\ConsoleApp\bin\Debug\netcoreapp2.1\ directory comes from?

Update:
The File.OpenRead() in my case, exists within in an dll & the filePath (C:\test\upload.pdf) is sent via the application that is using the dll.


问:
Finding the sum of minimum distance from the points in one list to points in other list?
I have two lists containing x and y number of n-dimensional points respectively. I had to calculate the sum of minimum distances of each point in list one (containing x points) from each point in second list (containing y points). The distance I am calculating is Euclidean distance. The optimized solution is needed.

I have already implemented its naive solution in Python. But its time complexity is too much to be used anywhere. There will be optimization possible. Can this problems time complexity be reduced than what I have implemented?

I was reading thispaper which I was trying to implement. In this they were having the similar problem to which they stated that it's special condition of Earth Mover Distance. As there was no code given, hence unable to know how it got implemented. Thus my naive implementation, the above code was too slow to work on data set of 11k documents. I used Google Colab for executing my code.

# Calculating Euclidean distance between two points
def euclidean_dist(x,y):
  dd = 0.0
  #len(x) is number of dimensions. Basically x and y is a
  #list which contains coordinates of a point
  for i in range(len(x)):
    dd = dd+(x[i]-y[i])**2
  return dd**(1/2)

# Calculating the desired solution to our problem
def dist(l1,l2):
  min_dd = 0.0
  dd = euclidean_dist(l1[0],l2[0])
  for j in range(len(l1)):
    for k in range(len(l2)):
      temp = euclidean_dist(l1[j],l2[k])
      if dd > temp:
        dd = temp
    min_dd = min_dd+dd
    dd = euclidean_dist(l1[j],l2[0])
  return min_dd
```

答:
To calculate the distance between two points, you can use the distance formula:

which you can implement like that in python:

```<code>import math

def dist(x1, y1, x2, y2):
    return math.sqrt(pow(x1 - x2, 2) + pow(y1 - y2, 2))
</code>```

Then all you need to do is to loop over X or Y list, check the distance of two points and store it if it's under the current stored minimal distance. You should end up with a O(n²) complexity algorithm which is what you seems to want. Here a working example:

```<code>min_dd = None
for i in range(len(l1)):
    for j in range(i + 1, len(l1)):
        dd = dist(l1[i], l2[i], l1[j], l2[j])
        if min_dd is None or dd < min_dd:
            min_dd = dd
</code>```

With this you can get pretty good performances even with large list of points.

Body:
To calculate the distance between two points, you can use the distance formula:

which you can implement like that in python:

import math

def dist(x1, y1, x2, y2):
    return math.sqrt(pow(x1 - x2, 2) + pow(y1 - y2, 2))

Then all you need to do is to loop over X or Y list, check the distance of two points and store it if it's under the current stored minimal distance. You should end up with a O(n²) complexity algorithm which is what you seems to want. Here a working example:

min_dd = None
for i in range(len(l1)):
    for j in range(i + 1, len(l1)):
        dd = dist(l1[i], l2[i], l1[j], l2[j])
        if min_dd is None or dd < min_dd:
            min_dd = dd

With this you can get pretty good performances even with large list of points.


问:
Azure OpenVPN appliance not traversing virtual network gateway
I deployed an openvpn virtual appliance and clients can reach peered networks, the VNET of the appliance itself, but not the network onpremise that is reachable via the virtual network gateway (routed VPN). When I use the P2S OpenVPN provided from Azure clients can reach onpremise network. What am I missing ?</p>

答:
I deployed an OpenVPN appliance because Azure OpenVPN lacks ccd support.
I solved the problem by adding the OpenVPN client IP range to the VNET address space. I then created a subnet with the same IP range. Obviously, you can't put any resource in this subnet. By then adding this subnet to the route, OpenVPN clients could traverse the gateway.


问:
D3.js Tree - Check and set fill circle node white if no children?
How to check if node has children and set the fill of circle to white if no children?

Currently using:

```<code>var colourScale = d3.scale.ordinal()
  .domain(["MD", "Professional", "Leader", "Advocate", "Clinician"])
  .range(["#6695c8", "#cd3838", "#d48440", "#a8ba5f", "#63b7c0"]);

nodeUpdate.select("circle")
    .attr("r", 10)
    .attr("fill-opacity","0.7")
    .attr("stroke-opacity","1")
    .style("fill", function(d) {
      return colourScale(findParent(d));
    })
    .style("stroke", function(d) {
      return colourScale(findParent(d));
    });
</code>```

Fiddle

答:
```<code>  nodeUpdate.select("circle")
    .attr("r", 10)
    .attr("fill-opacity", "0.7")
    .attr("stroke-opacity", "1")
    .style("fill", function(d) {
    console.log(d);
    return (typeof d._children !== 'undefined') ? (colourScale(findParent(d))) : '#FFF';
    })
    .style("stroke", function(d) {
    return colourScale(findParent(d));
    });
</code>```

Edit:
The problem here is that your first node doesn't have a _children attribute, but a children one. Because children is added when clicking (_children become empty, and children take the value. Change it and it's gonna be ok)

Fiddle

Body:
How to check if node has children and set the fill of circle to white if no children?

Currently using:

var colourScale = d3.scale.ordinal()
  .domain(["MD", "Professional", "Leader", "Advocate", "Clinician"])
  .range(["#6695c8", "#cd3838", "#d48440", "#a8ba5f", "#63b7c0"]);

nodeUpdate.select("circle")
    .attr("r", 10)
    .attr("fill-opacity","0.7")
    .attr("stroke-opacity","1")
    .style("fill", function(d) {
      return colourScale(findParent(d));
    })
    .style("stroke", function(d) {
      return colourScale(findParent(d));
    });

Fiddle

Body:
  nodeUpdate.select("circle")
    .attr("r", 10)
    .attr("fill-opacity", "0.7")
    .attr("stroke-opacity", "1")
    .style("fill", function(d) {
    console.log(d);
    return (typeof d._children !== 'undefined') ? (colourScale(findParent(d))) : '#FFF';
    })
    .style("stroke", function(d) {
    return colourScale(findParent(d));
    });

Edit:
The problem here is that your first node doesn't have a _children attribute, but a children one. Because children is added when clicking (_children become empty, and children take the value. Change it and it's gonna be ok)

Fiddle