AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / user-893254

FreelanceConsultant's questions

Martin Hope
user2138149
Asked: 2025-02-14 22:07:33 +0800 CST

Como posso controlar o tipo de valor retornado por std::ranges::iota_view?

  • 7

C++ 20 apresenta std::ranges::iota_view.

Pode ser usado como parte de um forloop, por exemplo.

for (auto i: std::ranges::iota_view(0, 10))

Parece levar dois parâmetros de template. Por exemplo, o seguinte será compilado.

std::ranges::iota_view<int64_t, int64_t>(0, 10)

O primeiro parâmetro do modelo é Wwhich should be std::weakly_incrementable. O segundo parâmetro do modelo é Boundwhich should be std::semiregular.

Qual é o propósito desses dois parâmetros de template? Eles podem ser usados ​​para controlar o tipo retornado por iota_view?

Em outras palavras, que efeito, se houver, eles têm no tipo deduzido auto ino exemplo acima?

c++
  • 1 respostas
  • 64 Views
Martin Hope
user2138149
Asked: 2025-02-12 22:26:42 +0800 CST

As chamadas para `send` correspondem 1:1 com as chamadas para `recv`?

  • 5

Até onde sei, a resposta para essa pergunta é "sim", mas eu queria verificar meu entendimento e, quem sabe, obter uma compreensão mais detalhada e aprofundada.

As chamadas para sendcorrespondem 1:1 com as chamadas para recv?

Para expressar isso de outra forma, se um programa fizer uma chamada sendpara enviar alguns dados por meio de um soquete de rede para outro programa conectado à rede, haverá exatamente 1 e somente 1 chamada feita recvno lado receptor da conexão? (Supondo que o recvbuffer seja grande o suficiente.)

Estou ciente de que os sistemas operacionais e outros hardwares de rede podem fragmentar um pacote IP. No entanto, meu entendimento é que o sistema operacional no lado receptor irá recombinar os pacotes fragmentados antes de apresentar o pacote recombinado a um aplicativo cliente via recv.

O motivo da pergunta é que estou tentando descobrir se, em algumas circunstâncias, preciso fazer recvvárias chamadas para obter todos os dados enviados por uma chamada sendem outra máquina.

A razão óbvia pela qual isso pode ser necessário é porque sendenvia mais dados do que cabe no buffer usado por recv. No entanto, para os propósitos desta questão, vamos supor que a maior quantidade de dados enviados por sendcaberá dentro do buffer usado por recv.

sockets
  • 1 respostas
  • 23 Views
Martin Hope
user2138149
Asked: 2025-02-09 05:11:09 +0800 CST

Como construir um projeto cmake que usa protobuf?

  • 5

Estou tentando criar um pequeno projeto de teste em C++ que usa protobuf e o sistema de compilação cmake.

Consegui fazer tudo funcionar com um único diretório e um único arquivo CMakeLists.txt.

No entanto, esta não é uma estrutura escalável.

A próxima mudança que tentei foi criar um protodiretório e mover os *.protoarquivos para ele.

O projeto não compila mais e não consigo descobrir como consertá-lo.

Pesquisei soluções na web e também tentei perguntar ao ChatGPT. O ChatGPT andou em círculos e encontrei o que pareciam ser soluções muito variáveis ​​ao pesquisar os recursos limitados que pude encontrar online. Não era óbvio para mim qual das muitas variações poderia ser o caminho certo a seguir, mas isso é mais provável porque não sou especialista em cmake, então não consegui descobrir como juntar as várias peças.

Isto é o que eu tenho atualmente:

protobuf-example/
  proto/
    CMakeLists.txt
    message.proto
  CMakeLists.txt
  main.cpp

proto/CMakeLists.txt

Não tenho certeza do que abaixo é necessário. Tenho algum entendimento do que cada uma dessas linhas faz, mas meu entendimento não é muito sólido.

set(PROTO_FILES message.proto)
set(GENERATED_PROTO_DIR ${CMAKE_CURRENT_BINARY_DIR}/generated)
file(MAKE_DIRECTORY ${GENERATED_PROTO_DIR})

protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS ${PROTO_FILES})

add_library(proto_files STATIC ${PROTO_SRCS})

target_include_directories(proto_files PUBLIC ${Protobuf_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR})

target_link_libraries(proto_files PUBLIC ${Protobuf_LIBRARIES})

set(PROTO_GEN_SRCS ${PROTO_SRCS} PARENT_SCOPE)
set(PROTO_GEN_HDRS ${PROTO_HDRS} PARENT_SCOPE)
set(PROTO_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR} PARENT_SCOPE)

message.proto

syntax = "proto3";

message Person {
  string name = 1;
  int32 age = 2;
  string email = 3;
}

CMakeLists.txt

Por outro lado, estou familiarizado com essas afirmações e tenho quase certeza de que sei o que cada uma delas faz.

cmake_minimum_required(VERSION 3.10)
project(ProtobufExample LANGUAGES CXX)

find_package(Protobuf REQUIRED)

add_subdirectory(proto)

add_executable(protobuf_example main.cpp ${PROTO_GEN_SRCS})

target_include_directories(protobuf_example PRIVATE ${Protobuf_INCLUDE_DIR})

target_link_libraries(protobuf_example PRIVATE ${proto_files})

main.cpp

Até onde sei, este é apenas um exemplo padrão.

#include <iostream>
#include <fstream>
#include "message.pb.h"

void serializePerson(const std::string& filename) {
    Person person;
    person.set_name("John Doe");
    person.set_age(30);
    person.set_email("[email protected]");

    std::ofstream output(filename, std::ios::binary);
    if (!person.SerializeToOstream(&output)) {
        std::cerr << "Failed to serialize data." << std::endl;
    }
}

void deserializePerson(const std::string& filename) {
    Person person;
    std::ifstream input(filename, std::ios::binary);
    if (!person.ParseFromIstream(&input)) {
        std::cerr << "Failed to parse data." << std::endl;
    } else {
        std::cout << "Name: " << person.name() << "\n"
                  << "Age: " << person.age() << "\n"
                  << "Email: " << person.email() << std::endl;
    }
}

int main() {
    GOOGLE_PROTOBUF_VERIFY_VERSION;

    const std::string filename = "person.data";

    serializePerson(filename);
    deserializePerson(filename);

    google::protobuf::ShutdownProtobufLibrary();
    return 0;
}

Erro

A mensagem de erro específica é:

Cannot find source file:

    /home/user/cmake-protobuf-test/protobuf-example/build/proto/message.pb.cc

Provavelmente isso ocorre porque o build/proto/generateddiretório está vazio.

Então parece que o protobuf_generate_cppnão está fazendo nada. No entanto, não há erros ou avisos produzidos relacionados a isso.

c++
  • 1 respostas
  • 34 Views
Martin Hope
user2138149
Asked: 2025-02-09 01:56:05 +0800 CST

Por que não posso pegar o endereço de alguns elementos de uma estrutura contendo vários elementos? [duplicado]

  • 7
Esta pergunta já tem respostas aqui :
Por que o endereço dos dados char não é exibido? (8 respostas)
Fechado ontem .

Por que não posso pegar o endereço dos elementos aand cneste struct?

#include <iostream>

struct Silly {
    char a;
    unsigned short b;
    char c;
    double d;
};

int main() {

    auto p_silly = new Silly[2];

    std::cout << "address of a: " << &(p_silly[0].a) << std::endl;
    std::cout << "address of b: " << &(p_silly[0].b) << std::endl;
    std::cout << "address of c: " << &(p_silly[0].c) << std::endl;
    std::cout << "address of d: " << &(p_silly[0].d) << std::endl;

    delete[] p_silly;
}

A saída:

address of a: 
address of b: 0x61620d70c6c2
address of c: 
address of d: 0x61620d70c6c8

Compilado com:

g++ main.cpp -o main -std=c++23
c++
  • 1 respostas
  • 107 Views
Martin Hope
user2138149
Asked: 2025-02-09 01:49:59 +0800 CST

Subtrair dois ponteiros para o mesmo tipo faz sentido se esses ponteiros apontam para itens em matrizes diferentes? [duplicado]

  • 4
Esta pergunta já tem respostas aqui :
Aritmética de ponteiros com dois buffers diferentes (4 respostas)
Fechado ontem .

Essa é uma pergunta meio boba, mas acho interessante.

Eu estava experimentando ponteiros e alinhamento e me perguntei se seria possível subtrair dois ponteiros diferentes, cada um apontando para itens em matrizes diferentes.

Normalmente, espera-se que a subtração de dois ponteiros produza um valor que representa o número de elementos entre dois itens em uma matriz.

Por exemplo, aqui está um código válido que funciona conforme o esperado:

unsigned short *p_short = new unsigned short[100];
unsigned short *p_1 = &p_short[10];
unsigned short *p_2 = &p_short[20];

std::cout << p_2 - p_1 << std::endl;
// should produce the value `10`.
// There are 10 `unsigned short`s between the
// two pointers.
// Note: NOT `20`. The subtraction does not
// calulate the number of bytes between the
// two pointers.
  • Não é possível, se os arrays forem arrays de tipos diferentes. Isso produz um erro de tipo.
  • É possível se os ponteiros forem do mesmo tipo, mas apontarem para elementos de matrizes diferentes.

Entretanto, no último caso, o resultado da subtração é significativo?

Exemplo possível com saída: Este é um exemplo de algo que provavelmente não produzirá um resultado significativo.

auto p1 = new unsigned short[100];
auto p2 = new unsigned short[100];
std::cout << p2 - p1 << std::endl;

Saída: 104.

(No entanto, já vi outros valores, como -6148914691236517216.)

c++
  • 3 respostas
  • 91 Views
Martin Hope
user2138149
Asked: 2025-02-09 01:38:33 +0800 CST

Por que essa estrutura de 3 bytes tem um valor `alignof` de 1? [duplicado]

  • 6
Esta pergunta já tem respostas aqui :
Alinhamento de memória: como usar alignof / alignas? (5 respostas)
Fechado ontem .

Escrevi um exemplo muito simples que demonstra o alinhamento de endereços de um arquivo struct.

#include <iostream>

struct Silly {
    char a;
    char b;
    char c;
};

int main() {

    std::cout << "sizeof(Silly): " << sizeof(Silly) << std::endl;
    std::cout << "alignof(Silly): " << alignof(Silly) << std::endl;
    auto p_silly = new Silly[2];
    std::cout << "address[0]: " << &p_silly[0] << std::endl;
    std::cout << "address[1]: " << &p_silly[1] << std::endl;
    std::cout << "stride: " << &p_silly[1] - &p_silly[0] << std::endl;
    delete[] p_silly;
}

Compilando isso com g++ -std=c++23, encontro os seguintes resultados:

sizeof(Silly): 3
alignof(Silly): 1
address[0]: 0x63b1ada176c0
address[1]: 0x63b1ada176c3
stride: 1

Essa saída não faz sentido para mim.

sizeof() = 3é sensato, já que a struct contém 3 bytes de dados. Não há preenchimento, já que cada campo é um char, os processadores podem carregar e armazenar bytes únicos de qualquer endereço.

alignof() = 1não faz sentido para mim. O alinhamento é o número de bytes entre endereços sucessivos onde um objeto pode ser alocado. Eu esperaria ver um valor de 3aqui?

Os dois endereços mostram que dois struct Sillyforam alocados um ao lado do outro, sem preenchimento. O endereço do segundo objeto está 3 bytes mais adiante do que o primeiro. Isso faz sentido.

strideinicialmente me confundiu, mas percebi que esse é o número de elementos entre os dois endereços. Inicialmente pensei que deveria ser o número de bytes entre os dois endereços.

Por que é alignofigual a 1?

c++
  • 1 respostas
  • 86 Views
Martin Hope
user2138149
Asked: 2025-02-08 21:45:50 +0800 CST

Para obter memória alinhada corretamente na alocação de `std::vector<T>`, importa qual é a escolha de `T`?

  • 6

A std::vector<char>contém um ponteiro para algum buffer alocado no heap.

Considerando problemas de alinhamento de memória, o buffer alocado retornado pela alocação de memória tem garantia de estar alinhado corretamente apenas para o tipo charou será alinhado a algum valor comum, como 4 ou 8 bytes? (Ou não é especificado?)

Para explicar por meio de exemplo, o alocador padrão é new. A chamada newpode retornar um endereço de memória arbitrário. Mas ele é realmente arbitrário?

  • Talvez ele seja alinhado em 8 bytes em máquinas de 64 bits?
  • Talvez esteja alinhado ao tipo Tusado em std::vector<T>? (Esta parece ser a opção mais provável.)
  • Talvez o endereço retornado seja arbitrário e possa ter qualquer valor. (Não acho que isso esteja correto.)
  • Mais alguma coisa?

O motivo desta pergunta é que quero saber se posso reinterpretar com segurança os bytes contidos neste bloco de memória como outros tipos, por exemplo float, double, uint64_t, etc.

Indo na outra direção, a situação é mais óbvia. (Eu acho - corrija-me.)

Por exemplo, se solicitássemos um std::vector<uint64_t>, o ponteiro retornado pela alocação de memória e mantido pelo std::vectorobjeto seria alinhado em 8 bytes.

Portanto, seria seguro ler e escrever dados como:

  • char*
  • Alinhado corretamente (alinhado de 4 bytes)float
  • Alinhado corretamente (8 bytes)double
  • Alinhado corretamente (2 bytes)unsigned short int
  • ...etc

Entretanto, se a alocação para std::vector<char>puder retornar um endereço de memória de 1025(decimal), então claramente não há garantia de que ele será alinhado corretamente em qualquer deslocamento se reinterpretado como qualquer tipo maior que 1 byte de largura.

Acho que meu entendimento está correto aqui, mas é claro que você pode me avisar nos comentários se alguma coisa não fizer sentido ou não se encaixar corretamente.


Editar:

Posso ter encontrado uma resposta para isso, mas não tenho certeza de como interpretar o que li.

De:

  • https://en.cppreference.com/w/cpp/memory/new/operator_new

Esta função é necessária para retornar um ponteiro adequadamente alinhado para apontar para um objeto do tamanho solicitado.

Mas o que isso significa?

Para um objeto de largura de 1 byte, isso aparentemente sugere que qualquer valor de endereço é aceitável.

Para um objeto de largura de 2 bytes, isso sugeriria que qualquer endereço de valor par seria aceitável.

Para 4 bytes, qualquer múltiplo de 4. E para 8 bytes, qualquer múltiplo de 8.

Mas e quanto a outros valores? Não há nenhuma instrução para carregar um valor de 3 bytes da memória em x86, até onde eu saiba. O que acontece se você solicitar new[T]where Tis a 3 byte wide struct?

c++
  • 1 respostas
  • 77 Views
Martin Hope
user2138149
Asked: 2025-02-07 23:30:20 +0800 CST

Julia LoadError: Criar um novo global no módulo fechado `__toplevel__` interrompe a compilação incremental porque os efeitos colaterais não serão permanentes

  • 5

Eu escrevi um código em Julia, também conhecido como Julialang.

Quando tento executar este código, recebo o seguinte erro:

LoadError: Creating a new global in closed module `__toplevel__` (FUNCTION_NAME) breaks incremental compilation because the side effects will not be permanent

O que esse erro significa e o que o causa?

Reduzi o código que tinha em um dos meus módulos para isto:

module ExampleModule

export exampleFunction1
export exampleFunction2

function exampleFunction1()
    # blaa blaa
end

end # <-- Note: See answer below

function exampleFunction2()
    # blaa blaa
end

end
julia
  • 1 respostas
  • 27 Views
Martin Hope
user2138149
Asked: 2025-02-04 04:13:27 +0800 CST

O servidor de rede de pilha dupla não lida com solicitações IPv4 conforme o esperado

  • 6

Abaixo está um exemplo mínimo de funcionamento de um servidor C++ que implementa uma infraestrutura de rede de pilha dupla. (O que significa que um único soquete manipula conexões IPv4 e IPv6.)

#include <format>
#include <print>
#include <cstring>

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <signal.h>
#include <arpa/inet.h>
#include <unistd.h>

int main(int argc, char* argv[]) {

    const auto SERVER_PORT = 7778;

    const auto server_fd = socket(AF_INET6, SOCK_STREAM, 0);
    int opt = 0;

    setsockopt(server_fd, IPPROTO_IPV6, IPV6_V6ONLY, &opt, sizeof(opt));

    sockaddr_in6 server_address;
    std::memset(&server_address, 0, sizeof(server_address));

    server_address.sin6_family = AF_INET6;
    server_address.sin6_addr = in6addr_any;
    server_address.sin6_port = htons(SERVER_PORT);
    bind(server_fd, reinterpret_cast<sockaddr*>(&server_address), sizeof(server_address));

    listen(server_fd, 10);

    sockaddr_storage peer_address;
    socklen_t peer_address_length = sizeof(peer_address);
    auto peer_fd = accept(server_fd, reinterpret_cast<sockaddr*>(&peer_address), &peer_address_length);

    if(peer_address.ss_family == AF_INET)
    {
        const auto p_peer_address = &peer_address;
        sockaddr_in* ipv4 = (sockaddr_in*)p_peer_address;
        std::println("Client port (IPv4): {}", ntohs(ipv4->sin_port));
    }
    else if(peer_address.ss_family == AF_INET6)
    {
        const auto p_peer_address = &peer_address;
        sockaddr_in6* ipv6 = (sockaddr_in6*)p_peer_address;
        std::println("Client port (IPv6): {}", ntohs(ipv6->sin6_port));
    }
    else
    {
        throw std::runtime_error("unrecognized ss_family");
    }

    close(peer_fd);
    close(server_fd);

    return 0;
}

No entanto, não está funcionando como esperado. Independentemente de um cliente se conectar via ipv4 ou ipv6, a lógica sempre segue o else ifbranch da ifdeclaração. O primeiro ifbranch nunca é executado, indicando que nenhuma conexão é iniciada com a AF_INETfamília.

Ambos os clientes parecem realmente funcionar. O servidor responde quando uma conexão é iniciada - é só que a mensagem ipv6 é impressa independentemente do tipo de conexão do cliente. (ipv4 ou ipv6)

Se fizer diferença, os clientes e o servidor estão sendo executados na mesma máquina, conectando-se via localhost ( 127.0.0.1)

Exemplos de código C++ para ambos os tipos de cliente são fornecidos abaixo.

// Client: ipv6

#include <format>
#include <print>
#include <format>
#include <cstring>

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>


int main(int argc, char* argv[]) {

    const auto PORT = 7778;

    const auto socket_fd = socket(AF_INET6, SOCK_STREAM, 0);

    in6_addr server_sin6_address;
    std::memset(&server_sin6_address, 0, sizeof(server_sin6_address));
    inet_pton(AF_INET6, "::1", &server_sin6_address);

    sockaddr_storage server_address;
    std::memset(&server_address, 0, sizeof(server_address));

    server_address.ss_family = AF_INET6;
    sockaddr_storage *p_server_address = &server_address;
    sockaddr_in6 *p_server_address_in6 = reinterpret_cast<sockaddr_in6*>(p_server_address);
    p_server_address_in6->sin6_family = AF_INET6; // why repeat?
    p_server_address_in6->sin6_port = htons(PORT);
    p_server_address_in6->sin6_flowinfo = 0; // not used?
    p_server_address_in6->sin6_addr = server_sin6_address;
    p_server_address_in6->sin6_scope_id = 0; // not used?

    const auto connect_result = connect(socket_fd, reinterpret_cast<sockaddr*>(&server_address), sizeof(server_address));

    const char* const buffer = "hello world ipv6";
    const auto buffer_length = strlen(buffer) + 1;
    send(socket_fd, buffer, buffer_length, 0);

    close(socket_fd);

    return 0;
}
// Client: ipv4

#include <format>
#include <print>
#include <format>
#include <cstring>

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>


int main(int argc, char* argv[]) {

    const auto PORT = 7778;

    const auto socket_fd = socket(AF_INET, SOCK_STREAM, 0);

    in_addr server_sin_address;
    std::memset(&server_sin_address, 0, sizeof(server_sin_address));
    inet_pton(AF_INET, "127.0.0.1", &server_sin_address);

    sockaddr_storage server_address;
    std::memset(&server_address, 0, sizeof(server_address));

    server_address.ss_family = AF_INET;
    sockaddr_storage *p_server_address = &server_address;
    sockaddr_in *p_server_address_in = reinterpret_cast<sockaddr_in*>(p_server_address);
    p_server_address_in->sin_family = AF_INET; // why repeat?
    p_server_address_in->sin_port = htons(PORT);
    p_server_address_in->sin_addr = server_sin_address;
    //p_server_address_in->sin_zero = 0; // not used?

    const auto connect_result = connect(socket_fd, reinterpret_cast<sockaddr*>(&server_address), sizeof(server_address));

    const char* const buffer = "hello world ipv4";
    const auto buffer_length = strlen(buffer) + 1;
    const auto send_result = send(socket_fd, buffer, buffer_length, 0);

    close(socket_fd);
    std::println("Server quit");

    return 0;
}

Talvez seja um bug na implementação do cliente IPv4, mas até agora não encontrei nada que parecesse estar obviamente incorreto.

As conexões ipv4 para um destino ipv6 de alguma forma são atualizadas automaticamente pelo SO ou algo assim? Parece um comportamento muito estranho.

c++
  • 1 respostas
  • 50 Views
Martin Hope
user2138149
Asked: 2025-01-20 22:17:16 +0800 CST

Como ler um arquivo em um vetor?

  • 5

O código a seguir, que pode ser executado no Julia REPL, mostra como gravar o conteúdo de um vetor no disco.

v = rand(Int64, 1000000)
ofile = open("example_vector.bin", "w")
write(ofile, v)
close(ofile)

A operação reversa provavelmente também é possível, porém não consigo descobrir a sintaxe correta para isso.

ifile = open("example_vector.bin", "r")

v2 = Vector{Int64}(undef, 1000000)
read(ifile, v) # this is not valid, perhaps unsurprisingly

# I tried a few other things which I thought might work, but none did
read(ifile, Vector{Int64}, 1000000)
read(ifile, Vector{Int64, 1000000})
read(ifile, ::Type{Vector{Int64}}, 1000000)

Já tentei as seguintes coisas:

  • Pesquisando soluções na web
  • Perguntando ao ChatGPT (sem surpresa, ele criou uma chamada de função que não existia)
  • Lendo a documentação para readusar o ?modo no REPL

O que quero evitar é ter que fazer 1 milhão de chamadas de função para readler cada elemento do vetor individualmente, o que provavelmente resultará em baixo desempenho.

julia
  • 2 respostas
  • 36 Views
Martin Hope
user2138149
Asked: 2025-01-19 17:36:44 +0800 CST

A configuração do Dockerfile ENV PATH faz com que os valores do host PATH sejam usados ​​dentro do contêiner

  • 4

Estou um pouco confuso com o comportamento da variável de ambiente $PATHdentro de um contêiner Docker.

  • Estou tentando definir a variável $PATH como /kdb/bin, mais alguns outros valores.
  • Em vez disso, o valor da $PATHvariável parece estar definido como o mesmo valor do sistema host do Docker Container

O valor de echo $PATHno host é:

$ echo $PATH
/usr/local/bin:/usr/bin:/bin

(Além de algumas outras coisas que omiti por questões de brevidade.)

Aqui está o meu Dockerfile:

FROM ubuntu:24.04
WORKDIR /kdb
ENV QHOME=/kdb
ENV PATH="${QHOME}/bin:${QHOME}:$PATH"
ENV QLIC=/kdb/kc.lic
COPY ./q q
COPY ./bin bin
COPY ./src src
CMD ["/bin/bash", "-c", "sleep infinity"]

e odocker-compose.yml

services:
    kdb:
        container_name: kdb
        build: .
        command: echo $PATH
        ports:
            - 5000:5000

Defini o comando padrão em para docker-compose.ymlser echo $PATH, de modo que o valor de PATHserá mostrado nos logs.

docker logsmostra que o mesmo valor do host está sendo usado dentro do contêiner. A PATHvariável Container não inclui /kdb/binor /kdb.

Por que isso acontece?

docker
  • 1 respostas
  • 36 Views
Martin Hope
user2138149
Asked: 2025-01-01 01:03:04 +0800 CST

Qual é a diferença entre as duas formas de sintaxe para construir uma Tupla Nomeada em Julia?

  • 7

Julia tem duas sintaxes para construir tuplas nomeadas.

A primeira sintaxe usa pares de chaves e valores dentro de parênteses, sem ponto e vírgula.

named_tuple = (a=1, b=2, c=3)

A segunda forma da sintaxe usa um ponto e vírgula inicial.

named_tuple = (; a=1, b=2, c=3)

Pelo que posso perceber pela documentação, ambos os formulários produzem o mesmo resultado. (Um NamedTupleobjeto.)

Não parece haver nenhuma diferença entre os dois formulários a seguir.

julia> tuple1 = (a=1, b=2, c=3)
(a = 1, b = 2, c = 3)

julia> typeof(tuple1)
@NamedTuple{a::Int64, b::Int64, c::Int64}

julia> tuple2 = (; a=1, b=2, c=3)
(a = 1, b = 2, c = 3)

julia> typeof(tuple2)
@NamedTuple{a::Int64, b::Int64, c::Int64}

Parece ser possível criar um NamedTuplea partir de uma série de pares, mas somente se o ponto e vírgula for incluído.

Em outras palavras, essa sintaxe é válida e produz o resultado esperado

julia> tuple3 = (; :a=>1, :b=>2, :c=>3)
(a = 1, b = 2, c = 3)

julia> typeof(tuple3)
@NamedTuple{a::Int64, b::Int64, c::Int64}

por outro lado, o seguinte não

julia> tuple4 = (:a=>1, :b=>2, :c=>3)
(:a => 1, :b => 2, :c => 3)

julia> typeof(tuple4)
Tuple{Pair{Symbol, Int64}, Pair{Symbol, Int64}, Pair{Symbol, Int64}}

Isso produz um Tuplede Pairem vez de um NamedTuple.

Qual é a finalidade de cada formulário ou o motivo de ter dois formulários diferentes?

julia
  • 1 respostas
  • 31 Views
Martin Hope
user2138149
Asked: 2024-12-28 22:36:53 +0800 CST

Como compartilhar um sinalizador booleano com um thread com escopo em Rust?

  • 7

Estou tentando usar um sinalizador booleano para sinalizar que um thread deve sair. No entanto, atualmente meu código viola as regras do verificador de empréstimo. Eu entendo por que ele viola essas regras, no entanto, o que eu não sei é qual é o design mais apropriado e como isso pode corrigir o problema.

fn long_running(exit_flag: &bool) {

    loop {
        std::thread::sleep(std::time::Duration::from_secs(10));

        if *exit_flag {
            break;
        }
    }
}

fn main() {

    let mut exit_flag = false;
    std::thread::scope(
        |scope| {
            let handle = scope.spawn(
                || {
                    long_running(&exit_flag); # (1)
                }
            );

            exit_flag = true; # (2)

            // terminate the consumer poll loop
            handle.join().expect("failed to join thread");
        }
    );
}

O problema envolve as linhas marcadas com # (1)e # (2).

  • # (1): A referência a exit_flagé emprestada
  • # (2): Tentando mutar a variável subjacente enquanto a referência ainda está emprestada

Isso não é permitido devido às regras do verificador de empréstimos.

  • Uma solução para o problema pode ser alocar o sinalizador em heap e usá-lo para compartilhar os dados entre os dois threads.
  • Entretanto, a intenção de uso std::thread::scopeera permitir o lançamento de um thread que tenha acesso a uma variável local da pilha do thread pai (principal).

a propósito, tive a ideia de fazer isso neste tópico

  • Como posso passar uma referência a uma variável de pilha para um thread?
multithreading
  • 1 respostas
  • 58 Views
Martin Hope
user2138149
Asked: 2024-12-26 23:03:21 +0800 CST

Como desserializar uma entrada JSON como uma estrutura de dados genérica em Rust?

  • 5

A maioria dos exemplos que mostram a desserialização de JSON com Rust serde_jsonmostram a desserialização em um formato de estrutura conhecido, usando um struct.

É possível desserializar um documento JSON com uma estrutura desconhecida em um tipo de dado Rust genérico que pode lidar com essa variação estrutural?

Por exemplo, eu tentei algo assim

let filename = "example.json";
let maybe_ifile = std::fs::File::open(filename);

match maybe_ifile {
    Ok(ifile) => {
        let maybe_json_data = serde_json::from_reader::<_, BTreeMap<String, String>>(ifile);

        match maybe_json_data {
            Ok(json_data) => {
                println!("{json_data:?}");
            }

            Err(error) => {
                panic!("{error}")
            }
        }
    }

    Err(error) => {
        panic!("{error}");
    }
}

Isso funciona se o documento JSON for estruturado como pares de strings de chave-valor, mas não funciona para estruturas mais gerais, então claramente usar BTreeMap<String, String>não é a abordagem correta aqui.

O que estou tentando alcançar é flexibilidade usando tipos de tempo de execução/um tanto dinâmicos.

Isso é possível em outras linguagens, então presumo que haja uma solução bastante trivial em Rust, só não sei qual é.

json
  • 1 respostas
  • 35 Views
Martin Hope
user2138149
Asked: 2024-11-02 16:59:02 +0800 CST

Como mesclar um dicionário em Julia?

  • 4

Quero escrever uma função em Julia que mescle dois dicionários.

function merge(left::Dict, right::Dict)::Dict

A semântica é a seguinte:

  • As entradas são lefteright
  • Ambos lefte rightassumiram a propriedade de seus dados, o que significa que eles serão modificados após a chamada da função e nenhuma garantia sobre os dados que eles contêm deve ser feita
  • O valor de retorno contém os dados de ambos os dicionários
  • Se alguma chave estiver presente em ambos lefte righto valor de leftfor mantido

Aqui está uma ideia inicial sobre como abordar esse problema. (Este é um pseudocódigo com notas, não algo que realmente será compilado.)

function mergeDict(left::Dict, right::Dict)::Dict

    # create a new dictionary from `left`
    return_value = left

    # move data from `right` to `left`, "no-clobber"
    for k, v in pop_next!(right)
    # the function `pop_next!` does not exist, no iterator-like `pop!`

    for k in keys(right)
        v = pop!(right, k)
        # does this work as expected? destructive operation while reading keys?
        # `keys()` returns an *iterator*, not a collection! (?)

        if !haskey(left, k)
            push!(left, k, v) # no `push!` function
            left[k] = v # this works instead
        end
    end
    
    # `left` and `right` are not pointers, but "copy-by-value references"
    # just as in Python, so this doesn't work
    left = nothing
    right = nothing

    # we want to invalidate the data, how to do that?
    # this also won't work because `left` references the same data
    # structure as `return_value`
    clear(left)
    clear(right)
end

Você pode ver que eu tentei escrever uma implementação manual. Tenho quase certeza de que Julia terá algumas funções úteis como parte da biblioteca padrão para implementar isso, no entanto, sendo novo em Julia, não sei o que elas podem ser.

Encontrei as funções merge, mergewith, merge!e , mergewith!no entanto nenhuma delas parece ter a semântica descrita acima.

dictionary
  • 1 respostas
  • 27 Views
Martin Hope
user2138149
Asked: 2024-11-02 00:42:17 +0800 CST

Como comparar um arquivo no disco com um arquivo de uma ramificação diferente que não existe no disco

  • 5

Quero realizar uma operação de comparação entre um arquivo que existe no disco e um arquivo que não existe mais porque eu o movi.

Aqui está a situação.

  • Eu tinha um arquivo que existia em uma pasta. Vamos chamá-lo de ./src/A.txt.
  • Mudei A.txtpara uma nova pasta. Agora ela se chama ./doc/A.txt.
  • Eu editei ./doc/A.txt.

Agora quero comparar ./doc/A.txtcom o estado do ./src/A.txtque existe no branch origin/main. Claro, esse arquivo não existe realmente no diretório de trabalho atual.

Acredito que uma maneira possível de fazer isso seria fazer o seguinte:

  • git checkout origin/main ./src/A.txt
  • git diff ./src/A.txt ./doc/A.txt

(Edição: Não, isso não funciona. Use diff ./src/A.txt ./doc/A.txtem vez disso.)

Existe uma maneira de fazer isso "diretamente"?

Talvez algo como

git diff ./src/A.txt@origin/main ./doc/A.txt
git
  • 1 respostas
  • 38 Views
Martin Hope
user2138149
Asked: 2024-10-28 23:32:24 +0800 CST

Qual é a diferença entre as expressões `:` e `quote` em Julialang?

  • 7

Não entendo completamente qual é a diferença entre as expressões quote ... ende :( ... )em Julia.

Parece que a única diferença é que o primeiro ( quote) introduz linhas de comentários adicionais.

  • A diferença é tão simples assim ou há mais do que isso?
  • Qual é o propósito dessas linhas de comentários? O que elas fazem, ou, dito de outra forma, por que você usaria uma em vez da outra?

Aqui estão alguns exemplos

julia> :(2+2)
:(2 + 2)

julia> e1=:(2+2)
:(2 + 2)

julia> e1
:(2 + 2)

julia> eval(e1)
4
julia> quote
           2+2
       end
quote
    #= REPL[2]:2 =#
    2 + 2
end

julia> e2=quote
           2+2
       end
quote
    #= REPL[5]:2 =#
    2 + 2
end

julia> e2
quote
    #= REPL[5]:2 =#
    2 + 2
end

julia> eval(e2)
4

Eu encontrei este wikibook , mas ele só diz que

os números de linha úteis que foram adicionados a cada linha da expressão citada

(referindo-se a quotecomparado a :).

As páginas de documentação para expressões de palavras-chave também não diziam muito.

Diferentemente de outros meios de citação, :( ... ), esta forma introduz elementos QuoteNode na árvore de expressão, o que deve ser considerado ao manipular diretamente a árvore.

O que isto significa?

julia
  • 1 respostas
  • 34 Views
Martin Hope
FreelanceConsultant
Asked: 2024-07-05 21:50:03 +0800 CST

Como selecionar linhas de um DataFrame do Pandas usando índice?

  • 4

Estou tentando selecionar linhas de um DataFrame do Pandas, usando valores de índice inteiro.

Isso não funciona e obtenho erros de índice.

  • Isso me sugere que realizar uma seleção de linhas por índice faz com que reset_index()seja chamado implicitamente, embora eu possa estar enganado
  • O exemplo a seguir explica por que o comportamento que observo sugere que esse seja o caso
import pandas

data = {
    'number': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
    'fruit': 3 * ['apple'] + 3 * ['pear'] + 2 * ['banana'] + ['pear'] + ['apple'],
    'color': 3 * ['red', 'green', 'blue'] + ['red'],
    'letter': 5 * ['A', 'B'],
}
df = pandas.DataFrame(data)
df

Quadro de dados do Pandas

df_selected = df[df['fruit'] == 'pear']
df_selected

Quadro de dados do Pandas

df_selected.index
Index([3, 4, 5, 8], dtype='int64')

Isto certamente sugere que tenho um DataFrame com um índice contendo os valores 3, 4, 5 e 8.

Agora quero selecionar todas as linhas no DataFrame desde a primeira ocorrência de 'pear' até a última ocorrência, usando o índice inteiro :

Achei que isso deveria ser possível com a seguinte sintaxe:

FIRST = 3
LAST = 8
df_selected[FIRST:LAST+1]

Mas estou enganado:

Quadro de dados do Pandas

  • Ao imprimir (exibindo o DataFrame stdoutou uma célula do Jupyter Notebook), o índice mostra valores 3, 4, 5, 8.
  • Ao selecionar por índice usando a sintaxe df_selected[A:B]ou df_selected.iloc[A:B]os argumentos inteiros Ae Bsão interpretados como se df_selected.reset_index()tivessem sido chamados
  • Digo isso porque a chamada reset_index()produz a seguinte saída

Quadro de dados do Pandas

O que implica que o intervalo correto a ser usado ao selecionar por índice édf_selected.iloc[0:3+1]

Estou ciente de que esta é uma pergunta incrivelmente básica, mas espero que alguém possa me indicar a direção certa para entender por que o comportamento é assim, se houver uma razão específica para isso.

pandas
  • 1 respostas
  • 37 Views
Martin Hope
FreelanceConsultant
Asked: 2024-02-12 01:49:56 +0800 CST

Como particionar um dicionário em Python?

  • 5

Muitas linguagens fornecem uma biblioteca padrão que fornece um tipo de dicionário ou mapa de árvore binária. Muitas dessas implementações de estruturas de dados fornecem uma função para dividir a estrutura de dados em um par de estruturas de dados com base em alguma condição.

Isso é conhecido como operação de partição. Rust chama isso de "separação". Os tipos C++ maptêm operação de "limite inferior" e "limite superior" para comparação com chaves. A biblioteca padrão também fornece uma operação de "partição" que existe no std::algorithm.

Não consigo ver uma maneira ideomática de fazer isso em Python. Consegui criar uma maneira manual de fazer isso, mas não gosto muito desse código, porque ele não divide um dictem duas partes, mas divide uma parte e depois divide outra parte, resultando em código frágil (e duplicado).

map = {
   ...
}

map_part_1 = {
    key: value for key, value in map.items() if <condition>
}

map_part_2 = {
    key: value for key, value in map.items() if not <condition>
}

Não é ótimo, certo? Existe uma maneira melhor?

python
  • 3 respostas
  • 121 Views
Martin Hope
FreelanceConsultant
Asked: 2024-01-03 01:32:31 +0800 CST

Como evitar que o matplotlib plote o “número do dia” em um eixo

  • 6

Estou vendo um problema um pouco irritante ao plotar alguns dados com o matplotlib.

Conforme mostrado no exemplo de saída abaixo, o eixo x tem um formato ligeiramente inesperado.

Os rótulos são (por exemplo) 04 12:30. Sendo 04o dia do mês.

O código e os dados são fornecidos para reproduzir esta figura, anexados ao final desta questão.

Por que o eixo x está sendo formatado assim e o que posso fazer para "consertar" isso? (Não quero que o dia do mês seja mostrado e, especialmente, não quero que seja formatado como "04".)

figura matplotlib

Código

Para executar o código:python3 example.py

# example.py

import matplotlib.pyplot as plt
import pandas

df = pandas.read_json('data.json')

print(df.head())

fig, ax1 = plt.subplots(figsize=(12, 8))
ax1.plot(df['column_name'], label='My data')
ax1.set_xlabel('Timestamp')
ax1.set_ylabel('Value')
ax1.grid(True)
ax1.legend()

plt.title('Example')
plt.tight_layout()
plt.savefig('example.png')

Dados

Salve este arquivo comodata.json

{"column_name":{"1649073600000":174.79,"1649073660000":174.8,"1649073720000":174.79,"1649073780000":174.76,"1649073840000":174.69,"1649073900000":174.7,"1649073960000":174.69,"1649074020000":174.65,"1649074140000":174.67,"1649074200000":174.7,"1649074260000":174.74,"1649074320000":174.65,"1649074380000":174.69,"1649074440000":174.65,"1649074500000":174.7,"1649074560000":174.74,"1649074680000":174.72,"1649074740000":174.7,"1649074860000":174.7,"1649074920000":174.71,"1649074980000":174.75,"1649075040000":174.76,"1649075100000":174.73,"1649075160000":174.76,"1649075220000":174.7,"1649075280000":174.66,"1649075340000":174.61,"1649075400000":174.63,"1649075460000":174.65,"1649075520000":174.7,"1649075580000":174.69,"1649075640000":174.63,"1649075760000":174.66,"1649075820000":174.63,"1649075880000":174.58,"1649075940000":174.5,"1649076000000":174.52,"1649076060000":174.55,"1649076120000":174.55,"1649076180000":174.54,"1649076240000":174.48,"1649076300000":174.45,"1649076360000":174.38,"1649076420000":174.22,"1649076480000":174.21,"1649076540000":174.15,"1649076660000":174.25,"1649076720000":174.3,"1649076780000":174.28,"1649076840000":174.26,"1649076900000":174.25,"1649076960000":174.23,"1649077020000":174.21,"1649077080000":174.25,"1649077140000":174.26,"1649077200000":174.27}}
python
  • 1 respostas
  • 31 Views

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Reformatar números, inserindo separadores em posições fixas

    • 6 respostas
  • Marko Smith

    Por que os conceitos do C++20 causam erros de restrição cíclica, enquanto o SFINAE antigo não?

    • 2 respostas
  • Marko Smith

    Problema com extensão desinstalada automaticamente do VScode (tema Material)

    • 2 respostas
  • Marko Smith

    Vue 3: Erro na criação "Identificador esperado, mas encontrado 'import'" [duplicado]

    • 1 respostas
  • Marko Smith

    Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores?

    • 1 respostas
  • Marko Smith

    Como faço para corrigir um erro MODULE_NOT_FOUND para um módulo que não importei manualmente?

    • 6 respostas
  • Marko Smith

    `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso?

    • 3 respostas
  • Marko Smith

    Um programa vazio que não faz nada em C++ precisa de um heap de 204 KB, mas não em C

    • 1 respostas
  • Marko Smith

    PowerBI atualmente quebrado com BigQuery: problema de driver Simba com atualização do Windows

    • 2 respostas
  • Marko Smith

    AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos

    • 1 respostas
  • Martin Hope
    Fantastic Mr Fox Somente o tipo copiável não é aceito na implementação std::vector do MSVC 2025-04-23 06:40:49 +0800 CST
  • Martin Hope
    Howard Hinnant Encontre o próximo dia da semana usando o cronógrafo 2025-04-21 08:30:25 +0800 CST
  • Martin Hope
    Fedor O inicializador de membro do construtor pode incluir a inicialização de outro membro? 2025-04-15 01:01:44 +0800 CST
  • Martin Hope
    Petr Filipský Por que os conceitos do C++20 causam erros de restrição cíclica, enquanto o SFINAE antigo não? 2025-03-23 21:39:40 +0800 CST
  • Martin Hope
    Catskul O C++20 mudou para permitir a conversão de `type(&)[N]` de matriz de limites conhecidos para `type(&)[]` de matriz de limites desconhecidos? 2025-03-04 06:57:53 +0800 CST
  • Martin Hope
    Stefan Pochmann Como/por que {2,3,10} e {x,3,10} com x=2 são ordenados de forma diferente? 2025-01-13 23:24:07 +0800 CST
  • Martin Hope
    Chad Feller O ponto e vírgula agora é opcional em condicionais bash com [[ .. ]] na versão 5.2? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench Por que um traço duplo (--) faz com que esta cláusula MariaDB seja avaliada como verdadeira? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng Por que `dict(id=1, **{'id': 2})` às vezes gera `KeyError: 'id'` em vez de um TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos 2024-03-20 03:12:31 +0800 CST

Hot tag

python javascript c++ c# java typescript sql reactjs html

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve